Skip to content

Commit 003cb57

Browse files
greggmankainino0x
andauthored
Fix readTextureToTextureViews for multisampled textures (#4049)
* Fix readTextureToTextureViews for multisampled textures I'm not sure when this bug was introduced. These tests (textureLoad:multisampled) used to pass. Fixed the bug and added a test to hopefully find it quicker if it breaks in the future. Also added a test for createTextureWithRandomDataAndGetTexels with a generator. This was fixed in a previous PR without a a specific test as the fact that it failed other tests showed it needed fixing but I decided it's probably best to keep these tests too. * Update src/webgpu/shader/execution/expression/call/builtin/texture_utils.ts Co-authored-by: Kai Ninomiya <kainino1@gmail.com>
1 parent 990c238 commit 003cb57

2 files changed

Lines changed: 55 additions & 7 deletions

File tree

src/webgpu/shader/execution/expression/call/builtin/texture_utils.spec.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Tests for texture_utils.ts
44

55
import { makeTestGroup } from '../../../../../../common/framework/test_group.js';
66
import { assert } from '../../../../../../common/util/util.js';
7+
import { isMultisampledTextureFormat, kDepthStencilFormats } from '../../../../../format_info.js';
78
import { GPUTest } from '../../../../../gpu_test.js';
89
import { getTextureDimensionFromView, virtualMipSize } from '../../../../../util/texture/base.js';
910
import {
@@ -16,6 +17,7 @@ import {
1617
chooseTextureSize,
1718
createTextureWithRandomDataAndGetTexels,
1819
isSupportedViewFormatCombo,
20+
makeRandomDepthComparisonTexelGenerator,
1921
readTextureToTexelViews,
2022
texelsApproximatelyEqual,
2123
} from './texture_utils.js';
@@ -26,6 +28,41 @@ function texelFormat(texel: Readonly<PerTexelComponent<number>>, rep: TexelRepre
2628
return rep.componentOrder.map(component => `${component}: ${texel[component]}`).join(', ');
2729
}
2830

31+
g.test('createTextureWithRandomDataAndGetTexels_with_generator')
32+
.desc(
33+
`
34+
Test createTextureWithRandomDataAndGetTexels with a generator. Generators
35+
are only used with textureXXXCompare builtins as we need specific random
36+
values to test these builtins with a depth reference value.
37+
`
38+
)
39+
.params(u =>
40+
u
41+
.combine('format', kDepthStencilFormats)
42+
.combine('viewDimension', ['2d', '2d-array', 'cube', 'cube-array'] as const)
43+
.filter(t => isSupportedViewFormatCombo(t.format, t.viewDimension))
44+
)
45+
.beforeAllSubcases(t => {
46+
t.skipIfTextureViewDimensionNotSupported(t.params.viewDimension);
47+
t.selectDeviceForTextureFormatOrSkipTestCase(t.params.format);
48+
})
49+
.fn(async t => {
50+
const { format, viewDimension } = t.params;
51+
const size = chooseTextureSize({ minSize: 8, minBlocks: 4, format, viewDimension });
52+
const descriptor: GPUTextureDescriptor = {
53+
format,
54+
dimension: getTextureDimensionFromView(viewDimension),
55+
size,
56+
mipLevelCount: 3,
57+
usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING,
58+
...(t.isCompatibility && { textureBindingViewDimension: viewDimension }),
59+
};
60+
await createTextureWithRandomDataAndGetTexels(t, descriptor, {
61+
generator: makeRandomDepthComparisonTexelGenerator(descriptor, 'equal'),
62+
});
63+
// We don't expect any particular results. We just expect no validation errors.
64+
});
65+
2966
g.test('readTextureToTexelViews')
3067
.desc('test readTextureToTexelViews for various formats and dimensions')
3168
.params(u =>
@@ -44,19 +81,26 @@ g.test('readTextureToTexelViews')
4481
] as const)
4582
.combine('viewDimension', ['1d', '2d', '2d-array', '3d', 'cube', 'cube-array'] as const)
4683
.filter(t => isSupportedViewFormatCombo(t.srcFormat, t.viewDimension))
84+
.combine('sampleCount', [1, 4] as const)
85+
.unless(
86+
t =>
87+
t.sampleCount > 1 &&
88+
(!isMultisampledTextureFormat(t.srcFormat) || t.viewDimension !== '2d')
89+
)
4790
)
4891
.beforeAllSubcases(t => {
4992
t.skipIfTextureViewDimensionNotSupported(t.params.viewDimension);
5093
})
5194
.fn(async t => {
52-
const { srcFormat, texelViewFormat, viewDimension } = t.params;
95+
const { srcFormat, texelViewFormat, viewDimension, sampleCount } = t.params;
5396
const size = chooseTextureSize({ minSize: 8, minBlocks: 4, format: srcFormat, viewDimension });
5497
const descriptor: GPUTextureDescriptor = {
5598
format: srcFormat,
5699
dimension: getTextureDimensionFromView(viewDimension),
57100
size,
58-
mipLevelCount: viewDimension === '1d' ? 1 : 3,
101+
mipLevelCount: viewDimension === '1d' || sampleCount > 1 ? 1 : 3,
59102
usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING,
103+
sampleCount,
60104
...(t.isCompatibility && { textureBindingViewDimension: viewDimension }),
61105
};
62106
const { texels: expectedTexelViews, texture } = await createTextureWithRandomDataAndGetTexels(

src/webgpu/shader/execution/expression/call/builtin/texture_utils.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3031,11 +3031,14 @@ export async function readTextureToTexelViews(
30313031
}
30323032
`,
30333033
});
3034-
const sampleType = isDepthTextureFormat(texture.format)
3035-
? 'unfilterable-float'
3036-
: isStencilTextureFormat(texture.format)
3034+
const info = kTextureFormatInfo[texture.format];
3035+
const sampleType = info.depth
3036+
? 'unfilterable-float' // depth only supports unfilterable-float if not a comparison.
3037+
: info.stencil
30373038
? 'uint'
3038-
: kTextureFormatInfo[texture.format].color?.type ?? 'unfilterable-float';
3039+
: info.color.type === 'float'
3040+
? 'unfilterable-float'
3041+
: info.color.type;
30393042
const bindGroupLayout = device.createBindGroupLayout({
30403043
entries: [
30413044
{
@@ -3051,6 +3054,7 @@ export async function readTextureToTexelViews(
30513054
texture: {
30523055
sampleType,
30533056
viewDimension,
3057+
multisampled: texture.sampleCount > 1,
30543058
},
30553059
},
30563060
{
@@ -3169,7 +3173,7 @@ function createTextureFromTexelViewsLocal(
31693173
): GPUTexture {
31703174
const modifiedDescriptor = { ...desc };
31713175
// If it's a depth or stencil texture we need to render to it to fill it with data.
3172-
if (isDepthOrStencilTextureFormat(desc.format)) {
3176+
if (isDepthOrStencilTextureFormat(desc.format) || desc.sampleCount! > 1) {
31733177
modifiedDescriptor.usage = desc.usage | GPUTextureUsage.RENDER_ATTACHMENT;
31743178
}
31753179
return createTextureFromTexelViews(t, texelViews, modifiedDescriptor);

0 commit comments

Comments
 (0)