summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/tests/cts/checkout/src/webgpu/shader/validation/shader_io/invariant.spec.ts
blob: 6ae34806613790cc75f5951b5c6a282b538f8af0 (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
export const description = `Validation tests for the invariant attribute`;

import { makeTestGroup } from '../../../../common/framework/test_group.js';
import { ShaderValidationTest } from '../shader_validation_test.js';

import { kBuiltins } from './builtins.spec.js';
import { generateShader } from './util.js';

export const g = makeTestGroup(ShaderValidationTest);

g.test('valid_only_with_vertex_position_builtin')
  .desc(`Test that the invariant attribute is only accepted with the vertex position builtin`)
  .params(u =>
    u
      .combineWithParams(kBuiltins)
      .combine('use_struct', [true, false] as const)
      .beginSubcases()
  )
  .fn(t => {
    const code = generateShader({
      attribute: `@builtin(${t.params.name}) @invariant`,
      type: t.params.type,
      stage: t.params.stage,
      io: t.params.io,
      use_struct: t.params.use_struct,
    });

    t.expectCompileResult(t.params.name === 'position', code);
  });

g.test('not_valid_on_user_defined_io')
  .desc(`Test that the invariant attribute is not accepted on user-defined IO attributes.`)
  .params(u => u.combine('use_invariant', [true, false] as const).beginSubcases())
  .fn(t => {
    const invariant = t.params.use_invariant ? '@invariant' : '';
    const code = `
    struct VertexOut {
      @location(0) ${invariant} loc0 : vec4<f32>,
      @builtin(position) position : vec4<f32>,
    };
    @vertex
    fn main() -> VertexOut {
      return VertexOut();
    }
    `;
    t.expectCompileResult(!t.params.use_invariant, code);
  });

g.test('invalid_use_of_parameters')
  .desc(`Test that no parameters are accepted for the invariant attribute`)
  .params(u => u.combine('suffix', ['', '()', '(0)'] as const).beginSubcases())
  .fn(t => {
    const code = `
    struct VertexOut {
      @builtin(position) @invariant${t.params.suffix} position : vec4<f32>
    };
    @vertex
    fn main() -> VertexOut {
      return VertexOut();
    }
    `;
    t.expectCompileResult(t.params.suffix === '', code);
  });

g.test('duplicate')
  .desc(`Test that the invariant attribute can only be applied once.`)
  .params(u =>
    u
      .combineWithParams(kBuiltins)
      .combine('use_struct', [true, false] as const)
      .combine('attr', ['', '@invariant'] as const)
      .beginSubcases()
  )
  .fn(t => {
    if (t.params.name !== 'position') {
      t.skip('only valid with position');
    }

    const code = generateShader({
      attribute: `@builtin(${t.params.name}) @invariant ${t.params.attr}`,
      type: t.params.type,
      stage: t.params.stage,
      io: t.params.io,
      use_struct: t.params.use_struct,
    });

    t.expectCompileResult(t.params.attr === '', code);
  });