@@ -3,11 +3,15 @@ use std::{
33 process:: Stdio ,
44} ;
55
6- use wgpu:: util:: DeviceExt ;
6+ use wgpu:: { util:: DeviceExt , Backends } ;
77use wgpu_test:: {
8- gpu_test, GpuTestConfiguration , GpuTestInitializer , TestParameters , TestingContext ,
8+ fail, gpu_test, FailureCase , GpuTestConfiguration , GpuTestInitializer , TestParameters ,
9+ TestingContext ,
910} ;
1011
12+ /// Backends that support mesh shaders
13+ const MESH_SHADER_BACKENDS : Backends = Backends :: DX12 . union ( Backends :: VULKAN ) ;
14+
1115pub fn all_tests ( tests : & mut Vec < GpuTestInitializer > ) {
1216 tests. extend ( [
1317 MESH_PIPELINE_BASIC_MESH ,
@@ -19,6 +23,7 @@ pub fn all_tests(tests: &mut Vec<GpuTestInitializer>) {
1923 MESH_MULTI_DRAW_INDIRECT_COUNT ,
2024 MESH_PIPELINE_BASIC_MESH_NO_DRAW ,
2125 MESH_PIPELINE_BASIC_TASK_MESH_FRAG_NO_DRAW ,
26+ MESH_DISABLED ,
2227 ] ) ;
2328}
2429
@@ -97,21 +102,44 @@ fn get_shaders(
97102 device : & wgpu:: Device ,
98103 backend : wgpu:: Backend ,
99104 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" ) ) ;
101117 if backend == wgpu:: Backend :: Vulkan {
102118 (
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" ) ) ,
106126 )
107127 } else if backend == wgpu:: Backend :: Dx12 {
108128 (
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) ) ,
112138 )
113139 } 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 )
115143 }
116144}
117145
@@ -146,6 +174,7 @@ fn create_depth(
146174
147175struct MeshPipelineTestInfo {
148176 use_task : bool ,
177+ use_mesh : bool ,
149178 use_frag : bool ,
150179 draw : bool ,
151180}
@@ -158,16 +187,11 @@ fn hash_testing_context(ctx: &TestingContext) -> u64 {
158187
159188fn mesh_pipeline_build ( ctx : & TestingContext , info : MeshPipelineTestInfo ) {
160189 let backend = ctx. adapter . get_info ( ) . backend ;
161- if backend != wgpu:: Backend :: Vulkan && backend != wgpu:: Backend :: Dx12 {
162- return ;
163- }
164190 let device = & ctx. device ;
165191 let ( _depth_image, depth_view, depth_state) = create_depth ( device) ;
166192
167193 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) ;
171195 let layout = device. create_pipeline_layout ( & wgpu:: PipelineLayoutDescriptor {
172196 label : None ,
173197 bind_group_layouts : & [ ] ,
@@ -246,7 +270,15 @@ fn mesh_draw(ctx: &TestingContext, draw_type: DrawType) {
246270 let device = & ctx. device ;
247271 let ( _depth_image, depth_view, depth_state) = create_depth ( device) ;
248272 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 ( ) ;
250282 let layout = device. create_pipeline_layout ( & wgpu:: PipelineLayoutDescriptor {
251283 label : None ,
252284 bind_group_layouts : & [ ] ,
@@ -343,6 +375,7 @@ fn mesh_draw(ctx: &TestingContext, draw_type: DrawType) {
343375fn default_gpu_test_config ( draw_type : DrawType ) -> GpuTestConfiguration {
344376 GpuTestConfiguration :: new ( ) . parameters (
345377 TestParameters :: default ( )
378+ . skip ( FailureCase :: backend ( !MESH_SHADER_BACKENDS ) )
346379 . test_features_limits ( )
347380 . features (
348381 wgpu:: Features :: EXPERIMENTAL_MESH_SHADER
@@ -365,6 +398,7 @@ pub static MESH_PIPELINE_BASIC_MESH: GpuTestConfiguration =
365398 & ctx,
366399 MeshPipelineTestInfo {
367400 use_task : false ,
401+ use_mesh : true ,
368402 use_frag : false ,
369403 draw : true ,
370404 } ,
@@ -377,6 +411,7 @@ pub static MESH_PIPELINE_BASIC_TASK_MESH: GpuTestConfiguration =
377411 & ctx,
378412 MeshPipelineTestInfo {
379413 use_task : true ,
414+ use_mesh : true ,
380415 use_frag : false ,
381416 draw : true ,
382417 } ,
@@ -389,6 +424,7 @@ pub static MESH_PIPELINE_BASIC_MESH_FRAG: GpuTestConfiguration =
389424 & ctx,
390425 MeshPipelineTestInfo {
391426 use_task : false ,
427+ use_mesh : true ,
392428 use_frag : true ,
393429 draw : true ,
394430 } ,
@@ -401,6 +437,7 @@ pub static MESH_PIPELINE_BASIC_TASK_MESH_FRAG: GpuTestConfiguration =
401437 & ctx,
402438 MeshPipelineTestInfo {
403439 use_task : true ,
440+ use_mesh : true ,
404441 use_frag : true ,
405442 draw : true ,
406443 } ,
@@ -413,6 +450,7 @@ pub static MESH_PIPELINE_BASIC_MESH_NO_DRAW: GpuTestConfiguration =
413450 & ctx,
414451 MeshPipelineTestInfo {
415452 use_task : false ,
453+ use_mesh : true ,
416454 use_frag : false ,
417455 draw : false ,
418456 } ,
@@ -425,6 +463,7 @@ pub static MESH_PIPELINE_BASIC_TASK_MESH_FRAG_NO_DRAW: GpuTestConfiguration =
425463 & ctx,
426464 MeshPipelineTestInfo {
427465 use_task : true ,
466+ use_mesh : true ,
428467 use_frag : true ,
429468 draw : false ,
430469 } ,
@@ -447,3 +486,30 @@ pub static MESH_MULTI_DRAW_INDIRECT_COUNT: GpuTestConfiguration =
447486 default_gpu_test_config ( DrawType :: MultiIndirectCount ) . run_sync ( |ctx| {
448487 mesh_draw ( & ctx, DrawType :: MultiIndirectCount ) ;
449488 } ) ;
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