Skip to content

Commit 6f9a52d

Browse files
committed
Compat: make expectTexturesToMatchByRendering work with compat
With the new textureBindingViewDimension requirements this pipeline has to use texture_2d_array for 2d_array textures.
1 parent d30a01d commit 6f9a52d

File tree

1 file changed

+57
-11
lines changed

1 file changed

+57
-11
lines changed

src/webgpu/gpu_test.ts

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,24 +1237,44 @@ export interface TextureTestMixinType {
12371237
): Generator<Required<GPUOrigin3DDict>>;
12381238
}
12391239

1240+
type PipelineType = '2d' | '2d-array';
1241+
12401242
type ImageCopyTestResources = {
1241-
pipeline: GPURenderPipeline;
1243+
pipelineByPipelineType: Map<PipelineType, GPURenderPipeline>;
12421244
};
12431245

12441246
const s_deviceToResourcesMap = new WeakMap<GPUDevice, ImageCopyTestResources>();
12451247

12461248
/**
12471249
* Gets a (cached) pipeline to render a texture to an rgba8unorm texture
12481250
*/
1249-
function getPipelineToRenderTextureToRGB8UnormTexture(device: GPUDevice) {
1251+
function getPipelineToRenderTextureToRGB8UnormTexture(
1252+
device: GPUDevice,
1253+
texture: GPUTexture,
1254+
isCompatibility: boolean
1255+
) {
12501256
if (!s_deviceToResourcesMap.has(device)) {
1257+
s_deviceToResourcesMap.set(device, {
1258+
pipelineByPipelineType: new Map<PipelineType, GPURenderPipeline>(),
1259+
});
1260+
}
1261+
1262+
const { pipelineByPipelineType } = s_deviceToResourcesMap.get(device)!;
1263+
const pipelineType = isCompatibility && texture.depthOrArrayLayers > 1 ? '2d-array' : '2d';
1264+
if (!pipelineByPipelineType.get(pipelineType)) {
1265+
const [textureType, layerCode] =
1266+
pipelineType === '2d' ? ['texture_2d', ''] : ['texture_2d_array', ', uni.baseArrayLayer'];
12511267
const module = device.createShaderModule({
12521268
code: `
12531269
struct VSOutput {
12541270
@builtin(position) position: vec4f,
12551271
@location(0) texcoord: vec2f,
12561272
};
12571273
1274+
struct Uniforms {
1275+
baseArrayLayer: u32,
1276+
};
1277+
12581278
@vertex fn vs(
12591279
@builtin(vertex_index) vertexIndex : u32
12601280
) -> VSOutput {
@@ -1275,10 +1295,11 @@ function getPipelineToRenderTextureToRGB8UnormTexture(device: GPUDevice) {
12751295
}
12761296
12771297
@group(0) @binding(0) var ourSampler: sampler;
1278-
@group(0) @binding(1) var ourTexture: texture_2d<f32>;
1298+
@group(0) @binding(1) var ourTexture: ${textureType}<f32>;
1299+
@group(0) @binding(2) var<uniform> uni: Uniforms;
12791300
12801301
@fragment fn fs(fsInput: VSOutput) -> @location(0) vec4f {
1281-
return textureSample(ourTexture, ourSampler, fsInput.texcoord);
1302+
return textureSample(ourTexture, ourSampler, fsInput.texcoord${layerCode});
12821303
}
12831304
`,
12841305
});
@@ -1294,10 +1315,10 @@ function getPipelineToRenderTextureToRGB8UnormTexture(device: GPUDevice) {
12941315
targets: [{ format: 'rgba8unorm' }],
12951316
},
12961317
});
1297-
s_deviceToResourcesMap.set(device, { pipeline });
1318+
pipelineByPipelineType.set(pipelineType, pipeline);
12981319
}
1299-
const { pipeline } = s_deviceToResourcesMap.get(device)!;
1300-
return pipeline;
1320+
const pipeline = pipelineByPipelineType.get(pipelineType)!;
1321+
return { pipelineType, pipeline };
13011322
}
13021323

13031324
type LinearCopyParameters = {
@@ -1441,7 +1462,11 @@ export function TextureTestMixin<F extends FixtureClass<GPUTest>>(
14411462
// Render every layer of both textures at mipLevel to an rgba8unorm texture
14421463
// that matches the size of the mipLevel. After each render, copy the
14431464
// result to a buffer and expect the results from both textures to match.
1444-
const pipeline = getPipelineToRenderTextureToRGB8UnormTexture(this.device);
1465+
const { pipelineType, pipeline } = getPipelineToRenderTextureToRGB8UnormTexture(
1466+
this.device,
1467+
actualTexture,
1468+
this.isCompatibility
1469+
);
14451470
const readbackPromisesPerTexturePerLayer = [actualTexture, expectedTexture].map(
14461471
(texture, ndx) => {
14471472
const attachmentSize = virtualMipSize('2d', [texture.width, texture.height, 1], mipLevel);
@@ -1457,6 +1482,14 @@ export function TextureTestMixin<F extends FixtureClass<GPUTest>>(
14571482

14581483
const numLayers = texture.depthOrArrayLayers;
14591484
const readbackPromisesPerLayer = [];
1485+
1486+
const uniformBuffer = this.device.createBuffer({
1487+
size: 4,
1488+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
1489+
});
1490+
this.trackForCleanup(uniformBuffer);
1491+
const uniformData = new Uint32Array(1);
1492+
14601493
for (let layer = 0; layer < numLayers; ++layer) {
14611494
const bindGroup = this.device.createBindGroup({
14621495
layout: pipeline.getBindGroupLayout(0),
@@ -1467,14 +1500,27 @@ export function TextureTestMixin<F extends FixtureClass<GPUTest>>(
14671500
resource: texture.createView({
14681501
baseMipLevel: mipLevel,
14691502
mipLevelCount: 1,
1470-
baseArrayLayer: layer,
1471-
arrayLayerCount: 1,
1472-
dimension: '2d',
1503+
...(!this.isCompatibility && {
1504+
baseArrayLayer: layer,
1505+
arrayLayerCount: 1,
1506+
}),
1507+
dimension: pipelineType as GPUTextureViewDimension,
14731508
}),
14741509
},
1510+
...(pipelineType === '2d-array'
1511+
? [
1512+
{
1513+
binding: 2,
1514+
resource: { buffer: uniformBuffer },
1515+
},
1516+
]
1517+
: []),
14751518
],
14761519
});
14771520

1521+
uniformData[0] = layer;
1522+
this.device.queue.writeBuffer(uniformBuffer, 0, uniformData);
1523+
14781524
const encoder = this.device.createCommandEncoder();
14791525
const pass = encoder.beginRenderPass({
14801526
colorAttachments: [

0 commit comments

Comments
 (0)