diff --git a/build.rs b/build.rs index 532b465..3a366b4 100644 --- a/build.rs +++ b/build.rs @@ -17,6 +17,8 @@ fn main() { println!("cargo::rerun-if-changed=shaders/rt_compute_rasterize.comp"); println!("cargo::rerun-if-changed=shaders/rt_compute_grow_one.comp"); println!("cargo::rerun-if-changed=shaders/rt_compute_grow_two.comp"); + println!("cargo::rerun-if-changed=shaders/rt_compute_grow_three.comp"); + println!("cargo::rerun-if-changed=shaders/rt_compute_combine.comp"); std::fs::remove_file("shaders/compiled/geo_cube.spv").unwrap_or(()); std::fs::remove_file("shaders/compiled/frag_cube.spv").unwrap_or(()); @@ -30,6 +32,7 @@ fn main() { std::fs::remove_file("shaders/compiled/rt_compute_grow_one.spv").unwrap_or(()); std::fs::remove_file("shaders/compiled/rt_compute_grow_two.spv").unwrap_or(()); std::fs::remove_file("shaders/compiled/rt_compute_grow_three.spv").unwrap_or(()); + std::fs::remove_file("shaders/compiled/rt_compute_combine.spv").unwrap_or(()); if std::env::consts::OS == "windows" { let mut command = Command::new("./shaders/compile.bat"); diff --git a/shaders/compile.bat b/shaders/compile.bat index 50c3d62..bb4fe6a 100644 --- a/shaders/compile.bat +++ b/shaders/compile.bat @@ -12,4 +12,5 @@ C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_quad.frag -o shaders/compiled/fr C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_rasterize.comp -o shaders/compiled/rt_compute_rasterize.spv C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_grow_one.comp -o shaders/compiled/rt_compute_grow_one.spv C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_grow_two.comp -o shaders/compiled/rt_compute_grow_two.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_grow_three.comp -o shaders/compiled/rt_compute_grow_three.spv \ No newline at end of file +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_grow_three.comp -o shaders/compiled/rt_compute_grow_three.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute_combine.comp -o shaders/compiled/rt_compute_combine.spv \ No newline at end of file diff --git a/shaders/compile.sh b/shaders/compile.sh index 8f37a28..88be158 100755 --- a/shaders/compile.sh +++ b/shaders/compile.sh @@ -13,4 +13,5 @@ glslc shaders/rt_quad.frag -o shaders/compiled/frag_rt_quad.spv glslc shaders/rt_compute_rasterize.comp -o shaders/compiled/rt_compute_rasterize.spv glslc shaders/rt_compute_grow_one.comp -o shaders/compiled/rt_compute_grow_one.spv glslc shaders/rt_compute_grow_two.comp -o shaders/compiled/rt_compute_grow_two.spv -glslc shaders/rt_compute_grow_three.comp -o shaders/compiled/rt_compute_grow_three.spv \ No newline at end of file +glslc shaders/rt_compute_grow_three.comp -o shaders/compiled/rt_compute_grow_three.spv +glslc shaders/rt_compute_combine.comp -o shaders/compiled/rt_compute_combine.spv \ No newline at end of file diff --git a/shaders/compiled/rt_compute_combine.spv b/shaders/compiled/rt_compute_combine.spv new file mode 100644 index 0000000..61fd2ee Binary files /dev/null and b/shaders/compiled/rt_compute_combine.spv differ diff --git a/shaders/rt_compute_combine.comp b/shaders/rt_compute_combine.comp new file mode 100644 index 0000000..c70c19e --- /dev/null +++ b/shaders/rt_compute_combine.comp @@ -0,0 +1,51 @@ +#version 450 + +layout(binding = 0) uniform UniformBufferObject { + mat4 model; + mat4 geom_rot; + mat4 view; + mat4 proj; + vec3 camera_pos; + bool[16] use_geom_shader; +} ubo; + +layout(binding = 3) readonly buffer CompoundBuffer { + uint compounds[]; +}; + +layout(binding = 4) readonly buffer ColorBuffer { + uint grid_in[]; +}; + +layout(binding = 9) readonly buffer TransparentBuffer { + bool transparent_grid[]; +}; + +layout(binding = 8) buffer SizeBuffer3D { + uint grid_size_in[]; +}; + +layout (local_size_x = 16, local_size_y = 1, local_size_z = 1) in; + +void main() { + uint index = gl_GlobalInvocationID.x; + uint output_offset = 0; + uint compound_start = 0; + // iterate over the compounds and find the work index inside of it + while (index > compounds[compound_start] * compounds[compound_start]) { + output_offset += compounds[compound_start] * compounds[compound_start] * compounds[compound_start] * 2; + index -= compounds[compound_start] * compounds[compound_start]; + compound_start = compounds[compound_start + 2]; + } + // grid pos in the task + uint compound_grid_size = compounds[compound_start]; + float compound_scale = uintBitsToFloat(compounds[compound_start + 1]); + vec3 mid_offset = vec3(compound_scale * 0.5, compound_scale * 0.5, compound_scale * 0.5); + uint x = index % compound_grid_size; + uint y = ((index) % (compound_grid_size * compound_grid_size) - x) / (compound_grid_size); + uint z = (index - x - y * compound_grid_size) / (compound_grid_size * compound_grid_size); + + uint size_x = grid_size_in[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3]; + uint size_y = grid_size_in[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3 + 1]; + uint size_z = grid_size_in[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3 + 2]; +} \ No newline at end of file diff --git a/src/app_data.rs b/src/app_data.rs index 6469600..0dafc31 100644 --- a/src/app_data.rs +++ b/src/app_data.rs @@ -27,6 +27,7 @@ pub struct AppData { pub pipeline_compute_grow_one: vk::Pipeline, pub pipeline_compute_grow_two: vk::Pipeline, pub pipeline_compute_grow_three: vk::Pipeline, + pub pipeline_compute_combine: vk::Pipeline, pub framebuffers: Vec<vk::Framebuffer>, pub command_pool: vk::CommandPool, diff --git a/src/command_buffer.rs b/src/command_buffer.rs index 3a70d1f..e477391 100644 --- a/src/command_buffer.rs +++ b/src/command_buffer.rs @@ -200,6 +200,35 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa &[] as &[vk::MemoryBarrier], &[buffer_memory_barrier_out], &[] as &[vk::ImageMemoryBarrier]); + + // combine element + device.cmd_bind_pipeline( + *command_buffer, vk::PipelineBindPoint::COMPUTE, data.pipeline_compute_combine); + + device.cmd_bind_descriptor_sets( + *command_buffer, + vk::PipelineBindPoint::COMPUTE, + data.pipeline_layout, + 0, + &[data.descriptor_sets[i]], + &[]); + + device.cmd_dispatch(*command_buffer, (data.compute_task_one_size as f64 / 16.0).ceil() as u32, 1, 1); + + let buffer_memory_barrier_out = vk::BufferMemoryBarrier::builder() + .buffer(data.render_storage_buffers[i]) + .src_access_mask(vk::AccessFlags::SHADER_WRITE) + .dst_access_mask(vk::AccessFlags::SHADER_READ) + .size(vk::WHOLE_SIZE as u64) + .build(); + + device.cmd_pipeline_barrier(*command_buffer, + vk::PipelineStageFlags::COMPUTE_SHADER, + vk::PipelineStageFlags::FRAGMENT_SHADER, + vk::DependencyFlags::DEVICE_GROUP, + &[] as &[vk::MemoryBarrier], + &[buffer_memory_barrier_out], + &[] as &[vk::ImageMemoryBarrier]); } // start render pass let clear_values = &[color_clear_value, depth_clear_value]; diff --git a/src/main.rs b/src/main.rs index 64de5c4..1b2714e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -474,6 +474,7 @@ impl App { self.device.destroy_pipeline(self.data.pipeline_compute_grow_one, None); self.device.destroy_pipeline(self.data.pipeline_compute_grow_two, None); self.device.destroy_pipeline(self.data.pipeline_compute_grow_three, None); + self.device.destroy_pipeline(self.data.pipeline_compute_combine, None); self.device.destroy_pipeline_layout(self.data.pipeline_layout, None); self.device.destroy_render_pass(self.data.render_pass, None); @@ -895,6 +896,16 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu .module(compute_shader_module_grow_three) .name(b"main\0"); + // load the byte data + let compute_bytes = include_bytes!("../shaders/compiled/rt_compute_combine.spv"); + // create the shaders + let compute_shader_module_combine = create_shader_module(device, &compute_bytes[..])?; + //create the shader stage for the compute shader + let compute_stage_combine = vk::PipelineShaderStageCreateInfo::builder() + .stage(vk::ShaderStageFlags::COMPUTE) + .module(compute_shader_module_combine) + .name(b"main\0"); + // define input assembly and object type. This is altered when using geometry shader let mut topology = vk::PrimitiveTopology::TRIANGLE_LIST; if data.use_geometry_shader { @@ -1051,7 +1062,11 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu .stage(compute_stage_grow_three) .layout(data.pipeline_layout); - let compute_pipelines = device.create_compute_pipelines(vk::PipelineCache::null(), &[info_compute_rasterize, info_compute_grow_one, info_compute_grow_two, info_compute_grow_three], None)?.0; + let info_compute_combine = vk::ComputePipelineCreateInfo::builder() + .stage(compute_stage_combine) + .layout(data.pipeline_layout); + + let compute_pipelines = device.create_compute_pipelines(vk::PipelineCache::null(), &[info_compute_rasterize, info_compute_grow_one, info_compute_grow_two, info_compute_grow_three, info_compute_combine], None)?.0; data.pipeline_cube = pipelines[0]; data.pipeline_cuboid = pipelines[1]; @@ -1061,6 +1076,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu data.pipeline_compute_grow_one = compute_pipelines[1]; data.pipeline_compute_grow_two = compute_pipelines[2]; data.pipeline_compute_grow_three = compute_pipelines[3]; + data.pipeline_compute_combine = compute_pipelines[4]; device.destroy_shader_module(vert_shader_module_cube, None); device.destroy_shader_module(geo_shader_module_cube, None); @@ -1077,6 +1093,7 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu device.destroy_shader_module(compute_shader_module_grow_one, None); device.destroy_shader_module(compute_shader_module_grow_two, None); device.destroy_shader_module(compute_shader_module_grow_three, None); + device.destroy_shader_module(compute_shader_module_combine, None); Ok(()) }