Skip to content

Commit

Permalink
refactor shader/types.ts: Add accessSuffixes to type info (gpuweb#3864)
Browse files Browse the repository at this point in the history
When testing accesses into uniform address space, the array
tests pack scalars into a 4-element vector.  This is a big hack,
to accommodate the 16byte alignment requirement for uniform address
space. Previously the robust access tests had a subtle tight coupling
to this decision.

This change adds a 'accessSuffixes' field to the array type info
to indicate how to access individual scalar elements under test.
So in the uniform case, when a vec4 is artificially created, return
a list of the .x .y .z .w components to get the original scalar
values back.  This allows client tests to smoothly generalize.

Update the robust access tests to this change. It's the only affected test.

Issue: gpuweb#3405
  • Loading branch information
dneto0 authored Jul 19, 2024
1 parent 5167b71 commit 50b6e7a
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/webgpu/listing_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@
"webgpu:api,validation,buffer,destroy:while_mapped:*": { "subcaseMS": 1.150 },
"webgpu:api,validation,buffer,mapping:gc_behavior,mapAsync:*": { "subcaseMS": 32.200 },
"webgpu:api,validation,buffer,mapping:gc_behavior,mappedAtCreation:*": { "subcaseMS": 76.200 },
"webgpu:api,validation,buffer,mapping:getMappedRange,disjointRanges_many:*": { "subcaseMS": 73.700 },
"webgpu:api,validation,buffer,mapping:getMappedRange,disjointRanges:*": { "subcaseMS": 2.257 },
"webgpu:api,validation,buffer,mapping:getMappedRange,disjointRanges_many:*": { "subcaseMS": 73.700 },
"webgpu:api,validation,buffer,mapping:getMappedRange,offsetAndSizeAlignment,mapped:*": { "subcaseMS": 3.119 },
"webgpu:api,validation,buffer,mapping:getMappedRange,offsetAndSizeAlignment,mappedAtCreation:*": { "subcaseMS": 5.611 },
"webgpu:api,validation,buffer,mapping:getMappedRange,sizeAndOffsetOOB,mapped:*": { "subcaseMS": 0.886 },
Expand Down
28 changes: 15 additions & 13 deletions src/webgpu/shader/execution/robust_access.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,21 +330,21 @@ struct TestData {
let index = (${indexToTest})${exprIndexAddon};`;
const exprZeroElement = `${_kTypeInfo.elementBaseType}()`;
const exprElement = `s.data[index]`;

const suffices = _kTypeInfo.accessSuffixes ?? [''];
switch (access) {
case 'read':
{
let exprLoadElement = isAtomic ? `atomicLoad(&${exprElement})` : exprElement;
if (addressSpace === 'uniform' && containerType === 'array') {
// Scalar types will be wrapped in a vec4 to satisfy array element size
// requirements for the uniform address space, so we need an additional index
// accessor expression.
exprLoadElement += '[0]';
const exprLoadElement = isAtomic ? `atomicLoad(&${exprElement})` : exprElement;
let conditions = suffices.map(x => `${exprLoadElement}${x} != ${exprZeroElement}`);
if (containerType === 'matrix') {
// The comparison is a vector bool result.
// Convert that to a scalar bool.
conditions = conditions.map(c => `any(${c})`);
}
let condition = `${exprLoadElement} != ${exprZeroElement}`;
if (containerType === 'matrix') condition = `any(${condition})`;
testFunctionSource += `
if (${condition}) { return ${nextErrorReturnValue()}; }`;
conditions.forEach(c => {
testFunctionSource += `
if (${c}) { return ${nextErrorReturnValue()}; }`;
});
}
break;

Expand All @@ -353,8 +353,10 @@ struct TestData {
testFunctionSource += `
atomicStore(&s.data[index], ${exprZeroElement});`;
} else {
testFunctionSource += `
s.data[index] = ${exprZeroElement};`;
suffices.forEach(x => {
testFunctionSource += `
s.data[index]${x} = ${exprZeroElement};`;
});
}
break;
}
Expand Down
10 changes: 9 additions & 1 deletion src/webgpu/shader/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ export function* generateTypes({
isAtomic = false,
}: {
addressSpace: AddressSpace;
/** Base scalar type (i32/u32/f32/bool). */
/** Base scalar type (i32/u32/f16/f32/bool). */
baseType: ScalarType;
/** Container type (scalar/vector/matrix/array) */
containerType: ContainerType;
Expand Down Expand Up @@ -238,6 +238,11 @@ export function* generateTypes({
* For a matrix type, this is the number of rows in the matrix.
*/
innerLength?: number;
/**
* If defined, the list of array access suffixes to use to access all
* the elements of the array, each yielding an elementBaseType value.
*/
accessSuffixes?: string[];
};
},
void
Expand Down Expand Up @@ -308,6 +313,7 @@ export function* generateTypes({
let arrayElementCount: number = kDefaultArrayLength;
let supportsAtomics = scalarInfo.supportsAtomics;
let layout: undefined | AlignmentAndSize = undefined;
let accessSuffixes: undefined | string[] = undefined;
if (scalarInfo.layout) {
// Compute the layout of the array type.
// Adjust the array element count or element type as needed.
Expand All @@ -318,6 +324,7 @@ export function* generateTypes({
assert(!isAtomic, 'the uniform case is making vec4 of scalar, which cannot handle atomics');
arrayElemType = `vec4<${baseType}>`;
supportsAtomics = false;
accessSuffixes = ['.x', '.y', '.z', '.w'];
const arrayElemLayout = vectorLayout('vec4', baseType) as AlignmentAndSize;
// assert(arrayElemLayout.alignment % 16 === 0); // Callers responsibility to avoid
arrayElementCount = align(arrayElementCount, 4) / 4;
Expand All @@ -344,6 +351,7 @@ export function* generateTypes({
arrayLength: arrayElementCount,
layout,
supportsAtomics,
accessSuffixes,
};

// Sized
Expand Down

0 comments on commit 50b6e7a

Please sign in to comment.