Skip to content

Commit

Permalink
Add validation tests on the limit of max vertex output location with …
Browse files Browse the repository at this point in the history
…clip_distances (#3958)

This patch adds the validation tests on the limit of max vertex output location with
clip_distances. According to the WebGPU SPEC, the maximum vertex output location will
be decreased by (align(clipDistancesArraySize, 4) / 4) when clip_distances is used.
  • Loading branch information
Jiawei-Shao authored Sep 19, 2024
1 parent 1967655 commit 9387aa0
Showing 1 changed file with 49 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ function getPipelineDescriptorWithClipDistances(
device: GPUDevice,
interStageShaderVariables: number,
pointList: boolean,
clipDistances: number
clipDistances: number,
startLocation: number = 0
): GPURenderPipelineDescriptor {
const vertexOutputVariables =
interStageShaderVariables - (pointList ? 1 : 0) - align(clipDistances, 4) / 4;
const maxVertexOutputVariables =
device.limits.maxInterStageShaderVariables - (pointList ? 1 : 0) - align(clipDistances, 4) / 4;

const varyings = `
${range(vertexOutputVariables, i => `@location(${i}) v4_${i}: vec4f,`).join('\n')}
${range(
vertexOutputVariables,
i => `@location(${i + startLocation}) v4_${i + startLocation}: vec4f,`
).join('\n')}
`;

const code = `
Expand All @@ -29,6 +33,7 @@ function getPipelineDescriptorWithClipDistances(
}
// maxInterStageVariables: : ${maxVertexOutputVariables}
// num used inter stage variables : ${vertexOutputVariables}
// vertex output start location : ${startLocation}
enable clip_distances;
Expand Down Expand Up @@ -112,3 +117,45 @@ g.test('createRenderPipeline,at_over')
['clip-distances']
);
});

g.test('createRenderPipeline,max_vertex_output_location')
.desc(`Test using clip_distances will limit the maximum value of vertex output location`)
.params(u =>
u
.combine('pointList', [false, true])
.combine('clipDistances', [1, 2, 3, 4, 5, 6, 7, 8])
.combine('startLocation', [0, 1, 2])
)
.beforeAllSubcases(t => {
t.selectDeviceOrSkipTestCase('clip-distances');
})
.fn(async t => {
const { pointList, clipDistances, startLocation } = t.params;

const maxInterStageShaderVariables = t.adapter.limits.maxInterStageShaderVariables;
const deviceInTest = await t.requestDeviceTracked(t.adapter, {
requiredFeatures: ['clip-distances'],
requiredLimits: {
maxInterStageShaderVariables: t.adapter.limits.maxInterStageShaderVariables,
},
});
const pipelineDescriptor = getPipelineDescriptorWithClipDistances(
deviceInTest,
maxInterStageShaderVariables,
pointList,
clipDistances,
startLocation
);
const vertexOutputVariables =
maxInterStageShaderVariables - (pointList ? 1 : 0) - align(clipDistances, 4) / 4;
const maxLocationInTest = startLocation + vertexOutputVariables - 1;
const maxAllowedLocation = maxInterStageShaderVariables - 1 - align(clipDistances, 4) / 4;
const shouldError = maxLocationInTest > maxAllowedLocation;

deviceInTest.pushErrorScope('validation');
deviceInTest.createRenderPipeline(pipelineDescriptor);
const error = await deviceInTest.popErrorScope();
t.expect(!!error === shouldError, `${error?.message || 'no error when one was expected'}`);

deviceInTest.destroy();
});

0 comments on commit 9387aa0

Please sign in to comment.