From 682f255dc82c378cb01fefc85fe087fc488eb10f Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 7 Jan 2025 10:01:07 +0000 Subject: [PATCH 1/6] Change index offset to first index. --- examples/src/ray_cube_compute/mod.rs | 2 +- examples/src/ray_cube_fragment/mod.rs | 2 +- examples/src/ray_scene/mod.rs | 2 +- examples/src/ray_shadows/mod.rs | 2 +- examples/src/ray_traced_triangle/mod.rs | 4 +- player/src/lib.rs | 4 +- tests/tests/ray_tracing/as_build.rs | 4 +- tests/tests/ray_tracing/as_use_after_free.rs | 2 +- tests/tests/ray_tracing/scene/mod.rs | 2 +- wgpu-core/src/command/ray_tracing.rs | 48 ++++++++++---------- wgpu-core/src/ray_tracing.rs | 4 +- wgpu/src/api/blas.rs | 4 +- wgpu/src/backend/wgpu_core.rs | 4 +- 13 files changed, 41 insertions(+), 43 deletions(-) diff --git a/examples/src/ray_cube_compute/mod.rs b/examples/src/ray_cube_compute/mod.rs index 62a3e36aab..b50657e03b 100644 --- a/examples/src/ray_cube_compute/mod.rs +++ b/examples/src/ray_cube_compute/mod.rs @@ -374,7 +374,7 @@ impl crate::framework::Example for Example { first_vertex: 0, vertex_stride: mem::size_of::() as u64, index_buffer: Some(&index_buf), - index_buffer_offset: Some(0), + first_index: Some(0), transform_buffer: None, transform_buffer_offset: None, }, diff --git a/examples/src/ray_cube_fragment/mod.rs b/examples/src/ray_cube_fragment/mod.rs index b9dfba9a16..9ebf36fb32 100644 --- a/examples/src/ray_cube_fragment/mod.rs +++ b/examples/src/ray_cube_fragment/mod.rs @@ -248,7 +248,7 @@ impl crate::framework::Example for Example { first_vertex: 0, vertex_stride: mem::size_of::() as u64, index_buffer: Some(&index_buf), - index_buffer_offset: Some(0), + first_index: Some(0), transform_buffer: None, transform_buffer_offset: None, }, diff --git a/examples/src/ray_scene/mod.rs b/examples/src/ray_scene/mod.rs index 886d0c0183..1d681b064e 100644 --- a/examples/src/ray_scene/mod.rs +++ b/examples/src/ray_scene/mod.rs @@ -264,7 +264,7 @@ fn upload_scene_components( first_vertex: vertex_range.start as u32, vertex_stride: mem::size_of::() as u64, index_buffer: Some(&indices), - index_buffer_offset: Some(scene.geometries[i].0.start as u64 * 4), + first_index: Some(scene.geometries[i].0.start as u32), transform_buffer: None, transform_buffer_offset: None, }) diff --git a/examples/src/ray_shadows/mod.rs b/examples/src/ray_shadows/mod.rs index adf25cd454..d605662283 100644 --- a/examples/src/ray_shadows/mod.rs +++ b/examples/src/ray_shadows/mod.rs @@ -258,7 +258,7 @@ impl crate::framework::Example for Example { first_vertex: 0, vertex_stride: mem::size_of::() as u64, index_buffer: Some(&index_buf), - index_buffer_offset: Some(0), + first_index: Some(0), transform_buffer: None, transform_buffer_offset: None, }, diff --git a/examples/src/ray_traced_triangle/mod.rs b/examples/src/ray_traced_triangle/mod.rs index d508e6113e..900aafea81 100644 --- a/examples/src/ray_traced_triangle/mod.rs +++ b/examples/src/ray_traced_triangle/mod.rs @@ -216,9 +216,9 @@ impl crate::framework::Example for Example { vertex_buffer: &vertex_buffer, first_vertex: 0, vertex_stride: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, - // in this case since one triangle gets no compression from an index buffer `index_buffer` and `index_buffer_offset` could be `None`. + // in this case since one triangle gets no compression from an index buffer `index_buffer` and `first_index` could be `None`. index_buffer: Some(&index_buffer), - index_buffer_offset: Some(0), + first_index: Some(0), transform_buffer: None, transform_buffer_offset: None, }]), diff --git a/player/src/lib.rs b/player/src/lib.rs index af82168ae4..33b038f249 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -133,7 +133,7 @@ impl GlobalPlay for wgc::global::Global { transform_buffer: tg.transform_buffer, first_vertex: tg.first_vertex, vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, + first_index: tg.first_index, transform_buffer_offset: tg.transform_buffer_offset, } }); @@ -171,7 +171,7 @@ impl GlobalPlay for wgc::global::Global { transform_buffer: tg.transform_buffer, first_vertex: tg.first_vertex, vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, + first_index: tg.first_index, transform_buffer_offset: tg.transform_buffer_offset, } }); diff --git a/tests/tests/ray_tracing/as_build.rs b/tests/tests/ray_tracing/as_build.rs index a75b280724..5255694011 100644 --- a/tests/tests/ray_tracing/as_build.rs +++ b/tests/tests/ray_tracing/as_build.rs @@ -75,7 +75,7 @@ impl AsBuildContext { first_vertex: 0, vertex_stride: mem::size_of::<[f32; 3]>() as BufferAddress, index_buffer: None, - index_buffer_offset: None, + first_index: None, transform_buffer: None, transform_buffer_offset: None, }]), @@ -406,7 +406,7 @@ fn build_with_transform(ctx: TestingContext) { first_vertex: 0, vertex_stride: mem::size_of::<[f32; 3]>() as BufferAddress, index_buffer: None, - index_buffer_offset: None, + first_index: None, transform_buffer: Some(&transform), transform_buffer_offset: Some(0), }]), diff --git a/tests/tests/ray_tracing/as_use_after_free.rs b/tests/tests/ray_tracing/as_use_after_free.rs index ae6c49da28..fcbc75b3a5 100644 --- a/tests/tests/ray_tracing/as_use_after_free.rs +++ b/tests/tests/ray_tracing/as_use_after_free.rs @@ -78,7 +78,7 @@ fn acceleration_structure_use_after_free(ctx: TestingContext) { first_vertex: 0, vertex_stride: mem::size_of::<[f32; 3]>() as BufferAddress, index_buffer: None, - index_buffer_offset: None, + first_index: None, transform_buffer: None, transform_buffer_offset: None, }]), diff --git a/tests/tests/ray_tracing/scene/mod.rs b/tests/tests/ray_tracing/scene/mod.rs index 299323af58..bd3a08da05 100644 --- a/tests/tests/ray_tracing/scene/mod.rs +++ b/tests/tests/ray_tracing/scene/mod.rs @@ -85,7 +85,7 @@ fn acceleration_structure_build(ctx: &TestingContext, use_index_buffer: bool) { first_vertex: 0, vertex_stride: mem::size_of::() as u64, index_buffer: use_index_buffer.then_some(&index_buffer), - index_buffer_offset: use_index_buffer.then_some(0), + first_index: use_index_buffer.then_some(0), transform_buffer: None, transform_buffer_offset: None, }]), diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 9395c20fc1..2d66f6e2df 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -109,7 +109,7 @@ impl Global { transform_buffer: tg.transform_buffer, first_vertex: tg.first_vertex, vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, + first_index: tg.first_index, transform_buffer_offset: tg.transform_buffer_offset, }) .collect(), @@ -149,7 +149,7 @@ impl Global { transform_buffer: tg.transform_buffer, first_vertex: tg.first_vertex, vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, + first_index: tg.first_index, transform_buffer_offset: tg.transform_buffer_offset, }); BlasGeometries::TriangleGeometries(Box::new(iter)) @@ -408,7 +408,7 @@ impl Global { transform_buffer: tg.transform_buffer, first_vertex: tg.first_vertex, vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, + first_index: tg.first_index, transform_buffer_offset: tg.transform_buffer_offset, }) .collect(), @@ -461,7 +461,7 @@ impl Global { transform_buffer: tg.transform_buffer, first_vertex: tg.first_vertex, vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, + first_index: tg.first_index, transform_buffer_offset: tg.transform_buffer_offset, }); BlasGeometries::TriangleGeometries(Box::new(iter)) @@ -979,7 +979,7 @@ fn iter_blas<'a>( Ok(buffer) => buffer, Err(_) => return Err(BuildAccelerationStructureError::InvalidBufferId), }; - if mesh.index_buffer_offset.is_none() + if mesh.first_index.is_none() || mesh.size.index_count.is_none() || mesh.size.index_count.is_none() { @@ -1110,11 +1110,8 @@ fn iter_buffers<'a, 'b>( wgt::IndexFormat::Uint16 => 2, wgt::IndexFormat::Uint32 => 4, }; - if mesh.index_buffer_offset.unwrap() % index_stride != 0 { - return Err(BuildAccelerationStructureError::UnalignedIndexBufferOffset( - index_buffer.error_ident(), - )); - } + // since byte sizes of all the index formats are powers of two we could bitshift instead of multiplying + let offset = mesh.first_index.unwrap() as u64 * index_stride; let index_buffer_size = mesh.size.index_count.unwrap() as u64 * index_stride; if mesh.size.index_count.unwrap() % 3 != 0 { @@ -1123,23 +1120,18 @@ fn iter_buffers<'a, 'b>( mesh.size.index_count.unwrap(), )); } - if index_buffer.size - < mesh.size.index_count.unwrap() as u64 * index_stride - + mesh.index_buffer_offset.unwrap() - { + if index_buffer.size < mesh.size.index_count.unwrap() as u64 * index_stride + offset { return Err(BuildAccelerationStructureError::InsufficientBufferSize( index_buffer.error_ident(), index_buffer.size, - mesh.size.index_count.unwrap() as u64 * index_stride - + mesh.index_buffer_offset.unwrap(), + mesh.size.index_count.unwrap() as u64 * index_stride + offset, )); } cmd_buf_data.buffer_memory_init_actions.extend( index_buffer.initialization_status.read().create_action( index_buffer, - mesh.index_buffer_offset.unwrap() - ..(mesh.index_buffer_offset.unwrap() + index_buffer_size), + offset..(offset + index_buffer_size), MemoryInitKind::NeedsInitializedMemory, ), ); @@ -1204,13 +1196,19 @@ fn iter_buffers<'a, 'b>( first_vertex: mesh.first_vertex, vertex_count: mesh.size.vertex_count, vertex_stride: mesh.vertex_stride, - indices: index_buffer.map(|index_buffer| hal::AccelerationStructureTriangleIndices::< - dyn hal::DynBuffer, - > { - format: mesh.size.index_format.unwrap(), - buffer: Some(index_buffer.as_ref()), - offset: mesh.index_buffer_offset.unwrap() as u32, - count: mesh.size.index_count.unwrap(), + indices: index_buffer.map(|index_buffer| { + let index_stride = match mesh.size.index_format.unwrap() { + wgt::IndexFormat::Uint16 => 2, + wgt::IndexFormat::Uint32 => 4, + }; + hal::AccelerationStructureTriangleIndices::< + dyn hal::DynBuffer, + > { + format: mesh.size.index_format.unwrap(), + buffer: Some(index_buffer.as_ref()), + offset: mesh.first_index.unwrap() * index_stride, + count: mesh.size.index_count.unwrap(), + } }), transform: transform_buffer.map(|transform_buffer| { hal::AccelerationStructureTriangleTransform { diff --git a/wgpu-core/src/ray_tracing.rs b/wgpu-core/src/ray_tracing.rs index 9f4a11946d..c707d34598 100644 --- a/wgpu-core/src/ray_tracing.rs +++ b/wgpu-core/src/ray_tracing.rs @@ -172,7 +172,7 @@ pub struct BlasTriangleGeometry<'a> { pub transform_buffer: Option, pub first_vertex: u32, pub vertex_stride: BufferAddress, - pub index_buffer_offset: Option, + pub first_index: Option, pub transform_buffer_offset: Option, } @@ -243,7 +243,7 @@ pub struct TraceBlasTriangleGeometry { pub transform_buffer: Option, pub first_vertex: u32, pub vertex_stride: BufferAddress, - pub index_buffer_offset: Option, + pub first_index: Option, pub transform_buffer_offset: Option, } diff --git a/wgpu/src/api/blas.rs b/wgpu/src/api/blas.rs index 67082700eb..de05ec9c4f 100644 --- a/wgpu/src/api/blas.rs +++ b/wgpu/src/api/blas.rs @@ -102,8 +102,8 @@ pub struct BlasTriangleGeometry<'a> { pub vertex_stride: wgt::BufferAddress, /// Index buffer (optional). pub index_buffer: Option<&'a Buffer>, - /// Index buffer offset in bytes (optional, required if index buffer is present). - pub index_buffer_offset: Option, + /// Index buffer offset as a factor of the size of the index type (optional, required if index buffer is present). + pub first_index: Option, /// Transform buffer containing 3x4 (rows x columns, row major) affine transform matrices `[f32; 12]` (optional). pub transform_buffer: Option<&'a Buffer>, /// Transform buffer offset in bytes (optional, required if transform buffer is present). diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index c49c65ab42..9aa6958f2d 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -2445,7 +2445,7 @@ impl dispatch::CommandEncoderInterface for CoreCommandEncoder { transform_buffer_offset: tg.transform_buffer_offset, first_vertex: tg.first_vertex, vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, + first_index: tg.first_index, } }); wgc::ray_tracing::BlasGeometries::TriangleGeometries(Box::new(iter)) @@ -2495,7 +2495,7 @@ impl dispatch::CommandEncoderInterface for CoreCommandEncoder { transform_buffer_offset: tg.transform_buffer_offset, first_vertex: tg.first_vertex, vertex_stride: tg.vertex_stride, - index_buffer_offset: tg.index_buffer_offset, + first_index: tg.first_index, } }); wgc::ray_tracing::BlasGeometries::TriangleGeometries(Box::new(iter)) From 0d3c8b72b848f8d6a06eb10b8f94c678feb99f3c Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 7 Jan 2025 20:04:24 +0000 Subject: [PATCH 2/6] Format --- wgpu-core/src/command/ray_tracing.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index 2d66f6e2df..b94ee4bf7f 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1201,9 +1201,7 @@ fn iter_buffers<'a, 'b>( wgt::IndexFormat::Uint16 => 2, wgt::IndexFormat::Uint32 => 4, }; - hal::AccelerationStructureTriangleIndices::< - dyn hal::DynBuffer, - > { + hal::AccelerationStructureTriangleIndices:: { format: mesh.size.index_format.unwrap(), buffer: Some(index_buffer.as_ref()), offset: mesh.first_index.unwrap() * index_stride, From fab1717e26892d7291807326fab2aa3ff1438caa Mon Sep 17 00:00:00 2001 From: Vecvec Date: Tue, 7 Jan 2025 20:22:24 +0000 Subject: [PATCH 3/6] Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c919e78bd6..b9b62eaa8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -179,6 +179,7 @@ By @wumpf in [#6849](https://github.com/gfx-rs/wgpu/pull/6849). - Add actual sample type to `CreateBindGroupError::InvalidTextureSampleType` error message. By @ErichDonGubler in [#6530](https://github.com/gfx-rs/wgpu/pull/6530). - Improve binding error to give a clearer message when there is a mismatch between resource binding as it is in the shader and as it is in the binding layout. By @eliemichel in [#6553](https://github.com/gfx-rs/wgpu/pull/6553). - `Surface::configure` and `Surface::get_current_texture` are no longer fatal. By @alokedesai in [#6253](https://github.com/gfx-rs/wgpu/pull/6253) +- Rename `BlasTriangleGeometry::index_buffer_offset` to `BlasTriangleGeometry::first_index`. By @Vecvec in [#6873](https://github.com/gfx-rs/wgpu/pull/6873/files) ##### D3D12 From 67c4413b5c54df9788a870a80b2e81ed18dc0940 Mon Sep 17 00:00:00 2001 From: Vecvec <130132884+Vecvec@users.noreply.github.com> Date: Wed, 8 Jan 2025 07:45:42 +0000 Subject: [PATCH 4/6] Update wgpu/src/api/blas.rs with better docs Co-authored-by: Connor Fitzgerald --- wgpu/src/api/blas.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wgpu/src/api/blas.rs b/wgpu/src/api/blas.rs index de05ec9c4f..2d385af808 100644 --- a/wgpu/src/api/blas.rs +++ b/wgpu/src/api/blas.rs @@ -102,7 +102,7 @@ pub struct BlasTriangleGeometry<'a> { pub vertex_stride: wgt::BufferAddress, /// Index buffer (optional). pub index_buffer: Option<&'a Buffer>, - /// Index buffer offset as a factor of the size of the index type (optional, required if index buffer is present). + /// Number of indexes to skip in the index buffer (optional, required if index buffer is present). pub first_index: Option, /// Transform buffer containing 3x4 (rows x columns, row major) affine transform matrices `[f32; 12]` (optional). pub transform_buffer: Option<&'a Buffer>, From 3f8cd4a03aee1d2eda84aeb12d6ba3ebc6916512 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Wed, 8 Jan 2025 08:02:08 +0000 Subject: [PATCH 5/6] Address feedback. --- wgpu-core/src/command/bundle.rs | 5 +---- wgpu-core/src/command/ray_tracing.rs | 11 ++--------- wgpu-types/src/lib.rs | 9 +++++++++ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index c7f433c3a0..6aa614ac5f 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -1174,10 +1174,7 @@ impl IndexState { /// /// Panic if no index buffer has been set. fn limit(&self) -> u64 { - let bytes_per_index = match self.format { - wgt::IndexFormat::Uint16 => 2, - wgt::IndexFormat::Uint32 => 4, - }; + let bytes_per_index = self.format.byte_size() as u64; (self.range.end - self.range.start) / bytes_per_index } diff --git a/wgpu-core/src/command/ray_tracing.rs b/wgpu-core/src/command/ray_tracing.rs index b94ee4bf7f..fbf90d8c83 100644 --- a/wgpu-core/src/command/ray_tracing.rs +++ b/wgpu-core/src/command/ray_tracing.rs @@ -1106,11 +1106,7 @@ fn iter_buffers<'a, 'b>( { input_barriers.push(barrier); } - let index_stride = match mesh.size.index_format.unwrap() { - wgt::IndexFormat::Uint16 => 2, - wgt::IndexFormat::Uint32 => 4, - }; - // since byte sizes of all the index formats are powers of two we could bitshift instead of multiplying + let index_stride = mesh.size.index_format.unwrap().byte_size() as u64; let offset = mesh.first_index.unwrap() as u64 * index_stride; let index_buffer_size = mesh.size.index_count.unwrap() as u64 * index_stride; @@ -1197,10 +1193,7 @@ fn iter_buffers<'a, 'b>( vertex_count: mesh.size.vertex_count, vertex_stride: mesh.vertex_stride, indices: index_buffer.map(|index_buffer| { - let index_stride = match mesh.size.index_format.unwrap() { - wgt::IndexFormat::Uint16 => 2, - wgt::IndexFormat::Uint32 => 4, - }; + let index_stride = mesh.size.index_format.unwrap().byte_size() as u32; hal::AccelerationStructureTriangleIndices:: { format: mesh.size.index_format.unwrap(), buffer: Some(index_buffer.as_ref()), diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 7753de289a..62e6b183af 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -5052,6 +5052,15 @@ pub enum IndexFormat { Uint32 = 1, } +impl IndexFormat { + pub fn byte_size(&self) -> usize { + match self { + IndexFormat::Uint16 => 2, + IndexFormat::Uint32 => 4, + } + } +} + /// Operation to perform on the stencil value. /// /// Corresponds to [WebGPU `GPUStencilOperation`]( From f9bd9b38fdc1363f5b5f60ff6c2bc72edf9975b0 Mon Sep 17 00:00:00 2001 From: Vecvec Date: Wed, 8 Jan 2025 08:22:32 +0000 Subject: [PATCH 6/6] Clippy. --- wgpu-types/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 62e6b183af..70f2f6973e 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -5053,6 +5053,7 @@ pub enum IndexFormat { } impl IndexFormat { + /// Returns the size in bytes of the index format pub fn byte_size(&self) -> usize { match self { IndexFormat::Uint16 => 2,