export const description = `Tests using a destroyed texture on a queue.`;import { makeTestGroup } from '../../../../../common/framework/test_group.js';import { unreachable } from '../../../../../common/util/util.js';import { AllFeaturesMaxLimitsGPUTest } from '../../../../gpu_test.js';export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest);g.test('writeTexture').desc(`Tests that using a destroyed texture in writeTexture fails.- x= {destroyed, not destroyed (control case)}`).paramsSubcasesOnly(u => u.combine('destroyed', [false, true] as const)).fn(t => {const { destroyed } = t.params;const texture = t.createTextureTracked({size: [1, 1, 1],format: 'rgba8unorm',usage: GPUTextureUsage.COPY_DST,});if (destroyed) {texture.destroy();}t.expectValidationError(() => t.queue.writeTexture({ texture }, new Uint8Array(4), { bytesPerRow: 4 }, [1, 1, 1]),destroyed);});g.test('copyTextureToTexture').desc(`Tests that using a destroyed texture in copyTextureToTexture fails.- x= {not destroyed (control case), src destroyed, dst destroyed}`).paramsSubcasesOnly(u => u.combine('destroyed', ['none', 'src', 'dst', 'both'] as const)).fn(t => {const src = t.createTextureTracked({size: [1, 1, 1],format: 'rgba8unorm',usage: GPUTextureUsage.COPY_SRC,});const dst = t.createTextureTracked({size: [1, 1, 1],format: 'rgba8unorm',usage: GPUTextureUsage.COPY_DST,});const encoder = t.device.createCommandEncoder();encoder.copyTextureToTexture({ texture: src }, { texture: dst }, [1, 1, 1]);const commandBuffer = encoder.finish();let shouldError = true;switch (t.params.destroyed) {case 'none':shouldError = false;break;case 'src':src.destroy();break;case 'dst':dst.destroy();break;case 'both':src.destroy();dst.destroy();break;}t.expectValidationError(() => {t.queue.submit([commandBuffer]);}, shouldError);});g.test('copyBufferToTexture').desc(`Tests that using a destroyed texture in copyBufferToTexture fails.- x= {not destroyed (control case), dst destroyed}`).paramsSubcasesOnly(u => u.combine('destroyed', [false, true] as const)).fn(t => {const { destroyed } = t.params;const buffer = t.createBufferTracked({ size: 4, usage: GPUBufferUsage.COPY_SRC });const texture = t.createTextureTracked({size: [1, 1, 1],format: 'rgba8unorm',usage: GPUTextureUsage.COPY_DST,});const encoder = t.device.createCommandEncoder();encoder.copyBufferToTexture({ buffer }, { texture }, [1, 1, 1]);const commandBuffer = encoder.finish();if (destroyed) {texture.destroy();}t.expectValidationError(() => {t.queue.submit([commandBuffer]);}, destroyed);});g.test('copyTextureToBuffer').desc(`Tests that using a destroyed texture in copyTextureToBuffer fails.- x= {not destroyed (control case), src destroyed}`).paramsSubcasesOnly(u => u.combine('destroyed', [false, true] as const)).fn(t => {const { destroyed } = t.params;const texture = t.createTextureTracked({size: [1, 1, 1],format: 'rgba8unorm',usage: GPUTextureUsage.COPY_SRC,});const buffer = t.createBufferTracked({ size: 4, usage: GPUBufferUsage.COPY_DST });const encoder = t.device.createCommandEncoder();encoder.copyTextureToBuffer({ texture }, { buffer }, [1, 1, 1]);const commandBuffer = encoder.finish();if (destroyed) {texture.destroy();}t.expectValidationError(() => {t.queue.submit([commandBuffer]);}, destroyed);});g.test('setBindGroup').desc(`Tests that using a destroyed texture referenced by a bindGroup set with setBindGroup fails- x= {not destroyed (control case), destroyed}`).paramsSubcasesOnly(u =>u.combine('destroyed', [false, true] as const).combine('encoderType', ['compute pass', 'render pass', 'render bundle'] as const).combine('bindingType', ['texture', 'storageTexture'] as const)).fn(t => {const { destroyed, encoderType, bindingType } = t.params;const { device } = t;const texture = t.createTextureTracked({size: [1, 1, 1],format: 'rgba8unorm',usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.STORAGE_BINDING,});const layout = device.createBindGroupLayout({entries: [{binding: 0,visibility: GPUShaderStage.COMPUTE,[bindingType]: {format: texture.format,},},],});const bindGroup = device.createBindGroup({layout,entries: [{ binding: 0, resource: texture.createView() }],});const { encoder, finish } = t.createEncoder(encoderType);encoder.setBindGroup(0, bindGroup);const commandBuffer = finish();if (destroyed) {texture.destroy();}t.expectValidationError(() => {t.queue.submit([commandBuffer]);}, destroyed);});g.test('beginRenderPass').desc(`Tests that using a destroyed texture referenced by a render pass fails- x= {not destroyed (control case), colorAttachment destroyed, depthAttachment destroyed, resolveTarget destroyed}`).paramsSubcasesOnly(u =>u.combine('textureToDestroy', ['none','colorAttachment','resolveAttachment','depthStencilAttachment',])).fn(t => {const { textureToDestroy } = t.params;const { device } = t;const colorAttachment = t.createTextureTracked({size: [1, 1, 1],format: 'rgba8unorm',sampleCount: 4,usage: GPUTextureUsage.RENDER_ATTACHMENT,});const resolveAttachment = t.createTextureTracked({size: [1, 1, 1],format: 'rgba8unorm',usage: GPUTextureUsage.RENDER_ATTACHMENT,});const depthStencilAttachment = t.createTextureTracked({size: [1, 1, 1],format: 'depth32float',sampleCount: 4,usage: GPUTextureUsage.RENDER_ATTACHMENT,});const encoder = device.createCommandEncoder();const pass = encoder.beginRenderPass({colorAttachments: [{view: colorAttachment.createView(),resolveTarget: resolveAttachment.createView(),loadOp: 'clear',storeOp: 'store',},],depthStencilAttachment: {view: depthStencilAttachment.createView(),depthClearValue: 0,depthLoadOp: 'clear',depthStoreOp: 'store',},});pass.end();const commandBuffer = encoder.finish();switch (textureToDestroy) {case 'none':break;case 'colorAttachment':colorAttachment.destroy();break;case 'resolveAttachment':resolveAttachment.destroy();break;case 'depthStencilAttachment':depthStencilAttachment.destroy();break;default:unreachable();}const shouldError = textureToDestroy !== 'none';t.expectValidationError(() => {t.queue.submit([commandBuffer]);}, shouldError);});