diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index 1f8f74330495..8380593d58bd 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -1830,6 +1830,8 @@ "webgpu:shader,validation,expression,call,builtin,unpack4xU8:must_use:*": { "subcaseMS": 32.800 }, "webgpu:shader,validation,expression,call,builtin,unpack4xU8:supported:*": { "subcaseMS": 98.501 }, "webgpu:shader,validation,expression,call,builtin,unpack4xU8:unsupported:*": { "subcaseMS": 346.801 }, + "webgpu:shader,validation,extension,pointer_composite_access:deref:*": { "subcaseMS": 0.0 }, + "webgpu:shader,validation,extension,pointer_composite_access:pointer:*": { "subcaseMS": 0.0 }, "webgpu:shader,validation,functions,alias_analysis:aliasing_inside_function:*": { "subcaseMS": 1.200 }, "webgpu:shader,validation,functions,alias_analysis:member_accessors:*": { "subcaseMS": 1.656 }, "webgpu:shader,validation,functions,alias_analysis:one_pointer_one_module_scope:*": { "subcaseMS": 1.598 }, diff --git a/src/webgpu/shader/validation/extension/pointer_composite_access.spec.ts b/src/webgpu/shader/validation/extension/pointer_composite_access.spec.ts new file mode 100644 index 000000000000..c2cbf8517176 --- /dev/null +++ b/src/webgpu/shader/validation/extension/pointer_composite_access.spec.ts @@ -0,0 +1,130 @@ +export const description = ` +Validation tests for pointer_composite_access extension +`; + +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); + +function makeSource(module: string, init_expr: string, pointer_read_expr: string) { + return ` + ${module} + fn f() { + var a = ${init_expr}; + let p = &a; + let r = ${pointer_read_expr}; + }`; +} + +const kCases = { + // Via identifier 'a' + array_index_access_via_identifier: { + module: '', + init_expr: 'array()', + via_deref: '(*(&a))[0];', + via_pointer: '(&a)[0];', + }, + vector_index_access_via_identifier: { + module: '', + init_expr: 'vec3()', + via_deref: '(*(&a))[0]', + via_pointer: '(&a)[0]', + }, + vector_member_access_via_identifier: { + module: '', + init_expr: 'vec3()', + via_deref: '(*(&a)).x;', + via_pointer: '(&a).x;', + }, + matrix_index_access_via_identifier: { + module: '', + init_expr: 'mat2x3()', + via_deref: '(*(&a))[0]', + via_pointer: '(&a)[0]', + }, + struct_member_access_via_identifier: { + module: 'struct S { a : i32, }', + init_expr: 'S()', + via_deref: '(*(&a)).a;', + via_pointer: '(&a).a;', + }, + builtin_struct_modf_via_identifier: { + module: '', + init_expr: 'modf(1.5)', + via_deref: 'vec2((*(&a)).fract, (*(&a)).whole)', + via_pointer: 'vec2((&a).fract, (&a).whole)', + }, + builtin_struct_frexp_via_identifier: { + module: '', + init_expr: 'frexp(1.5)', + via_deref: 'vec2((*(&a)).fract, f32((*(&a)).exp))', + via_pointer: 'vec2((&a).fract, f32((&a).exp))', + }, + + // Via pointer 'p' + array_index_access_via_pointer: { + module: '', + init_expr: 'array()', + via_deref: '(*p)[0];', + via_pointer: 'p[0];', + }, + vector_index_access_via_pointer: { + module: '', + init_expr: 'vec3()', + via_deref: '(*p)[0]', + via_pointer: 'p[0]', + }, + vector_member_access_via_pointer: { + module: '', + init_expr: 'vec3()', + via_deref: '(*p).x;', + via_pointer: 'p.x;', + }, + matrix_index_access_via_pointer: { + module: '', + init_expr: 'mat2x3()', + via_deref: '(*p)[0]', + via_pointer: 'p[0]', + }, + struct_member_access_via_pointer: { + module: 'struct S { a : i32, }', + init_expr: 'S()', + via_deref: '(*p).a;', + via_pointer: 'p.a;', + }, + builtin_struct_modf_via_pointer: { + module: '', + init_expr: 'modf(1.5)', + via_deref: 'vec2((*p).fract, (*p).whole)', + via_pointer: 'vec2(p.fract, p.whole)', + }, + builtin_struct_frexp_via_pointer: { + module: '', + init_expr: 'frexp(1.5)', + via_deref: 'vec2((*p).fract, f32((*p).exp))', + via_pointer: 'vec2(p.fract, f32(p.exp))', + }, +}; + +g.test('deref') + .desc('Baseline test: pointer deref is always valid') + .params(u => u.combine('case', keysOf(kCases))) + .fn(t => { + const curr = kCases[t.params.case]; + const source = makeSource(curr.module, curr.init_expr, curr.via_deref); + t.expectCompileResult(true, source); + }); + +g.test('pointer') + .desc( + 'Tests that direct pointer access is valid if pointer_composite_access is supported, else it should fail' + ) + .params(u => u.combine('case', keysOf(kCases))) + .fn(t => { + const curr = kCases[t.params.case]; + const source = makeSource(curr.module, curr.init_expr, curr.via_pointer); + const should_pass = t.hasLanguageFeature('pointer_composite_access'); + t.expectCompileResult(should_pass, source); + });