diff --git a/src/render_domain.rs b/src/render_domain.rs index 39b6f8ed..cddd4b38 100644 --- a/src/render_domain.rs +++ b/src/render_domain.rs @@ -23,6 +23,8 @@ struct MeshData { meshlets: Vec, vertex_count: u32, triangle_count: u32, + /// The base index of the vertex buffer + vertex_offset: u32, } /// This the visibility buffer implementation of the world render domain. @@ -31,8 +33,8 @@ pub struct VisibilityWorldRenderDomain { vertex_positions_buffer: render_system::BaseBufferHandle, vertex_normals_buffer: render_system::BaseBufferHandle, - - indices_buffer: render_system::BaseBufferHandle, + vertex_indices_buffer: render_system::BaseBufferHandle, + primitive_indices_buffer: render_system::BaseBufferHandle, albedo: render_system::ImageHandle, depth_target: render_system::ImageHandle, @@ -112,6 +114,7 @@ const MAX_INSTANCES: usize = 1024; const MAX_MATERIALS: usize = 1024; const MAX_LIGHTS: usize = 16; const MAX_TRIANGLES: usize = 65536; +const MAX_PRIMITIVE_TRIANGLES: usize = 65536; const MAX_VERTICES: usize = 65536; impl VisibilityWorldRenderDomain { @@ -155,7 +158,7 @@ impl VisibilityWorldRenderDomain { immutable_samplers: None, }, render_system::DescriptorSetLayoutBinding { - name: "indices", + name: "vertex indices", binding: 4, descriptor_type: render_system::DescriptorType::StorageBuffer, descriptor_count: 1, @@ -163,11 +166,11 @@ impl VisibilityWorldRenderDomain { immutable_samplers: None, }, render_system::DescriptorSetLayoutBinding { - name: "textures", + name: "primitive indices", binding: 5, - descriptor_type: render_system::DescriptorType::CombinedImageSampler, + descriptor_type: render_system::DescriptorType::StorageBuffer, descriptor_count: 1, - stages: render_system::Stages::COMPUTE, + stages: render_system::Stages::MESH | render_system::Stages::COMPUTE, immutable_samplers: None, }, render_system::DescriptorSetLayoutBinding { @@ -178,6 +181,14 @@ impl VisibilityWorldRenderDomain { stages: render_system::Stages::MESH | render_system::Stages::COMPUTE, immutable_samplers: None, }, + render_system::DescriptorSetLayoutBinding { + name: "textures", + binding: 7, + descriptor_type: render_system::DescriptorType::CombinedImageSampler, + descriptor_count: 1, + stages: render_system::Stages::COMPUTE, + immutable_samplers: None, + }, ]; let descriptor_set_layout = render_system.create_descriptor_set_layout(Some("Base Set Layout"), &bindings); @@ -188,7 +199,8 @@ impl VisibilityWorldRenderDomain { let vertex_positions_buffer_handle = render_system.create_buffer(Some("Visibility Vertex Positions Buffer"), std::mem::size_of::<[[f32; 3]; MAX_VERTICES]>(), render_system::Uses::Vertex | render_system::Uses::Storage, render_system::DeviceAccesses::CpuWrite | render_system::DeviceAccesses::GpuRead, render_system::UseCases::STATIC); let vertex_normals_buffer_handle = render_system.create_buffer(Some("Visibility Vertex Normals Buffer"), std::mem::size_of::<[[f32; 3]; MAX_VERTICES]>(), render_system::Uses::Vertex | render_system::Uses::Storage, render_system::DeviceAccesses::CpuWrite | render_system::DeviceAccesses::GpuRead, render_system::UseCases::STATIC); - let indices_buffer_handle = render_system.create_buffer(Some("Visibility Index Buffer"), std::mem::size_of::<[[u8; 3]; MAX_TRIANGLES]>(), render_system::Uses::Index | render_system::Uses::Storage, render_system::DeviceAccesses::CpuWrite | render_system::DeviceAccesses::GpuRead, render_system::UseCases::STATIC); + let vertex_indices_buffer_handle = render_system.create_buffer(Some("Visibility Index Buffer"), std::mem::size_of::<[[u8; 3]; MAX_TRIANGLES]>(), render_system::Uses::Index | render_system::Uses::Storage, render_system::DeviceAccesses::CpuWrite | render_system::DeviceAccesses::GpuRead, render_system::UseCases::STATIC); + let primitive_indices_buffer_handle = render_system.create_buffer(Some("Visibility Primitive Indices Buffer"), std::mem::size_of::<[[u16; 3]; MAX_PRIMITIVE_TRIANGLES]>(), render_system::Uses::Index | render_system::Uses::Storage, render_system::DeviceAccesses::CpuWrite | render_system::DeviceAccesses::GpuRead, render_system::UseCases::STATIC); let debug_position = render_system.create_image(Some("debug position"), Extent::new(1920, 1080, 1), render_system::Formats::RGBAu16, None, render_system::Uses::RenderTarget | render_system::Uses::Storage | render_system::Uses::TransferDestination, render_system::DeviceAccesses::GpuRead, render_system::UseCases::DYNAMIC); let debug_normals = render_system.create_image(Some("debug normal"), Extent::new(1920, 1080, 1), render_system::Formats::RGBAu16, None, render_system::Uses::RenderTarget | render_system::Uses::Storage | render_system::Uses::TransferDestination, render_system::DeviceAccesses::GpuRead, render_system::UseCases::DYNAMIC); @@ -238,7 +250,13 @@ impl VisibilityWorldRenderDomain { descriptor_set, binding: 4, array_element: 0, - descriptor: render_system::Descriptor::Buffer{ handle: indices_buffer_handle, size: render_system::Ranges::Whole }, + descriptor: render_system::Descriptor::Buffer{ handle: vertex_indices_buffer_handle, size: render_system::Ranges::Whole }, + }, + render_system::DescriptorWrite { + descriptor_set, + binding: 5, + array_element: 0, + descriptor: render_system::Descriptor::Buffer{ handle: primitive_indices_buffer_handle, size: render_system::Ranges::Whole }, }, render_system::DescriptorWrite { descriptor_set, @@ -274,6 +292,7 @@ struct Camera {{ struct Mesh {{ mat4 model; uint material_id; + uint32_t base_vertex_index; }}; struct Meshlet {{ @@ -296,8 +315,12 @@ layout(set=0,binding=2,scalar) buffer readonly MeshVertexPositions {{ vec3 vertex_positions[]; }}; -layout(set=0,binding=4,scalar) buffer readonly MeshIndices {{ - uint8_t indices[]; +layout(set=0,binding=4,scalar) buffer readonly VertexIndices {{ + uint16_t vertex_indices[]; +}}; + +layout(set=0,binding=5,scalar) buffer readonly PrimitiveIndices {{ + uint8_t primitive_indices[]; }}; layout(set=0,binding=6,scalar) buffer readonly MeshletsBuffer {{ @@ -310,20 +333,21 @@ void main() {{ uint meshlet_index = gl_WorkGroupID.x; Meshlet meshlet = meshlets[meshlet_index]; + Mesh mesh = meshes[meshlet.instance_index]; uint instance_index = meshlet.instance_index; SetMeshOutputsEXT(meshlet.vertex_count, meshlet.triangle_count); - if (gl_LocalInvocationID.x < uint(meshlet.vertex_count) && gl_LocalInvocationID.x < {VERTEX_COUNT}) {{ - uint vertex_index = uint(meshlet.vertex_offset) + gl_LocalInvocationID.x; + if (gl_LocalInvocationID.x < uint(meshlet.vertex_count)) {{ + uint vertex_index = mesh.base_vertex_index + uint32_t(vertex_indices[uint(meshlet.vertex_offset) + gl_LocalInvocationID.x]); gl_MeshVerticesEXT[gl_LocalInvocationID.x].gl_Position = camera.view_projection * meshes[instance_index].model * vec4(vertex_positions[vertex_index], 1.0); // gl_MeshVerticesEXT[gl_LocalInvocationID.x].gl_Position = vec4(vertex_positions[vertex_index], 1.0); }} - if (gl_LocalInvocationID.x < uint(meshlet.triangle_count) && gl_LocalInvocationID.x < {TRIANGLE_COUNT}) {{ + if (gl_LocalInvocationID.x < uint(meshlet.triangle_count)) {{ uint triangle_index = uint(meshlet.triangle_offset) + gl_LocalInvocationID.x; - uint triangle_indices[3] = uint[](indices[triangle_index * 3 + 0], indices[triangle_index * 3 + 1], indices[triangle_index * 3 + 2]); + uint triangle_indices[3] = uint[](primitive_indices[triangle_index * 3 + 0], primitive_indices[triangle_index * 3 + 1], primitive_indices[triangle_index * 3 + 2]); gl_PrimitiveTriangleIndicesEXT[gl_LocalInvocationID.x] = uvec3(triangle_indices[0], triangle_indices[1], triangle_indices[2]); out_instance_index[gl_LocalInvocationID.x] = instance_index; out_primitive_index[gl_LocalInvocationID.x] = (meshlet_index << 8) | (gl_LocalInvocationID.x & 0xFF); @@ -335,6 +359,7 @@ void main() {{ #pragma shader_stage(fragment) #extension GL_EXT_scalar_block_layout: enable + #extension GL_EXT_shader_explicit_arithmetic_types : enable #extension GL_EXT_buffer_reference: enable #extension GL_EXT_buffer_reference2: enable #extension GL_EXT_mesh_shader: require @@ -414,10 +439,12 @@ void main() {{ #extension GL_EXT_scalar_block_layout: enable #extension GL_EXT_buffer_reference2: enable + #extension GL_EXT_shader_explicit_arithmetic_types : enable struct Mesh { mat4 model; uint material_index; + uint32_t base_vertex_index; }; layout(set=0,binding=1,scalar) buffer MeshesBuffer { @@ -451,6 +478,7 @@ void main() {{ #extension GL_EXT_scalar_block_layout: enable #extension GL_EXT_buffer_reference2: enable + #extension GL_EXT_shader_explicit_arithmetic_types : enable layout(set=1,binding=0,scalar) buffer MaterialCount { uint material_count[]; @@ -487,11 +515,12 @@ void main() {{ #extension GL_EXT_scalar_block_layout: enable #extension GL_EXT_buffer_reference2: enable - #extension GL_EXT_shader_explicit_arithmetic_types_int16 : enable + #extension GL_EXT_shader_explicit_arithmetic_types : enable struct Mesh { mat4 model; uint material_index; + uint32_t base_vertex_index; }; layout(set=0,binding=1,scalar) buffer MeshesBuffer { @@ -785,7 +814,7 @@ void main() {{ descriptor_set: material_evaluation_descriptor_set, binding: 4, array_element: 0, - descriptor: render_system::Descriptor::Buffer{ handle: indices_buffer_handle, size: render_system::Ranges::Whole }, + descriptor: render_system::Descriptor::Buffer{ handle: vertex_indices_buffer_handle, size: render_system::Ranges::Whole }, }, render_system::DescriptorWrite { // CameraData descriptor_set: material_evaluation_descriptor_set, @@ -1012,7 +1041,8 @@ void main() { vertex_positions_buffer: vertex_positions_buffer_handle, vertex_normals_buffer: vertex_normals_buffer_handle, - indices_buffer: indices_buffer_handle, + vertex_indices_buffer: vertex_indices_buffer_handle, + primitive_indices_buffer: primitive_indices_buffer_handle, descriptor_set_layout, descriptor_set, @@ -1356,7 +1386,7 @@ void main() { access: render_system::AccessPolicies::READ, layout: render_system::Layouts::General, },render_system::Consumption{ - handle: render_system::Handle::Buffer(self.indices_buffer), + handle: render_system::Handle::Buffer(self.primitive_indices_buffer), stages: render_system::Stages::MESH, access: render_system::AccessPolicies::READ, layout: render_system::Layouts::General, @@ -1412,7 +1442,7 @@ void main() { layout: render_system::Layouts::General, }, render_system::Consumption { - handle: render_system::Handle::Buffer(self.indices_buffer), + handle: render_system::Handle::Buffer(self.primitive_indices_buffer), stages: render_system::Stages::MESH, access: render_system::AccessPolicies::READ, layout: render_system::Layouts::General, @@ -1648,7 +1678,7 @@ impl orchestrator::EntitySubscriber for VisibilityWorldRenderDom #[repr(C)] struct ShaderMeshletData { instance_index: u32, - vertex_offset: u16, + vertex_triangles_offset: u16, triangle_offset: u16, vertex_count: u8, triangle_count: u8, @@ -1658,7 +1688,9 @@ struct ShaderMeshletData { struct ShaderInstanceData { model: Mat4f, material_id: u32, + base_vertex_index: u32, } + #[repr(C)] struct LightingData { count: u32, @@ -1703,21 +1735,28 @@ impl orchestrator::EntitySubscriber for VisibilityWorldRenderDomain { let mut options = resource_manager::Options { resources: Vec::new(), }; + let mut meshlet_stream_buffer = vec![0u8; 1024 * 8]; + for resource in &resource_request.resources { match resource.class.as_str() { "Mesh" => { let vertex_positions_buffer = render_system.get_mut_buffer_slice(self.vertex_positions_buffer); let vertex_normals_buffer = render_system.get_mut_buffer_slice(self.vertex_normals_buffer); - let index_buffer = render_system.get_mut_buffer_slice(self.indices_buffer); + let vertex_indices_buffer = render_system.get_mut_buffer_slice(self.vertex_indices_buffer); + let primitive_indices_buffer = render_system.get_mut_buffer_slice(self.primitive_indices_buffer); options.resources.push(resource_manager::OptionResource { url: resource.url.clone(), - buffers: vec![ - resource_manager::Buffer{ buffer: &mut vertex_positions_buffer[(self.visiblity_info.vertex_count as usize * std::mem::size_of::())..], tag: "Vertex.Position".to_string() }, - resource_manager::Buffer{ buffer: &mut vertex_normals_buffer[(self.visiblity_info.vertex_count as usize * std::mem::size_of::())..], tag: "Vertex.Normal".to_string() }, - resource_manager::Buffer{ buffer: &mut index_buffer[(self.visiblity_info.triangle_count as usize * 3 * std::mem::size_of::())..], tag: "MeshletIndices".to_string() } + streams: vec![ + resource_manager::Stream{ buffer: &mut vertex_positions_buffer[(self.visiblity_info.vertex_count as usize * std::mem::size_of::())..], name: "Vertex.Position".to_string() }, + resource_manager::Stream{ buffer: &mut vertex_normals_buffer[(self.visiblity_info.vertex_count as usize * std::mem::size_of::())..], name: "Vertex.Normal".to_string() }, + resource_manager::Stream{ buffer: &mut vertex_indices_buffer[(self.visiblity_info.vertex_count as usize * std::mem::size_of::())..], name: "Indices".to_string() }, + resource_manager::Stream{ buffer: &mut primitive_indices_buffer[(self.visiblity_info.triangle_count as usize * 3 * std::mem::size_of::())..], name: "MeshletIndices".to_string() }, + resource_manager::Stream{ buffer: meshlet_stream_buffer.as_mut_slice() , name: "Meshlets".to_string() }, ], }); + + break; } _ => {} } @@ -1735,28 +1774,46 @@ impl orchestrator::EntitySubscriber for VisibilityWorldRenderDomain { let mesh: &mesh_resource_handler::Mesh = resource.resource.downcast_ref().unwrap(); { - let vertex_offset = self.visiblity_info.vertex_count; - let triangle_offset = self.visiblity_info.triangle_count; + let vertex_triangles_offset = self.visiblity_info.vertex_count; + let primitive_triangle_offset = self.visiblity_info.triangle_count; + + let meshlet_count; - let meshlet_count = (mesh.vertex_count).div_ceil(63); + if let Some(meshlet_data) = &mesh.meshlet_stream { + meshlet_count = meshlet_data.count; + } else { + meshlet_count = 0; + }; let mut mesh_vertex_count = 0; let mut mesh_triangle_count = 0; let mut meshlets = Vec::with_capacity(meshlet_count as usize); + let raw_mesh_stream = mesh.index_streams.iter().find(|is| is.stream_type == mesh_resource_handler::IndexStreamTypes::Raw).unwrap(); let meshlet_index_stream = mesh.index_streams.iter().find(|is| is.stream_type == mesh_resource_handler::IndexStreamTypes::Meshlets).unwrap(); assert_eq!(meshlet_index_stream.data_type, mesh_resource_handler::IntegralTypes::U8, "Meshlet index stream is not u8"); - for _ in 0..meshlet_count { - let meshlet_vertex_count = (mesh.vertex_count - mesh_vertex_count).min(63) as u8; - let meshlet_triangle_count = (meshlet_index_stream.count / 3 - mesh_triangle_count).min(21) as u8; + struct Meshlet { + vertex_count: u8, + triangle_count: u8, + } + + let meshlet_stream = unsafe { + // assert_eq!(meshlet_count as usize, meshlet_stream_buffer.len() / std::mem::size_of::()); + std::slice::from_raw_parts(meshlet_stream_buffer.as_ptr() as *const Meshlet, meshlet_count as usize) + }; + + for i in 0..meshlet_count as usize { + let meshlet = &meshlet_stream[i]; + let meshlet_vertex_count = meshlet.vertex_count; + let meshlet_triangle_count = meshlet.triangle_count; let meshlet_data = ShaderMeshletData { instance_index: self.visiblity_info.instance_count, - vertex_offset: vertex_offset as u16 + mesh_vertex_count as u16, - triangle_offset:triangle_offset as u16 + mesh_triangle_count as u16, + vertex_triangles_offset: vertex_triangles_offset as u16 + mesh_vertex_count as u16, + triangle_offset:primitive_triangle_offset as u16 + mesh_triangle_count as u16, vertex_count: meshlet_vertex_count, triangle_count: meshlet_triangle_count, }; @@ -1767,7 +1824,7 @@ impl orchestrator::EntitySubscriber for VisibilityWorldRenderDomain { mesh_triangle_count += meshlet_triangle_count as u32; } - self.meshes.insert(resource.url.clone(), MeshData{ meshlets, vertex_count: mesh_vertex_count, triangle_count: mesh_triangle_count, }); + self.meshes.insert(resource.url.clone(), MeshData{ meshlets, vertex_count: mesh_vertex_count, triangle_count: mesh_triangle_count, vertex_offset: self.visiblity_info.vertex_count }); } } _ => {} @@ -1777,34 +1834,36 @@ impl orchestrator::EntitySubscriber for VisibilityWorldRenderDomain { let meshes_data_slice = render_system.get_mut_buffer_slice(self.meshes_data_buffer); - let mesh_data = ShaderInstanceData { + let mesh_data = self.meshes.get(mesh.resource_id).expect("Mesh not loaded"); + + let shader_mesh_data = ShaderInstanceData { model: mesh.transform, material_id: self.material_evaluation_materials.get(mesh.material_id).unwrap().0, + base_vertex_index: mesh_data.vertex_offset, }; let meshes_data_slice = unsafe { std::slice::from_raw_parts_mut(meshes_data_slice.as_mut_ptr() as *mut ShaderInstanceData, MAX_INSTANCES) }; - meshes_data_slice[self.visiblity_info.instance_count as usize] = mesh_data; + meshes_data_slice[self.visiblity_info.instance_count as usize] = shader_mesh_data; let meshlets_data_slice = render_system.get_mut_buffer_slice(self.meshlets_data_buffer); let meshlets_data_slice = unsafe { std::slice::from_raw_parts_mut(meshlets_data_slice.as_mut_ptr() as *mut ShaderMeshletData, MAX_MESHLETS) }; - let mesh = self.meshes.get(mesh.resource_id).expect("Mesh not loaded"); - - for (i, meshlet) in mesh.meshlets.iter().enumerate() { + for (i, meshlet) in mesh_data.meshlets.iter().enumerate() { let meshlet = ShaderMeshletData { instance_index: self.visiblity_info.instance_count, ..(*meshlet) }; meshlets_data_slice[self.visiblity_info.meshlet_count as usize + i] = meshlet; } - self.visiblity_info.meshlet_count += mesh.meshlets.len() as u32; - self.visiblity_info.vertex_count += mesh.vertex_count; - self.visiblity_info.triangle_count += mesh.triangle_count; + self.visiblity_info.meshlet_count += mesh_data.meshlets.len() as u32; + self.visiblity_info.vertex_count += mesh_data.vertex_count; + self.visiblity_info.triangle_count += mesh_data.triangle_count; self.visiblity_info.instance_count += 1; assert!((self.visiblity_info.meshlet_count as usize) < MAX_MESHLETS, "Meshlet count exceeded"); assert!((self.visiblity_info.instance_count as usize) < MAX_INSTANCES, "Instance count exceeded"); assert!((self.visiblity_info.vertex_count as usize) < MAX_VERTICES, "Vertex count exceeded"); + assert!((self.visiblity_info.vertex_count as usize) < MAX_PRIMITIVE_TRIANGLES, "Primitive triangle count exceeded"); assert!((self.visiblity_info.triangle_count as usize) < MAX_TRIANGLES, "Triangle count exceeded"); } } diff --git a/src/rendering/visibility_shader_generator.rs b/src/rendering/visibility_shader_generator.rs index 45118c55..261095e7 100644 --- a/src/rendering/visibility_shader_generator.rs +++ b/src/rendering/visibility_shader_generator.rs @@ -102,7 +102,32 @@ impl VisibilityShaderGenerator { fn fragment_transform(&self, material: &json::JsonValue, shader_node: &lexer::Node) -> String { let mut string = shader_generator::generate_glsl_header_block(&json::object! { "glsl": { "version": "450" }, "stage": "Compute" }); - string.push_str("layout(set=0,binding=5) uniform sampler2D textures[1]; + string.push_str(" +struct Mesh { + mat4 model; + uint material_id; + uint32_t base_vertex_index; +}; + +layout(set=0, binding=1, scalar) buffer readonly MeshBuffer { + Mesh meshes[]; +}; + +layout(set=0, binding=2, scalar) buffer readonly Positions { + vec3 positions[]; +}; + +layout(set=0, binding=3, scalar) buffer readonly Normals { + vec3 normals[]; +}; + +layout(set=0, binding=4, scalar) buffer readonly VertexIndices { + uint16_t vertex_indices[]; +}; + +layout(set=0, binding=5, scalar) buffer readonly PrimitiveIndeces { + uint8_t primitive_indeces[]; +}; struct Meshlet { uint32_t instance_index; @@ -116,15 +141,20 @@ layout(set=0,binding=6,scalar) buffer readonly MeshletsBuffer { Meshlet meshlets[]; }; +layout(set=0,binding=7) uniform sampler2D textures[1]; + layout(set=1,binding=0,scalar) buffer MaterialCount { uint material_count[]; }; + layout(set=1,binding=1,scalar) buffer MaterialOffset { uint material_offset[]; }; + layout(set=1,binding=4,scalar) buffer PixelMapping { u16vec2 pixel_mapping[]; }; + layout(set=1, binding=6, r32ui) uniform readonly uimage2D triangle_index; layout(set=1, binding=7, r32ui) uniform readonly uimage2D instance_id; layout(set=2, binding=0, rgba16) uniform image2D out_albedo; @@ -177,27 +207,6 @@ BarycentricDeriv CalcFullBary(vec4 pt0, vec4 pt1, vec4 pt2, vec2 pixelNdc, vec2 return ret; } -struct Mesh { - mat4 model; - uint material_id; -}; - -layout(set=2, binding=1, scalar) buffer readonly MeshBuffer { - Mesh meshes[]; -}; - -layout(set=2, binding=2, scalar) buffer readonly Positions { - vec3 positions[]; -}; - -layout(set=2, binding=3, scalar) buffer readonly Normals { - vec3 normals[]; -}; - -layout(set=2, binding=4, scalar) buffer readonly Indeces { - uint8_t indeces[]; -}; - const float PI = 3.14159265359; float DistributionGGX(vec3 N, vec3 H, float roughness) { @@ -338,10 +347,16 @@ void main() { Material material = materials[pc.material_id]; Meshlet meshlet = meshlets[BE_MESHLET_INDEX]; + uint primitive_indices[3] = uint[3]( + uint(primitive_indeces[(meshlet.triangle_offset + BE_MESHLET_TRIANGLE_INDEX) * 3 + 0]), + uint(primitive_indeces[(meshlet.triangle_offset + BE_MESHLET_TRIANGLE_INDEX) * 3 + 1]), + uint(primitive_indeces[(meshlet.triangle_offset + BE_MESHLET_TRIANGLE_INDEX) * 3 + 2]) + ); + uint vertex_indeces[3] = uint[3]( - uint(indeces[meshlet.triangle_offset * 3 + BE_MESHLET_TRIANGLE_INDEX * 3 + 0] + meshlet.vertex_offset), - uint(indeces[meshlet.triangle_offset * 3 + BE_MESHLET_TRIANGLE_INDEX * 3 + 1] + meshlet.vertex_offset), - uint(indeces[meshlet.triangle_offset * 3 + BE_MESHLET_TRIANGLE_INDEX * 3 + 2] + meshlet.vertex_offset) + mesh.base_vertex_index + uint(vertex_indices[meshlet.vertex_offset + primitive_indices[0]]), + mesh.base_vertex_index + uint(vertex_indices[meshlet.vertex_offset + primitive_indices[1]]), + mesh.base_vertex_index + uint(vertex_indices[meshlet.vertex_offset + primitive_indices[2]]) ); vec4 vertex_positions[3] = vec4[3]( diff --git a/src/rendering/vulkan_render_system.rs b/src/rendering/vulkan_render_system.rs index 14e777da..a7f1dfab 100644 --- a/src/rendering/vulkan_render_system.rs +++ b/src/rendering/vulkan_render_system.rs @@ -138,7 +138,11 @@ impl render_system::RenderSystem for VulkanRenderSystem { let mut error_string = String::new(); for (error_line_index, error) in errors { - error_string.push_str(&format!("{} Error: {}\n", shader_text.lines().nth(error_line_index).unwrap(), error)); + let previous_line = shader_text.lines().nth(error_line_index - 1).unwrap_or(""); + let current_line = shader_text.lines().nth(error_line_index).unwrap_or(""); + let next_line = shader_text.lines().nth(error_line_index + 1).unwrap_or(""); + + error_string.push_str(&format!("{}\n{} Error: {}\n{}\n", previous_line, current_line, error, next_line)); } error!("Error compiling shader:\n{}", error_string); @@ -3098,19 +3102,19 @@ impl render_system::CommandBufferRecording for VulkanCommandBufferRecording<'_> buffer_memory_barriers.push(buffer_memory_barrier); - // let memory_barrier = if let Some(source) = self.states.get(&consumption.handle) { - // vk::MemoryBarrier2::default() - // .src_stage_mask(source.stage) - // .src_access_mask(source.access) - // } else { - // vk::MemoryBarrier2::default() - // .src_stage_mask(vk::PipelineStageFlags2::empty()) - // .src_access_mask(vk::AccessFlags2KHR::empty()) - // } - // .dst_stage_mask(new_stage_mask) - // .dst_access_mask(new_access_mask); - - // memory_barriers.push(memory_barrier); + let memory_barrier = if let Some(source) = self.states.get(&consumption.handle) { + vk::MemoryBarrier2::default() + .src_stage_mask(source.stage) + .src_access_mask(source.access) + } else { + vk::MemoryBarrier2::default() + .src_stage_mask(vk::PipelineStageFlags2::empty()) + .src_access_mask(vk::AccessFlags2KHR::empty()) + } + .dst_stage_mask(new_stage_mask) + .dst_access_mask(new_access_mask); + + memory_barriers.push(memory_barrier); }, render_system::Handle::TopLevelAccelerationStructure(_) | render_system::Handle::BottomLevelAccelerationStructure(_)=> { // let (handle, acceleration_structure) = self.get_top_level_acceleration_structure(handle); diff --git a/src/resource_manager/material_resource_handler.rs b/src/resource_manager/material_resource_handler.rs index 2e5e8096..575c84ef 100644 --- a/src/resource_manager/material_resource_handler.rs +++ b/src/resource_manager/material_resource_handler.rs @@ -81,7 +81,7 @@ impl ResourceHandler for MaterialResourcerHandler { } } - fn read(&self, _resource: &Box, file: &mut std::fs::File, buffers: &mut [super::Buffer]) { + fn read(&self, _resource: &Box, file: &mut std::fs::File, buffers: &mut [super::Stream]) { file.read_exact(buffers[0].buffer).unwrap(); } @@ -191,8 +191,19 @@ impl MaterialResourcerHandler { // TODO: if shader fails to compile try to generate a failsafe shader let compilation_artifact = match binary { Ok(binary) => { binary } Err(err) => { - error!("Failed to compile shader: {}", err); - error!("{}", &glsl); + let error_string = err.to_string(); + let errors = error_string.lines().filter(|error| error.starts_with("shader_name:")).map(|error| (error.split(':').nth(1).unwrap(), error.split(':').nth(4).unwrap())).map(|(error_line_number_string, error)| (error_line_number_string.trim().parse::().unwrap(), error.trim())).collect::>(); + let mut error_string = String::new(); + + for (error_line_index, error) in errors { + let previous_line = glsl.lines().nth(error_line_index - 1).unwrap_or(""); + let current_line = glsl.lines().nth(error_line_index).unwrap_or(""); + let next_line = glsl.lines().nth(error_line_index + 1).unwrap_or(""); + + error_string.push_str(&format!("{} Error: {}\n{}\n{}\n", previous_line, current_line, next_line, error)); + } + + error!("Error compiling shader:\n{}", error_string); return Some(Err(err.to_string())); } }; diff --git a/src/resource_manager/mesh_resource_handler.rs b/src/resource_manager/mesh_resource_handler.rs index 7171b41d..bc2cfb68 100644 --- a/src/resource_manager/mesh_resource_handler.rs +++ b/src/resource_manager/mesh_resource_handler.rs @@ -78,7 +78,7 @@ impl ResourceHandler for MeshResourceHandler { if let Some(tangents) = reader.read_tangents() { tangents.for_each(|tangent| tangent.iter().for_each(|m| m.to_le_bytes().iter().for_each(|byte| buffer.push(*byte)))); - vertex_components.push(VertexComponent { semantic: VertexSemantics::Tangent, format: "vec3f".to_string(), channel: 2 }); + vertex_components.push(VertexComponent { semantic: VertexSemantics::Tangent, format: "vec4f".to_string(), channel: 2 }); } if let Some(uv) = reader.read_tex_coords(0) { @@ -91,27 +91,33 @@ impl ResourceHandler for MeshResourceHandler { let mut index_streams = Vec::with_capacity(2); - let offset = buffer.len(); - - { - let index_type = IntegralTypes::U16; - - match index_type { - IntegralTypes::U16 => { - optimized_indices.iter().map(|i| *i as u16).for_each(|index| index.to_le_bytes().iter().for_each(|byte| buffer.push(*byte))); - index_streams.push(IndexStream{ data_type: IntegralTypes::U16, stream_type: IndexStreamTypes::Raw, offset, count: optimized_indices.len() as u32 }); - } - _ => panic!("Unsupported index type") - } - } - - let offset = buffer.len(); - let meshlet_stream; if MESHLETIZE { let meshlets = meshopt::clusterize::build_meshlets(&optimized_indices, vertex_count, 64, 126); + let offset = buffer.len(); + + { + let index_type = IntegralTypes::U16; + + match index_type { + IntegralTypes::U16 => { + let mut index_count = 0usize; + for meshlet in &meshlets { + index_count += meshlet.vertex_count as usize; + for i in 0..meshlet.vertex_count as usize { + (meshlet.vertices[i] as u16).to_le_bytes().iter().for_each(|byte| buffer.push(*byte)); + } + } + index_streams.push(IndexStream{ data_type: IntegralTypes::U16, stream_type: IndexStreamTypes::Raw, offset, count: index_count as u32 }); + } + _ => panic!("Unsupported index type") + } + } + + let offset = buffer.len(); + let mut index_count: usize = 0; for meshlet in &meshlets { @@ -126,7 +132,7 @@ impl ResourceHandler for MeshResourceHandler { assert_eq!(index_count, optimized_indices.len()); - index_streams.push(IndexStream{ data_type: IntegralTypes::U8, stream_type: IndexStreamTypes::Meshlets, offset, count: optimized_indices.len() as u32 }); + index_streams.push(IndexStream{ data_type: IntegralTypes::U8, stream_type: IndexStreamTypes::Meshlets, offset, count: index_count as u32 }); let offset = buffer.len(); @@ -137,6 +143,20 @@ impl ResourceHandler for MeshResourceHandler { buffer.push(meshlet.triangle_count); } } else { + let offset = buffer.len(); + + { + let index_type = IntegralTypes::U16; + + match index_type { + IntegralTypes::U16 => { + optimized_indices.iter().map(|i| *i as u16).for_each(|i| i.to_le_bytes().iter().for_each(|byte| buffer.push(*byte))); + index_streams.push(IndexStream{ data_type: IntegralTypes::U16, stream_type: IndexStreamTypes::Raw, offset, count: optimized_indices.len() as u32 }); + } + _ => panic!("Unsupported index type") + } + } + meshlet_stream = None; } @@ -165,11 +185,11 @@ impl ResourceHandler for MeshResourceHandler { }))] } - fn read(&self, resource: &Box, file: &mut std::fs::File, buffers: &mut [super::Buffer]) { + fn read(&self, resource: &Box, file: &mut std::fs::File, buffers: &mut [super::Stream]) { let mesh: &Mesh = resource.downcast_ref().unwrap(); for buffer in buffers { - match buffer.tag.as_str() { + match buffer.name.as_str() { "Vertex" => { file.seek(std::io::SeekFrom::Start(0)).unwrap(); file.read(&mut buffer.buffer[0..(mesh.vertex_count as usize * mesh.vertex_components.size())]).unwrap(); @@ -213,7 +233,7 @@ impl ResourceHandler for MeshResourceHandler { file.read(&mut buffer.buffer[0..(meshlet_stream.count as usize * 2)]).unwrap(); } _ => { - error!("Unknown buffer tag: {}", buffer.tag); + error!("Unknown buffer tag: {}", buffer.name); } } } @@ -375,7 +395,7 @@ impl Size for IntegralTypes { #[cfg(test)] mod tests { - use crate::{resource_manager::{resource_manager::ResourceManager, Options, OptionResource, Buffer}, Vector3}; + use crate::{resource_manager::{resource_manager::ResourceManager, Options, OptionResource, Stream}, Vector3}; use super::*; @@ -430,6 +450,8 @@ mod tests { assert_eq!(mesh.index_streams[0].count, 36); assert_eq!(mesh.index_streams[0].data_type, IntegralTypes::U16); + let meshlet_stream_info = mesh.meshlet_stream.as_ref().unwrap(); + let offset = offset + mesh.index_streams[0].count as usize * mesh.index_streams[0].data_type.size(); assert_eq!(mesh.index_streams[1].stream_type, IndexStreamTypes::Meshlets); @@ -452,7 +474,7 @@ mod tests { "Mesh" => { options.resources.push(OptionResource { url: resource.url.clone(), - buffers: vec![Buffer{ buffer: vertex_buffer.as_mut_slice(), tag: "Vertex".to_string() }, Buffer{ buffer: index_buffer.as_mut_slice(), tag: "Indices".to_string() }], + streams: vec![Stream{ buffer: vertex_buffer.as_mut_slice(), name: "Vertex".to_string() }, Stream{ buffer: index_buffer.as_mut_slice(), name: "Indices".to_string() }], }); } _ => {} @@ -621,7 +643,7 @@ mod tests { "Mesh" => { options.resources.push(OptionResource { url: resource.url.clone(), - buffers: vec![Buffer{ buffer: vertex_buffer.as_mut_slice(), tag: "Vertex".to_string() }, Buffer{ buffer: index_buffer.as_mut_slice(), tag: "Indices".to_string() }], + streams: vec![Stream{ buffer: vertex_buffer.as_mut_slice(), name: "Vertex".to_string() }, Stream{ buffer: index_buffer.as_mut_slice(), name: "Indices".to_string() }], }); } _ => {} @@ -684,10 +706,10 @@ mod tests { "Mesh" => { options.resources.push(OptionResource { url: resource.url.clone(), - buffers: vec![ - Buffer{ buffer: vertex_positions_buffer.as_mut_slice(), tag: "Vertex.Position".to_string() }, - Buffer{ buffer: vertex_normals_buffer.as_mut_slice(), tag: "Vertex.Normal".to_string() }, - Buffer{ buffer: index_buffer.as_mut_slice(), tag: "Indices".to_string() } + streams: vec![ + Stream{ buffer: vertex_positions_buffer.as_mut_slice(), name: "Vertex.Position".to_string() }, + Stream{ buffer: vertex_normals_buffer.as_mut_slice(), name: "Vertex.Normal".to_string() }, + Stream{ buffer: index_buffer.as_mut_slice(), name: "Indices".to_string() } ], }); } diff --git a/src/resource_manager/mod.rs b/src/resource_manager/mod.rs index 6a66cf86..a0285c0b 100644 --- a/src/resource_manager/mod.rs +++ b/src/resource_manager/mod.rs @@ -46,11 +46,11 @@ pub enum ProcessedResources { Ref(String), } -pub struct Buffer<'a> { +pub struct Stream<'a> { /// The slice of the buffer to load the resource binary data into. pub buffer: &'a mut [u8], /// The subresource tag. This is used to identify the subresource. (EJ: "Vertex", "Index", etc.) - pub tag: String, + pub name: String, } /// Enumaration for all the possible results of a resource load fails. @@ -113,7 +113,7 @@ pub struct OptionResource<'a> { /// The resource to apply this option to. pub url: String, /// The buffers to load the resource binary data into. - pub buffers: Vec>, + pub streams: Vec>, } /// Represents the options for performing a bundled/batch resource load. diff --git a/src/resource_manager/resource_handler.rs b/src/resource_manager/resource_handler.rs index eed0b9f8..4c79537c 100644 --- a/src/resource_manager/resource_handler.rs +++ b/src/resource_manager/resource_handler.rs @@ -1,4 +1,4 @@ -use super::{resource_manager, ProcessedResources, Buffer}; +use super::{resource_manager, ProcessedResources, Stream}; pub trait ResourceHandler { fn can_handle_type(&self, resource_type: &str) -> bool; @@ -18,5 +18,5 @@ pub trait ResourceHandler { fn get_deserializers(&self) -> Vec<(&'static str, Box Box + Send>)>; - fn read(&self, _resource: &Box, file: &mut std::fs::File, buffers: &mut [Buffer]); + fn read(&self, _resource: &Box, file: &mut std::fs::File, buffers: &mut [Stream]); } \ No newline at end of file diff --git a/src/resource_manager/resource_manager.rs b/src/resource_manager/resource_manager.rs index 1f406699..1f31bd48 100644 --- a/src/resource_manager/resource_manager.rs +++ b/src/resource_manager/resource_manager.rs @@ -354,7 +354,7 @@ impl ResourceManager { let _slice = if let Some(options) = &mut options { if let Some(x) = options.resources.iter_mut().find(|e| e.url == resource_container.url) { self.resource_handlers.iter().find(|h| h.can_handle_type(resource_container.class.as_str())).unwrap(). - read(&response.resource, &mut file, x.buffers.as_mut_slice()); + read(&response.resource, &mut file, x.streams.as_mut_slice()); } else { let range = &mut buffer[offset..(offset + resource_container.size as usize)]; offset += resource_container.size as usize; diff --git a/src/resource_manager/texture_resource_handler.rs b/src/resource_manager/texture_resource_handler.rs index 1d165e6a..326aaaf0 100644 --- a/src/resource_manager/texture_resource_handler.rs +++ b/src/resource_manager/texture_resource_handler.rs @@ -70,7 +70,7 @@ impl ResourceHandler for ImageResourceHandler { Ok(vec![ProcessedResources::Generated((resource_document, intel_tex_2::bc7::compress_blocks(&settings, &rgba_surface)))]) } - fn read(&self, _resource: &Box, file: &mut std::fs::File, buffers: &mut [super::Buffer]) { + fn read(&self, _resource: &Box, file: &mut std::fs::File, buffers: &mut [super::Stream]) { file.read_exact(buffers[0].buffer).unwrap(); }