diff options
Diffstat (limited to 'dom/webgpu/tests/cts/checkout/src/webgpu/compat/api/validation/createBindGroup.spec.ts')
-rw-r--r-- | dom/webgpu/tests/cts/checkout/src/webgpu/compat/api/validation/createBindGroup.spec.ts | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/dom/webgpu/tests/cts/checkout/src/webgpu/compat/api/validation/createBindGroup.spec.ts b/dom/webgpu/tests/cts/checkout/src/webgpu/compat/api/validation/createBindGroup.spec.ts new file mode 100644 index 0000000000..b48fa80422 --- /dev/null +++ b/dom/webgpu/tests/cts/checkout/src/webgpu/compat/api/validation/createBindGroup.spec.ts @@ -0,0 +1,178 @@ +export const description = ` +Tests that, in compat mode, the dimension of a view is compatible with a texture's textureBindingViewDimension. +`; + +import { makeTestGroup } from '../../../../common/framework/test_group.js'; +import { kTextureDimensions, kTextureViewDimensions } from '../../../capability_info.js'; +import { + effectiveViewDimensionForTexture, + getTextureDimensionFromView, +} from '../../../util/texture/base.js'; +import { CompatibilityTest } from '../../compatibility_test.js'; + +export const g = makeTestGroup(CompatibilityTest); + +function isTextureBindingViewDimensionCompatibleWithDimension( + dimension: GPUTextureDimension = '2d', + textureBindingViewDimension: GPUTextureViewDimension = '2d' +) { + return getTextureDimensionFromView(textureBindingViewDimension) === dimension; +} + +function isValidViewDimensionForDimension( + dimension: GPUTextureDimension | undefined, + depthOrArrayLayers: number, + viewDimension: GPUTextureViewDimension | undefined +) { + if (viewDimension === undefined) { + return true; + } + + switch (dimension) { + case '1d': + return viewDimension === '1d'; + case '2d': + case undefined: + switch (viewDimension) { + case undefined: + case '2d': + case '2d-array': + return true; + case 'cube': + return depthOrArrayLayers === 6; + case 'cube-array': + return depthOrArrayLayers % 6 === 0; + default: + return false; + } + break; + case '3d': + return viewDimension === '3d'; + } +} + +function isValidDimensionForDepthOrArrayLayers( + dimension: GPUTextureDimension | undefined, + depthOrArrayLayers: number +) { + switch (dimension) { + case '1d': + return depthOrArrayLayers === 1; + default: + return true; + } +} + +function isValidViewDimensionForDepthOrArrayLayers( + viewDimension: GPUTextureViewDimension | undefined, + depthOrArrayLayers: number +) { + switch (viewDimension) { + case '2d': + return depthOrArrayLayers === 1; + case 'cube': + return depthOrArrayLayers === 6; + case 'cube-array': + return depthOrArrayLayers % 6 === 0; + default: + return true; + } + return viewDimension === 'cube'; +} + +function getEffectiveTextureBindingViewDimension( + dimension: GPUTextureDimension | undefined, + depthOrArrayLayers: number, + textureBindingViewDimension: GPUTextureViewDimension | undefined +) { + if (textureBindingViewDimension) { + return textureBindingViewDimension; + } + + switch (dimension) { + case '1d': + return '1d'; + case '2d': + case undefined: + return depthOrArrayLayers > 1 ? '2d-array' : '2d'; + break; + case '3d': + return '3d'; + } +} + +g.test('viewDimension_matches_textureBindingViewDimension') + .desc( + ` + Tests that, in compat mode, the dimension of a view is compatible with a texture's textureBindingViewDimension + when used as a TEXTURE_BINDING. + ` + ) + .params(u => + u // + .combine('dimension', [...kTextureDimensions, undefined]) + .combine('textureBindingViewDimension', [...kTextureViewDimensions, undefined]) + .combine('viewDimension', [...kTextureViewDimensions, undefined]) + .combine('depthOrArrayLayers', [1, 2, 6]) + .filter( + ({ dimension, textureBindingViewDimension, depthOrArrayLayers, viewDimension }) => + textureBindingViewDimension !== 'cube-array' && + viewDimension !== 'cube-array' && + isTextureBindingViewDimensionCompatibleWithDimension( + dimension, + textureBindingViewDimension + ) && + isValidViewDimensionForDimension(dimension, depthOrArrayLayers, viewDimension) && + isValidViewDimensionForDepthOrArrayLayers( + textureBindingViewDimension, + depthOrArrayLayers + ) && + isValidDimensionForDepthOrArrayLayers(dimension, depthOrArrayLayers) + ) + ) + .fn(t => { + const { dimension, textureBindingViewDimension, viewDimension, depthOrArrayLayers } = t.params; + + const texture = t.device.createTexture({ + size: [1, 1, depthOrArrayLayers], + format: 'rgba8unorm', + usage: GPUTextureUsage.TEXTURE_BINDING, + ...(dimension && { dimension }), + ...(textureBindingViewDimension && { textureBindingViewDimension }), + } as GPUTextureDescriptor); // MAINTENANCE_TODO: remove cast once textureBindingViewDimension is added to IDL + t.trackForCleanup(texture); + + const effectiveTextureBindingViewDimension = getEffectiveTextureBindingViewDimension( + dimension, + texture.depthOrArrayLayers, + textureBindingViewDimension + ); + + const effectiveViewDimension = getEffectiveTextureBindingViewDimension( + dimension, + texture.depthOrArrayLayers, + viewDimension + ); + + const layout = t.device.createBindGroupLayout({ + entries: [ + { + binding: 0, + visibility: GPUShaderStage.COMPUTE, + texture: { + viewDimension: effectiveViewDimensionForTexture(texture, viewDimension), + }, + }, + ], + }); + + const resource = texture.createView({ dimension: viewDimension }); + const shouldError = effectiveTextureBindingViewDimension !== effectiveViewDimension; + + t.expectValidationError(() => { + t.device.createBindGroup({ + layout, + entries: [{ binding: 0, resource }], + }); + }, shouldError); + }); |