export const description = `API Operation Tests for transient attachment in render passes.`;
import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { AllFeaturesMaxLimitsGPUTest } from '../../../gpu_test.js';
const kSize = 4;
export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest);
g.test('increasing_attachments_count')
.desc(
`
Use multiple render passes with increasing amounts of transient attachments.
`
)
.fn(t => {
t.skipIfTransientAttachmentNotSupported();
const maxAttachments = t.device.limits.maxColorAttachments;
const encoder = t.device.createCommandEncoder();
for (let count = 1; count <= maxAttachments; count++) {
const colorAttachments: GPURenderPassColorAttachment[] = [];
for (let i = 0; i < count; i++) {
const texture = t.createTextureTracked({
size: [kSize, kSize, 1],
format: 'rgba8unorm',
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TRANSIENT_ATTACHMENT,
});
colorAttachments.push({
view: texture.createView(),
clearValue: { r: 0.0, g: 0.0, b: 0.0, a: 0.0 },
loadOp: 'clear',
storeOp: 'discard',
});
}
const pass = encoder.beginRenderPass({ colorAttachments });
pass.end();
}
t.device.queue.submit([encoder.finish()]);
});
g.test('overlapping_transient_attachments')
.desc(
`
Use multiple render passes with transient attachments in a circular overlap pattern:
Pass 1: (T1, T2)
Pass 2: (T2, T3)
Pass 3: (T3, T1)
This stresses the driver's transient memory allocator. If the driver naively reuses
T1's memory for T3 during Pass 2 (because T1 isn't active in Pass 2),
Pass 3 will fail or corrupt because T1 and T3 are both needed simultaneously again.
`
)
.fn(t => {
t.skipIfTransientAttachmentNotSupported();
const encoder = t.device.createCommandEncoder();
const desc = {
size: [kSize, kSize, 1],
format: 'rgba8unorm',
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TRANSIENT_ATTACHMENT,
} as const;
const t1 = t.createTextureTracked(desc);
const t2 = t.createTextureTracked(desc);
const t3 = t.createTextureTracked(desc);
const passes = [
[t1, t2],
[t2, t3],
[t3, t1],
];
for (const attachments of passes) {
const colorAttachments: GPURenderPassColorAttachment[] = attachments.map(texture => ({
view: texture.createView(),
clearValue: { r: 0.0, g: 0.0, b: 0.0, a: 0.0 },
loadOp: 'clear',
storeOp: 'discard',
}));
const pass = encoder.beginRenderPass({ colorAttachments });
pass.end();
}
t.device.queue.submit([encoder.finish()]);
});