diff --git a/src/webgpu/capability_info.ts b/src/webgpu/capability_info.ts index 9d9478077eb6..b543582bc816 100644 --- a/src/webgpu/capability_info.ts +++ b/src/webgpu/capability_info.ts @@ -937,6 +937,7 @@ export const kKnownWGSLLanguageFeatures = [ 'unrestricted_pointer_parameters', 'pointer_composite_access', 'uniform_buffer_standard_layout', + 'texture_and_sampler_let', ] as const; export type WGSLLanguageFeature = (typeof kKnownWGSLLanguageFeatures)[number]; diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index dbebe183a129..4eda9bb60de0 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -2000,6 +2000,7 @@ "webgpu:shader,validation,decl,context_dependent_resolution:language_names:*": { "subcaseMS": 4.920 }, "webgpu:shader,validation,decl,context_dependent_resolution:swizzle_names:*": { "subcaseMS": 27.579 }, "webgpu:shader,validation,decl,let:initializer:*": { "subcaseMS": 0.706 }, + "webgpu:shader,validation,decl,let:initializer_type:*": { "subcaseMS": 423.312 }, "webgpu:shader,validation,decl,let:module_scope:*": { "subcaseMS": 0.619 }, "webgpu:shader,validation,decl,let:type:*": { "subcaseMS": 122.199 }, "webgpu:shader,validation,decl,override:array_size:*": { "subcaseMS": 44.868 }, diff --git a/src/webgpu/shader/execution/expression/call/builtin/textureDimensions.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/textureDimensions.spec.ts index 6933ea3ae1de..023f6847d1c5 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/textureDimensions.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/textureDimensions.spec.ts @@ -239,14 +239,16 @@ function run( values: TestValues ) { const outputType = values.expected.length > 1 ? `vec${values.expected.length}u` : 'u32'; + const allowLet = t.hasLanguageFeature('texture_and_sampler_let'); + const decl = allowLet ? 'let t = texture;' : ''; + const tex = allowLet ? 't' : 'texture'; const wgsl = ` @group(0) @binding(0) var texture : ${textureType}; fn getValue() -> ${outputType} { + ${decl} return ${ - levelArg !== undefined - ? `textureDimensions(texture, ${levelArg})` - : 'textureDimensions(texture)' + levelArg !== undefined ? `textureDimensions(${tex}, ${levelArg})` : `textureDimensions(${tex})` }; } `; diff --git a/src/webgpu/shader/validation/decl/let.spec.ts b/src/webgpu/shader/validation/decl/let.spec.ts index 0a37534cdca8..1082f7ea26d8 100644 --- a/src/webgpu/shader/validation/decl/let.spec.ts +++ b/src/webgpu/shader/validation/decl/let.spec.ts @@ -10,7 +10,7 @@ export const g = makeTestGroup(ShaderValidationTest); interface Case { code: string; - valid: boolean; + valid: boolean | 'texture_and_sampler_let'; decls?: string; } @@ -89,6 +89,26 @@ const kTypeCases: Record = { let y : i32 = x;`, valid: true, }, + texture_2d: { + code: `let x = tex2d;`, + valid: 'texture_and_sampler_let', + decls: `@group(0) @binding(0) var tex2d : texture_2d;`, + }, + texture_storage_1d: { + code: `let x : texture_storage_1d = tex1d;`, + valid: 'texture_and_sampler_let', + decls: `@group(0) @binding(0) var tex1d : texture_storage_1d;`, + }, + sampler: { + code: `let s = samp;`, + valid: 'texture_and_sampler_let', + decls: `@group(0) @binding(0) var samp : sampler;`, + }, + sampler_comparison: { + code: `let s : sampler_comparison = samp_comp;`, + valid: 'texture_and_sampler_let', + decls: `@group(0) @binding(0) var samp_comp : sampler_comparison;`, + }, }; g.test('type') @@ -106,7 +126,10 @@ ${testcase.decls ?? ''} fn foo() { ${testcase.code} }`; - const expect = testcase.valid; + let expect: boolean = testcase.valid === true; + if (testcase.valid === 'texture_and_sampler_let') { + expect = t.hasLanguageFeature('texture_and_sampler_let'); + } t.expectCompileResult(expect, code); }); @@ -168,7 +191,7 @@ fn foo() { ${testcase.code} }`; const expect = testcase.valid; - t.expectCompileResult(expect, code); + t.expectCompileResult(expect === true, code); }); g.test('module_scope') diff --git a/src/webgpu/shader/validation/expression/call/builtin/textureDimensions.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/textureDimensions.spec.ts index 2927a4dc3cf5..c549e176d029 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/textureDimensions.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/textureDimensions.spec.ts @@ -118,11 +118,15 @@ Validates the return type of ${builtin} is the expected type. .combine('returnType', keysOf(kValuesTypes)) .combine('textureType', kNonStorageTextureTypes) .beginSubcases() + .combine('let', [false, true] as const) .expand('texelType', t => kNonStorageTextureTypeInfo[t.textureType].texelTypes.map(v => v.toString()) ) ) .fn(t => { + if (t.params.let) { + t.skipIfLanguageFeatureNotSupported('texture_and_sampler_let'); + } const { returnType, textureType, texelType } = t.params; const returnVarType = kValuesTypes[returnType]; const { returnType: returnRequiredType, hasLevelArg } = @@ -132,11 +136,14 @@ Validates the return type of ${builtin} is the expected type. const texelArgType = stringToType(texelType); const textureWGSL = getNonStorageTextureTypeWGSL(textureType, texelArgType); const levelWGSL = hasLevelArg ? ', 0' : ''; + const t_let = t.params.let ? `let t_let = t${levelWGSL};` : ``; + const param = t.params.let ? t_let : `t${levelWGSL}`; const code = ` @group(0) @binding(0) var t: ${textureWGSL}; @fragment fn fs() -> @location(0) vec4f { - let v: ${varWGSL} = textureDimensions(t${levelWGSL}); + ${t_let} + let v: ${varWGSL} = textureDimensions(${param}); return vec4f(0); } `;