From 5a1465ee97cb3b2f864b8ccfaa3cf58d2cdf8344 Mon Sep 17 00:00:00 2001 From: Brandon Jones Date: Wed, 13 Mar 2024 15:01:33 -0700 Subject: [PATCH] Add validation test for min/max builtin functions --- src/webgpu/listing_meta.json | 6 ++ .../expression/call/builtin/max.spec.ts | 85 +++++++++++++++++++ .../expression/call/builtin/min.spec.ts | 85 +++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 src/webgpu/shader/validation/expression/call/builtin/max.spec.ts create mode 100644 src/webgpu/shader/validation/expression/call/builtin/min.spec.ts diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index 99efc128226d..ad476a77944c 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -1896,6 +1896,12 @@ "webgpu:shader,validation,expression,call,builtin,log2:values:*": { "subcaseMS": 0.398 }, "webgpu:shader,validation,expression,call,builtin,log:integer_argument:*": { "subcaseMS": 1.134 }, "webgpu:shader,validation,expression,call,builtin,log:values:*": { "subcaseMS": 0.291 }, + "webgpu:shader,validation,expression,call,builtin,max:bad_args:*": { "subcaseMS": 79.423 }, + "webgpu:shader,validation,expression,call,builtin,max:must_use:*": { "subcaseMS": 8.286 }, + "webgpu:shader,validation,expression,call,builtin,max:values:*": { "subcaseMS": 260241.074 }, + "webgpu:shader,validation,expression,call,builtin,min:bad_args:*": { "subcaseMS": 40.137 }, + "webgpu:shader,validation,expression,call,builtin,min:must_use:*": { "subcaseMS": 3.899 }, + "webgpu:shader,validation,expression,call,builtin,min:values:*": { "subcaseMS": 246733.594 }, "webgpu:shader,validation,expression,call,builtin,modf:integer_argument:*": { "subcaseMS": 1.089 }, "webgpu:shader,validation,expression,call,builtin,modf:values:*": { "subcaseMS": 1.866 }, "webgpu:shader,validation,expression,call,builtin,pack4xI8:bad_args:*": { "subcaseMS": 40.750 }, diff --git a/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts new file mode 100644 index 000000000000..a1cfabeb00c0 --- /dev/null +++ b/src/webgpu/shader/validation/expression/call/builtin/max.spec.ts @@ -0,0 +1,85 @@ +const builtin = 'max'; +export const description = ` +Validation tests for the ${builtin}() builtin. +`; + +import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; +import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; +import { + Type, + kAllNumericScalarsAndVectors, + scalarTypeOf, +} from '../../../../../util/conversion.js'; +import { ShaderValidationTest } from '../../../shader_validation_test.js'; + +import { + fullRangeForType, + kConstantAndOverrideStages, + stageSupportsType, + validateConstOrOverrideBuiltinEval, +} from './const_override_validation.js'; + +export const g = makeTestGroup(ShaderValidationTest); + +const kValuesTypes = objectsToRecord(kAllNumericScalarsAndVectors); + +g.test('values') + .desc( + ` +Validates that constant evaluation and override evaluation of ${builtin}() never errors +` + ) + .params(u => + u + .combine('stage', kConstantAndOverrideStages) + .combine('type', keysOf(kValuesTypes)) + .filter(u => stageSupportsType(u.stage, kValuesTypes[u.type])) + .beginSubcases() + .expand('a', u => fullRangeForType(kValuesTypes[u.type])) + .expand('b', u => fullRangeForType(kValuesTypes[u.type])) + ) + .beforeAllSubcases(t => { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { + t.selectDeviceOrSkipTestCase('shader-f16'); + } + }) + .fn(t => { + const type = kValuesTypes[t.params.type]; + const expectedResult = true; // should never error + validateConstOrOverrideBuiltinEval( + t, + builtin, + expectedResult, + [type.create(t.params.a), type.create(t.params.b)], + t.params.stage + ); + }); + +const kGoodArgs = '(1.1, 2.2)'; +const kBadArgs = { + no_parens: '', + // Bad number of args + '0args': '()', + '1arg': '(1.0)', + // Bad value for arg 0 + '0bool': '(false, 1.0)', + '0array': '(array(1.1,2.2), 1.0)', + '0struct': '(modf(2.2), 1.0)', + // Bad value for arg 1 + '1bool': '(1.0, true)', + '1array': '(1.0, array(1.1,2.2))', + '1struct': '(1.0, modf(2.2))', +}; + +g.test('bad_args') + .desc(`Test compilation failure of ${builtin} with bad arguments`) + .params(u => u.combine('arg', keysOf(kBadArgs))) + .fn(t => { + t.expectCompileResult(false, `const c = ${builtin}${kBadArgs[t.params.arg]};`); + }); + +g.test('must_use') + .desc(`Result of ${builtin} must be used`) + .fn(t => { + t.expectCompileResult(false, `fn f() { ${builtin}${kGoodArgs}; }`); + }); diff --git a/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts b/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts new file mode 100644 index 000000000000..f31d8971e133 --- /dev/null +++ b/src/webgpu/shader/validation/expression/call/builtin/min.spec.ts @@ -0,0 +1,85 @@ +const builtin = 'min'; +export const description = ` +Validation tests for the ${builtin}() builtin. +`; + +import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; +import { keysOf, objectsToRecord } from '../../../../../../common/util/data_tables.js'; +import { + Type, + kAllNumericScalarsAndVectors, + scalarTypeOf, +} from '../../../../../util/conversion.js'; +import { ShaderValidationTest } from '../../../shader_validation_test.js'; + +import { + fullRangeForType, + kConstantAndOverrideStages, + stageSupportsType, + validateConstOrOverrideBuiltinEval, +} from './const_override_validation.js'; + +export const g = makeTestGroup(ShaderValidationTest); + +const kValuesTypes = objectsToRecord(kAllNumericScalarsAndVectors); + +g.test('values') + .desc( + ` +Validates that constant evaluation and override evaluation of ${builtin}() never errors +` + ) + .params(u => + u + .combine('stage', kConstantAndOverrideStages) + .combine('type', keysOf(kValuesTypes)) + .filter(u => stageSupportsType(u.stage, kValuesTypes[u.type])) + .beginSubcases() + .expand('a', u => fullRangeForType(kValuesTypes[u.type])) + .expand('b', u => fullRangeForType(kValuesTypes[u.type])) + ) + .beforeAllSubcases(t => { + if (scalarTypeOf(kValuesTypes[t.params.type]) === Type.f16) { + t.selectDeviceOrSkipTestCase('shader-f16'); + } + }) + .fn(t => { + const type = kValuesTypes[t.params.type]; + const expectedResult = true; // should never error + validateConstOrOverrideBuiltinEval( + t, + builtin, + expectedResult, + [type.create(t.params.a), type.create(t.params.b)], + t.params.stage + ); + }); + +const kGoodArgs = '(1.1, 2.2)'; +const kBadArgs = { + no_parens: '', + // Bad number of args + '0args': '()', + '1arg': '(1.0)', + // Bad value for arg 0 + '0bool': '(false, 1.0)', + '0array': '(array(1.1,2.2), 1.0)', + '0struct': '(modf(2.2), 1.0)', + // Bad value for arg 1 + '1bool': '(1.0, true)', + '1array': '(1.0, array(1.1,2.2))', + '1struct': '(1.0, modf(2.2))', +}; + +g.test('bad_args') + .desc(`Test compilation failure of ${builtin} with bad arguments`) + .params(u => u.combine('arg', keysOf(kBadArgs))) + .fn(t => { + t.expectCompileResult(false, `const c = ${builtin}${kBadArgs[t.params.arg]};`); + }); + +g.test('must_use') + .desc(`Result of ${builtin} must be used`) + .fn(t => { + t.expectCompileResult(false, `fn f() { ${builtin}${kGoodArgs}; }`); + });