1// test fixture with only valid WGSL code. Contains most features of the language.3// directives4diagnostic(error, foo);5diagnostic(error, foo.bar, );6enable f16;7// enable clip_distances, subgroups, ;8requires unrestricted_pointer_parameters;9requires subgroup_id, buffer_view, ;11// global declarations12const c1 = 1;13const c2: u32 = 2;14override o1: f32;15override o2 = 0;16@id(10,) override o3: u32 = 0;17var<private> vp1 = 0;18var<private> vp2: u32 = 0;19var<workgroup> vw1: u32;20@group(0) @binding(1) var<uniform> vu1: u32;21@group(0) @binding(2) var vh1: texture_2d<f32>;22@group(0) @binding(3) var vh2: sampler;23@group(0) @binding(4) var<storage> vs1: u32;24@group(0) @binding(5) var<storage,read> vs2: u32;25@group(0) @binding(6) var<storage,read_write> vs4: u32;26@group(0) @binding(7) var<storage,read_write> vs5: atomic<u32>;27alias a1 = u32;28alias a2 = vec4<f32>;29alias a3 = array<f32, 4>;31// global const asserts32const_assert c1 == 1;33const_assert(c1 < c2);34;36// literals (used later as initializers)37const l1 = 0;38const l2 = 0i;39const l3 = 0u;40const l4 = 123;41const l5 = 456i;42const l6 = 789u;43const l7 = 0x0;44const l8 = 0xff;45const l9 = 0Xffu;46const l10 = 0xFFi;47const l11 = true;48const l12 = false;49const l13 = 0f;50const l14 = 0h;51const l15 = 1f;52const l16 = 1h;53const l17 = 0.5;54const l18 = .5;55const l19 = 1.;56const l20 = 1.5e10;57const l21 = 1.5e-10;58const l22 = 1.5E+10f;59const l23 = 0.5h;60const l24 = 1e10;61const l25 = 1e-10f;62const l26 = 0x1p4;63const l27 = 0x1.8p4;64const l28 = 0x.8p0;65const l29 = 0x1.p0f;66const l30 = 0x1p-4h;68// structs69struct S1 {70 m1: u32,71}73struct S2 {74 m1: u32,75 m2: f32,76}78struct S3 {79 @align(16) m1: u32,80 @size(32) m2: f32,81 @align(8) @size(4) m3: i32,82 m4: vec3<f32>,83 m5: array<u32, 4>,84 m6: S2,85}87struct S4 {88 @location(0) @interpolate(flat) m1: f32,89 @builtin(position) m2: vec4<f32>,90 @location(1) @interpolate(perspective, center) m3: f32,91 @location(2,) @interpolate(linear, centroid,) m4: f32,92 @location(3) @interpolate(flat, first) m5: f32,93 @invariant @builtin(position) m6: vec4<f32>,94}96// types (via alias declarations)97alias t1 = bool;98alias t2 = i32;99alias t3 = u32;100alias t4 = f32;101alias t5 = f16;102alias t6 = vec2<f32>;103alias t7 = vec3<i32>;104alias t8 = vec4<u32>;105alias t9 = vec2f;106alias t10 = vec3i;107alias t11 = vec4u;108alias t12 = vec2h;109alias t13 = mat2x2<f32>;110alias t14 = mat2x3<f32>;111alias t15 = mat2x4<f32>;112alias t16 = mat3x2<f32>;113alias t17 = mat3x3<f32>;114alias t18 = mat3x4<f32>;115alias t19 = mat4x2<f32>;116alias t20 = mat4x3<f32>;117alias t21 = mat4x4<f32>;118alias t22 = mat2x2f;119alias t23 = mat4x4h;120alias t24 = array<f32>;121alias t25 = array<f32, 8>;122alias t26 = array<array<f32, 2>, 3>;123alias t27 = atomic<u32>;124alias t28 = atomic<i32>;125alias t29 = ptr<function, u32>;126alias t30 = ptr<private, f32>;127alias t31 = ptr<workgroup, u32>;128alias t32 = ptr<storage, u32, read>;129alias t33 = ptr<storage, u32, read_write>;130alias t34 = ptr<uniform, vec4<f32>>;131alias t35 = texture_1d<f32>;132alias t36 = texture_2d<f32>;133alias t37 = texture_2d_array<f32>;134alias t38 = texture_3d<f32>;135alias t39 = texture_cube<f32>;136alias t40 = texture_cube_array<f32>;137alias t41 = texture_multisampled_2d<f32>;138alias t42 = texture_depth_2d;139alias t43 = texture_depth_2d_array;140alias t44 = texture_depth_cube;141alias t45 = texture_depth_cube_array;142alias t46 = texture_depth_multisampled_2d;143alias t47 = texture_storage_1d<rgba8unorm, write>;144alias t48 = texture_storage_2d<rgba8unorm, read>;145alias t49 = texture_storage_2d_array<rgba8unorm, read_write>;146alias t50 = texture_storage_3d<rgba32float, write>;147alias t51 = sampler;148alias t52 = sampler_comparison;149alias t53 = texture_external;151// function with no return type and empty body152fn f1() {}154// function with parameters155fn f2(p1: u32, p2: f32) {}157// function with attributes on params, and trailing comma158fn f3(@builtin(vertex_index) p1: u32, p2: f32,) -> u32 {159 return p1;160}162// function with return type and return attribute163fn f4() -> @location(0) vec4<f32> {164 return vec4<f32>(0.0);165}167// must_use attribute168@must_use169fn f5() -> u32 {170 return 0u;171}173// expressions174fn f7() {175 // literals176 let e1 = 1;177 let e2 = 1.0;178 let e3 = true;180 // identifier and template-elaborated identifier181 let e4 = c1;182 let e5 = vec2<f32>();184 // paren expression185 let e6 = (1 + 2);187 // call expressions and constructors188 let e7 = vec3<f32>(1.0, 2.0, 3.0);189 let e8 = vec3f(1.0);190 let e9 = mat2x2<f32>(1.0, 0.0, 0.0, 1.0);191 let e10 = array<u32, 3>(1u, 2u, 3u);192 let e11 = S2(1u, 2.0);193 let e12 = f3(0u, 0.0);194 let e13 = bitcast<u32>(1i);196 // unary operators197 let e14 = -1;198 let e15 = !true;199 let e16 = ~1u;200 var e17 = 1;201 let e18 = &e17;202 let e19 = *e18;204 // binary arithmetic205 let e20 = 1 + 2;206 let e21 = 1 - 2;207 let e22 = 1 * 2;208 let e23 = 1 / 2;209 let e24 = 1 % 2;211 // binary bitwise212 let e25 = 1u & 2u;213 let e26 = 1u | 2u;214 let e27 = 1u ^ 2u;215 let e28 = 1u << 2u;216 let e29 = 1u >> 2u;218 // comparison219 let e30 = 1 < 2;220 let e31 = 1 > 2;221 let e32 = 1 <= 2;222 let e33 = 1 >= 2;223 let e34 = 1 == 2;224 let e35 = 1 != 2;226 // short-circuit227 let e36 = true && false;228 let e37 = true || false;230 // precedence and nesting231 let e38 = 1 + 2 * 3 - 4 / 2;232 let e39 = (1 + 2) * (3 - 4);234 // component and swizzle access235 let e40 = vec4<f32>(1.0, 2.0, 3.0, 4.0);236 let e41 = e40.x;237 let e42 = e40.xy;238 let e43 = e40.xyz;239 let e44 = e40.xyzw;240 let e45 = e40.r;241 let e46 = e40.rgba;242 let e47 = e40[0];243 let e48 = e40.xy[1];245 // member access246 let e49 = e11.m1;247 let e50 = e11.m2;249 // array indexing chained250 var e51 = array<array<u32, 2>, 2>(array<u32, 2>(1u, 2u), array<u32, 2>(3u, 4u));251 let e52 = e51[0][1];252}254// statements255fn f8() {256 // empty statement257 ;259 // variable declarations (let, const, var)260 let s1 = 1;261 let s2: u32 = 1u;262 const s3 = 2;263 const s4: i32 = 2i;264 var s5 = 3;265 var s6: f32 = 3.0;266 var s7: u32;267 var<function> s8: u32;268 var<function> s9 = 0u;270 // assignments271 var s10 = 0;272 s10 = 1;273 s10 += 1;274 s10 -= 1;275 s10 *= 2;276 s10 /= 2;277 s10 %= 2;278 var s11 = 0u;279 s11 &= 1u;280 s11 |= 1u;281 s11 ^= 1u;282 s11 <<= 1u;283 s11 >>= 1u;285 // phony assignment286 _ = 1;287 _ = f5();289 // increment / decrement290 var s12 = 0;291 s12++;292 s12--;294 // assignment through pointer / lhs expressions295 var s13 = 0;296 let s14 = &s13;297 *s14 = 5;298 (*s14) = 6;300 // if statement301 if s10 > 0 {302 s10 = 0;303 }305 // if / else if / else306 if s10 == 0 {307 s10 = 1;308 } else if s10 == 1 {309 s10 = 2;310 } else {311 s10 = 3;312 }314 // if with attribute315 @diagnostic(off, derivative_uniformity)316 if true {317 }319 // switch statement320 switch s10 {321 case 0: {322 s10 = 1;323 }324 case 1, 2: {325 s10 = 2;326 }327 case 3, default: {328 s10 = 3;329 }330 }332 // switch with default alone and no colon333 switch s10 {334 default {335 s10 = 0;336 }337 }339 // loop statement with continuing and break if340 var s15 = 0;341 loop {342 s15 += 1;343 if s15 > 10 {344 break;345 }346 continuing {347 s15 += 1;348 break if s15 > 100;349 }350 }352 // loop with continue353 loop {354 if s15 > 0 {355 break;356 }357 continue;358 }360 // for statement361 for (var s16 = 0; s16 < 10; s16++) {362 s10 += s16;363 }365 // for with empty header parts366 for (;;) {367 break;368 }370 // for with variable_updating_statement371 for (s10++;;s10++) {372 }374 // for with func call init/update375 for (f1(); false; f1()) {376 }378 // while statement379 var s17 = 0;380 while s17 < 10 {381 s17 += 1;382 }384 // compound statement (nested block)385 {386 let s18 = 1;387 {388 let s19 = 2;389 }390 }392 // function call statement393 f1();394 f2(0u, 0.0);396 // const_assert inside function397 const_assert 1 < 2;398}400// function returning value with various return forms401fn f9(p1: bool) -> u32 {402 if p1 {403 return 1u;404 }405 return 0u;406}408// discard is only valid in fragment shaders409@fragment410fn f10() -> @location(0) vec4<f32> {411 if true {412 discard;413 }414 return vec4<f32>(0.0);415}417// entry points with stage attributes418@vertex419fn vert_main(@builtin(vertex_index) p1: u32) -> @builtin(position) vec4<f32> {420 return vec4<f32>(f32(p1));421}423@fragment424fn frag_main(@builtin(position) p1: vec4<f32>, @location(0) @interpolate(flat) p2: f32) -> @location(0) vec4<f32> {425 return vec4<f32,>(p2);426}428@compute @workgroup_size(1)429fn comp_main1() {}431@compute @workgroup_size(8, 8)432fn comp_main2(@builtin(global_invocation_id) p1: vec3<u32>) {}434@compute @workgroup_size(8, 8, 1,)435fn comp_main3(436 @builtin(local_invocation_id) p1: vec3<u32>,437 @builtin(local_invocation_index) p2: u32,438 @builtin(workgroup_id) p3: vec3<u32>,439 @builtin(num_workgroups) p4: vec3<u32>,440) {}442// pointers as parameters443fn f11(p1: ptr<function, u32>) {444 *p1 = 1u;445}447fn f12() {448 var v1 = 0u;449 f11(&v1);450}452// nested member and swizzle write targets453fn f13() {454 var v1 = vec4<f32>(0.0);455 v1.x = 1.0;456 v1[0] = 2.0;457 v1.x += 1.0;459 var v2 = S3();460 v2.m1 = 1u;461 v2.m4.x = 1.0;462 v2.m5[0] = 1u;463}