export const description = `Tests limitations of createRenderPipeline related to vertex state in compat mode.`;import { makeTestGroup } from '../../../../../common/framework/test_group.js';import { range } from '../../../../../common/util/util.js';import * as vtu from '../../../../api/validation/validation_test_utils.js';import { CompatibilityTest } from '../../../compatibility_test.js';export const g = makeTestGroup(CompatibilityTest);g.test('maxVertexAttributesVertexIndexInstanceIndex').desc(`Tests @builtin(vertex_index) and @builtin(instance_index) each count as an attribute.- Test that you can use maxVertexAttributes- Test that you can not use maxVertexAttributes and @builtin(vertex_index)- Test that you can not use maxVertexAttributes and @builtin(instance_index)- Test that you can use maxVertexAttributes - 1 and @builtin(vertex_index)- Test that you can use maxVertexAttributes - 1 and @builtin(instance_index)- Test that you can not use maxVertexAttributes - 1 and both @builtin(vertex_index) and @builtin(instance_index)- Test that you can use maxVertexAttributes - 2 and both @builtin(vertex_index) and @builtin(instance_index)`).params(u =>u.combine('useVertexIndex', [false, true] as const).combine('useInstanceIndex', [false, true] as const).combine('numAttribsToReserve', [0, 1, 2] as const).combine('isAsync', [false, true] as const)).fn(t => {const { useVertexIndex, useInstanceIndex, numAttribsToReserve, isAsync } = t.params;const numAttribs = t.device.limits.maxVertexAttributes - numAttribsToReserve;const numBuiltinsUsed = (useVertexIndex ? 1 : 0) + (useInstanceIndex ? 1 : 0);const isValidInCompat = numAttribs + numBuiltinsUsed <= t.device.limits.maxVertexAttributes;const isValidInCore = numAttribs <= t.device.limits.maxVertexAttributes;const isValid = t.isCompatibility ? isValidInCompat : isValidInCore;const inputs = range(numAttribs, i => `@location(${i}) v${i}: vec4f`);const outputs = range(numAttribs, i => `v${i}`);if (useVertexIndex) {inputs.push('@builtin(vertex_index) vNdx: u32');outputs.push('vec4f(f32(vNdx))');}if (useInstanceIndex) {inputs.push('@builtin(instance_index) iNdx: u32');outputs.push('vec4f(f32(iNdx))');}const module = t.device.createShaderModule({code: `@fragment fn fs() -> @location(0) vec4f {return vec4f(1);}@vertex fn vs(${inputs.join(', ')}) -> @builtin(position) vec4f {return ${outputs.join(' + ')};}`,});const pipelineDescriptor: GPURenderPipelineDescriptor = {layout: 'auto',vertex: {module,entryPoint: 'vs',buffers: [{arrayStride: 16,attributes: range(numAttribs, i => ({shaderLocation: i,format: 'float32x4',offset: 0,})),},],},fragment: {module,entryPoint: 'fs',targets: [{format: 'rgba8unorm',},],},};vtu.doCreateRenderPipelineTest(t, isAsync, isValid, pipelineDescriptor);});