Skip to content

Commit 87718e0

Browse files
Vecvecsharmajai
authored andcommitted
Add extra acceleration structure vertex formats. (gfx-rs#7580)
1 parent 199d5e0 commit 87718e0

File tree

9 files changed

+193
-5
lines changed

9 files changed

+193
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Bottom level categories:
5151

5252
- Add support for astc-sliced-3d feature. By @mehmetoguzderin in [#7577](https://github.com/gfx-rs/wgpu/issues/7577)
5353
- Add support for rendering to slices of 3D texture views and single layered 2D-Array texture views (this requires `VK_KHR_maintenance1` which should be widely available on newer drivers). By @teoxoy in [#7596](https://github.com/gfx-rs/wgpu/pull/7596)
54+
- Add extra acceleration structure vertex formats. By @Vecvec in [#7580](https://github.com/gfx-rs/wgpu/pull/7580).
5455

5556
#### Naga
5657

tests/tests/wgpu-gpu/ray_tracing/as_build.rs

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::ray_tracing::AsBuildContext;
44
use wgpu::util::{BufferInitDescriptor, DeviceExt};
55
use wgpu::*;
66
use wgpu_test::{
7-
fail, gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext,
7+
fail, fail_if, gpu_test, FailureCase, GpuTestConfiguration, TestParameters, TestingContext,
88
};
99

1010
#[gpu_test]
@@ -604,3 +604,106 @@ fn only_tlas_vertex_return(ctx: TestingContext) {
604604
None,
605605
);
606606
}
607+
608+
#[gpu_test]
609+
static EXTRA_FORMAT_BUILD: GpuTestConfiguration = GpuTestConfiguration::new()
610+
.parameters(
611+
TestParameters::default()
612+
.test_features_limits()
613+
.features(
614+
wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE
615+
| wgpu::Features::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS,
616+
)
617+
// https://github.com/gfx-rs/wgpu/issues/6727
618+
.skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")),
619+
)
620+
.run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Snorm16x4, 6, false));
621+
622+
#[gpu_test]
623+
static MISALIGNED_BUILD: GpuTestConfiguration = GpuTestConfiguration::new()
624+
.parameters(
625+
TestParameters::default()
626+
.test_features_limits()
627+
.features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE)
628+
// https://github.com/gfx-rs/wgpu/issues/6727
629+
.skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")),
630+
)
631+
// Larger than the minimum size, but not aligned as required
632+
.run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Float32x3, 13, true));
633+
634+
#[gpu_test]
635+
static TOO_SMALL_STRIDE_BUILD: GpuTestConfiguration = GpuTestConfiguration::new()
636+
.parameters(
637+
TestParameters::default()
638+
.test_features_limits()
639+
.features(wgpu::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE)
640+
// https://github.com/gfx-rs/wgpu/issues/6727
641+
.skip(FailureCase::backend_adapter(wgpu::Backends::VULKAN, "AMD")),
642+
)
643+
// Aligned as required, but smaller than minimum size
644+
.run_sync(|ctx| test_as_build_format_stride(ctx, VertexFormat::Float32x3, 8, true));
645+
646+
fn test_as_build_format_stride(
647+
ctx: TestingContext,
648+
format: VertexFormat,
649+
stride: BufferAddress,
650+
invalid_combination: bool,
651+
) {
652+
let vertices = ctx.device.create_buffer_init(&BufferInitDescriptor {
653+
label: None,
654+
contents: &vec![0; (format.min_acceleration_structure_vertex_stride() * 3) as usize],
655+
usage: BufferUsages::BLAS_INPUT,
656+
});
657+
658+
let blas_size = BlasTriangleGeometrySizeDescriptor {
659+
// The fourth component is ignored, and it allows us to have a smaller stride.
660+
vertex_format: format,
661+
vertex_count: 3,
662+
index_format: None,
663+
index_count: None,
664+
flags: wgpu::AccelerationStructureGeometryFlags::empty(),
665+
};
666+
667+
let blas = ctx.device.create_blas(
668+
&CreateBlasDescriptor {
669+
label: Some("BLAS"),
670+
flags: wgpu::AccelerationStructureFlags::PREFER_FAST_TRACE,
671+
update_mode: AccelerationStructureUpdateMode::Build,
672+
},
673+
BlasGeometrySizeDescriptors::Triangles {
674+
descriptors: vec![blas_size.clone()],
675+
},
676+
);
677+
678+
let mut command_encoder = ctx
679+
.device
680+
.create_command_encoder(&CommandEncoderDescriptor {
681+
label: Some("BLAS_1"),
682+
});
683+
fail_if(
684+
&ctx.device,
685+
invalid_combination,
686+
|| {
687+
command_encoder.build_acceleration_structures(
688+
&[BlasBuildEntry {
689+
blas: &blas,
690+
geometry: BlasGeometries::TriangleGeometries(vec![BlasTriangleGeometry {
691+
size: &blas_size,
692+
vertex_buffer: &vertices,
693+
first_vertex: 0,
694+
vertex_stride: stride,
695+
index_buffer: None,
696+
first_index: None,
697+
transform_buffer: None,
698+
transform_buffer_offset: None,
699+
}]),
700+
}],
701+
&[],
702+
)
703+
},
704+
None,
705+
);
706+
if !invalid_combination {
707+
ctx.queue.submit([command_encoder.finish()]);
708+
}
709+
}

wgpu-core/src/command/ray_tracing.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,35 @@ fn iter_blas<'a>(
898898
));
899899
}
900900

901+
if size_desc
902+
.vertex_format
903+
.min_acceleration_structure_vertex_stride()
904+
> mesh.vertex_stride
905+
{
906+
return Err(BuildAccelerationStructureError::VertexStrideTooSmall(
907+
blas.error_ident(),
908+
size_desc
909+
.vertex_format
910+
.min_acceleration_structure_vertex_stride(),
911+
mesh.vertex_stride,
912+
));
913+
}
914+
915+
if mesh.vertex_stride
916+
% size_desc
917+
.vertex_format
918+
.acceleration_structure_stride_alignment()
919+
!= 0
920+
{
921+
return Err(BuildAccelerationStructureError::VertexStrideUnaligned(
922+
blas.error_ident(),
923+
size_desc
924+
.vertex_format
925+
.acceleration_structure_stride_alignment(),
926+
mesh.vertex_stride,
927+
));
928+
}
929+
901930
match (size_desc.index_count, mesh.size.index_count) {
902931
(Some(_), None) | (None, Some(_)) => {
903932
return Err(

wgpu-core/src/ray_tracing.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ pub enum BuildAccelerationStructureError {
102102
#[error("Blas {0:?} vertex formats are different, creation format: {1:?}, provided: {2:?}")]
103103
DifferentBlasVertexFormats(ResourceErrorIdent, VertexFormat, VertexFormat),
104104

105+
#[error("Blas {0:?} stride was required to be at least {1} but stride given was {2}")]
106+
VertexStrideTooSmall(ResourceErrorIdent, u64, u64),
107+
108+
#[error("Blas {0:?} stride was required to be a multiple of {1} but stride given was {2}")]
109+
VertexStrideUnaligned(ResourceErrorIdent, u64, u64),
110+
105111
#[error("Blas {0:?} index count was provided at creation or building, but not the other")]
106112
BlasIndexCountProvidedMismatch(ResourceErrorIdent),
107113

wgpu-hal/src/dx12/adapter.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,8 @@ impl super::Adapter {
474474
// Once ray tracing pipelines are supported they also will go here
475475
features.set(
476476
wgt::Features::EXPERIMENTAL_RAY_QUERY
477-
| wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE,
477+
| wgt::Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE
478+
| wgt::Features::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS,
478479
features5.RaytracingTier == Direct3D12::D3D12_RAYTRACING_TIER_1_1
479480
&& shader_model >= naga::back::hlsl::ShaderModel::V6_5
480481
&& has_features5,

wgpu-hal/src/vulkan/adapter.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,8 @@ impl PhysicalDeviceFeatures {
799799
features.set(F::DEPTH32FLOAT_STENCIL8, texture_d32_s8);
800800

801801
features.set(
802-
F::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE,
802+
F::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE
803+
| F::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS,
803804
caps.supports_extension(khr::deferred_host_operations::NAME)
804805
&& caps.supports_extension(khr::acceleration_structure::NAME)
805806
&& caps.supports_extension(khr::buffer_device_address::NAME),

wgpu-types/src/features.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,15 @@ bitflags_array! {
12171217
///
12181218
/// This is a native only feature.
12191219
const EXPERIMENTAL_MESH_SHADER_MULTIVIEW = 1 << 49;
1220+
1221+
/// Allows usage of additional vertex formats in [BlasTriangleGeometrySizeDescriptor::vertex_format]
1222+
///
1223+
/// Supported platforms
1224+
/// - Vulkan
1225+
/// - DX12
1226+
///
1227+
/// [BlasTriangleGeometrySizeDescriptor::vertex_format]: super::BlasTriangleGeometrySizeDescriptor
1228+
const EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS = 1 << 50;
12201229
}
12211230

12221231
/// Features that are not guaranteed to be supported.
@@ -1484,6 +1493,13 @@ impl Features {
14841493
if self.contains(Self::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE) {
14851494
formats.push(VertexFormat::Float32x3);
14861495
}
1496+
if self.contains(Self::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS) {
1497+
formats.push(VertexFormat::Float32x2);
1498+
formats.push(VertexFormat::Float16x2);
1499+
formats.push(VertexFormat::Float16x4);
1500+
formats.push(VertexFormat::Snorm16x2);
1501+
formats.push(VertexFormat::Snorm16x4);
1502+
}
14871503
formats
14881504
}
14891505
}

wgpu-types/src/lib.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4974,6 +4974,36 @@ impl VertexFormat {
49744974
Self::Float64x4 => 32,
49754975
}
49764976
}
4977+
4978+
/// Returns the size read by an acceleration structure build of the vertex format. This is
4979+
/// slightly different from [`Self::size`] because the alpha component of 4-component formats
4980+
/// are not read in an acceleration structure build, allowing for a smaller stride.
4981+
#[must_use]
4982+
pub const fn min_acceleration_structure_vertex_stride(&self) -> u64 {
4983+
match self {
4984+
Self::Float16x2 | Self::Snorm16x2 => 4,
4985+
Self::Float32x3 => 12,
4986+
Self::Float32x2 => 8,
4987+
// This is the minimum value from DirectX
4988+
// > A16 component is ignored, other data can be packed there, such as setting vertex stride to 6 bytes
4989+
//
4990+
// https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html#d3d12_raytracing_geometry_triangles_desc
4991+
//
4992+
// Vulkan does not express a minimum stride.
4993+
Self::Float16x4 | Self::Snorm16x4 => 6,
4994+
_ => unreachable!(),
4995+
}
4996+
}
4997+
4998+
/// Returns the alignment required for `wgpu::BlasTriangleGeometry::vertex_stride`
4999+
#[must_use]
5000+
pub const fn acceleration_structure_stride_alignment(&self) -> u64 {
5001+
match self {
5002+
Self::Float16x4 | Self::Float16x2 | Self::Snorm16x4 | Self::Snorm16x2 => 2,
5003+
Self::Float32x2 | Self::Float32x3 => 4,
5004+
_ => unreachable!(),
5005+
}
5006+
}
49775007
}
49785008

49795009
bitflags::bitflags! {
@@ -7436,7 +7466,7 @@ impl Default for ShaderRuntimeChecks {
74367466
pub struct BlasTriangleGeometrySizeDescriptor {
74377467
/// Format of a vertex position, must be [`VertexFormat::Float32x3`]
74387468
/// with just [`Features::EXPERIMENTAL_RAY_TRACING_ACCELERATION_STRUCTURE`]
7439-
/// but later features may add more formats.
7469+
/// but [`Features::EXTENDED_ACCELERATION_STRUCTURE_VERTEX_FORMATS`] adds more.
74407470
pub vertex_format: VertexFormat,
74417471
/// Number of vertices.
74427472
pub vertex_count: u32,

wgpu/src/api/blas.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ pub struct BlasTriangleGeometry<'a> {
100100
pub vertex_buffer: &'a Buffer,
101101
/// Offset into the vertex buffer as a factor of the vertex stride.
102102
pub first_vertex: u32,
103-
/// Vertex stride.
103+
/// Vertex stride, must be greater than [`wgpu_types::VertexFormat::min_acceleration_structure_vertex_stride`]
104+
/// of the format and must be a multiple of [`wgpu_types::VertexFormat::acceleration_structure_stride_alignment`].
104105
pub vertex_stride: wgt::BufferAddress,
105106
/// Index buffer (optional).
106107
pub index_buffer: Option<&'a Buffer>,

0 commit comments

Comments
 (0)