Search across packages, versions, files, declarations, and comments. Use multiple terms to narrow results (AND), and add @vertex, @fragment, or @compute to filter by shader stage.
1// Root module of the package (module path `package`).
2// The test runner compiles this fixture twice:
3// run "toml_feat1": feat1 = true, feat2 = false
4// run "toml_feat2": feat1 = false, feat2 = true
5// and provides the virtual constants PI = 3.1415 and TRUE = true,
6// plus the `random_wgsl` package (renamed `random` in wesl.toml).
8// -- conditional import statements (@if/@else on imports) --------------------
9// both bind the name `op`, only one survives conditional translation.
10@if(feat1)
11import package::util::ops::scale as op;
12@else
13import package::util::ops::shift as op;
15// -- the `constants` virtual module ------------------------------------------
16import constants::{PI, TRUE};
18// -- import statements: single item, collections, nested collections,
19// -- wildcard as a member of a collection ------------------------------------
20// TODO: wildcards
21// import package::util::{dot2, ops::{double, *}}; // flattens to dot2, ops::double, ops::*
22import package::util::{dot2, ops::{double, scale, shift, OPS_BASE}}; // flattens to dot2, ops::double, ops::*
24// wildcard import of a module that only contains re-exports (`public import`).
25// brings `pdot2`, `x2` and `dbl` into scope.
26// TODO: wildcards
27// import package::prelude::*;
28import package::prelude::{pdot2, x2, dbl};
30// modules that circularly import each other (cycle_a <-> cycle_b).
31import package::cycle_a::ping2;
33// module testing shadowing rules.
34import package::shadow::shadowed_fn;
36// plain WGSL file used as a WESL module (.wgsl fallback).
37import package::legacy::legacy_fn;
39// deeply nested submodule (itself uses `super::super::` imports).
40import package::util::deep::mix::mix2;
42// package (external dependency) import statement.
43import random::hash::rand11;
45// helper from the module whose entry points are re-exported below.
46import package::gfx::tonemap;
48// -- visibility and re-exports (public imports) -------------------------------
49// re-exported entry points, resource variable and override become part of the
50// pipeline-visible API of this entry module, keeping their (aliased) names.
51public import package::gfx::{vert_main, frag_main as fs_main};
52public import package::gfx::scene_data;
53public import package::gfx::exposure;
55// -- conditional directives ---------------------------------------------------
56@if(feat2)
57diagnostic(off, derivative_uniformity);
59// -- conditional global declarations ------------------------------------------
60// @if/@elif/@else chain on global const declarations.
61@if(feat1)
62const K: f32 = 1.0;
63@elif(feat2)
64const K: f32 = 2.0;
65@else
66const K: f32 = 3.0;
68// conditional type alias declarations. `Vec(0.5)` is valid with both.
69@if(feat1)
70alias Vec = vec2f;
71@else
72alias Vec = vec3f;
74// conditional module-scope var, only referenced under the same condition.
75@if(feat2)
76var<private> counter: u32 = 0u;
78// conditional override declarations.
79@if(feat1)
80override root_boost: f32 = 1.0;
81@else
82override root_boost: f32 = 2.0;
84// visibility keywords on global declarations:
85// `private` = visible only in this module, no keyword = package-visible.
86private const ROOT_SECRET: f32 = 0.5;
88// this *declaration* shares its name with the *module* `package::util`
89// (util.wesl): modules and declarations live in separate namespaces.
90// `gfx.wesl` imports `package::util` and uses both `util()` and `util::dot2`.
91public fn util() -> f32 {
92 return ROOT_SECRET * 8.0;
95// -- conditional struct declarations and struct members ------------------------
96@if(feat1)
97struct Aux {
98 n: u32,
100@else
101struct Aux {
102 n: u32,
103 extra_field: f32,
106struct Config {
107 size: f32,
108 // @if/@elif/@else chain on struct members.
109 @if(feat1)
110 extra: vec2f,
111 @elif(feat2)
112 extra: vec3f,
113 @else
114 extra: f32,
117// -- conditional global const assertions ---------------------------------------
118const_assert TRUE; // uses the virtual bool constant
119const_assert PI > 3.0;
120@if(feat1)
121const_assert K == 1.0;
122@elif(feat2)
123const_assert K == 2.0;
125// -- conditional function declarations and formal parameters -------------------
126// `boost` only exists when feat2 is enabled; call sites are guarded the same way.
127fn weight(x: f32, @if(feat2) boost: f32) -> f32 {
128 // conditional return statements.
129 @if(feat2)
130 return x * boost;
131 @else
132 return x;
135// a second entry point, conditionally translated (workgroup size differs).
136@if(feat1)
137@compute @workgroup_size(1)
138fn variant() {
139 scene_data[0] = vec4f(K);
141@else
142@compute @workgroup_size(2)
143fn variant() {
144 scene_data[1] = vec4f(K);
147@compute @workgroup_size(1)
148fn my_compute(@builtin(global_invocation_id) gid: vec3u) {
149 // -- inline imports (fully qualified paths in expressions) -----------------
150 let inline_pkg = package::util::norm2(vec2f(1.0, 2.0));
151 let inline_dep = random::noise::value::value_noise(2.0);
153 // named imports and virtual constants.
154 let a = dot2(vec2f(PI), vec2f(1.0));
155 let b = double(a) + K + root_boost;
156 let c = op(b); // conditionally-imported binding (scale or shift)
157 let d = OPS_BASE; // brought in by the wildcard `ops::*`
158 let e = pdot2(vec2f(d), vec2f(1.0)) + x2(vec2f(a), vec2f(b)) + dbl(c); // prelude re-exports
159 let f = ping2(e); // circular modules
160 let g = shadowed_fn(f); // shadowing tests
161 let h = legacy_fn(g); // plain WGSL module
162 let i = rand11(h) + mix2(inline_pkg) + tonemap(vec2f(inline_dep));
164 // conditional local declarations (@if/@elif/@else on statements).
165 @if(feat1)
166 let cond = K * 1.0;
167 @elif(feat2)
168 let cond = K * 2.0;
169 @else
170 let cond = K * 3.0;
172 var acc = 0.0;
174 // conditional assignment / compound assignment statements.
175 @if(feat1)
176 acc += cond;
177 @if(feat2)
178 acc = cond;
180 // conditional increment / phony-assignment on the feat2-only global.
181 @if(feat2)
182 counter++;
183 @if(feat2)
184 _ = counter;
186 // conditional function call statement.
187 @if(feat1)
188 workgroupBarrier();
190 // conditionally-translated struct construction, matching Config's members.
191 @if(feat1)
192 let cfg = Config(1.0, vec2f(0.0));
193 @elif(feat2)
194 let cfg = Config(1.0, vec3f(0.0));
195 @else
196 let cfg = Config(1.0, 0.0);
197 acc += cfg.size;
199 // conditional alias in use.
200 let v = Vec(0.5);
201 acc += v.x;
203 @if(feat1)
204 let aux = Aux(gid.x);
205 @else
206 let aux = Aux(gid.x, 0.5);
207 acc += f32(aux.n);
209 // guarded call of the function with a conditional parameter.
210 @if(feat2)
211 acc += weight(a, 2.0);
212 @else
213 acc += weight(a);
215 // bool virtual constant in a regular expression.
216 if TRUE {
217 acc += 1.0;
218 }
220 // conditional switch clauses (@if/@elif on case clauses).
221 switch gid.x {
222 @if(feat1)
223 case 1u: {
224 acc += 1.0;
225 }
226 @elif(feat2)
227 case 2u: {
228 acc += 2.0;
229 }
230 @if(feat2)
231 case 3u, 4u: {
232 acc += 3.0;
233 }
234 default: {
235 acc += 0.5;
236 }
237 }
239 // conditional break / continue statements.
240 for (var t = 0u; t < 4u; t++) {
241 @if(feat2)
242 continue;
243 @if(feat1)
244 break;
245 }
247 // conditional const assertion inside a function body.
248 @if(feat1)
249 const_assert 1 < 2;
251 // write through the re-exported resource variable.
252 scene_data[gid.x] = vec4f(acc + b + c + e + g + i);
Contents