@@ -3,11 +3,15 @@ use std::{
3
3
process:: Stdio ,
4
4
} ;
5
5
6
- use wgpu:: util:: DeviceExt ;
6
+ use wgpu:: { util:: DeviceExt , Backends } ;
7
7
use wgpu_test:: {
8
- gpu_test, GpuTestConfiguration , GpuTestInitializer , TestParameters , TestingContext ,
8
+ fail, gpu_test, FailureCase , GpuTestConfiguration , GpuTestInitializer , TestParameters ,
9
+ TestingContext ,
9
10
} ;
10
11
12
+ /// Backends that support mesh shaders
13
+ const MESH_SHADER_BACKENDS : Backends = Backends :: DX12 . union ( Backends :: VULKAN ) ;
14
+
11
15
pub fn all_tests ( tests : & mut Vec < GpuTestInitializer > ) {
12
16
tests. extend ( [
13
17
MESH_PIPELINE_BASIC_MESH ,
@@ -19,6 +23,7 @@ pub fn all_tests(tests: &mut Vec<GpuTestInitializer>) {
19
23
MESH_MULTI_DRAW_INDIRECT_COUNT ,
20
24
MESH_PIPELINE_BASIC_MESH_NO_DRAW ,
21
25
MESH_PIPELINE_BASIC_TASK_MESH_FRAG_NO_DRAW ,
26
+ MESH_DISABLED ,
22
27
] ) ;
23
28
}
24
29
@@ -97,21 +102,44 @@ fn get_shaders(
97
102
device : & wgpu:: Device ,
98
103
backend : wgpu:: Backend ,
99
104
test_name : & str ,
100
- ) -> ( wgpu:: ShaderModule , wgpu:: ShaderModule , wgpu:: ShaderModule ) {
105
+ info : & MeshPipelineTestInfo ,
106
+ ) -> (
107
+ Option < wgpu:: ShaderModule > ,
108
+ wgpu:: ShaderModule ,
109
+ Option < wgpu:: ShaderModule > ,
110
+ ) {
111
+ // On backends that don't support mesh shaders, or for the MESH_DISABLED
112
+ // test, compile a dummy shader so we can construct a structurally valid
113
+ // pipeline description and test that `create_mesh_pipeline` fails.
114
+ // (In the case that the platform does support mesh shaders, the dummy
115
+ // shader is used to avoid requiring EXPERIMENTAL_PASSTHROUGH_SHADERS.)
116
+ let dummy_shader = device. create_shader_module ( wgpu:: include_wgsl!( "non_mesh.wgsl" ) ) ;
101
117
if backend == wgpu:: Backend :: Vulkan {
102
118
(
103
- compile_glsl ( device, "task" ) ,
104
- compile_glsl ( device, "mesh" ) ,
105
- compile_glsl ( device, "frag" ) ,
119
+ info. use_task . then ( || compile_glsl ( device, "task" ) ) ,
120
+ if info. use_mesh {
121
+ compile_glsl ( device, "mesh" )
122
+ } else {
123
+ dummy_shader
124
+ } ,
125
+ info. use_frag . then ( || compile_glsl ( device, "frag" ) ) ,
106
126
)
107
127
} else if backend == wgpu:: Backend :: Dx12 {
108
128
(
109
- compile_hlsl ( device, "Task" , "as" , test_name) ,
110
- compile_hlsl ( device, "Mesh" , "ms" , test_name) ,
111
- compile_hlsl ( device, "Frag" , "ps" , test_name) ,
129
+ info. use_task
130
+ . then ( || compile_hlsl ( device, "Task" , "as" , test_name) ) ,
131
+ if info. use_mesh {
132
+ compile_hlsl ( device, "Mesh" , "ms" , test_name)
133
+ } else {
134
+ dummy_shader
135
+ } ,
136
+ info. use_frag
137
+ . then ( || compile_hlsl ( device, "Frag" , "ps" , test_name) ) ,
112
138
)
113
139
} else {
114
- unreachable ! ( )
140
+ assert ! ( !MESH_SHADER_BACKENDS . contains( Backends :: from( backend) ) ) ;
141
+ assert ! ( !info. use_task && !info. use_mesh && !info. use_frag) ;
142
+ ( None , dummy_shader, None )
115
143
}
116
144
}
117
145
@@ -146,6 +174,7 @@ fn create_depth(
146
174
147
175
struct MeshPipelineTestInfo {
148
176
use_task : bool ,
177
+ use_mesh : bool ,
149
178
use_frag : bool ,
150
179
draw : bool ,
151
180
}
@@ -158,16 +187,11 @@ fn hash_testing_context(ctx: &TestingContext) -> u64 {
158
187
159
188
fn mesh_pipeline_build ( ctx : & TestingContext , info : MeshPipelineTestInfo ) {
160
189
let backend = ctx. adapter . get_info ( ) . backend ;
161
- if backend != wgpu:: Backend :: Vulkan && backend != wgpu:: Backend :: Dx12 {
162
- return ;
163
- }
164
190
let device = & ctx. device ;
165
191
let ( _depth_image, depth_view, depth_state) = create_depth ( device) ;
166
192
167
193
let test_hash = hash_testing_context ( ctx) . to_string ( ) ;
168
- let ( task, mesh, frag) = get_shaders ( device, backend, & test_hash) ;
169
- let task = if info. use_task { Some ( task) } else { None } ;
170
- let frag = if info. use_frag { Some ( frag) } else { None } ;
194
+ let ( task, mesh, frag) = get_shaders ( device, backend, & test_hash, & info) ;
171
195
let layout = device. create_pipeline_layout ( & wgpu:: PipelineLayoutDescriptor {
172
196
label : None ,
173
197
bind_group_layouts : & [ ] ,
@@ -246,7 +270,15 @@ fn mesh_draw(ctx: &TestingContext, draw_type: DrawType) {
246
270
let device = & ctx. device ;
247
271
let ( _depth_image, depth_view, depth_state) = create_depth ( device) ;
248
272
let test_hash = hash_testing_context ( ctx) . to_string ( ) ;
249
- let ( task, mesh, frag) = get_shaders ( device, backend, & test_hash) ;
273
+ let info = MeshPipelineTestInfo {
274
+ use_task : true ,
275
+ use_mesh : true ,
276
+ use_frag : true ,
277
+ draw : true ,
278
+ } ;
279
+ let ( task, mesh, frag) = get_shaders ( device, backend, & test_hash, & info) ;
280
+ let task = task. unwrap ( ) ;
281
+ let frag = frag. unwrap ( ) ;
250
282
let layout = device. create_pipeline_layout ( & wgpu:: PipelineLayoutDescriptor {
251
283
label : None ,
252
284
bind_group_layouts : & [ ] ,
@@ -343,6 +375,7 @@ fn mesh_draw(ctx: &TestingContext, draw_type: DrawType) {
343
375
fn default_gpu_test_config ( draw_type : DrawType ) -> GpuTestConfiguration {
344
376
GpuTestConfiguration :: new ( ) . parameters (
345
377
TestParameters :: default ( )
378
+ . skip ( FailureCase :: backend ( !MESH_SHADER_BACKENDS ) )
346
379
. test_features_limits ( )
347
380
. features (
348
381
wgpu:: Features :: EXPERIMENTAL_MESH_SHADER
@@ -365,6 +398,7 @@ pub static MESH_PIPELINE_BASIC_MESH: GpuTestConfiguration =
365
398
& ctx,
366
399
MeshPipelineTestInfo {
367
400
use_task : false ,
401
+ use_mesh : true ,
368
402
use_frag : false ,
369
403
draw : true ,
370
404
} ,
@@ -377,6 +411,7 @@ pub static MESH_PIPELINE_BASIC_TASK_MESH: GpuTestConfiguration =
377
411
& ctx,
378
412
MeshPipelineTestInfo {
379
413
use_task : true ,
414
+ use_mesh : true ,
380
415
use_frag : false ,
381
416
draw : true ,
382
417
} ,
@@ -389,6 +424,7 @@ pub static MESH_PIPELINE_BASIC_MESH_FRAG: GpuTestConfiguration =
389
424
& ctx,
390
425
MeshPipelineTestInfo {
391
426
use_task : false ,
427
+ use_mesh : true ,
392
428
use_frag : true ,
393
429
draw : true ,
394
430
} ,
@@ -401,6 +437,7 @@ pub static MESH_PIPELINE_BASIC_TASK_MESH_FRAG: GpuTestConfiguration =
401
437
& ctx,
402
438
MeshPipelineTestInfo {
403
439
use_task : true ,
440
+ use_mesh : true ,
404
441
use_frag : true ,
405
442
draw : true ,
406
443
} ,
@@ -413,6 +450,7 @@ pub static MESH_PIPELINE_BASIC_MESH_NO_DRAW: GpuTestConfiguration =
413
450
& ctx,
414
451
MeshPipelineTestInfo {
415
452
use_task : false ,
453
+ use_mesh : true ,
416
454
use_frag : false ,
417
455
draw : false ,
418
456
} ,
@@ -425,6 +463,7 @@ pub static MESH_PIPELINE_BASIC_TASK_MESH_FRAG_NO_DRAW: GpuTestConfiguration =
425
463
& ctx,
426
464
MeshPipelineTestInfo {
427
465
use_task : true ,
466
+ use_mesh : true ,
428
467
use_frag : true ,
429
468
draw : false ,
430
469
} ,
@@ -447,3 +486,30 @@ pub static MESH_MULTI_DRAW_INDIRECT_COUNT: GpuTestConfiguration =
447
486
default_gpu_test_config ( DrawType :: MultiIndirectCount ) . run_sync ( |ctx| {
448
487
mesh_draw ( & ctx, DrawType :: MultiIndirectCount ) ;
449
488
} ) ;
489
+
490
+ /// When the mesh shading feature is disabled, calls to `create_mesh_pipeline`
491
+ /// should be rejected. This should be the case on all backends, not just the
492
+ /// ones where the feature could be turned on.
493
+ #[ gpu_test]
494
+ pub static MESH_DISABLED : GpuTestConfiguration = GpuTestConfiguration :: new ( ) . run_sync ( |ctx| {
495
+ fail (
496
+ & ctx. device ,
497
+ || {
498
+ mesh_pipeline_build (
499
+ & ctx,
500
+ MeshPipelineTestInfo {
501
+ use_task : false ,
502
+ use_mesh : false ,
503
+ use_frag : false ,
504
+ draw : true ,
505
+ } ,
506
+ ) ;
507
+ } ,
508
+ Some ( concat ! [
509
+ "Features Features { " ,
510
+ "features_wgpu: FeaturesWGPU(EXPERIMENTAL_MESH_SHADER), " ,
511
+ "features_webgpu: FeaturesWebGPU(0x0) " ,
512
+ "} are required but not enabled on the device" ,
513
+ ] ) ,
514
+ )
515
+ } ) ;
0 commit comments