Skip to content

Commit

Permalink
Refactor createView test for texture formats.
Browse files Browse the repository at this point in the history
  • Loading branch information
greggman committed Feb 20, 2025
1 parent 0d0ce46 commit b959c30
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 47 deletions.
77 changes: 30 additions & 47 deletions src/webgpu/api/validation/createView.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import {
} from '../../capability_info.js';
import { GPUConst } from '../../constants.js';
import {
kTextureFormatInfo,
kAllTextureFormats,
kFeaturesForFormats,
filterFormatsByFeature,
viewCompatibleDeprecated,
textureFormatsAreViewCompatible,
isDepthTextureFormat,
isStencilTextureFormat,
getBlockInfoForTextureFormat,
isTextureFormatPossiblyUsableAsRenderAttachment,
} from '../../format_info.js';
import { kResourceStates } from '../../gpu_test.js';
import {
Expand All @@ -25,9 +28,9 @@ import {
} from '../../util/texture/base.js';
import { reifyExtent3D } from '../../util/unions.js';

import { ValidationTest } from './validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from './validation_test.js';

export const g = makeTestGroup(ValidationTest);
export const g = makeTestGroup(AllFeaturesMaxLimitsValidationTest);

const kLevels = 6;

Expand All @@ -48,19 +51,15 @@ g.test('format')
)
.combine('useViewFormatList', [false, true])
)
.beforeAllSubcases(t => {
const { textureFormatFeature, viewFormatFeature } = t.params;
t.selectDeviceOrSkipTestCase([textureFormatFeature, viewFormatFeature]);
})
.fn(t => {
const { textureFormat, viewFormat, useViewFormatList } = t.params;
const { blockWidth, blockHeight } = kTextureFormatInfo[textureFormat];
const { blockWidth, blockHeight } = getBlockInfoForTextureFormat(textureFormat);

t.skipIfTextureFormatNotSupportedDeprecated(textureFormat, viewFormat);
t.skipIfTextureFormatNotSupported(textureFormat, viewFormat);

const compatible =
viewFormat === undefined ||
viewCompatibleDeprecated(t.isCompatibility, textureFormat, viewFormat);
textureFormatsAreViewCompatible(t.device, textureFormat, viewFormat);

const texture = t.createTextureTracked({
format: textureFormat,
Expand Down Expand Up @@ -94,11 +93,9 @@ g.test('dimension')
.combine('textureDimension', kTextureDimensions)
.combine('viewDimension', [...kTextureViewDimensions, undefined])
)
.beforeAllSubcases(t => {
t.skipIfTextureViewDimensionNotSupportedDeprecated(t.params.viewDimension);
})
.fn(t => {
const { textureDimension, viewDimension } = t.params;
t.skipIfTextureViewDimensionNotSupported(t.params.viewDimension);

const size = textureDimension === '1d' ? [4] : [4, 4, 6];
const textureDescriptor = {
Expand Down Expand Up @@ -130,24 +127,22 @@ g.test('aspect')
.combine('format', kAllTextureFormats)
.combine('aspect', kTextureAspects)
)
.beforeAllSubcases(t => {
const { format } = t.params;
t.selectDeviceForTextureFormatOrSkipTestCase(format);
})
.fn(t => {
const { format, aspect } = t.params;
const info = kTextureFormatInfo[format];
const { blockWidth, blockHeight } = getBlockInfoForTextureFormat(format);

t.skipIfTextureFormatNotSupported(format);

const texture = t.createTextureTracked({
format,
size: [info.blockWidth, info.blockHeight, 1],
size: [blockWidth, blockHeight, 1],
usage: GPUTextureUsage.TEXTURE_BINDING,
});

const success =
aspect === 'all' ||
(aspect === 'depth-only' && info.depth) ||
(aspect === 'stencil-only' && info.stencil);
(aspect === 'depth-only' && isDepthTextureFormat(format)) ||
(aspect === 'stencil-only' && isStencilTextureFormat(format));
t.expectValidationError(() => {
texture.createView({ aspect });
}, !success);
Expand Down Expand Up @@ -277,7 +272,7 @@ g.test('mip_levels')
const { textureDimension, viewDimension, textureLevels, baseMipLevel, mipLevelCount } =
t.params;

t.skipIfTextureViewDimensionNotSupportedDeprecated(viewDimension);
t.skipIfTextureViewDimensionNotSupported(viewDimension);

const textureDescriptor: GPUTextureDescriptor = {
format: 'rgba8unorm',
Expand Down Expand Up @@ -317,7 +312,7 @@ g.test('cube_faces_square')
.fn(t => {
const { dimension, size } = t.params;

t.skipIfTextureViewDimensionNotSupportedDeprecated(dimension);
t.skipIfTextureViewDimensionNotSupported(dimension);

const texture = t.createTextureTracked({
format: 'rgba8unorm',
Expand Down Expand Up @@ -352,43 +347,31 @@ g.test('texture_view_usage')
.combine('format', kAllTextureFormats)
.combine('textureUsage0', kTextureUsages)
.combine('textureUsage1', kTextureUsages)
.filter(({ format, textureUsage0, textureUsage1 }) => {
const info = kTextureFormatInfo[format];
.unless(({ format, textureUsage0, textureUsage1 }) => {
const textureUsage = textureUsage0 | textureUsage1;

if (
return (
(textureUsage & GPUConst.TextureUsage.RENDER_ATTACHMENT) !== 0 &&
info.color &&
!info.colorRender
) {
return false;
}

return true;
!isTextureFormatPossiblyUsableAsRenderAttachment(format)
);
})
.beginSubcases()
.combine('textureViewUsage0', [0, ...kTextureUsages])
.combine('textureViewUsage1', [0, ...kTextureUsages])
)
.beforeAllSubcases(t => {
const { format, textureUsage0, textureUsage1 } = t.params;
const info = kTextureFormatInfo[format];
const textureUsage = textureUsage0 | textureUsage1;
t.skipIfTextureFormatNotSupportedDeprecated(format);
t.selectDeviceOrSkipTestCase(info.feature);
if (textureUsage & GPUTextureUsage.STORAGE_BINDING) {
t.skipIfTextureFormatNotUsableAsStorageTextureDeprecated(format);
}
})
.fn(t => {
const { format, textureUsage0, textureUsage1, textureViewUsage0, textureViewUsage1 } = t.params;
const info = kTextureFormatInfo[format];

const size = [info.blockWidth, info.blockHeight, 1];
t.skipIfTextureFormatNotSupported(format);

const { blockWidth, blockHeight } = getBlockInfoForTextureFormat(format);

const size = [blockWidth, blockHeight, 1];
const dimension = '2d';
const mipLevelCount = 1;
const usage = textureUsage0 | textureUsage1;

t.skipIfTextureFormatDoesNotSupportUsage(usage, format);

const textureDescriptor: GPUTextureDescriptor = {
size,
mipLevelCount,
Expand Down
22 changes: 22 additions & 0 deletions src/webgpu/format_info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1784,6 +1784,19 @@ export function getBlockInfoForColorTextureFormat(format: ColorTextureFormat) {
};
}

/**
* Gets the block width, height, and bytes per block for a color texture format.
* Note that bytesPerBlock will be undefined if format's size is undefined.
*/
export function getBlockInfoForTextureFormat(format: GPUTextureFormat) {
const info = kTextureFormatInfo[format];
return {
blockWidth: info.blockWidth,
blockHeight: info.blockHeight,
bytesPerBlock: info.color?.bytes ?? info.depth?.bytes ?? info.stencil?.bytes,
};
}

/**
* Gets the baseFormat for a texture format.
*/
Expand Down Expand Up @@ -1863,6 +1876,15 @@ export function isTextureFormatColorRenderable(
return !!kAllTextureFormatInfo[format].colorRender;
}

/**
* Returns true of a texture can possibly be used as a render attachment.
* The texture may require certain features to be enabled.
*/
export function isTextureFormatPossiblyUsableAsRenderAttachment(format: GPUTextureFormat) {
const info = kTextureFormatInfo[format];
return format === 'rg11b10ufloat' || isDepthOrStencilTextureFormat(format) || !!info.colorRender;
}

export function is16Float(format: GPUTextureFormat) {
return format === 'r16float' || format === 'rg16float' || format === 'rgba16float';
}
Expand Down
24 changes: 24 additions & 0 deletions src/webgpu/gpu_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
isTextureFormatUsableAsStorageFormatDeprecated,
isMultisampledTextureFormatDeprecated,
isTextureFormatUsableAsStorageFormat,
isTextureFormatUsableAsRenderAttachment,
} from './format_info.js';
import { checkElementsEqual, checkElementsBetween } from './util/check_contents.js';
import { CommandBufferMaker, EncoderType } from './util/command_buffer_maker.js';
Expand Down Expand Up @@ -613,6 +614,29 @@ export class GPUTestBase extends Fixture<GPUTestSubcaseBatchState> {
}
}

skipIfTextureFormatNotUsableAsRenderAttachment(...formats: (GPUTextureFormat | undefined)[]) {
for (const format of formats) {
if (format && !isTextureFormatUsableAsRenderAttachment(this.device, format)) {
this.skip(`Texture with ${format} is not usable as a render attachment`);
}
}
}

skipIfTextureFormatDoesNotSupportUsage(
usage: GPUTextureUsageFlags,
...formats: (GPUTextureFormat | undefined)[]
) {
for (const format of formats) {
if (!format) continue;
if (usage & GPUTextureUsage.RENDER_ATTACHMENT) {
this.skipIfTextureFormatNotUsableAsRenderAttachment(format);
}
if (usage & GPUTextureUsage.STORAGE_BINDING) {
this.skipIfTextureFormatNotUsableAsStorageTexture(format);
}
}
}

/** Skips this test case if the `langFeature` is *not* supported. */
skipIfLanguageFeatureNotSupported(langFeature: WGSLLanguageFeature) {
if (!this.hasLanguageFeature(langFeature)) {
Expand Down

0 comments on commit b959c30

Please sign in to comment.