Skip to content

Commit

Permalink
Compat: update maxXXXInYYYStage tests (#4168)
Browse files Browse the repository at this point in the history
The proposal changed so that the corresponding PerStage
limit is auto-upgraded so these tests need to change.
  • Loading branch information
greggman authored Jan 31, 2025
1 parent eeea35c commit a134c34
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 76 deletions.
44 changes: 24 additions & 20 deletions src/webgpu/api/validation/capability_checks/limits/limit_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1275,42 +1275,46 @@ export function testMaxStorageXXXInYYYStageDeviceCreationWithDependentLimit(
| 'maxStorageTexturesInVertexStage',
dependentLimitName: 'maxStorageBuffersPerShaderStage' | 'maxStorageTexturesPerShaderStage'
) {
g.test(`validate,${dependentLimitName}`)
g.test(`auto_upgrades_per_stage,${dependentLimitName}`)
.desc(
`Test that adapter.limit.${limit} and requiredLimits.${limit} must be <= ${dependentLimitName}`
`Test that
* adapter.limit.${limit} < adapter.limit.${dependentLimitName}
* requiredLimits.${limit} auto-upgrades device.limits.${dependentLimitName}
`
)
.params(u => u.combine('useMax', [true, false] as const)) // true case should not reject.
.fn(async t => {
const { useMax } = t.params;
const { adapterLimit: maximumLimit, adapter } = t;

const dependentLimit = adapter.limits[dependentLimitName]!;
t.expect(
maximumLimit <= dependentLimit,
`maximumLimit(${maximumLimit}) is <= adapter.limits.${dependentLimitName}(${dependentLimit})`
);
{
const dependentLimit = adapter.limits[dependentLimitName]!;
t.expect(
maximumLimit <= dependentLimit,
`maximumLimit(${maximumLimit}) is <= adapter.limits.${dependentLimitName}(${dependentLimit})`
);
}

const dependentEffectiveLimits = useMax
? dependentLimit
: t.getDefaultLimit(dependentLimitName);
const shouldReject = maximumLimit > dependentEffectiveLimits;
t.debug(
`${limit}(${maximumLimit}) > ${dependentLimitName}(${dependentEffectiveLimits}) shouldReject: ${shouldReject}`
);
const shouldReject = false;
const device = await t.requestDeviceWithLimits(
adapter,
{
[limit]: maximumLimit,
...(useMax && {
[dependentLimitName]: dependentLimit,
}),
},
shouldReject
);

{
const dependentLimit = device!.limits[dependentLimitName]!;
const actualLimit = device!.limits[limit]!;
t.expect(
dependentLimit >= actualLimit,
`device.limits.${dependentLimitName}(${dependentLimit}) is >= adapter.limits.${limit}(${actualLimit})`
);
}

device?.destroy();
});

g.test(`auto_upgrade,${dependentLimitName}`)
g.test(`auto_upgraded_from_per_stage,${dependentLimitName}`)
.desc(
`Test that adapter.limit.${limit} is automatically upgraded to ${dependentLimitName} except in compat.`
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,15 @@ import {
} from './limit_utils.js';

const limit = 'maxStorageBuffersInFragmentStage';
const dependentLimitName = 'maxStorageBuffersPerShaderStage';

const kExtraLimits: LimitsRequest = {
maxBindingsPerBindGroup: 'adapterLimit',
maxBindGroups: 'adapterLimit',
[dependentLimitName]: 'adapterLimit',
};

export const { g, description } = makeLimitTestGroup(limit, {
// MAINTAINANCE_TODO: remove once this limit is required.
limitOptional: true,
limitCheckFn(t, device, { actualLimit }) {
if (!t.isCompatibility) {
const expectedLimit = device.limits[dependentLimitName];
t.expect(
actualLimit === expectedLimit,
`expected actual actualLimit: ${actualLimit} to equal ${dependentLimitName}: ${expectedLimit}`
);
return true;
}
return false;
},
});

function createBindGroupLayout(
Expand Down Expand Up @@ -208,4 +195,8 @@ g.test('createPipeline,at_over')
);
});

testMaxStorageXXXInYYYStageDeviceCreationWithDependentLimit(g, limit, dependentLimitName);
testMaxStorageXXXInYYYStageDeviceCreationWithDependentLimit(
g,
limit,
'maxStorageBuffersPerShaderStage'
);
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,15 @@ import {
} from './limit_utils.js';

const limit = 'maxStorageBuffersInVertexStage';
const dependentLimitName = 'maxStorageBuffersPerShaderStage';

const kExtraLimits: LimitsRequest = {
maxBindingsPerBindGroup: 'adapterLimit',
maxBindGroups: 'adapterLimit',
[dependentLimitName]: 'adapterLimit',
};

export const { g, description } = makeLimitTestGroup(limit, {
// MAINTAINANCE_TODO: remove once this limit is required.
limitOptional: true,
limitCheckFn(t, device, { actualLimit }) {
if (!t.isCompatibility) {
const expectedLimit = device.limits[dependentLimitName];
t.expect(
actualLimit === expectedLimit,
`expected actual actualLimit: ${actualLimit} to equal ${dependentLimitName}: ${expectedLimit}`
);
return true;
}
return false;
},
});

function createBindGroupLayout(
Expand Down Expand Up @@ -199,4 +186,8 @@ g.test('createPipeline,at_over')
);
});

testMaxStorageXXXInYYYStageDeviceCreationWithDependentLimit(g, limit, dependentLimitName);
testMaxStorageXXXInYYYStageDeviceCreationWithDependentLimit(
g,
limit,
'maxStorageBuffersPerShaderStage'
);
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,15 @@ import {
} from './limit_utils.js';

const limit = 'maxStorageTexturesInFragmentStage';
const dependentLimitName = 'maxStorageTexturesPerShaderStage';

const kExtraLimits: LimitsRequest = {
maxBindingsPerBindGroup: 'adapterLimit',
maxBindGroups: 'adapterLimit',
[dependentLimitName]: 'adapterLimit',
};

export const { g, description } = makeLimitTestGroup(limit, {
// MAINTAINANCE_TODO: remove once this limit is required.
limitOptional: true,
limitCheckFn(t, device, { actualLimit }) {
if (!t.isCompatibility) {
const expectedLimit = device.limits[dependentLimitName];
t.expect(
actualLimit === expectedLimit,
`expected actual actualLimit: ${actualLimit} to equal ${dependentLimitName}: ${expectedLimit}`
);
return true;
}
return false;
},
});

function createBindGroupLayout(
Expand Down Expand Up @@ -209,4 +196,8 @@ g.test('createPipeline,at_over')
);
});

testMaxStorageXXXInYYYStageDeviceCreationWithDependentLimit(g, limit, dependentLimitName);
testMaxStorageXXXInYYYStageDeviceCreationWithDependentLimit(
g,
limit,
'maxStorageTexturesPerShaderStage'
);
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,15 @@ import {
} from './limit_utils.js';

const limit = 'maxStorageTexturesInVertexStage';
const dependentLimitName = 'maxStorageTexturesPerShaderStage';

const kExtraLimits: LimitsRequest = {
maxBindingsPerBindGroup: 'adapterLimit',
maxBindGroups: 'adapterLimit',
[dependentLimitName]: 'adapterLimit',
};

export const { g, description } = makeLimitTestGroup(limit, {
// MAINTAINANCE_TODO: remove once this limit is required.
limitOptional: true,
limitCheckFn(t, device, { actualLimit }) {
if (!t.isCompatibility) {
const expectedLimit = device.limits[dependentLimitName];
t.expect(
actualLimit === expectedLimit,
`expected actual actualLimit: ${actualLimit} to equal ${dependentLimitName}: ${expectedLimit}`
);
return true;
}
return false;
},
});

function createBindGroupLayout(
Expand Down Expand Up @@ -199,4 +186,8 @@ g.test('createPipeline,at_over')
);
});

testMaxStorageXXXInYYYStageDeviceCreationWithDependentLimit(g, limit, dependentLimitName);
testMaxStorageXXXInYYYStageDeviceCreationWithDependentLimit(
g,
limit,
'maxStorageTexturesPerShaderStage'
);

0 comments on commit a134c34

Please sign in to comment.