@@ -1237,24 +1237,44 @@ export interface TextureTestMixinType {
12371237 ) : Generator < Required < GPUOrigin3DDict > > ;
12381238}
12391239
1240+ type PipelineType = '2d' | '2d-array' ;
1241+
12401242type ImageCopyTestResources = {
1241- pipeline : GPURenderPipeline ;
1243+ pipelineByPipelineType : Map < PipelineType , GPURenderPipeline > ;
12421244} ;
12431245
12441246const 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
13031324type 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