From b697f76ff655da234de74458f735c6c60ca4a611 Mon Sep 17 00:00:00 2001 From: Natalie Chouinard Date: Tue, 28 Jul 2026 11:59:10 -0400 Subject: [PATCH] Add chained swizzle assignment tests Add validation and execution tests for chained swizzles on the LHS of an assignment. These are valid with the swizzle_assignment language feature as long as the final indices actually assigned are free from duplicate targets. Bug: crbug.com/539634915 --- .../statement/swizzle_assignment.spec.ts | 20 ++++++++++++ .../statement/swizzle_assignment.spec.ts | 31 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/webgpu/shader/execution/statement/swizzle_assignment.spec.ts b/src/webgpu/shader/execution/statement/swizzle_assignment.spec.ts index fef0a734b8bd..26e4e3159cc2 100644 --- a/src/webgpu/shader/execution/statement/swizzle_assignment.spec.ts +++ b/src/webgpu/shader/execution/statement/swizzle_assignment.spec.ts @@ -297,6 +297,26 @@ const kSwizzleAssignmentCases: Record = { rhs: 'true', expected: [1, 0], }, + // v = vec3u(1, 2, 3) + // v.xyy.xy = vec2u(4, 5); + vec3u_chained_dup_lhs_pass: { + elemType: 'u32', + vecSize: 3, + initial: [1, 2, 3], + swizzle: 'xyy.xy', + rhs: 'vec2u(4, 5)', + expected: [4, 5, 3], + }, + // v = vec2f(1.0, 2.0) + // v.xx.x = 5.0; + vec2f_chained_dup_lhs_pass: { + elemType: 'f32', + vecSize: 2, + initial: [1.0, 2.0], + swizzle: 'xx.x', + rhs: '5.0f', + expected: [5.0, 2.0], + }, }; g.test('swizzle_assignment_vars') diff --git a/src/webgpu/shader/validation/statement/swizzle_assignment.spec.ts b/src/webgpu/shader/validation/statement/swizzle_assignment.spec.ts index fcc4e2478090..163e243639b3 100644 --- a/src/webgpu/shader/validation/statement/swizzle_assignment.spec.ts +++ b/src/webgpu/shader/validation/statement/swizzle_assignment.spec.ts @@ -3,6 +3,7 @@ Validation tests for swizzle assignments. `; 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); @@ -213,3 +214,33 @@ fn main() { t.expectCompileResult(expected, code); }); + +const kChainedSwizzleCases = { + // Valid cases: + xy_y: { chain: 'xy.y', size: 1, pass: true }, // y + xx_x: { chain: 'xx.x', size: 1, pass: true }, // x + xyy_xy: { chain: 'xyy.xy', size: 2, pass: true }, // xy + xxyy_zxy_xy: { chain: 'xxyy.zxy.xy', size: 2, pass: true }, // yx + // Invalid cases: + xxyy_xy: { chain: 'xxyy.xy', size: 2, pass: false }, // xx + xyy_yy: { chain: 'xyy.yy', size: 2, pass: false }, // yy + xxyy_zxy_yz: { chain: 'xxyy.zxy.yz', size: 2, pass: false }, // xx + zy_xyx: { chain: 'zy.xyx', size: 3, pass: false }, // zyz +}; + +g.test('chained_swizzle') + .desc('Validate chained swizzles on the LHS of an assignment') + .params(u => u.combine('case', keysOf(kChainedSwizzleCases))) + .fn(t => { + const { chain, size, pass } = kChainedSwizzleCases[t.params.case]; + const rhs = size === 1 ? '1.0' : `vec${size}f(1.0)`; + const code = ` +@fragment +fn main() { + var v = vec4f(); + v.${chain} = ${rhs}; +} +`; + const expected = pass && t.hasLanguageFeature('swizzle_assignment'); + t.expectCompileResult(expected, code); + });