summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/tests/cts/checkout/src/webgpu/compat/api/validation/createBindGroup.spec.ts
diff options
context:
space:
mode:
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.ts178
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);
+ });