Skip to content

Commit 85678b2

Browse files
authored
Compat: fix rgXXX format as storage texture issues (#3805)
Spec changed so that usage of rgXXX format textures as storage textures should generate a shader module creation error.
1 parent 9f1f6db commit 85678b2

File tree

10 files changed

+27
-10
lines changed

10 files changed

+27
-10
lines changed

src/webgpu/format_info.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,13 +1782,14 @@ export const kCompatModeUnsupportedStorageTextureFormats: readonly GPUTextureFor
17821782
export function isTextureFormatUsableAsStorageFormat(
17831783
format: GPUTextureFormat,
17841784
isCompatibilityMode: boolean
1785-
) {
1785+
): boolean {
17861786
if (isCompatibilityMode) {
17871787
if (kCompatModeUnsupportedStorageTextureFormats.indexOf(format) >= 0) {
17881788
return false;
17891789
}
17901790
}
1791-
return !!kTextureFormatInfo[format].color?.storage;
1791+
const info = kTextureFormatInfo[format];
1792+
return !!(info.color?.storage || info.depth?.storage || info.stencil?.storage);
17921793
}
17931794

17941795
export function isRegularTextureFormat(format: GPUTextureFormat) {

src/webgpu/gpu_test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,14 @@ export class GPUTestBase extends Fixture<GPUTestSubcaseBatchState> {
491491
}
492492
}
493493

494+
skipIfTextureFormatNotUsableAsStorageTexture(...formats: (GPUTextureFormat | undefined)[]) {
495+
for (const format of formats) {
496+
if (format && !isTextureFormatUsableAsStorageFormat(format, this.isCompatibility)) {
497+
this.skip(`Texture with ${format} is not usable as a storage texture`);
498+
}
499+
}
500+
}
501+
494502
/** Skips this test case if the `langFeature` is *not* supported. */
495503
skipIfLanguageFeatureNotSupported(langFeature: WGSLLanguageFeature) {
496504
if (!this.hasLanguageFeature(langFeature)) {

src/webgpu/shader/validation/expression/call/builtin/textureDimensions.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ Validates the return type of ${builtin} is the expected type.
162162
)
163163
.fn(t => {
164164
const { returnType, textureType, format } = t.params;
165+
t.skipIfTextureFormatNotUsableAsStorageTexture(format);
166+
165167
const returnVarType = kValuesTypes[returnType];
166168
const { returnType: returnRequiredType, hasLevelArg } =
167169
kValidTextureDimensionParameterTypesForStorageTextures[textureType];

src/webgpu/shader/validation/expression/call/builtin/textureLoad.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ Validates that only incorrect coords arguments are rejected by ${builtin}
210210
)
211211
.fn(t => {
212212
const { textureType, coordType, format, value } = t.params;
213+
t.skipIfTextureFormatNotUsableAsStorageTexture(format);
214+
213215
const coordArgType = kValuesTypes[coordType];
214216
const { coordsArgTypes, hasArrayIndexArg } =
215217
kValidTextureLoadParameterTypesForStorageTextures[textureType];
@@ -307,6 +309,8 @@ Validates that only incorrect array_index arguments are rejected by ${builtin}
307309
)
308310
.fn(t => {
309311
const { textureType, arrayIndexType, format, value } = t.params;
312+
t.skipIfTextureFormatNotUsableAsStorageTexture(format);
313+
310314
const arrayIndexArgType = kValuesTypes[arrayIndexType];
311315
const args = [arrayIndexArgType.create(value)];
312316
const { coordsArgTypes, hasLevelArg } =

src/webgpu/shader/validation/expression/call/builtin/textureNumLayers.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ Validates the return type of ${builtin} is the expected type.
8989
)
9090
.fn(t => {
9191
const { returnType, textureType, format } = t.params;
92+
t.skipIfTextureFormatNotUsableAsStorageTexture(format);
93+
9294
const returnVarType = kValuesTypes[returnType];
9395

9496
const varWGSL = returnVarType.toString();

src/webgpu/shader/validation/expression/call/builtin/textureStore.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ Validates that only incorrect value arguments are rejected by ${builtin}
152152
)
153153
.fn(t => {
154154
const { textureType, valueType, format, value } = t.params;
155+
t.skipIfTextureFormatNotUsableAsStorageTexture(format);
156+
155157
const valueArgType = kValuesTypes[valueType];
156158
const args = [valueArgType.create(value)];
157159
const { coordsArgTypes, hasArrayIndexArg } = kValidTextureStoreParameterTypes[textureType];

src/webgpu/shader/validation/extension/readonly_and_readwrite_storage_textures.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ g.test('var_decl')
2727
)
2828
.fn(t => {
2929
const { type, format, access } = t.params;
30+
t.skipIfTextureFormatNotUsableAsStorageTexture(format.format);
31+
3032
const source = `@group(0) @binding(0) var t : ${type}<${format.format}, ${access}>;`;
3133
const requiresFeature = access !== 'write';
3234
t.expectCompileResult(t.hasLanguageFeature(kFeatureName) || !requiresFeature, source);

src/webgpu/shader/validation/shader_io/util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export const kResourceEmitters = new Map<string, ResourceDeclarationEmitter>([
111111
['texture_storage_1d', basicEmitter('texture_storage_1d<rgba8unorm, write>')],
112112
['texture_storage_2d', basicEmitter('texture_storage_2d<rgba8sint, write>')],
113113
['texture_storage_2d_array', basicEmitter('texture_storage_2d_array<r32uint, write>')],
114-
['texture_storage_3d', basicEmitter('texture_storage_3d<rg32uint, write>')],
114+
['texture_storage_3d', basicEmitter('texture_storage_3d<rgba32uint, write>')],
115115
['texture_depth_2d', basicEmitter('texture_depth_2d')],
116116
['texture_depth_2d_array', basicEmitter('texture_depth_2d_array')],
117117
['texture_depth_cube', basicEmitter('texture_depth_cube')],

src/webgpu/shader/validation/types/alias.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ const kTypes = [
171171
'texture_storage_1d<r32sint, read_write>',
172172
'texture_storage_1d<r32float, read>',
173173
'texture_storage_2d<rgba16uint, write>',
174-
'texture_storage_2d_array<rg32float, write>',
174+
'texture_storage_2d_array<rgba32float, write>',
175175
'texture_storage_3d<bgra8unorm, write>',
176176
'texture_depth_2d',
177177
'texture_depth_2d_array',

src/webgpu/shader/validation/types/textures.spec.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ g.test('sampled_texture_types')
9191

9292
g.test('external_sampled_texture_types')
9393
.desc(
94-
`Test that texture_extenal compiles and cannot specify address space
94+
`Test that texture_external compiles and cannot specify address space
9595
`
9696
)
9797
.fn(t => {
@@ -118,13 +118,9 @@ Besides, the shader compilation should always pass regardless of whether the for
118118
)
119119
.fn(t => {
120120
const { format, access, comma } = t.params;
121-
const info = kTextureFormatInfo[format];
122121
// bgra8unorm is considered a valid storage format at shader compilation stage
123122
const isFormatValid =
124-
info.color?.storage ||
125-
info.depth?.storage ||
126-
info.stencil?.storage ||
127-
format === 'bgra8unorm';
123+
isTextureFormatUsableAsStorageFormat(format, t.isCompatibility) || format === 'bgra8unorm';
128124
const isAccessValid = kAccessModes.includes(access);
129125
const wgsl = `@group(0) @binding(0) var tex: texture_storage_2d<${format}, ${access}${comma}>;`;
130126
t.expectCompileResult(isFormatValid && isAccessValid, wgsl);

0 commit comments

Comments
 (0)