From d3fec1ffa922e8da4a5cf6da9fd77190ea8c23cf Mon Sep 17 00:00:00 2001 From: Greggman Date: Tue, 7 Jan 2025 00:25:17 +0900 Subject: [PATCH] Compat: Refactor subgroup tests for 0 storage buffers in frag (#4129) --- .../call/builtin/quadBroadcast.spec.ts | 2 +- .../expression/call/builtin/quadSwap.spec.ts | 2 +- .../call/builtin/subgroupAdd.spec.ts | 2 +- .../call/builtin/subgroupAll.spec.ts | 4 +- .../call/builtin/subgroupAny.spec.ts | 4 +- .../call/builtin/subgroupBitwise.spec.ts | 4 +- .../call/builtin/subgroupBroadcast.spec.ts | 10 ++--- .../call/builtin/subgroupElect.spec.ts | 2 +- .../call/builtin/subgroupMinMax.spec.ts | 4 +- .../call/builtin/subgroupMul.spec.ts | 40 +++++++++---------- .../call/builtin/subgroupShuffle.spec.ts | 2 +- .../expression/call/builtin/subgroup_util.ts | 14 ++++++- 12 files changed, 50 insertions(+), 40 deletions(-) diff --git a/src/webgpu/shader/execution/expression/call/builtin/quadBroadcast.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/quadBroadcast.spec.ts index f8d9ec9a362b..8ecd864ed6b1 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/quadBroadcast.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/quadBroadcast.spec.ts @@ -496,7 +496,7 @@ g.test('fragment,all_active') enable subgroups; @group(0) @binding(0) -var inputs : array; // unused +var inputs : array; // unused @fragment fn main( diff --git a/src/webgpu/shader/execution/expression/call/builtin/quadSwap.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/quadSwap.spec.ts index 7e754152c9b5..1e28e23a692a 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/quadSwap.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/quadSwap.spec.ts @@ -506,7 +506,7 @@ g.test('fragment,all_active') enable subgroups; @group(0) @binding(0) -var inputs : array; // unused +var inputs : array; // unused @fragment fn main( diff --git a/src/webgpu/shader/execution/expression/call/builtin/subgroupAdd.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/subgroupAdd.spec.ts index a4f5b04f0529..6763c9de8a98 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/subgroupAdd.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/subgroupAdd.spec.ts @@ -504,7 +504,7 @@ g.test('fragment') enable subgroups; @group(0) @binding(0) -var inputs : array; +var inputs : array; @fragment fn main( diff --git a/src/webgpu/shader/execution/expression/call/builtin/subgroupAll.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/subgroupAll.spec.ts index 5b8515c05762..86feaa3b5165 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/subgroupAll.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/subgroupAll.spec.ts @@ -342,7 +342,7 @@ g.test('fragment,all_active') enable subgroups; @group(0) @binding(0) -var inputs : array; +var inputs : array; @fragment fn main( @@ -357,7 +357,7 @@ fn main( let x_in_range = u32(pos.x) < (${t.params.size[0]} - 1); let y_in_range = u32(pos.y) < (${t.params.size[1]} - 1); let in_range = x_in_range && y_in_range; - let input = select(1u, inputs[linear], in_range); + let input = select(1u, inputs[linear].x, in_range); let res = select(0u, 1u, subgroupAll(bool(input))); return vec2u(res, subgroup_id); diff --git a/src/webgpu/shader/execution/expression/call/builtin/subgroupAny.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/subgroupAny.spec.ts index cad48235eceb..7fbdee0cfd68 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/subgroupAny.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/subgroupAny.spec.ts @@ -342,7 +342,7 @@ g.test('fragment,all_active') enable subgroups; @group(0) @binding(0) -var inputs : array; +var inputs : array; @fragment fn main( @@ -357,7 +357,7 @@ fn main( let x_in_range = u32(pos.x) < (${t.params.size[0]} - 1); let y_in_range = u32(pos.y) < (${t.params.size[1]} - 1); let in_range = x_in_range && y_in_range; - let input = select(0u, inputs[linear], in_range); + let input = select(0u, inputs[linear].x, in_range); let res = select(0u, 1u, subgroupAny(bool(input))); return vec2u(res, subgroup_id); diff --git a/src/webgpu/shader/execution/expression/call/builtin/subgroupBitwise.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/subgroupBitwise.spec.ts index b134e5db633d..14503fdf46b6 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/subgroupBitwise.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/subgroupBitwise.spec.ts @@ -561,7 +561,7 @@ g.test('fragment,all_active') enable subgroups; @group(0) @binding(0) -var inputs : array; +var inputs : array; @fragment fn main( @@ -575,7 +575,7 @@ fn main( let x_in_range = u32(pos.x) < (${t.params.size[0]} - 1); let y_in_range = u32(pos.y) < (${t.params.size[1]} - 1); let in_range = x_in_range && y_in_range; - let input = select(${ident}, inputs[linear], in_range); + let input = select(${ident}, inputs[linear].x, in_range); let res = ${t.params.op}(input); return vec2u(res, subgroup_id); diff --git a/src/webgpu/shader/execution/expression/call/builtin/subgroupBroadcast.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/subgroupBroadcast.spec.ts index 211cf1285340..cabc465af54f 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/subgroupBroadcast.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/subgroupBroadcast.spec.ts @@ -676,14 +676,16 @@ g.test('fragment') const broadcast = t.params.id === 0 - ? `subgroupBroadcastFirst(input[linear])` - : `subgroupBroadcast(input[linear], ${t.params.id})`; + ? `subgroupBroadcastFirst(input[linear].x)` + : `subgroupBroadcast(input[linear].x, ${t.params.id})`; + const texels = t.params.size[0] * t.params.size[1]; + const inputData = new Uint32Array([...iterRange(texels, x => x)]); const fsShader = ` enable subgroups; @group(0) @binding(0) -var input : array; +var input : array; @fragment fn main( @@ -696,8 +698,6 @@ fn main( return vec4u(${broadcast}, id, size, linear); }`; - const texels = t.params.size[0] * t.params.size[1]; - const inputData = new Uint32Array([...iterRange(texels, x => x)]); await runFragmentTest( t, t.params.format, diff --git a/src/webgpu/shader/execution/expression/call/builtin/subgroupElect.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/subgroupElect.spec.ts index 074d8545dea7..23b86fe2a378 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/subgroupElect.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/subgroupElect.spec.ts @@ -351,7 +351,7 @@ g.test('fragment') enable subgroups; @group(0) @binding(0) -var inputs : array; // unused +var inputs : array; // unused @fragment fn main( diff --git a/src/webgpu/shader/execution/expression/call/builtin/subgroupMinMax.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/subgroupMinMax.spec.ts index f070632488c0..d9bb796c4934 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/subgroupMinMax.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/subgroupMinMax.spec.ts @@ -598,7 +598,7 @@ g.test('fragment') enable subgroups; @group(0) @binding(0) -var inputs : array; +var inputs : array; @fragment fn main( @@ -612,7 +612,7 @@ fn main( let x_in_range = u32(pos.x) < (${t.params.size[0]} - 1); let y_in_range = u32(pos.y) < (${t.params.size[1]} - 1); let in_range = x_in_range && y_in_range; - let input = select(${identity}, inputs[linear], in_range); + let input = select(${identity}, inputs[linear].x, in_range); let res = ${t.params.op}(input); return vec2u(res, subgroup_id); diff --git a/src/webgpu/shader/execution/expression/call/builtin/subgroupMul.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/subgroupMul.spec.ts index 2a6a8648a333..210a138b77fc 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/subgroupMul.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/subgroupMul.spec.ts @@ -528,11 +528,29 @@ g.test('fragment') t.skipIf(innerTexels < subgroupMinSize, 'Too few texels to be reliable'); t.skipIf(subgroupMaxSize === 4 && t.params.quadIndex !== 0, 'Duplicate test'); + // Max possible subgroup size is 128 which is too large so we reduce the + // multiplication by a factor of 4. We populate one element of each quad with a + // non-identity value. subgroupMaxSize of 4 is a special case where all + // elements are populated. + const numInputs = t.params.size[0] * t.params.size[1]; + const inputData = new Uint32Array([ + ...iterRange(numInputs, x => { + if (subgroupMaxSize === 4) { + return 2; + } else { + const row = Math.floor(x / t.params.size[0]); + const col = x % t.params.size[0]; + const idx = (col % 2) + 2 * (row % 2); + return idx === t.params.quadIndex ? 2 : kIdentity; + } + }), + ]); + const fsShader = ` enable subgroups; @group(0) @binding(0) -var inputs : array; +var inputs : array; @fragment fn main( @@ -547,28 +565,10 @@ fn main( let y_in_range = u32(pos.y) < (${t.params.size[1]} - 1); let in_range = x_in_range && y_in_range; - let value = select(${kIdentity}, inputs[linear], in_range); + let value = select(${kIdentity}, inputs[linear].x, in_range); return vec4u(${t.params.op}(value), id, subgroup_id, 0); };`; - // Max possible subgroup size is 128 which is too large so we reduce the - // multiplication by a factor of 4. We populate one element of each quad with a - // non-identity value. subgroupMaxSize of 4 is a special case where all - // elements are populated. - const numInputs = t.params.size[0] * t.params.size[1]; - const inputData = new Uint32Array([ - ...iterRange(numInputs, x => { - if (subgroupMaxSize === 4) { - return 2; - } else { - const row = Math.floor(x / t.params.size[0]); - const col = x % t.params.size[0]; - const idx = (col % 2) + 2 * (row % 2); - return idx === t.params.quadIndex ? 2 : kIdentity; - } - }), - ]); - await runFragmentTest( t, t.params.format, diff --git a/src/webgpu/shader/execution/expression/call/builtin/subgroupShuffle.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/subgroupShuffle.spec.ts index 73e1fe6bcaa7..60c95edbc334 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/subgroupShuffle.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/subgroupShuffle.spec.ts @@ -893,7 +893,7 @@ g.test('fragment') enable subgroups; @group(0) @binding(0) -var inputs : array; // unused +var inputs : array; // unused @fragment fn main( diff --git a/src/webgpu/shader/execution/expression/call/builtin/subgroup_util.ts b/src/webgpu/shader/execution/expression/call/builtin/subgroup_util.ts index 71852c6a315c..3566490d7ca3 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/subgroup_util.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/subgroup_util.ts @@ -521,9 +521,19 @@ fn vsMain(@builtin(vertex_index) index : u32) -> @builtin(position) vec4f { const byteLength = bytesPerRow * blocksPerColumn; const uintLength = byteLength / 4; + const expandedInputData = new ( + inputData instanceof Uint32Array + ? Uint32Array + : inputData instanceof Float32Array + ? Float32Array + : Float16Array + )(inputData.length * 4); + for (let i = 0; i < inputData.length; ++i) { + expandedInputData[i * 4] = inputData[i]; + } const buffer = t.makeBufferWithContents( - inputData, - GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST + expandedInputData, + GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST ); const bg = t.device.createBindGroup({