@@ -83,22 +83,31 @@ class F extends ValidationTest {
8383 }
8484
8585 testVertexState (
86- success : boolean ,
86+ success : { shader : boolean ; pipeline : boolean } ,
8787 buffers : Iterable < GPUVertexBufferLayout > ,
8888 vertexShader : string = VERTEX_SHADER_CODE_WITH_NO_INPUT
8989 ) {
90- const vsModule = this . device . createShaderModule ( { code : vertexShader } ) ;
9190 const fsModule = this . device . createShaderModule ( {
9291 code : `
9392 [[stage(fragment)]] fn main() -> [[location(0)]] vec4<f32> {
9493 return vec4<f32>(0.0, 1.0, 0.0, 1.0);
9594 }` ,
9695 } ) ;
9796
97+ let vsModule : GPUShaderModule | undefined ;
98+
99+ this . expectValidationError ( ( ) => {
100+ vsModule = this . device . createShaderModule ( { code : vertexShader } ) ;
101+ } , ! success . shader ) ;
102+
103+ if ( vsModule === undefined ) {
104+ return ;
105+ }
106+
98107 this . expectValidationError ( ( ) => {
99108 this . device . createRenderPipeline ( {
100109 vertex : {
101- module : vsModule ,
110+ module : vsModule as GPUShaderModule ,
102111 entryPoint : 'main' ,
103112 buffers,
104113 } ,
@@ -109,7 +118,7 @@ class F extends ValidationTest {
109118 } ,
110119 primitive : { topology : 'triangle-list' } ,
111120 } ) ;
112- } , ! success ) ;
121+ } , ! success . pipeline ) ;
113122 }
114123
115124 generateTestVertexShader ( inputs : { type : string ; location : number } [ ] ) : string {
@@ -164,7 +173,7 @@ g.test('max_vertex_buffer_limit')
164173 }
165174 }
166175
167- const success = count <= kMaxVertexBuffers ;
176+ const success = { shader : true , pipeline : count <= kMaxVertexBuffers } ;
168177 t . testVertexState ( success , vertexBuffers ) ;
169178 } ) ;
170179
@@ -201,7 +210,7 @@ g.test('max_vertex_attribute_limit')
201210 vertexBuffers . push ( { arrayStride : 0 , attributes } ) ;
202211 }
203212
204- const success = attribCount <= kMaxVertexAttributes ;
213+ const success = { shader : true , pipeline : attribCount <= kMaxVertexAttributes } ;
205214 t . testVertexState ( success , vertexBuffers ) ;
206215 } ) ;
207216
@@ -229,7 +238,7 @@ g.test('max_vertex_buffer_array_stride_limit')
229238 const vertexBuffers = [ ] ;
230239 vertexBuffers [ vertexBufferIndex ] = { arrayStride, attributes : [ ] } ;
231240
232- const success = arrayStride <= kMaxVertexBufferArrayStride ;
241+ const success = { shader : true , pipeline : arrayStride <= kMaxVertexBufferArrayStride } ;
233242 t . testVertexState ( success , vertexBuffers ) ;
234243 } ) ;
235244
@@ -258,7 +267,7 @@ g.test('vertex_buffer_array_stride_limit_alignment')
258267 const vertexBuffers = [ ] ;
259268 vertexBuffers [ vertexBufferIndex ] = { arrayStride, attributes : [ ] } ;
260269
261- const success = arrayStride % 4 === 0 ;
270+ const success = { shader : true , pipeline : arrayStride % 4 === 0 } ;
262271 t . testVertexState ( success , vertexBuffers ) ;
263272 } ) ;
264273
@@ -295,7 +304,7 @@ g.test('vertex_attribute_shaderLocation_limit')
295304 const vertexBuffers = [ ] ;
296305 vertexBuffers [ vertexBufferIndex ] = { arrayStride : 256 , attributes } ;
297306
298- const success = testShaderLocation < kMaxVertexAttributes ;
307+ const success = { shader : true , pipeline : testShaderLocation < kMaxVertexAttributes } ;
299308 t . testVertexState ( success , vertexBuffers ) ;
300309 } ) ;
301310
@@ -360,18 +369,26 @@ g.test('vertex_attribute_shaderLocation_unique')
360369
361370 // Note that an empty vertex shader will be used so errors only happens because of the conflict
362371 // in the vertex state.
363- const success = shaderLocationA !== shaderLocationB ;
372+ const success = { shader : true , pipeline : shaderLocationA !== shaderLocationB } ;
364373 t . testVertexState ( success , vertexBuffers ) ;
365374 } ) ;
366375
367376g . test ( 'vertex_shader_input_location_limit' )
368377 . desc (
369378 `Test that vertex shader's input's location decoration must be less than maxVertexAttributes.
370- - Test for shaderLocation 0, 1, limit - 1, limit`
379+ - Test for shaderLocation 0, 1, limit - 1, limit, -1, 0x7fffffff, 2 ** 32 `
371380 )
372381 . paramsSubcasesOnly ( u =>
373382 u //
374- . combine ( 'testLocation' , [ 0 , 1 , kMaxVertexAttributes - 1 , kMaxVertexAttributes , - 1 , 2 ** 32 ] )
383+ . combine ( 'testLocation' , [
384+ 0 ,
385+ 1 ,
386+ kMaxVertexAttributes - 1 ,
387+ kMaxVertexAttributes ,
388+ - 1 ,
389+ 0x7fffffff ,
390+ 2 ** 32 ,
391+ ] )
375392 )
376393 . fn ( t => {
377394 const { testLocation } = t . params ;
@@ -396,7 +413,13 @@ g.test('vertex_shader_input_location_limit')
396413 } ,
397414 ] ;
398415
399- const success = testLocation < kMaxVertexAttributes ;
416+ const success = {
417+ // [[location(n)]] decoration must be a "non-negative i32 literal"
418+ // TODO: Dawn raises a "Attribute location (N) over limits" error at
419+ // shader creation time for N>15. Is this right?
420+ shader : testLocation >= 0 && testLocation < 0x7fffffff ,
421+ pipeline : testLocation >= 0 && testLocation < kMaxVertexAttributes ,
422+ } ;
400423 t . testVertexState ( success , vertexBuffers , shader ) ;
401424 } ) ;
402425
@@ -438,14 +461,15 @@ g.test('vertex_shader_input_location_in_vertex_state')
438461 extraAttributeCount,
439462 extraAttributeSkippedLocations : [ testShaderLocation ] ,
440463 } ) ;
441- t . testVertexState ( false , vertexBuffers , shader ) ;
464+
465+ t . testVertexState ( { shader : true , pipeline : false } , vertexBuffers , shader ) ;
442466
443467 // Add an attribute for the test location and try again.
444468 addTestAttributes ( attributes , {
445469 testAttribute : { format : 'float32' , shaderLocation : testShaderLocation , offset : 0 } ,
446470 testAttributeAtStart,
447471 } ) ;
448- t . testVertexState ( true , vertexBuffers , shader ) ;
472+ t . testVertexState ( { shader : true , pipeline : true } , vertexBuffers , shader ) ;
449473 } ) ;
450474
451475g . test ( 'vertex_shader_type_matches_attribute_format' )
@@ -484,7 +508,7 @@ g.test('vertex_shader_type_matches_attribute_format')
484508 float : 'f32' ,
485509 } [ kVertexFormatInfo [ format ] . type ] ;
486510
487- const success = requiredBaseType === shaderBaseType ;
511+ const success = { shader : true , pipeline : requiredBaseType === shaderBaseType } ;
488512 t . testVertexState (
489513 success ,
490514 [
@@ -554,7 +578,7 @@ g.test('vertex_attribute_offset_alignment')
554578
555579 const formatInfo = kVertexFormatInfo [ format ] ;
556580 const formatSize = formatInfo . bytesPerComponent * formatInfo . componentCount ;
557- const success = offset % Math . min ( 4 , formatSize ) === 0 ;
581+ const success = { shader : true , pipeline : offset % Math . min ( 4 , formatSize ) === 0 } ;
558582
559583 t . testVertexState ( success , vertexBuffers ) ;
560584 } ) ;
@@ -628,7 +652,7 @@ g.test('vertex_attribute_contained_in_stride')
628652 const formatSize = formatInfo . bytesPerComponent * formatInfo . componentCount ;
629653 const limit = arrayStride === 0 ? kMaxVertexBufferArrayStride : arrayStride ;
630654
631- const success = offset + formatSize <= limit ;
655+ const success = { shader : true , pipeline : offset + formatSize <= limit } ;
632656 t . testVertexState ( success , vertexBuffers ) ;
633657 } ) ;
634658
@@ -642,5 +666,5 @@ g.test('many_attributes_overlapping')
642666 attributes . push ( { format : formats [ i % 3 ] , offset : i * 4 , shaderLocation : i } as const ) ;
643667 }
644668
645- t . testVertexState ( true , [ { arrayStride : 0 , attributes } ] ) ;
669+ t . testVertexState ( { shader : true , pipeline : true } , [ { arrayStride : 0 , attributes } ] ) ;
646670 } ) ;
0 commit comments