From 84fae1feb137891f37563965e0461ee98605b3e3 Mon Sep 17 00:00:00 2001 From: Greggman Date: Thu, 14 Dec 2023 08:09:05 +0900 Subject: [PATCH] Compat: Skip or expect error for rg32xxx texture formats (#3223) * Compat: Skip or expect error for rg32xxx texture formats rg32float, rg32sint, rg32uint texture formats don't support storage texture usage in compat mode. --- src/webgpu/api/validation/createBindGroup.spec.ts | 4 ++++ .../api/validation/createBindGroupLayout.spec.ts | 1 + src/webgpu/api/validation/createTexture.spec.ts | 13 +++++++++++-- src/webgpu/format_info.ts | 15 +++++++++++++++ src/webgpu/gpu_test.ts | 9 +++++++++ 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/webgpu/api/validation/createBindGroup.spec.ts b/src/webgpu/api/validation/createBindGroup.spec.ts index 75a545aeb5ee..2c3eecc29503 100644 --- a/src/webgpu/api/validation/createBindGroup.spec.ts +++ b/src/webgpu/api/validation/createBindGroup.spec.ts @@ -815,6 +815,10 @@ g.test('storage_texture,format') .combine('storageTextureFormat', kStorageTextureFormats) .combine('resourceFormat', kStorageTextureFormats) ) + .beforeAllSubcases(t => { + const { resourceFormat } = t.params; + t.skipIfTextureFormatNotUsableAsStorageTexture(resourceFormat); + }) .fn(t => { const { storageTextureFormat, resourceFormat } = t.params; diff --git a/src/webgpu/api/validation/createBindGroupLayout.spec.ts b/src/webgpu/api/validation/createBindGroupLayout.spec.ts index 0db9f438763b..b09adc2af187 100644 --- a/src/webgpu/api/validation/createBindGroupLayout.spec.ts +++ b/src/webgpu/api/validation/createBindGroupLayout.spec.ts @@ -450,6 +450,7 @@ g.test('storage_texture,formats') ) .beforeAllSubcases(t => { t.selectDeviceForTextureFormatOrSkipTestCase(t.params.format); + t.skipIfTextureFormatNotUsableAsStorageTexture(t.params.format); }) .fn(t => { const { format, access } = t.params; diff --git a/src/webgpu/api/validation/createTexture.spec.ts b/src/webgpu/api/validation/createTexture.spec.ts index 1b2041682446..cede60821d0c 100644 --- a/src/webgpu/api/validation/createTexture.spec.ts +++ b/src/webgpu/api/validation/createTexture.spec.ts @@ -15,6 +15,7 @@ import { filterFormatsByFeature, viewCompatible, textureDimensionAndFormatCompatible, + isTextureFormatUsableAsStorageFormat, } from '../../format_info.js'; import { maxMipLevelCount } from '../../util/texture/base.js'; @@ -372,8 +373,12 @@ g.test('sampleCount,valid_sampleCount_with_other_parameter_varies') usage, }; + const satisfyWithStorageUsageRequirement = + (usage & GPUConst.TextureUsage.STORAGE_BINDING) === 0 || + isTextureFormatUsableAsStorageFormat(format, t.isCompatibility); + const success = - sampleCount === 1 || + (sampleCount === 1 && satisfyWithStorageUsageRequirement) || (sampleCount === 4 && (dimension === '2d' || dimension === undefined) && kTextureFormatInfo[format].multisample && @@ -1058,7 +1063,11 @@ g.test('texture_usage') // Note that we unconditionally test copy usages for all formats. We don't check copySrc/copyDst in kTextureFormatInfo in capability_info.js // if (!info.copySrc && (usage & GPUTextureUsage.COPY_SRC) !== 0) success = false; // if (!info.copyDst && (usage & GPUTextureUsage.COPY_DST) !== 0) success = false; - if (!info.color?.storage && (usage & GPUTextureUsage.STORAGE_BINDING) !== 0) success = false; + if ( + (usage & GPUTextureUsage.STORAGE_BINDING) !== 0 && + !isTextureFormatUsableAsStorageFormat(format, t.isCompatibility) + ) + success = false; if ( (!info.renderable || (appliedDimension !== '2d' && appliedDimension !== '3d')) && (usage & GPUTextureUsage.RENDER_ATTACHMENT) !== 0 diff --git a/src/webgpu/format_info.ts b/src/webgpu/format_info.ts index 3fd2f0b3fc82..b8de86bb0c8b 100644 --- a/src/webgpu/format_info.ts +++ b/src/webgpu/format_info.ts @@ -1931,6 +1931,21 @@ export function isCompressedTextureFormat(format: GPUTextureFormat) { return format in kCompressedTextureFormatInfo; } +export function isTextureFormatUsableAsStorageFormat( + format: GPUTextureFormat, + isCompatibilityMode: boolean +) { + if (isCompatibilityMode) { + switch (format) { + case 'rg32float': + case 'rg32sint': + case 'rg32uint': + return false; + } + } + return !!kTextureFormatInfo[format].color?.storage; +} + export function isEncodableTextureformat(format: GPUTextureFormat) { return format in kEncodableTextureFormatInfo; } diff --git a/src/webgpu/gpu_test.ts b/src/webgpu/gpu_test.ts index 53b9668c667b..2c1a29a3dabf 100644 --- a/src/webgpu/gpu_test.ts +++ b/src/webgpu/gpu_test.ts @@ -35,6 +35,7 @@ import { EncodableTextureFormat, isCompressedTextureFormat, ColorTextureFormat, + isTextureFormatUsableAsStorageFormat, } from './format_info.js'; import { makeBufferWithContents } from './util/buffer.js'; import { checkElementsEqual, checkElementsBetween } from './util/check_contents.js'; @@ -251,6 +252,14 @@ export class GPUTestSubcaseBatchState extends SubcaseBatchState { } } } + + skipIfTextureFormatNotUsableAsStorageTexture(...formats: (GPUTextureFormat | undefined)[]) { + for (const format of formats) { + if (format && !isTextureFormatUsableAsStorageFormat(format, this.isCompatibility)) { + this.skip(`Texture with ${format} is not usable as a storage texture`); + } + } + } } /**