@@ -83,22 +83,31 @@ class F extends ValidationTest {
83
83
}
84
84
85
85
testVertexState (
86
- success : boolean ,
86
+ success : { shader : boolean ; pipeline : boolean } ,
87
87
buffers : Iterable < GPUVertexBufferLayout > ,
88
88
vertexShader : string = VERTEX_SHADER_CODE_WITH_NO_INPUT
89
89
) {
90
- const vsModule = this . device . createShaderModule ( { code : vertexShader } ) ;
91
90
const fsModule = this . device . createShaderModule ( {
92
91
code : `
93
92
[[stage(fragment)]] fn main() -> [[location(0)]] vec4<f32> {
94
93
return vec4<f32>(0.0, 1.0, 0.0, 1.0);
95
94
}` ,
96
95
} ) ;
97
96
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
+
98
107
this . expectValidationError ( ( ) => {
99
108
this . device . createRenderPipeline ( {
100
109
vertex : {
101
- module : vsModule ,
110
+ module : vsModule as GPUShaderModule ,
102
111
entryPoint : 'main' ,
103
112
buffers,
104
113
} ,
@@ -109,7 +118,7 @@ class F extends ValidationTest {
109
118
} ,
110
119
primitive : { topology : 'triangle-list' } ,
111
120
} ) ;
112
- } , ! success ) ;
121
+ } , ! success . pipeline ) ;
113
122
}
114
123
115
124
generateTestVertexShader ( inputs : { type : string ; location : number } [ ] ) : string {
@@ -164,7 +173,7 @@ g.test('max_vertex_buffer_limit')
164
173
}
165
174
}
166
175
167
- const success = count <= kMaxVertexBuffers ;
176
+ const success = { shader : true , pipeline : count <= kMaxVertexBuffers } ;
168
177
t . testVertexState ( success , vertexBuffers ) ;
169
178
} ) ;
170
179
@@ -201,7 +210,7 @@ g.test('max_vertex_attribute_limit')
201
210
vertexBuffers . push ( { arrayStride : 0 , attributes } ) ;
202
211
}
203
212
204
- const success = attribCount <= kMaxVertexAttributes ;
213
+ const success = { shader : true , pipeline : attribCount <= kMaxVertexAttributes } ;
205
214
t . testVertexState ( success , vertexBuffers ) ;
206
215
} ) ;
207
216
@@ -229,7 +238,7 @@ g.test('max_vertex_buffer_array_stride_limit')
229
238
const vertexBuffers = [ ] ;
230
239
vertexBuffers [ vertexBufferIndex ] = { arrayStride, attributes : [ ] } ;
231
240
232
- const success = arrayStride <= kMaxVertexBufferArrayStride ;
241
+ const success = { shader : true , pipeline : arrayStride <= kMaxVertexBufferArrayStride } ;
233
242
t . testVertexState ( success , vertexBuffers ) ;
234
243
} ) ;
235
244
@@ -258,7 +267,7 @@ g.test('vertex_buffer_array_stride_limit_alignment')
258
267
const vertexBuffers = [ ] ;
259
268
vertexBuffers [ vertexBufferIndex ] = { arrayStride, attributes : [ ] } ;
260
269
261
- const success = arrayStride % 4 === 0 ;
270
+ const success = { shader : true , pipeline : arrayStride % 4 === 0 } ;
262
271
t . testVertexState ( success , vertexBuffers ) ;
263
272
} ) ;
264
273
@@ -295,7 +304,7 @@ g.test('vertex_attribute_shaderLocation_limit')
295
304
const vertexBuffers = [ ] ;
296
305
vertexBuffers [ vertexBufferIndex ] = { arrayStride : 256 , attributes } ;
297
306
298
- const success = testShaderLocation < kMaxVertexAttributes ;
307
+ const success = { shader : true , pipeline : testShaderLocation < kMaxVertexAttributes } ;
299
308
t . testVertexState ( success , vertexBuffers ) ;
300
309
} ) ;
301
310
@@ -360,18 +369,26 @@ g.test('vertex_attribute_shaderLocation_unique')
360
369
361
370
// Note that an empty vertex shader will be used so errors only happens because of the conflict
362
371
// in the vertex state.
363
- const success = shaderLocationA !== shaderLocationB ;
372
+ const success = { shader : true , pipeline : shaderLocationA !== shaderLocationB } ;
364
373
t . testVertexState ( success , vertexBuffers ) ;
365
374
} ) ;
366
375
367
376
g . test ( 'vertex_shader_input_location_limit' )
368
377
. desc (
369
378
`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 `
371
380
)
372
381
. paramsSubcasesOnly ( u =>
373
382
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
+ ] )
375
392
)
376
393
. fn ( t => {
377
394
const { testLocation } = t . params ;
@@ -396,7 +413,13 @@ g.test('vertex_shader_input_location_limit')
396
413
} ,
397
414
] ;
398
415
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
+ } ;
400
423
t . testVertexState ( success , vertexBuffers , shader ) ;
401
424
} ) ;
402
425
@@ -438,14 +461,15 @@ g.test('vertex_shader_input_location_in_vertex_state')
438
461
extraAttributeCount,
439
462
extraAttributeSkippedLocations : [ testShaderLocation ] ,
440
463
} ) ;
441
- t . testVertexState ( false , vertexBuffers , shader ) ;
464
+
465
+ t . testVertexState ( { shader : true , pipeline : false } , vertexBuffers , shader ) ;
442
466
443
467
// Add an attribute for the test location and try again.
444
468
addTestAttributes ( attributes , {
445
469
testAttribute : { format : 'float32' , shaderLocation : testShaderLocation , offset : 0 } ,
446
470
testAttributeAtStart,
447
471
} ) ;
448
- t . testVertexState ( true , vertexBuffers , shader ) ;
472
+ t . testVertexState ( { shader : true , pipeline : true } , vertexBuffers , shader ) ;
449
473
} ) ;
450
474
451
475
g . test ( 'vertex_shader_type_matches_attribute_format' )
@@ -484,7 +508,7 @@ g.test('vertex_shader_type_matches_attribute_format')
484
508
float : 'f32' ,
485
509
} [ kVertexFormatInfo [ format ] . type ] ;
486
510
487
- const success = requiredBaseType === shaderBaseType ;
511
+ const success = { shader : true , pipeline : requiredBaseType === shaderBaseType } ;
488
512
t . testVertexState (
489
513
success ,
490
514
[
@@ -554,7 +578,7 @@ g.test('vertex_attribute_offset_alignment')
554
578
555
579
const formatInfo = kVertexFormatInfo [ format ] ;
556
580
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 } ;
558
582
559
583
t . testVertexState ( success , vertexBuffers ) ;
560
584
} ) ;
@@ -628,7 +652,7 @@ g.test('vertex_attribute_contained_in_stride')
628
652
const formatSize = formatInfo . bytesPerComponent * formatInfo . componentCount ;
629
653
const limit = arrayStride === 0 ? kMaxVertexBufferArrayStride : arrayStride ;
630
654
631
- const success = offset + formatSize <= limit ;
655
+ const success = { shader : true , pipeline : offset + formatSize <= limit } ;
632
656
t . testVertexState ( success , vertexBuffers ) ;
633
657
} ) ;
634
658
@@ -642,5 +666,5 @@ g.test('many_attributes_overlapping')
642
666
attributes . push ( { format : formats [ i % 3 ] , offset : i * 4 , shaderLocation : i } as const ) ;
643
667
}
644
668
645
- t . testVertexState ( true , [ { arrayStride : 0 , attributes } ] ) ;
669
+ t . testVertexState ( { shader : true , pipeline : true } , [ { arrayStride : 0 , attributes } ] ) ;
646
670
} ) ;
0 commit comments