Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor src/webpgu/api/validation/encoding and a few extra #4217

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 6 additions & 12 deletions src/webgpu/api/validation/encoding/beginComputePass.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Tests for validation in beginComputePass and GPUComputePassDescriptor as its opt

import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { kQueryTypes } from '../../../capability_info.js';
import { ValidationTest } from '../validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from '../validation_test.js';

class F extends ValidationTest {
class F extends AllFeaturesMaxLimitsValidationTest {
tryComputePass(success: boolean, descriptor: GPUComputePassDescriptor): void {
const encoder = this.device.createCommandEncoder();
const computePass = encoder.beginComputePass(descriptor);
Expand All @@ -31,11 +31,9 @@ g.test('timestampWrites,query_set_type')
u //
.combine('queryType', kQueryTypes)
)
.beforeAllSubcases(t => {
t.selectDeviceForQueryTypeOrSkipTestCase(['timestamp', t.params.queryType]);
})
.fn(t => {
const { queryType } = t.params;
t.skipIfDeviceDoesNotSupportQueryType(queryType);

const isValid = queryType === 'timestamp';

Expand All @@ -55,10 +53,8 @@ g.test('timestampWrites,query_set_type')
g.test('timestampWrites,invalid_query_set')
.desc(`Tests that timestampWrite that has an invalid query set generates a validation error.`)
.params(u => u.combine('querySetState', ['valid', 'invalid'] as const))
.beforeAllSubcases(t => {
t.selectDeviceOrSkipTestCase(['timestamp-query']);
})
.fn(t => {
t.skipIfDeviceDoesNotSupportQueryType('timestamp');
const { querySetState } = t.params;

const querySet = t.createQuerySetWithState(querySetState, {
Expand Down Expand Up @@ -88,10 +84,8 @@ g.test('timestampWrites,query_index')
.combine('beginningOfPassWriteIndex', [undefined, 0, 1, 2, 3] as const)
.combine('endOfPassWriteIndex', [undefined, 0, 1, 2, 3] as const)
)
.beforeAllSubcases(t => {
t.selectDeviceOrSkipTestCase(['timestamp-query']);
})
.fn(t => {
t.skipIfDeviceDoesNotSupportQueryType('timestamp');
const { beginningOfPassWriteIndex, endOfPassWriteIndex } = t.params;

const querySetCount = 2;
Expand Down Expand Up @@ -122,10 +116,10 @@ g.test('timestamp_query_set,device_mismatch')
)
.paramsSubcasesOnly(u => u.combine('mismatched', [true, false]))
.beforeAllSubcases(t => {
t.selectDeviceOrSkipTestCase(['timestamp-query']);
t.selectMismatchedDeviceOrSkipTestCase('timestamp-query');
})
.fn(t => {
t.skipIfDeviceDoesNotSupportQueryType('timestamp');
const { mismatched } = t.params;
const sourceDevice = mismatched ? t.mismatchedDevice : t.device;

Expand Down
6 changes: 3 additions & 3 deletions src/webgpu/api/validation/encoding/beginRenderPass.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ Notes:
`;

import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { ValidationTest } from '../validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from '../validation_test.js';

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

g.test('color_attachments,device_mismatch')
.desc(
Expand Down Expand Up @@ -176,10 +176,10 @@ g.test('timestamp_query_set,device_mismatch')
)
.paramsSubcasesOnly(u => u.combine('mismatched', [true, false]))
.beforeAllSubcases(t => {
t.selectDeviceOrSkipTestCase(['timestamp-query']);
t.selectMismatchedDeviceOrSkipTestCase('timestamp-query');
})
.fn(t => {
t.skipIfDeviceDoesNotSupportQueryType('timestamp');
const { mismatched } = t.params;
const sourceDevice = mismatched ? t.mismatchedDevice : t.device;

Expand Down
4 changes: 2 additions & 2 deletions src/webgpu/api/validation/encoding/cmds/clearBuffer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js';
import { kBufferUsages } from '../../../../capability_info.js';
import { kResourceStates } from '../../../../gpu_test.js';
import { kMaxSafeMultipleOf8 } from '../../../../util/math.js';
import { ValidationTest } from '../../validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from '../../validation_test.js';

class F extends ValidationTest {
class F extends AllFeaturesMaxLimitsValidationTest {
TestClearBuffer(options: {
buffer: GPUBuffer;
offset: number | undefined;
Expand Down
4 changes: 2 additions & 2 deletions src/webgpu/api/validation/encoding/cmds/compute_pass.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { makeValueTestVariant } from '../../../../../common/util/util.js';
import { kBufferUsages } from '../../../../capability_info.js';
import { GPUConst } from '../../../../constants.js';
import { kResourceStates, ResourceState } from '../../../../gpu_test.js';
import { ValidationTest } from '../../validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from '../../validation_test.js';

class F extends ValidationTest {
class F extends AllFeaturesMaxLimitsValidationTest {
createComputePipeline(state: 'valid' | 'invalid'): GPUComputePipeline {
if (state === 'valid') {
return this.createNoOpComputePipeline();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ import { makeTestGroup } from '../../../../../common/framework/test_group.js';
import { kBufferUsages } from '../../../../capability_info.js';
import { kResourceStates } from '../../../../gpu_test.js';
import { kMaxSafeMultipleOf8 } from '../../../../util/math.js';
import { ValidationTest } from '../../validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from '../../validation_test.js';

class F extends ValidationTest {
class F extends AllFeaturesMaxLimitsValidationTest {
TestCopyBufferToBuffer(options: {
srcBuffer: GPUBuffer;
srcOffset: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@ copyTextureToTexture tests.
import { makeTestGroup } from '../../../../../common/framework/test_group.js';
import { kTextureUsages, kTextureDimensions } from '../../../../capability_info.js';
import {
kTextureFormatInfo,
kAllTextureFormats,
kCompressedTextureFormats,
kDepthStencilFormats,
kFeaturesForFormats,
filterFormatsByFeature,
textureDimensionAndFormatCompatible,
getBlockInfoForTextureFormat,
getBaseFormatForTextureFormat,
canCopyFromAllAspectsOfTextureFormat,
canCopyToAllAspectsOfTextureFormat,
ColorTextureFormat,
} from '../../../../format_info.js';
import { kResourceStates } from '../../../../gpu_test.js';
import { align, lcm } from '../../../../util/math.js';
import { ValidationTest } from '../../validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from '../../validation_test.js';

class F extends ValidationTest {
class F extends AllFeaturesMaxLimitsValidationTest {
TestCopyTextureToTexture(
source: GPUTexelCopyTextureInfo,
destination: GPUTexelCopyTextureInfo,
Expand Down Expand Up @@ -45,13 +47,11 @@ class F extends ValidationTest {
format: GPUTextureFormat,
mipLevel: number
): Required<GPUExtent3DDict> {
const { blockWidth, blockHeight } = getBlockInfoForTextureFormat(format);
const virtualWidthAtLevel = Math.max(textureSize.width >> mipLevel, 1);
const virtualHeightAtLevel = Math.max(textureSize.height >> mipLevel, 1);
const physicalWidthAtLevel = align(virtualWidthAtLevel, kTextureFormatInfo[format].blockWidth);
const physicalHeightAtLevel = align(
virtualHeightAtLevel,
kTextureFormatInfo[format].blockHeight
);
const physicalWidthAtLevel = align(virtualWidthAtLevel, blockWidth);
const physicalHeightAtLevel = align(virtualHeightAtLevel, blockHeight);

switch (dimension) {
case '1d':
Expand Down Expand Up @@ -358,28 +358,26 @@ Test the formats of textures in copyTextureToTexture must be copy-compatible.
)
.params(u =>
u
.combine('srcFormatFeature', kFeaturesForFormats)
.combine('dstFormatFeature', kFeaturesForFormats)
.beginSubcases()
.expand('srcFormat', ({ srcFormatFeature }) =>
filterFormatsByFeature(srcFormatFeature, kAllTextureFormats)
)
.expand('dstFormat', ({ dstFormatFeature }) =>
filterFormatsByFeature(dstFormatFeature, kAllTextureFormats)
)
.combine('srcFormat', kAllTextureFormats)
.filter(t => canCopyFromAllAspectsOfTextureFormat(t.srcFormat))
.combine('dstFormat', kAllTextureFormats)
.filter(t => canCopyToAllAspectsOfTextureFormat(t.dstFormat))
.filter(t => {
const srcInfo = getBlockInfoForTextureFormat(t.srcFormat);
const dstInfo = getBlockInfoForTextureFormat(t.dstFormat);
return (
srcInfo.blockWidth === dstInfo.blockWidth && srcInfo.blockHeight === dstInfo.blockHeight
);
})
)
.beforeAllSubcases(t => {
const { srcFormatFeature, dstFormatFeature } = t.params;
t.selectDeviceOrSkipTestCase([srcFormatFeature, dstFormatFeature]);
})
.fn(t => {
const { srcFormat, dstFormat } = t.params;

t.skipIfTextureFormatNotSupportedDeprecated(srcFormat, dstFormat);
t.skipIfCopyTextureToTextureNotSupportedForFormatDeprecated(srcFormat, dstFormat);
t.skipIfTextureFormatNotSupported(srcFormat, dstFormat);
t.skipIfCopyTextureToTextureNotSupportedForFormat(srcFormat, dstFormat);

const srcFormatInfo = kTextureFormatInfo[srcFormat];
const dstFormatInfo = kTextureFormatInfo[dstFormat];
const srcFormatInfo = getBlockInfoForTextureFormat(srcFormat);
const dstFormatInfo = getBlockInfoForTextureFormat(dstFormat);

const textureSize = {
width: lcm(srcFormatInfo.blockWidth, dstFormatInfo.blockWidth),
Expand All @@ -400,8 +398,10 @@ Test the formats of textures in copyTextureToTexture must be copy-compatible.
});

// Allow copy between compatible format textures.
const srcBaseFormat = kTextureFormatInfo[srcFormat].baseFormat ?? srcFormat;
const dstBaseFormat = kTextureFormatInfo[dstFormat].baseFormat ?? dstFormat;
const srcBaseFormat =
getBaseFormatForTextureFormat(srcFormat as ColorTextureFormat) ?? srcFormat;
const dstBaseFormat =
getBaseFormatForTextureFormat(dstFormat as ColorTextureFormat) ?? dstFormat;
const isSuccess = srcBaseFormat === dstBaseFormat;

t.TestCopyTextureToTexture(
Expand Down Expand Up @@ -448,13 +448,10 @@ Note: this is only tested for 2D textures as it is the only dimension compatible
.combine('srcCopyLevel', [1, 2])
.combine('dstCopyLevel', [0, 1])
)
.beforeAllSubcases(t => {
const { format } = t.params;
t.selectDeviceOrSkipTestCase(kTextureFormatInfo[format].feature);
})
.fn(t => {
const { format, copyBoxOffsets, srcTextureSize, dstTextureSize, srcCopyLevel, dstCopyLevel } =
t.params;
t.skipIfTextureFormatNotSupported(format);
const kMipLevelCount = 3;

const srcTexture = t.createTextureTracked({
Expand Down Expand Up @@ -704,12 +701,9 @@ Test the validations on the member 'aspect' of GPUTexelCopyTextureInfo in CopyTe
.combine('sourceAspect', ['all', 'depth-only', 'stencil-only'] as const)
.combine('destinationAspect', ['all', 'depth-only', 'stencil-only'] as const)
)
.beforeAllSubcases(t => {
const { format } = t.params;
t.selectDeviceOrSkipTestCase(kTextureFormatInfo[format].feature);
})
.fn(t => {
const { format, sourceAspect, destinationAspect } = t.params;
t.skipIfTextureFormatNotSupported(format);

const kTextureSize = { width: 16, height: 8, depthOrArrayLayers: 1 };

Expand Down Expand Up @@ -783,14 +777,13 @@ TODO: Express the offsets in "block size" so as to be able to test non-4x4 compr
.combine('srcCopyLevel', [0, 1, 2])
.combine('dstCopyLevel', [0, 1, 2])
)
.beforeAllSubcases(t => {
const { format } = t.params;
t.selectDeviceOrSkipTestCase(kTextureFormatInfo[format].feature);
t.skipIfCopyTextureToTextureNotSupportedForFormat(format);
})
.fn(t => {
const { format, dimension, copyBoxOffsets, srcCopyLevel, dstCopyLevel } = t.params;
const { blockWidth, blockHeight } = kTextureFormatInfo[format];

t.skipIfTextureFormatNotSupported(format);
t.skipIfCopyTextureToTextureNotSupportedForFormat(format);

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

const kTextureSize = {
width: 15 * blockWidth,
Expand Down Expand Up @@ -840,14 +833,11 @@ TODO: Express the offsets in "block size" so as to be able to test non-4x4 compr
const copyDepth =
kTextureSize.depthOrArrayLayers + copyBoxOffsets.depthOrArrayLayers - copyOrigin.z;

const texelBlockWidth = kTextureFormatInfo[format].blockWidth;
const texelBlockHeight = kTextureFormatInfo[format].blockHeight;

const isSuccessForCompressedFormats =
copyOrigin.x % texelBlockWidth === 0 &&
copyOrigin.y % texelBlockHeight === 0 &&
copyWidth % texelBlockWidth === 0 &&
copyHeight % texelBlockHeight === 0;
copyOrigin.x % blockWidth === 0 &&
copyOrigin.y % blockHeight === 0 &&
copyWidth % blockWidth === 0 &&
copyHeight % blockHeight === 0;

{
const isSuccess =
Expand Down
4 changes: 2 additions & 2 deletions src/webgpu/api/validation/encoding/cmds/debug.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ Test Coverage:

import { makeTestGroup } from '../../../../../common/framework/test_group.js';
import { kEncoderTypes } from '../../../../util/command_buffer_maker.js';
import { ValidationTest } from '../../validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from '../../validation_test.js';

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

g.test('debug_group_balanced')
.params(u =>
Expand Down
4 changes: 2 additions & 2 deletions src/webgpu/api/validation/encoding/cmds/index_access.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ Validation tests for indexed draws accessing the index buffer.
`;

import { makeTestGroup } from '../../../../../common/framework/test_group.js';
import { ValidationTest } from '../../validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from '../../validation_test.js';

class F extends ValidationTest {
class F extends AllFeaturesMaxLimitsValidationTest {
createIndexBuffer(indexData: Iterable<number>): GPUBuffer {
return this.makeBufferWithContents(new Uint32Array(indexData), GPUBufferUsage.INDEX);
}
Expand Down
8 changes: 4 additions & 4 deletions src/webgpu/api/validation/encoding/cmds/render/draw.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ and parameters as expect.
import { makeTestGroup } from '../../../../../../common/framework/test_group.js';
import { kVertexFormatInfo } from '../../../../../capability_info.js';
import { GPUTest } from '../../../../../gpu_test.js';
import { ValidationTest } from '../../../validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from '../../../validation_test.js';

type VertexAttrib<A> = A & { shaderLocation: number };
type VertexBuffer<V, A> = V & {
Expand Down Expand Up @@ -98,7 +98,7 @@ function callDraw(
}

function makeTestPipeline(
test: ValidationTest,
test: AllFeaturesMaxLimitsValidationTest,
buffers: VertexState<
{ stepMode: GPUVertexStepMode; arrayStride: number },
{
Expand Down Expand Up @@ -133,7 +133,7 @@ function makeTestPipeline(
}

function makeTestPipelineWithVertexAndInstanceBuffer(
test: ValidationTest,
test: AllFeaturesMaxLimitsValidationTest,
arrayStride: number,
attributeFormat: GPUVertexFormat,
attributeOffset: number = 0
Expand Down Expand Up @@ -190,7 +190,7 @@ const kDefaultParameterForIndexedDraw = {
indexBufferSize: 2 * 200, // exact required bound size for index buffer
};

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

g.test(`unused_buffer_bound`)
.desc(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ TODO: ensure existing tests cover these notes. Note many of these may be operati
import { makeTestGroup } from '../../../../../../common/framework/test_group.js';
import { MaxLimitsTestMixin } from '../../../../../gpu_test.js';
import { nextAfterF32 } from '../../../../../util/math.js';
import { ValidationTest } from '../../../validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from '../../../validation_test.js';

interface ViewportCall {
x: number;
Expand All @@ -43,7 +43,7 @@ interface ScissorCall {
h: number;
}

class F extends ValidationTest {
class F extends AllFeaturesMaxLimitsValidationTest {
testViewportCall(
success: boolean,
v: ViewportCall,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ Validation tests for drawIndirect/drawIndexedIndirect on render pass and render
import { makeTestGroup } from '../../../../../../common/framework/test_group.js';
import { GPUConst } from '../../../../../constants.js';
import { kResourceStates } from '../../../../../gpu_test.js';
import { ValidationTest } from '../../../validation_test.js';
import { AllFeaturesMaxLimitsValidationTest } from '../../../validation_test.js';

import { kRenderEncodeTypeParams } from './render.js';

const kIndirectDrawTestParams = kRenderEncodeTypeParams.combine('indexed', [true, false] as const);

class F extends ValidationTest {
class F extends AllFeaturesMaxLimitsValidationTest {
makeIndexBuffer(): GPUBuffer {
return this.createBufferTracked({
size: 16,
Expand Down
Loading