From dfc384a7fd4ab7250a75d59c6f831d9ffb220f7e Mon Sep 17 00:00:00 2001 From: Vecvec <130132884+Vecvec@users.noreply.github.com> Date: Thu, 19 Sep 2024 09:02:25 +1200 Subject: [PATCH] Stop Vulkan generating validation error in build acceleration structures (#6282) --- CHANGELOG.md | 1 + wgpu-hal/examples/ray-traced-triangle/main.rs | 80 ++++++++++++------- wgpu-hal/src/vulkan/command.rs | 3 + 3 files changed, 55 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34bc30131..aafc73b31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -117,6 +117,7 @@ By @bradwerth [#6216](https://github.com/gfx-rs/wgpu/pull/6216). #### Vulkan - Vulkan debug labels assumed no interior nul byte. By @DJMcNab in [#6257](https://github.com/gfx-rs/wgpu/pull/6257) +- Add `.index_type(vk::IndexType::NONE_KHR)` when creating `AccelerationStructureGeometryTrianglesDataKHR` in the raytraced triangle example to prevent a validation error. By @Vecvec in [#6282](https://github.com/gfx-rs/wgpu/pull/6282) ### Changes diff --git a/wgpu-hal/examples/ray-traced-triangle/main.rs b/wgpu-hal/examples/ray-traced-triangle/main.rs index 816827b5a..dd9184373 100644 --- a/wgpu-hal/examples/ray-traced-triangle/main.rs +++ b/wgpu-hal/examples/ray-traced-triangle/main.rs @@ -205,7 +205,7 @@ struct Example { uniform_buffer: A::Buffer, pipeline_layout: A::PipelineLayout, vertices_buffer: A::Buffer, - indices_buffer: A::Buffer, + indices_buffer: Option, texture: A::Texture, instances: [AccelerationStructureInstance; 3], instances_buffer: A::Buffer, @@ -217,6 +217,18 @@ struct Example { impl Example { fn init(window: &winit::window::Window) -> Result> { + let mut index_buffer = false; + + for arg in std::env::args() { + if arg == "index_buffer" { + index_buffer = true; + } + } + + if index_buffer { + log::info!("using index buffer") + } + let instance_desc = hal::InstanceDescriptor { name: "example", flags: wgt::InstanceFlags::default(), @@ -420,29 +432,34 @@ impl Example { vertices_buffer }; - let indices_buffer = unsafe { - let indices_buffer = device - .create_buffer(&hal::BufferDescriptor { - label: Some("indices buffer"), - size: indices_size_in_bytes as u64, - usage: hal::BufferUses::MAP_WRITE - | hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, - memory_flags: hal::MemoryFlags::TRANSIENT | hal::MemoryFlags::PREFER_COHERENT, - }) - .unwrap(); + let indices_buffer = if index_buffer { + unsafe { + let indices_buffer = device + .create_buffer(&hal::BufferDescriptor { + label: Some("indices buffer"), + size: indices_size_in_bytes as u64, + usage: hal::BufferUses::MAP_WRITE + | hal::BufferUses::BOTTOM_LEVEL_ACCELERATION_STRUCTURE_INPUT, + memory_flags: hal::MemoryFlags::TRANSIENT + | hal::MemoryFlags::PREFER_COHERENT, + }) + .unwrap(); - let mapping = device - .map_buffer(&indices_buffer, 0..indices_size_in_bytes as u64) - .unwrap(); - ptr::copy_nonoverlapping( - indices.as_ptr() as *const u8, - mapping.ptr.as_ptr(), - indices_size_in_bytes, - ); - device.unmap_buffer(&indices_buffer); - assert!(mapping.is_coherent); + let mapping = device + .map_buffer(&indices_buffer, 0..indices_size_in_bytes as u64) + .unwrap(); + ptr::copy_nonoverlapping( + indices.as_ptr() as *const u8, + mapping.ptr.as_ptr(), + indices_size_in_bytes, + ); + device.unmap_buffer(&indices_buffer); + assert!(mapping.is_coherent); - indices_buffer + Some((indices_buffer, indices.len())) + } + } else { + None }; let blas_triangles = vec![hal::AccelerationStructureTriangles { @@ -451,12 +468,15 @@ impl Example { vertex_format: wgt::VertexFormat::Float32x3, vertex_count: vertices.len() as u32, vertex_stride: 3 * 4, - indices: Some(hal::AccelerationStructureTriangleIndices { - buffer: Some(&indices_buffer), - format: wgt::IndexFormat::Uint32, - offset: 0, - count: indices.len() as u32, + indices: indices_buffer.as_ref().map(|(buf, len)| { + hal::AccelerationStructureTriangleIndices { + buffer: Some(buf), + format: wgt::IndexFormat::Uint32, + offset: 0, + count: *len as u32, + } }), + transform: None, flags: hal::AccelerationStructureGeometryFlags::OPAQUE, }]; @@ -800,7 +820,7 @@ impl Example { tlas, scratch_buffer, time: 0.0, - indices_buffer, + indices_buffer: indices_buffer.map(|(buf, _)| buf), vertices_buffer, uniform_buffer, texture_view, @@ -1026,7 +1046,9 @@ impl Example { self.device.destroy_bind_group(self.bind_group); self.device.destroy_buffer(self.scratch_buffer); self.device.destroy_buffer(self.instances_buffer); - self.device.destroy_buffer(self.indices_buffer); + if let Some(buffer) = self.indices_buffer { + self.device.destroy_buffer(buffer); + } self.device.destroy_buffer(self.vertices_buffer); self.device.destroy_buffer(self.uniform_buffer); self.device.destroy_acceleration_structure(self.tlas); diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 8bd749cd3..6b02e35f4 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -503,6 +503,9 @@ impl crate::CommandEncoder for super::CommandEncoder { for triangles in in_geometries { let mut triangle_data = vk::AccelerationStructureGeometryTrianglesDataKHR::default() + // IndexType::NONE_KHR is not set by default (due to being provided by VK_KHR_acceleration_structure) but unless there is an + // index buffer we need to have IndexType::NONE_KHR as our index type. + .index_type(vk::IndexType::NONE_KHR) .vertex_data(vk::DeviceOrHostAddressConstKHR { device_address: get_device_address(triangles.vertex_buffer), })