import { range } from '../../../../../common/util/util.js';
import { kShaderStageCombinationsWithStage } from '../../../../capability_info.js';
import { kMaximumLimitBaseParams, LimitsRequest, makeLimitTestGroup } from './limit_utils.js';
const kExtraLimits: LimitsRequest = {
maxBindingsPerBindGroup: 'adapterLimit',
maxBindGroups: 'adapterLimit',
maxUniformBuffersPerShaderStage: 'adapterLimit',
};
const limit = 'maxDynamicUniformBuffersPerPipelineLayout';
export const { g, description } = makeLimitTestGroup(limit);
g.test('createBindGroupLayout,at_over')
.desc(`Test using createBindGroupLayout at and over ${limit} limit`)
.params(kMaximumLimitBaseParams.combine('visibility', kShaderStageCombinationsWithStage))
.fn(async t => {
const { limitTest, testValueName, visibility } = t.params;
await t.testDeviceWithRequestedMaximumLimits(
limitTest,
testValueName,
async ({ device, testValue, shouldError }) => {
await t.expectValidationError(() => {
device.createBindGroupLayout({
entries: range(testValue, i => ({
binding: i,
visibility,
buffer: {
hasDynamicOffset: true,
},
})),
});
}, shouldError);
},
kExtraLimits
);
});
g.test('createPipelineLayout,at_over')
.desc(`Test using at and over ${limit} limit in createPipelineLayout`)
.params(kMaximumLimitBaseParams)
.fn(async t => {
const { limitTest, testValueName } = t.params;
await t.testDeviceWithRequestedMaximumLimits(
limitTest,
testValueName,
async ({ device, testValue, shouldError, actualLimit }) => {
const maxUniformBindings = Math.min(
device.limits.maxUniformBuffersPerShaderStage,
actualLimit
);
const totalBindings = maxUniformBindings * 3;
t.skipIf(
totalBindings < testValue,
`total uniform buffer bindings across stages (${totalBindings}) < testValue(${testValue})`
);
const maxBindingsPerStage = [maxUniformBindings, maxUniformBindings, maxUniformBindings];
let numBindingsAvailable = testValue;
const bindGroupLayouts = maxBindingsPerStage.map((maxBindings, visibilityBit) => {
const numInGroup = Math.min(numBindingsAvailable, maxBindings);
numBindingsAvailable -= numInGroup;
t.debug(`group(${visibilityBit}) numBindings: ${numInGroup}`);
return device.createBindGroupLayout({
entries: range(numInGroup, i => ({
binding: i,
visibility: 1 << visibilityBit,
buffer: {
hasDynamicOffset: true,
},
})),
});
});
await t.expectValidationError(
() => device.createPipelineLayout({ bindGroupLayouts }),
shouldError
);
},
kExtraLimits
);
});