compute shader 1 with sized vertice render and pipeline barrier
This commit is contained in:
parent
c02522b6c2
commit
680039cdfa
11 changed files with 814 additions and 313 deletions
624
Cargo.lock
generated
624
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
@ -11,17 +11,244 @@ layout(binding = 0) uniform UniformBufferObject {
|
|||
} ubo;
|
||||
|
||||
layout(binding = 3) readonly buffer SceneInfoBuffer {
|
||||
uint gridsIn[];
|
||||
uint compounds[];
|
||||
};
|
||||
|
||||
layout(binding = 4) buffer SceneInfoBuffer2 {
|
||||
uint volumes[];
|
||||
};
|
||||
|
||||
layout(binding = 5) buffer SizedVertices {
|
||||
float vertices[];
|
||||
};
|
||||
|
||||
layout(binding = 6) buffer Indices {
|
||||
uint indices[];
|
||||
};
|
||||
|
||||
layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
|
||||
|
||||
void main() {
|
||||
uint index = gl_GlobalInvocationID.x;
|
||||
uvec4 unpack_color(uint val) {
|
||||
// left most 8 bits first
|
||||
uint val1 = (val >> 24);
|
||||
uint val2 = (val << 8) >> 24;
|
||||
uint val3 = (val << 16) >> 24;
|
||||
uint val4 = (val << 24) >> 24;
|
||||
|
||||
volumes[index] = gridsIn[index];
|
||||
return uvec4(val4, val3, val2, val1);
|
||||
}
|
||||
|
||||
void add_cube(uint cube_num, float scale, vec3 pos, vec3 color) {
|
||||
// add node info for the cube
|
||||
//vertice 0
|
||||
vertices[(cube_num * 8 + 0) * 11 + 0] = pos.x - 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 0) * 11 + 1] = pos.y + 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 0) * 11 + 2] = pos.z + 0.5 * scale;
|
||||
|
||||
vertices[(cube_num * 8 + 0) * 11 + 3] = color.x;
|
||||
vertices[(cube_num * 8 + 0) * 11 + 4] = color.y;
|
||||
vertices[(cube_num * 8 + 0) * 11 + 5] = color.z;
|
||||
|
||||
//vertice 1
|
||||
vertices[(cube_num * 8 + 1) * 11 + 0] = pos.x + 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 1) * 11 + 1] = pos.y + 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 1) * 11 + 2] = pos.z + 0.5 * scale;
|
||||
|
||||
vertices[(cube_num * 8 + 1) * 11 + 3] = color.x;
|
||||
vertices[(cube_num * 8 + 1) * 11 + 4] = color.y;
|
||||
vertices[(cube_num * 8 + 1) * 11 + 5] = color.z;
|
||||
|
||||
//vertice 2
|
||||
vertices[(cube_num * 8 + 2) * 11 + 0] = pos.x - 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 2) * 11 + 1] = pos.y - 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 2) * 11 + 2] = pos.z + 0.5 * scale;
|
||||
|
||||
vertices[(cube_num * 8 + 2) * 11 + 3] = color.x;
|
||||
vertices[(cube_num * 8 + 2) * 11 + 4] = color.y;
|
||||
vertices[(cube_num * 8 + 2) * 11 + 5] = color.z;
|
||||
|
||||
//vertice 3
|
||||
vertices[(cube_num * 8 + 3) * 11 + 0] = pos.x + 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 3) * 11 + 1] = pos.y - 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 3) * 11 + 2] = pos.z + 0.5 * scale;
|
||||
|
||||
vertices[(cube_num * 8 + 3) * 11 + 3] = color.x;
|
||||
vertices[(cube_num * 8 + 3) * 11 + 4] = color.y;
|
||||
vertices[(cube_num * 8 + 3) * 11 + 5] = color.z;
|
||||
|
||||
//vertice 4
|
||||
vertices[(cube_num * 8 + 4) * 11 + 0] = pos.x - 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 4) * 11 + 1] = pos.y + 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 4) * 11 + 2] = pos.z - 0.5 * scale;
|
||||
|
||||
vertices[(cube_num * 8 + 4) * 11 + 3] = color.x;
|
||||
vertices[(cube_num * 8 + 4) * 11 + 4] = color.y;
|
||||
vertices[(cube_num * 8 + 4) * 11 + 5] = color.z;
|
||||
|
||||
//vertice 5
|
||||
vertices[(cube_num * 8 + 5) * 11 + 0] = pos.x + 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 5) * 11 + 1] = pos.y + 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 5) * 11 + 2] = pos.z - 0.5 * scale;
|
||||
|
||||
vertices[(cube_num * 8 + 5) * 11 + 3] = color.x;
|
||||
vertices[(cube_num * 8 + 5) * 11 + 4] = color.y;
|
||||
vertices[(cube_num * 8 + 5) * 11 + 5] = color.z;
|
||||
|
||||
//vertice 6
|
||||
vertices[(cube_num * 8 + 6) * 11 + 0] = pos.x - 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 6) * 11 + 1] = pos.y - 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 6) * 11 + 2] = pos.z - 0.5 * scale;
|
||||
|
||||
vertices[(cube_num * 8 + 6) * 11 + 3] = color.x;
|
||||
vertices[(cube_num * 8 + 6) * 11 + 4] = color.y;
|
||||
vertices[(cube_num * 8 + 6) * 11 + 5] = color.z;
|
||||
|
||||
//vertice 7
|
||||
vertices[(cube_num * 8 + 7) * 11 + 0] = pos.x + 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 7) * 11 + 1] = pos.y - 0.5 * scale;
|
||||
vertices[(cube_num * 8 + 7) * 11 + 2] = pos.z - 0.5 * scale;
|
||||
|
||||
vertices[(cube_num * 8 + 7) * 11 + 3] = color.x;
|
||||
vertices[(cube_num * 8 + 7) * 11 + 4] = color.y;
|
||||
vertices[(cube_num * 8 + 7) * 11 + 5] = color.z;
|
||||
|
||||
//add indices for the cube
|
||||
//top
|
||||
indices[cube_num * 36 + 0] = cube_num * 8 + 3;
|
||||
indices[cube_num * 36 + 1] = cube_num * 8 + 0;
|
||||
indices[cube_num * 36 + 2] = cube_num * 8 + 2;
|
||||
|
||||
indices[cube_num * 36 + 3] = cube_num * 8 + 3;
|
||||
indices[cube_num * 36 + 4] = cube_num * 8 + 1;
|
||||
indices[cube_num * 36 + 5] = cube_num * 8 + 0;
|
||||
|
||||
//bottom
|
||||
indices[cube_num * 36 + 6] = cube_num * 8 + 6;
|
||||
indices[cube_num * 36 + 7] = cube_num * 8 + 4;
|
||||
indices[cube_num * 36 + 8] = cube_num * 8 + 7;
|
||||
|
||||
indices[cube_num * 36 + 9] = cube_num * 8 + 4;
|
||||
indices[cube_num * 36 + 10] = cube_num * 8 + 5;
|
||||
indices[cube_num * 36 + 11] = cube_num * 8 + 7;
|
||||
|
||||
//left
|
||||
indices[cube_num * 36 + 12] = cube_num * 8 + 0;
|
||||
indices[cube_num * 36 + 13] = cube_num * 8 + 4;
|
||||
indices[cube_num * 36 + 14] = cube_num * 8 + 2;
|
||||
|
||||
indices[cube_num * 36 + 15] = cube_num * 8 + 6;
|
||||
indices[cube_num * 36 + 16] = cube_num * 8 + 2;
|
||||
indices[cube_num * 36 + 17] = cube_num * 8 + 4;
|
||||
|
||||
//right
|
||||
indices[cube_num * 36 + 18] = cube_num * 8 + 1;
|
||||
indices[cube_num * 36 + 19] = cube_num * 8 + 3;
|
||||
indices[cube_num * 36 + 20] = cube_num * 8 + 5;
|
||||
|
||||
indices[cube_num * 36 + 21] = cube_num * 8 + 5;
|
||||
indices[cube_num * 36 + 22] = cube_num * 8 + 3;
|
||||
indices[cube_num * 36 + 23] = cube_num * 8 + 7;
|
||||
|
||||
//near
|
||||
indices[cube_num * 36 + 24] = cube_num * 8 + 6;
|
||||
indices[cube_num * 36 + 25] = cube_num * 8 + 3;
|
||||
indices[cube_num * 36 + 26] = cube_num * 8 + 2;
|
||||
|
||||
indices[cube_num * 36 + 27] = cube_num * 8 + 3;
|
||||
indices[cube_num * 36 + 28] = cube_num * 8 + 6;
|
||||
indices[cube_num * 36 + 29] = cube_num * 8 + 7;
|
||||
|
||||
//far
|
||||
indices[cube_num * 36 + 30] = cube_num * 8 + 0;
|
||||
indices[cube_num * 36 + 31] = cube_num * 8 + 1;
|
||||
indices[cube_num * 36 + 32] = cube_num * 8 + 4;
|
||||
|
||||
indices[cube_num * 36 + 33] = cube_num * 8 + 5;
|
||||
indices[cube_num * 36 + 34] = cube_num * 8 + 4;
|
||||
indices[cube_num * 36 + 35] = cube_num * 8 + 1;
|
||||
|
||||
}
|
||||
|
||||
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]) {
|
||||
compound_start = compounds[compound_start + 2];
|
||||
index -= compounds[compound_start] * compounds[compound_start];
|
||||
output_offset += compounds[compound_start] * compounds[compound_start] * compounds[compound_start];
|
||||
}
|
||||
// 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 x = (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 z axis
|
||||
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;
|
||||
uvec4 color_roughness;
|
||||
bool render = false;
|
||||
vec3 color = vec3(0.0, 0.0, 1.0);
|
||||
bool transparent = false;
|
||||
//handle included shapes
|
||||
for (uint o=0; o < compounds[compound_start + 3]; o++) {
|
||||
uint component_index = compounds[compound_start + 9 + o];
|
||||
uint component_type = compounds[component_index];
|
||||
vec3 component_pos = vec3(uintBitsToFloat(compounds[component_index + 1]), uintBitsToFloat(compounds[component_index + 2]), uintBitsToFloat(compounds[component_index + 3]));
|
||||
vec3 component_rot = vec3(uintBitsToFloat(compounds[component_index + 4]), uintBitsToFloat(compounds[component_index + 5]), uintBitsToFloat(compounds[component_index + 6]));
|
||||
|
||||
uvec4 component_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]);
|
||||
|
||||
render = length(component_pos - check_pos) <= radius;
|
||||
if (render) {
|
||||
color = vec3(float(component_color.x) / 255.0, float(component_color.y) / 255.0, float(component_color.z) / 255.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//handle excluded shapes
|
||||
for (uint o=0; o < compounds[compound_start + 4]; o++) {
|
||||
uint component_index = compounds[compound_start + 9 + compounds[compound_start + 3] + o];
|
||||
uint component_type = compounds[component_index];
|
||||
vec3 component_pos = vec3(uintBitsToFloat(compounds[component_index + 1]), uintBitsToFloat(compounds[component_index + 2]), uintBitsToFloat(compounds[component_index + 3]));
|
||||
vec3 component_rot = vec3(uintBitsToFloat(compounds[component_index + 4]), uintBitsToFloat(compounds[component_index + 5]), uintBitsToFloat(compounds[component_index + 6]));
|
||||
|
||||
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]);
|
||||
|
||||
render = render && !(length(component_pos - check_pos) <= radius);
|
||||
if (!render) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (render) {
|
||||
add_cube(index * compound_grid_size + z, compound_scale, check_pos, color);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//add_cube(0, compound_scale, compound_pos + mid_offset, vec3(1.0, 0.0, 0.0));
|
||||
//add_cube(1, compound_scale, compound_pos + vec3(float(compound_grid_size) * compound_scale, float(compound_grid_size) * compound_scale, float(compound_grid_size) * compound_scale) + mid_offset, vec3(1.0, 0.0, 0.0));
|
||||
|
||||
volumes[index] = compounds[index];
|
||||
}
|
|
@ -47,6 +47,12 @@ pub struct AppData {
|
|||
pub compute_out_storage_buffers: Vec<vk::Buffer>,
|
||||
pub compute_out_storage_buffers_memory: Vec<vk::DeviceMemory>,
|
||||
|
||||
pub compute_out_cuboid_buffers: Vec<vk::Buffer>,
|
||||
pub compute_out_cuboid_buffers_memory: Vec<vk::DeviceMemory>,
|
||||
|
||||
pub compute_out_cuboid_index_buffers: Vec<vk::Buffer>,
|
||||
pub compute_out_cuboid_index_buffers_memory: Vec<vk::DeviceMemory>,
|
||||
|
||||
pub descriptor_pool: vk::DescriptorPool,
|
||||
pub descriptor_sets: Vec<vk::DescriptorSet>,
|
||||
|
||||
|
@ -71,6 +77,8 @@ pub struct AppData {
|
|||
pub scene_rt_memory_size: u64,
|
||||
pub scene_rt_volumetric_size: u64,
|
||||
pub compute_task_one_size: usize,
|
||||
pub compute_task_one_out_buffer_size: u64,
|
||||
pub compute_task_one_out_size: u64,
|
||||
// values passed to shader
|
||||
pub num_lights_per_volume: u32,
|
||||
pub min_light_weight: f32,
|
||||
|
|
127
src/buffer.rs
127
src/buffer.rs
|
@ -10,6 +10,8 @@ pub type Mat4 = cgmath::Matrix4<f32>;
|
|||
|
||||
use crate::app_data;
|
||||
use crate::command_buffer;
|
||||
use crate::primitives;
|
||||
use crate::vertex;
|
||||
use crate::vertex::VertexContainer;
|
||||
use crate::scene;
|
||||
|
||||
|
@ -218,7 +220,19 @@ pub unsafe fn create_descriptor_set_layout(
|
|||
.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];
|
||||
let storage_binding_compute_cuboid_out = vk::DescriptorSetLayoutBinding::builder()
|
||||
.binding(5)
|
||||
.descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
|
||||
.descriptor_count(1)
|
||||
.stage_flags(vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::COMPUTE);
|
||||
|
||||
let storage_binding_compute_cuboid_index_out = vk::DescriptorSetLayoutBinding::builder()
|
||||
.binding(6)
|
||||
.descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
|
||||
.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 info = vk::DescriptorSetLayoutCreateInfo::builder()
|
||||
.bindings(bindings);
|
||||
|
||||
|
@ -265,6 +279,12 @@ pub unsafe fn create_storage_buffers(
|
|||
data.compute_out_storage_buffers.clear();
|
||||
data.compute_out_storage_buffers_memory.clear();
|
||||
|
||||
data.compute_out_cuboid_buffers.clear();
|
||||
data.compute_out_cuboid_buffers_memory.clear();
|
||||
|
||||
data.compute_out_cuboid_index_buffers.clear();
|
||||
data.compute_out_cuboid_index_buffers_memory.clear();
|
||||
|
||||
for _ in 0..data.swapchain_images.len() {
|
||||
let (storage_buffer, storage_buffer_memory) = create_buffer(
|
||||
instance,
|
||||
|
@ -293,13 +313,37 @@ pub unsafe fn create_storage_buffers(
|
|||
instance,
|
||||
device,
|
||||
data,
|
||||
data.scene_rt_memory_size.max(1),
|
||||
vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::STORAGE_BUFFER,
|
||||
data.compute_task_one_out_buffer_size.max(1),
|
||||
vk::BufferUsageFlags::STORAGE_BUFFER,
|
||||
vk::MemoryPropertyFlags::DEVICE_LOCAL,
|
||||
)?;
|
||||
|
||||
data.compute_out_storage_buffers.push(storage_buffer);
|
||||
data.compute_out_storage_buffers_memory.push(storage_buffer_memory);
|
||||
|
||||
let (storage_buffer, storage_buffer_memory) = create_buffer(
|
||||
instance,
|
||||
device,
|
||||
data,
|
||||
(size_of::<vertex::SizedVertex>() * 8) as u64 * data.compute_task_one_out_size,
|
||||
vk::BufferUsageFlags::STORAGE_BUFFER | vk::BufferUsageFlags::VERTEX_BUFFER,
|
||||
vk::MemoryPropertyFlags::DEVICE_LOCAL,
|
||||
)?;
|
||||
|
||||
data.compute_out_cuboid_buffers.push(storage_buffer);
|
||||
data.compute_out_cuboid_buffers_memory.push(storage_buffer_memory);
|
||||
|
||||
let (storage_buffer, storage_buffer_memory) = create_buffer(
|
||||
instance,
|
||||
device,
|
||||
data,
|
||||
(size_of::<u32>() * 36) as u64 * data.compute_task_one_out_size,
|
||||
vk::BufferUsageFlags::STORAGE_BUFFER | vk::BufferUsageFlags::INDEX_BUFFER,
|
||||
vk::MemoryPropertyFlags::DEVICE_LOCAL,
|
||||
)?;
|
||||
|
||||
data.compute_out_cuboid_index_buffers.push(storage_buffer);
|
||||
data.compute_out_cuboid_index_buffers_memory.push(storage_buffer_memory);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -368,6 +412,43 @@ pub unsafe fn update_render_storage_buffer(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub unsafe fn update_compute_storage_buffer(
|
||||
instance: &Instance,
|
||||
device: &Device,
|
||||
data: &app_data::AppData,
|
||||
image_index: usize,
|
||||
scene_handler: &scene::Scene,
|
||||
) -> Result<()> {
|
||||
// rt compute buffer
|
||||
if scene_handler.volumetrics.len() > 0 {
|
||||
let (staging_buffer, staging_buffer_memory) = create_buffer(
|
||||
instance,
|
||||
device,
|
||||
data,
|
||||
data.scene_rt_volumetric_size,
|
||||
vk::BufferUsageFlags::TRANSFER_SRC,
|
||||
vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE,
|
||||
)?;
|
||||
|
||||
let memory = device.map_memory(
|
||||
staging_buffer_memory,
|
||||
0,
|
||||
data.scene_rt_volumetric_size,
|
||||
vk::MemoryMapFlags::empty(),
|
||||
)?;
|
||||
|
||||
memcpy(scene_handler.volumetrics_memory.as_ptr(), memory.cast(), scene_handler.volumetrics_memory.len());
|
||||
|
||||
device.unmap_memory(staging_buffer_memory);
|
||||
|
||||
copy_buffer(device, data, staging_buffer, data.compute_in_storage_buffers[image_index], data.scene_rt_volumetric_size)?;
|
||||
|
||||
device.destroy_buffer(staging_buffer, None);
|
||||
device.free_memory(staging_buffer_memory, None);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub unsafe fn create_descriptor_pool(device: &Device, data: &mut app_data::AppData) -> Result<()> {
|
||||
let ubo_size = vk::DescriptorPoolSize::builder()
|
||||
.type_(vk::DescriptorType::UNIFORM_BUFFER)
|
||||
|
@ -388,8 +469,16 @@ pub unsafe fn create_descriptor_pool(device: &Device, data: &mut app_data::AppDa
|
|||
let compute_out_storage_size = vk::DescriptorPoolSize::builder()
|
||||
.type_(vk::DescriptorType::STORAGE_BUFFER)
|
||||
.descriptor_count(data.swapchain_images.len() as u32);
|
||||
|
||||
let compute_out_cuboid_size = vk::DescriptorPoolSize::builder()
|
||||
.type_(vk::DescriptorType::STORAGE_BUFFER)
|
||||
.descriptor_count(data.swapchain_images.len() as u32);
|
||||
|
||||
let compute_out_cuboid_index_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];
|
||||
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 info = vk::DescriptorPoolCreateInfo::builder()
|
||||
.pool_sizes(pool_sizes)
|
||||
.max_sets(data.swapchain_images.len() as u32);
|
||||
|
@ -462,7 +551,7 @@ pub unsafe fn create_descriptor_sets(device: &Device, data: &mut app_data::AppDa
|
|||
let info = vk::DescriptorBufferInfo::builder()
|
||||
.buffer(data.compute_out_storage_buffers[i])
|
||||
.offset(0)
|
||||
.range(data.scene_rt_memory_size);
|
||||
.range(data.compute_task_one_out_buffer_size);
|
||||
let storage_info = &[info];
|
||||
|
||||
let storage_write_compute_out = vk::WriteDescriptorSet::builder()
|
||||
|
@ -471,10 +560,36 @@ pub unsafe fn create_descriptor_sets(device: &Device, data: &mut app_data::AppDa
|
|||
.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)
|
||||
.range((size_of::<vertex::SizedVertex>() * 8) as u64 * data.compute_task_one_out_size);
|
||||
let storage_info = &[info];
|
||||
|
||||
let storage_write_compute_cuboid_out = vk::WriteDescriptorSet::builder()
|
||||
.dst_set(data.descriptor_sets[i])
|
||||
.dst_binding(5)
|
||||
.dst_array_element(0)
|
||||
.descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
|
||||
.buffer_info(storage_info);
|
||||
|
||||
let info = vk::DescriptorBufferInfo::builder()
|
||||
.buffer(data.compute_out_cuboid_index_buffers[i])
|
||||
.offset(0)
|
||||
.range((size_of::<u32>() * 36) as u64 * data.compute_task_one_out_size);
|
||||
let storage_info = &[info];
|
||||
|
||||
let storage_write_compute_cuboid_index_out = vk::WriteDescriptorSet::builder()
|
||||
.dst_set(data.descriptor_sets[i])
|
||||
.dst_binding(6)
|
||||
.dst_array_element(0)
|
||||
.descriptor_type(vk::DescriptorType::STORAGE_BUFFER)
|
||||
.buffer_info(storage_info);
|
||||
|
||||
|
||||
device.update_descriptor_sets(
|
||||
&[ubo_write, sampler_write, storage_write_render, storage_write_compute_in, storage_write_compute_out],
|
||||
&[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],
|
||||
&[] as &[vk::CopyDescriptorSet],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -69,8 +69,29 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
|
|||
0,
|
||||
&[data.descriptor_sets[i]],
|
||||
&[]);
|
||||
|
||||
|
||||
device.cmd_dispatch(*command_buffer, (data.compute_task_one_size as f64 / 256.0).ceil() as u32, 1, 1);
|
||||
|
||||
let buffer_memory_barrier_vertex = vk::BufferMemoryBarrier::builder()
|
||||
.buffer(data.compute_out_cuboid_buffers[i])
|
||||
.src_access_mask(vk::AccessFlags::SHADER_READ | vk::AccessFlags::SHADER_WRITE)
|
||||
.dst_access_mask(vk::AccessFlags::VERTEX_ATTRIBUTE_READ)
|
||||
.size(vk::WHOLE_SIZE as u64)
|
||||
.build();
|
||||
let buffer_memory_barrier_index = vk::BufferMemoryBarrier::builder()
|
||||
.buffer(data.compute_out_cuboid_index_buffers[i])
|
||||
.src_access_mask(vk::AccessFlags::SHADER_READ | vk::AccessFlags::SHADER_WRITE)
|
||||
.dst_access_mask(vk::AccessFlags::INDEX_READ)
|
||||
.size(vk::WHOLE_SIZE as u64)
|
||||
.build();
|
||||
|
||||
device.cmd_pipeline_barrier(*command_buffer,
|
||||
vk::PipelineStageFlags::COMPUTE_SHADER,
|
||||
vk::PipelineStageFlags::VERTEX_INPUT,
|
||||
vk::DependencyFlags::DEVICE_GROUP,
|
||||
&[] as &[vk::MemoryBarrier],
|
||||
&[buffer_memory_barrier_index, buffer_memory_barrier_vertex],
|
||||
&[] as &[vk::ImageMemoryBarrier]);
|
||||
}
|
||||
// start render pass
|
||||
let clear_values = &[color_clear_value, depth_clear_value];
|
||||
|
@ -122,6 +143,26 @@ pub unsafe fn create_command_buffers(device: &Device, data: &mut app_data::AppDa
|
|||
|
||||
device.cmd_draw_indexed(*command_buffer, scene_handler.indices_cuboid.len() as u32, 1, 0, 0, 0);
|
||||
}
|
||||
// draw sized vertices from compute shader
|
||||
if scene_handler.volumetrics.len() != 0 {
|
||||
device.cmd_bind_pipeline(
|
||||
*command_buffer, vk::PipelineBindPoint::GRAPHICS, data.pipeline_cuboid);
|
||||
|
||||
device.cmd_bind_vertex_buffers(*command_buffer, 0, &[data.compute_out_cuboid_buffers[i]], &[0]);
|
||||
device.cmd_bind_index_buffer(*command_buffer, data.compute_out_cuboid_index_buffers[i], 0, vk::IndexType::UINT32);
|
||||
|
||||
|
||||
device.cmd_bind_descriptor_sets(
|
||||
*command_buffer,
|
||||
vk::PipelineBindPoint::GRAPHICS,
|
||||
data.pipeline_layout,
|
||||
0,
|
||||
&[data.descriptor_sets[i]],
|
||||
&[],
|
||||
);
|
||||
|
||||
device.cmd_draw_indexed(*command_buffer, (data.compute_task_one_out_size * 36) as u32, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
if scene_handler.rt_vertices.len() != 0 {
|
||||
device.cmd_bind_pipeline(
|
||||
|
|
18
src/main.rs
18
src/main.rs
|
@ -57,7 +57,8 @@ const VALIDATION_ENABLED: bool =
|
|||
const VALIDATION_LAYER: vk::ExtensionName =
|
||||
vk::ExtensionName::from_bytes(b"VK_LAYER_KHRONOS_validation");
|
||||
const DEVICE_EXTENSIONS: &[vk::ExtensionName] = &[
|
||||
vk::KHR_SWAPCHAIN_EXTENSION.name
|
||||
vk::KHR_SWAPCHAIN_EXTENSION.name,
|
||||
vk::EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION.name,
|
||||
];
|
||||
|
||||
const MAX_FRAMES_IN_FLIGHT: usize = 30;
|
||||
|
@ -288,6 +289,7 @@ impl App {
|
|||
self.scene_handler.update_memory(&mut self.data, true)
|
||||
}
|
||||
buffer::update_render_storage_buffer(&self.instance, &self.device, &self.data, image_index, &self.scene_handler)?;
|
||||
buffer::update_compute_storage_buffer(&self.instance, &self.device, &self.data, image_index, &self.scene_handler)?;
|
||||
self.synchronized += 1
|
||||
}
|
||||
|
||||
|
@ -424,6 +426,20 @@ impl App {
|
|||
self.data.compute_out_storage_buffers_memory
|
||||
.iter()
|
||||
.for_each(|m| self.device.free_memory(*m, None));
|
||||
|
||||
self.data.compute_out_cuboid_buffers
|
||||
.iter()
|
||||
.for_each(|b| self.device.destroy_buffer(*b, None));
|
||||
self.data.compute_out_cuboid_buffers_memory
|
||||
.iter()
|
||||
.for_each(|m| self.device.free_memory(*m, None));
|
||||
|
||||
self.data.compute_out_cuboid_index_buffers
|
||||
.iter()
|
||||
.for_each(|b| self.device.destroy_buffer(*b, None));
|
||||
self.data.compute_out_cuboid_index_buffers_memory
|
||||
.iter()
|
||||
.for_each(|m| self.device.free_memory(*m, None));
|
||||
|
||||
self.data.framebuffers
|
||||
.iter()
|
||||
|
|
|
@ -115,7 +115,7 @@ impl EmptyVolume {
|
|||
// abort if it is already covered
|
||||
continue;
|
||||
}
|
||||
println!("new starting pos: {}, {}, {}", x_index, y_index, z_index);
|
||||
//println!("new starting pos: {}, {}, {}", x_index, y_index, z_index);
|
||||
// MARK: Start new Volume
|
||||
let mut x_size = 0;
|
||||
let mut y_size = 0;
|
||||
|
@ -127,9 +127,9 @@ impl EmptyVolume {
|
|||
x_size = query_result.1 - 1 - (x_index - query_result.2.0);
|
||||
y_size = query_result.1 - 1 - (y_index - query_result.2.1);
|
||||
z_size = query_result.1 - 1 - (z_index - query_result.2.2);
|
||||
println!("enhanced starting size: {}, {}, {}", x_size+1, y_size+1, z_size+1);
|
||||
//println!("enhanced starting size: {}, {}, {}", x_size+1, y_size+1, z_size+1);
|
||||
}
|
||||
println!("start growing volume x");
|
||||
//println!("start growing volume x");
|
||||
let mut grow = true;
|
||||
while grow {
|
||||
grow &= (x_index + x_size + 1) < tree.borrow().size;
|
||||
|
@ -179,7 +179,7 @@ impl EmptyVolume {
|
|||
x_size += 1;
|
||||
}
|
||||
}
|
||||
println!("start growing volume y");
|
||||
//println!("start growing volume y");
|
||||
grow = true;
|
||||
while grow {
|
||||
grow &= (y_index + y_size + 1) < tree.borrow().size;
|
||||
|
@ -230,7 +230,7 @@ impl EmptyVolume {
|
|||
y_size += 1;
|
||||
}
|
||||
}
|
||||
println!("start growing volume z");
|
||||
//println!("start growing volume z");
|
||||
grow = true;
|
||||
while grow {
|
||||
grow &= (z_index + z_size + 1) < tree.borrow().size;
|
||||
|
@ -280,7 +280,7 @@ impl EmptyVolume {
|
|||
z_size += 1;
|
||||
}
|
||||
}
|
||||
println!("final size: {}, {}, {}", x_size+1, y_size+1, z_size+1);
|
||||
//println!("final size: {}, {}, {}", x_size+1, y_size+1, z_size+1);
|
||||
// create new empty volume
|
||||
let new_volume = EmptyVolume {
|
||||
memory_start: 0,
|
||||
|
@ -311,7 +311,7 @@ impl EmptyVolume {
|
|||
old_memory_size: 0,
|
||||
dirty: true,
|
||||
};
|
||||
println!("adding neighbor references");
|
||||
//println!("adding neighbor references");
|
||||
// MARK: fill in info in the neighbor octtree
|
||||
let reference = Rc::new(RefCell::new(new_volume));
|
||||
for x in 0..x_size+1 {
|
||||
|
@ -325,7 +325,7 @@ impl EmptyVolume {
|
|||
}
|
||||
}
|
||||
}
|
||||
println!("add the border information for color and roughness");
|
||||
//println!("add the border information for color and roughness");
|
||||
let x_min_pos;
|
||||
if reference.borrow().grid_position.x == 0 {
|
||||
// will result in an empty color and roughness map.
|
||||
|
@ -514,7 +514,7 @@ impl EmptyVolume {
|
|||
reference.borrow_mut().roughness_right= vec![];
|
||||
}
|
||||
|
||||
println!("new volume done");
|
||||
//println!("new volume done");
|
||||
//push to the list
|
||||
volumes.push(reference);
|
||||
}
|
||||
|
@ -525,7 +525,7 @@ impl EmptyVolume {
|
|||
x_index += 1;
|
||||
}
|
||||
println!("Did {} oct tree checks!", check_its);
|
||||
println!("add the neighbor linkage for all the volumes of the oct tree");
|
||||
//println!("add the neighbor linkage for all the volumes of the oct tree");
|
||||
// MARK: Neighbor Linkage
|
||||
for reference in volumes.iter_mut() {
|
||||
let x_min_pos;
|
||||
|
|
|
@ -119,7 +119,9 @@ pub fn generate_test_scene(scene: &mut Scene, data: &mut AppData) -> Result<(Poi
|
|||
scene.oct_trees = vec![vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]], vec![vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_one.clone(), tree_ref_two.clone()], vec![tree_ref_two.clone(), tree_ref_two.clone(), tree_ref_two.clone()]]];
|
||||
|
||||
let mut comp = ShapeComposition::new(64);
|
||||
comp.included_shapes.push(Rc::new(RefCell::new(Sphere::new(Vector3 { x: 5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 2.5, Vector3 { x: 255, y: 0, z: 0 }, 64))));
|
||||
comp.included_shapes.push(Rc::new(RefCell::new(Sphere::new(Vector3 { x: 5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 2.0, Vector3 { x: 0, y: 255, z: 0 }, 64, false))));
|
||||
comp.included_shapes.push(Rc::new(RefCell::new(Sphere::new(Vector3 { x: 5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 10.0 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 2.5, Vector3 { x: 255, y: 0, z: 0 }, 64, false))));
|
||||
comp.excluded_shapes.push(Rc::new(RefCell::new(Sphere::new(Vector3 { x: 5.0 + grid_size as f32, y: 5.0 + grid_size as f32, z: 11.5 }, Vector3 { x: 0.0, y: 0.0, z: 0.0 }, 1.5, Vector3 { x: 0, y: 255, z: 0 }, 64, false))));
|
||||
scene.volumetrics.push(Rc::new(RefCell::new(comp)));
|
||||
|
||||
Ok((cgmath::point3(5.0, 5.0, 10.0)))
|
||||
|
|
|
@ -226,15 +226,18 @@ impl Scene {
|
|||
let mut volumetrics_memory = vec![0; data_len];
|
||||
|
||||
let mut compute_task_one_size = 0;
|
||||
let mut compute_task_one_out_size = 0;
|
||||
for compound in &self.volumetrics {
|
||||
volumetrics_memory = compound.borrow_mut().insert_into_memory(volumetrics_memory, data, &self);
|
||||
compute_task_one_size += compound.borrow().size.pow(2) as usize;
|
||||
compute_task_one_out_size += compound.borrow().size.pow(3) as usize;
|
||||
}
|
||||
|
||||
self.volumetrics_memory = volumetrics_memory;
|
||||
data.scene_rt_volumetric_size = (self.volumetrics_memory.len() * 4) as u64; // size of the needed buffer size in bytes
|
||||
data.compute_task_one_size = compute_task_one_size;
|
||||
|
||||
data.compute_task_one_out_buffer_size = (compute_task_one_out_size * 4) as u64;
|
||||
data.compute_task_one_out_size = compute_task_one_out_size as u64;
|
||||
}
|
||||
|
||||
pub unsafe fn destroy(&mut self, device: &vulkanalia::Device) {
|
||||
|
|
|
@ -15,6 +15,9 @@ pub trait Volumetrics: Memorizable {
|
|||
fn set_rot(&mut self, p: Vector3<f32>);
|
||||
|
||||
fn get_bbox(&self) -> (Vector3<f32>,Vector3<f32>);
|
||||
|
||||
fn is_transparent(&self) -> bool;
|
||||
fn set_transparency(&mut self, transparent: bool);
|
||||
}
|
||||
|
||||
enum ShapeTypes {
|
||||
|
@ -54,8 +57,8 @@ impl CompoundMemorizable for ShapeComposition {
|
|||
|
||||
impl Memorizable for ShapeComposition {
|
||||
fn get_buffer_mem_size(&self, data: &AppData) -> u32 {
|
||||
//size, scale, memory_end, num_included, num_excluded, pos, included_address, excluded_address
|
||||
1 + 1 + 1 + 1 + 1 + 3 + self.included_shapes.len() as u32 + self.excluded_shapes.len() as u32
|
||||
//size, scale, memory_end, num_included, num_excluded, pos, wrapping address, included_address, excluded_address
|
||||
1 + 1 + 1 + 1 + 1 + 3 + 1 + self.included_shapes.len() as u32 + self.excluded_shapes.len() as u32
|
||||
}
|
||||
|
||||
fn get_prev_buffer_mem_size(&self) -> u32 {
|
||||
|
@ -74,7 +77,7 @@ impl Memorizable for ShapeComposition {
|
|||
let mut bbox_low = Vector3 {x: f32::INFINITY, y: f32::INFINITY, z: f32::INFINITY};
|
||||
let mut bbox_high = Vector3 {x: f32::NEG_INFINITY, y: f32::NEG_INFINITY, z: f32::NEG_INFINITY};
|
||||
|
||||
let mut element_offset = 8;
|
||||
let mut element_offset = 9;
|
||||
for volumetric in &self.included_shapes {
|
||||
// create bbox for scale calculation. Only the included elements matter for the scale, as exclusion does not need to be fully included in the grid
|
||||
let (l, h) = volumetric.borrow().get_bbox();
|
||||
|
@ -102,13 +105,17 @@ impl Memorizable for ShapeComposition {
|
|||
element_offset += 1;
|
||||
}
|
||||
|
||||
v[self.memory_start + 1] = u32::from_ne_bytes((bbox_high.x.max(bbox_high.y.max(bbox_high.z)) - bbox_low.x.min(bbox_low.y.min(bbox_low.z)) / (self.size as f32)).to_ne_bytes());
|
||||
let bbox_high_pos_ind = bbox_high - bbox_low;
|
||||
let scale = bbox_high_pos_ind.x.max(bbox_high_pos_ind.y.max(bbox_high_pos_ind.z)) / (self.size as f32);
|
||||
|
||||
v[self.memory_start + 1] = u32::from_ne_bytes(scale.to_ne_bytes());
|
||||
v[self.memory_start + 2] = (shapes_index + shapes_memory) as u32;
|
||||
v[self.memory_start + 3] = self.included_shapes.len() as u32;
|
||||
v[self.memory_start + 4] = self.excluded_shapes.len() as u32;
|
||||
v[self.memory_start + 5] = u32::from_ne_bytes(bbox_low.x.to_ne_bytes());
|
||||
v[self.memory_start + 6] = u32::from_ne_bytes(bbox_low.y.to_ne_bytes());
|
||||
v[self.memory_start + 7] = u32::from_ne_bytes(bbox_low.z.to_ne_bytes());
|
||||
v[self.memory_start + 8] = 0; //TODO add wrapping reference
|
||||
|
||||
self.prev_memory_size = self.get_compound_buffer_mem_size(data);
|
||||
self.dirty = false;
|
||||
|
@ -128,8 +135,9 @@ impl Memorizable for ShapeComposition {
|
|||
pub struct Sphere {
|
||||
pos: Vector3<f32>,
|
||||
rot: Vector3<f32>, // rotation will only matter once textures are implemented, till then it is a holdover
|
||||
radius: f32,
|
||||
color: Vector3<u8>, // color, either as pure color or texture modifier
|
||||
transparent: bool,
|
||||
radius: f32,
|
||||
roughness: u8,
|
||||
memory_start: usize,
|
||||
dirty: bool
|
||||
|
@ -141,20 +149,21 @@ impl Sphere {
|
|||
rot: Vector3<f32>,
|
||||
radius: f32,
|
||||
color: Vector3<u8>,
|
||||
roughness: u8) -> Self {
|
||||
Self { pos: pos, rot: rot, radius: radius, color: color, roughness: roughness, memory_start: 0, dirty: true }
|
||||
roughness: u8,
|
||||
transparent: bool) -> Self {
|
||||
Self { pos: pos, rot: rot, radius: radius, color: color, roughness: roughness, memory_start: 0, dirty: true, transparent: transparent }
|
||||
}
|
||||
}
|
||||
|
||||
impl Memorizable for Sphere {
|
||||
fn get_buffer_mem_size(&self, data: &AppData) -> u32 {
|
||||
// type, pos, rot, radius, (color + roughness)
|
||||
1 + 3 + 3 + 1 + 1
|
||||
// type, pos, rot, (color + roughness), transparent, radius
|
||||
1 + 3 + 3 + 1 + 1 + 1
|
||||
}
|
||||
|
||||
fn get_prev_buffer_mem_size(&self) -> u32 {
|
||||
// constant memory size
|
||||
1 + 3 + 3 + 1 + 1
|
||||
1 + 3 + 3 + 1 + 1 + 1
|
||||
}
|
||||
fn is_dirty(&self) -> bool {
|
||||
self.dirty
|
||||
|
@ -169,9 +178,11 @@ impl Memorizable for Sphere {
|
|||
v[self.memory_start + 5] = u32::from_ne_bytes(self.rot.y.to_ne_bytes());
|
||||
v[self.memory_start + 6] = u32::from_ne_bytes(self.rot.z.to_ne_bytes());
|
||||
|
||||
v[self.memory_start + 7] = u32::from_ne_bytes(self.radius.to_ne_bytes());
|
||||
v[self.memory_start + 7] = u32::from_ne_bytes([self.color.x, self.color.y, self.color.z, self.roughness]);
|
||||
|
||||
v[self.memory_start + 8] = u32::from_ne_bytes([self.color.x, self.color.y, self.color.z, self.roughness]);
|
||||
v[self.memory_start + 8] = self.transparent as u32;
|
||||
|
||||
v[self.memory_start + 9] = u32::from_ne_bytes(self.radius.to_ne_bytes());
|
||||
|
||||
v
|
||||
}
|
||||
|
@ -205,4 +216,12 @@ impl Volumetrics for Sphere {
|
|||
let rad_vec = Vector3 {x: self.radius, y: self.radius, z: self.radius};
|
||||
(self.pos - rad_vec, self.pos + rad_vec)
|
||||
}
|
||||
|
||||
fn is_transparent(&self) -> bool {
|
||||
self.transparent
|
||||
}
|
||||
|
||||
fn set_transparency(&mut self, transparent: bool) {
|
||||
self.transparent = transparent;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue