@@ -216,6 +216,36 @@ const kSwizzleAssignmentCases: Record<string, SwizzleAssignmentCase> = {
216216 rhs : 'vec2<bool>(false, false)' ,
217217 expected : [ 0 , 1 , 0 ] ,
218218 } ,
219+ // v = vec4u(1, 2, 3, 4)
220+ // v.xy.x = 5;
221+ vec4u_xy_x_literal : {
222+ elemType : 'u32' ,
223+ vecSize : 4 ,
224+ initial : [ 1 , 2 , 3 , 4 ] ,
225+ swizzle : 'xy.x' ,
226+ rhs : '5' ,
227+ expected : [ 5 , 2 , 3 , 4 ] ,
228+ } ,
229+ // v = vec3f(1.0, 2.0, 3.0)
230+ // v.zyx.yz = vec2f(5.0, 6.0);
231+ vec3f_zyx_yz_vec2f : {
232+ elemType : 'f32' ,
233+ vecSize : 3 ,
234+ initial : [ 1.0 , 2.0 , 3.0 ] ,
235+ swizzle : 'zyx.yz' ,
236+ rhs : 'vec2f(5.0, 6.0)' ,
237+ expected : [ 6.0 , 5.0 , 3.0 ] ,
238+ } ,
239+ // v = vec3i(-1, 0, -1)
240+ // v.xz.yx = vec2i(2);
241+ vec2i_xz_yx_vec2i : {
242+ elemType : 'i32' ,
243+ vecSize : 3 ,
244+ initial : [ - 1 , 0 , - 1 ] ,
245+ swizzle : 'xz.yx' ,
246+ rhs : 'vec2i(2,3)' ,
247+ expected : [ 3 , 0 , 2 ] ,
248+ } ,
219249} ;
220250
221251g . test ( 'swizzle_assignment_vars' )
@@ -285,10 +315,108 @@ fn main() {
285315 runSwizzleAssignmentTest ( t , elemType , expected , wgsl ) ;
286316 } ) ;
287317
288- g . test ( 'swizzle_assignment_chained' )
289- . desc ( 'Tests the value of a vector after swizzle assignment on a chained swizzle.' )
290- . unimplemented ( ) ;
318+ interface SwizzleCompoundAssignmentCase extends SwizzleAssignmentCase {
319+ op : string ;
320+ }
321+
322+ const kSwizzleCompoundAssignmentCases : Record < string , SwizzleCompoundAssignmentCase > = {
323+ // v = vec4u(1, 2, 3, 4)
324+ // v.w += 5;
325+ vec4u_w_add_5 : {
326+ elemType : 'u32' ,
327+ vecSize : 4 ,
328+ initial : [ 1 , 2 , 3 , 4 ] ,
329+ swizzle : 'w' ,
330+ op : '+=' ,
331+ rhs : '5' ,
332+ expected : [ 1 , 2 , 3 , 9 ] ,
333+ } ,
334+ // v = vec4u(1, 2, 3, 4)
335+ // v.xy *= vec2u(6, 7);
336+ vec4u_xy_mul_vec2u : {
337+ elemType : 'u32' ,
338+ vecSize : 4 ,
339+ initial : [ 1 , 2 , 3 , 4 ] ,
340+ swizzle : 'xy' ,
341+ op : '*=' ,
342+ rhs : 'vec2u(6, 7)' ,
343+ expected : [ 6 , 14 , 3 , 4 ] ,
344+ } ,
345+ // v = vec3i(10, 20, 30)
346+ // v.zx += vec2i(100);
347+ vec3i_zx_add_vec2i : {
348+ elemType : 'i32' ,
349+ vecSize : 3 ,
350+ initial : [ 10 , 20 , 30 ] ,
351+ swizzle : 'zx' ,
352+ op : '+=' ,
353+ rhs : 'vec2i(100)' ,
354+ expected : [ 110 , 20 , 130 ] ,
355+ } ,
356+ // v = vec3f(1.0, 2.0, 3.0)
357+ // v.xy *= vec2f(0.5, 2.0);
358+ vec3f_xy_mul_vec2f : {
359+ elemType : 'f32' ,
360+ vecSize : 3 ,
361+ initial : [ 1.0 , 2.0 , 3.0 ] ,
362+ swizzle : 'xy' ,
363+ op : '*=' ,
364+ rhs : 'vec2f(0.5, 2.0)' ,
365+ expected : [ 0.5 , 4.0 , 3.0 ] ,
366+ } ,
367+ } ;
291368
292369g . test ( 'swizzle_compound_assignment' )
293370 . desc ( 'Tests the value of a vector after compound swizzle assignment.' )
294- . unimplemented ( ) ;
371+ . params ( u =>
372+ u
373+ . combine ( 'case' , keysOf ( kSwizzleCompoundAssignmentCases ) )
374+ . beginSubcases ( )
375+ . combine ( 'address_space' , [ 'function' , 'private' , 'workgroup' , 'storage' ] )
376+ . combine ( 'memory_view' , [ 'ref' , 'ptr' ] )
377+ )
378+ . fn ( t => {
379+ const { elemType, vecSize, initial, swizzle, op, rhs, expected } =
380+ kSwizzleCompoundAssignmentCases [ t . params . case ] ;
381+
382+ const vecType = `vec${ vecSize } <${ elemType } >` ;
383+ const initialValues = initial . join ( ', ' ) ;
384+
385+ const var_ref = t . params . address_space === 'storage' ? 'outputs.v' : 'v' ;
386+ const lhs =
387+ t . params . memory_view === 'ptr'
388+ ? `let ptr = &${ var_ref } ; ptr.${ swizzle } `
389+ : `${ var_ref } .${ swizzle } ` ;
390+ const new_rhs = rhs . replaceAll ( / \b v \b / g, `${ var_ref } ` ) ;
391+
392+ const wgsl = `
393+ requires swizzle_assignment;
394+ ${ elemType === 'f16' ? 'enable f16;' : '' }
395+
396+ struct Outputs {
397+ ${ t . params . address_space === 'storage' ? `v : ${ vecType } ,` : '' }
398+ data : array<${ elemType } >,
399+ };
400+
401+ @group(0) @binding(1) var<storage, read_write> outputs : Outputs;
402+
403+ ${
404+ t . params . address_space === 'private' || t . params . address_space === 'workgroup'
405+ ? `var<${ t . params . address_space } > v : ${ vecType } ;`
406+ : ''
407+ }
408+
409+ @compute @workgroup_size(1)
410+ fn main() {
411+
412+ ${ t . params . address_space === 'function' ? `var v : ${ vecType } ;` : '' }
413+ ${ var_ref } = ${ vecType } (${ initialValues } );
414+ ${ lhs } ${ op } ${ new_rhs } ;
415+
416+ // Store result to Output
417+ for (var i = 0; i < ${ vecSize } ; i++) {
418+ outputs.data[i] = ${ var_ref } [i];
419+ }
420+ }` ;
421+ runSwizzleAssignmentTest ( t , elemType , expected , wgsl ) ;
422+ } ) ;
0 commit comments