diff --git a/build.rs b/build.rs index d21056e..532b465 100644 --- a/build.rs +++ b/build.rs @@ -14,26 +14,22 @@ fn main() { println!("cargo::rerun-if-changed=shaders/rt_quad.vert"); println!("cargo::rerun-if-changed=shaders/rt_quad.frag"); - println!("cargo::rerun-if-changed=shaders/rt_compute.comp"); + 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"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/compiled/geo_cube.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/compiled/frag_cube.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/compiled/vert_cube.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/compiled/geo_cuboid.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/compiled/frag_cuboid.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/compiled/vert_cuboid.spv"); - #[warn(unused_must_use)] - std::fs::remove_file("shaders/compiled/vert_rt_quad.spv"); - #[warn(unused_must_use)] - std::fs::remove_file("shaders/compiled/frag_rt_quad.spv"); - #[warn(unused_must_use)] - std::fs::remove_file("shaders/compiled/rt_compute.spv"); + std::fs::remove_file("shaders/compiled/geo_cube.spv").unwrap_or(()); + std::fs::remove_file("shaders/compiled/frag_cube.spv").unwrap_or(()); + std::fs::remove_file("shaders/compiled/vert_cube.spv").unwrap_or(()); + std::fs::remove_file("shaders/compiled/geo_cuboid.spv").unwrap_or(()); + std::fs::remove_file("shaders/compiled/frag_cuboid.spv").unwrap_or(()); + std::fs::remove_file("shaders/compiled/vert_cuboid.spv").unwrap_or(()); + std::fs::remove_file("shaders/compiled/vert_rt_quad.spv").unwrap_or(()); + std::fs::remove_file("shaders/compiled/frag_rt_quad.spv").unwrap_or(()); + std::fs::remove_file("shaders/compiled/rt_compute_rasterize.spv").unwrap_or(()); + 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(()); 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 400c217..50c3d62 100644 --- a/shaders/compile.bat +++ b/shaders/compile.bat @@ -9,4 +9,7 @@ C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.geom -o shaders/compiled/geo C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_quad.vert -o shaders/compiled/vert_rt_quad.spv C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_quad.frag -o shaders/compiled/frag_rt_quad.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_compute.comp -o shaders/compiled/rt_compute.spv \ No newline at end of file +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 diff --git a/shaders/compile.sh b/shaders/compile.sh index 1b139d3..8f37a28 100755 --- a/shaders/compile.sh +++ b/shaders/compile.sh @@ -8,4 +8,9 @@ glslc shaders/cuboid.frag -o shaders/compiled/frag_cuboid.spv glslc shaders/cuboid.geom -o shaders/compiled/geo_cuboid.spv glslc shaders/rt_quad.vert -o shaders/compiled/vert_rt_quad.spv -glslc shaders/rt_quad.frag -o shaders/compiled/frag_rt_quad.spv \ No newline at end of file +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 diff --git a/shaders/compiled/rt_compute.spv b/shaders/compiled/rt_compute.spv deleted file mode 100644 index 289f343..0000000 Binary files a/shaders/compiled/rt_compute.spv and /dev/null differ diff --git a/shaders/compiled/rt_compute_grow_one.spv b/shaders/compiled/rt_compute_grow_one.spv new file mode 100644 index 0000000..82ea0be Binary files /dev/null and b/shaders/compiled/rt_compute_grow_one.spv differ diff --git a/shaders/compiled/rt_compute_grow_three.spv b/shaders/compiled/rt_compute_grow_three.spv new file mode 100644 index 0000000..1a326ca Binary files /dev/null and b/shaders/compiled/rt_compute_grow_three.spv differ diff --git a/shaders/compiled/rt_compute_grow_two.spv b/shaders/compiled/rt_compute_grow_two.spv new file mode 100644 index 0000000..136cf1c Binary files /dev/null and b/shaders/compiled/rt_compute_grow_two.spv differ diff --git a/shaders/compiled/rt_compute_rasterize.spv b/shaders/compiled/rt_compute_rasterize.spv new file mode 100644 index 0000000..9ad3d50 Binary files /dev/null and b/shaders/compiled/rt_compute_rasterize.spv differ diff --git a/shaders/rt_compute_grow_one.comp b/shaders/rt_compute_grow_one.comp new file mode 100644 index 0000000..f4161f4 --- /dev/null +++ b/shaders/rt_compute_grow_one.comp @@ -0,0 +1,82 @@ +#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_out[]; +}; + +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]; + 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 y = index % compound_grid_size; + uint z = (index - y) / compound_grid_size; + vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7])); + // iterate upwards along the x axis + bool seen_empty = false; + uint start = 0; + uint last_col = 0; + for (uint x=0; x < compound_grid_size; x++) { + uint color_val = grid_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z]; + bool transparent = transparent_grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z]; + grid_out[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = 0; + // check if we need to stop a volume + if (color_val != 0 && !transparent) { + // check if we are in a volume right now + if (seen_empty) { + // close the current volume + grid_out[output_offset + start * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = x - start; + seen_empty = false; + last_col = 0; + } + } else { + // check if transparency changed + if (seen_empty && transparent && last_col != color_val) { + // if we switch colors close the current volume and prepare for a new one + grid_out[output_offset + start * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = x - start; + seen_empty = false; + } + // start a new volume if we are not in one right now + if (!seen_empty) { + seen_empty = true; + start = x; + last_col = color_val; + } + } + } + if (seen_empty) { + grid_out[output_offset + start * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = compound_grid_size - start; + } +} \ No newline at end of file diff --git a/shaders/rt_compute_grow_three.comp b/shaders/rt_compute_grow_three.comp new file mode 100644 index 0000000..0460631 --- /dev/null +++ b/shaders/rt_compute_grow_three.comp @@ -0,0 +1,101 @@ +#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 = 7) readonly buffer SizeBuffer2D { + uint grid_size_in[]; +}; + +layout(binding = 8) buffer SizeBuffer3D { + uint grid_out[]; +}; + +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 - x) / compound_grid_size; + vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7])); + // iterate upwards along the x axis + bool seen_empty = false; + uint start = 0; + uint start_x_size = 0; + uint start_y_size = 0; + uint last_col = 0; + for (uint z=0; z < compound_grid_size; z++) { + uint color_val = grid_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z]; + bool transparent = transparent_grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z]; + uint current_x_size = grid_size_in[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 2]; + uint current_y_size = grid_size_in[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 2 + 1]; + + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3] = 0; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3 + 1] = 0; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 3 + 2] = 0; + // check if we need to stop a volume + if (color_val != 0 && !transparent) { + // check if we are in a volume right now + if (seen_empty) { + // close the current volume + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3] = start_x_size; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 1] = start_y_size; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 2] = z - start; + seen_empty = false; + last_col = 0; + } + } else { + // check if transparency changed + if (seen_empty && ((transparent && last_col != color_val) || (start_x_size != current_x_size) || (start_y_size != current_y_size))) { + // if we switch colors or size close the current volume and prepare for a new one + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3] = start_x_size; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 1] = start_y_size; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 2] = z - start; + seen_empty = false; + } + // start a new volume if we are not in one right now + if (!seen_empty && current_x_size != 0 && current_y_size != 0) { + seen_empty = true; + start = z; + start_x_size = current_x_size; + start_y_size = current_y_size; + last_col = color_val; + } + } + } + if (seen_empty) { + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3] = start_x_size; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 1] = start_y_size; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + start) * 3 + 2] = compound_grid_size - start; + } +} \ No newline at end of file diff --git a/shaders/rt_compute_grow_two.comp b/shaders/rt_compute_grow_two.comp new file mode 100644 index 0000000..c2ec2f6 --- /dev/null +++ b/shaders/rt_compute_grow_two.comp @@ -0,0 +1,94 @@ +#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 = 7) buffer SizeBuffer2D { + uint grid_out[]; +}; + +layout(binding = 8) readonly 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 z = (index - x) / compound_grid_size; + vec3 compound_pos = vec3(uintBitsToFloat(compounds[compound_start + 5]), uintBitsToFloat(compounds[compound_start + 6]), uintBitsToFloat(compounds[compound_start + 7])); + // iterate upwards along the x axis + bool seen_empty = false; + uint start = 0; + uint start_x_size = 0; + uint last_col = 0; + for (uint y=0; y < compound_grid_size; y++) { + uint color_val = grid_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z]; + bool transparent = transparent_grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z]; + uint current_x_size = grid_size_in[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z]; + + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 2] = 0; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + y * compound_grid_size + z) * 2 + 1] = 0; + // check if we need to stop a volume + if (color_val != 0 && !transparent) { + // check if we are in a volume right now + if (seen_empty) { + // close the current volume + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2] = start_x_size; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2 + 1] = y - start; + seen_empty = false; + last_col = 0; + } + } else { + // check if transparency changed + if (seen_empty && ((transparent && last_col != color_val) || (start_x_size != current_x_size))) { + // if we switch colors or size close the current volume and prepare for a new one + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2] = start_x_size; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2 + 1] = y - start; + seen_empty = false; + } + // start a new volume if we are not in one right now + if (!seen_empty && current_x_size != 0) { + seen_empty = true; + start = y; + start_x_size = current_x_size; + last_col = color_val; + } + } + } + if (seen_empty) { + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2] = start_x_size; + grid_out[output_offset + (x * compound_grid_size * compound_grid_size + start * compound_grid_size + z) * 2 + 1] = compound_grid_size - start; + } +} \ No newline at end of file diff --git a/shaders/rt_compute.comp b/shaders/rt_compute_rasterize.comp similarity index 94% rename from shaders/rt_compute.comp rename to shaders/rt_compute_rasterize.comp index f0ec353..8603805 100644 --- a/shaders/rt_compute.comp +++ b/shaders/rt_compute_rasterize.comp @@ -1,6 +1,5 @@ #version 450 - layout(binding = 0) uniform UniformBufferObject { mat4 model; mat4 geom_rot; @@ -15,7 +14,7 @@ layout(binding = 3) readonly buffer SceneInfoBuffer { }; layout(binding = 4) buffer SceneInfoBuffer2 { - uint volumes[]; + uint grid[]; }; layout(binding = 5) buffer SizedVertices { @@ -26,6 +25,10 @@ layout(binding = 6) buffer Indices { uint indices[]; }; +layout(binding = 9) buffer transparencies { + bool transparent_grid[]; +}; + layout (local_size_x = 16, local_size_y = 1, local_size_z = 1) in; uvec4 unpack_color(uint val) { @@ -190,6 +193,7 @@ void main() { for (uint z=0; z < compound_grid_size; z++) { // iterate over the included shapes vec3 check_pos = compound_pos + vec3(float(x) * compound_scale, float(y) * compound_scale, float(z) * compound_scale) + mid_offset; + uint color_int; uvec4 color_roughness; bool render = false; vec3 color = vec3(0.0, 0.0, 1.0); @@ -214,9 +218,10 @@ void main() { vec3(0.0, 0.0, 1.0) ); - uvec4 component_color = unpack_color(compounds[component_index + 7]); + color_int = compounds[component_index + 7]; + uvec4 component_color = unpack_color(color_int); - uint transparent = compounds[component_index + 8]; + transparent = compounds[component_index + 8] != 0; if (component_type == 0) { // handle sphere @@ -292,8 +297,6 @@ void main() { ); uvec4 color = unpack_color(compounds[component_index + 7]); - uint transparent = compounds[component_index + 8]; - if (component_type == 0) { // handle sphere float radius = uintBitsToFloat(compounds[component_index + 9]); @@ -344,9 +347,12 @@ void main() { } if (render) { + grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = color_int; + transparent_grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = transparent; add_cube(output_offset + index * compound_grid_size + z, compound_scale, check_pos, color); + } else { + grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = 0; + transparent_grid[output_offset + x * compound_grid_size * compound_grid_size + y * compound_grid_size + z] = false; } } - - //volumes[index] = compounds[index]; } \ No newline at end of file diff --git a/src/app_data.rs b/src/app_data.rs index 3bcb10b..6469600 100644 --- a/src/app_data.rs +++ b/src/app_data.rs @@ -23,7 +23,10 @@ pub struct AppData { pub pipeline_cuboid: vk::Pipeline, pub pipeline_quad: vk::Pipeline, - pub pipeline_compute: vk::Pipeline, + pub pipeline_compute_rasterize: vk::Pipeline, + pub pipeline_compute_grow_one: vk::Pipeline, + pub pipeline_compute_grow_two: vk::Pipeline, + pub pipeline_compute_grow_three: vk::Pipeline, pub framebuffers: Vec<vk::Framebuffer>, pub command_pool: vk::CommandPool, @@ -44,8 +47,17 @@ pub struct AppData { pub compute_in_storage_buffers: Vec<vk::Buffer>, pub compute_in_storage_buffers_memory: Vec<vk::DeviceMemory>, - pub compute_out_storage_buffers: Vec<vk::Buffer>, - pub compute_out_storage_buffers_memory: Vec<vk::DeviceMemory>, + pub compute_out_storage_buffers_color: Vec<vk::Buffer>, + pub compute_out_storage_buffers_memory_color: Vec<vk::DeviceMemory>, + + pub compute_out_storage_buffers_transparent: Vec<vk::Buffer>, + pub compute_out_storage_buffers_memory_transparent: Vec<vk::DeviceMemory>, + + pub compute_out_storage_buffers_size_two: Vec<vk::Buffer>, + pub compute_out_storage_buffers_memory_size_two: Vec<vk::DeviceMemory>, + + pub compute_out_storage_buffers_size_three: Vec<vk::Buffer>, + pub compute_out_storage_buffers_memory_size_three: Vec<vk::DeviceMemory>, pub compute_out_cuboid_buffers: Vec<vk::Buffer>, pub compute_out_cuboid_buffers_memory: Vec<vk::DeviceMemory>, diff --git a/src/buffer.rs b/src/buffer.rs index 61ce46d..8374162 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -214,7 +214,7 @@ pub unsafe fn create_descriptor_set_layout( .descriptor_count(1) .stage_flags(vk::ShaderStageFlags::COMPUTE); - let storage_binding_compute_out = vk::DescriptorSetLayoutBinding::builder() + let storage_binding_compute_out_color = vk::DescriptorSetLayoutBinding::builder() .binding(4) .descriptor_type(vk::DescriptorType::STORAGE_BUFFER) .descriptor_count(1) @@ -232,7 +232,25 @@ pub unsafe fn create_descriptor_set_layout( .descriptor_count(1) .stage_flags(vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::COMPUTE); - let bindings = &[ubo_binding, sampler_binding, storage_binding_render, storage_binding_compute_in, storage_binding_compute_out, storage_binding_compute_cuboid_out, storage_binding_compute_cuboid_index_out]; + let storage_binding_compute_out_size_two = vk::DescriptorSetLayoutBinding::builder() + .binding(7) + .descriptor_type(vk::DescriptorType::STORAGE_BUFFER) + .descriptor_count(1) + .stage_flags(vk::ShaderStageFlags::FRAGMENT | vk::ShaderStageFlags::COMPUTE); + + let storage_binding_compute_out_size_three = vk::DescriptorSetLayoutBinding::builder() + .binding(8) + .descriptor_type(vk::DescriptorType::STORAGE_BUFFER) + .descriptor_count(1) + .stage_flags(vk::ShaderStageFlags::FRAGMENT | vk::ShaderStageFlags::COMPUTE); + + let storage_binding_compute_out_size_transparent = vk::DescriptorSetLayoutBinding::builder() + .binding(9) + .descriptor_type(vk::DescriptorType::STORAGE_BUFFER) + .descriptor_count(1) + .stage_flags(vk::ShaderStageFlags::FRAGMENT | vk::ShaderStageFlags::COMPUTE); + + let bindings = &[ubo_binding, sampler_binding, storage_binding_render, storage_binding_compute_in, storage_binding_compute_out_color, storage_binding_compute_cuboid_out, storage_binding_compute_cuboid_index_out, storage_binding_compute_out_size_two, storage_binding_compute_out_size_three, storage_binding_compute_out_size_transparent]; let info = vk::DescriptorSetLayoutCreateInfo::builder() .bindings(bindings); @@ -276,8 +294,16 @@ pub unsafe fn create_storage_buffers( data.compute_in_storage_buffers.clear(); data.compute_in_storage_buffers_memory.clear(); - data.compute_out_storage_buffers.clear(); - data.compute_out_storage_buffers_memory.clear(); + data.compute_out_storage_buffers_color.clear(); + data.compute_out_storage_buffers_memory_color.clear(); + data.compute_out_storage_buffers_transparent.clear(); + data.compute_out_storage_buffers_memory_transparent.clear(); + + data.compute_out_storage_buffers_size_two.clear(); + data.compute_out_storage_buffers_memory_size_two.clear(); + + data.compute_out_storage_buffers_size_three.clear(); + data.compute_out_storage_buffers_memory_size_three.clear(); data.compute_out_cuboid_buffers.clear(); data.compute_out_cuboid_buffers_memory.clear(); @@ -318,8 +344,44 @@ pub unsafe fn create_storage_buffers( vk::MemoryPropertyFlags::DEVICE_LOCAL, )?; - data.compute_out_storage_buffers.push(storage_buffer); - data.compute_out_storage_buffers_memory.push(storage_buffer_memory); + data.compute_out_storage_buffers_color.push(storage_buffer); + data.compute_out_storage_buffers_memory_color.push(storage_buffer_memory); + + let (storage_buffer, storage_buffer_memory) = create_buffer( + instance, + device, + data, + (size_of::<bool>() * 3) as u64 * data.compute_task_one_out_buffer_size.max(1), + vk::BufferUsageFlags::STORAGE_BUFFER, + vk::MemoryPropertyFlags::DEVICE_LOCAL, + )?; + + data.compute_out_storage_buffers_transparent.push(storage_buffer); + data.compute_out_storage_buffers_memory_transparent.push(storage_buffer_memory); + + let (storage_buffer, storage_buffer_memory) = create_buffer( + instance, + device, + data, + (size_of::<u32>() * 2) as u64 * data.compute_task_one_out_buffer_size.max(1), + vk::BufferUsageFlags::STORAGE_BUFFER, + vk::MemoryPropertyFlags::DEVICE_LOCAL, + )?; + + data.compute_out_storage_buffers_size_two.push(storage_buffer); + data.compute_out_storage_buffers_memory_size_two.push(storage_buffer_memory); + + let (storage_buffer, storage_buffer_memory) = create_buffer( + instance, + device, + data, + (size_of::<u32>() * 3) as u64 * data.compute_task_one_out_buffer_size.max(1), + vk::BufferUsageFlags::STORAGE_BUFFER, + vk::MemoryPropertyFlags::DEVICE_LOCAL, + )?; + + data.compute_out_storage_buffers_size_three.push(storage_buffer); + data.compute_out_storage_buffers_memory_size_three.push(storage_buffer_memory); let (storage_buffer, storage_buffer_memory) = create_buffer( instance, @@ -466,7 +528,7 @@ pub unsafe fn create_descriptor_pool(device: &Device, data: &mut app_data::AppDa .type_(vk::DescriptorType::STORAGE_BUFFER) .descriptor_count(data.swapchain_images.len() as u32); - let compute_out_storage_size = vk::DescriptorPoolSize::builder() + let compute_out_storage_color_size = vk::DescriptorPoolSize::builder() .type_(vk::DescriptorType::STORAGE_BUFFER) .descriptor_count(data.swapchain_images.len() as u32); @@ -477,8 +539,20 @@ pub unsafe fn create_descriptor_pool(device: &Device, data: &mut app_data::AppDa let compute_out_cuboid_index_size = vk::DescriptorPoolSize::builder() .type_(vk::DescriptorType::STORAGE_BUFFER) .descriptor_count(data.swapchain_images.len() as u32); + + let compute_out_storage_size_two_size = vk::DescriptorPoolSize::builder() + .type_(vk::DescriptorType::STORAGE_BUFFER) + .descriptor_count(data.swapchain_images.len() as u32); + + let compute_out_storage_size_three_size = vk::DescriptorPoolSize::builder() + .type_(vk::DescriptorType::STORAGE_BUFFER) + .descriptor_count(data.swapchain_images.len() as u32); + + let compute_out_storage_transparent_size = vk::DescriptorPoolSize::builder() + .type_(vk::DescriptorType::STORAGE_BUFFER) + .descriptor_count(data.swapchain_images.len() as u32); - let pool_sizes = &[ubo_size, sampler_size, render_storage_size, compute_in_storage_size, compute_out_storage_size, compute_out_cuboid_size, compute_out_cuboid_index_size]; + let pool_sizes = &[ubo_size, sampler_size, render_storage_size, compute_in_storage_size, compute_out_storage_color_size, compute_out_cuboid_size, compute_out_cuboid_index_size, compute_out_storage_size_two_size, compute_out_storage_size_three_size, compute_out_storage_transparent_size]; let info = vk::DescriptorPoolCreateInfo::builder() .pool_sizes(pool_sizes) .max_sets(data.swapchain_images.len() as u32); @@ -549,18 +623,57 @@ pub unsafe fn create_descriptor_sets(device: &Device, data: &mut app_data::AppDa .buffer_info(storage_info); let info = vk::DescriptorBufferInfo::builder() - .buffer(data.compute_out_storage_buffers[i]) + .buffer(data.compute_out_storage_buffers_color[i]) .offset(0) .range((size_of::<u32>() * 3) as u64 * data.compute_task_one_out_buffer_size.max(1)); let storage_info = &[info]; - let storage_write_compute_out = vk::WriteDescriptorSet::builder() + let storage_write_compute_out_color = vk::WriteDescriptorSet::builder() .dst_set(data.descriptor_sets[i]) .dst_binding(4) .dst_array_element(0) .descriptor_type(vk::DescriptorType::STORAGE_BUFFER) .buffer_info(storage_info); + let info = vk::DescriptorBufferInfo::builder() + .buffer(data.compute_out_storage_buffers_size_two[i]) + .offset(0) + .range((size_of::<u32>() * 2) as u64 * data.compute_task_one_out_buffer_size.max(1)); + let storage_info = &[info]; + + let storage_write_compute_out_size_two = vk::WriteDescriptorSet::builder() + .dst_set(data.descriptor_sets[i]) + .dst_binding(7) + .dst_array_element(0) + .descriptor_type(vk::DescriptorType::STORAGE_BUFFER) + .buffer_info(storage_info); + + let info = vk::DescriptorBufferInfo::builder() + .buffer(data.compute_out_storage_buffers_size_three[i]) + .offset(0) + .range((size_of::<u32>() * 3) as u64 * data.compute_task_one_out_buffer_size.max(1)); + let storage_info = &[info]; + + let storage_write_compute_out_size_three = vk::WriteDescriptorSet::builder() + .dst_set(data.descriptor_sets[i]) + .dst_binding(8) + .dst_array_element(0) + .descriptor_type(vk::DescriptorType::STORAGE_BUFFER) + .buffer_info(storage_info); + + let info = vk::DescriptorBufferInfo::builder() + .buffer(data.compute_out_storage_buffers_transparent[i]) + .offset(0) + .range((size_of::<bool>() * 3) as u64 * data.compute_task_one_out_buffer_size.max(1)); + let storage_info = &[info]; + + let storage_write_compute_out_transparent = vk::WriteDescriptorSet::builder() + .dst_set(data.descriptor_sets[i]) + .dst_binding(9) + .dst_array_element(0) + .descriptor_type(vk::DescriptorType::STORAGE_BUFFER) + .buffer_info(storage_info); + let info = vk::DescriptorBufferInfo::builder() .buffer(data.compute_out_cuboid_buffers[i]) .offset(0) @@ -589,7 +702,7 @@ pub unsafe fn create_descriptor_sets(device: &Device, data: &mut app_data::AppDa device.update_descriptor_sets( - &[ubo_write, sampler_write, storage_write_render, storage_write_compute_in, storage_write_compute_out, storage_write_compute_cuboid_out, storage_write_compute_cuboid_index_out], + &[ubo_write, sampler_write, storage_write_render, storage_write_compute_in, storage_write_compute_out_color, storage_write_compute_cuboid_out, storage_write_compute_cuboid_index_out, storage_write_compute_out_size_two, storage_write_compute_out_size_three, storage_write_compute_out_transparent], &[] as &[vk::CopyDescriptorSet], ); } diff --git a/src/command_buffer.rs b/src/command_buffer.rs index 583f1e9..3a70d1f 100644 --- a/src/command_buffer.rs +++ b/src/command_buffer.rs @@ -60,7 +60,7 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa // define the compute load before going into the render pass if scene_handler.volumetrics.len() != 0 { device.cmd_bind_pipeline( - *command_buffer, vk::PipelineBindPoint::COMPUTE, data.pipeline_compute); //todo build own pipeline + *command_buffer, vk::PipelineBindPoint::COMPUTE, data.pipeline_compute_rasterize); //todo build own pipeline device.cmd_bind_descriptor_sets( *command_buffer, @@ -92,6 +92,114 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa &[] as &[vk::MemoryBarrier], &[buffer_memory_barrier_index, buffer_memory_barrier_vertex], &[] as &[vk::ImageMemoryBarrier]); + + // compute storage barrier + let buffer_memory_barrier_color = vk::BufferMemoryBarrier::builder() + .buffer(data.compute_out_storage_buffers_color[i]) + .src_access_mask(vk::AccessFlags::SHADER_WRITE) + .dst_access_mask(vk::AccessFlags::SHADER_READ) + .size(vk::WHOLE_SIZE as u64) + .build(); + + let buffer_memory_barrier_transparent = vk::BufferMemoryBarrier::builder() + .buffer(data.compute_out_storage_buffers_transparent[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::COMPUTE_SHADER, + vk::DependencyFlags::DEVICE_GROUP, + &[] as &[vk::MemoryBarrier], + &[buffer_memory_barrier_color, buffer_memory_barrier_transparent], + &[] as &[vk::ImageMemoryBarrier]); + // grow x axis + device.cmd_bind_pipeline( + *command_buffer, vk::PipelineBindPoint::COMPUTE, data.pipeline_compute_grow_one); + + 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.compute_out_storage_buffers_size_three[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::COMPUTE_SHADER, + vk::DependencyFlags::DEVICE_GROUP, + &[] as &[vk::MemoryBarrier], + &[buffer_memory_barrier_out], + &[] as &[vk::ImageMemoryBarrier]); + // grow y axis + device.cmd_bind_pipeline( + *command_buffer, vk::PipelineBindPoint::COMPUTE, data.pipeline_compute_grow_two); + + 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.compute_out_storage_buffers_size_two[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::COMPUTE_SHADER, + vk::DependencyFlags::DEVICE_GROUP, + &[] as &[vk::MemoryBarrier], + &[buffer_memory_barrier_out], + &[] as &[vk::ImageMemoryBarrier]); + + // grow z axis + device.cmd_bind_pipeline( + *command_buffer, vk::PipelineBindPoint::COMPUTE, data.pipeline_compute_grow_three); + + 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.compute_out_storage_buffers_size_three[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::COMPUTE_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 71bae1b..64de5c4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -420,10 +420,31 @@ impl App { .iter() .for_each(|m| self.device.free_memory(*m, None)); - self.data.compute_out_storage_buffers + self.data.compute_out_storage_buffers_color .iter() .for_each(|b| self.device.destroy_buffer(*b, None)); - self.data.compute_out_storage_buffers_memory + self.data.compute_out_storage_buffers_memory_color + .iter() + .for_each(|m| self.device.free_memory(*m, None)); + + self.data.compute_out_storage_buffers_transparent + .iter() + .for_each(|b| self.device.destroy_buffer(*b, None)); + self.data.compute_out_storage_buffers_memory_transparent + .iter() + .for_each(|m| self.device.free_memory(*m, None)); + + self.data.compute_out_storage_buffers_size_two + .iter() + .for_each(|b| self.device.destroy_buffer(*b, None)); + self.data.compute_out_storage_buffers_memory_size_two + .iter() + .for_each(|m| self.device.free_memory(*m, None)); + + self.data.compute_out_storage_buffers_size_three + .iter() + .for_each(|b| self.device.destroy_buffer(*b, None)); + self.data.compute_out_storage_buffers_memory_size_three .iter() .for_each(|m| self.device.free_memory(*m, None)); @@ -449,7 +470,10 @@ impl App { self.device.destroy_pipeline(self.data.pipeline_cuboid, None); self.device.destroy_pipeline(self.data.pipeline_quad, None); - self.device.destroy_pipeline(self.data.pipeline_compute, None); + self.device.destroy_pipeline(self.data.pipeline_compute_rasterize, None); + 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_layout(self.data.pipeline_layout, None); self.device.destroy_render_pass(self.data.render_pass, None); @@ -832,13 +856,43 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu // set up compute shader // load the byte data - let compute_bytes = include_bytes!("../shaders/compiled/rt_compute.spv"); + let compute_bytes = include_bytes!("../shaders/compiled/rt_compute_rasterize.spv"); // create the shaders - let compute_shader_module = create_shader_module(device, &compute_bytes[..])?; + let compute_shader_module_rasterize = create_shader_module(device, &compute_bytes[..])?; //create the shader stage for the compute shader - let compute_stage = vk::PipelineShaderStageCreateInfo::builder() + let compute_stage_rasterize = vk::PipelineShaderStageCreateInfo::builder() .stage(vk::ShaderStageFlags::COMPUTE) - .module(compute_shader_module) + .module(compute_shader_module_rasterize) + .name(b"main\0"); + + // load the byte data + let compute_bytes = include_bytes!("../shaders/compiled/rt_compute_grow_one.spv"); + // create the shaders + let compute_shader_module_grow_one = create_shader_module(device, &compute_bytes[..])?; + //create the shader stage for the compute shader + let compute_stage_grow_one = vk::PipelineShaderStageCreateInfo::builder() + .stage(vk::ShaderStageFlags::COMPUTE) + .module(compute_shader_module_grow_one) + .name(b"main\0"); + + // load the byte data + let compute_bytes = include_bytes!("../shaders/compiled/rt_compute_grow_two.spv"); + // create the shaders + let compute_shader_module_grow_two = create_shader_module(device, &compute_bytes[..])?; + //create the shader stage for the compute shader + let compute_stage_grow_two = vk::PipelineShaderStageCreateInfo::builder() + .stage(vk::ShaderStageFlags::COMPUTE) + .module(compute_shader_module_grow_two) + .name(b"main\0"); + + // load the byte data + let compute_bytes = include_bytes!("../shaders/compiled/rt_compute_grow_three.spv"); + // create the shaders + let compute_shader_module_grow_three = create_shader_module(device, &compute_bytes[..])?; + //create the shader stage for the compute shader + let compute_stage_grow_three = vk::PipelineShaderStageCreateInfo::builder() + .stage(vk::ShaderStageFlags::COMPUTE) + .module(compute_shader_module_grow_three) .name(b"main\0"); // define input assembly and object type. This is altered when using geometry shader @@ -981,17 +1035,32 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu // create the pipeline let pipelines = device.create_graphics_pipelines(vk::PipelineCache::null(), &[info_cube, info_cuboid, info_quad], None)?.0; - let info_compute = vk::ComputePipelineCreateInfo::builder() - .stage(compute_stage) + let info_compute_rasterize = vk::ComputePipelineCreateInfo::builder() + .stage(compute_stage_rasterize) .layout(data.pipeline_layout); - let compute_pipelines = device.create_compute_pipelines(vk::PipelineCache::null(), &[info_compute], None)?.0; + let info_compute_grow_one = vk::ComputePipelineCreateInfo::builder() + .stage(compute_stage_grow_one) + .layout(data.pipeline_layout); + + let info_compute_grow_two = vk::ComputePipelineCreateInfo::builder() + .stage(compute_stage_grow_two) + .layout(data.pipeline_layout); + + let info_compute_grow_three = vk::ComputePipelineCreateInfo::builder() + .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; data.pipeline_cube = pipelines[0]; data.pipeline_cuboid = pipelines[1]; data.pipeline_quad = pipelines[2]; - data.pipeline_compute = compute_pipelines[0]; + data.pipeline_compute_rasterize = compute_pipelines[0]; + data.pipeline_compute_grow_one = compute_pipelines[1]; + data.pipeline_compute_grow_two = compute_pipelines[2]; + data.pipeline_compute_grow_three = compute_pipelines[3]; device.destroy_shader_module(vert_shader_module_cube, None); device.destroy_shader_module(geo_shader_module_cube, None); @@ -1004,7 +1073,10 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu device.destroy_shader_module(vert_shader_module_quad, None); device.destroy_shader_module(frag_shader_module_quad, None); - device.destroy_shader_module(compute_shader_module, None); + device.destroy_shader_module(compute_shader_module_rasterize, None); + 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); Ok(()) }