blob: 59caf533e6c3674b82ead7cd1e05048c4de3d308 [file] [log] [blame]
/**
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
**/
export const description = `
render pass descriptor validation tests.
`;
import { TestGroup } from '../../../framework/index.js';
import { ValidationTest } from './validation_test.js';
class F extends ValidationTest {
createTexture(options = {}) {
const {
format = 'rgba8unorm',
width = 16,
height = 16,
arrayLayerCount = 1,
mipLevelCount = 1,
sampleCount = 1,
usage = GPUTextureUsage.OUTPUT_ATTACHMENT
} = options;
return this.device.createTexture({
size: {
width,
height,
depth: 1
},
format,
arrayLayerCount,
mipLevelCount,
sampleCount,
usage
});
}
getColorAttachment(texture, textureViewDescriptor) {
const attachment = texture.createView(textureViewDescriptor);
return {
attachment,
loadValue: {
r: 1.0,
g: 0.0,
b: 0.0,
a: 1.0
}
};
}
getDepthStencilAttachment(texture, textureViewDescriptor) {
const attachment = texture.createView(textureViewDescriptor);
return {
attachment,
depthLoadValue: 1.0,
depthStoreOp: 'store',
stencilLoadValue: 0,
stencilStoreOp: 'store'
};
}
async tryRenderPass(success, descriptor) {
const commandEncoder = this.device.createCommandEncoder();
const renderPass = commandEncoder.beginRenderPass(descriptor);
renderPass.endPass();
this.expectValidationError(() => {
commandEncoder.finish();
}, !success);
}
}
export const g = new TestGroup(F);
g.test('a render pass with only one color is ok', t => {
const colorTexture = t.createTexture({
format: 'rgba8unorm'
});
const descriptor = {
colorAttachments: [t.getColorAttachment(colorTexture)]
};
t.tryRenderPass(true, descriptor);
});
g.test('a render pass with only one depth attachment is ok', t => {
const depthStencilTexture = t.createTexture({
format: 'depth24plus-stencil8'
});
const descriptor = {
colorAttachments: [],
depthStencilAttachment: t.getDepthStencilAttachment(depthStencilTexture)
};
t.tryRenderPass(true, descriptor);
});
g.test('OOB color attachment indices are handled', async t => {
const {
colorAttachmentsCount,
_success
} = t.params;
const colorAttachments = [];
for (let i = 0; i < colorAttachmentsCount; i++) {
const colorTexture = t.createTexture();
colorAttachments.push(t.getColorAttachment(colorTexture));
}
await t.tryRenderPass(_success, {
colorAttachments
});
}).params([{
colorAttachmentsCount: 4,
_success: true
}, // Control case
{
colorAttachmentsCount: 5,
_success: false
} // Out of bounds
]);
g.test('attachments must have the same size', async t => {
const colorTexture1x1A = t.createTexture({
width: 1,
height: 1,
format: 'rgba8unorm'
});
const colorTexture1x1B = t.createTexture({
width: 1,
height: 1,
format: 'rgba8unorm'
});
const colorTexture2x2 = t.createTexture({
width: 2,
height: 2,
format: 'rgba8unorm'
});
const depthStencilTexture1x1 = t.createTexture({
width: 1,
height: 1,
format: 'depth24plus-stencil8'
});
const depthStencilTexture2x2 = t.createTexture({
width: 2,
height: 2,
format: 'depth24plus-stencil8'
});
{
// Control case: all the same size (1x1)
const descriptor = {
colorAttachments: [t.getColorAttachment(colorTexture1x1A), t.getColorAttachment(colorTexture1x1B)],
depthStencilAttachment: t.getDepthStencilAttachment(depthStencilTexture1x1)
};
t.tryRenderPass(true, descriptor);
}
{
// One of the color attachments has a different size
const descriptor = {
colorAttachments: [t.getColorAttachment(colorTexture1x1A), t.getColorAttachment(colorTexture2x2)]
};
await t.tryRenderPass(false, descriptor);
}
{
// The depth stencil attachment has a different size
const descriptor = {
colorAttachments: [t.getColorAttachment(colorTexture1x1A), t.getColorAttachment(colorTexture1x1B)],
depthStencilAttachment: t.getDepthStencilAttachment(depthStencilTexture2x2)
};
await t.tryRenderPass(false, descriptor);
}
});
g.test('attachments must match whether they are used for color or depth stencil', async t => {
const colorTexture = t.createTexture({
format: 'rgba8unorm'
});
const depthStencilTexture = t.createTexture({
format: 'depth24plus-stencil8'
});
{
// Using depth-stencil for color
const descriptor = {
colorAttachments: [t.getColorAttachment(depthStencilTexture)]
};
await t.tryRenderPass(false, descriptor);
}
{
// Using color for depth-stencil
const descriptor = {
colorAttachments: [],
depthStencilAttachment: t.getDepthStencilAttachment(colorTexture)
};
await t.tryRenderPass(false, descriptor);
}
});
g.test('check layer count for color or depth stencil', async t => {
const {
arrayLayerCount,
baseArrayLayer,
_success
} = t.params;
const ARRAY_LAYER_COUNT = 10;
const MIP_LEVEL_COUNT = 1;
const COLOR_FORMAT = 'rgba8unorm';
const DEPTH_STENCIL_FORMAT = 'depth24plus-stencil8';
const colorTexture = t.createTexture({
format: COLOR_FORMAT,
width: 32,
height: 32,
mipLevelCount: MIP_LEVEL_COUNT,
arrayLayerCount: ARRAY_LAYER_COUNT
});
const depthStencilTexture = t.createTexture({
format: DEPTH_STENCIL_FORMAT,
width: 32,
height: 32,
mipLevelCount: MIP_LEVEL_COUNT,
arrayLayerCount: ARRAY_LAYER_COUNT
});
const baseTextureViewDescriptor = {
dimension: '2d-array',
baseArrayLayer,
arrayLayerCount,
baseMipLevel: 0,
mipLevelCount: MIP_LEVEL_COUNT
};
{
// Check 2D array texture view for color
const textureViewDescriptor = { ...baseTextureViewDescriptor,
format: COLOR_FORMAT
};
const descriptor = {
colorAttachments: [t.getColorAttachment(colorTexture, textureViewDescriptor)]
};
await t.tryRenderPass(_success, descriptor);
}
{
// Check 2D array texture view for depth stencil
const textureViewDescriptor = { ...baseTextureViewDescriptor,
format: DEPTH_STENCIL_FORMAT
};
const descriptor = {
colorAttachments: [],
depthStencilAttachment: t.getDepthStencilAttachment(depthStencilTexture, textureViewDescriptor)
};
await t.tryRenderPass(_success, descriptor);
}
}).params([{
arrayLayerCount: 5,
baseArrayLayer: 0,
_success: false
}, // using 2D array texture view with arrayLayerCount > 1 is not allowed
{
arrayLayerCount: 1,
baseArrayLayer: 0,
_success: true
}, // using 2D array texture view that covers the first layer of the texture is OK
{
arrayLayerCount: 1,
baseArrayLayer: 9,
_success: true
} // using 2D array texture view that covers the last layer is OK for depth stencil
]);
g.test('check mip level count for color or depth stencil', async t => {
const {
mipLevelCount,
baseMipLevel,
_success
} = t.params;
const ARRAY_LAYER_COUNT = 1;
const MIP_LEVEL_COUNT = 4;
const COLOR_FORMAT = 'rgba8unorm';
const DEPTH_STENCIL_FORMAT = 'depth24plus-stencil8';
const colorTexture = t.createTexture({
format: COLOR_FORMAT,
width: 32,
height: 32,
mipLevelCount: MIP_LEVEL_COUNT,
arrayLayerCount: ARRAY_LAYER_COUNT
});
const depthStencilTexture = t.createTexture({
format: DEPTH_STENCIL_FORMAT,
width: 32,
height: 32,
mipLevelCount: MIP_LEVEL_COUNT,
arrayLayerCount: ARRAY_LAYER_COUNT
});
const baseTextureViewDescriptor = {
dimension: '2d',
baseArrayLayer: 0,
arrayLayerCount: ARRAY_LAYER_COUNT,
baseMipLevel,
mipLevelCount
};
{
// Check 2D texture view for color
const textureViewDescriptor = { ...baseTextureViewDescriptor,
format: COLOR_FORMAT
};
const descriptor = {
colorAttachments: [t.getColorAttachment(colorTexture, textureViewDescriptor)]
};
await t.tryRenderPass(_success, descriptor);
}
{
// Check 2D texture view for depth stencil
const textureViewDescriptor = { ...baseTextureViewDescriptor,
format: DEPTH_STENCIL_FORMAT
};
const descriptor = {
colorAttachments: [],
depthStencilAttachment: t.getDepthStencilAttachment(depthStencilTexture, textureViewDescriptor)
};
await t.tryRenderPass(_success, descriptor);
}
}).params([{
mipLevelCount: 2,
baseMipLevel: 0,
_success: false
}, // using 2D texture view with mipLevelCount > 1 is not allowed
{
mipLevelCount: 1,
baseMipLevel: 0,
_success: true
}, // using 2D texture view that covers the first level of the texture is OK
{
mipLevelCount: 1,
baseMipLevel: 3,
_success: true
} // using 2D texture view that covers the last level of the texture is OK
]);
g.test('it is invalid to set resolve target if color attachment is non multisampled', async t => {
const colorTexture = t.createTexture({
sampleCount: 1
});
const resolveTargetTexture = t.createTexture({
sampleCount: 1
});
const descriptor = {
colorAttachments: [{
attachment: colorTexture.createView(),
resolveTarget: resolveTargetTexture.createView(),
loadValue: {
r: 1.0,
g: 0.0,
b: 0.0,
a: 1.0
}
}]
};
await t.tryRenderPass(false, descriptor);
});
g.test('check the use of multisampled textures as color attachments', async t => {
const colorTexture = t.createTexture({
sampleCount: 1
});
const multisampledColorTexture = t.createTexture({
sampleCount: 4
});
{
// It is allowed to use a multisampled color attachment without setting resolve target
const descriptor = {
colorAttachments: [t.getColorAttachment(multisampledColorTexture)]
};
t.tryRenderPass(true, descriptor);
}
{
// It is not allowed to use multiple color attachments with different sample counts
const descriptor = {
colorAttachments: [t.getColorAttachment(colorTexture), t.getColorAttachment(multisampledColorTexture)]
};
await t.tryRenderPass(false, descriptor);
}
});
g.test('it is invalid to use a multisampled resolve target', async t => {
const multisampledColorTexture = t.createTexture({
sampleCount: 4
});
const multisampledResolveTargetTexture = t.createTexture({
sampleCount: 4
});
const colorAttachment = t.getColorAttachment(multisampledColorTexture);
colorAttachment.resolveTarget = multisampledResolveTargetTexture.createView();
const descriptor = {
colorAttachments: [colorAttachment]
};
await t.tryRenderPass(false, descriptor);
});
g.test('it is invalid to use a resolve target with array layer count greater than 1', async t => {
const multisampledColorTexture = t.createTexture({
sampleCount: 4
});
const resolveTargetTexture = t.createTexture({
arrayLayerCount: 2
});
const colorAttachment = t.getColorAttachment(multisampledColorTexture);
colorAttachment.resolveTarget = resolveTargetTexture.createView();
const descriptor = {
colorAttachments: [colorAttachment]
};
await t.tryRenderPass(false, descriptor);
});
g.test('it is invalid to use a resolve target with mipmap level count greater than 1', async t => {
const multisampledColorTexture = t.createTexture({
sampleCount: 4
});
const resolveTargetTexture = t.createTexture({
mipLevelCount: 2
});
const colorAttachment = t.getColorAttachment(multisampledColorTexture);
colorAttachment.resolveTarget = resolveTargetTexture.createView();
const descriptor = {
colorAttachments: [colorAttachment]
};
await t.tryRenderPass(false, descriptor);
});
g.test('it is invalid to use a resolve target whose usage is not output attachment', async t => {
const multisampledColorTexture = t.createTexture({
sampleCount: 4
});
const resolveTargetTexture = t.createTexture({
usage: GPUTextureUsage.COPY_SRC | GPUTextureUsage.COPY_DST
});
const colorAttachment = t.getColorAttachment(multisampledColorTexture);
colorAttachment.resolveTarget = resolveTargetTexture.createView();
const descriptor = {
colorAttachments: [colorAttachment]
};
await t.tryRenderPass(false, descriptor);
});
g.test('it is invalid to use a resolve target in error state', async t => {
const ARRAY_LAYER_COUNT = 1;
const multisampledColorTexture = t.createTexture({
sampleCount: 4
});
const resolveTargetTexture = t.createTexture({
arrayLayerCount: ARRAY_LAYER_COUNT
});
const colorAttachment = t.getColorAttachment(multisampledColorTexture);
t.expectValidationError(() => {
colorAttachment.resolveTarget = resolveTargetTexture.createView({
dimension: '2d',
format: 'rgba8unorm',
baseArrayLayer: ARRAY_LAYER_COUNT + 1
});
});
const descriptor = {
colorAttachments: [colorAttachment]
};
await t.tryRenderPass(false, descriptor);
});
g.test('use of multisampled attachment and non multisampled resolve target is allowed', async t => {
const multisampledColorTexture = t.createTexture({
sampleCount: 4
});
const resolveTargetTexture = t.createTexture({
sampleCount: 1
});
const colorAttachment = t.getColorAttachment(multisampledColorTexture);
colorAttachment.resolveTarget = resolveTargetTexture.createView();
const descriptor = {
colorAttachments: [colorAttachment]
};
t.tryRenderPass(true, descriptor);
});
g.test('use a resolve target in a format different than the attachment is not allowed', async t => {
const multisampledColorTexture = t.createTexture({
sampleCount: 4
});
const resolveTargetTexture = t.createTexture({
format: 'bgra8unorm'
});
const colorAttachment = t.getColorAttachment(multisampledColorTexture);
colorAttachment.resolveTarget = resolveTargetTexture.createView();
const descriptor = {
colorAttachments: [colorAttachment]
};
await t.tryRenderPass(false, descriptor);
});
g.test('size of the resolve target must be the same as the color attachment', async t => {
const size = 16;
const multisampledColorTexture = t.createTexture({
width: size,
height: size,
sampleCount: 4
});
const resolveTargetTexture = t.createTexture({
width: size * 2,
height: size * 2,
mipLevelCount: 2
});
{
const resolveTargetTextureView = resolveTargetTexture.createView({
baseMipLevel: 0,
mipLevelCount: 1
});
const colorAttachment = t.getColorAttachment(multisampledColorTexture);
colorAttachment.resolveTarget = resolveTargetTextureView;
const descriptor = {
colorAttachments: [colorAttachment]
};
await t.tryRenderPass(false, descriptor);
}
{
const resolveTargetTextureView = resolveTargetTexture.createView({
baseMipLevel: 1
});
const colorAttachment = t.getColorAttachment(multisampledColorTexture);
colorAttachment.resolveTarget = resolveTargetTextureView;
const descriptor = {
colorAttachments: [colorAttachment]
};
t.tryRenderPass(true, descriptor);
}
});
g.test('check depth stencil attachment sample counts mismatch', async t => {
const multisampledDepthStencilTexture = t.createTexture({
sampleCount: 4,
format: 'depth24plus-stencil8'
});
{
// It is not allowed to use a depth stencil attachment whose sample count is different from the
// one of the color attachment
const depthStencilTexture = t.createTexture({
sampleCount: 1,
format: 'depth24plus-stencil8'
});
const multisampledColorTexture = t.createTexture({
sampleCount: 4
});
const descriptor = {
colorAttachments: [t.getColorAttachment(multisampledColorTexture)],
depthStencilAttachment: t.getDepthStencilAttachment(depthStencilTexture)
};
await t.tryRenderPass(false, descriptor);
}
{
const colorTexture = t.createTexture({
sampleCount: 1
});
const descriptor = {
colorAttachments: [t.getColorAttachment(colorTexture)],
depthStencilAttachment: t.getDepthStencilAttachment(multisampledDepthStencilTexture)
};
await t.tryRenderPass(false, descriptor);
}
{
// It is allowed to use a multisampled depth stencil attachment whose sample count is equal to
// the one of the color attachment.
const multisampledColorTexture = t.createTexture({
sampleCount: 4
});
const descriptor = {
colorAttachments: [t.getColorAttachment(multisampledColorTexture)],
depthStencilAttachment: t.getDepthStencilAttachment(multisampledDepthStencilTexture)
};
t.tryRenderPass(true, descriptor);
}
{
// It is allowed to use a multisampled depth stencil attachment with no color attachment
const descriptor = {
colorAttachments: [],
depthStencilAttachment: t.getDepthStencilAttachment(multisampledDepthStencilTexture)
};
t.tryRenderPass(true, descriptor);
}
});
//# sourceMappingURL=render_pass_descriptor.spec.js.map