Skip to content

Commit

Permalink
Fix readTextureToTextureViews for multisampled textures
Browse files Browse the repository at this point in the history
I'm not sure when this bug was introduced. These tests 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.
  • Loading branch information
greggman committed Nov 19, 2024
1 parent 990c238 commit 1383d3f
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Tests for texture_utils.ts

import { makeTestGroup } from '../../../../../../common/framework/test_group.js';
import { assert } from '../../../../../../common/util/util.js';
import { isMultisampledTextureFormat, kDepthStencilFormats } from '../../../../../format_info.js';
import { GPUTest } from '../../../../../gpu_test.js';
import { getTextureDimensionFromView, virtualMipSize } from '../../../../../util/texture/base.js';
import {
Expand All @@ -16,6 +17,7 @@ import {
chooseTextureSize,
createTextureWithRandomDataAndGetTexels,
isSupportedViewFormatCombo,
makeRandomDepthComparisonTexelGenerator,
readTextureToTexelViews,
texelsApproximatelyEqual,
} from './texture_utils.js';
Expand All @@ -26,6 +28,41 @@ function texelFormat(texel: Readonly<PerTexelComponent<number>>, rep: TexelRepre
return rep.componentOrder.map(component => `${component}: ${texel[component]}`).join(', ');
}

g.test('createTextureWithRandomDataAndGetTexels_with_generator')
.desc(
`
Test createTextureWithRandomDataAndGetTexels with a generator. Generators
are only used with textureXXXCompare builtins as we need specific random
values to test these builtins with a depth reference value.
`
)
.params(u =>
u
.combine('format', kDepthStencilFormats)
.combine('viewDimension', ['2d', '2d-array', 'cube', 'cube-array'] as const)
.filter(t => isSupportedViewFormatCombo(t.format, t.viewDimension))
)
.beforeAllSubcases(t => {
t.skipIfTextureViewDimensionNotSupported(t.params.viewDimension);
t.selectDeviceForTextureFormatOrSkipTestCase(t.params.format);
})
.fn(async t => {
const { format, viewDimension } = t.params;
const size = chooseTextureSize({ minSize: 8, minBlocks: 4, format, viewDimension });
const descriptor: GPUTextureDescriptor = {
format,
dimension: getTextureDimensionFromView(viewDimension),
size,
mipLevelCount: 3,
usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING,
...(t.isCompatibility && { textureBindingViewDimension: viewDimension }),
};
await createTextureWithRandomDataAndGetTexels(t, descriptor, {
generator: makeRandomDepthComparisonTexelGenerator(descriptor, 'equal'),
});
// We don't expect any particular results. We just expect no validation errors.
});

g.test('readTextureToTexelViews')
.desc('test readTextureToTexelViews for various formats and dimensions')
.params(u =>
Expand All @@ -44,19 +81,26 @@ g.test('readTextureToTexelViews')
] as const)
.combine('viewDimension', ['1d', '2d', '2d-array', '3d', 'cube', 'cube-array'] as const)
.filter(t => isSupportedViewFormatCombo(t.srcFormat, t.viewDimension))
.combine('sampleCount', [1, 4] as const)
.unless(
t =>
t.sampleCount > 1 &&
(!isMultisampledTextureFormat(t.srcFormat) || t.viewDimension !== '2d')
)
)
.beforeAllSubcases(t => {
t.skipIfTextureViewDimensionNotSupported(t.params.viewDimension);
})
.fn(async t => {
const { srcFormat, texelViewFormat, viewDimension } = t.params;
const { srcFormat, texelViewFormat, viewDimension, sampleCount } = t.params;
const size = chooseTextureSize({ minSize: 8, minBlocks: 4, format: srcFormat, viewDimension });
const descriptor: GPUTextureDescriptor = {
format: srcFormat,
dimension: getTextureDimensionFromView(viewDimension),
size,
mipLevelCount: viewDimension === '1d' ? 1 : 3,
mipLevelCount: viewDimension === '1d' || sampleCount > 1 ? 1 : 3,
usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING,
sampleCount,
...(t.isCompatibility && { textureBindingViewDimension: viewDimension }),
};
const { texels: expectedTexelViews, texture } = await createTextureWithRandomDataAndGetTexels(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3031,11 +3031,14 @@ export async function readTextureToTexelViews(
}
`,
});
const sampleType = isDepthTextureFormat(texture.format)
? 'unfilterable-float'
: isStencilTextureFormat(texture.format)
const info = kTextureFormatInfo[texture.format];
const sampleType = info.depth
? 'unfilterable-float' // depth only supports unfilterable-float if not a comparison.
: info.stencil
? 'uint'
: kTextureFormatInfo[texture.format].color?.type ?? 'unfilterable-float';
: info.color.type === 'float'
? 'unfilterable-float'
: info.color.type;
const bindGroupLayout = device.createBindGroupLayout({
entries: [
{
Expand All @@ -3051,6 +3054,7 @@ export async function readTextureToTexelViews(
texture: {
sampleType,
viewDimension,
multisampled: texture.sampleCount > 1,
},
},
{
Expand Down Expand Up @@ -3169,7 +3173,7 @@ function createTextureFromTexelViewsLocal(
): GPUTexture {
const modifiedDescriptor = { ...desc };
// If it's a depth or stencil texture we need to render to it to fill it with data.
if (isDepthOrStencilTextureFormat(desc.format)) {
if (isDepthOrStencilTextureFormat(desc.format) || desc.sampleCount! > 1) {
modifiedDescriptor.usage = desc.usage | GPUTextureUsage.RENDER_ATTACHMENT;
}
return createTextureFromTexelViews(t, texelViews, modifiedDescriptor);
Expand Down

0 comments on commit 1383d3f

Please sign in to comment.