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

Compat: fix float16(32)-renderable tests (validation) #4152

Merged
merged 5 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ import {
} from './limit_utils.js';

const kFormatsToUseBySize: GPUTextureFormat[] = [
'rgba32float',
'rgba16float',
'rgba32uint',
'rgba16uint',
'rgba8unorm',
'rg8unorm',
'r8unorm',
];

const kInterleaveFormats: GPUTextureFormat[] = [
'rgba16float',
'rg16float',
'rgba16uint',
'rg16uint',
'rgba8unorm',
'rg8unorm',
'r8unorm',
Expand Down
18 changes: 14 additions & 4 deletions src/webgpu/api/validation/createBindGroup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import { getTextureDimensionFromView } from '../../util/texture/base.js';

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

const kTestFormat: GPUTextureFormat = 'r32float';

function clone<T extends GPUTextureDescriptor>(descriptor: T): T {
return JSON.parse(JSON.stringify(descriptor));
}
Expand Down Expand Up @@ -144,7 +146,7 @@ g.test('binding_must_contain_resource_defined_in_layout')
.params(u =>
u //
.combine('resourceType', kBindableResources)
.combine('entry', allBindingEntries(false))
.combine('entry', allBindingEntries(false, kTestFormat))
)
.fn(t => {
const { resourceType, entry } = t.params;
Expand Down Expand Up @@ -195,18 +197,26 @@ g.test('texture_binding_must_have_correct_usage')
.desc('Tests that texture bindings must have the correct usage.')
.paramsSubcasesOnly(u =>
u //
.combine('entry', sampledAndStorageBindingEntries(false))
.combine('entry', sampledAndStorageBindingEntries(false, kTestFormat))
.combine('usage', kTextureUsages)
.unless(({ entry, usage }) => {
const info = texBindingTypeInfo(entry);
// Can't create the texture for this (usage=STORAGE_BINDING and sampleCount=4), so skip.
return usage === GPUConst.TextureUsage.STORAGE_BINDING && info.resource === 'sampledTexMS';
})
)
.beforeAllSubcases(t => {
t.selectDeviceForRenderableColorFormatOrSkipTestCase(kTestFormat);
})
.fn(t => {
const { entry, usage } = t.params;
const info = texBindingTypeInfo(entry);

t.skipIf(
t.isCompatibility && info.resource === 'sampledTexMS',
"The test requires 'r32float' multisampled support which compat mode doesn't guarantee."
);

const bindGroupLayout = t.device.createBindGroupLayout({
entries: [{ binding: 0, visibility: GPUShaderStage.COMPUTE, ...entry }],
});
Expand All @@ -217,7 +227,7 @@ g.test('texture_binding_must_have_correct_usage')

const descriptor = {
size: { width: 16, height: 16, depthOrArrayLayers: 1 },
format: 'r32float' as const,
format: kTestFormat,
usage: appliedUsage,
sampleCount: info.resource === 'sampledTexMS' ? 4 : 1,
};
Expand Down Expand Up @@ -601,7 +611,7 @@ g.test('texture,resource_state')
.paramsSubcasesOnly(u =>
u
.combine('state', kResourceStates)
.combine('entry', sampledAndStorageBindingEntries(true))
.combine('entry', sampledAndStorageBindingEntries(true, kTestFormat))
.combine('visibilityMask', [kAllShaderStages, GPUConst.ShaderStage.COMPUTE] as const)
)
.fn(t => {
Expand Down
6 changes: 6 additions & 0 deletions src/webgpu/api/validation/createTexture.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,11 +355,16 @@ g.test('sampleCount,valid_sampleCount_with_other_parameter_varies')
const info = kTextureFormatInfo[format];
t.skipIfTextureFormatNotSupported(format);
t.selectDeviceOrSkipTestCase(info.feature);
t.selectDeviceForRenderableColorFormatOrSkipTestCase(format);
})
.fn(t => {
const { dimension, sampleCount, format, mipLevelCount, arrayLayerCount, usage } = t.params;
const { blockWidth, blockHeight } = kTextureFormatInfo[format];

if (sampleCount > 1) {
t.skipIfMultisampleNotSupportedForFormat(format);
}

const size =
dimension === '1d'
? [32 * blockWidth, 1 * blockHeight, 1]
Expand Down Expand Up @@ -1047,6 +1052,7 @@ g.test('texture_usage')
const info = kTextureFormatInfo[format];
t.skipIfTextureFormatNotSupported(format);
t.selectDeviceOrSkipTestCase(info.feature);
t.selectDeviceForRenderableColorFormatOrSkipTestCase(format);
})
.fn(t => {
const { dimension, format, usage0, usage1 } = t.params;
Expand Down
3 changes: 3 additions & 0 deletions src/webgpu/api/validation/createView.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@ g.test('texture_view_usage')
if (textureUsage & GPUTextureUsage.STORAGE_BINDING) {
t.skipIfTextureFormatNotUsableAsStorageTexture(format);
}
if (textureUsage & GPUTextureUsage.RENDER_ATTACHMENT) {
t.selectDeviceForRenderableColorFormatOrSkipTestCase(format);
}
})
.fn(t => {
const { format, textureUsage0, textureUsage1, textureViewUsage0, textureViewUsage1 } = t.params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ g.test('attachment_state,limits,maxColorAttachmentBytesPerSample,aligned')
)
.beforeAllSubcases(t => {
t.skipIfTextureFormatNotSupported(t.params.format);
t.selectDeviceForRenderableColorFormatOrSkipTestCase(t.params.format);
})
.fn(t => {
const { format, colorFormatCount } = t.params;
Expand Down Expand Up @@ -118,6 +119,9 @@ g.test('attachment_state,limits,maxColorAttachmentBytesPerSample,unaligned')
},
])
)
.beforeAllSubcases(t => {
t.selectDeviceForRenderableColorFormatOrSkipTestCase('r32float');
})
.fn(t => {
const { formats } = t.params;

Expand Down Expand Up @@ -168,6 +172,7 @@ g.test('valid_texture_formats')
.beforeAllSubcases(t => {
const { format } = t.params;
t.selectDeviceForTextureFormatOrSkipTestCase(format);
t.selectDeviceForRenderableColorFormatOrSkipTestCase(format);
})
.fn(t => {
const { format, attachment } = t.params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,7 @@ g.test('destination_texture,format')
const { format } = t.params;
t.skipIfTextureFormatNotSupported(format);
t.selectDeviceOrSkipTestCase(kTextureFormatInfo[format].feature);
t.selectDeviceForRenderableColorFormatOrSkipTestCase(format);
})
.fn(async t => {
const { format, copySize } = t.params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
kTextureFormatInfo,
filterFormatsByFeature,
getFeaturesForFormats,
is16Float,
is32Float,
} from '../../../format_info.js';
import { ValidationTest } from '../validation_test.js';

Expand Down Expand Up @@ -182,6 +184,14 @@ g.test('render_pass_and_bundle,color_format')
const { passFormat, bundleFormat } = t.params;

t.skipIfTextureFormatNotSupported(passFormat, bundleFormat);
// float16 and float32 might miss color renderablity under compat mode
t.skipIf(
shrekshao marked this conversation as resolved.
Show resolved Hide resolved
t.isCompatibility &&
(is16Float(passFormat) ||
is32Float(passFormat) ||
is16Float(bundleFormat) ||
is32Float(bundleFormat))
);

const bundleEncoder = t.device.createRenderBundleEncoder({
colorFormats: [bundleFormat],
Expand Down Expand Up @@ -358,7 +368,7 @@ g.test('render_pass_and_bundle,device_mismatch')
const { mismatched } = t.params;
const sourceDevice = mismatched ? t.mismatchedDevice : t.device;

const format = 'r16float';
const format = 'r16uint';
const bundleEncoder = sourceDevice.createRenderBundleEncoder({
colorFormats: [format],
});
Expand Down Expand Up @@ -390,6 +400,14 @@ Test that color attachment formats in render passes or bundles match the pipelin
const { encoderType, encoderFormat, pipelineFormat } = t.params;

t.skipIfTextureFormatNotSupported(encoderFormat, pipelineFormat);
// float16 and float32 might miss color renderablity under compat mode
shrekshao marked this conversation as resolved.
Show resolved Hide resolved
t.skipIf(
t.isCompatibility &&
(is16Float(encoderFormat) ||
is32Float(encoderFormat) ||
is16Float(pipelineFormat) ||
is32Float(pipelineFormat))
);

const pipeline = t.createRenderPipeline([{ format: pipelineFormat, writeMask: 0 }]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ g.test('color_attachments,limits,maxColorAttachmentBytesPerSample,aligned')
)
.beforeAllSubcases(t => {
t.skipIfTextureFormatNotSupported(t.params.format);
t.selectDeviceForRenderableColorFormatOrSkipTestCase(t.params.format);
})
.fn(t => {
const { format, attachmentCount } = t.params;
Expand Down Expand Up @@ -267,6 +268,9 @@ g.test('color_attachments,limits,maxColorAttachmentBytesPerSample,unaligned')
},
])
)
.beforeAllSubcases(t => {
t.selectDeviceForRenderableColorFormatOrSkipTestCase('r32float');
})
.fn(t => {
const { formats } = t.params;

Expand Down Expand Up @@ -1168,7 +1172,10 @@ g.test('resolveTarget,format_supports_resolve')
.filter(t => kTextureFormatInfo[t.format].multisample)
)
.beforeAllSubcases(t => {
t.skipIfTextureFormatNotSupported(t.params.format);
const { format } = t.params;
t.skipIfTextureFormatNotSupported(format);
t.skipIfMultisampleNotSupportedForFormat(format);
t.selectDeviceForRenderableColorFormatOrSkipTestCase(format);
})
.fn(t => {
const { format } = t.params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pipeline that uses blending with any float32-format attachment.
if (t.params.enabled) {
t.selectDeviceOrSkipTestCase('float32-blendable');
}
t.selectDeviceForRenderableColorFormatOrSkipTestCase('r32float');
})
.fn(t => {
const { isAsync, enabled, hasBlend, format } = t.params;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ g.test('limits,maxColorAttachmentBytesPerSample,aligned')
)
.beforeAllSubcases(t => {
t.skipIfTextureFormatNotSupported(t.params.format);
t.selectDeviceForRenderableColorFormatOrSkipTestCase(t.params.format);
})
.fn(t => {
const { format, attachmentCount, isAsync } = t.params;
Expand Down Expand Up @@ -228,6 +229,9 @@ g.test('limits,maxColorAttachmentBytesPerSample,unaligned')
.beginSubcases()
.combine('isAsync', [false, true])
)
.beforeAllSubcases(t => {
t.selectDeviceForRenderableColorFormatOrSkipTestCase('r32float');
})
.fn(t => {
const { formats, isAsync } = t.params;

Expand Down Expand Up @@ -394,6 +398,7 @@ g.test('pipeline_output_targets')
)
.beforeAllSubcases(t => {
t.selectDeviceForTextureFormatOrSkipTestCase(t.params.format);
t.selectDeviceForRenderableColorFormatOrSkipTestCase(t.params.format);
})
.fn(t => {
const { isAsync, format, writeMask, shaderOutput } = t.params;
Expand Down
25 changes: 17 additions & 8 deletions src/webgpu/capability_info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,16 +592,22 @@ export function textureBindingEntries(includeUndefined: boolean): readonly BGLEn
*
* Note: Generates different `access` options, but not `format` or `viewDimension` options.
*/
export function storageTextureBindingEntries(): readonly BGLEntry[] {
export function storageTextureBindingEntries(format: GPUTextureFormat): readonly BGLEntry[] {
return [
{ storageTexture: { access: 'write-only', format: 'r32float' } },
{ storageTexture: { access: 'read-only', format: 'r32float' } },
{ storageTexture: { access: 'read-write', format: 'r32float' } },
{ storageTexture: { access: 'write-only', format } },
{ storageTexture: { access: 'read-only', format } },
{ storageTexture: { access: 'read-write', format } },
] as const;
}
/** Generate a list of possible texture-or-storageTexture-typed BGLEntry values. */
export function sampledAndStorageBindingEntries(includeUndefined: boolean): readonly BGLEntry[] {
return [...textureBindingEntries(includeUndefined), ...storageTextureBindingEntries()] as const;
export function sampledAndStorageBindingEntries(
includeUndefined: boolean,
format: GPUTextureFormat = 'r32float'
): readonly BGLEntry[] {
return [
...textureBindingEntries(includeUndefined),
...storageTextureBindingEntries(format),
] as const;
}
/**
* Generate a list of possible BGLEntry values of every type, but not variants with different:
Expand All @@ -610,11 +616,14 @@ export function sampledAndStorageBindingEntries(includeUndefined: boolean): read
* - texture.viewDimension
* - storageTexture.viewDimension
*/
export function allBindingEntries(includeUndefined: boolean): readonly BGLEntry[] {
export function allBindingEntries(
includeUndefined: boolean,
format: GPUTextureFormat = 'r32float'
): readonly BGLEntry[] {
return [
...bufferBindingEntries(includeUndefined),
...samplerBindingEntries(includeUndefined),
...sampledAndStorageBindingEntries(includeUndefined),
...sampledAndStorageBindingEntries(includeUndefined, format),
] as const;
}

Expand Down
41 changes: 41 additions & 0 deletions src/webgpu/gpu_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
isTextureFormatUsableAsStorageFormat,
is32Float,
is16Float,
isMultisampledTextureFormat,
} 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 @@ -288,6 +289,26 @@ export class GPUTestSubcaseBatchState extends SubcaseBatchState {
}
}

skipIfMultisampleNotSupportedForFormat(...formats: (GPUTextureFormat | undefined)[]) {
if (this.isCompatibility) {
for (const format of formats) {
if (format === undefined) continue;
if (format === 'rgba16float' || is32Float(format)) {
this.skip(
`texture format '${format} is not guaranteed to be multisampled support in compat mode`
);
}
}
}

for (const format of formats) {
if (format === undefined) continue;
if (!isMultisampledTextureFormat(format)) {
this.skip(`texture format '${format} is not supported to be multisampled`);
}
}
}

getFloatTextureFormatColorRenderableFeatures(...formats: (GPUTextureFormat | undefined)[]) {
const requiredFeatures: GPUFeatureName[] = [];
if (this.isCompatibility) {
Expand Down Expand Up @@ -543,6 +564,26 @@ export class GPUTestBase extends Fixture<GPUTestSubcaseBatchState> {
}
}

skipIfMultisampleNotSupportedForFormat(...formats: (GPUTextureFormat | undefined)[]) {
if (this.isCompatibility) {
for (const format of formats) {
if (format === undefined) continue;
if (format === 'rgba16float' || is32Float(format)) {
this.skip(
`texture format '${format} is not guaranteed to be multisampled support in compat mode`
);
}
}
}

for (const format of formats) {
if (format === undefined) continue;
if (!isMultisampledTextureFormat(format)) {
this.skip(`texture format '${format} is not supported to be multisampled`);
}
}
}

skipIfTextureViewDimensionNotSupported(...dimensions: (GPUTextureViewDimension | undefined)[]) {
if (this.isCompatibility) {
for (const dimension of dimensions) {
Expand Down
Loading