1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
export const description = `Validation tests for static_assert`;
import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { ShaderValidationTest } from '../shader_validation_test.js';
export const g = makeTestGroup(ShaderValidationTest);
/**
* Builds a static_assert() statement, which checks that @p expr is equal to @p expect_true.
* @param expect_true true if @p expr should evaluate to true
* @param expr the constant expression
* @param scope module-scope or function-scope constant expression
* @returns the WGSL code
*/
function buildStaticAssert(expect_true: boolean, expr: string, scope: 'module' | 'function') {
const stmt = expect_true ? `static_assert ${expr};` : `static_assert !(${expr});`;
return scope === 'module' ? stmt : `fn f() { ${stmt} }`;
}
const kConditionCases = {
true_literal: `true`,
not_false: `!false`,
const_eq_literal_int: `one == 1`,
const_eq_literal_float: `one == 1.0`,
binary_op_eq_const: `one+1 == two`,
any: `any(vec3(false, true, false))`,
min_max: `min(three, max(two, one)) == 2`,
};
g.test('constant_expression')
.desc(`Test that static_assert validates the condition expression.`)
.params(u =>
u
.combine('case', Object.keys(kConditionCases) as Array<keyof typeof kConditionCases>)
.combine('scope', ['module', 'function'] as const)
.beginSubcases()
)
.fn(t => {
const constants = `
const one = 1;
const two = 2;
const three = 2;
`;
const expr = kConditionCases[t.params.case];
t.expectCompileResult(true, constants + buildStaticAssert(true, expr, t.params.scope));
t.expectCompileResult(false, constants + buildStaticAssert(false, expr, t.params.scope));
});
g.test('evaluation_stage')
.desc(`Test that the static_assert expression must be a constant expression.`)
.params(u =>
u
.combine('scope', ['module', 'function'] as const)
.combine('stage', ['constant', 'override', 'runtime'] as const)
.beginSubcases()
)
.fn(t => {
const staticAssert = buildStaticAssert(true, 'value', t.params.scope);
switch (t.params.stage) {
case 'constant':
t.expectCompileResult(true, `const value = true;\n${staticAssert}`);
break;
case 'override':
t.expectCompileResult(false, `override value = true;\n${staticAssert}`);
break;
case 'runtime':
t.expectCompileResult(false, `var<private> value = true;\n${staticAssert}`);
break;
}
});
|