From 40774d3b7d2ca8c0e6d78ac498f0f1ccabe823c1 Mon Sep 17 00:00:00 2001 From: Gregg Tavares Date: Mon, 24 Feb 2025 16:08:40 -0800 Subject: [PATCH] Refactor api/operation/rendering/* Issue #4181 Issue #4178 --- .../rendering/3d_texture_slices.spec.ts | 10 +- .../api/operation/rendering/basic.spec.ts | 4 +- .../rendering/color_target_state.spec.ts | 26 ++--- .../api/operation/rendering/depth.spec.ts | 107 ++++++++---------- .../operation/rendering/depth_bias.spec.ts | 16 +-- .../rendering/depth_clip_clamp.spec.ts | 81 +++++++------ .../operation/rendering/indirect_draw.spec.ts | 4 +- .../rendering/robust_access_index.spec.ts | 4 +- .../api/operation/rendering/stencil.spec.ts | 57 ++++------ src/webgpu/gpu_test.ts | 2 + 10 files changed, 146 insertions(+), 165 deletions(-) diff --git a/src/webgpu/api/operation/rendering/3d_texture_slices.spec.ts b/src/webgpu/api/operation/rendering/3d_texture_slices.spec.ts index f423bcc4d23a..3ecfd08e3fe6 100644 --- a/src/webgpu/api/operation/rendering/3d_texture_slices.spec.ts +++ b/src/webgpu/api/operation/rendering/3d_texture_slices.spec.ts @@ -5,14 +5,14 @@ Test rendering to 3d texture slices. `; import { makeTestGroup } from '../../../../common/framework/test_group.js'; -import { kTextureFormatInfo } from '../../../format_info.js'; -import { GPUTest } from '../../../gpu_test.js'; +import { getColorRenderByteCost } from '../../../format_info.js'; +import { AllFeaturesMaxLimitsGPUTest } from '../../../gpu_test.js'; import { kBytesPerRowAlignment } from '../../../util/texture/layout.js'; const kSize = 4; const kFormat = 'rgba8unorm' as const; -class F extends GPUTest { +class F extends AllFeaturesMaxLimitsGPUTest { createShaderModule(attachmentCount: number = 1): GPUShaderModule { let locations = ''; let outputs = ''; @@ -170,7 +170,7 @@ g.test('multiple_color_attachments,same_mip_level') .fn(t => { const { sameTexture, samePass, mipLevel } = t.params; - const formatByteCost = kTextureFormatInfo[kFormat].colorRender.byteCost; + const formatByteCost = getColorRenderByteCost(kFormat); const maxAttachmentCountPerSample = Math.trunc( t.device.limits.maxColorAttachmentBytesPerSample / formatByteCost ); @@ -288,7 +288,7 @@ g.test('multiple_color_attachments,same_slice_with_diff_mip_levels') const kBaseSize = 1; - const formatByteCost = kTextureFormatInfo[kFormat].colorRender.byteCost; + const formatByteCost = getColorRenderByteCost(kFormat); const maxAttachmentCountPerSample = Math.trunc( t.device.limits.maxColorAttachmentBytesPerSample / formatByteCost ); diff --git a/src/webgpu/api/operation/rendering/basic.spec.ts b/src/webgpu/api/operation/rendering/basic.spec.ts index 4d0c31d55666..1fe0951fbb28 100644 --- a/src/webgpu/api/operation/rendering/basic.spec.ts +++ b/src/webgpu/api/operation/rendering/basic.spec.ts @@ -4,10 +4,10 @@ Basic command buffer rendering tests. import { makeTestGroup } from '../../../../common/framework/test_group.js'; import { now } from '../../../../common/util/util.js'; -import { GPUTest } from '../../../gpu_test.js'; +import { AllFeaturesMaxLimitsGPUTest } from '../../../gpu_test.js'; import { checkElementsEqual } from '../../../util/check_contents.js'; -export const g = makeTestGroup(GPUTest); +export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest); g.test('clear').fn(t => { const dst = t.createBufferTracked({ diff --git a/src/webgpu/api/operation/rendering/color_target_state.spec.ts b/src/webgpu/api/operation/rendering/color_target_state.spec.ts index 8f0384dfd240..b466a01d19bb 100644 --- a/src/webgpu/api/operation/rendering/color_target_state.spec.ts +++ b/src/webgpu/api/operation/rendering/color_target_state.spec.ts @@ -15,12 +15,15 @@ import { kBlendOperations, } from '../../../capability_info.js'; import { GPUConst } from '../../../constants.js'; -import { kRegularTextureFormats, kTextureFormatInfo } from '../../../format_info.js'; -import { GPUTest, TextureTestMixin } from '../../../gpu_test.js'; +import { + EncodableTextureFormat, + kPossibleColorRenderableTextureFormats, +} from '../../../format_info.js'; +import { AllFeaturesMaxLimitsGPUTest, TextureTestMixin } from '../../../gpu_test.js'; import { clamp } from '../../../util/math.js'; import { TexelView } from '../../../util/texture/texel_view.js'; -class BlendingTest extends GPUTest { +class BlendingTest extends AllFeaturesMaxLimitsGPUTest { createRenderPipelineForTest(colorTargetState: GPUColorTargetState): GPURenderPipeline { return this.device.createRenderPipeline({ layout: 'auto', @@ -378,11 +381,6 @@ struct FragOutput { ); }); -const kBlendableFormats = kRegularTextureFormats.filter(f => { - const info = kTextureFormatInfo[f]; - return info.colorRender && info.color.type === 'float'; -}); - g.test('blending,formats') .desc( `Test blending results works for all formats that support it, and that blending is not applied @@ -390,13 +388,12 @@ g.test('blending,formats') ) .params(u => u // - .combine('format', kBlendableFormats) + .combine('format', kPossibleColorRenderableTextureFormats) ) - .beforeAllSubcases(t => { - t.skipIfTextureFormatNotSupportedDeprecated(t.params.format); - }) .fn(t => { const { format } = t.params; + t.skipIfTextureFormatNotSupported(format); + t.skipIfTextureFormatNotBlendable(format); const pipeline = t.device.createRenderPipeline({ layout: 'auto', @@ -457,7 +454,10 @@ g.test('blending,formats') t.device.queue.submit([commandEncoder.finish()]); const expColor = { R: 0.6, G: 0.6, B: 0.6, A: 0.6 }; - const expTexelView = TexelView.fromTexelsAsColors(format, _coords => expColor); + const expTexelView = TexelView.fromTexelsAsColors( + format as EncodableTextureFormat, + _coords => expColor + ); t.expectTexelViewComparisonIsOkInTexture({ texture: renderTarget }, expTexelView, [1, 1, 1]); }); diff --git a/src/webgpu/api/operation/rendering/depth.spec.ts b/src/webgpu/api/operation/rendering/depth.spec.ts index a1a62e54ab89..1a4335ba8de6 100644 --- a/src/webgpu/api/operation/rendering/depth.spec.ts +++ b/src/webgpu/api/operation/rendering/depth.spec.ts @@ -4,8 +4,8 @@ Test related to depth buffer, depth op, compare func, etc. import { makeTestGroup } from '../../../../common/framework/test_group.js'; import { TypedArrayBufferView } from '../../../../common/util/util.js'; -import { kDepthStencilFormats, kTextureFormatInfo } from '../../../format_info.js'; -import { GPUTest, TextureTestMixin } from '../../../gpu_test.js'; +import { isStencilTextureFormat, kDepthTextureFormats } from '../../../format_info.js'; +import { AllFeaturesMaxLimitsGPUTest, TextureTestMixin } from '../../../gpu_test.js'; import { TexelView } from '../../../util/texture/texel_view.js'; const backgroundColor = [0x00, 0x00, 0x00, 0xff]; @@ -21,7 +21,7 @@ type TestStates = { depth: number; }; -class DepthTest extends TextureTestMixin(GPUTest) { +class DepthTest extends TextureTestMixin(AllFeaturesMaxLimitsGPUTest) { runDepthStateTest(testStates: TestStates[], expectedColor: Float32Array) { const renderTargetFormat = 'rgba8unorm'; @@ -187,7 +187,7 @@ g.test('depth_write_disabled') .fn(t => { const { depthWriteEnabled, lastDepth, _expectedColor } = t.params; - const depthSpencilFormat: GPUTextureFormat = 'depth24plus-stencil8'; + const depthStencilFormat: GPUTextureFormat = 'depth24plus-stencil8'; const stencilState = { compare: 'always', @@ -197,7 +197,7 @@ g.test('depth_write_disabled') } as const; const baseState = { - format: depthSpencilFormat, + format: depthStencilFormat, depthWriteEnabled: true, depthCompare: 'always', stencilFront: stencilState, @@ -207,7 +207,7 @@ g.test('depth_write_disabled') } as const; const depthWriteState = { - format: depthSpencilFormat, + format: depthStencilFormat, depthWriteEnabled, depthCompare: 'always', stencilFront: stencilState, @@ -217,7 +217,7 @@ g.test('depth_write_disabled') } as const; const checkState = { - format: depthSpencilFormat, + format: depthStencilFormat, depthWriteEnabled: false, depthCompare: 'equal', stencilFront: stencilState, @@ -256,10 +256,10 @@ g.test('depth_test_fail') .fn(t => { const { secondDepth, lastDepth, _expectedColor } = t.params; - const depthSpencilFormat: GPUTextureFormat = 'depth24plus-stencil8'; + const depthStencilFormat: GPUTextureFormat = 'depth24plus-stencil8'; const baseState = { - format: depthSpencilFormat, + format: depthStencilFormat, depthWriteEnabled: true, depthCompare: 'always', stencilReadMask: 0xff, @@ -267,7 +267,7 @@ g.test('depth_test_fail') } as const; const depthTestState = { - format: depthSpencilFormat, + format: depthStencilFormat, depthWriteEnabled: true, depthCompare: 'less', stencilReadMask: 0xff, @@ -292,55 +292,48 @@ g.test('depth_compare_func') `Tests each depth compare function works properly. Clears the depth attachment to various values, and renders a point at depth 0.5 with various depthCompare modes.` ) .params(u => - u - .combine( - 'format', - kDepthStencilFormats.filter(format => kTextureFormatInfo[format].depth) - ) - .combineWithParams([ - { depthCompare: 'never', depthClearValue: 1.0, _expected: backgroundColor }, - { depthCompare: 'never', depthClearValue: kMiddleDepthValue, _expected: backgroundColor }, - { depthCompare: 'never', depthClearValue: 0.0, _expected: backgroundColor }, - { depthCompare: 'less', depthClearValue: 1.0, _expected: triangleColor }, - { depthCompare: 'less', depthClearValue: kMiddleDepthValue, _expected: backgroundColor }, - { depthCompare: 'less', depthClearValue: 0.0, _expected: backgroundColor }, - { depthCompare: 'less-equal', depthClearValue: 1.0, _expected: triangleColor }, - { - depthCompare: 'less-equal', - depthClearValue: kMiddleDepthValue, - _expected: triangleColor, - }, - { depthCompare: 'less-equal', depthClearValue: 0.0, _expected: backgroundColor }, - { depthCompare: 'equal', depthClearValue: 1.0, _expected: backgroundColor }, - { depthCompare: 'equal', depthClearValue: kMiddleDepthValue, _expected: triangleColor }, - { depthCompare: 'equal', depthClearValue: 0.0, _expected: backgroundColor }, - { depthCompare: 'not-equal', depthClearValue: 1.0, _expected: triangleColor }, - { - depthCompare: 'not-equal', - depthClearValue: kMiddleDepthValue, - _expected: backgroundColor, - }, - { depthCompare: 'not-equal', depthClearValue: 0.0, _expected: triangleColor }, - { depthCompare: 'greater-equal', depthClearValue: 1.0, _expected: backgroundColor }, - { - depthCompare: 'greater-equal', - depthClearValue: kMiddleDepthValue, - _expected: triangleColor, - }, - { depthCompare: 'greater-equal', depthClearValue: 0.0, _expected: triangleColor }, - { depthCompare: 'greater', depthClearValue: 1.0, _expected: backgroundColor }, - { depthCompare: 'greater', depthClearValue: kMiddleDepthValue, _expected: backgroundColor }, - { depthCompare: 'greater', depthClearValue: 0.0, _expected: triangleColor }, - { depthCompare: 'always', depthClearValue: 1.0, _expected: triangleColor }, - { depthCompare: 'always', depthClearValue: kMiddleDepthValue, _expected: triangleColor }, - { depthCompare: 'always', depthClearValue: 0.0, _expected: triangleColor }, - ] as const) + u.combine('format', kDepthTextureFormats).combineWithParams([ + { depthCompare: 'never', depthClearValue: 1.0, _expected: backgroundColor }, + { depthCompare: 'never', depthClearValue: kMiddleDepthValue, _expected: backgroundColor }, + { depthCompare: 'never', depthClearValue: 0.0, _expected: backgroundColor }, + { depthCompare: 'less', depthClearValue: 1.0, _expected: triangleColor }, + { depthCompare: 'less', depthClearValue: kMiddleDepthValue, _expected: backgroundColor }, + { depthCompare: 'less', depthClearValue: 0.0, _expected: backgroundColor }, + { depthCompare: 'less-equal', depthClearValue: 1.0, _expected: triangleColor }, + { + depthCompare: 'less-equal', + depthClearValue: kMiddleDepthValue, + _expected: triangleColor, + }, + { depthCompare: 'less-equal', depthClearValue: 0.0, _expected: backgroundColor }, + { depthCompare: 'equal', depthClearValue: 1.0, _expected: backgroundColor }, + { depthCompare: 'equal', depthClearValue: kMiddleDepthValue, _expected: triangleColor }, + { depthCompare: 'equal', depthClearValue: 0.0, _expected: backgroundColor }, + { depthCompare: 'not-equal', depthClearValue: 1.0, _expected: triangleColor }, + { + depthCompare: 'not-equal', + depthClearValue: kMiddleDepthValue, + _expected: backgroundColor, + }, + { depthCompare: 'not-equal', depthClearValue: 0.0, _expected: triangleColor }, + { depthCompare: 'greater-equal', depthClearValue: 1.0, _expected: backgroundColor }, + { + depthCompare: 'greater-equal', + depthClearValue: kMiddleDepthValue, + _expected: triangleColor, + }, + { depthCompare: 'greater-equal', depthClearValue: 0.0, _expected: triangleColor }, + { depthCompare: 'greater', depthClearValue: 1.0, _expected: backgroundColor }, + { depthCompare: 'greater', depthClearValue: kMiddleDepthValue, _expected: backgroundColor }, + { depthCompare: 'greater', depthClearValue: 0.0, _expected: triangleColor }, + { depthCompare: 'always', depthClearValue: 1.0, _expected: triangleColor }, + { depthCompare: 'always', depthClearValue: kMiddleDepthValue, _expected: triangleColor }, + { depthCompare: 'always', depthClearValue: 0.0, _expected: triangleColor }, + ] as const) ) - .beforeAllSubcases(t => { - t.selectDeviceForTextureFormatOrSkipTestCase(t.params.format); - }) .fn(t => { const { depthCompare, depthClearValue, _expected, format } = t.params; + t.skipIfTextureFormatNotSupported(format); const colorAttachmentFormat = 'rgba8unorm'; const colorAttachment = t.createTextureTracked({ @@ -397,7 +390,7 @@ g.test('depth_compare_func') depthLoadOp: 'clear', depthStoreOp: 'store', }; - if (kTextureFormatInfo[format].stencil) { + if (isStencilTextureFormat(format)) { depthStencilAttachment.stencilClearValue = 0; depthStencilAttachment.stencilLoadOp = 'clear'; depthStencilAttachment.stencilStoreOp = 'store'; diff --git a/src/webgpu/api/operation/rendering/depth_bias.spec.ts b/src/webgpu/api/operation/rendering/depth_bias.spec.ts index 2c26d059d2bb..9ab644e2798f 100644 --- a/src/webgpu/api/operation/rendering/depth_bias.spec.ts +++ b/src/webgpu/api/operation/rendering/depth_bias.spec.ts @@ -6,11 +6,12 @@ Tests render results with different depth bias values like 'positive', 'negative import { makeTestGroup } from '../../../../common/framework/test_group.js'; import { unreachable } from '../../../../common/util/util.js'; import { - kTextureFormatInfo, DepthStencilFormat, EncodableTextureFormat, + isDepthTextureFormat, + isStencilTextureFormat, } from '../../../format_info.js'; -import { GPUTest, TextureTestMixin } from '../../../gpu_test.js'; +import { AllFeaturesMaxLimitsGPUTest, TextureTestMixin } from '../../../gpu_test.js'; import { TexelView } from '../../../util/texture/texel_view.js'; enum QuadAngle { @@ -29,7 +30,7 @@ enum QuadAngle { // depthBias = 0.25 / (2 ** (-2 - 23)) = 8388608. const kPointTwoFiveBiasForPointTwoFiveZOnFloat = 8388608; -class DepthBiasTest extends TextureTestMixin(GPUTest) { +class DepthBiasTest extends TextureTestMixin(AllFeaturesMaxLimitsGPUTest) { runDepthBiasTestInternal( depthFormat: DepthStencilFormat, { @@ -47,7 +48,6 @@ class DepthBiasTest extends TextureTestMixin(GPUTest) { } ): { renderTarget: GPUTexture; depthTexture: GPUTexture } { const renderTargetFormat = 'rgba8unorm'; - const depthFormatInfo = kTextureFormatInfo[depthFormat]; let vertexShaderCode: string; switch (quadAngle) { @@ -103,10 +103,10 @@ class DepthBiasTest extends TextureTestMixin(GPUTest) { const depthStencilAttachment: GPURenderPassDepthStencilAttachment = { view: depthTexture.createView(), - depthLoadOp: depthFormatInfo.depth ? 'clear' : undefined, - depthStoreOp: depthFormatInfo.depth ? 'store' : undefined, - stencilLoadOp: depthFormatInfo.stencil ? 'clear' : undefined, - stencilStoreOp: depthFormatInfo.stencil ? 'store' : undefined, + depthLoadOp: isDepthTextureFormat(depthFormat) ? 'clear' : undefined, + depthStoreOp: isDepthTextureFormat(depthFormat) ? 'store' : undefined, + stencilLoadOp: isStencilTextureFormat(depthFormat) ? 'clear' : undefined, + stencilStoreOp: isStencilTextureFormat(depthFormat) ? 'store' : undefined, depthClearValue: initialDepth, }; diff --git a/src/webgpu/api/operation/rendering/depth_clip_clamp.spec.ts b/src/webgpu/api/operation/rendering/depth_clip_clamp.spec.ts index 774ff4169b4d..1bc75fa971b4 100644 --- a/src/webgpu/api/operation/rendering/depth_clip_clamp.spec.ts +++ b/src/webgpu/api/operation/rendering/depth_clip_clamp.spec.ts @@ -4,8 +4,11 @@ depth ranges as well. `; import { makeTestGroup } from '../../../../common/framework/test_group.js'; -import { assert } from '../../../../common/util/util.js'; -import { kDepthStencilFormats, kTextureFormatInfo } from '../../../format_info.js'; +import { + getBlockInfoForTextureFormat, + isStencilTextureFormat, + kDepthTextureFormats, +} from '../../../format_info.js'; import { AllFeaturesMaxLimitsGPUTest } from '../../../gpu_test.js'; import { checkElementsBetween, @@ -36,24 +39,17 @@ have unexpected values then get drawn to the color buffer, which is later checke ) .params(u => u // - .combine('format', kDepthStencilFormats) - .filter(p => !!kTextureFormatInfo[p.format].depth) + .combine('format', kDepthTextureFormats) .combine('unclippedDepth', [undefined, false, true]) .combine('writeDepth', [false, true]) .combine('multisampled', [false, true]) ) - .beforeAllSubcases(t => { - const info = kTextureFormatInfo[t.params.format]; - - t.selectDeviceOrSkipTestCase([ - t.params.unclippedDepth ? 'depth-clip-control' : undefined, - info.feature, - ]); - }) .fn(async t => { const { format, unclippedDepth, writeDepth, multisampled } = t.params; - const info = kTextureFormatInfo[format]; - assert(!!info.depth); + t.skipIfTextureFormatNotSupported(format); + if (unclippedDepth) { + t.skipIfDeviceDoesNotHaveFeature('depth-clip-control'); + } const hasStorageBuffers = t.isCompatibility ? t.device.limits.maxStorageBuffersInFragmentStage! > 0 @@ -233,17 +229,18 @@ have unexpected values then get drawn to the color buffer, which is later checke ? t.createTextureTracked({ ...checkTextureDesc, sampleCount: 4 }).createView() : undefined; + const { bytesPerBlock } = getBlockInfoForTextureFormat(format); const dsActual = - !multisampled && info.depth.bytes + !multisampled && bytesPerBlock ? t.createBufferTracked({ - size: kNumTestPoints * info.depth.bytes, + size: kNumTestPoints * bytesPerBlock, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, }) : undefined; const dsExpected = - !multisampled && info.depth.bytes + !multisampled && bytesPerBlock ? t.createBufferTracked({ - size: kNumTestPoints * info.depth.bytes, + size: kNumTestPoints * bytesPerBlock, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, }) : undefined; @@ -272,9 +269,11 @@ have unexpected values then get drawn to the color buffer, which is later checke depthClearValue: 0.5, // Will see this depth value if the fragment was clipped. depthLoadOp: 'clear', depthStoreOp: 'store', - stencilClearValue: info.stencil ? 0 : undefined, - stencilLoadOp: info.stencil ? 'clear' : undefined, - stencilStoreOp: info.stencil ? 'discard' : undefined, + ...(isStencilTextureFormat(format) && { + stencilClearValue: 0, + stencilLoadOp: 'clear', + stencilStoreOp: 'discard', + }), }, }); pass.setPipeline(testPipeline); @@ -308,9 +307,11 @@ have unexpected values then get drawn to the color buffer, which is later checke view: dsTextureView, depthLoadOp: 'load', depthStoreOp: 'store', - stencilClearValue: info.stencil ? 0 : undefined, - stencilLoadOp: info.stencil ? 'clear' : undefined, - stencilStoreOp: info.stencil ? 'discard' : undefined, + ...(isStencilTextureFormat(format) && { + stencilClearValue: 0, + stencilLoadOp: 'clear', + stencilStoreOp: 'discard', + }), }, }); pass.setPipeline(checkPipeline); @@ -375,22 +376,16 @@ to be empty.` ) .params(u => u // - .combine('format', kDepthStencilFormats) - .filter(p => !!kTextureFormatInfo[p.format].depth) + .combine('format', kDepthTextureFormats) .combine('unclippedDepth', [false, true]) .combine('multisampled', [false, true]) ) - .beforeAllSubcases(t => { - const info = kTextureFormatInfo[t.params.format]; - - t.selectDeviceOrSkipTestCase([ - t.params.unclippedDepth ? 'depth-clip-control' : undefined, - info.feature, - ]); - }) .fn(t => { const { format, unclippedDepth, multisampled } = t.params; - const info = kTextureFormatInfo[format]; + t.skipIfTextureFormatNotSupported(format); + if (unclippedDepth) { + t.skipIfDeviceDoesNotHaveFeature('depth-clip-control'); + } const kNumDepthValues = 8; const kViewportMinDepth = 0.25; @@ -502,9 +497,11 @@ to be empty.` depthClearValue: 1.0, depthLoadOp: 'clear', depthStoreOp: 'store', - stencilClearValue: info.stencil ? 0 : undefined, - stencilLoadOp: info.stencil ? 'clear' : undefined, - stencilStoreOp: info.stencil ? 'discard' : undefined, + ...(isStencilTextureFormat(format) && { + stencilClearValue: 0, + stencilLoadOp: 'clear', + stencilStoreOp: 'discard', + }), }, }); pass.setPipeline(initPipeline); @@ -529,9 +526,11 @@ to be empty.` view: dsTextureView, depthLoadOp: 'load', depthStoreOp: 'store', - stencilClearValue: info.stencil ? 0 : undefined, - stencilLoadOp: info.stencil ? 'clear' : undefined, - stencilStoreOp: info.stencil ? 'discard' : undefined, + ...(isStencilTextureFormat(format) && { + stencilClearValue: 0, + stencilLoadOp: 'clear', + stencilStoreOp: 'discard', + }), }, }); pass.setPipeline(testPipeline); diff --git a/src/webgpu/api/operation/rendering/indirect_draw.spec.ts b/src/webgpu/api/operation/rendering/indirect_draw.spec.ts index 6823bd84634e..b28a873b1db2 100644 --- a/src/webgpu/api/operation/rendering/indirect_draw.spec.ts +++ b/src/webgpu/api/operation/rendering/indirect_draw.spec.ts @@ -7,14 +7,14 @@ import { kDrawIndirectParametersSize, kDrawIndexedIndirectParametersSize, } from '../../../capability_info.js'; -import { GPUTest, TextureTestMixin } from '../../../gpu_test.js'; +import { AllFeaturesMaxLimitsGPUTest, TextureTestMixin } from '../../../gpu_test.js'; const filled = new Uint8Array([0, 255, 0, 255]); const notFilled = new Uint8Array([0, 0, 0, 0]); const kRenderTargetFormat = 'rgba8unorm'; -class F extends GPUTest { +class F extends AllFeaturesMaxLimitsGPUTest { MakeIndexBuffer(): GPUBuffer { return this.makeBufferWithContents( /* prettier-ignore */ new Uint32Array([ diff --git a/src/webgpu/api/operation/rendering/robust_access_index.spec.ts b/src/webgpu/api/operation/rendering/robust_access_index.spec.ts index 68d7bc795da2..0ad782d41235 100644 --- a/src/webgpu/api/operation/rendering/robust_access_index.spec.ts +++ b/src/webgpu/api/operation/rendering/robust_access_index.spec.ts @@ -3,6 +3,6 @@ TODO: Test that drawIndexedIndirect accesses the index buffer robustly. `; import { makeTestGroup } from '../../../../common/framework/test_group.js'; -import { GPUTest } from '../../../gpu_test.js'; +import { AllFeaturesMaxLimitsGPUTest } from '../../../gpu_test.js'; -export const g = makeTestGroup(GPUTest); +export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest); diff --git a/src/webgpu/api/operation/rendering/stencil.spec.ts b/src/webgpu/api/operation/rendering/stencil.spec.ts index 9a51c365741f..99b0fab005bf 100644 --- a/src/webgpu/api/operation/rendering/stencil.spec.ts +++ b/src/webgpu/api/operation/rendering/stencil.spec.ts @@ -5,15 +5,15 @@ Test related to stencil states, stencil op, compare func, etc. import { makeTestGroup } from '../../../../common/framework/test_group.js'; import { TypedArrayBufferView } from '../../../../common/util/util.js'; import { - kDepthStencilFormats, - kTextureFormatInfo, + kStencilTextureFormats, DepthStencilFormat, + isDepthTextureFormat, + isStencilTextureFormat, + kDepthStencilFormats, } from '../../../format_info.js'; -import { GPUTest, TextureTestMixin } from '../../../gpu_test.js'; +import { AllFeaturesMaxLimitsGPUTest, TextureTestMixin } from '../../../gpu_test.js'; import { TexelView } from '../../../util/texture/texel_view.js'; -const kStencilFormats = kDepthStencilFormats.filter(format => kTextureFormatInfo[format].stencil); - const kBaseColor = new Float32Array([1.0, 1.0, 1.0, 1.0]); const kRedStencilColor = new Float32Array([1.0, 0.0, 0.0, 1.0]); const kGreenStencilColor = new Float32Array([0.0, 1.0, 0.0, 1.0]); @@ -24,7 +24,7 @@ type TestStates = { stencil: number | undefined; }; -class StencilTest extends TextureTestMixin(GPUTest) { +class StencilTest extends TextureTestMixin(AllFeaturesMaxLimitsGPUTest) { checkStencilOperation( depthStencilFormat: DepthStencilFormat, testStencilState: GPUStencilFaceState, @@ -142,7 +142,7 @@ class StencilTest extends TextureTestMixin(GPUTest) { usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST, }); - const hasDepth = kTextureFormatInfo[depthStencilFormat].depth; + const hasDepth = isDepthTextureFormat(depthStencilFormat); const depthStencilAttachment: GPURenderPassDepthStencilAttachment = { view: depthTexture.createView(), depthLoadOp: hasDepth ? 'load' : undefined, @@ -272,7 +272,7 @@ g.test('stencil_compare_func') ) .params(u => u // - .combine('format', kStencilFormats) + .combine('format', kStencilTextureFormats) .combineWithParams([ { stencilCompare: 'always', stencilRefValue: 0, _expectedColor: kGreenStencilColor }, { stencilCompare: 'always', stencilRefValue: 1, _expectedColor: kGreenStencilColor }, @@ -300,11 +300,9 @@ g.test('stencil_compare_func') { stencilCompare: 'not-equal', stencilRefValue: 2, _expectedColor: kGreenStencilColor }, ] as const) ) - .beforeAllSubcases(t => { - t.selectDeviceForTextureFormatOrSkipTestCase(t.params.format); - }) .fn(t => { const { format, stencilCompare, stencilRefValue, _expectedColor } = t.params; + t.skipIfTextureFormatNotSupported(format); t.checkStencilCompareFunction(format, stencilCompare, stencilRefValue, _expectedColor); }); @@ -322,7 +320,7 @@ g.test('stencil_passOp_operation') ) .params(u => u // - .combine('format', kStencilFormats) + .combine('format', kStencilTextureFormats) .combineWithParams([ { passOp: 'keep', initialStencil: 1, _expectedStencil: 1 }, { passOp: 'zero', initialStencil: 1, _expectedStencil: 0 }, @@ -338,11 +336,9 @@ g.test('stencil_passOp_operation') { passOp: 'decrement-wrap', initialStencil: 0, _expectedStencil: 0xff }, ] as const) ) - .beforeAllSubcases(t => { - t.selectDeviceForTextureFormatOrSkipTestCase(t.params.format); - }) .fn(t => { const { format, passOp, initialStencil, _expectedStencil } = t.params; + t.skipIfTextureFormatNotSupported(format); const stencilState = { compare: 'always', @@ -366,7 +362,7 @@ g.test('stencil_failOp_operation') ) .params(u => u // - .combine('format', kStencilFormats) + .combine('format', kStencilTextureFormats) .combineWithParams([ { failOp: 'keep', initialStencil: 1, _expectedStencil: 1 }, { failOp: 'zero', initialStencil: 1, _expectedStencil: 0 }, @@ -383,11 +379,9 @@ g.test('stencil_failOp_operation') { failOp: 'decrement-wrap', initialStencil: 0, _expectedStencil: 0xff }, ] as const) ) - .beforeAllSubcases(t => { - t.selectDeviceForTextureFormatOrSkipTestCase(t.params.format); - }) .fn(t => { const { format, failOp, initialStencil, _expectedStencil } = t.params; + t.skipIfTextureFormatNotSupported(format); const stencilState = { compare: 'never', @@ -416,10 +410,9 @@ g.test('stencil_depthFailOp_operation') u // .combine( 'format', - kDepthStencilFormats.filter(format => { - const info = kTextureFormatInfo[format]; - return info.depth && info.stencil; - }) + kDepthStencilFormats.filter( + format => isDepthTextureFormat(format) && isStencilTextureFormat(format) + ) ) .combineWithParams([ { depthFailOp: 'keep', initialStencil: 1, _expectedStencil: 1 }, @@ -437,11 +430,9 @@ g.test('stencil_depthFailOp_operation') { depthFailOp: 'decrement-wrap', initialStencil: 0, _expectedStencil: 0xff }, ] as const) ) - .beforeAllSubcases(t => { - t.selectDeviceForTextureFormatOrSkipTestCase(t.params.format); - }) .fn(t => { const { format, depthFailOp, initialStencil, _expectedStencil } = t.params; + t.skipIfTextureFormatNotSupported(format); const stencilState = { compare: 'always', @@ -475,7 +466,7 @@ g.test('stencil_read_write_mask') ) .params(u => u // - .combine('format', kStencilFormats) + .combine('format', kStencilTextureFormats) .combineWithParams([ { maskType: 'write', stencilRefValue: 1, _expectedColor: kRedStencilColor }, { maskType: 'write', stencilRefValue: 2, _expectedColor: kBaseColor }, @@ -483,11 +474,9 @@ g.test('stencil_read_write_mask') { maskType: 'read', stencilRefValue: 2, _expectedColor: kRedStencilColor }, ]) ) - .beforeAllSubcases(t => { - t.selectDeviceForTextureFormatOrSkipTestCase(t.params.format); - }) .fn(t => { const { format, maskType, stencilRefValue, _expectedColor } = t.params; + t.skipIfTextureFormatNotSupported(format); const baseStencilState = { compare: 'always', @@ -532,12 +521,10 @@ g.test('stencil_read_write_mask') g.test('stencil_reference_initialized') .desc('Test that stencil reference is initialized as zero for new render pass.') - .params(u => u.combine('format', kStencilFormats)) - .beforeAllSubcases(t => { - t.selectDeviceForTextureFormatOrSkipTestCase(t.params.format); - }) + .params(u => u.combine('format', kStencilTextureFormats)) .fn(t => { const { format } = t.params; + t.skipIfTextureFormatNotSupported(format); const baseStencilState = { compare: 'always', @@ -549,7 +536,7 @@ g.test('stencil_reference_initialized') passOp: 'keep', } as const; - const hasDepth = !!kTextureFormatInfo[format].depth; + const hasDepth = isDepthTextureFormat(format); const baseState = { format, diff --git a/src/webgpu/gpu_test.ts b/src/webgpu/gpu_test.ts index 82e308917c28..90d792926111 100644 --- a/src/webgpu/gpu_test.ts +++ b/src/webgpu/gpu_test.ts @@ -38,6 +38,7 @@ import { isTextureFormatUsableAsRenderAttachment, isTextureFormatMultisampled, is32Float, + isSintOrUintFormat, } from './format_info.js'; import { checkElementsEqual, checkElementsBetween } from './util/check_contents.js'; import { CommandBufferMaker, EncoderType } from './util/command_buffer_maker.js'; @@ -673,6 +674,7 @@ export class GPUTestBase extends Fixture { skipIfTextureFormatNotBlendable(...formats: (GPUTextureFormat | undefined)[]) { for (const format of formats) { if (format === undefined) continue; + this.skipIf(isSintOrUintFormat(format), 'sint/uint formats are not blendable'); if (is32Float(format)) { this.skipIf( !this.device.features.has('float32-blendable'),