Stop Vulkan generating validation error in build acceleration structures (#6282)

This commit is contained in:
Vecvec 2024-09-19 09:02:25 +12:00 committed by GitHub
parent 0d339fc9f1
commit dfc384a7fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 55 additions and 29 deletions

View File

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

View File

@ -205,7 +205,7 @@ struct Example<A: hal::Api> {
uniform_buffer: A::Buffer,
pipeline_layout: A::PipelineLayout,
vertices_buffer: A::Buffer,
indices_buffer: A::Buffer,
indices_buffer: Option<A::Buffer>,
texture: A::Texture,
instances: [AccelerationStructureInstance; 3],
instances_buffer: A::Buffer,
@ -217,6 +217,18 @@ struct Example<A: hal::Api> {
impl<A: hal::Api> Example<A> {
fn init(window: &winit::window::Window) -> Result<Self, Box<dyn std::error::Error>> {
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<A: hal::Api> Example<A> {
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<A: hal::Api> Example<A> {
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<A: hal::Api> Example<A> {
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<A: hal::Api> Example<A> {
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);

View File

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