diff --git a/build.rs b/build.rs index 42858e0..0a3c430 100644 --- a/build.rs +++ b/build.rs @@ -6,32 +6,40 @@ fn main() { println!("cargo::rerun-if-changed=shaders/cube.frag"); println!("cargo::rerun-if-changed=shaders/cube.geom"); println!("cargo::rerun-if-changed=shaders/cube.vert"); - println!("cargo::rerun-if-changed=shaders/geo_cube.spv"); - println!("cargo::rerun-if-changed=shaders/frag_cube.spv"); - println!("cargo::rerun-if-changed=shaders/vert_cube.spv"); + println!("cargo::rerun-if-changed=shaders/compiled/geo_cube.spv"); + println!("cargo::rerun-if-changed=shaders/compiled/frag_cube.spv"); + println!("cargo::rerun-if-changed=shaders/compiled/vert_cube.spv"); println!("cargo::rerun-if-changed=shaders/cuboid.frag"); println!("cargo::rerun-if-changed=shaders/cuboid.geom"); println!("cargo::rerun-if-changed=shaders/cuboid.vert"); - println!("cargo::rerun-if-changed=shaders/geo_cuboid.spv"); - println!("cargo::rerun-if-changed=shaders/frag_cuboid.spv"); - println!("cargo::rerun-if-changed=shaders/vert_cuboid.spv"); + println!("cargo::rerun-if-changed=shaders/compiled/geo_cuboid.spv"); + println!("cargo::rerun-if-changed=shaders/compiled/frag_cuboid.spv"); + println!("cargo::rerun-if-changed=shaders/compiled/vert_cuboid.spv"); + + println!("cargo::rerun-if-changed=shaders/rt_quad.vert"); + println!("cargo::rerun-if-changed=shaders/compiled/vert_rt_quad.spv"); + println!("cargo::rerun-if-changed=shaders/rt_quad.frag"); + println!("cargo::rerun-if-changed=shaders/compiled/frag_rt_quad.spv"); + + #[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"); if std::env::consts::OS == "windows" { - #[allow(unused_must_use)] - std::fs::remove_file("shaders/geo_cube.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/frag_cube.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/vert_cube.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/geo_cuboid.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/frag_cuboid.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/vert_cuboid.spv"); - #[warn(unused_must_use)] - // probably need to check the os and have different versions let mut command = Command::new("./shaders/compile.bat"); let output = command.output().expect("Failed to execute command"); println!("status: {}", output.status); @@ -40,20 +48,6 @@ fn main() { assert!(output.status.success()); } else if std::env::consts::OS == "linux" { - #[allow(unused_must_use)] - std::fs::remove_file("shaders/geo_cube.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/frag_cube.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/vert_cube.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/geo_cuboid.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/frag_cuboid.spv"); - #[allow(unused_must_use)] - std::fs::remove_file("shaders/vert_cuboid.spv"); - #[warn(unused_must_use)] - // probably need to check the os and have different versions let mut command = Command::new("./shaders/compile.sh"); let output = command.output().expect("Failed to execute command"); println!("status: {}", output.status); @@ -63,10 +57,12 @@ fn main() { assert!(output.status.success()); } - assert!(Path::new("shaders/geo_cube.spv").exists()); - assert!(Path::new("shaders/frag_cube.spv").exists()); - assert!(Path::new("shaders/vert_cube.spv").exists()); - assert!(Path::new("shaders/geo_cuboid.spv").exists()); - assert!(Path::new("shaders/frag_cuboid.spv").exists()); - assert!(Path::new("shaders/vert_cuboid.spv").exists()); + assert!(Path::new("shaders/compiled/geo_cube.spv").exists()); + assert!(Path::new("shaders/compiled/frag_cube.spv").exists()); + assert!(Path::new("shaders/compiled/vert_cube.spv").exists()); + assert!(Path::new("shaders/compiled/geo_cuboid.spv").exists()); + assert!(Path::new("shaders/compiled/frag_cuboid.spv").exists()); + assert!(Path::new("shaders/compiled/vert_cuboid.spv").exists()); + assert!(Path::new("shaders/compiled/vert_rt_quad.spv").exists()); + assert!(Path::new("shaders/compiled/frag_rt_quad.spv").exists()); } \ No newline at end of file diff --git a/shaders/compile.bat b/shaders/compile.bat index 01e5f2c..9090ab5 100644 --- a/shaders/compile.bat +++ b/shaders/compile.bat @@ -1,10 +1,10 @@ -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cube.vert -o shaders/vert_cube.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cube.frag -o shaders/frag_cube.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cube.geom -o shaders/geo_cube.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cube.vert -o shaders/compiled/vert_cube.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cube.frag -o shaders/compiled/frag_cube.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cube.geom -o shaders/compiled/geo_cube.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.vert -o shaders/vert_cuboid.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.frag -o shaders/frag_cuboid.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.geom -o shaders/geo_cuboid.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.vert -o shaders/compiled/vert_cuboid.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.frag -o shaders/compiled/frag_cuboid.spv +C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/cuboid.geom -o shaders/compiled/geo_cuboid.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_quad.vert -o shaders/vert_rt_quad.spv -C:/VulkanSDK/1.3.280.0/Bin/glslc.exe shaders/rt_quad.frag -o shaders/frag_rt_quad.spv \ No newline at end of file +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 \ No newline at end of file diff --git a/shaders/compile.sh b/shaders/compile.sh index 46bcd3a..1b139d3 100755 --- a/shaders/compile.sh +++ b/shaders/compile.sh @@ -1,11 +1,11 @@ #!/bin/sh -glslc shaders/cube.vert -o shaders/vert_cube.spv -glslc shaders/cube.frag -o shaders/frag_cube.spv -glslc shaders/cube.geom -o shaders/geo_cube.spv +glslc shaders/cube.vert -o shaders/compiled/vert_cube.spv +glslc shaders/cube.frag -o shaders/compiled/frag_cube.spv +glslc shaders/cube.geom -o shaders/compiled/geo_cube.spv -glslc shaders/cuboid.vert -o shaders/vert_cuboid.spv -glslc shaders/cuboid.frag -o shaders/frag_cuboid.spv -glslc shaders/cuboid.geom -o shaders/geo_cuboid.spv +glslc shaders/cuboid.vert -o shaders/compiled/vert_cuboid.spv +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/vert_rt_quad.spv -glslc shaders/rt_quad.frag -o shaders/frag_rt_quad.spv \ No newline at end of file +glslc shaders/rt_quad.vert -o shaders/compiled/vert_rt_quad.spv +glslc shaders/rt_quad.frag -o shaders/compiled/frag_rt_quad.spv \ No newline at end of file diff --git a/shaders/frag_cube.spv b/shaders/compiled/frag_cube.spv similarity index 100% rename from shaders/frag_cube.spv rename to shaders/compiled/frag_cube.spv diff --git a/shaders/frag_cuboid.spv b/shaders/compiled/frag_cuboid.spv similarity index 100% rename from shaders/frag_cuboid.spv rename to shaders/compiled/frag_cuboid.spv diff --git a/shaders/compiled/frag_rt_quad.spv b/shaders/compiled/frag_rt_quad.spv new file mode 100644 index 0000000..e586d97 Binary files /dev/null and b/shaders/compiled/frag_rt_quad.spv differ diff --git a/shaders/geo_cube.spv b/shaders/compiled/geo_cube.spv similarity index 100% rename from shaders/geo_cube.spv rename to shaders/compiled/geo_cube.spv diff --git a/shaders/geo_cuboid.spv b/shaders/compiled/geo_cuboid.spv similarity index 100% rename from shaders/geo_cuboid.spv rename to shaders/compiled/geo_cuboid.spv diff --git a/shaders/vert_cube.spv b/shaders/compiled/vert_cube.spv similarity index 100% rename from shaders/vert_cube.spv rename to shaders/compiled/vert_cube.spv diff --git a/shaders/vert_cuboid.spv b/shaders/compiled/vert_cuboid.spv similarity index 100% rename from shaders/vert_cuboid.spv rename to shaders/compiled/vert_cuboid.spv diff --git a/shaders/vert_rt_quad.spv b/shaders/compiled/vert_rt_quad.spv similarity index 61% rename from shaders/vert_rt_quad.spv rename to shaders/compiled/vert_rt_quad.spv index 62118cc..87bf2ac 100644 Binary files a/shaders/vert_rt_quad.spv and b/shaders/compiled/vert_rt_quad.spv differ diff --git a/shaders/frag_rt_quad.spv b/shaders/frag_rt_quad.spv deleted file mode 100644 index 50157c9..0000000 Binary files a/shaders/frag_rt_quad.spv and /dev/null differ diff --git a/shaders/rt_quad.frag b/shaders/rt_quad.frag index ffaa3b5..7ffe0e8 100644 --- a/shaders/rt_quad.frag +++ b/shaders/rt_quad.frag @@ -2,9 +2,114 @@ layout(location = 0) flat in uvec2 fragRasterPos; layout(location = 1) flat in uint fragVolumeStart; +layout(location = 2) in vec3 origPosition; +layout(location = 3) flat in uint facing; layout(location = 0) out vec4 outColor; +layout(binding = 2) buffer SceneInfoBuffer{ + uint infos[]; +} scene_info; + +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; + + return uvec4(val1, val2, val3, val4); +} + +uvec4 sample_from_scene_info(uint volume_start, uvec2 raster_pos, uint f) { + uint array_descr_start = volume_start + 3; + uint color_array_start = array_descr_start + 24; + + uint top_color_size_u = scene_info.infos[array_descr_start]; + uint top_color_size_v = scene_info.infos[array_descr_start + 1]; + + uint bottom_color_size_u = scene_info.infos[array_descr_start + 2]; + uint bottom_color_size_v = scene_info.infos[array_descr_start + 3]; + + uint left_color_size_u = scene_info.infos[array_descr_start + 4]; + uint left_color_size_v = scene_info.infos[array_descr_start + 5]; + + uint right_color_size_u = scene_info.infos[array_descr_start + 6]; + uint right_color_size_v = scene_info.infos[array_descr_start + 7]; + + uint front_color_size_u = scene_info.infos[array_descr_start + 8]; + uint front_color_size_v = scene_info.infos[array_descr_start + 9]; + + uint back_color_size_u = scene_info.infos[array_descr_start + 10]; + uint back_color_size_v = scene_info.infos[array_descr_start + 11]; + + uint top_neighbor_size_u = scene_info.infos[array_descr_start + 12]; + uint top_neighbor_size_v = scene_info.infos[array_descr_start + 13]; + + /*uint bottom_neighbor_size_u = scene_info.infos[array_descr_start + 14]; + uint bottom_neighbor_size_v = scene_info.infos[array_descr_start + 15]; + + uint left_neighbor_size_u = scene_info.infos[array_descr_start + 16]; + uint left_neighbor_size_v = scene_info.infos[array_descr_start + 17]; + + uint right_neighbor_size_u = scene_info.infos[array_descr_start + 18]; + uint right_neighbor_size_v = scene_info.infos[array_descr_start + 19]; + + uint front_neighbor_size_u = scene_info.infos[array_descr_start + 20]; + uint front_neighbor_size_v = scene_info.infos[array_descr_start + 21]; + + uint back_neighbor_size_u = scene_info.infos[array_descr_start + 22]; + uint back_neighbor_size_v = scene_info.infos[array_descr_start + 23];*/ + + uint top_size = top_color_size_u * top_color_size_v; + uint bottom_size = bottom_color_size_u * bottom_color_size_v; + uint left_size = left_color_size_u * left_color_size_v; + uint right_size = right_color_size_u * right_color_size_v; + uint front_size = front_color_size_u * front_color_size_v; + uint back_size = back_color_size_u * back_color_size_v; + + // maybe do an array solution for this as well + uint array_start = color_array_start + uint(f > 0) * top_size + uint(f > 1) * bottom_size + uint(f > 2) * left_size + uint(f > 3) * right_size + uint(f > 4) * front_size; + uint us[6] = {top_color_size_u, bottom_color_size_u, left_color_size_u, right_color_size_u, front_color_size_u, back_color_size_u}; + uint vs[6] = {top_color_size_v, bottom_color_size_v, left_color_size_v, right_color_size_v, front_color_size_v, back_color_size_v}; + uint u_size = us[f]; + uint v_size = vs[f]; + uint value = scene_info.infos[array_start + raster_pos.x * v_size + raster_pos.y]; + + if (top_color_size_v == 0) { + return uvec4(255, 0, 0, 255); + } + + return unpack_color(value); +} + void main() { - outColor = vec4(1, 0, 0, 1); + uint max_length = scene_info.infos[0]; + uint last = scene_info.infos[max_length]; + + uvec4 color_roughness = sample_from_scene_info(fragVolumeStart, fragRasterPos, facing); + outColor = vec4(float(color_roughness.x) / 255.0, float(color_roughness.y) / 255.0, float(color_roughness.z) / 255.0, 1); + + /*if (scene_info.infos[1] == 16) { + outColor = vec4(0, 1, 0, 1); + }*/ + + /*if (fragVolumeStart == 1 && scene_info.infos[fragVolumeStart] == 16) { + outColor = vec4(0, 1, 0, 1); + }*/ + + /*if (facing == 0) { + outColor = vec4(1, 0, 0, 1); + } else if (facing == 1) { + outColor = vec4(0, 1, 1, 1); + } else if (facing == 2) { + outColor = vec4(0, 1, 0, 1); + } else if (facing == 3) { + outColor = vec4(1, 0, 1, 1); + } else if (facing == 4) { + outColor = vec4(0, 0, 1, 1); + } else if (facing == 5) { + outColor = vec4(1, 1, 0, 1); + }*/ + } \ No newline at end of file diff --git a/shaders/rt_quad.vert b/shaders/rt_quad.vert index 4b679a4..b027c8d 100644 --- a/shaders/rt_quad.vert +++ b/shaders/rt_quad.vert @@ -12,9 +12,12 @@ layout(binding = 0) uniform UniformBufferObject { layout(location = 0) in vec3 inPosition; layout(location = 1) in uvec2 inRasterPos; layout(location = 2) in uint inVolumeStart; +layout(location = 3) in uint inFacing; -layout(location = 0) out uvec2 rasterPos; -layout(location = 1) out uint volumeStart; +layout(location = 0) flat out uvec2 rasterPos; +layout(location = 1) flat out uint volumeStart; +layout(location = 2) out vec3 origPosition; +layout(location = 3) flat out uint facing; void main() { if (ubo.use_geom_shader[0]) { @@ -24,4 +27,6 @@ void main() { } rasterPos = inRasterPos; volumeStart = inVolumeStart; + origPosition = inPosition; + facing = inFacing; } \ No newline at end of file diff --git a/src/app_data.rs b/src/app_data.rs index fcf3f73..b30b6a1 100644 --- a/src/app_data.rs +++ b/src/app_data.rs @@ -58,4 +58,6 @@ pub struct AppData { pub use_geometry_shader: bool, pub topology: vk::PrimitiveTopology, + + pub scene_rt_memory_size: u64, } \ No newline at end of file diff --git a/src/buffer.rs b/src/buffer.rs index 56f1206..15e96d5 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -253,7 +253,7 @@ pub unsafe fn create_storage_buffers( instance, device, data, - size_of::() as u64, + data.scene_rt_memory_size, vk::BufferUsageFlags::STORAGE_BUFFER, vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE, )?; @@ -324,7 +324,7 @@ pub unsafe fn create_descriptor_sets(device: &Device, data: &mut app_data::AppDa let info = vk::DescriptorBufferInfo::builder() .buffer(data.storage_buffers[i]) .offset(0) - .range(size_of::() as u64); + .range(data.scene_rt_memory_size); let storage_info = &[info]; let storage_write = vk::WriteDescriptorSet::builder() diff --git a/src/main.rs b/src/main.rs index 8228225..8a8508c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ use anyhow::{anyhow, Result}; use log::*; use winit::dpi::{LogicalSize, LogicalPosition}; -use winit::event::{Event, WindowEvent}; +use winit::event::{ElementState, Event, WindowEvent}; use winit::event_loop::EventLoop; use winit::keyboard::NamedKey; use winit::window::{Window, WindowBuilder}; @@ -132,6 +132,9 @@ fn main() -> Result<()> { if event.logical_key == "d" { app.cur_pos += app.view_direction.cross(vertex::Vec3::new(0.0, 0.0, 1.0)) * 0.1; } + if event.logical_key == "f" && event.state == ElementState::Pressed && event.repeat == false { + app.show_frame_rate = !app.show_frame_rate; + } if event.logical_key == NamedKey::Escape { elwt.exit(); unsafe { app.device.device_wait_idle().unwrap(); } @@ -164,6 +167,8 @@ struct App { view_direction: vertex::Vec3, cur_pos: cgmath::Point3, scene_handler: scene::Scene, + show_frame_rate: bool, + synchronized: usize, } impl App { @@ -199,7 +204,7 @@ impl App { image::create_texture_image_view(&device, &mut data)?; image::create_texture_sampler(&device, &mut data)?; - scene_handler.prepare_data(&instance, &device, &data)?; + scene_handler.prepare_data(&instance, &device, &mut data)?; buffer::create_uniform_buffers(&instance, &device, &mut data)?; buffer::create_storage_buffers(&instance, &device, &mut data)?; @@ -215,7 +220,9 @@ impl App { last_pos: LogicalPosition::new(-1 as f32, -1 as f32), view_direction: vertex::Vec3::new(0.0, 0.0, 0.0), cur_pos: cgmath::point3(0.0, 0.0, 0.0), - scene_handler + scene_handler, + show_frame_rate: false, + synchronized: 0 }) } @@ -247,6 +254,10 @@ impl App { self.data.images_in_flight[image_index] = in_flight_fence; self.update_uniform_buffer(image_index)?; + if self.synchronized < MAX_FRAMES_IN_FLIGHT { + self.update_storage_buffer(image_index)?; + self.synchronized += 1 + } let wait_semaphores = &[self.data.image_available_semaphores[self.frame]]; let wait_stages = &[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT]; @@ -281,7 +292,9 @@ impl App { self.frame = (self.frame + 1) % MAX_FRAMES_IN_FLIGHT; - println!("{}", 1000000.0 / start_time.elapsed().as_micros() as f32); + if self.show_frame_rate { + println!("{}", 1000000.0 / start_time.elapsed().as_micros() as f32); + } Ok(()) } @@ -338,6 +351,7 @@ impl App { self.data .images_in_flight .resize(self.data.swapchain_images.len(), vk::Fence::null()); + self.synchronized = 0; Ok(()) } @@ -431,14 +445,18 @@ impl App { self.device.unmap_memory(self.data.uniform_buffers_memory[image_index]); + Ok(()) + } + + unsafe fn update_storage_buffer(&mut self, image_index: usize) -> Result<()> { let memory = self.device.map_memory( self.data.storage_buffers_memory[image_index], 0, - size_of::() as u64, + self.data.scene_rt_memory_size, vk::MemoryMapFlags::empty(), )?; - memcpy(&ubo, memory.cast(), 1); + memcpy(self.scene_handler.rt_memory.as_ptr(), memory.cast(), 2103); self.device.unmap_memory(self.data.storage_buffers_memory[image_index]); @@ -677,9 +695,9 @@ unsafe fn create_logical_device( unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Result<()> { // set up shaders for cubes // load the byte data - let vert_cube = include_bytes!("../shaders/vert_cube.spv"); - let geo_cube = include_bytes!("../shaders/geo_cube.spv"); - let frag_cube = include_bytes!("../shaders/frag_cube.spv"); + let vert_cube = include_bytes!("../shaders/compiled/vert_cube.spv"); + let geo_cube = include_bytes!("../shaders/compiled/geo_cube.spv"); + let frag_cube = include_bytes!("../shaders/compiled/frag_cube.spv"); // create the shaders let vert_shader_module_cube = create_shader_module(device, &vert_cube[..])?; let geo_shader_module_cube = create_shader_module(device, &geo_cube[..])?; @@ -708,9 +726,9 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu // set up shaders for cuboids // load the byte data - let vert_cuboid = include_bytes!("../shaders/vert_cuboid.spv"); - let geo_cuboid = include_bytes!("../shaders/geo_cuboid.spv"); - let frag_cuboid = include_bytes!("../shaders/frag_cuboid.spv"); + let vert_cuboid = include_bytes!("../shaders/compiled/vert_cuboid.spv"); + let geo_cuboid = include_bytes!("../shaders/compiled/geo_cuboid.spv"); + let frag_cuboid = include_bytes!("../shaders/compiled/frag_cuboid.spv"); // create the shaders let vert_shader_module_cuboid = create_shader_module(device, &vert_cuboid[..])?; let geo_shader_module_cuboid = create_shader_module(device, &geo_cuboid[..])?; @@ -739,8 +757,8 @@ unsafe fn create_pipeline(device: &Device, data: &mut app_data::AppData) -> Resu // set up shaders for quads/raytracing // load the byte data - let vert_quad = include_bytes!("../shaders/vert_rt_quad.spv"); - let frag_quad = include_bytes!("../shaders/frag_rt_quad.spv"); + let vert_quad = include_bytes!("../shaders/compiled/vert_rt_quad.spv"); + let frag_quad = include_bytes!("../shaders/compiled/frag_rt_quad.spv"); // create the shaders let vert_shader_module_quad = create_shader_module(device, &vert_quad[..])?; let frag_shader_module_quad = create_shader_module(device, &frag_quad[..])?; diff --git a/src/primitives/quad.rs b/src/primitives/quad.rs index 0068e27..5be1b03 100644 --- a/src/primitives/quad.rs +++ b/src/primitives/quad.rs @@ -1,6 +1,6 @@ use vulkanalia::prelude::v1_0::*; use cgmath::vec3; -use crate::vertex; +use crate::vertex::{self, Facing}; use crate::scene::Scene; use crate::primitives::drawable::Drawable; @@ -12,6 +12,7 @@ pub struct Quad{ pub pos4: vertex::Vec3, pub raster_pos: cgmath::Vector2, pub volume_index: u32, + pub facing: Facing, } impl Drawable for Quad { @@ -21,25 +22,29 @@ impl Drawable for Quad { scene.rt_vertices.push(vertex::RTVertex::new( vec3(self.pos1.x as f32, self.pos1.y as f32, self.pos1.z as f32), self.raster_pos, - self.volume_index + self.volume_index, + self.facing )); // 1 top right far scene.rt_vertices.push(vertex::RTVertex::new( vec3(self.pos2.x as f32, self.pos2.y as f32, self.pos2.z as f32), self.raster_pos, - self.volume_index + self.volume_index, + self.facing )); // 2 top left near scene.rt_vertices.push(vertex::RTVertex::new( vec3(self.pos3.x as f32, self.pos3.y as f32, self.pos3.z as f32), self.raster_pos, - self.volume_index + self.volume_index, + self.facing )); // 3 top right near scene.rt_vertices.push(vertex::RTVertex::new( vec3(self.pos4.x as f32, self.pos4.y as f32, self.pos4.z as f32), self.raster_pos, - self.volume_index + self.volume_index, + self.facing )); // top diff --git a/src/scene.rs b/src/scene.rs index c231b71..0c08f4d 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -5,6 +5,7 @@ use anyhow::Result; use cgmath::{vec2, vec3, Vector3}; use std::cell::RefCell; +use std::mem; use std::rc::Rc; use std::time::Instant; @@ -20,11 +21,12 @@ use crate::primitives::drawable::Drawable; extern crate rand; use rand::Rng; -const CHUNK_SIZE_EXPONENT: u32 = 6; +const CHUNK_SIZE_EXPONENT: u32 = 4; const CHUNK_SIZE: usize = (2 as usize).pow(CHUNK_SIZE_EXPONENT); -const MAX_TREE_DEPTH: usize = 4; +const MAX_TREE_DEPTH: usize = 2; const MIN_CHUNK_SIZE: usize = CHUNK_SIZE / (2 as usize).pow(MAX_TREE_DEPTH as u32); +#[repr(C)] #[derive(Clone, Debug, Default)] pub struct Scene { pub vertices: Vec, @@ -51,10 +53,12 @@ pub struct Scene { pub index_buffer_quad: vk::Buffer, pub index_buffer_memory_quad: vk::DeviceMemory, + + pub rt_memory: Vec, } impl Scene { - pub unsafe fn prepare_data(&mut self, instance: &vulkanalia::Instance, device: &vulkanalia::Device, data: &AppData) -> Result<()> { + pub unsafe fn prepare_data(&mut self, instance: &vulkanalia::Instance, device: &vulkanalia::Device, data: &mut AppData) -> Result<()> { let mut rng = rand::thread_rng(); let grid_size = CHUNK_SIZE as i32; @@ -111,13 +115,34 @@ impl Scene { None => {} } } + + let mut memory_index = 1; // zero should be the location for the overall length (also will be the invalid memory allocation for pointing to a nonexistant neighbor) + for volume in &empty_volumes { + volume.borrow_mut().memory_start = memory_index; + memory_index += volume.borrow().get_buffer_mem_size() as usize; - for volume in empty_volumes { + } + for volume in &empty_volumes { let quads = volume.borrow().to_quads(); for quad in quads { quad.draw(&data.topology, self.rt_vertices.len(), self); } } + println!("Memory size is {} kB, max indes is {}", memory_index * 32 / 8 /1024 + 1, memory_index); + let mut volume_vec = vec![memory_index as u32; memory_index]; + for volume in &empty_volumes { + volume_vec = volume.borrow().insert_into_memory(volume_vec); + } + println!("volume_vec print {:?}", volume_vec); + let mut empty_count = 0; + for element in &volume_vec { + if *element == memory_index as u32 { + empty_count += 1; + } + } + println!("empty elements count is {}", empty_count); + self.rt_memory = volume_vec; + data.scene_rt_memory_size = (self.rt_memory.len() * 4) as u64; // size of the needed buffer size in bytes if self.vertices.len() != 0 { (self.vertex_buffer_cube, self.vertex_buffer_memory_cube) = buffer::create_vertex_buffer(instance, device, &data, &self.vertices)?; @@ -658,12 +683,12 @@ struct EmptyVolume { pub color_back: Vec>, pub color_front: Vec>, - pub roughness_left: Vec>, - pub roughness_right: Vec>, - pub roughness_top: Vec>, - pub roughness_bottom: Vec>, - pub roughness_back: Vec>, - pub roughness_front: Vec>, + pub roughness_left: Vec, + pub roughness_right: Vec, + pub roughness_top: Vec, + pub roughness_bottom: Vec, + pub roughness_back: Vec, + pub roughness_front: Vec, pub neighbor_left: Vec>>>, pub neighbor_right: Vec>>>, @@ -842,11 +867,11 @@ impl EmptyVolume { bottom_elements_num += 1; let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8}; bottom_colors.push(u8_color); - bottom_roughness.push(Vector3 {x: 128, y: 128, z: 128}); + bottom_roughness.push(128); } else { bottom_colors.push(Vector3 { x: 255, y: 255, z: 255 }); - bottom_roughness.push(Vector3 {x: 255, y: 255, z: 255}); + bottom_roughness.push(255); } } } @@ -868,11 +893,11 @@ impl EmptyVolume { top_elements_num += 1; let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8}; top_colors.push(u8_color); - top_roughness.push(Vector3 {x: 128, y: 128, z: 128}); + top_roughness.push(128); } else { top_colors.push(Vector3 { x: 255, y: 255, z: 255 }); - top_roughness.push(Vector3 {x: 255, y: 255, z: 255}); + top_roughness.push(255); } } } @@ -895,11 +920,11 @@ impl EmptyVolume { back_elements_num += 1; let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8}; back_colors.push(u8_color); - back_roughness.push(Vector3 {x: 128, y: 128, z: 128}); + back_roughness.push(128); } else { back_colors.push(Vector3 { x: 255, y: 255, z: 255 }); - back_roughness.push(Vector3 {x: 255, y: 255, z: 255}); + back_roughness.push(255); } } } @@ -922,11 +947,11 @@ impl EmptyVolume { front_elements_num += 1; let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8}; front_colors.push(u8_color); - front_roughness.push(Vector3 {x: 128, y: 128, z: 128}); + front_roughness.push(128); } else { front_colors.push(Vector3 { x: 255, y: 255, z: 255 }); - front_roughness.push(Vector3 {x: 255, y: 255, z: 255}); + front_roughness.push(255); } } } @@ -949,11 +974,11 @@ impl EmptyVolume { left_elements_num += 1; let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8}; left_colors.push(u8_color); - left_roughness.push(Vector3 {x: 128, y: 128, z: 128}); + left_roughness.push(128); } else { left_colors.push(Vector3 { x: 255, y: 255, z: 255 }); - left_roughness.push(Vector3 {x: 255, y: 255, z: 255}); + left_roughness.push(255); } } } @@ -976,11 +1001,11 @@ impl EmptyVolume { right_elements_num += 1; let u8_color = Vector3 {x: (c.color * 255.0).x.min(255.0).max(0.0) as u8, y: (c.color * 255.0).y.min(255.0).max(0.0) as u8, z: (c.color * 255.0).z.min(255.0).max(0.0) as u8}; right_colors.push(u8_color); - right_roughness.push(Vector3 {x: 128, y: 128, z: 128}); + right_roughness.push(128); } else { right_colors.push(Vector3 { x: 255, y: 255, z: 255 }); - right_roughness.push(Vector3 {x: 255, y: 255, z: 255}); + right_roughness.push(255); } } } @@ -1186,7 +1211,8 @@ impl EmptyVolume { pos3: float_pos + Vector3 { x: 0.5 + x as f32, y: 0.5 + y as f32, z: -0.5 }, pos2: float_pos + Vector3 { x: -0.5 + x as f32, y: 0.5 + y as f32, z: -0.5 }, raster_pos: cgmath::Vector2 { x: x as u32, y: y as u32 }, - volume_index: 0 + volume_index: self.memory_start as u32, + facing: vertex::Facing::Bottom }; quads.push(quad); } @@ -1209,7 +1235,8 @@ impl EmptyVolume { pos2: float_pos + Vector3 { x: 0.5 + x as f32, y: 0.5 + y as f32, z: self.size_z as f32 - 0.5 }, pos3: float_pos + Vector3 { x: -0.5 + x as f32, y: 0.5 + y as f32, z: self.size_z as f32 - 0.5 }, raster_pos: cgmath::Vector2 { x: x as u32, y: y as u32 }, - volume_index: 0 + volume_index: self.memory_start as u32, + facing: vertex::Facing::Top }; quads.push(quad); } @@ -1233,7 +1260,8 @@ impl EmptyVolume { pos3: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + 0 as f32, z: z as f32 + 0.5 }, pos2: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + 0 as f32, z: z as f32 - 0.5 }, raster_pos: cgmath::Vector2 { x: x as u32, y: z as u32 }, - volume_index: 0 + volume_index: self.memory_start as u32, + facing: vertex::Facing::Front }; quads.push(quad); } @@ -1257,7 +1285,8 @@ impl EmptyVolume { pos2: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + self.size_y as f32, z: z as f32 + 0.5 }, pos3: float_pos + Vector3 { x: 0.5 + x as f32, y: -0.5 + self.size_y as f32, z: z as f32 - 0.5 }, raster_pos: cgmath::Vector2 { x: x as u32, y: z as u32 }, - volume_index: 0 + volume_index: self.memory_start as u32, + facing: vertex::Facing::Back }; quads.push(quad); } @@ -1281,7 +1310,8 @@ impl EmptyVolume { pos2: float_pos + Vector3 { x: -0.5 + 0.0 as f32, y: y as f32 + 0.5, z: z as f32 + 0.5 }, pos3: float_pos + Vector3 { x: -0.5 + 0.0 as f32, y: y as f32 + 0.5, z: z as f32 - 0.5 }, raster_pos: cgmath::Vector2 { x: y as u32, y: z as u32 }, - volume_index: 0 + volume_index: self.memory_start as u32, + facing: vertex::Facing::Left }; quads.push(quad); } @@ -1305,13 +1335,342 @@ impl EmptyVolume { pos3: float_pos + Vector3 { x: -0.5 + self.size_x as f32, y: y as f32 + 0.5, z: z as f32 + 0.5 }, pos2: float_pos + Vector3 { x: -0.5 + self.size_x as f32, y: y as f32 + 0.5, z: z as f32 - 0.5 }, raster_pos: cgmath::Vector2 { x: y as u32, y: z as u32 }, - volume_index: 0 + volume_index: self.memory_start as u32, + facing: vertex::Facing::Right }; quads.push(quad); } } quads } + + pub fn get_buffer_mem_size(&self) -> u32 { + let mut mem_size: u32 = 0; + mem_size += 3; //max sizes + mem_size += 12; //color/roughness buffer sizes, 2 values each + mem_size += 12; //neighbor buffer sizes, 2 values each + + // this covers full color and roughness + mem_size += (self.color_top.len() as u32).max(1); + mem_size += (self.color_bottom.len() as u32).max(1); + mem_size += (self.color_left.len() as u32).max(1); + mem_size += (self.color_right.len() as u32).max(1); + mem_size += (self.color_front.len() as u32).max(1); + mem_size += (self.color_back.len() as u32).max(1); + + mem_size += (self.neighbor_top.len() as u32).max(1); + mem_size += (self.neighbor_bottom.len() as u32).max(1); + mem_size += (self.neighbor_left.len() as u32).max(1); + mem_size += (self.neighbor_right.len() as u32).max(1); + mem_size += (self.neighbor_front.len() as u32).max(1); + mem_size += (self.neighbor_back.len() as u32).max(1); + + mem_size + } + + pub fn insert_into_memory(&self, mut v: Vec) -> Vec { + let mut mem_index = self.memory_start; + //max sizes + v[mem_index] = self.size_x as u32; + mem_index += 1; + v[mem_index] = self.size_y as u32; + mem_index += 1; + v[mem_index] = self.size_z as u32; + mem_index += 1; + //color/roughness buffer sizes, 2 values each + if self.color_top.len() > 0 { + v[mem_index] = self.size_x as u32; + v[mem_index + 1] = self.size_y as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + + if self.color_bottom.len() > 0 { + v[mem_index] = self.size_x as u32; + v[mem_index + 1] = self.size_y as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + + if self.color_left.len() > 0 { + v[mem_index] = self.size_y as u32; + v[mem_index + 1] = self.size_z as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + + if self.color_right.len() > 0 { + v[mem_index] = self.size_y as u32; + v[mem_index + 1] = self.size_z as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + + if self.color_front.len() > 0 { + v[mem_index] = self.size_x as u32; + v[mem_index + 1] = self.size_z as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + + if self.color_back.len() > 0 { + v[mem_index] = self.size_x as u32; + v[mem_index + 1] = self.size_z as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + //neighbor buffer sizes, 2 values each + if self.neighbor_top.len() > 0 { + v[mem_index] = self.size_x as u32; + v[mem_index + 1] = self.size_y as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + + if self.neighbor_bottom.len() > 0 { + v[mem_index] = self.size_x as u32; + v[mem_index + 1] = self.size_y as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + + if self.neighbor_left.len() > 0 { + v[mem_index] = self.size_y as u32; + v[mem_index + 1] = self.size_z as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + + if self.neighbor_right.len() > 0 { + v[mem_index] = self.size_y as u32; + v[mem_index + 1] = self.size_z as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + + if self.neighbor_front.len() > 0 { + v[mem_index] = self.size_x as u32; + v[mem_index + 1] = self.size_z as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + + if self.neighbor_back.len() > 0 { + v[mem_index] = self.size_x as u32; + v[mem_index + 1] = self.size_z as u32; + } else { + v[mem_index] = 1; + v[mem_index + 1] = 1; + } + mem_index += 2; + + //color and roughness + //check which endian should be used in conjun´ction of the graphicscard (might already be handled by vulkan) + if self.color_top.len() > 0 { + for index in 0..self.color_top.len() { + let value = &self.color_top[index]; + let roughness = self.roughness_top[index]; + let test : u32 = 5; + v[mem_index] = u32::from_ne_bytes([value.x, value.y, value.z, roughness]); + mem_index += 1; + } + } + else { + v[mem_index] = u32::from_ne_bytes([255, 255, 255, 255]); + mem_index += 1; + } + + if self.color_bottom.len() > 0 { + for index in 0..self.color_bottom.len() { + let value = &self.color_bottom[index]; + let roughness = self.roughness_bottom[index]; + let test : u32 = 5; + v[mem_index] = u32::from_ne_bytes([value.x, value.y, value.z, roughness]); + mem_index += 1; + } + } + else { + v[mem_index] = u32::from_ne_bytes([255, 255, 255, 255]); + mem_index += 1; + } + + if self.color_left.len() > 0 { + for index in 0..self.color_left.len() { + let value = &self.color_left[index]; + let roughness = self.roughness_left[index]; + let test : u32 = 5; + v[mem_index] = u32::from_ne_bytes([value.x, value.y, value.z, roughness]); + mem_index += 1; + } + } + else { + v[mem_index] = u32::from_ne_bytes([255, 255, 255, 255]); + mem_index += 1; + } + + if self.color_right.len() > 0 { + for index in 0..self.color_right.len() { + let value = &self.color_right[index]; + let roughness = self.roughness_right[index]; + let test : u32 = 5; + v[mem_index] = u32::from_ne_bytes([value.x, value.y, value.z, roughness]); + mem_index += 1; + } + } + else { + v[mem_index] = u32::from_ne_bytes([255, 255, 255, 255]); + mem_index += 1; + } + + if self.color_front.len() > 0 { + for index in 0..self.color_front.len() { + let value = &self.color_front[index]; + let roughness = self.roughness_front[index]; + let test : u32 = 5; + v[mem_index] = u32::from_ne_bytes([value.x, value.y, value.z, roughness]); + mem_index += 1; + } + } + else { + v[mem_index] = u32::from_ne_bytes([255, 255, 255, 255]); + mem_index += 1; + } + + if self.color_back.len() > 0 { + for index in 0..self.color_back.len() { + let value = &self.color_back[index]; + let roughness = self.roughness_back[index]; + let test : u32 = 5; + v[mem_index] = u32::from_ne_bytes([value.x, value.y, value.z, roughness]); + mem_index += 1; + } + } + else { + v[mem_index] = u32::from_ne_bytes([255, 255, 255, 255]); + mem_index += 1; + } + + // neighbors + if self.neighbor_top.len() > 0 { + for value in &self.neighbor_top { + if let Some(reference) = value { + v[mem_index] = reference.borrow().memory_start as u32; + } + else { + v[mem_index] = 0; + } + mem_index += 1; + } + } + else { + v[mem_index] = 0; + mem_index += 1; + } + + if self.neighbor_bottom.len() > 0 { + for value in &self.neighbor_bottom { + if let Some(reference) = value { + v[mem_index] = reference.borrow().memory_start as u32; + } + else { + v[mem_index] = 0; + } + mem_index += 1; + } + } + else { + v[mem_index] = 0; + mem_index += 1; + } + + if self.neighbor_left.len() > 0 { + for value in &self.neighbor_left { + if let Some(reference) = value { + v[mem_index] = reference.borrow().memory_start as u32; + } + else { + v[mem_index] = 0; + } + mem_index += 1; + } + } + else { + v[mem_index] = 0; + mem_index += 1; + } + + if self.neighbor_right.len() > 0 { + for value in &self.neighbor_right { + if let Some(reference) = value { + v[mem_index] = reference.borrow().memory_start as u32; + } + else { + v[mem_index] = 0; + } + mem_index += 1; + } + } + else { + v[mem_index] = 0; + mem_index += 1; + } + + if self.neighbor_front.len() > 0 { + for value in &self.neighbor_front { + if let Some(reference) = value { + v[mem_index] = reference.borrow().memory_start as u32; + } + else { + v[mem_index] = 0; + } + mem_index += 1; + } + } + else { + v[mem_index] = 0; + mem_index += 1; + } + + if self.neighbor_back.len() > 0 { + for value in &self.neighbor_back { + if let Some(reference) = value { + v[mem_index] = reference.borrow().memory_start as u32; + } + else { + v[mem_index] = 0; + } + mem_index += 1; + } + } + else { + v[mem_index] = 0; + mem_index += 1; + } + println!("last memory index of volume was {}, equivalent to {}kB", mem_index, mem_index * 32 / 8 / 1024); + v + } } #[cfg(test)] diff --git a/src/vertex.rs b/src/vertex.rs index 1d221de..3d5c6e7 100644 --- a/src/vertex.rs +++ b/src/vertex.rs @@ -163,20 +163,32 @@ impl Hash for SizedVertex { } } +#[repr(C)] +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum Facing { + Top, + Bottom, + Left, + Right, + Front, + Back +} + #[repr(C)] #[derive(Copy, Clone, Debug)] pub struct RTVertex { pub pos: Vec3, pub raster_pos: cgmath::Vector2, pub volume_start: u32, + facing: Facing, } impl RTVertex { - pub const fn new(pos: Vec3, raster_pos: cgmath::Vector2, volume_start: u32) -> Self { - Self { pos, raster_pos, volume_start } + pub const fn new(pos: Vec3, raster_pos: cgmath::Vector2, volume_start: u32, facing: Facing) -> Self { + Self { pos, raster_pos, volume_start, facing } } } -impl VertexContainer<3> for RTVertex { +impl VertexContainer<4> for RTVertex { fn binding_description() -> vk::VertexInputBindingDescription { vk::VertexInputBindingDescription::builder() .binding(0) @@ -185,7 +197,7 @@ impl VertexContainer<3> for RTVertex { .build() } - fn attribute_descriptions() -> [vk::VertexInputAttributeDescription; 3] { + fn attribute_descriptions() -> [vk::VertexInputAttributeDescription; 4] { let pos = vk::VertexInputAttributeDescription::builder() .binding(0) .location(0) @@ -206,7 +218,15 @@ impl VertexContainer<3> for RTVertex { .format(vk::Format::R32_UINT) .offset((size_of::() + size_of::>()) as u32) .build(); - [pos, raster_pos, volume_start] + + let facing = vk::VertexInputAttributeDescription::builder() + .binding(0) + .location(3) + .format(vk::Format::R32_UINT) + .offset((size_of::() + size_of::>() + size_of::()) as u32) + .build(); + + [pos, raster_pos, volume_start, facing] } }