diff --git a/src/webgpu/api/validation/createView.spec.ts b/src/webgpu/api/validation/createView.spec.ts index 981a24a6138e..18506f9799d5 100644 --- a/src/webgpu/api/validation/createView.spec.ts +++ b/src/webgpu/api/validation/createView.spec.ts @@ -5,6 +5,7 @@ import { kUnitCaseParamsBuilder } from '../../../common/framework/params_builder import { makeTestGroup } from '../../../common/framework/test_group.js'; import { unreachable } from '../../../common/util/util.js'; import { + isValidTextureUsageCombination, kTextureAspects, kTextureDimensions, kTextureUsages, @@ -356,7 +357,7 @@ g.test('texture_view_usage') ); }) .beginSubcases() - .combine('textureViewUsage', [0, ...kTextureUsages]) + .combine('textureViewUsage', kTextureUsages) .unless(({ textureUsage, textureViewUsage }) => { // TRANSIENT_ATTACHMENT is only valid when combined with RENDER_ATTACHMENT. return ( @@ -391,9 +392,50 @@ g.test('texture_view_usage') }, !success); }); +g.test('texture_view_usage_of_multiple_usages') + .desc( + `For a single format (rgba8unorm), check that createView: + - allows 0 usages + - disallows subsetting usages of TRANSIENT_ATTACHMENT textures + ` + ) + .params(u => + u + .combine('usage1', kTextureUsages) + .combine('usage2', kTextureUsages) + .filter(p => p.usage1 <= p.usage2) + .filter(p => isValidTextureUsageCombination(p.usage1 | p.usage2)) + .beginSubcases() + .expand('viewUsage', p => new Set([0, p.usage1, p.usage2, p.usage1 | p.usage2])) + ) + .fn(t => { + const { usage1, usage2, viewUsage } = t.params; + const usage = usage1 | usage2; + + // MAINTENANCE_TODO(#4509): Remove this after all implementations have TRANSIENT_ATTACHMENT. + if ((usage & GPUConst.TextureUsage.TRANSIENT_ATTACHMENT) !== 0) { + t.skipIfTransientAttachmentNotSupported(); + } + + let isValid = true; + if (usage & GPUTextureUsage.TRANSIENT_ATTACHMENT) { + isValid &&= viewUsage === usage; + } + + const texture = t.createTextureTracked({ format: 'rgba8unorm', size: [1, 1], usage }); + t.expectGPUError( + 'validation', + () => { + texture.createView({ usage: viewUsage }); + }, + !isValid + ); + }); + g.test('texture_view_usage_with_view_format') .desc( - `Test that the texture view usage must be supported by the view's format. Checks for every view format possible, and every usage supported by the texture's format` + `Test that the texture view usage must be supported by the view's format. Checks for every view + format possible, and every usage supported by the texture's format` ) .params(u => u diff --git a/src/webgpu/api/validation/render_pass/resolve.spec.ts b/src/webgpu/api/validation/render_pass/resolve.spec.ts index 1ef96643e374..d4578aace2d5 100644 --- a/src/webgpu/api/validation/render_pass/resolve.spec.ts +++ b/src/webgpu/api/validation/render_pass/resolve.spec.ts @@ -20,6 +20,7 @@ Test various validation behaviors when a resolveTarget is provided. - resolve source is not multisampled. - resolve target is not single sampled. - resolve target missing RENDER_ATTACHMENT usage. +- resolve target has TRANSIENT_ATTACHMENT usage. - resolve target must have exactly one subresource: - base mip level {0, >0}, mip level count {1, >1}. - base array layer {0, >0}, array layer count {1, >1}. @@ -35,12 +36,20 @@ Test various validation behaviors when a resolveTarget is provided. // control cases should be valid { _valid: true }, { bindTextureResource: true, _valid: true }, + { resolveTargetUsage: GPUConst.TextureUsage.RENDER_ATTACHMENT, _valid: true }, // a single sampled resolve source should cause a validation error. { colorAttachmentSamples: 1, _valid: false }, // a multisampled resolve target should cause a validation error. { resolveTargetSamples: 4, _valid: false }, // resolveTargetUsage without RENDER_ATTACHMENT usage should cause a validation error. { resolveTargetUsage: GPUConst.TextureUsage.COPY_SRC, _valid: false }, + // resolveTargetUsage with TRANSIENT_ATTACHMENT | RENDER_ATTACHMENT usage should cause a + // validation error. + { + resolveTargetUsage: + GPUConst.TextureUsage.RENDER_ATTACHMENT | GPUConst.TextureUsage.TRANSIENT_ATTACHMENT, + _valid: false, + }, // non-zero resolve target base mip level should be valid. { resolveTargetViewBaseMipLevel: 1, @@ -98,6 +107,11 @@ Test various validation behaviors when a resolveTarget is provided. _valid, } = t.params; + // MAINTENANCE_TODO(#4509): Remove this after all implementations have TRANSIENT_ATTACHMENT. + if ((resolveTargetUsage & GPUConst.TextureUsage.TRANSIENT_ATTACHMENT) !== 0) { + t.skipIfTransientAttachmentNotSupported(); + } + // Run the test in a nested loop such that the configured color attachment with resolve target // is tested while occupying each individual colorAttachment slot. for (let resolveSlot = 0; resolveSlot < kNumColorAttachments; resolveSlot++) {