Skip to content

Commit b05a778

Browse files
authored
Check that createView format is compatible with the view usage. (#4495)
For example rgba8unorm -> rgba8unorm-srgb prevents using the storage usage on the created view.
1 parent 7c0a48e commit b05a778

File tree

1 file changed

+69
-24
lines changed

1 file changed

+69
-24
lines changed

src/webgpu/api/validation/createView.spec.ts

Lines changed: 69 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ import {
1717
filterFormatsByFeature,
1818
textureFormatsAreViewCompatible,
1919
isDepthTextureFormat,
20+
isTextureFormatUsableWithStorageAccessMode,
21+
isTextureFormatColorRenderable,
22+
isColorTextureFormat,
2023
isStencilTextureFormat,
2124
getBlockInfoForTextureFormat,
2225
isTextureFormatPossiblyUsableAsRenderAttachment,
@@ -345,53 +348,95 @@ g.test('texture_view_usage')
345348
.params(u =>
346349
u //
347350
.combine('format', kAllTextureFormats)
348-
.combine('textureUsage0', kTextureUsages)
349-
.combine('textureUsage1', kTextureUsages)
350-
.unless(({ format, textureUsage0, textureUsage1 }) => {
351-
const textureUsage = textureUsage0 | textureUsage1;
351+
.combine('textureUsage', kTextureUsages)
352+
.unless(({ format, textureUsage }) => {
352353
return (
353354
(textureUsage & GPUConst.TextureUsage.RENDER_ATTACHMENT) !== 0 &&
354355
!isTextureFormatPossiblyUsableAsRenderAttachment(format)
355356
);
356357
})
357358
.beginSubcases()
358-
.combine('textureViewUsage0', [0, ...kTextureUsages])
359-
.combine('textureViewUsage1', [0, ...kTextureUsages])
359+
.combine('textureViewUsage', [0, ...kTextureUsages])
360360
)
361361
.fn(t => {
362-
const { format, textureUsage0, textureUsage1, textureViewUsage0, textureViewUsage1 } = t.params;
362+
const { format, textureUsage, textureViewUsage } = t.params;
363363

364364
t.skipIfTextureFormatNotSupported(format);
365+
t.skipIfTextureFormatDoesNotSupportUsage(textureUsage, format);
365366

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

368-
const size = [blockWidth, blockHeight, 1];
369-
const dimension = '2d';
370-
const mipLevelCount = 1;
371-
const usage = textureUsage0 | textureUsage1;
369+
const texture = t.createTextureTracked({
370+
size: [blockWidth, blockHeight, 1],
371+
format,
372+
usage: textureUsage,
373+
});
372374

373-
t.skipIfTextureFormatDoesNotSupportUsage(usage, format);
375+
let success = true;
374376

375-
const textureDescriptor: GPUTextureDescriptor = {
376-
size,
377-
mipLevelCount,
378-
dimension,
379-
format,
380-
usage,
381-
};
377+
// Texture view usage must be a subset of texture usage
378+
if ((~textureUsage & textureViewUsage) !== 0) success = false;
382379

383-
const texture = t.createTextureTracked(textureDescriptor);
380+
t.expectValidationError(() => {
381+
texture.createView({
382+
usage: textureViewUsage,
383+
});
384+
}, !success);
385+
});
384386

385-
let success = true;
387+
g.test('texture_view_usage_with_view_format')
388+
.desc(
389+
`Test that the texture view usage must be supported by the view's format. Checks for every view format possible, and every usage supported by the texture's format`
390+
)
391+
.params(u =>
392+
u
393+
.combine('textureFormat', kAllTextureFormats)
394+
.combine('usage', kTextureUsages)
395+
.beginSubcases()
396+
.combine('viewFormat', kAllTextureFormats)
397+
)
398+
.fn(t => {
399+
const { textureFormat, viewFormat, usage } = t.params;
386400

387-
const textureViewUsage = textureViewUsage0 | textureViewUsage1;
401+
t.skipIfTextureFormatNotSupported(textureFormat, viewFormat);
402+
t.skipIfTextureFormatDoesNotSupportUsage(usage, textureFormat);
403+
404+
if (!textureFormatsAreViewCompatible(t.device, textureFormat, viewFormat)) {
405+
t.skip(`"${textureFormat}" and "${viewFormat}" are not view-compatible`);
406+
}
407+
408+
const { blockWidth, blockHeight } = getBlockInfoForTextureFormat(textureFormat);
409+
const texture = t.createTextureTracked({
410+
size: [blockWidth, blockHeight, 1],
411+
format: textureFormat,
412+
usage,
413+
viewFormats: [viewFormat],
414+
});
415+
416+
let success = true;
388417

389418
// Texture view usage must be a subset of texture usage
390-
if ((~usage & textureViewUsage) !== 0) success = false;
419+
if (usage & GPUTextureUsage.STORAGE_BINDING) {
420+
if (!isTextureFormatUsableWithStorageAccessMode(t.device, viewFormat, 'write-only'))
421+
success = false;
422+
}
423+
if (usage & GPUTextureUsage.RENDER_ATTACHMENT) {
424+
if (isColorTextureFormat(viewFormat) && !isTextureFormatColorRenderable(t.device, viewFormat))
425+
success = false;
426+
}
427+
428+
// Test with explicitly setting the view usage.
429+
t.expectValidationError(() => {
430+
texture.createView({
431+
usage,
432+
format: viewFormat,
433+
});
434+
}, !success);
391435

436+
// Test with inheriting the view usage.
392437
t.expectValidationError(() => {
393438
texture.createView({
394-
usage: textureViewUsage,
439+
format: viewFormat,
395440
});
396441
}, !success);
397442
});

0 commit comments

Comments
 (0)