From ea310edea95b79fa706cf332be006769dad859f2 Mon Sep 17 00:00:00 2001 From: Jiawei Shao Date: Wed, 18 Sep 2024 14:14:38 +0800 Subject: [PATCH 1/3] Add validation tests on clip_distances and maxInterStageShaderVariables --- .../features/clip_distances.spec.ts | 115 ++++++++++++++++++ .../capability_checks/limits/limit_utils.ts | 9 +- src/webgpu/listing_meta.json | 3 +- 3 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 src/webgpu/api/validation/capability_checks/features/clip_distances.spec.ts diff --git a/src/webgpu/api/validation/capability_checks/features/clip_distances.spec.ts b/src/webgpu/api/validation/capability_checks/features/clip_distances.spec.ts new file mode 100644 index 000000000000..684030fe6f67 --- /dev/null +++ b/src/webgpu/api/validation/capability_checks/features/clip_distances.spec.ts @@ -0,0 +1,115 @@ +import { range } from '../../../../../common/util/util.js'; +import { align } from '../../../../util/math.js'; +import { kMaximumLimitBaseParams, makeLimitTestGroup } from '../limits/limit_utils.js'; + +function getPipelineDescriptorWithClipDistances( + device: GPUDevice, + testValue: number, + pointList: boolean, + clipDistances: number +): GPURenderPipelineDescriptor { + const vertexOutputVariables = testValue - (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')} + `; + + const code = ` + // test value : ${testValue} + // maxInterStageShaderVariables : ${device.limits.maxInterStageShaderVariables} + // num variables in vertex shader : ${vertexOutputVariables}${ + pointList ? ' + point-list' : '' + }${ + clipDistances > 0 + ? ` + ${align(clipDistances, 4) / 4} (clip_distances[${clipDistances}])` + : '' + } + // maxInterStageVariables: : ${maxVertexOutputVariables} + // num used inter stage variables : ${vertexOutputVariables} + + enable clip_distances; + + struct VSOut { + @builtin(position) p: vec4f, + ${varyings} + ${ + clipDistances > 0 + ? `@builtin(clip_distances) clipDistances: array,` + : '' + } + } + struct FSIn { + ${varyings} + } + struct FSOut { + @location(0) color: vec4f, + } + @vertex fn vs() -> VSOut { + var o: VSOut; + o.p = vec4f(0); + return o; + } + @fragment fn fs(i: FSIn) -> FSOut { + var o: FSOut; + o.color = vec4f(0); + return o; + } + `; + const module = device.createShaderModule({ code }); + const pipelineDescriptor: GPURenderPipelineDescriptor = { + layout: 'auto', + primitive: { + topology: pointList ? 'point-list' : 'triangle-list', + }, + vertex: { + module, + entryPoint: 'vs', + }, + fragment: { + module, + entryPoint: 'fs', + targets: [ + { + format: 'rgba8unorm', + }, + ], + }, + }; + return pipelineDescriptor; +} + +const limit = 'maxInterStageShaderVariables'; +export const { g, description } = makeLimitTestGroup(limit); + +g.test('createRenderPipeline,at_over') + .desc(`Test using at and over ${limit} limit with clip_distances in createRenderPipeline(Async)`) + .params( + kMaximumLimitBaseParams + .combine('async', [false, true]) + .combine('pointList', [false, true]) + .combine('clipDistances', [1, 2, 3, 4, 5, 6, 7, 8]) + ) + .beforeAllSubcases(t => { + t.selectDeviceOrSkipTestCase('clip-distances'); + }) + .fn(async t => { + const { limitTest, testValueName, async, pointList, clipDistances } = t.params; + await t.testDeviceWithRequestedMaximumLimits( + limitTest, + testValueName, + async ({ device, testValue, shouldError }) => { + const pipelineDescriptor = getPipelineDescriptorWithClipDistances( + device, + testValue, + pointList, + clipDistances + ); + + await t.testCreateRenderPipeline(pipelineDescriptor, async, shouldError); + }, + undefined, + ['clip-distances'] + ); + }); diff --git a/src/webgpu/api/validation/capability_checks/limits/limit_utils.ts b/src/webgpu/api/validation/capability_checks/limits/limit_utils.ts index ea44b11c9148..14f1642cea9f 100644 --- a/src/webgpu/api/validation/capability_checks/limits/limit_utils.ts +++ b/src/webgpu/api/validation/capability_checks/limits/limit_utils.ts @@ -535,11 +535,16 @@ export class LimitTestsImpl extends GPUTestBase { limitTest: MaximumLimitValueTest, testValueName: MaximumTestValue, fn: (inputs: MaximumLimitTestInputs) => void | Promise, - extraLimits?: LimitsRequest + extraLimits?: LimitsRequest, + extraFeatures: GPUFeatureName[] = [] ) { assert(!this._device); - const deviceAndLimits = await this._getDeviceWithRequestedMaximumLimit(limitTest, extraLimits); + const deviceAndLimits = await this._getDeviceWithRequestedMaximumLimit( + limitTest, + extraLimits, + extraFeatures + ); // If we request over the limit requestDevice will throw if (!deviceAndLimits) { return; diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index 1ad427ac7668..26b30f33a02b 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -283,11 +283,12 @@ "webgpu:api,validation,capability_checks,features,texture_formats:texture_descriptor:*": { "subcaseMS": 3.830 }, "webgpu:api,validation,capability_checks,features,texture_formats:texture_descriptor_view_formats:*": { "subcaseMS": 5.734 }, "webgpu:api,validation,capability_checks,features,texture_formats:texture_view_descriptor:*": { "subcaseMS": 4.113 }, + "webgpu:api,validation,capability_checks,features,clip_distances:createRenderPipeline,at_over:*": { "subcaseMS": 13.7 }, "webgpu:api,validation,capability_checks,limits,maxBindGroups:createPipeline,at_over:*": { "subcaseMS": 10.990 }, "webgpu:api,validation,capability_checks,limits,maxBindGroups:createPipelineLayout,at_over:*": { "subcaseMS": 9.310 }, "webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,at_over:*": { "subcaseMS": 9.984 }, "webgpu:api,validation,capability_checks,limits,maxBindGroups:validate,maxBindGroupsPlusVertexBuffers:*": { "subcaseMS": 11.200 }, - "webgpu:api,validation,capability_checks,limits,maxBindGroupsPlusVertexBuffers:createRenderPipeline,at_over:*": { "subcaseMS": 11.200 }, + "webgpu:api,validation,capability_checks,limits,maxBindGroupsPlusVertexBuffers:createRenderPipeline,at_over:*": { "subcaseMS": 80.200 }, "webgpu:api,validation,capability_checks,limits,maxBindGroupsPlusVertexBuffers:draw,at_over:*": { "subcaseMS": 11.200 }, "webgpu:api,validation,capability_checks,limits,maxBindingsPerBindGroup:createBindGroupLayout,at_over:*": { "subcaseMS": 12.441 }, "webgpu:api,validation,capability_checks,limits,maxBindingsPerBindGroup:createPipeline,at_over:*": { "subcaseMS": 11.179 }, From a85d05d8989c8a063800cdfc7924d03cf0514c2b Mon Sep 17 00:00:00 2001 From: Jiawei Shao Date: Wed, 18 Sep 2024 14:29:50 +0800 Subject: [PATCH 2/3] Small fix --- src/webgpu/listing_meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index 26b30f33a02b..cf2ba6104cff 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -288,7 +288,7 @@ "webgpu:api,validation,capability_checks,limits,maxBindGroups:createPipelineLayout,at_over:*": { "subcaseMS": 9.310 }, "webgpu:api,validation,capability_checks,limits,maxBindGroups:setBindGroup,at_over:*": { "subcaseMS": 9.984 }, "webgpu:api,validation,capability_checks,limits,maxBindGroups:validate,maxBindGroupsPlusVertexBuffers:*": { "subcaseMS": 11.200 }, - "webgpu:api,validation,capability_checks,limits,maxBindGroupsPlusVertexBuffers:createRenderPipeline,at_over:*": { "subcaseMS": 80.200 }, + "webgpu:api,validation,capability_checks,limits,maxBindGroupsPlusVertexBuffers:createRenderPipeline,at_over:*": { "subcaseMS": 11.200 }, "webgpu:api,validation,capability_checks,limits,maxBindGroupsPlusVertexBuffers:draw,at_over:*": { "subcaseMS": 11.200 }, "webgpu:api,validation,capability_checks,limits,maxBindingsPerBindGroup:createBindGroupLayout,at_over:*": { "subcaseMS": 12.441 }, "webgpu:api,validation,capability_checks,limits,maxBindingsPerBindGroup:createPipeline,at_over:*": { "subcaseMS": 11.179 }, From 7993247fa927e0050a4d90ec2757cf5336de5216 Mon Sep 17 00:00:00 2001 From: Jiawei Shao Date: Wed, 18 Sep 2024 16:51:03 +0800 Subject: [PATCH 3/3] Address reviewer's comments --- .../capability_checks/features/clip_distances.spec.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/webgpu/api/validation/capability_checks/features/clip_distances.spec.ts b/src/webgpu/api/validation/capability_checks/features/clip_distances.spec.ts index 684030fe6f67..6b8809d5616d 100644 --- a/src/webgpu/api/validation/capability_checks/features/clip_distances.spec.ts +++ b/src/webgpu/api/validation/capability_checks/features/clip_distances.spec.ts @@ -4,11 +4,12 @@ import { kMaximumLimitBaseParams, makeLimitTestGroup } from '../limits/limit_uti function getPipelineDescriptorWithClipDistances( device: GPUDevice, - testValue: number, + interStageShaderVariables: number, pointList: boolean, clipDistances: number ): GPURenderPipelineDescriptor { - const vertexOutputVariables = testValue - (pointList ? 1 : 0) - align(clipDistances, 4) / 4; + const vertexOutputVariables = + interStageShaderVariables - (pointList ? 1 : 0) - align(clipDistances, 4) / 4; const maxVertexOutputVariables = device.limits.maxInterStageShaderVariables - (pointList ? 1 : 0) - align(clipDistances, 4) / 4; @@ -17,7 +18,7 @@ function getPipelineDescriptorWithClipDistances( `; const code = ` - // test value : ${testValue} + // test value : ${interStageShaderVariables} // maxInterStageShaderVariables : ${device.limits.maxInterStageShaderVariables} // num variables in vertex shader : ${vertexOutputVariables}${ pointList ? ' + point-list' : '' @@ -65,11 +66,9 @@ function getPipelineDescriptorWithClipDistances( }, vertex: { module, - entryPoint: 'vs', }, fragment: { module, - entryPoint: 'fs', targets: [ { format: 'rgba8unorm',