export const description = `
Validation tests for setIndexBuffer on render pass and render bundle.
`;
import { makeTestGroup } from '../../../../../../common/framework/test_group.js';
import { GPUConst } from '../../../../../constants.js';
import { kResourceStates, AllFeaturesMaxLimitsGPUTest } from '../../../../../gpu_test.js';
import * as vtu from '../../../validation_test_utils.js';
import { kRenderEncodeTypeParams, buildBufferOffsetAndSizeOOBTestParams } from './render.js';
export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest);
g.test('index_buffer_state')
.desc(
`
Tests index buffer must be valid.
`
)
.paramsSubcasesOnly(kRenderEncodeTypeParams.combine('state', kResourceStates))
.fn(t => {
const { encoderType, state } = t.params;
const indexBuffer = vtu.createBufferWithState(t, state, {
size: 16,
usage: GPUBufferUsage.INDEX,
});
const { encoder, validateFinishAndSubmitGivenState } = t.createEncoder(encoderType);
encoder.setIndexBuffer(indexBuffer, 'uint32');
validateFinishAndSubmitGivenState(state);
});
g.test('index_buffer,device_mismatch')
.desc('Tests setIndexBuffer cannot be called with an index buffer created from another device')
.paramsSubcasesOnly(kRenderEncodeTypeParams.combine('mismatched', [true, false]))
.beforeAllSubcases(t => t.usesMismatchedDevice())
.fn(t => {
const { encoderType, mismatched } = t.params;
const sourceDevice = mismatched ? t.mismatchedDevice : t.device;
const indexBuffer = t.trackForCleanup(
sourceDevice.createBuffer({
size: 16,
usage: GPUBufferUsage.INDEX,
})
);
const { encoder, validateFinish } = t.createEncoder(encoderType);
encoder.setIndexBuffer(indexBuffer, 'uint32');
validateFinish(!mismatched);
});
g.test('index_buffer_usage')
.desc(
`
Tests index buffer must have 'Index' usage.
`
)
.paramsSubcasesOnly(
kRenderEncodeTypeParams.combine('usage', [
GPUConst.BufferUsage.INDEX,
GPUConst.BufferUsage.COPY_DST,
GPUConst.BufferUsage.COPY_DST | GPUConst.BufferUsage.INDEX,
] as const)
)
.fn(t => {
const { encoderType, usage } = t.params;
const indexBuffer = t.createBufferTracked({
size: 16,
usage,
});
const { encoder, validateFinish } = t.createEncoder(encoderType);
encoder.setIndexBuffer(indexBuffer, 'uint32');
validateFinish((usage & GPUBufferUsage.INDEX) !== 0);
});
g.test('offset_alignment')
.desc(
`
Tests offset must be a multiple of index formatβs byte size.
`
)
.paramsSubcasesOnly(
kRenderEncodeTypeParams
.combine('indexFormat', ['uint16', 'uint32'] as const)
.expand('offset', p => {
return p.indexFormat === 'uint16' ? ([0, 1, 2] as const) : ([0, 2, 4] as const);
})
)
.fn(t => {
const { encoderType, indexFormat, offset } = t.params;
const indexBuffer = t.createBufferTracked({
size: 16,
usage: GPUBufferUsage.INDEX,
});
const { encoder, validateFinish } = t.createEncoder(encoderType);
encoder.setIndexBuffer(indexBuffer, indexFormat, offset);
const alignment =
indexFormat === 'uint16' ? Uint16Array.BYTES_PER_ELEMENT : Uint32Array.BYTES_PER_ELEMENT;
validateFinish(offset % alignment === 0);
});
g.test('offset_and_size_oob')
.desc(
`
Tests offset and size cannot be larger than index buffer size.
`
)
.paramsSubcasesOnly(buildBufferOffsetAndSizeOOBTestParams(4, 256))
.fn(t => {
const { encoderType, offset, size, _valid } = t.params;
const indexBuffer = t.createBufferTracked({
size: 256,
usage: GPUBufferUsage.INDEX,
});
const { encoder, validateFinish } = t.createEncoder(encoderType);
encoder.setIndexBuffer(indexBuffer, 'uint32', offset, size);
validateFinish(_valid);
});