diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index 4df2c9dd10b6..f23268f9ece3 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -2252,6 +2252,8 @@ "webgpu:shader,validation,types,alias:no_indirect_recursion_via_struct_attribute:*": { "subcaseMS": 1.584 }, "webgpu:shader,validation,types,alias:no_indirect_recursion_via_struct_member:*": { "subcaseMS": 1.000 }, "webgpu:shader,validation,types,alias:no_indirect_recursion_via_vector_element:*": { "subcaseMS": 1.050 }, + "webgpu:shader,validation,types,array:invalid:*": { "subcaseMS": 2.470 }, + "webgpu:shader,validation,types,array:valid:*": { "subcaseMS": 449.293 }, "webgpu:shader,validation,types,atomics:address_space:*": { "subcaseMS": 1.050 }, "webgpu:shader,validation,types,atomics:invalid_operations:*": { "subcaseMS": 1.050 }, "webgpu:shader,validation,types,atomics:type:*": { "subcaseMS": 1.050 }, diff --git a/src/webgpu/shader/validation/types/array.spec.ts b/src/webgpu/shader/validation/types/array.spec.ts new file mode 100644 index 000000000000..636906f52ea7 --- /dev/null +++ b/src/webgpu/shader/validation/types/array.spec.ts @@ -0,0 +1,122 @@ +export const description = ` +Validation tests for array types +`; + +import { makeTestGroup } from '../../../../common/framework/test_group.js'; +import { keysOf } from '../../../../common/util/data_tables.js'; +import { ShaderValidationTest } from '../shader_validation_test.js'; + +export const g = makeTestGroup(ShaderValidationTest); + +const kValidCases = { + // Basic element types. + i32: `alias T = array;`, + u32: `alias T = array;`, + f32: `alias T = array;`, + f16: `enable f16;\nalias T = array;`, + bool: `alias T = array;`, + + // Composite elements + vec2u: `alias T = array;`, + vec3i: `alias T = array;`, + vec4f: `alias T = array;`, + array: `alias T = array>;`, + struct: `struct S { x : u32 }\nalias T = array;`, + mat2x2f: `alias T = array;`, + mat4x4h: `enable f16;\nalias T = array;`, + + // Atomic elements + atomicu: `alias T = array>;`, + atomici: `alias T = array>;`, + + // Count expressions + literal_count: `alias T = array;`, + literali_count: `alias T = array;`, + literalu_count: `alias T = array;`, + const_count: `const x = 8;\nalias T = array;`, + const_expr_count1: `alias T = array;`, + const_expr_count2: `const x = 4;\nalias T = array;`, + override_count: `override x : u32;\nalias T = array;`, + override_expr1: `override x = 2;\nalias T = array;`, + override_expr2: `override x = 1;\nalias T = array;`, + override_zero: `override x = 0;\nalias T = array;`, + override_neg: `override x = -1;\nalias T = array;`, + + // Same array types + same_const_value1: ` + const x = 8; + const y = 8; + var v : array = array();`, + same_const_value2: ` + const x = 8; + var v : array = array();`, + same_const_value3: ` + var v : array = array();`, + same_override: ` + requires unrestricted_pointer_parameters; + override x : u32; + var v : array; + fn bar(p : ptr>) { } + fn foo() { bar(&v); }`, + + // Shadow + shadow: `alias array = vec2f;`, +}; + +g.test('valid') + .desc('Valid array type tests') + .params(u => u.combine('case', keysOf(kValidCases))) + .beforeAllSubcases(t => { + const code = kValidCases[t.params.case]; + if (code.indexOf('f16') >= 0) { + t.selectDeviceOrSkipTestCase('shader-f16'); + } + }) + .fn(t => { + const code = kValidCases[t.params.case]; + t.skipIf( + code.indexOf('unrestricted') >= 0 && !t.hasLanguageFeature('unrestricted_pointer_parameters'), + 'Test requires unrestricted_pointer_parameters' + ); + t.expectCompileResult(true, code); + }); + +const kInvalidCases = { + f16_without_enable: `alias T = array;`, + runtime_nested: `alias T = array, 4>;`, + override_nested: ` + override x : u32; + alias T = array, 4>;`, + override_nested_struct: ` + override x : u32; + struct T { x : array }`, + zero_size: `alias T = array;`, + negative_size: `alias T = array;`, + const_zero: `const x = 0;\nalias T = array;`, + const_neg: `const x = 1;\nconst y = 2;\nalias T = array;`, + incompatible_overrides: ` + requires unrestricted_pointer_parameters; + override x = 8; + override y = 8; + var v : array + fn bar(p : ptr>) { } + fn foo() { bar(&v); }`, +}; + +g.test('invalid') + .desc('Invalid array type tests') + .params(u => u.combine('case', keysOf(kInvalidCases))) + .beforeAllSubcases(t => { + const code = kInvalidCases[t.params.case]; + if (code.indexOf('f16') >= 0) { + t.selectDeviceOrSkipTestCase('shader-f16'); + } + }) + .fn(t => { + const code = kInvalidCases[t.params.case]; + t.skipIf( + code.indexOf('unrestricted') >= 0 && !t.hasLanguageFeature('unrestricted_pointer_parameters'), + 'Test requires unrestricted_pointer_parameters' + ); + t.expectCompileResult(false, code); + });