Partial evaluation validation for constructors (#3820)

Contributes to #3778

* Add tests for partial evaluation errors in value constructors
  * Only constant and runtime values are checked
  * Overrides that are out of range are caught by the API so the WGSL
    would need to use a more complicated expression which should be
    tested elsewhere
This commit is contained in:
alan-baker 2024-06-27 11:03:20 -04:00 committed by GitHub
parent 62a07dc53c
commit 7f49bfcbc7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 75 additions and 0 deletions

View file

@ -2394,6 +2394,7 @@
"webgpu:shader,validation,expression,call,builtin,value_constructor:matrix_elementwise:*": { "subcaseMS": 0.095 },
"webgpu:shader,validation,expression,call,builtin,value_constructor:matrix_zero_value:*": { "subcaseMS": 26.722 },
"webgpu:shader,validation,expression,call,builtin,value_constructor:must_use:*": { "subcaseMS": 61.112 },
"webgpu:shader,validation,expression,call,builtin,value_constructor:partial_eval:*": { "subcaseMS": 276.225 },
"webgpu:shader,validation,expression,call,builtin,value_constructor:scalar_value:*": { "subcaseMS": 39.728 },
"webgpu:shader,validation,expression,call,builtin,value_constructor:scalar_zero_value:*": { "subcaseMS": 538.303 },
"webgpu:shader,validation,expression,call,builtin,value_constructor:struct_value:*": { "subcaseMS": 5.548 },

View file

@ -725,3 +725,77 @@ g.test('must_use')
}`;
t.expectCompileResult(t.params.use, code);
});
g.test('partial_eval')
.desc('Tests that mixed runtime and early eval expressions catch errors')
.params(u =>
u
.combine('eleTy', ['i32', 'u32'] as const)
.combine('compTy', ['array', 'vec2', 'vec3', 'vec4', 'S'] as const)
.combine('stage', ['constant', 'runtime'] as const)
.beginSubcases()
.expandWithParams(t => {
const cases = [];
switch (t.compTy) {
case 'array':
cases.push({ numEles: 2, index: 0 });
cases.push({ numEles: 2, index: 1 });
cases.push({ numEles: 3, index: 0 });
cases.push({ numEles: 3, index: 1 });
cases.push({ numEles: 3, index: 2 });
break;
case 'vec2':
cases.push({ numEles: 2, index: 0 });
cases.push({ numEles: 2, index: 1 });
break;
case 'vec3':
cases.push({ numEles: 3, index: 0 });
cases.push({ numEles: 3, index: 1 });
cases.push({ numEles: 3, index: 2 });
break;
case 'vec4':
cases.push({ numEles: 4, index: 0 });
cases.push({ numEles: 4, index: 1 });
cases.push({ numEles: 4, index: 2 });
cases.push({ numEles: 4, index: 3 });
break;
case 'S':
cases.push({ numEles: 2, index: 0 });
cases.push({ numEles: 2, index: 1 });
break;
}
return cases;
})
)
.fn(t => {
const eleTy = Type['abstract-int'];
const value = t.params.eleTy === 'i32' ? 0xfffffffff : -1;
let compParams = '';
for (let i = 0; i < t.params.numEles; i++) {
if (t.params.index === i) {
switch (t.params.stage) {
case 'constant':
compParams += `${eleTy.create(value).wgsl()}, `;
break;
case 'runtime':
compParams += `v, `;
break;
}
} else {
compParams += `v, `;
}
}
const wgsl = `
struct S {
x : ${t.params.eleTy},
y : ${t.params.eleTy},
}
fn foo() {
var v : ${t.params.eleTy};
let tmp = ${t.params.compTy}(${compParams});
}`;
const shader_error = t.params.stage === 'constant';
t.expectCompileResult(!shader_error, wgsl);
});