grow compute shaders

This commit is contained in:
zomseffen 2025-04-17 15:47:35 +02:00
parent 62e4062cbf
commit 8902c2a0e3
16 changed files with 648 additions and 56 deletions

View file

@ -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");

View file

@ -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
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

View file

@ -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
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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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];
}

View file

@ -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>,

View file

@ -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],
);
}

View file

@ -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];

View file

@ -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(())
}