From 97fd0414dd4fccce3048e2f19dcfccd7361499a3 Mon Sep 17 00:00:00 2001 From: Alan Baker Date: Wed, 29 Oct 2025 11:43:07 -0400 Subject: [PATCH 1/6] Add CTS for texture_and_sampler_let language feature --- src/webgpu/capability_info.ts | 1 + src/webgpu/listing_meta.json | 1 + src/webgpu/shader/validation/decl/let.spec.ts | 29 +++++++++++++++++-- .../call/builtin/textureDimensions.spec.ts | 9 +++++- 4 files changed, 36 insertions(+), 4 deletions(-) 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/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); } `; From 725195c3fbd84fd56006eadb9510b17dddd72c5c Mon Sep 17 00:00:00 2001 From: Alan Baker Date: Sun, 2 Nov 2025 22:16:16 -0500 Subject: [PATCH 2/6] add usage in execution test --- .../expression/call/builtin/textureDimensions.spec.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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})` }; } `; From 8d92a754254b2b631835445951cb4e4b6a5b5f15 Mon Sep 17 00:00:00 2001 From: alan-baker Date: Wed, 7 Jan 2026 21:19:58 -0500 Subject: [PATCH 3/6] Update src/webgpu/shader/validation/decl/let.spec.ts Co-authored-by: dan sinclair --- src/webgpu/shader/validation/decl/let.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webgpu/shader/validation/decl/let.spec.ts b/src/webgpu/shader/validation/decl/let.spec.ts index 1082f7ea26d8..f7c002d80cb6 100644 --- a/src/webgpu/shader/validation/decl/let.spec.ts +++ b/src/webgpu/shader/validation/decl/let.spec.ts @@ -97,7 +97,7 @@ const kTypeCases: Record = { 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;`, + decls: `@group(0) @binding(0) var tex1d : texture_storage_1d;`, }, sampler: { code: `let s = samp;`, From 7965d01cb1cc1fd8e067e85853d36ce110bf6640 Mon Sep 17 00:00:00 2001 From: alan-baker Date: Wed, 7 Jan 2026 21:20:05 -0500 Subject: [PATCH 4/6] Update src/webgpu/shader/validation/decl/let.spec.ts Co-authored-by: dan sinclair --- src/webgpu/shader/validation/decl/let.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webgpu/shader/validation/decl/let.spec.ts b/src/webgpu/shader/validation/decl/let.spec.ts index f7c002d80cb6..3c1ec06d4bd5 100644 --- a/src/webgpu/shader/validation/decl/let.spec.ts +++ b/src/webgpu/shader/validation/decl/let.spec.ts @@ -95,7 +95,7 @@ const kTypeCases: Record = { decls: `@group(0) @binding(0) var tex2d : texture_2d;`, }, texture_storage_1d: { - code: `let x : texture_storage_1d = tex1d;`, + code: `let x : texture_storage_1d = tex1d;`, valid: 'texture_and_sampler_let', decls: `@group(0) @binding(0) var tex1d : texture_storage_1d;`, }, From 1c1d66a704de4693ba3604039e1881920ae00543 Mon Sep 17 00:00:00 2001 From: alan-baker Date: Wed, 7 Jan 2026 21:20:21 -0500 Subject: [PATCH 5/6] Update src/webgpu/shader/validation/expression/call/builtin/textureDimensions.spec.ts Co-authored-by: dan sinclair --- .../expression/call/builtin/textureDimensions.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c549e176d029..5e7c5d7b9e96 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/textureDimensions.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/textureDimensions.spec.ts @@ -137,7 +137,7 @@ Validates the return type of ${builtin} is the expected type. 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 param = t.params.let ? 't_let' : `t${levelWGSL}`; const code = ` @group(0) @binding(0) var t: ${textureWGSL}; From 2ba7faedce0184bbc0dbbc4103125d81d289877a Mon Sep 17 00:00:00 2001 From: alan-baker Date: Wed, 7 Jan 2026 21:20:39 -0500 Subject: [PATCH 6/6] Update src/webgpu/shader/validation/expression/call/builtin/textureDimensions.spec.ts Co-authored-by: dan sinclair --- .../expression/call/builtin/textureDimensions.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5e7c5d7b9e96..68699aa74448 100644 --- a/src/webgpu/shader/validation/expression/call/builtin/textureDimensions.spec.ts +++ b/src/webgpu/shader/validation/expression/call/builtin/textureDimensions.spec.ts @@ -136,7 +136,7 @@ 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 t_let = t.params.let ? `let t_let = t;` : ``; const param = t.params.let ? 't_let' : `t${levelWGSL}`; const code = `