Compute based enable flag generation

This commit is contained in:
2026-01-13 00:28:28 +00:00
parent 2f34678a03
commit bafd63e3c5
7 changed files with 335 additions and 116 deletions
+5
View File
@@ -25,6 +25,7 @@ pub(crate) struct PreviousDebug {
pub(crate) show_all: bool,
pub(crate) disable_ao: bool,
pub(crate) use_linear_ao: bool,
pub(crate) use_cpu_enable_gen: bool,
}
#[derive(Debug)]
@@ -355,6 +356,10 @@ pub(crate) fn gui_up(gui: &mut Gui, state: &mut GState) {
&mut state.debug.use_linear_ao,
"Use linear falloff for occlusion calculation",
);
ui.toggle_value(
&mut state.debug.use_cpu_enable_gen,
"Use CPU side enable flag generation",
);
state.recreate_pipelines = ui.button("Force recompile pipelines").clicked();
});
+129 -7
View File
@@ -225,6 +225,7 @@ struct App {
trace_module: Module,
normals_module: Module,
fuzz_module: Module,
enable_gen_module: Module,
_threads: Vec<JoinHandle<()>>,
thread_work_creation: mpmc::Sender<WorkItem>,
thread_work_completion: mpsc::Receiver<WorkComplete>,
@@ -677,6 +678,14 @@ impl App {
rspirv::binary::parse_words(fuzz_spv_code_u32, &mut loader).unwrap();
let fuzz_module = loader.module();
let enable_gen_spv_code = include_bytes!("../shaders_out/enable_gen.comp.spv");
let enable_gen_spv_code_u32 = vulkano::shader::spirv::bytes_to_words(enable_gen_spv_code)
.unwrap()
.into_owned();
let mut loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(enable_gen_spv_code_u32, &mut loader).unwrap();
let enable_gen_module = loader.module();
let (thread_work_creation_sender, thread_work_creation_receiver) =
mpmc::sync_channel::<WorkItem>(256);
let (thread_work_completion_sender, thread_work_completion_receiver) =
@@ -749,6 +758,7 @@ impl App {
trace_module,
normals_module,
fuzz_module,
enable_gen_module,
_threads: threads,
thread_work_creation: thread_work_creation_sender,
thread_work_completion: thread_work_completion_receiver,
@@ -823,6 +833,15 @@ mod fuzz_cs {
}
}
mod enable_gen_cs {
vulkano_shaders::shader! {
bytes: "shaders_out/enable_gen.comp.spv",
vulkan_version: "1.3",
spirv_version: "1.6",
custom_derives: [Debug, Clone, Copy],
}
}
impl ApplicationHandler for App {
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
let window = Arc::new(
@@ -1248,6 +1267,7 @@ impl ApplicationHandler for App {
self.trace_module.clone(),
self.normals_module.clone(),
self.fuzz_module.clone(),
self.enable_gen_module.clone(),
rcx.render_pass.clone(),
self.pipeline_cache.clone(),
rcx.shader_modules.clone(),
@@ -1413,6 +1433,7 @@ impl App {
Arc<DescriptorSet>,
Arc<DescriptorSet>,
Arc<DescriptorSet>,
Option<Arc<DescriptorSet>>,
) {
let trace_set1 = if self.csg_count > 0 {
let trace_layout = &self.gstate.csg[0]
@@ -1558,6 +1579,29 @@ impl App {
)
.unwrap();
let enable_gen_set1 = if self.csg_count > 0 {
let enable_gen_layout = &self.gstate.csg[0]
.read()
.unwrap()
.enable_gen_pipeline
.layout()
.set_layouts()[0]
.clone();
let enable_gen_set = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
enable_gen_layout.clone(),
[WriteDescriptorSet::buffer(
1,
rcx.camera_buffers[index].clone(),
)],
[],
)
.unwrap();
Some(enable_gen_set)
} else {
None
};
(
trace_set1,
normals_set1,
@@ -1568,6 +1612,7 @@ impl App {
rt_set2,
rt_set3,
rt_set4,
enable_gen_set1,
)
}
@@ -1586,6 +1631,50 @@ impl App {
.unwrap();
}
fn add_commands_enable_gen(
&self,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
push_constants: &[PushConstantData],
enable_gen_set: Arc<DescriptorSet>,
frame_index: usize,
) {
for (i, csg) in self.gstate.csg.iter().enumerate() {
let csg = csg.read().unwrap();
builder
.bind_pipeline_compute(csg.enable_gen_pipeline.clone())
.unwrap()
.bind_descriptor_sets(
PipelineBindPoint::Compute,
csg.enable_gen_pipeline.layout().clone(),
0,
vec![
enable_gen_set.clone(),
csg.enable_gen_descriptor_set[frame_index].clone(),
],
)
.unwrap();
builder
.push_constants(
csg.enable_gen_pipeline.layout().clone(),
0,
push_constants[i],
)
.unwrap();
debug_assert_eq!(csg.subdivision % 8, 0);
unsafe {
builder.dispatch([
csg.subdivision / 8,
csg.subdivision / 8,
csg.subdivision / 8,
])
}
.unwrap();
}
}
fn add_commands_depth_pass(
&self,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
@@ -1785,6 +1874,13 @@ impl App {
}
let fuzz_comp = fuzz_comp.unwrap();
let enable_gen_comp = read_spirv_words_from_file("enable_gen.comp.spv");
if enable_gen_comp.is_err() {
error!("Could not read enable_gen comp file");
return;
}
let enable_gen_comp = enable_gen_comp.unwrap();
let mut trace_loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(trace_frag, &mut trace_loader).unwrap();
@@ -1794,6 +1890,9 @@ impl App {
let mut fuzz_loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(fuzz_comp, &mut fuzz_loader).unwrap();
let mut enable_gen_loader = rspirv::dr::Loader::new();
rspirv::binary::parse_words(enable_gen_comp, &mut enable_gen_loader).unwrap();
let trace_vert = unsafe {
::vulkano::shader::ShaderModule::new(
self.device.clone(),
@@ -1854,6 +1953,7 @@ impl App {
self.trace_module = trace_loader.module();
self.normals_module = normals_loader.module();
self.fuzz_module = fuzz_loader.module();
self.enable_gen_module = enable_gen_loader.module();
}
fn recreate_pipelines(
@@ -1872,6 +1972,7 @@ impl App {
self.trace_module.clone(),
self.normals_module.clone(),
self.fuzz_module.clone(),
self.enable_gen_module.clone(),
rcx.render_pass.clone(),
self.pipeline_cache.clone(),
rcx.shader_modules.clone(),
@@ -1913,6 +2014,7 @@ impl App {
self.trace_module.clone(),
self.normals_module.clone(),
self.fuzz_module.clone(),
self.enable_gen_module.clone(),
rcx.render_pass.clone(),
self.pipeline_cache.clone(),
rcx.shader_modules.clone(),
@@ -1950,11 +2052,11 @@ impl App {
let mut input_rw = input.write().unwrap();
for val in input_rw.iter_mut() {
for i in 0..4 {
val.point[i] = rand::random_range(-1000.0..1000.0);
val.gradient[i] = rand::random_range(-1000.0..1000.0);
let midpoint = rand::random_range(-999.0..999.0);
val.interval_low[i] = rand::random_range(-1000.0..midpoint);
val.interval_high[i] = rand::random_range(midpoint..1000.0);
val.point[i] = rand::random_range(-10.0..10.0);
val.gradient[i] = rand::random_range(-10.0..10.0);
let midpoint = rand::random_range(-9.0..9.0);
val.interval_low[i] = rand::random_range(-10.0..midpoint);
val.interval_high[i] = rand::random_range(midpoint..10.0);
}
}
drop(input_rw);
@@ -2067,14 +2169,16 @@ impl App {
),
);
if (interval_expected.upper() - interval_val.upper()).abs() > f32x8::splat(0.001) {
if (interval_expected.upper() - interval_val.upper()).abs() > f32x8::splat(0.000001)
{
println!(
"ERROR: interval upper expected {:?}, got {:?}",
interval_expected.upper(),
interval_val.upper()
);
}
if (interval_expected.lower() - interval_val.lower()).abs() > f32x8::splat(0.001) {
if (interval_expected.lower() - interval_val.lower()).abs() > f32x8::splat(0.000001)
{
println!(
"ERROR: interval lower expected {:?}, got {:?}",
interval_expected.lower(),
@@ -2138,6 +2242,7 @@ impl App {
self.trace_module.clone(),
self.normals_module.clone(),
self.fuzz_module.clone(),
self.enable_gen_module.clone(),
rcx.render_pass.clone(),
self.pipeline_cache.clone(),
rcx.shader_modules.clone(),
@@ -2229,6 +2334,7 @@ impl App {
self.trace_module.clone(),
self.normals_module.clone(),
self.fuzz_module.clone(),
self.enable_gen_module.clone(),
rcx.render_pass.clone(),
self.pipeline_cache.clone(),
rcx.shader_modules.clone(),
@@ -2278,6 +2384,7 @@ impl App {
image_index,
self.command_buffer_allocator.clone(),
self.transfer_queue.clone(),
self.gstate.debug.use_cpu_enable_gen,
i,
))
.unwrap();
@@ -2306,6 +2413,7 @@ impl App {
rt_set2,
rt_set3,
rt_set4,
enable_gen_set1,
) = self.get_descriptor_sets(rcx, image_index);
let mut builder = AutoCommandBufferBuilder::primary(
@@ -2332,6 +2440,15 @@ impl App {
}
if RUN_STANDARD_PIPELINE {
if !self.gstate.csg.is_empty() {
self.add_commands_enable_gen(
&mut builder,
&push_constants,
enable_gen_set1.unwrap(),
image_index,
);
}
let depth_clear = if self.depth_format.numeric_format_stencil().is_some() {
Some((0.0, 0).into())
} else {
@@ -2657,6 +2774,7 @@ fn get_spec_constants(debug: &PreviousDebug) -> HashMap<u32, SpecializationConst
const SPEC_SHOW_ALL: u32 = 7;
const SPEC_DISABLE_AO: u32 = 8;
const SPEC_USE_LINEAR_AO: u32 = 9;
const SPEC_USE_CPU_ENABLE_GEN: u32 = 10;
const SPEC_MAXIMUM_SUBDISIVION: u32 = 30;
let mut spec_constants = HashMap::with_capacity(6);
@@ -2694,6 +2812,10 @@ fn get_spec_constants(debug: &PreviousDebug) -> HashMap<u32, SpecializationConst
SPEC_USE_LINEAR_AO,
SpecializationConstant::Bool(debug.use_linear_ao),
);
spec_constants.insert(
SPEC_USE_CPU_ENABLE_GEN,
SpecializationConstant::Bool(debug.use_cpu_enable_gen),
);
spec_constants.insert(
SPEC_MAXIMUM_SUBDISIVION,
SpecializationConstant::U32(MAXIMUM_SUBDIVISION),
+3
View File
@@ -52,14 +52,17 @@ pub(crate) struct CSG {
pub(crate) trace_shader_module: Arc<ShaderModule>,
pub(crate) normals_shader_module: Arc<ShaderModule>,
pub(crate) fuzz_shader_module: Arc<ShaderModule>,
pub(crate) enable_gen_shader_module: Arc<ShaderModule>,
pub(crate) trace_pipeline: Arc<GraphicsPipeline>,
pub(crate) normals_pipeline: Arc<GraphicsPipeline>,
pub(crate) fuzz_pipeline: Arc<ComputePipeline>,
pub(crate) enable_gen_pipeline: Arc<ComputePipeline>,
pub(crate) subdivision: u32,
pub(crate) enable_buffer: Vec<Subbuffer<Object>>,
pub(crate) enable_buffer_host_visible: Vec<Subbuffer<Object>>,
pub(crate) trace_descriptor_set: Vec<Arc<DescriptorSet>>,
pub(crate) normals_descriptor_set: Vec<Arc<DescriptorSet>>,
pub(crate) enable_gen_descriptor_set: Vec<Arc<DescriptorSet>>,
}
pub(crate) fn load_obj(
+16 -8
View File
@@ -5,16 +5,27 @@
layout(local_size_x = 8, local_size_y = 8, local_size_z = 8) in;
void main() {
if (SPEC_BRUTE_FORCE) {
if (SPEC_BRUTE_FORCE || SPEC_USE_CPU_ENABLE_GEN) {
return;
}
uvec3 total_invocations = gl_NumWorkGroups * gl_WorkGroupSize;
vec3 internal_pos = vec3(gl_GlobalInvocationID) / vec3(total_invocations);
uint base_index = (gl_GlobalInvocationID.z * total_invocations.x * total_invocations.y) +
(gl_GlobalInvocationID.y * total_invocations.x) + gl_GlobalInvocationID.x;
vec3 box_dimensions = object_uniforms.dimensions / vec3(total_invocations);
vec3 low_corner = object_uniforms.lowest_corner + (box_dimensions * internal_pos);
vec3 high_corner = object_uniforms.lowest_corner + (box_dimensions * (internal_pos + 1));
vec3 internal_pos = vec3(
float((base_index >> (object_uniforms.subdivision_log2 * 2)) & ((1 << object_uniforms.subdivision_log2) - 1))
/ float(1 << object_uniforms.subdivision_log2),
float((base_index >> (object_uniforms.subdivision_log2 * 1)) & ((1 << object_uniforms.subdivision_log2) - 1))
/ float(1 << object_uniforms.subdivision_log2),
float((base_index >> (object_uniforms.subdivision_log2 * 0)) & ((1 << object_uniforms.subdivision_log2) - 1))
/ float(1 << object_uniforms.subdivision_log2)
);
vec3 low_corner = (((vec3(0.0) / float(1 << object_uniforms.subdivision_log2)) + internal_pos)
* object_uniforms.dimensions) + object_uniforms.lowest_corner;
vec3 high_corner = (((vec3(1.0) / float(1 << object_uniforms.subdivision_log2)) + internal_pos)
* object_uniforms.dimensions) + object_uniforms.lowest_corner;
vec2 interval = interval_scene(
vec4(low_corner, camera_uniforms.campos_and_time.w),
@@ -23,9 +34,6 @@ void main() {
bool enable = (interval.x < 0) && (interval.y > 0);
uint base_index = (gl_GlobalInvocationID.z * total_invocations.x * total_invocations.y) +
(gl_GlobalInvocationID.y * total_invocations.x) + gl_GlobalInvocationID.x;
switch ((base_index >> 5) & 3) {
default:
case 0:
+1
View File
@@ -11,6 +11,7 @@ layout(constant_id = 6) const bool SPEC_SHOW_MATERIAL = false;
layout(constant_id = 7) const bool SPEC_SHOW_ALL = false;
layout(constant_id = 8) const bool SPEC_DISABLE_AO = false;
layout(constant_id = 9) const bool SPEC_USE_LINEAR_AO = false;
layout(constant_id = 10) const bool SPEC_USE_CPU_ENABLE_GEN = false;
//layout(constant_id = 30) const uint SPEC_MAXIMUM_SUBDIVISION = 64;
const uint SPEC_MAXIMUM_SUBDIVISION = 64;
+90 -11
View File
@@ -56,6 +56,7 @@ pub enum WorkItem {
Module,
Module,
Module,
Module,
Arc<RenderPass>,
Arc<PipelineCache>,
ShaderModules,
@@ -74,6 +75,7 @@ pub enum WorkItem {
usize,
Arc<dyn CommandBufferAllocator>,
Arc<Queue>,
bool,
usize,
),
RecompilePipelines(
@@ -82,6 +84,7 @@ pub enum WorkItem {
Module,
Module,
Module,
Module,
Arc<RenderPass>,
Arc<PipelineCache>,
ShaderModules,
@@ -104,6 +107,7 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
trace_module,
normals_module,
fuzz_module,
enable_gen_module,
render_pass,
cache,
modules,
@@ -125,8 +129,10 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
sdf_specialize_module(device.clone(), &parts, normals_module, "normals");
let fuzz_shader_module =
sdf_specialize_module(device.clone(), &parts, fuzz_module, "fuzz");
let enable_gen_shader_module =
sdf_specialize_module(device.clone(), &parts, enable_gen_module, "enable_gen");
let (trace_pipeline, normals_pipeline, fuzz_pipeline) =
let (trace_pipeline, normals_pipeline, fuzz_pipeline, enable_gen_pipeline) =
deferred_pipelines_recompile(
device,
render_pass,
@@ -135,6 +141,7 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
trace_shader_module.clone(),
normals_shader_module.clone(),
fuzz_shader_module.clone(),
enable_gen_shader_module.clone(),
debug,
);
@@ -189,6 +196,22 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
})
.collect();
let enable_gen_layout = enable_gen_pipeline.layout().set_layouts()[1].clone();
let enable_gen_descriptor_set = (0..frames)
.map(|f| {
DescriptorSet::new(
descriptor_set_allocator.clone(),
enable_gen_layout.clone(),
[WriteDescriptorSet::buffer(
0,
enable_buffer[f as usize].clone(),
)],
[],
)
.unwrap()
})
.collect();
let csg = Arc::new(RwLock::new(CSG {
name: "example".to_string(),
_seed: seed,
@@ -200,14 +223,17 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
trace_shader_module,
normals_shader_module,
fuzz_shader_module,
enable_gen_shader_module,
trace_pipeline,
normals_pipeline,
fuzz_pipeline,
enable_gen_pipeline,
subdivision,
enable_buffer,
enable_buffer_host_visible,
trace_descriptor_set,
normals_descriptor_set,
enable_gen_descriptor_set,
colour: Vec3::ONE,
roughness: 1.0,
metallic: 0.67,
@@ -227,6 +253,7 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
frame_index,
command_allocator,
transfer_queue,
use_cpu_enable_gen,
index,
) => {
let csg = csg.read().unwrap();
@@ -252,6 +279,7 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
frame_index,
command_allocator,
transfer_queue,
use_cpu_enable_gen,
);
send.send(WorkComplete::GetPushConstants(
@@ -267,6 +295,7 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
trace_module,
normals_module,
fuzz_module,
enable_gen_module,
render_pass,
cache,
modules,
@@ -281,9 +310,19 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
sdf_specialize_module(device.clone(), &csg.parts, normals_module, "normals");
csg.fuzz_shader_module =
sdf_specialize_module(device.clone(), &csg.parts, fuzz_module, "fuzz");
csg.enable_gen_shader_module = sdf_specialize_module(
device.clone(),
&csg.parts,
enable_gen_module,
"enable_gen",
);
(csg.trace_pipeline, csg.normals_pipeline, csg.fuzz_pipeline) =
deferred_pipelines_recompile(
(
csg.trace_pipeline,
csg.normals_pipeline,
csg.fuzz_pipeline,
csg.enable_gen_pipeline,
) = deferred_pipelines_recompile(
device,
render_pass,
cache,
@@ -291,6 +330,7 @@ pub fn thread_loop(recv: mpmc::Receiver<WorkItem>, send: mpsc::SyncSender<WorkCo
csg.trace_shader_module.clone(),
csg.normals_shader_module.clone(),
csg.fuzz_shader_module.clone(),
csg.enable_gen_shader_module.clone(),
debug,
);
csg.new_pipelines_needed = false;
@@ -314,11 +354,13 @@ fn deferred_pipelines_recompile(
trace_shader_module: Arc<ShaderModule>,
normals_shader_module: Arc<ShaderModule>,
fuzz_shader_module: Arc<ShaderModule>,
enable_gen_shader_module: Arc<ShaderModule>,
debug: PreviousDebug,
) -> (
Arc<GraphicsPipeline>,
Arc<GraphicsPipeline>,
Arc<ComputePipeline>,
Arc<ComputePipeline>,
) {
let specs = get_spec_constants(&debug);
@@ -454,7 +496,7 @@ fn deferred_pipelines_recompile(
.unwrap(),
);
let compute_pipeline_layout = PipelineLayout::new(
let fuzz_pipeline_layout = PipelineLayout::new(
device.clone(),
PipelineDescriptorSetLayoutCreateInfo::from_stages([&fuzz_cs_info])
.into_pipeline_layout_create_info(device.clone())
@@ -462,14 +504,45 @@ fn deferred_pipelines_recompile(
)
.unwrap();
let compute_pipeline = ComputePipeline::new(
let fuzz_pipeline = ComputePipeline::new(
device.clone(),
None,
ComputePipelineCreateInfo::stage_layout(fuzz_cs_info, compute_pipeline_layout.clone()),
ComputePipelineCreateInfo::stage_layout(fuzz_cs_info, fuzz_pipeline_layout.clone()),
)
.expect("failed to create compute pipeline");
.expect("failed to create fuzz pipeline");
(trace_pipeline, normals_pipeline, compute_pipeline)
let enable_gen_cs_info = PipelineShaderStageCreateInfo::new(
enable_gen_shader_module
.specialize(specs.clone())
.unwrap()
.single_entry_point()
.unwrap(),
);
let enable_gen_pipeline_layout = PipelineLayout::new(
device.clone(),
PipelineDescriptorSetLayoutCreateInfo::from_stages([&enable_gen_cs_info])
.into_pipeline_layout_create_info(device.clone())
.unwrap(),
)
.unwrap();
let enable_gen_pipeline = ComputePipeline::new(
device.clone(),
None,
ComputePipelineCreateInfo::stage_layout(
enable_gen_cs_info,
enable_gen_pipeline_layout.clone(),
),
)
.expect("failed to create enable_gen pipeline");
(
trace_pipeline,
normals_pipeline,
fuzz_pipeline,
enable_gen_pipeline,
)
}
fn create_csg(seed: u64) -> SSATape {
@@ -545,6 +618,7 @@ fn interval_check(
frame_index: usize,
command_allocator: Arc<dyn CommandBufferAllocator>,
transfer_queue: Arc<Queue>,
use_cpu_enable_gen: bool,
) -> Box<dyn GpuFuture + Send + Sync> {
const INTERPRET_INPUT_X: interpreters::Value =
interpreters::Value::from_array([10000.0, 0.0, 0.0, -10000.0, 0.0, 0.0, 0.0, 0.0]);
@@ -598,6 +672,7 @@ fn interval_check(
metallic: csg.metallic,
};
if use_cpu_enable_gen {
for x in 0..xdim {
for y in 0..ydim {
for z in 0..(zdim / 8) {
@@ -660,24 +735,28 @@ fn interval_check(
let output = interpreter.scene(
Interval::const_splat2(
(x as f32 / (xdim as f32)) * obj.dimensions[0] + obj.lowest_corner[0],
((x + 1) as f32 / (xdim as f32)) * obj.dimensions[0] + obj.lowest_corner[0],
((x + 1) as f32 / (xdim as f32)) * obj.dimensions[0]
+ obj.lowest_corner[0],
),
Interval::const_splat2(
(y as f32 / (ydim as f32)) * obj.dimensions[1] + obj.lowest_corner[1],
((y + 1) as f32 / (ydim as f32)) * obj.dimensions[1] + obj.lowest_corner[1],
((y + 1) as f32 / (ydim as f32)) * obj.dimensions[1]
+ obj.lowest_corner[1],
),
interval_input_z,
Interval::const_splat(time),
);
let total_index = (x * zdim * ydim) + (y * zdim) + (z * 8);
let output = ((output.lower().simd_le(VALUE_0) & output.upper().simd_ge(VALUE_0))
let output = ((output.lower().simd_le(VALUE_0)
& output.upper().simd_ge(VALUE_0))
.to_bitmask() as u32)
<< (total_index & 31);
obj.enable[total_index >> 7][(total_index >> 5) & 3] |= output;
}
}
}
}
gpu_upload(
obj,
+1
View File
@@ -551,6 +551,7 @@ impl SSATape {
let module = b.module();
if DUMP_SPV_DIS_TO_FILE {
std::fs::create_dir_all("spv-dis").unwrap();
std::fs::write(
format!(
"spv-dis/{}.spv-dis",