Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix fragment shader subgroup builtin io test #4024

Merged
merged 6 commits into from
Nov 4, 2024
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 41 additions & 13 deletions src/webgpu/shader/execution/shader_io/fragment_builtins.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1537,7 +1537,7 @@ function checkSubgroupSizeConsistency(
* @param height The framebuffer height
* @param checker A functor to check the framebuffer values
*/
async function runSubgroupTest(
async function runSubgroupTest(
t: FragmentBuiltinTest,
format: GPUTextureFormat,
fsShader: string,
Expand Down Expand Up @@ -1618,7 +1618,8 @@ fn vsMain(@builtin(vertex_index) index : u32) -> @builtin(position) vec4f {
});
pass.setPipeline(pipeline);
pass.setBindGroup(0, bg);
pass.draw(3, 1, i);
// Draw the uperr-left triangle (vertices 0-2) or the lower-right triangle (vertices 3-5)
pass.draw(3, 1, i * 3);
pass.end();
t.queue.submit([encoder.finish()]);

Expand Down Expand Up @@ -1704,12 +1705,13 @@ fn fsMain(
*
* Very little uniformity is expected for subgroup_invocation_id.
* This function checks that all ids are less than the subgroup size
* and no id is repeated.
* (not the ballot size, since the subgroup id can be allocated to
* inactivate invocations between active ones) and no id is repeated.
* @param data An array of vec4u that contains (per texel):
* * subgroup_invocation_id
* * subgroup size
* * ballot size
* * non-zero ID unique to each subgroup
* * 0
* @param format The texture format of data
* @param width The width of the framebuffer
* @param height The height of the framebuffer
Expand All @@ -1726,31 +1728,57 @@ function checkSubgroupInvocationIdConsistency(
const uintsPerRow = bytesPerRow / 4;
const uintsPerTexel = (bytesPerBlock ?? 1) / blockWidth / blockHeight / 4;

const mappings = new Map<number, bigint>();
const invocationIdBitmapOfSubgroups = new Map<number, bigint>();
const ballotSizeRecordOfSubgroups = new Map<
number,
{ ballotSize: number; row: number; col: number }
>();
for (let row = 0; row < height; row++) {
for (let col = 0; col < width; col++) {
const offset = uintsPerRow * row + col * uintsPerTexel;
const id = data[offset];
const size = data[offset + 1];
const repId = data[offset + 2];
const sgSize = data[offset + 1];
const ballotSize = data[offset + 2];
const repId = data[offset + 3];
jzm-intel marked this conversation as resolved.
Show resolved Hide resolved

if (repId === 0) {
continue;
}

if (size < id) {
if (sgSize < id) {
return new Error(
`Invocation id '${id}' is greater than subgroup size '${sgSize}' for (${row}, ${col})`
);
}

if (sgSize < ballotSize) {
return new Error(
`Invocation id '${id}' is greater than subgroup size '${size}' for (${row}, ${col})`
`Ballot size '${ballotSize}' is greater than subgroup size '${sgSize}' for (${row}, ${col})`
);
}

let v = mappings.get(repId) ?? 0n;
const ballotSizeRecord = ballotSizeRecordOfSubgroups.get(repId);
if (ballotSizeRecord === undefined) {
ballotSizeRecordOfSubgroups.set(repId, { ballotSize, row, col });
} else {
if (ballotSize !== ballotSizeRecord.ballotSize) {
return new Error(
`Inconsistent subgroup ballot size within same subgroup
- icoord: (${ballotSizeRecord.row}, ${ballotSizeRecord.col})
- got: ${ballotSizeRecord.ballotSize}
- icoord: (${row}, ${col})
- got: ${ballotSize}`
);
}
}

let invocationIdBitmap = invocationIdBitmapOfSubgroups.get(repId) ?? 0n;
const mask = 1n << BigInt(id);
if ((mask & v) !== 0n) {
if ((mask & invocationIdBitmap) !== 0n) {
return new Error(`Multiple invocations with id '${id}' in subgroup '${repId}'`);
}
v |= mask;
mappings.set(repId, v);
invocationIdBitmap |= mask;
invocationIdBitmapOfSubgroups.set(repId, invocationIdBitmap);
}
}

Expand Down
Loading