tint: Experimental Static Samplers Extension

Add a file describing the experimental static sampler extension.

Change-Id: I7d211ba1afc252d60c956dce21824df1e6105689
Bug: 345117909
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/192180
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: Srijan Dhungana <srijan.dhungana6@gmail.com>
diff --git a/docs/tint/extensions/chromium_experimental_static_samplers.md b/docs/tint/extensions/chromium_experimental_static_samplers.md
new file mode 100644
index 0000000..5d9d885
--- /dev/null
+++ b/docs/tint/extensions/chromium_experimental_static_samplers.md
@@ -0,0 +1,118 @@
+# Chromium Experimental Static Samplers
+
+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.
+
+# Status
+
+This extension is experimental and the syntax is being discussed. No official WebGPU specification has been written yet.
+
+# Design considerations
+
+## const or var
+
+`@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.
+
+## Using a struct
+
+```wgsl
+@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.
+
+## Using a function
+
+```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
+
+```wgsl
+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.
+
+# Pseudo-specification
+
+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:
+- The function can only be called to initialize a static sampler.
+- Only built-in functions can return a sampler, user-defined functions cannot.
+- The function can not be used in an expression, only in a declaration.
+
+Order of arguments:
+- addressModeU
+- addressModeV
+- addressModeW
+- magFilter
+- minFilter
+- mipmapFilter
+- compare (only for `sampler_comparison(...)`)
+- lodMinClamp
+- lodMaxClamp
+
+New Constants:
+- Address Mode:
+  - WGSL: `clamp_to_edge=0`, `repeat=1`, `mirror_repeat=2`
+  - WebGPU equivalent: `"clamp-to-edge"`, `"repeat"`, `"mirror-repeat"`
+- Filter Mode:
+  - WGSL: `nearest=0`, `linear=1`
+  - WebGPU equivalent: `"nearest"`, `"linear"`
+- Mipmap Filter Mode:
+  - WGSL: `mipmap_nearest=0`, `mipmap_linear=1`
+  - WebGPU equivalent: `"nearest"`, `"linear"`
+- Comparison Function:
+  - WGSL: `never=0`, `less=1`, `equal=2`, `less_equal=3`, `greater=4`, `not_equal=5`, `greater_equal=6`, `always=7`
+  - WebGPU equivalent: `"never"`, `"less"`, `"equal"`, `"less-equal"`, `"greater"`, `"not-equal"`, `"greater-equal"`, `"always"`
+
+# Example usage
+
+```wgsl
+@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)
+
+```
+