The chromium_experimental_static_samplers extension is an experimental extension that allows the use of static samplers in WGSL. Static samplers translate to immutable samplers in Vulkan, constexpr samplers in Metal Shading Language, and static samplers in Direct3D 12.
This extension is experimental and the syntax is being discussed. No official WebGPU specification has been written yet.
@group(X) @binding(Y) const mySampler;
or @group(X) @binding(Y) var mySampler;
In HLSL and SPIR-V, static samplers need a binding slot, hence the @group(X) @binding(Y)
syntax. Vulkan and Direct3D 12 supply static samplers via the API. Metal Shading Language declares static samplers with constexpr
, which is ready to be used in the shader without Metal API interaction.
Normal samplers in WGSL are declared with var
because they have a handle address space, which is read-only. Using the const
keyword for static samplers is sensible, as static samplers are immutable objects. However, const
does not have a handle address space which is required for HLSL and SPIR-V and would require spec changes to support it.
Using var
for static samplers is recommended for consistency with the rest of the language and they are already immutable.
@group(X) @binding(Y) const mySampler = sampler { addressModeU: mirror_repeat, // enumerant magFilter: linear, lodMinClamp: 1, // abstract float ... };
The sampler
is a built-in struct that can be used to define samplers. Advantages are its readability and similarity to the WebGPU API's GPUSamplerDescriptor
struct.
This approach would require a new WGSL feature for initializing struct values.
If the new WGSL feature is introduced, this approach is recommended for readability and intuitiveness. However, for the initial implementation, it is not desirable to introduce a substantial change in WGSL.
const clamp_to_edge = 0; const mirror_repeat = 1; ... sampler(mirror_repeat, linear, 0.0, 16); sampler_comparison(mirror_repeat, linear, 0.0, 16);
or
sampler<mirror_repeat, linear>(0.0, 16); sampler_comparison<mirror_repeat, linear>(0.0, 16);
In both cases, sampler
is a built-in function that returns a static sampler. The first approach takes a list of arguments. These arguments are predefined constant values and not enums. The second approach takes a list of enum template parameters and a list of arguments. The arguments are LOD min and max clamps, because they are not enums.
Both approaches are readable and intuitive but due to the large amount of parameters that can be set on a sampler, the approaches may become hard to read and write. The approaches do not need any new WGSL features and are sufficient for a prototype implementation.
For the prototype implementation, the first function approach is good for its simplicity.
This extension adds sampler(...)
and sampler_comparison(...)
functions to return a sampler type. The functions take integer values that are predefined constants. If a sampler is initialized with any of the two functions, it is considered a static sampler, otherwise it is a normal sampler. The predefined constant variable names are similar to the WebGPU API enums.
Function restrictions include:
Order of arguments:
sampler_comparison(...)
)New Constants:
clamp_to_edge=0
, repeat=1
, mirror_repeat=2
"clamp-to-edge"
, "repeat"
, "mirror-repeat"
nearest=0
, linear=1
"nearest"
, "linear"
mipmap_nearest=0
, mipmap_linear=1
"nearest"
, "linear"
never=0
, less=1
, equal=2
, less_equal=3
, greater=4
, not_equal=5
, greater_equal=6
, always=7
"never"
, "less"
, "equal"
, "less-equal"
, "greater"
, "not-equal"
, "greater-equal"
, "always"
@group(0) @binding(0) var mySampler = sampler(mirror_repeat, clamp_to_edge, mirror_repeat, linear, linear, mipmap_linear, 0.0, 16.0) @group(0) @binding(1) var myComparisonSampler = sampler_comparison(mirror_repeat, clamp_to_edge, mirror_repeat, linear, linear, mipmap_linear, less, 0.0, 16.0)