summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/tests/cts/checkout/src/webgpu/shader/validation/static_assert/static_assert.spec.ts
blob: 24db6bd5af7bed82616b0187c240e47d11eb701e (plain)
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;
    }
  });