Skip to content

Commit 16a5189

Browse files
committed
Add testing for tracking.
1 parent 38b7628 commit 16a5189

File tree

2 files changed

+170
-2
lines changed

2 files changed

+170
-2
lines changed

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

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
use crate::ray_tracing::{acceleration_structure_limits, AsBuildContext};
2+
use wgpu::util::{BufferInitDescriptor, DeviceExt};
23
use wgpu::{
3-
include_wgsl, BindGroupDescriptor, BindGroupEntry, BindingResource, BufferDescriptor,
4+
include_wgsl, Backends, BindGroupDescriptor, BindGroupEntry, BindingResource, BufferDescriptor,
45
CommandEncoderDescriptor, ComputePassDescriptor, ComputePipelineDescriptor,
56
};
67
use wgpu::{AccelerationStructureFlags, BufferUsages};
78
use wgpu_macros::gpu_test;
8-
use wgpu_test::GpuTestInitializer;
9+
use wgpu_test::{FailureCase, GpuTestInitializer};
910
use wgpu_test::{GpuTestConfiguration, TestParameters, TestingContext};
1011

1112
const STRUCT_SIZE: wgpu::BufferAddress = 176;
1213

1314
pub fn all_tests(tests: &mut Vec<GpuTestInitializer>) {
1415
tests.push(ACCESS_ALL_STRUCT_MEMBERS);
16+
tests.push(PREVENT_INVALID_RAY_QUERY_CALLS);
1517
}
1618

1719
#[gpu_test]
@@ -103,3 +105,95 @@ fn access_all_struct_members(ctx: TestingContext) {
103105

104106
ctx.queue.submit([encoder_compute.finish()]);
105107
}
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+
}

tests/tests/wgpu-gpu/ray_tracing/shader.wgsl

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,78 @@ fn all_of_struct() {
4848
intersection.world_to_object,
4949
intersection.object_to_world,
5050
);
51+
}
52+
53+
struct MaybeInvalidValues {
54+
nan: f32,
55+
inf: f32,
56+
}
57+
58+
@group(0) @binding(1)
59+
var<storage> invalid_values: MaybeInvalidValues;
60+
61+
@workgroup_size(1)
62+
@compute
63+
fn invalid_usages() {
64+
{
65+
var rq: ray_query;
66+
// no initialize
67+
rayQueryProceed(&rq);
68+
let intersection = rayQueryGetCommittedIntersection(&rq);
69+
}
70+
{
71+
var rq: ray_query;
72+
rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 0.001, 100000.0, vec3f(0.0, 0.0, 0.0), vec3f(0.0, 0.0, 1.0)));
73+
// no proceed
74+
let intersection = rayQueryGetCommittedIntersection(&rq);
75+
}
76+
{
77+
var rq: ray_query;
78+
rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 0.001, 100000.0, vec3f(0.0, 0.0, 0.0), vec3f(0.0, 0.0, 1.0)));
79+
rayQueryProceed(&rq);
80+
// The acceleration structure has been set up to not generate an intersections, meaning it will be a committed intersection, not candidate.
81+
let intersection = rayQueryGetCandidateIntersection(&rq);
82+
}
83+
{
84+
var rq: ray_query;
85+
// NaN in origin
86+
rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 0.001, 100000.0, vec3f(0.0, invalid_values.nan, 0.0), vec3f(0.0, 0.0, 1.0)));
87+
rayQueryProceed(&rq);
88+
let intersection = rayQueryGetCommittedIntersection(&rq);
89+
}
90+
{
91+
var rq: ray_query;
92+
// Inf in origin
93+
rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 0.001, 100000.0, vec3f(0.0, invalid_values.inf, 0.0), vec3f(0.0, 0.0, 1.0)));
94+
rayQueryProceed(&rq);
95+
let intersection = rayQueryGetCommittedIntersection(&rq);
96+
}
97+
{
98+
var rq: ray_query;
99+
// NaN in direction
100+
rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 0.001, 100000.0, vec3f(0.0, 0.0, 0.0), vec3f(0.0, invalid_values.nan, 1.0)));
101+
rayQueryProceed(&rq);
102+
let intersection = rayQueryGetCommittedIntersection(&rq);
103+
}
104+
{
105+
var rq: ray_query;
106+
// Inf in direction
107+
rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 0.001, 100000.0, vec3f(0.0, 0.0, 0.0), vec3f(0.0, invalid_values.inf, 1.0)));
108+
rayQueryProceed(&rq);
109+
let intersection = rayQueryGetCommittedIntersection(&rq);
110+
}
111+
{
112+
var rq: ray_query;
113+
// t_min greater than t_max
114+
rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, 100000.0, 0.1, vec3f(0.0, 0.0, 0.0), vec3f(0.0, 0.0, 1.0)));
115+
rayQueryProceed(&rq);
116+
let intersection = rayQueryGetCommittedIntersection(&rq);
117+
}
118+
{
119+
var rq: ray_query;
120+
// t_min less than 0
121+
rayQueryInitialize(&rq, acc_struct, RayDesc(0u, 0xFFu, -0.001, 100000.0, vec3f(0.0, 0.0, 0.0), vec3f(0.0, 0.0, 1.0)));
122+
rayQueryProceed(&rq);
123+
let intersection = rayQueryGetCommittedIntersection(&rq);
124+
}
51125
}

0 commit comments

Comments
 (0)