blob: c897aa494f9c17b417fb908dcddf330a850d23c9 [file] [log] [blame]
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.createTextureTracked({
size: [1, 1, depthOrArrayLayers],
format: 'rgba8unorm',
usage: GPUTextureUsage.TEXTURE_BINDING,
...(dimension && { dimension }),
...(textureBindingViewDimension && { textureBindingViewDimension }),
});
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.expectValidationErrorInCompatibilityMode(() => {
t.device.createBindGroup({
layout,
entries: [{ binding: 0, resource }],
});
}, shouldError);
});