| export const description = `Validation tests for attributes`; |
| |
| import { makeTestGroup } from '../../../../common/framework/test_group.js'; |
| import { keysOf } from '../../../../common/util/data_tables.js'; |
| import { ShaderValidationTest } from '../shader_validation_test.js'; |
| |
| export const g = makeTestGroup(ShaderValidationTest); |
| |
| const kPossibleValues = { |
| val: '32', |
| expr: '30 + 2', |
| override: 'a_override', |
| user_func: 'a_func()', |
| const_func: 'min(4, 8)', |
| const: 'a_const', |
| }; |
| const kAttributeUsage = { |
| align: '@align($val)', |
| binding: '@binding($val) @group(0)', |
| group: '@binding(1) @group($val)', |
| id: '@id($val)', |
| location: '@location($val)', |
| size: '@size($val)', |
| workgroup_size: '@workgroup_size($val, $val, $val)', |
| }; |
| const kAllowedUsages = { |
| align: ['val', 'expr', 'const', 'const_func'], |
| binding: ['val', 'expr', 'const', 'const_func'], |
| group: ['val', 'expr', 'const', 'const_func'], |
| id: ['val', 'expr', 'const', 'const_func'], |
| location: ['val', 'expr', 'const', 'const_func'], |
| size: ['val', 'expr', 'const', 'const_func'], |
| workgroup_size: ['val', 'expr', 'const', 'const_func', 'override'], |
| }; |
| |
| g.test('expressions') |
| .desc(`Tests attributes which allow expressions`) |
| .params(u => |
| u.combine('value', keysOf(kPossibleValues)).combine('attribute', keysOf(kAllowedUsages)) |
| ) |
| .fn(t => { |
| const attributes = { |
| align: '', |
| binding: '@binding(0) @group(0)', |
| group: '@binding(1) @group(1)', |
| id: '@id(2)', |
| location: '@location(0)', |
| size: '', |
| workgroup_size: '@workgroup_size(1)', |
| }; |
| |
| const val = kPossibleValues[t.params.value]; |
| attributes[t.params.attribute] = kAttributeUsage[t.params.attribute].replace(/(\$val)/g, val); |
| |
| const code = ` |
| fn a_func() -> i32 { |
| return 4; |
| } |
| |
| const a_const = -2 + 10; |
| override a_override: i32 = 2; |
| |
| ${attributes.id} override my_id: i32 = 4; |
| |
| struct B { |
| ${attributes.align} ${attributes.size} a: i32, |
| } |
| |
| ${attributes.binding} |
| var<uniform> uniform_buffer_1: B; |
| |
| ${attributes.group} |
| var<uniform> uniform_buffer_2: B; |
| |
| @fragment |
| fn main() -> ${attributes.location} vec4<f32> { |
| return vec4<f32>(.4, .2, .3, .1); |
| } |
| |
| @compute |
| ${attributes.workgroup_size} |
| fn compute_main() {} |
| `; |
| |
| const pass = kAllowedUsages[t.params.attribute].includes(t.params.value); |
| t.expectCompileResult(pass, code); |
| }); |