compute shader 1 with sized vertice render and pipeline barrier

This commit is contained in:
zomseffen 2025-04-04 20:40:48 +02:00
parent c02522b6c2
commit 680039cdfa
11 changed files with 814 additions and 313 deletions

624
Cargo.lock generated

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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