diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d9558c36b5..489efaa6080 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,10 @@ By @Vecvec in [#7913](https://github.com/gfx-rs/wgpu/pull/7913). ### Changes +#### General + +- Prevent resources for acceleration structures being created if acceleration structures are not enabled. By @Vecvec in [#8036](https://github.com/gfx-rs/wgpu/pull/8036). + #### Naga Naga now requires that no type be larger than 1 GB. This limit may be lowered in the future; feedback on an appropriate value for the limit is welcome. By @andyleiserson in [#7950](https://github.com/gfx-rs/wgpu/pull/7950). diff --git a/tests/tests/wgpu-gpu/ray_tracing/as_create.rs b/tests/tests/wgpu-gpu/ray_tracing/as_create.rs index 19edb096be2..8f424c5f1bf 100644 --- a/tests/tests/wgpu-gpu/ray_tracing/as_create.rs +++ b/tests/tests/wgpu-gpu/ray_tracing/as_create.rs @@ -9,7 +9,11 @@ use wgpu_macros::gpu_test; use wgpu_test::{fail, GpuTestConfiguration, TestParameters, TestingContext}; pub fn all_tests(tests: &mut Vec) { - tests.extend([BLAS_INVALID_VERTEX_FORMAT, BLAS_MISMATCHED_INDEX]); + tests.extend([ + BLAS_INVALID_VERTEX_FORMAT, + BLAS_MISMATCHED_INDEX, + UNSUPPORTED_ACCELERATION_STRUCTURE_RESOURCES, + ]); } #[gpu_test] @@ -124,3 +128,42 @@ fn mismatched_index_blas_create(ctx: TestingContext) { None, ); } + +#[gpu_test] +static UNSUPPORTED_ACCELERATION_STRUCTURE_RESOURCES: GpuTestConfiguration = + GpuTestConfiguration::new() + .parameters(TestParameters::default().test_features_limits()) + .run_sync(unsupported_acceleration_structure_resources); + +fn unsupported_acceleration_structure_resources(ctx: TestingContext) { + fail( + &ctx.device, + || { + ctx.device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: 4, + usage: wgpu::BufferUsages::BLAS_INPUT, + mapped_at_creation: false, + }) + }, + None, + ); + fail( + &ctx.device, + || { + ctx.device + .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: None, + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::COMPUTE, + ty: wgpu::BindingType::AccelerationStructure { + vertex_return: false, + }, + count: None, + }], + }) + }, + None, + ); +} diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 5fe0de4134c..68a425c0594 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -795,6 +795,13 @@ impl Device { }); } + if desc + .usage + .intersects(wgt::BufferUsages::BLAS_INPUT | wgt::BufferUsages::TLAS_INPUT) + { + self.require_features(wgt::Features::EXPERIMENTAL_RAY_QUERY)?; + } + if desc.usage.contains(wgt::BufferUsages::INDEX) && desc.usage.contains( wgt::BufferUsages::VERTEX @@ -2303,7 +2310,22 @@ impl Device { }, ) } - Bt::AccelerationStructure { .. } => (None, WritableStorage::No), + Bt::AccelerationStructure { vertex_return } => { + self.require_features(wgt::Features::EXPERIMENTAL_RAY_QUERY) + .map_err(|e| binding_model::CreateBindGroupLayoutError::Entry { + binding: entry.binding, + error: e.into(), + })?; + if vertex_return { + self.require_features(wgt::Features::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN) + .map_err(|e| binding_model::CreateBindGroupLayoutError::Entry { + binding: entry.binding, + error: e.into(), + })?; + } + + (None, WritableStorage::No) + } Bt::ExternalTexture => { self.require_features(wgt::Features::EXTERNAL_TEXTURE) .map_err(|e| binding_model::CreateBindGroupLayoutError::Entry { diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 6fe4d794bd3..8d51298a711 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -912,6 +912,8 @@ pub enum CreateBufferError { MaxBufferSize { requested: u64, maximum: u64 }, #[error(transparent)] MissingDownlevelFlags(#[from] MissingDownlevelFlags), + #[error(transparent)] + MissingFeatures(#[from] MissingFeatures), #[error("Failed to create bind group for indirect buffer validation: {0}")] IndirectValidationBindGroup(DeviceError), } @@ -929,6 +931,7 @@ impl WebGpuError for CreateBufferError { Self::AccessError(e) => e, Self::MissingDownlevelFlags(e) => e, Self::IndirectValidationBindGroup(e) => e, + Self::MissingFeatures(e) => e, Self::UnalignedSize | Self::InvalidUsage(_)