|
1 | 1 | use crate::ray_tracing::{acceleration_structure_limits, AsBuildContext}; |
| 2 | +use wgpu::util::{BufferInitDescriptor, DeviceExt}; |
2 | 3 | use wgpu::{ |
3 | | - include_wgsl, BindGroupDescriptor, BindGroupEntry, BindingResource, BufferDescriptor, |
| 4 | + include_wgsl, Backends, BindGroupDescriptor, BindGroupEntry, BindingResource, BufferDescriptor, |
4 | 5 | CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor, |
5 | 6 | }; |
6 | 7 | use wgpu::{AccelerationStructureFlags, BufferUsages}; |
7 | 8 | use wgpu_macros::gpu_test; |
8 | | -use wgpu_test::GpuTestInitializer; |
| 9 | +use wgpu_test::{FailureCase, GpuTestInitializer}; |
9 | 10 | use wgpu_test::{GpuTestConfiguration, TestParameters, TestingContext}; |
10 | 11 |
|
11 | 12 | const STRUCT_SIZE: wgpu::BufferAddress = 176; |
12 | 13 |
|
13 | 14 | pub fn all_tests(tests: &mut Vec<GpuTestInitializer>) { |
14 | 15 | tests.push(ACCESS_ALL_STRUCT_MEMBERS); |
| 16 | + tests.push(PREVENT_INVALID_RAY_QUERY_CALLS); |
15 | 17 | } |
16 | 18 |
|
17 | 19 | #[gpu_test] |
@@ -103,3 +105,95 @@ fn access_all_struct_members(ctx: TestingContext) { |
103 | 105 |
|
104 | 106 | ctx.queue.submit([encoder_compute.finish()]); |
105 | 107 | } |
| 108 | + |
| 109 | +#[gpu_test] |
| 110 | +static PREVENT_INVALID_RAY_QUERY_CALLS: GpuTestConfiguration = GpuTestConfiguration::new() |
| 111 | + .parameters( |
| 112 | + TestParameters::default() |
| 113 | + .test_features_limits() |
| 114 | + .limits(acceleration_structure_limits()) |
| 115 | + .features(wgpu::Features::EXPERIMENTAL_RAY_QUERY) |
| 116 | + // not yet implemented in directx12 |
| 117 | + .skip(FailureCase::backend(Backends::DX12)), |
| 118 | + ) |
| 119 | + .run_sync(prevent_invalid_ray_query_calls); |
| 120 | + |
| 121 | +fn prevent_invalid_ray_query_calls(ctx: TestingContext) { |
| 122 | + let invalid_values_buffer = ctx.device.create_buffer_init(&BufferInitDescriptor { |
| 123 | + label: Some("invalid values buffer"), |
| 124 | + contents: bytemuck::cast_slice(&[f32::NAN, f32::INFINITY]), |
| 125 | + usage: BufferUsages::STORAGE, |
| 126 | + }); |
| 127 | + |
| 128 | + // |
| 129 | + // Create a clean `AsBuildContext` |
| 130 | + // |
| 131 | + |
| 132 | + let as_ctx = AsBuildContext::new( |
| 133 | + &ctx, |
| 134 | + AccelerationStructureFlags::empty(), |
| 135 | + AccelerationStructureFlags::empty(), |
| 136 | + ); |
| 137 | + |
| 138 | + let mut encoder_build = ctx |
| 139 | + .device |
| 140 | + .create_command_encoder(&CommandEncoderDescriptor { |
| 141 | + label: Some("Build"), |
| 142 | + }); |
| 143 | + |
| 144 | + encoder_build.build_acceleration_structures([&as_ctx.blas_build_entry()], [&as_ctx.tlas]); |
| 145 | + |
| 146 | + ctx.queue.submit([encoder_build.finish()]); |
| 147 | + |
| 148 | + // |
| 149 | + // Create shader |
| 150 | + // |
| 151 | + |
| 152 | + let shader = ctx |
| 153 | + .device |
| 154 | + .create_shader_module(include_wgsl!("shader.wgsl")); |
| 155 | + let compute_pipeline = ctx |
| 156 | + .device |
| 157 | + .create_compute_pipeline(&ComputePipelineDescriptor { |
| 158 | + label: None, |
| 159 | + layout: None, |
| 160 | + module: &shader, |
| 161 | + entry_point: Some("invalid_usages"), |
| 162 | + compilation_options: Default::default(), |
| 163 | + cache: None, |
| 164 | + }); |
| 165 | + |
| 166 | + let bind_group = ctx.device.create_bind_group(&BindGroupDescriptor { |
| 167 | + label: None, |
| 168 | + layout: &compute_pipeline.get_bind_group_layout(0), |
| 169 | + entries: &[ |
| 170 | + BindGroupEntry { |
| 171 | + binding: 0, |
| 172 | + resource: BindingResource::AccelerationStructure(&as_ctx.tlas), |
| 173 | + }, |
| 174 | + BindGroupEntry { |
| 175 | + binding: 1, |
| 176 | + resource: BindingResource::Buffer(invalid_values_buffer.as_entire_buffer_binding()), |
| 177 | + }, |
| 178 | + ], |
| 179 | + }); |
| 180 | + |
| 181 | + // |
| 182 | + // Submit once to check for no issues |
| 183 | + // |
| 184 | + |
| 185 | + let mut encoder_compute = ctx |
| 186 | + .device |
| 187 | + .create_command_encoder(&CommandEncoderDescriptor::default()); |
| 188 | + { |
| 189 | + let mut pass = encoder_compute.begin_compute_pass(&ComputePassDescriptor { |
| 190 | + label: None, |
| 191 | + timestamp_writes: None, |
| 192 | + }); |
| 193 | + pass.set_pipeline(&compute_pipeline); |
| 194 | + pass.set_bind_group(0, Some(&bind_group), &[]); |
| 195 | + pass.dispatch_workgroups(1, 1, 1) |
| 196 | + } |
| 197 | + |
| 198 | + ctx.queue.submit([encoder_compute.finish()]); |
| 199 | +} |
0 commit comments