Source browser

shdr.h

Read the complete file below or download its original bytes. Line numbers provide stable links to a declaration or processing step.

File fingerprint
1// shdr 1.0.0
2// C++11 CPU and OpenGL compute pipelines.
3#ifndef SHDR_SINGLE_HEADER_INCLUDED
4#define SHDR_SINGLE_HEADER_INCLUDED
5
6// ---- math.hpp ----
7/** @file math.hpp
8 * @brief GLSL-compatible scalar, vector and matrix operations for C++11.
9 *
10 * Vectors provide x/y/z/w component fields, indexed access, and writable
11 * swizzles. Color and texture-coordinate aliases are accessor functions in
12 * ordinary C++ code. Matrices use GLSL column-major order. The same types and
13 * functions are available to generated CPU kernels and application code.
14 *
15 * Floating-point precision and exceptional values depend on the implementation.
16 * Normalize nonzero vectors, invert nonsingular matrices and use valid shift
17 * counts. Keep signed arithmetic within its representable range and use
18 * nonnegative signed operands for left shifts to follow portable C++ rules.
19 * Resource element layout is defined by the buffer and image APIs separately.
20 */
21#ifndef SHDR_DETAIL_MATH_HPP // Include this math layer only once.
22#define SHDR_DETAIL_MATH_HPP // Remember that the math layer is available.
23#include <cmath> // Use the standard scalar math functions.
24#include <cstddef> // Use portable size types.
25#include <cstdint> // Use exact-width GLSL integer types.
26#include <cstring> // Copy bit patterns through byte storage.
27#include <initializer_list> // Accept ordinary C++ brace lists.
28#include <limits> // Query numeric limits and quiet NaNs.
29#include <ostream> // Support readable vector and matrix output.
30#include <stdexcept> // Report invalid array initializers.
31#include <type_traits> // Choose only compatible template overloads.
32namespace shdr { // Keep these names inside the shdr namespace.
33namespace glsl { // Keep these names inside the glsl namespace.
34/** @brief GLSL's portable 32-bit unsigned scalar spelling. */
35typedef std::uint32_t uint; // Use a portable 32-bit unsigned scalar.
36template <class T, std::size_t N> class vec; // Store a fixed-size vector with named component fields.
37template <class T, std::size_t N> class array; // Store a fixed number of values of one element type.
38template <class T, std::size_t N, std::size_t... I> class swizzle_ref; // Describe a component selection that refers to a vector.
39template <class T, std::size_t C, std::size_t R> class mat; // Describe a matrix by its scalar type and dimensions.
40namespace detail { // Keep these names inside the detail namespace.
41template <class T, std::size_t N> struct storage; // Choose named storage for the vector dimension.
42template <class T> struct storage<T, 2> { // Choose named storage for the vector dimension.
43    T x, y; // Store the named vector components in order.
44    T& at(std::size_t i) { // Select the named component matching this index.
45        return i == 0 ? x : y; // Select the named field for this valid component index.
46    } // Finish the at operation.
47    const T& at(std::size_t i) const { // Select the named component matching this index.
48        return i == 0 ? x : y; // Select the named field for this valid component index.
49    } // Finish the at operation.
50}; // Finish the storage type description.
51template <class T> struct storage<T, 3> { // Choose named storage for the vector dimension.
52    T x, y, z; // Store the named vector components in order.
53    T& at(std::size_t i) { // Select the named component matching this index.
54        return i == 0 ? x : (i == 1 ? y : z); // Select the named field for this valid component index.
55    } // Finish the at operation.
56    const T& at(std::size_t i) const { // Select the named component matching this index.
57        return i == 0 ? x : (i == 1 ? y : z); // Select the named field for this valid component index.
58    } // Finish the at operation.
59}; // Finish the storage type description.
60template <class T> struct storage<T, 4> { // Choose named storage for the vector dimension.
61    T x, y, z, w; // Store the named vector components in order.
62    T& at(std::size_t i) { // Select the named component matching this index.
63        return i == 0 ? x : (i == 1 ? y : (i == 2 ? z : w)); // Select the named field for this valid component index.
64    } // Finish the at operation.
65    const T& at(std::size_t i) const { // Select the named component matching this index.
66        return i == 0 ? x : (i == 1 ? y : (i == 2 ? z : w)); // Select the named field for this valid component index.
67    } // Finish the at operation.
68}; // Finish the storage type description.
69template <class A> struct shape { // Describe an ordinary scalar input.
70    typedef A scalar; // Keep the chosen component type for the calculation.
71    static const std::size_t size = 1; // Treat a scalar as one component.
72    static const bool vector = false; // Keep this input out of vector-only overloads.
73    static const bool valid = std::is_arithmetic<A>::value; // Record whether componentwise arithmetic accepts this shape.
74}; // Finish the shape type description.
75template <class T, std::size_t N> struct shape<vec<T, N>> { // Describe the scalar type and size of a vector.
76    typedef T scalar; // Keep the chosen component type for the calculation.
77    static const std::size_t size = N; // Keep the fixed component count available at compile time.
78    static const bool vector = true; // Mark this input as a vector-shaped value.
79    static const bool valid = true; // Record whether componentwise arithmetic accepts this shape.
80}; // Finish the shape type description.
81template <class T, std::size_t N, std::size_t... I> struct shape<swizzle_ref<T, N, I...>> { // Describe the scalar type and size of a component selection.
82    typedef T scalar; // Keep the chosen component type for the calculation.
83    static const std::size_t size = sizeof...(I); // Count the selected vector components.
84    static const bool vector = true; // Mark this input as a vector-shaped value.
85    static const bool valid = true; // Record whether componentwise arithmetic accepts this shape.
86}; // Finish the shape type description.
87template <class A> struct traits : shape<typename std::decay<A>::type> {}; // Ignore references and const when inspecting an input type.
88template <class... A> struct count; // Count components supplied by constructor arguments.
89template <> struct count<> { // Count components supplied by constructor arguments.
90    static const std::size_t value = 0; // Start the component count at zero.
91}; // Finish the count type description.
92template <class A, class... B> struct count<A, B...> { // Count components supplied by constructor arguments.
93    static const std::size_t value = traits<A>::size + count<B...>::value; // Add this argument count to the remaining components.
94}; // Finish the count type description.
95template <class... A> struct prefix_count; // Count constructor components before the final argument.
96template <class Last> struct prefix_count<Last> { // Count constructor components before the final argument.
97    static const std::size_t value = 0; // Start the component count at zero.
98}; // Finish the prefix_count type description.
99template <class A, class B, class... Rest> struct prefix_count<A, B, Rest...> { // Count constructor components before the final argument.
100    static const std::size_t value = traits<A>::size + prefix_count<B, Rest...>::value; // Add this argument count to the remaining components.
101}; // Finish the prefix_count type description.
102template <class A> struct is_matrix : std::false_type {}; // Identify matrix types at compile time.
103template <class T, std::size_t C, std::size_t R> struct is_matrix<mat<T, C, R>> : std::true_type {}; // Identify matrix types at compile time.
104template <class T, std::size_t C, std::size_t R> struct shape<mat<T, C, R>> { // Describe a matrix separately from vector arithmetic.
105    typedef T scalar; // Keep the chosen component type for the calculation.
106    static const std::size_t size = C * R; // Count scalar entries across every matrix column.
107    static const bool vector = false; // Keep this input out of vector-only overloads.
108    static const bool valid = false; // Record whether componentwise arithmetic accepts this shape.
109}; // Finish the shape type description.
110template <class... A> struct any_matrix; // Check whether a constructor argument is a matrix.
111template <> struct any_matrix<> : std::false_type {}; // Check whether a constructor argument is a matrix.
112template <class A, class... B> // Accept the matching input types and dimensions.
113struct any_matrix<A, B...> // Describe this input or selection at compile time.
114    : std::integral_constant<bool, // Turn the component rule into a compile-time boolean.
115                             is_matrix<typename std::decay<A>::type>::value || // Complete the type and dimension rule for this overload.
116                                 any_matrix<B...>::value> {}; // Complete the type and dimension rule for this overload.
117template <std::size_t Needle, std::size_t... I> struct contains; // Check whether the remaining index list contains an index.
118template <std::size_t Needle> struct contains<Needle> : std::false_type {}; // Check whether the remaining index list contains an index.
119template <std::size_t Needle, std::size_t A, std::size_t... I> // Accept the matching input types and dimensions.
120struct contains<Needle, A, I...> // Describe this input or selection at compile time.
121    : std::integral_constant<bool, Needle == A || contains<Needle, I...>::value> {}; // Turn the component rule into a compile-time boolean.
122template <std::size_t... I> struct unique; // Check that selected component indices are distinct.
123template <> struct unique<> : std::true_type {}; // Check that selected component indices are distinct.
124template <std::size_t A, std::size_t... I> // Accept the matching input types and dimensions.
125struct unique<A, I...> // Describe this input or selection at compile time.
126    : std::integral_constant<bool, !contains<A, I...>::value && unique<I...>::value> {}; // Turn the component rule into a compile-time boolean.
127template <class A> struct writable_shape : std::false_type {}; // Identify vector selections that can receive values.
128template <class T, std::size_t N> struct writable_shape<vec<T, N>> : std::true_type {}; // Describe the scalar type and size of a vector.
129template <class T, std::size_t N, std::size_t... I> // Accept the matching input types and dimensions.
130struct writable_shape<swizzle_ref<T, N, I...>> : unique<I...> {}; // Describe this input or selection at compile time.
131template <class A> // Accept the matching input types and dimensions.
132struct writable // Describe this input or selection at compile time.
133    : std::integral_constant<bool, // Turn the component rule into a compile-time boolean.
134                             writable_shape<typename std::decay<A>::type>::value && // Complete the type and dimension rule for this overload.
135                                 !std::is_const<typename std::remove_reference<A>::type>::value> {}; // Complete the type and dimension rule for this overload.
136template <std::size_t N, std::size_t... I> struct in_range; // Check that every selected index fits the vector.
137template <std::size_t N> struct in_range<N> : std::true_type {}; // Check that every selected index fits the vector.
138template <std::size_t N, std::size_t A, std::size_t... I> // Accept the matching input types and dimensions.
139struct in_range<N, A, I...> : std::integral_constant<bool, // Check this index and the remaining selected indices.
140    A < N && in_range<N, I...>::value> {}; // Require every selected component index to fit the vector.
141template <class A> // Accept the matching input types and dimensions.
142typename std::enable_if<!traits<A>::vector, typename traits<A>::scalar>::type // Enable this overload only for compatible input types.
143component(const A& a, std::size_t) { // Read the requested scalar or vector component.
144    return a; // Return the scalar unchanged.
145} // Finish the component operation.
146template <class A> // Accept the matching input types and dimensions.
147typename std::enable_if<traits<A>::vector, typename traits<A>::scalar>::type // Enable this overload only for compatible input types.
148component(const A& a, std::size_t i) { // Read the requested scalar or vector component.
149    return a[i]; // Read the requested scalar or vector component.
150} // Finish the component operation.
151template <class A, class B> struct binary { // Choose compatible componentwise operand shapes.
152    static const bool valid = // Record whether componentwise arithmetic accepts this shape.
153        traits<A>::valid && traits<B>::valid && (traits<A>::vector || traits<B>::vector) && // Complete the type and dimension rule for this overload.
154        (!traits<A>::vector || !traits<B>::vector || traits<A>::size == traits<B>::size); // Require equal lengths when both operands are vectors.
155    typedef typename std::conditional<traits<A>::vector, // Name the type selected for this math result.
156                                      typename traits<A>::scalar, // Preserve the selected component type and result shape.
157                                      typename traits<B>::scalar>::type scalar; // Preserve the selected component type and result shape.
158    static const std::size_t size = traits<A>::vector ? traits<A>::size : traits<B>::size; // Record the compile-time component rule.
159    typedef vec<scalar, size> result; // Name the vector type produced by this operation.
160}; // Finish the binary type description.
161template <class A> struct result { // Choose the value type for this expression result.
162    typedef typename std::conditional<traits<A>::vector, // Name the type selected for this math result.
163                                      vec<typename traits<A>::scalar, traits<A>::size>, // Preserve the selected component type and result shape.
164                                      typename traits<A>::scalar>::type type; // Preserve the selected component type and result shape.
165}; // Finish the result type description.
166template <class T, class U> // Accept the matching input types and dimensions.
167typename std::enable_if<std::is_arithmetic<U>::value>::type // Enable this overload only for compatible input types.
168append(T* target, std::size_t& n, const U& a) { // Append the next argument to the flat component list.
169    target[n++] = static_cast<T>(a); // Append this component and advance the destination position.
170} // Finish the append operation.
171template <class T, class U, std::size_t N> // Accept the matching input types and dimensions.
172void append(T* target, std::size_t& n, const vec<U, N>& a) { // Append constructor components in their original order.
173    for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
174        target[n++] = static_cast<T>(a[i]); // Append this component and advance the destination position.
175} // Finish the append operation.
176template <class T, class U, std::size_t N, std::size_t... I> // Accept the matching input types and dimensions.
177void append(T* target, std::size_t& n, const swizzle_ref<U, N, I...>& a) { // Append constructor components in their original order.
178    for (std::size_t i = 0; i < sizeof...(I); ++i) // Visit each component needed by this calculation.
179        target[n++] = static_cast<T>(a[i]); // Append this component and advance the destination position.
180} // Finish the append operation.
181template <class T, class U, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
182void append(T* target, std::size_t& n, const mat<U, C, R>& a) { // Append constructor components in their original order.
183    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
184        for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
185            target[n++] = static_cast<T>(a[c][r]); // Append this component and advance the destination position.
186} // Finish the append operation.
187template <class T> void flatten(T*, std::size_t&) { // Accept the matching input types and dimensions.
188} // Finish the flatten operation.
189template <class T, class A, class... B> // Accept the matching input types and dimensions.
190void flatten(T* target, std::size_t& n, const A& a, const B&... b) { // Collect components from the remaining constructor arguments.
191    append(target, n, a); // Append the next argument to the flat component list.
192    flatten(target, n, b...); // Append the remaining arguments in order.
193} // Finish the flatten operation.
194} // namespace detail
195
196/** @brief A fixed-size array for GLSL local variables and function arguments.
197 * The size must be positive. Default construction initializes every element to
198 * its zero/default value.  component construction requires exactly N elements.
199 * Copy construction and assignment copy all elements. Use length() to query
200 * the element count and operator[] to select an element with a valid index.
201 * Resource ports define buffer and uniform memory layouts separately.
202 */
203template <class T, std::size_t N> class array { // Store a fixed number of values of one element type.
204    static_assert(N > 0, "GLSL fixed arrays require a positive size"); // Require at least one fixed-array element.
205    T elements_[N]; // Keep exactly N fixed-array elements.
206
207  public: // Expose the public math operations.
208    typedef T value_type; // Expose the element type to host code and templates.
209    static const std::size_t size_value = N; // Keep the fixed component count available at compile time.
210    /** @brief Return the number of array elements. */
211    static constexpr std::size_t length() { // Record the compile-time component rule.
212        return N; // Return the fixed number of available components.
213    } // Finish the length operation.
214    /** @brief Initialize every element to its zero/default value. */
215    array() : elements_() { // Initialize fixed-array storage from the supplied values.
216    } // Finish initializing the fixed array.
217    /** @brief Construct from exactly N scalar or aggregate element values. */
218    template <class... A> // Accept the matching input types and dimensions.
219    explicit array(const A&... values) : elements_{static_cast<T>(values)...} { // Initialize fixed-array storage from the supplied values.
220        static_assert(sizeof...(A) == N, "array constructor element count mismatch"); // Require exactly one argument for each array element.
221    } // Finish initializing the fixed array.
222    /** @brief Initialize from a C++ brace list containing exactly N elements.
223     * A length mismatch throws std::invalid_argument.
224     */
225    array(std::initializer_list<T> values) : elements_() { // Initialize fixed-array storage from the supplied values.
226        if (values.size() != N) // Reject a brace list with the wrong element count.
227            throw std::invalid_argument("array initializer element count mismatch"); // Report an initializer length mismatch.
228        std::size_t i = 0; // Begin filling the first array element.
229        for (const T& value : values) // Read initializer values in their original order.
230            elements_[i++] = value; // Store the next brace-list element.
231    } // Finish initializing the fixed array.
232    /** @brief Read or modify element i.  i must be less than length(). */
233    T& operator[](std::size_t i) { // Provide this arithmetic or component access overload.
234        return elements_[i]; // Return the selected component with its original reference type.
235    } // Finish this operator overload.
236    const T& operator[](std::size_t i) const { // Provide this arithmetic or component access overload.
237        return elements_[i]; // Return the selected component with its original reference type.
238    } // Finish this operator overload.
239}; // Finish the array type description.
240template <class T, std::size_t N> const std::size_t array<T, N>::size_value; // Accept the matching input types and dimensions.
241/** @brief Compare two arrays by comparing every element. */
242template <class T, std::size_t N> bool operator==(const array<T, N>& a, const array<T, N>& b) { // Accept the matching input types and dimensions.
243    for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
244        if (!(a[i] == b[i])) // Stop when corresponding components differ.
245            return false; // Report that at least one component differs.
246    return true; // Report that every required component matched.
247} // Finish this operator overload.
248/** @brief Return true when any pair of corresponding elements differs. */
249template <class T, std::size_t N> bool operator!=(const array<T, N>& a, const array<T, N>& b) { // Accept the matching input types and dimensions.
250    return !(a == b); // Return the component count or geometric length.
251} // Finish this operator overload.
252
253/** @brief A vector with two, three or four components of one scalar type.
254 * A scalar constructor fills every component. Component constructors consume
255 * scalar, vector and matrix arguments from left to right.  matrices contribute
256 * columns in order. Excess components in the final argument are discarded.
257 * Vector conversion takes the first N components of a source with at least N components.
258 * Default construction initializes every component to zero. Indexing requires
259 * an index less than length().
260 */
261template <class T, std::size_t N> class vec : public detail::storage<T, N> { // Store a fixed-size vector with named component fields.
262    static_assert(N >= 2 && N <= 4, "GLSL vectors require 2 to 4 components"); // Require two, three or four vector components.
263
264  public: // Expose the public math operations.
265    typedef T value_type; // Expose the element type to host code and templates.
266    typedef T component_type; // Expose the element type to host code and templates.
267    static const std::size_t length_value = N; // Keep the fixed component count available at compile time.
268    /** @brief Return the number of vector components. */
269    static constexpr std::size_t length() { // Record the compile-time component rule.
270        return N; // Return the fixed number of available components.
271    } // Finish the length operation.
272    vec() { // Initialize vector components from the supplied values.
273        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
274            (*this)[i] = T(); // Update the selected destination component.
275    } // Finish initializing the vector.
276    template <class U, typename std::enable_if<std::is_arithmetic<U>::value, int>::type = 0> // Accept the matching input types and dimensions.
277    explicit vec(U value) { // Initialize vector components from the supplied values.
278        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
279            (*this)[i] = static_cast<T>(value); // Update the selected destination component.
280    } // Finish initializing the vector.
281    template <class U, std::size_t M> explicit vec(const vec<U, M>& value) { // Accept the matching input types and dimensions.
282        static_assert(M >= N, "vector conversion cannot invent components"); // Check this type or dimension requirement at compile time.
283        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
284            (*this)[i] = static_cast<T>(value[i]); // Update the selected destination component.
285    } // Finish initializing the vector.
286    template <class U, std::size_t M, std::size_t... I> vec(const swizzle_ref<U, M, I...>& value) { // Accept the matching input types and dimensions.
287        static_assert(sizeof...(I) >= N, "swizzle conversion cannot invent components"); // Check this type or dimension requirement at compile time.
288        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
289            (*this)[i] = static_cast<T>(value[i]); // Update the selected destination component.
290    } // Finish initializing the vector.
291    /** @brief Read matrix columns consecutively to initialize the vector. */
292    template <class U, std::size_t C, std::size_t R> explicit vec(const mat<U, C, R>& value) { // Accept the matching input types and dimensions.
293        static_assert(C * R >= N, "matrix does not provide enough vector components"); // Check this type or dimension requirement at compile time.
294        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
295            (*this)[i] = static_cast<T>(value[i / R][i % R]); // Update the selected destination component.
296    } // Finish initializing the vector.
297    template <class A, class B, class... Rest> // Accept the matching input types and dimensions.
298    explicit vec(const A& a, const B& b, const Rest&... rest) { // Initialize vector components from the supplied values.
299        static_assert(detail::count<A, B, Rest...>::value >= N, // Require enough components to fill the destination.
300                      "vector constructor has too few components"); // Explain the rejected input: vector constructor has too few components.
301        static_assert(detail::prefix_count<A, B, Rest...>::value < N, // Reject constructor arguments that would go unused.
302                      "vector constructor has unused arguments"); // Explain the rejected input: vector constructor has unused arguments.
303        T values[detail::count<A, B, Rest...>::value]; // Allocate space for the supplied constructor components.
304        std::size_t n = 0; // Begin appending at the first temporary component.
305        detail::flatten(values, n, a, b, rest...); // Append the remaining arguments in order.
306        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
307            (*this)[i] = values[i]; // Update the selected destination component.
308    } // Finish initializing the vector.
309    /** @brief Read or modify component i. */
310    T& operator[](std::size_t i) { // Provide this arithmetic or component access overload.
311        return this->at(i); // Return the selected component with its original reference type.
312    } // Finish this operator overload.
313    const T& operator[](std::size_t i) const { // Provide this arithmetic or component access overload.
314        return this->at(i); // Return the selected component with its original reference type.
315    } // Finish this operator overload.
316    /** @brief Color aliases for x/y/z/w.  b and a require three and four components. */
317    T& r() { // Expose the first component through its color name.
318        return (*this)[0]; // Return the selected component with its original reference type.
319    } // Finish the r operation.
320    const T& r() const { // Expose the first component through its color name.
321        return (*this)[0]; // Return the selected component with its original reference type.
322    } // Finish the r operation.
323    T& g() { // Expose the second component through its color name.
324        return (*this)[1]; // Return the selected component with its original reference type.
325    } // Finish the g operation.
326    const T& g() const { // Expose the second component through its color name.
327        return (*this)[1]; // Return the selected component with its original reference type.
328    } // Finish the g operation.
329    T& b() { // Expose the third component through its color name.
330        static_assert(N >= 3, "b needs three components"); // Check this type or dimension requirement at compile time.
331        return (*this)[2]; // Return the selected component with its original reference type.
332    } // Finish the b operation.
333    const T& b() const { // Expose the third component through its color name.
334        static_assert(N >= 3, "b needs three components"); // Check this type or dimension requirement at compile time.
335        return (*this)[2]; // Return the selected component with its original reference type.
336    } // Finish the b operation.
337    T& a() { // Expose the fourth component through its color name.
338        static_assert(N >= 4, "a needs four components"); // Check this type or dimension requirement at compile time.
339        return (*this)[3]; // Return the selected component with its original reference type.
340    } // Finish the a operation.
341    const T& a() const { // Expose the fourth component through its color name.
342        static_assert(N >= 4, "a needs four components"); // Check this type or dimension requirement at compile time.
343        return (*this)[3]; // Return the selected component with its original reference type.
344    } // Finish the a operation.
345    /** @brief Texture-coordinate aliases for x/y/z/w. */
346    T& s() { // Expose the first texture coordinate.
347        return (*this)[0]; // Return the selected component with its original reference type.
348    } // Finish the s operation.
349    const T& s() const { // Expose the first texture coordinate.
350        return (*this)[0]; // Return the selected component with its original reference type.
351    } // Finish the s operation.
352    T& t() { // Expose the second texture coordinate.
353        return (*this)[1]; // Return the selected component with its original reference type.
354    } // Finish the t operation.
355    const T& t() const { // Expose the second texture coordinate.
356        return (*this)[1]; // Return the selected component with its original reference type.
357    } // Finish the t operation.
358    T& p() { // Expose the third texture coordinate.
359        static_assert(N >= 3, "p needs three components"); // Check this type or dimension requirement at compile time.
360        return (*this)[2]; // Return the selected component with its original reference type.
361    } // Finish the p operation.
362    const T& p() const { // Expose the third texture coordinate.
363        static_assert(N >= 3, "p needs three components"); // Check this type or dimension requirement at compile time.
364        return (*this)[2]; // Return the selected component with its original reference type.
365    } // Finish the p operation.
366    T& q() { // Expose the fourth texture coordinate.
367        static_assert(N >= 4, "q needs four components"); // Check this type or dimension requirement at compile time.
368        return (*this)[3]; // Return the selected component with its original reference type.
369    } // Finish the q operation.
370    const T& q() const { // Expose the fourth texture coordinate.
371        static_assert(N >= 4, "q needs four components"); // Check this type or dimension requirement at compile time.
372        return (*this)[3]; // Return the selected component with its original reference type.
373    } // Finish the q operation.
374    /** @brief Select one component as a scalar reference. */
375    template <std::size_t I> T& swizzle() { // Accept the matching input types and dimensions.
376        static_assert(I < N, "swizzle index out of range"); // Reject a component index outside the vector.
377        return (*this)[I]; // Return the selected component with its original reference type.
378    } // Finish the swizzle operation.
379    template <std::size_t I> const T& swizzle() const { // Accept the matching input types and dimensions.
380        static_assert(I < N, "swizzle index out of range"); // Reject a component index outside the vector.
381        return (*this)[I]; // Return the selected component with its original reference type.
382    } // Finish the swizzle operation.
383    /** @brief Select components in the requested order.  writable destinations
384     * must contain unique indices. Const vectors produce an independent value.
385     */
386    template <std::size_t... I> // Accept the matching input types and dimensions.
387    typename std::enable_if<(sizeof...(I) >= 2), swizzle_ref<T, N, I...>>::type swizzle() { // Enable this overload only for compatible input types.
388        static_assert(sizeof...(I) >= 2 && sizeof...(I) <= 4, "swizzles require 2 to 4 components"); // Check this type or dimension requirement at compile time.
389        static_assert(detail::in_range<N, I...>::value, "swizzle index out of range"); // Reject a component index outside the vector.
390        return swizzle_ref<T, N, I...>(*this); // Select components in the requested order.
391    } // Finish the swizzle operation.
392    template <std::size_t... I> // Accept the matching input types and dimensions.
393    typename std::enable_if<(sizeof...(I) >= 2), vec<T, sizeof...(I)>>::type swizzle() const { // Enable this overload only for compatible input types.
394        static_assert(sizeof...(I) >= 2 && sizeof...(I) <= 4, "swizzles require 2 to 4 components"); // Check this type or dimension requirement at compile time.
395        static_assert(detail::in_range<N, I...>::value, "swizzle index out of range"); // Reject a component index outside the vector.
396        const std::size_t indices[] = {I...}; // Keep the requested component order available for indexing.
397        vec<T, sizeof...(I)> out; // Keep an independent value for the result or aliased inputs.
398        for (std::size_t j = 0; j < sizeof...(I); ++j) // Visit each component needed by this calculation.
399            out[j] = (*this)[indices[j]]; // Store the computed component in the independent result.
400        return out; // Return the completed result.
401    } // Finish the swizzle operation.
402#define SHDR_DETAIL_VEC_ASSIGN(OP) /* Generate the matching scalar and vector overloads. */ \
403    template <class A> vec& operator OP(const A & a) { /* Accept the matching input types and dimensions. */ \
404        static_assert(!detail::traits<A>::vector || detail::traits<A>::size == N, /* Require matching component counts. */ \
405                      "vector dimension mismatch"); /* Explain the rejected input: vector dimension mismatch. */ \
406        T values[N]; /* Allocate space for the supplied constructor components. */ \
407        for (std::size_t i = 0; i < N; ++i) { /* Visit each component needed by this calculation. */ \
408            values[i] = static_cast<T>(detail::component(a, i)); /* Copy source components before any destination is changed. */ \
409        } /* Finish this component or matrix pass. */ \
410        for (std::size_t i = 0; i < N; ++i) { /* Visit each component needed by this calculation. */ \
411            (*this)[i] OP values[i]; /* Update the selected destination component. */ \
412        } /* Finish this component or matrix pass. */ \
413        return *this; /* Allow this update to be used in a chained expression. */ \
414    } /* Finish this operator overload. */
415    SHDR_DETAIL_VEC_ASSIGN(+=) // Provide componentwise addition.
416    SHDR_DETAIL_VEC_ASSIGN(-=) // Provide componentwise subtraction.
417    SHDR_DETAIL_VEC_ASSIGN(*=) // Provide componentwise multiplication.
418    SHDR_DETAIL_VEC_ASSIGN(/=) // Provide componentwise division.
419    SHDR_DETAIL_VEC_ASSIGN(%=) // Provide componentwise integer remainder.
420    SHDR_DETAIL_VEC_ASSIGN(&=) // Provide componentwise bitwise AND.
421    SHDR_DETAIL_VEC_ASSIGN(|=) // Provide componentwise bitwise OR.
422    SHDR_DETAIL_VEC_ASSIGN(^=) // Provide componentwise bitwise XOR.
423    SHDR_DETAIL_VEC_ASSIGN(<<=) // Provide componentwise left shifting.
424    SHDR_DETAIL_VEC_ASSIGN(>>=) // Provide componentwise right shifting.
425#undef SHDR_DETAIL_VEC_ASSIGN // Remove this local code generator macro.
426    vec& operator++() { // Provide this arithmetic or component access overload.
427        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
428            ++(*this)[i]; // Increment this vector component.
429        return *this; // Allow this update to be used in a chained expression.
430    } // Finish this operator overload.
431    vec operator++(int) { // Provide this arithmetic or component access overload.
432        vec old(*this); // Save the vector value before incrementing or decrementing it.
433        ++*this; // Increment every vector component.
434        return old; // Return the value from before the update.
435    } // Finish this operator overload.
436    vec& operator--() { // Provide this arithmetic or component access overload.
437        for (std::size_t i = 0; i < N; ++i) // Visit each component needed by this calculation.
438            --(*this)[i]; // Decrement this vector component.
439        return *this; // Allow this update to be used in a chained expression.
440    } // Finish this operator overload.
441    vec operator--(int) { // Provide this arithmetic or component access overload.
442        vec old(*this); // Save the vector value before incrementing or decrementing it.
443        --*this; // Decrement every vector component.
444        return old; // Return the value from before the update.
445    } // Finish this operator overload.
446}; // Finish the vec type description.
447template <class T, std::size_t N> const std::size_t vec<T, N>::length_value; // Accept the matching input types and dimensions.
448
449/** @brief A component selection referencing an existing vector.
450 * Assignment evaluates all source components before writing any destination,
451 * so exchanging components of the same vector is safe. Duplicate destination
452 * indices are rejected at compile time. The vector must outlive the selection.
453 * construct a vec value to keep an independent copy.
454 */
455template <class T, std::size_t N, std::size_t... I> class swizzle_ref { // Describe a component selection that refers to a vector.
456    vec<T, N>* source_; // Refer to the vector that owns the selected components.
457
458  public: // Expose the public math operations.
459    static constexpr std::size_t length() { // Record the compile-time component rule.
460        return sizeof...(I); // Return the fixed number of available components.
461    } // Finish the length operation.
462    explicit swizzle_ref(vec<T, N>& source) : source_(&source) { // Keep a reference to the source vector.
463    } // Finish keeping the source vector reference.
464    swizzle_ref(const swizzle_ref&) = default; // Copy the reference to the same source vector.
465    T& operator[](std::size_t i) { // Provide this arithmetic or component access overload.
466        const std::size_t indices[] = {I...}; // Keep the requested component order available for indexing.
467        return (*source_)[indices[i]]; // Return the selected component with its original reference type.
468    } // Finish this operator overload.
469    const T& operator[](std::size_t i) const { // Provide this arithmetic or component access overload.
470        const std::size_t indices[] = {I...}; // Keep the requested component order available for indexing.
471        return (*source_)[indices[i]]; // Return the selected component with its original reference type.
472    } // Finish this operator overload.
473    operator vec<T, sizeof...(I)>() const { // Provide this arithmetic or component access overload.
474        return vec<T, sizeof...(I)>(*this); // Return the component count or geometric length.
475    } // Finish this operator overload.
476    swizzle_ref& operator=(const swizzle_ref& rhs) { // Provide this arithmetic or component access overload.
477        return assign(rhs); // Write through a temporary so overlapping selections remain safe.
478    } // Finish this operator overload.
479    template <class A> swizzle_ref& operator=(const A& rhs) { // Accept the matching input types and dimensions.
480        return assign(rhs); // Write through a temporary so overlapping selections remain safe.
481    } // Finish this operator overload.
482    template <class A> swizzle_ref& assign(const A& rhs) { // Accept the matching input types and dimensions.
483        static_assert(detail::unique<I...>::value, "a writable swizzle cannot repeat components"); // Prevent repeated destination components.
484        static_assert(!detail::traits<A>::vector || detail::traits<A>::size == sizeof...(I), // Require matching component counts.
485                      "swizzle dimension mismatch"); // Explain the rejected input: swizzle dimension mismatch.
486        vec<T, sizeof...(I)> temp; // Keep an independent value for the result or aliased inputs.
487        for (std::size_t j = 0; j < sizeof...(I); ++j) // Visit each component needed by this calculation.
488            temp[j] = static_cast<T>(detail::component(rhs, j)); // Save this source component before writing the selection.
489        for (std::size_t j = 0; j < sizeof...(I); ++j) // Visit each component needed by this calculation.
490            (*this)[j] = temp[j]; // Update the selected destination component.
491        return *this; // Allow this update to be used in a chained expression.
492    } // Finish the assign operation.
493#define SHDR_DETAIL_SWIZZLE_ASSIGN(OP, BINARY) /* Generate the matching scalar and vector overloads. */ \
494    template <class A> swizzle_ref& operator OP(const A & rhs) { /* Accept the matching input types and dimensions. */ \
495        return assign(vec<T, sizeof...(I)>(*this) BINARY rhs); /* Write through a temporary so overlapping selections remain safe. */ \
496    } /* Finish this operator overload. */
497    SHDR_DETAIL_SWIZZLE_ASSIGN(+=, +) // Provide componentwise addition.
498    SHDR_DETAIL_SWIZZLE_ASSIGN(-=, -) // Provide componentwise subtraction.
499    SHDR_DETAIL_SWIZZLE_ASSIGN(*=, *) // Provide componentwise multiplication.
500    SHDR_DETAIL_SWIZZLE_ASSIGN(/=, /) // Provide componentwise division.
501    SHDR_DETAIL_SWIZZLE_ASSIGN(%=, %) // Provide componentwise integer remainder.
502    SHDR_DETAIL_SWIZZLE_ASSIGN(&=, &) // Provide componentwise bitwise AND.
503    SHDR_DETAIL_SWIZZLE_ASSIGN(|=, |) // Provide componentwise bitwise OR.
504    SHDR_DETAIL_SWIZZLE_ASSIGN(^=, ^) // Provide componentwise bitwise XOR.
505    SHDR_DETAIL_SWIZZLE_ASSIGN(<<=, <<) // Provide componentwise left shifting.
506    SHDR_DETAIL_SWIZZLE_ASSIGN(>>=, >>) // Provide componentwise right shifting.
507#undef SHDR_DETAIL_SWIZZLE_ASSIGN // Remove this local code generator macro.
508}; // Finish the swizzle_ref type description.
509/** @name Vector component arithmetic
510 * Vector/scalar and scalar/vector forms broadcast the scalar.
511 * Integer operators require integer components, as in GLSL.
512 * @{ */
513#define SHDR_DETAIL_VEC_BINARY(OP) /* Generate the matching scalar and vector overloads. */ \
514    template <class A, class B> /* Accept the matching input types and dimensions. */ \
515    typename std::enable_if<detail::binary<A, B>::valid, /* Enable this overload only for compatible input types. */ \
516                            typename detail::binary<A, B>::result>::type /* Preserve the selected component type and result shape. */ \
517    operator OP(const A& a, const B& b) { /* Provide this arithmetic or component access overload. */ \
518        typedef typename detail::binary<A, B>::scalar T; /* Keep the chosen component type for the calculation. */ \
519        typename detail::binary<A, B>::result out; /* Allocate an independent result with the correct shape. */ \
520        for (std::size_t i = 0; i < detail::binary<A, B>::size; ++i) { /* Visit each component needed by this calculation. */ \
521            out[i] = static_cast<T>(detail::component(a, i) OP detail::component(b, i)); /* Store the computed component in the independent result. */ \
522        } /* Finish this component or matrix pass. */ \
523        return out; /* Return the completed result. */ \
524    } /* Finish this operator overload. */
525SHDR_DETAIL_VEC_BINARY(+) // Provide componentwise addition.
526SHDR_DETAIL_VEC_BINARY(-) // Provide componentwise subtraction.
527SHDR_DETAIL_VEC_BINARY(*) // Provide componentwise multiplication.
528SHDR_DETAIL_VEC_BINARY(/) // Provide componentwise division.
529SHDR_DETAIL_VEC_BINARY(%) // Provide componentwise integer remainder.
530SHDR_DETAIL_VEC_BINARY(&) // Provide componentwise bitwise AND.
531SHDR_DETAIL_VEC_BINARY(|) // Provide componentwise bitwise OR.
532SHDR_DETAIL_VEC_BINARY(^) // Provide componentwise bitwise XOR.
533SHDR_DETAIL_VEC_BINARY(<<) // Provide componentwise left shifting.
534SHDR_DETAIL_VEC_BINARY(>>) // Provide componentwise right shifting.
535#undef SHDR_DETAIL_VEC_BINARY // Remove this local code generator macro.
536template <class A> // Accept the matching input types and dimensions.
537typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
538operator-(const A& a) { // Provide this arithmetic or component access overload.
539    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
540    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
541        out[i] = -a[i]; // Store the computed component in the independent result.
542    return out; // Return the completed result.
543} // Finish this operator overload.
544template <class A> // Accept the matching input types and dimensions.
545typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
546operator+(const A& a) { // Provide this arithmetic or component access overload.
547    return typename detail::result<A>::type(a); // Copy source components before changing the destination.
548} // Finish this operator overload.
549template <class A> // Accept the matching input types and dimensions.
550typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
551operator~(const A& a) { // Provide this arithmetic or component access overload.
552    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
553    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
554        out[i] = ~a[i]; // Store the computed component in the independent result.
555    return out; // Return the completed result.
556} // Finish this operator overload.
557template <class A, class B> // Accept the matching input types and dimensions.
558typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && // Enable this overload only for compatible input types.
559                            detail::traits<A>::size == detail::traits<B>::size, // Complete the type and dimension rule for this overload.
560                        bool>::type // Complete the type and dimension rule for this overload.
561operator==(const A& a, const B& b) { // Provide this arithmetic or component access overload.
562    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) { // Visit each component needed by this calculation.
563        if (a[i] != b[i]) // Stop when corresponding components differ.
564            return false; // Report that at least one component differs.
565    } // Finish this component or matrix pass.
566    return true; // Report that every required component matched.
567} // Finish this operator overload.
568template <class A, class B> // Accept the matching input types and dimensions.
569typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && // Enable this overload only for compatible input types.
570                            detail::traits<A>::size == detail::traits<B>::size, // Complete the type and dimension rule for this overload.
571                        bool>::type // Complete the type and dimension rule for this overload.
572operator!=(const A& a, const B& b) { // Provide this arithmetic or component access overload.
573    return !(a == b); // Copy source components before changing the destination.
574} // Finish this operator overload.
575/** @} */
576typedef vec<float, 2> vec2; // Name the 2-component float vector.
577typedef vec<float, 3> vec3; // Name the 3-component float vector.
578typedef vec<float, 4> vec4; // Name the 4-component float vector.
579typedef vec<double, 2> dvec2; // Name the 2-component double vector.
580typedef vec<double, 3> dvec3; // Name the 3-component double vector.
581typedef vec<double, 4> dvec4; // Name the 4-component double vector.
582typedef vec<std::int32_t, 2> ivec2; // Name the 2-component signed integer vector.
583typedef vec<std::int32_t, 3> ivec3; // Name the 3-component signed integer vector.
584typedef vec<std::int32_t, 4> ivec4; // Name the 4-component signed integer vector.
585typedef vec<std::uint32_t, 2> uvec2; // Name the 2-component unsigned integer vector.
586typedef vec<std::uint32_t, 3> uvec3; // Name the 3-component unsigned integer vector.
587typedef vec<std::uint32_t, 4> uvec4; // Name the 4-component unsigned integer vector.
588typedef vec<bool, 2> bvec2; // Name the 2-component boolean vector.
589typedef vec<bool, 3> bvec3; // Name the 3-component boolean vector.
590typedef vec<bool, 4> bvec4; // Name the 4-component boolean vector.
591template <class T, std::size_t N> // Accept the matching input types and dimensions.
592std::ostream& operator<<(std::ostream& out, const vec<T, N>& value) { // Provide this arithmetic or component access overload.
593    out << '('; // Write the next component or separator for readable output.
594    for (std::size_t i = 0; i < N; ++i) { // Visit each component needed by this calculation.
595        if (i) // Write a separator only after the first component.
596            out << ", "; // Write the next component or separator for readable output.
597        out << value[i]; // Write the next component or separator for readable output.
598    } // Finish this component or matrix pass.
599    return out << ')'; // Finish the readable representation and return the stream.
600} // Finish this operator overload.
601
602/** @brief A floating-point matrix with C columns and R rows.
603 * A scalar constructor initializes the diagonal and sets other entries to
604 * zero. Component constructors consume scalars and vectors in column order,
605 * discarding excess components in the final argument. Matrix conversion copies
606 * the common region and fills the remaining entries with the identity matrix.
607 * Default construction initializes every component to zero.
608 */
609template <class T, std::size_t C, std::size_t R> class mat { // Describe a matrix by its scalar type and dimensions.
610    static_assert(C >= 2 && C <= 4 && R >= 2 && R <= 4, "matrix dimensions require 2 to 4"); // Require matching component counts.
611    static_assert(std::is_floating_point<T>::value, // Require floating-point components for this operation.
612                  "GLSL matrices require floating point components"); // Explain the rejected input: GLSL matrices require floating point components.
613    vec<T, R> columns_[C]; // Store each matrix column as a vector.
614
615  public: // Expose the public math operations.
616    typedef T value_type; // Expose the element type to host code and templates.
617    typedef vec<T, R> column_type; // Expose the vector type used for each matrix column.
618    static const std::size_t columns = C; // Keep the matrix column count available at compile time.
619    static const std::size_t rows = R; // Keep the matrix row count available at compile time.
620    /** @brief Return the number of matrix columns. */
621    static constexpr std::size_t length() { // Record the compile-time component rule.
622        return C; // Return the fixed number of available components.
623    } // Finish the length operation.
624    mat() : columns_() { // Initialize matrix columns from the supplied values.
625    } // Finish initializing the matrix.
626    template <class U, typename std::enable_if<std::is_arithmetic<U>::value, int>::type = 0> // Accept the matching input types and dimensions.
627    explicit mat(U diagonal) : columns_() { // Initialize matrix columns from the supplied values.
628        for (std::size_t c = 0; c < C && c < R; ++c) // Visit each matrix column.
629            columns_[c][c] = static_cast<T>(diagonal); // Set this diagonal entry to the requested scalar.
630    } // Finish initializing the matrix.
631    template <class U, std::size_t A, std::size_t B> // Accept the matching input types and dimensions.
632    explicit mat(const mat<U, A, B>& other) : columns_() { // Initialize matrix columns from the supplied values.
633        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
634            for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
635                columns_[c][r] = // Copy or complete this matrix entry.
636                    c < A && r < B ? static_cast<T>(other[c][r]) : (c == r ? T(1) : T(0)); // Copy the common region and use identity entries elsewhere.
637    } // Finish initializing the matrix.
638    /** @brief Construct a matrix from the components of one vector or swizzle. */
639    template <class A, typename std::enable_if<detail::traits<A>::vector, int>::type = 0> // Accept the matching input types and dimensions.
640    explicit mat(const A& value) { // Initialize matrix columns from the supplied values.
641        static_assert(detail::traits<A>::size >= C * R, // Check this type or dimension requirement at compile time.
642                      "matrix constructor has too few components"); // Explain the rejected input: matrix constructor has too few components.
643        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
644            for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
645                columns_[c][r] = static_cast<T>(value[c * R + r]); // Copy the next source component in column order.
646    } // Finish initializing the matrix.
647    template <class A, class B, class... Rest> // Accept the matching input types and dimensions.
648    explicit mat(const A& a, const B& b, const Rest&... rest) { // Initialize matrix columns from the supplied values.
649        static_assert(!detail::any_matrix<A, B, Rest...>::value, // Check this type or dimension requirement at compile time.
650                      "matrix conversion cannot be mixed with other arguments"); // Require the matrix to be the sole conversion argument.
651        static_assert(detail::count<A, B, Rest...>::value >= C * R, // Require enough components to fill the destination.
652                      "matrix constructor has too few components"); // Explain the rejected input: matrix constructor has too few components.
653        static_assert(detail::prefix_count<A, B, Rest...>::value < C * R, // Reject constructor arguments that would go unused.
654                      "matrix constructor has unused arguments"); // Explain the rejected input: matrix constructor has unused arguments.
655        T values[detail::count<A, B, Rest...>::value]; // Allocate space for the supplied constructor components.
656        std::size_t n = 0; // Begin appending at the first temporary component.
657        detail::flatten(values, n, a, b, rest...); // Append the remaining arguments in order.
658        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
659            for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
660                columns_[c][r] = values[c * R + r]; // Fill the column from the flattened constructor values.
661    } // Finish initializing the matrix.
662    /** @brief Read or modify column c.  m[c][r] selects row r within that column. */
663    column_type& operator[](std::size_t c) { // Provide this arithmetic or component access overload.
664        return columns_[c]; // Return the component count or geometric length.
665    } // Finish this operator overload.
666    const column_type& operator[](std::size_t c) const { // Provide this arithmetic or component access overload.
667        return columns_[c]; // Return the component count or geometric length.
668    } // Finish this operator overload.
669    mat& operator+=(const mat& b) { // Provide this arithmetic or component access overload.
670        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
671            columns_[c] += b[c]; // Add the corresponding matrix column.
672        return *this; // Allow this update to be used in a chained expression.
673    } // Finish this operator overload.
674    mat& operator-=(const mat& b) { // Provide this arithmetic or component access overload.
675        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
676            columns_[c] -= b[c]; // Subtract the corresponding matrix column.
677        return *this; // Allow this update to be used in a chained expression.
678    } // Finish this operator overload.
679    mat& operator+=(T b) { // Provide this arithmetic or component access overload.
680        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
681            columns_[c] += b; // Add the scalar to every entry in this column.
682        return *this; // Allow this update to be used in a chained expression.
683    } // Finish this operator overload.
684    mat& operator-=(T b) { // Provide this arithmetic or component access overload.
685        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
686            columns_[c] -= b; // Subtract the scalar from every entry in this column.
687        return *this; // Allow this update to be used in a chained expression.
688    } // Finish this operator overload.
689    mat& operator*=(T b) { // Provide this arithmetic or component access overload.
690        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
691            columns_[c] *= b; // Scale this column by the scalar.
692        return *this; // Allow this update to be used in a chained expression.
693    } // Finish this operator overload.
694    mat& operator/=(T b) { // Provide this arithmetic or component access overload.
695        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
696            columns_[c] /= b; // Divide this column by the scalar.
697        return *this; // Allow this update to be used in a chained expression.
698    } // Finish this operator overload.
699    mat& operator/=(const mat& b) { // Provide this arithmetic or component access overload.
700        for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
701            columns_[c] /= b[c]; // Divide corresponding entries in this column.
702        return *this; // Allow this update to be used in a chained expression.
703    } // Finish this operator overload.
704    mat& operator*=(const mat<T, C, C>& b) { // Provide this arithmetic or component access overload.
705        *this = *this * b;
706        return *this; // Allow this update to be used in a chained expression.
707    } // Finish this operator overload.
708}; // Finish the mat type description.
709template <class T, std::size_t C, std::size_t R> const std::size_t mat<T, C, R>::columns; // Accept the matching input types and dimensions.
710template <class T, std::size_t C, std::size_t R> const std::size_t mat<T, C, R>::rows; // Accept the matching input types and dimensions.
711
712/** @brief Convert a scalar, or the first component of a vector, to T.
713 * This implements GLSL scalar constructors such as float(vec3) for generated
714 * C++ kernels. Ordinary C++ callers may use scalar_cast<float>(value) directly.
715 */
716template <class T, class A> // Accept the matching input types and dimensions.
717typename std::enable_if<std::is_arithmetic<T>::value && detail::traits<A>::valid, T>::type // Enable this overload only for compatible input types.
718scalar_cast(const A& value) { // Convert the first scalar component to the requested type.
719    return static_cast<T>(detail::component(value, 0)); // Convert the first scalar component to the requested type.
720} // Finish the scalar_cast operation.
721/** @brief Convert the first column's first matrix component to scalar type T. */
722template <class T, class U, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
723typename std::enable_if<std::is_arithmetic<T>::value, T>::type // Enable this overload only for compatible input types.
724scalar_cast(const mat<U, C, R>& value) { // Convert the first scalar component to the requested type.
725    return static_cast<T>(value[0][0]); // Convert the first scalar component to the requested type.
726} // Finish the scalar_cast operation.
727/** @brief GLSL square and rectangular matrix aliases.  dimensions are columns
728 * followed by rows. Float aliases are mat2..4 and mat2x2..mat4x4.  double aliases
729 * use dmat. Double arithmetic is a host extension and requires a supporting
730 * desktop GLSL profile when used by shared shaders.
731 */
732#define SHDR_DETAIL_MATRIX_ALIASES(T, PREFIX) /* Generate the matching scalar and vector overloads. */ \
733    typedef mat<T, 2, 2> PREFIX##2; /* Name the type selected for this math result. */ \
734    typedef mat<T, 3, 3> PREFIX##3; /* Name the type selected for this math result. */ \
735    typedef mat<T, 4, 4> PREFIX##4; /* Name the type selected for this math result. */ \
736    typedef mat<T, 2, 2> PREFIX##2x2; /* Name the type selected for this math result. */ \
737    typedef mat<T, 2, 3> PREFIX##2x3; /* Name the type selected for this math result. */ \
738    typedef mat<T, 2, 4> PREFIX##2x4; /* Name the type selected for this math result. */ \
739    typedef mat<T, 3, 2> PREFIX##3x2; /* Name the type selected for this math result. */ \
740    typedef mat<T, 3, 3> PREFIX##3x3; /* Name the type selected for this math result. */ \
741    typedef mat<T, 3, 4> PREFIX##3x4; /* Name the type selected for this math result. */ \
742    typedef mat<T, 4, 2> PREFIX##4x2; /* Name the type selected for this math result. */ \
743    typedef mat<T, 4, 3> PREFIX##4x3; /* Name the type selected for this math result. */ \
744    typedef mat<T, 4, 4> PREFIX##4x4; /* Name the type selected for this math result. */
745SHDR_DETAIL_MATRIX_ALIASES(float, mat) // Provide the single-precision matrix names.
746SHDR_DETAIL_MATRIX_ALIASES(double, dmat) // Provide the double-precision matrix names.
747#undef SHDR_DETAIL_MATRIX_ALIASES // Remove this local code generator macro.
748template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
749mat<T, C, R> operator+(mat<T, C, R> a, const mat<T, C, R>& b) { // Keep an independent value for the result or aliased inputs.
750    return a += b; // Convert the first scalar component to the requested type.
751} // Finish this operator overload.
752template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
753mat<T, C, R> operator-(mat<T, C, R> a, const mat<T, C, R>& b) { // Keep an independent value for the result or aliased inputs.
754    return a -= b; // Convert the first scalar component to the requested type.
755} // Finish this operator overload.
756template <class T, std::size_t C, std::size_t R> mat<T, C, R> operator-(const mat<T, C, R>& a) { // Accept the matching input types and dimensions.
757    mat<T, C, R> out; // Keep an independent value for the result or aliased inputs.
758    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
759        out[c] = -a[c]; // Store the computed component in the independent result.
760    return out; // Return the completed result.
761} // Finish this operator overload.
762template <class T, std::size_t C, std::size_t R> mat<T, C, R> operator+(const mat<T, C, R>& a) { // Accept the matching input types and dimensions.
763    return a; // Return the scalar unchanged.
764} // Finish this operator overload.
765#define SHDR_DETAIL_MATRIX_SCALAR(OP, ASSIGN) /* Generate the matching scalar and vector overloads. */ \
766    template <class T, std::size_t C, std::size_t R, class U> /* Accept the matching input types and dimensions. */ \
767    typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type operator OP( /* Enable this overload only for compatible input types. */ \
768        mat<T, C, R> a, U b) { /* Keep an independent value for the result or aliased inputs. */ \
769        return a ASSIGN static_cast<T>(b); /* Convert the first scalar component to the requested type. */ \
770    } /* Finish this declaration. */ \
771    template <class T, std::size_t C, std::size_t R, class U> /* Accept the matching input types and dimensions. */ \
772    typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type operator OP( /* Enable this overload only for compatible input types. */ \
773        U a, const mat<T, C, R>& b) { /* Accept a scalar before the matrix operand. */ \
774        mat<T, C, R> out; /* Keep an independent value for the result or aliased inputs. */ \
775        for (std::size_t c = 0; c < C; ++c) { /* Visit each matrix column. */ \
776            out[c] = static_cast<T>(a) OP b[c]; /* Store the computed component in the independent result. */ \
777        } /* Finish this component or matrix pass. */ \
778        return out; /* Return the completed result. */ \
779    } /* Finish this declaration. */
780SHDR_DETAIL_MATRIX_SCALAR(+, +=) // Provide componentwise addition.
781SHDR_DETAIL_MATRIX_SCALAR(-, -=) // Provide componentwise subtraction.
782#undef SHDR_DETAIL_MATRIX_SCALAR // Remove this local code generator macro.
783template <class T, std::size_t C, std::size_t R, class U> // Accept the matching input types and dimensions.
784typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type operator*(mat<T, C, R> a, // Enable this overload only for compatible input types.
785                                                                                    U b) { // Accept a scalar after the matrix operand.
786    return a *= static_cast<T>(b); // Convert the first scalar component to the requested type.
787} // Finish this declaration.
788template <class T, std::size_t C, std::size_t R, class U> // Accept the matching input types and dimensions.
789typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type // Enable this overload only for compatible input types.
790operator*(U a, mat<T, C, R> b) { // Provide this arithmetic or component access overload.
791    return b *= static_cast<T>(a); // Convert the first scalar component to the requested type.
792} // Finish this operator overload.
793template <class T, std::size_t C, std::size_t R, class U> // Accept the matching input types and dimensions.
794typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type operator/(mat<T, C, R> a, // Enable this overload only for compatible input types.
795                                                                                    U b) { // Accept a scalar after the matrix operand.
796    return a /= static_cast<T>(b); // Convert the first scalar component to the requested type.
797} // Finish this declaration.
798template <class T, std::size_t C, std::size_t R, class U> // Accept the matching input types and dimensions.
799typename std::enable_if<std::is_arithmetic<U>::value, mat<T, C, R>>::type // Enable this overload only for compatible input types.
800operator/(U a, const mat<T, C, R>& b) { // Provide this arithmetic or component access overload.
801    mat<T, C, R> out; // Keep an independent value for the result or aliased inputs.
802    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
803        out[c] = static_cast<T>(a) / b[c]; // Store the computed component in the independent result.
804    return out; // Return the completed result.
805} // Finish this operator overload.
806template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
807mat<T, C, R> operator/(const mat<T, C, R>& a, const mat<T, C, R>& b) { // Provide this arithmetic or component access overload.
808    mat<T, C, R> out; // Keep an independent value for the result or aliased inputs.
809    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
810        out[c] = a[c] / b[c]; // Store the computed component in the independent result.
811    return out; // Return the completed result.
812} // Finish this operator overload.
813template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
814bool operator==(const mat<T, C, R>& a, const mat<T, C, R>& b) { // Provide this arithmetic or component access overload.
815    for (std::size_t c = 0; c < C; ++c) { // Visit each matrix column.
816        if (a[c] != b[c]) // Handle the exceptional or boundary case before continuing.
817            return false; // Report that at least one component differs.
818    } // Finish this component or matrix pass.
819    return true; // Report that every required component matched.
820} // Finish this operator overload.
821template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
822bool operator!=(const mat<T, C, R>& a, const mat<T, C, R>& b) { // Provide this arithmetic or component access overload.
823    return !(a == b); // Convert the first scalar component to the requested type.
824} // Finish this operator overload.
825/** @brief Algebraic matrix-vector multiplication. */
826template <class T, std::size_t C, std::size_t R, class A> // Accept the matching input types and dimensions.
827typename std::enable_if<detail::traits<A>::vector && detail::traits<A>::size == C, vec<T, R>>::type // Enable this overload only for compatible input types.
828operator*(const mat<T, C, R>& a, const A& b) { // Provide this arithmetic or component access overload.
829    vec<T, R> out(T(0)); // Keep an independent value for the result or aliased inputs.
830    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
831        out += a[c] * b[c]; // Add this component product to the running total.
832    return out; // Return the completed result.
833} // Finish this operator overload.
834template <class T, std::size_t C, std::size_t R, class A> // Accept the matching input types and dimensions.
835typename std::enable_if<detail::traits<A>::vector && detail::traits<A>::size == R, vec<T, C>>::type // Enable this overload only for compatible input types.
836operator*(const A& a, const mat<T, C, R>& b) { // Provide this arithmetic or component access overload.
837    vec<T, C> out(T(0)); // Keep an independent value for the result or aliased inputs.
838    for (std::size_t c = 0; c < C; ++c) { // Visit each matrix column.
839        for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
840            out[c] += a[r] * b[c][r]; // Store the computed component in the independent result.
841    } // Finish this component or matrix pass.
842    return out; // Return the completed result.
843} // Finish this operator overload.
844/** @brief Algebraic multiplication, including nonsquare matrices. */
845template <class T, std::size_t C, std::size_t R, std::size_t K> // Accept the matching input types and dimensions.
846mat<T, K, R> operator*(const mat<T, C, R>& a, const mat<T, K, C>& b) { // Provide this arithmetic or component access overload.
847    mat<T, K, R> out; // Keep an independent value for the result or aliased inputs.
848    for (std::size_t c = 0; c < K; ++c) // Visit each matrix column.
849        out[c] = a * b[c]; // Store the computed component in the independent result.
850    return out; // Return the completed result.
851} // Finish this operator overload.
852/** @brief Exchange rows and columns, including rectangular matrices. */
853template <class T, std::size_t C, std::size_t R> mat<T, R, C> transpose(const mat<T, C, R>& a) { // Accept the matching input types and dimensions.
854    mat<T, R, C> out; // Keep an independent value for the result or aliased inputs.
855    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
856        for (std::size_t r = 0; r < R; ++r) // Visit each matrix row.
857            out[r][c] = a[c][r]; // Copy the entry to its exchanged row and column.
858    return out; // Return the completed result.
859} // Finish the transpose operation.
860/** @brief Multiply corresponding matrix components element by element. */
861template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
862mat<T, C, R> matrixCompMult(const mat<T, C, R>& a, const mat<T, C, R>& b) { // Multiply corresponding matrix entries.
863    mat<T, C, R> out; // Keep an independent value for the result or aliased inputs.
864    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
865        out[c] = a[c] * b[c]; // Store the computed component in the independent result.
866    return out; // Return the completed result.
867} // Finish the matrixCompMult operation.
868/** @brief Form a column-by-row outer product.  output column j is column*row[j]. */
869template <class T, std::size_t R, std::size_t C> // Accept the matching input types and dimensions.
870mat<T, C, R> outerProduct(const vec<T, R>& column, const vec<T, C>& row) { // Keep an independent value for the result or aliased inputs.
871    mat<T, C, R> out; // Keep an independent value for the result or aliased inputs.
872    for (std::size_t c = 0; c < C; ++c) // Visit each matrix column.
873        out[c] = column * row[c]; // Store the computed component in the independent result.
874    return out; // Return the completed result.
875} // Finish the outerProduct operation.
876/** @brief Determinant using partial-pivot elimination. */
877template <class T, std::size_t N> T determinant(mat<T, N, N> a) { // Accept the matching input types and dimensions.
878    T result(1); // Begin the determinant product with multiplicative identity.
879    for (std::size_t i = 0; i < N; ++i) { // Visit each component needed by this calculation.
880        std::size_t pivot = i; // Begin with the current row as the pivot candidate.
881        for (std::size_t r = i + 1; r < N; ++r) // Visit each matrix row.
882            if (std::abs(a[i][r]) > std::abs(a[i][pivot])) // Prefer the row with the larger pivot magnitude.
883                pivot = r; // Use the stronger row for the next pivot.
884        if (a[i][pivot] == T(0)) // Detect a singular column before division.
885            return T(0); // Compute the determinant with row pivoting.
886        if (pivot != i) { // Swap rows when a better pivot was found.
887            for (std::size_t c = 0; c < N; ++c) { // Visit each matrix column.
888                T temp = a[c][i]; // Save an entry while exchanging the two rows.
889                a[c][i] = a[c][pivot]; // Update this matrix entry during row elimination or exchange.
890                a[c][pivot] = temp; // Update this matrix entry during row elimination or exchange.
891            } // Finish this component or matrix pass.
892            result = -result; // Reverse the determinant sign after a row exchange.
893        } // Finish handling this condition.
894        T diagonal = a[i][i]; // Save the pivot value before normalizing the row.
895        result *= diagonal; // Multiply the determinant by the next diagonal value.
896        for (std::size_t r = i + 1; r < N; ++r) { // Visit each matrix row.
897            T factor = a[i][r] / diagonal; // Find the amount of the pivot row to eliminate.
898            for (std::size_t c = i + 1; c < N; ++c) // Visit each matrix column.
899                a[c][r] -= factor * a[c][i]; // Update this matrix entry during row elimination or exchange.
900        } // Finish this component or matrix pass.
901    } // Finish this component or matrix pass.
902    return result; // Return the completed result.
903} // Finish the determinant operation.
904/** @brief Inverse using partial-pivot Gauss-Jordan elimination.
905 * Singular input has undefined GLSL semantics.  the host returns quiet NaNs.
906 */
907template <class T, std::size_t N> mat<T, N, N> inverse(mat<T, N, N> a) { // Accept the matching input types and dimensions.
908    mat<T, N, N> out(T(1)); // Keep an independent value for the result or aliased inputs.
909    for (std::size_t i = 0; i < N; ++i) { // Visit each component needed by this calculation.
910        std::size_t pivot = i; // Begin with the current row as the pivot candidate.
911        for (std::size_t r = i + 1; r < N; ++r) // Visit each matrix row.
912            if (std::abs(a[i][r]) > std::abs(a[i][pivot])) // Prefer the row with the larger pivot magnitude.
913                pivot = r; // Use the stronger row for the next pivot.
914        if (a[i][pivot] == T(0)) { // Detect a singular column before division.
915            for (std::size_t c = 0; c < N; ++c) // Visit each matrix column.
916                out[c] = vec<T, N>(std::numeric_limits<T>::quiet_NaN()); // Store the computed component in the independent result.
917            return out; // Return the completed result.
918        } // Finish handling this condition.
919        if (pivot != i) // Swap rows when a better pivot was found.
920            for (std::size_t c = 0; c < N; ++c) { // Visit each matrix column.
921                T temp = a[c][i]; // Save an entry while exchanging the two rows.
922                a[c][i] = a[c][pivot]; // Update this matrix entry during row elimination or exchange.
923                a[c][pivot] = temp; // Update this matrix entry during row elimination or exchange.
924                temp = out[c][i]; // Save an entry while exchanging the two rows.
925                out[c][i] = out[c][pivot]; // Store the computed component in the independent result.
926                out[c][pivot] = temp; // Store the computed component in the independent result.
927            } // Finish this component or matrix pass.
928        T diagonal = a[i][i]; // Save the pivot value before normalizing the row.
929        for (std::size_t c = 0; c < N; ++c) { // Visit each matrix column.
930            a[c][i] /= diagonal; // Update this matrix entry during row elimination or exchange.
931            out[c][i] /= diagonal; // Store the computed component in the independent result.
932        } // Finish this component or matrix pass.
933        for (std::size_t r = 0; r < N; ++r) // Visit each matrix row.
934            if (r != i) { // Handle the exceptional or boundary case before continuing.
935                T factor = a[i][r]; // Find the amount of the pivot row to eliminate.
936                for (std::size_t c = 0; c < N; ++c) { // Visit each matrix column.
937                    a[c][r] -= factor * a[c][i]; // Update this matrix entry during row elimination or exchange.
938                    out[c][r] -= factor * out[c][i]; // Subtract the pivot-row contribution from the inverse.
939                } // Finish this component or matrix pass.
940            } // Finish handling this condition.
941    } // Finish this component or matrix pass.
942    return out; // Return the completed result.
943} // Finish the inverse operation.
944template <class T, std::size_t C, std::size_t R> // Accept the matching input types and dimensions.
945std::ostream& operator<<(std::ostream& out, const mat<T, C, R>& value) { // Provide this arithmetic or component access overload.
946    out << '['; // Write the next component or separator for readable output.
947    for (std::size_t c = 0; c < C; ++c) { // Visit each matrix column.
948        if (c) // Write a separator only after the first component.
949            out << ", "; // Write the next component or separator for readable output.
950        out << value[c]; // Write the next component or separator for readable output.
951    } // Finish this component or matrix pass.
952    return out << ']'; // Finish the readable representation and return the stream.
953} // Finish this operator overload.
954/** @name Angle, exponential and common scalar/vector math
955 * Floating-point overloads preserve their component type. Vector overloads
956 * apply each scalar operation independently, including swizzle expressions.
957 * @{ */
958#define SHDR_DETAIL_FLOAT_UNARY(NAME, EXPR) /* Generate the matching scalar and vector overloads. */ \
959    template <class T> /* Accept the matching input types and dimensions. */ \
960    typename std::enable_if<std::is_floating_point<T>::value, T>::type NAME(T x) { /* Enable this overload only for compatible input types. */ \
961        return static_cast<T>(EXPR); /* Compute the inverse with row pivoting. */ \
962    } /* Finish this generated overload. */ \
963    template <class A> /* Accept the matching input types and dimensions. */ \
964    typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type /* Enable this overload only for compatible input types. */ \
965    NAME(const A& x) { /* Start the matching math overload. */ \
966        typedef typename detail::traits<A>::scalar T; /* Keep the chosen component type for the calculation. */ \
967        static_assert(std::is_floating_point<T>::value, "floating point components required"); /* Require floating-point components for this operation. */ \
968        typename detail::result<A>::type out; /* Allocate an independent result with the correct shape. */ \
969        for (std::size_t i = 0; i < detail::traits<A>::size; ++i) /* Visit each component needed by this calculation. */ \
970            out[i] = glsl::NAME(x[i]); /* Store the computed component in the independent result. */ \
971        return out; /* Return the completed result. */ \
972    } /* Finish this generated overload. */
973SHDR_DETAIL_FLOAT_UNARY(radians, x* T(0.01745329251994329576923690768489L)) // Convert degrees to radians for scalars and vector components.
974SHDR_DETAIL_FLOAT_UNARY(degrees, x* T(57.295779513082320876798154814105L)) // Convert radians to degrees for scalars and vector components.
975SHDR_DETAIL_FLOAT_UNARY(sin, std::sin(x)) // Compute the sine for scalars and vector components.
976SHDR_DETAIL_FLOAT_UNARY(cos, std::cos(x)) // Compute the cosine for scalars and vector components.
977SHDR_DETAIL_FLOAT_UNARY(tan, std::tan(x)) // Compute the tangent for scalars and vector components.
978SHDR_DETAIL_FLOAT_UNARY(asin, std::asin(x)) // Compute the inverse sine for scalars and vector components.
979SHDR_DETAIL_FLOAT_UNARY(acos, std::acos(x)) // Compute the inverse cosine for scalars and vector components.
980SHDR_DETAIL_FLOAT_UNARY(atan, std::atan(x)) // Compute the inverse tangent for scalars and vector components.
981SHDR_DETAIL_FLOAT_UNARY(sinh, std::sinh(x)) // Compute the hyperbolic sine for scalars and vector components.
982SHDR_DETAIL_FLOAT_UNARY(cosh, std::cosh(x)) // Compute the hyperbolic cosine for scalars and vector components.
983SHDR_DETAIL_FLOAT_UNARY(tanh, std::tanh(x)) // Compute the hyperbolic tangent for scalars and vector components.
984SHDR_DETAIL_FLOAT_UNARY(asinh, std::asinh(x)) // Compute the inverse hyperbolic sine for scalars and vector components.
985SHDR_DETAIL_FLOAT_UNARY(acosh, std::acosh(x)) // Compute the inverse hyperbolic cosine for scalars and vector components.
986SHDR_DETAIL_FLOAT_UNARY(atanh, std::atanh(x)) // Compute the inverse hyperbolic tangent for scalars and vector components.
987SHDR_DETAIL_FLOAT_UNARY(exp, std::exp(x)) // Raise e to the input power for scalars and vector components.
988SHDR_DETAIL_FLOAT_UNARY(log, std::log(x)) // Compute the natural logarithm for scalars and vector components.
989SHDR_DETAIL_FLOAT_UNARY(exp2, std::exp2(x)) // Raise two to the input power for scalars and vector components.
990SHDR_DETAIL_FLOAT_UNARY(log2, std::log2(x)) // Compute the base-two logarithm for scalars and vector components.
991SHDR_DETAIL_FLOAT_UNARY(sqrt, std::sqrt(x)) // Compute the square root for scalars and vector components.
992SHDR_DETAIL_FLOAT_UNARY(inversesqrt, T(1) / std::sqrt(x)) // Compute the reciprocal square root for scalars and vector components.
993SHDR_DETAIL_FLOAT_UNARY(floor, std::floor(x)) // Round toward negative infinity for scalars and vector components.
994SHDR_DETAIL_FLOAT_UNARY(trunc, std::trunc(x)) // Round toward zero for scalars and vector components.
995SHDR_DETAIL_FLOAT_UNARY(round, std::round(x)) // Round to the nearest integer for scalars and vector components.
996SHDR_DETAIL_FLOAT_UNARY(ceil, std::ceil(x)) // Round toward positive infinity for scalars and vector components.
997SHDR_DETAIL_FLOAT_UNARY(fract, x - std::floor(x)) // Keep the fraction above the floor for scalars and vector components.
998#undef SHDR_DETAIL_FLOAT_UNARY // Remove this local code generator macro.
999template <class T> typename std::enable_if<std::is_arithmetic<T>::value, T>::type abs(T x) { // Accept the matching input types and dimensions.
1000    return x < T(0) ? -x : x; // Return a nonnegative magnitude.
1001} // Finish the abs operation.
1002template <class A> // Accept the matching input types and dimensions.
1003typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1004abs(const A& a) { // Return a nonnegative magnitude.
1005    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1006    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1007        out[i] = glsl::abs(a[i]); // Store the computed component in the independent result.
1008    return out; // Return the completed result.
1009} // Finish the abs operation.
1010template <class T> typename std::enable_if<std::is_arithmetic<T>::value, T>::type sign(T x) { // Accept the matching input types and dimensions.
1011    return x > T(0) ? T(1) : (x < T(0) ? T(-1) : T(0)); // Return minus one, zero or one from the input sign.
1012} // Finish the sign operation.
1013template <class A> // Accept the matching input types and dimensions.
1014typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1015sign(const A& a) { // Return minus one, zero or one from the input sign.
1016    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1017    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1018        out[i] = glsl::sign(a[i]); // Store the computed component in the independent result.
1019    return out; // Return the completed result.
1020} // Finish the sign operation.
1021/** @brief Round halfway cases to the nearest even integer, independent of the
1022 * host's floating-point rounding mode. Nonfinite inputs are preserved.
1023 */
1024template <class T> // Accept the matching input types and dimensions.
1025typename std::enable_if<std::is_floating_point<T>::value, T>::type roundEven(T x) { // Enable this overload only for compatible input types.
1026    if (!std::isfinite(x)) // Keep nonfinite inputs unchanged.
1027        return x; // Round halfway values to the nearest even integer.
1028    T lo = std::floor(x), fraction = x - lo; // Separate the lower integer from its fractional remainder.
1029    if (fraction < T(0.5)) // Choose the lower integer below the halfway point.
1030        return lo; // Round halfway values to the nearest even integer.
1031    if (fraction > T(0.5)) // Choose the upper integer above the halfway point.
1032        return lo + T(1); // Round halfway values to the nearest even integer.
1033    return std::fmod(lo, T(2)) == T(0) ? lo : lo + T(1); // Round halfway values to the nearest even integer.
1034} // Finish the roundEven operation.
1035template <class A> // Accept the matching input types and dimensions.
1036typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1037roundEven(const A& a) { // Round halfway values to the nearest even integer.
1038    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1039    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1040        out[i] = glsl::roundEven(a[i]); // Store the computed component in the independent result.
1041    return out; // Return the completed result.
1042} // Finish the roundEven operation.
1043#define SHDR_DETAIL_MATH_BINARY(NAME, ENABLE, EXPR) /* Generate the matching scalar and vector overloads. */ \
1044    template <class T> typename std::enable_if<ENABLE, T>::type NAME(T x, T y) { /* Accept the matching input types and dimensions. */ \
1045        return static_cast<T>(EXPR); /* Round halfway values to the nearest even integer. */ \
1046    } /* Finish this generated overload. */ \
1047    template <class A, class B> /* Accept the matching input types and dimensions. */ \
1048    typename std::enable_if<detail::binary<A, B>::valid, /* Enable this overload only for compatible input types. */ \
1049                            typename detail::binary<A, B>::result>::type /* Preserve the selected component type and result shape. */ \
1050    NAME(const A& a, const B& b) { /* Start the matching math overload. */ \
1051        typedef typename detail::binary<A, B>::scalar T; /* Keep the chosen component type for the calculation. */ \
1052        typename detail::binary<A, B>::result out; /* Allocate an independent result with the correct shape. */ \
1053        for (std::size_t i = 0; i < detail::binary<A, B>::size; ++i) { /* Visit each component needed by this calculation. */ \
1054            out[i] = glsl::NAME(static_cast<T>(detail::component(a, i)), /* Store the computed component in the independent result. */ \
1055                                static_cast<T>(detail::component(b, i))); /* Convert the second operand component to the result type. */ \
1056        } /* Finish this component or matrix pass. */ \
1057        return out; /* Return the completed result. */ \
1058    } /* Finish this generated overload. */
1059SHDR_DETAIL_MATH_BINARY(atan, std::is_floating_point<T>::value, std::atan2(x, y)) // Compute the inverse tangent for scalars and vector components.
1060SHDR_DETAIL_MATH_BINARY(pow, std::is_floating_point<T>::value, std::pow(x, y)) // Raise each base to its exponent.
1061SHDR_DETAIL_MATH_BINARY(mod, std::is_floating_point<T>::value, x - y * std::floor(x / y)) // Use the GLSL floor-based remainder.
1062SHDR_DETAIL_MATH_BINARY(min, std::is_arithmetic<T>::value, y < x ? y : x) // Choose the smaller value.
1063SHDR_DETAIL_MATH_BINARY(max, std::is_arithmetic<T>::value, x < y ? y : x) // Choose the larger value.
1064SHDR_DETAIL_MATH_BINARY(step, std::is_floating_point<T>::value, y < x ? T(0) : T(1)) // Return zero below the edge and one otherwise.
1065#undef SHDR_DETAIL_MATH_BINARY // Remove this local code generator macro.
1066/** @brief Fused multiply-add.  final rounding may differ across CPU/GPU. */
1067template <class T> // Accept the matching input types and dimensions.
1068typename std::enable_if<std::is_floating_point<T>::value, T>::type fma(T a, T b, T c) { // Enable this overload only for compatible input types.
1069    return std::fma(a, b, c); // Multiply and add with one final rounding.
1070} // Finish the fma operation.
1071template <class A, class B, class C> // Accept the matching input types and dimensions.
1072typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1073fma(const A& a, const B& b, const C& c) { // Multiply and add with one final rounding.
1074    static_assert(detail::binary<A, B>::valid && detail::binary<A, C>::valid, // Check this type or dimension requirement at compile time.
1075                  "fma dimensions mismatch"); // Explain the rejected input: fma dimensions mismatch.
1076    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1077    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1078    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1079        out[i] = glsl::fma( // Store the computed component in the independent result.
1080            a[i], static_cast<T>(detail::component(b, i)), static_cast<T>(detail::component(c, i))); // Supply the matching three components to fused multiply-add.
1081    return out; // Return the completed result.
1082} // Finish the fma operation.
1083template <class T> // Accept the matching input types and dimensions.
1084typename std::enable_if<std::is_arithmetic<T>::value, T>::type clamp(T x, T lower, T upper) { // Enable this overload only for compatible input types.
1085    return glsl::min(glsl::max(x, lower), upper); // Keep a value between its lower and upper limits.
1086} // Finish the clamp operation.
1087template <class A, class B, class C> // Accept the matching input types and dimensions.
1088typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1089clamp(const A& a, const B& lower, const C& upper) { // Keep a value between its lower and upper limits.
1090    static_assert(detail::binary<A, B>::valid && detail::binary<A, C>::valid, // Check this type or dimension requirement at compile time.
1091                  "clamp dimensions mismatch"); // Explain the rejected input: clamp dimensions mismatch.
1092    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1093    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1094    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1095        out[i] = glsl::clamp(a[i], // Store the computed component in the independent result.
1096                             static_cast<T>(detail::component(lower, i)), // Use the matching lower bound component.
1097                             static_cast<T>(detail::component(upper, i))); // Use the matching upper bound component.
1098    return out; // Return the completed result.
1099} // Finish the clamp operation.
1100template <class T, class U> // Accept the matching input types and dimensions.
1101typename std::enable_if<std::is_floating_point<T>::value && std::is_arithmetic<U>::value && // Enable this overload only for compatible input types.
1102                            !std::is_same<U, bool>::value, // Complete the type and dimension rule for this overload.
1103                        T>::type // Complete the type and dimension rule for this overload.
1104mix(T x, T y, U selector) { // Blend values or select one with a boolean.
1105    T a = static_cast<T>(selector); // Convert the interpolation amount to the component type.
1106    return x * (T(1) - a) + y * a; // Blend values or select one with a boolean.
1107} // Finish the mix operation.
1108template <class T, class B> // Accept the matching input types and dimensions.
1109typename std::enable_if<std::is_arithmetic<T>::value && std::is_same<B, bool>::value, T>::type // Enable this overload only for compatible input types.
1110mix(T x, T y, B a) { // Blend values or select one with a boolean.
1111    return a ? y : x; // Blend values or select one with a boolean.
1112} // Finish the mix operation.
1113template <class A, class B, class C> // Accept the matching input types and dimensions.
1114typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1115mix(const A& a, const B& b, const C& selector) { // Blend values or select one with a boolean.
1116    static_assert(detail::binary<A, B>::valid && detail::binary<A, C>::valid, // Check this type or dimension requirement at compile time.
1117                  "mix dimensions mismatch"); // Explain the rejected input: mix dimensions mismatch.
1118    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1119    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1120    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1121        out[i] = glsl::mix( // Store the computed component in the independent result.
1122            a[i], static_cast<T>(detail::component(b, i)), detail::component(selector, i)); // Blend or select the matching input components.
1123    return out; // Return the completed result.
1124} // Finish the mix operation.
1125template <class T> // Accept the matching input types and dimensions.
1126typename std::enable_if<std::is_floating_point<T>::value, T>::type // Enable this overload only for compatible input types.
1127smoothstep(T lower, T upper, T x) { // Interpolate smoothly between two edges.
1128    T t = glsl::clamp((x - lower) / (upper - lower), T(0), T(1)); // Map the input into a clamped zero-to-one interval.
1129    return t * t * (T(3) - T(2) * t); // Interpolate smoothly between two edges.
1130} // Finish the smoothstep operation.
1131template <class A, class B, class C> // Accept the matching input types and dimensions.
1132typename std::enable_if<detail::traits<C>::vector, typename detail::result<C>::type>::type // Enable this overload only for compatible input types.
1133smoothstep(const A& lower, const B& upper, const C& x) { // Interpolate smoothly between two edges.
1134    static_assert(detail::binary<C, A>::valid && detail::binary<C, B>::valid, // Check this type or dimension requirement at compile time.
1135                  "smoothstep dimensions mismatch"); // Explain the rejected input: smoothstep dimensions mismatch.
1136    typedef typename detail::traits<C>::scalar T; // Keep the chosen component type for the calculation.
1137    typename detail::result<C>::type out; // Allocate an independent result with the correct shape.
1138    for (std::size_t i = 0; i < detail::traits<C>::size; ++i) // Visit each component needed by this calculation.
1139        out[i] = glsl::smoothstep(static_cast<T>(detail::component(lower, i)), // Store the computed component in the independent result.
1140                                  static_cast<T>(detail::component(upper, i)), // Use the matching upper interpolation edge.
1141                                  x[i]); // Interpolate this input component between its edges.
1142    return out; // Return the completed result.
1143} // Finish the smoothstep operation.
1144template <class T> // Accept the matching input types and dimensions.
1145typename std::enable_if<std::is_floating_point<T>::value, bool>::type isnan(T x) { // Enable this overload only for compatible input types.
1146    return std::isnan(x); // Check whether the value is not a number.
1147} // Finish the isnan operation.
1148template <class T> // Accept the matching input types and dimensions.
1149typename std::enable_if<std::is_floating_point<T>::value, bool>::type isinf(T x) { // Enable this overload only for compatible input types.
1150    return std::isinf(x); // Check whether the value is infinite.
1151} // Finish the isinf operation.
1152#define SHDR_DETAIL_CLASSIFICATION(NAME) /* Generate the matching scalar and vector overloads. */ \
1153    template <class A> /* Accept the matching input types and dimensions. */ \
1154    typename std::enable_if<detail::traits<A>::vector, vec<bool, detail::traits<A>::size>>::type /* Enable this overload only for compatible input types. */ \
1155    NAME(const A& a) { /* Start the matching math overload. */ \
1156        vec<bool, detail::traits<A>::size> out; /* Keep an independent value for the result or aliased inputs. */ \
1157        for (std::size_t i = 0; i < detail::traits<A>::size; ++i) /* Visit each component needed by this calculation. */ \
1158            out[i] = glsl::NAME(a[i]); /* Store the computed component in the independent result. */ \
1159        return out; /* Return the completed result. */ \
1160    } /* Finish this generated overload. */
1161SHDR_DETAIL_CLASSIFICATION(isnan) // Check whether the value is not a number.
1162SHDR_DETAIL_CLASSIFICATION(isinf) // Check whether the value is infinite.
1163#undef SHDR_DETAIL_CLASSIFICATION // Remove this local code generator macro.
1164template <class T> // Accept the matching input types and dimensions.
1165typename std::enable_if<std::is_floating_point<T>::value, T>::type modf(T x, T& integer) { // Enable this overload only for compatible input types.
1166    return std::modf(x, &integer); // Separate fractional and integral components.
1167} // Finish the modf operation.
1168/** @brief Split a vector into signed fractional and integer parts.
1169 * The return value contains fractional components.  integer receives the
1170 * integral components. Both arguments may be swizzles, including selections
1171 * of the same vector, because the input is copied before output assignment.
1172 */
1173template <class A, class B> // Accept the matching input types and dimensions.
1174typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector, // Enable this overload only for compatible input types.
1175                        typename detail::result<A>::type>::type // Preserve the selected component type and result shape.
1176modf(const A& x, B&& integer) { // Separate fractional and integral components.
1177    static_assert(detail::traits<A>::size == detail::traits<B>::size, "modf dimensions mismatch"); // Require matching component counts.
1178    static_assert( // Check this type or dimension requirement at compile time.
1179        std::is_same<typename detail::traits<A>::scalar, typename detail::traits<B>::scalar>::value, // Require the input and output component types to match.
1180        "modf component types must match"); // Explain the rejected input: modf component types must match.
1181    static_assert(detail::writable<B>::value, "modf output requires writable unique components"); // Prevent repeated destination components.
1182    typename detail::result<A>::type input(x), out, integral; // Preserve the selected component type and result shape.
1183    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1184        out[i] = glsl::modf(input[i], integral[i]); // Store the computed component in the independent result.
1185    integer = integral; // Publish all integral components after reading the input.
1186    return out; // Return the completed result.
1187} // Finish the modf operation.
1188template <class T> // Accept the matching input types and dimensions.
1189typename std::enable_if<std::is_floating_point<T>::value, T>::type frexp(T x, int& exponent) { // Enable this overload only for compatible input types.
1190    return std::frexp(x, &exponent); // Separate a significand and its binary exponent.
1191} // Finish the frexp operation.
1192/** @brief Return binary significands and write matching signed exponents.
1193 * Each nonzero component satisfies x = significand * 2^exponent. Output may be
1194 * an integer vector or a writable swizzle with matching component count.
1195 */
1196template <class A, class B> // Accept the matching input types and dimensions.
1197typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector, // Enable this overload only for compatible input types.
1198                        typename detail::result<A>::type>::type // Preserve the selected component type and result shape.
1199frexp(const A& x, B&& exponent) { // Separate a significand and its binary exponent.
1200    static_assert(detail::traits<A>::size == detail::traits<B>::size, "frexp dimensions mismatch"); // Require matching component counts.
1201    static_assert(std::is_same<typename detail::traits<B>::scalar, std::int32_t>::value, // Check this type or dimension requirement at compile time.
1202                  "frexp requires signed integer exponent components"); // Explain the rejected input: frexp requires signed integer exponent components.
1203    static_assert(detail::writable<B>::value, "frexp output requires writable unique components"); // Prevent repeated destination components.
1204    typename detail::result<A>::type input(x), out; // Allocate an independent result with the correct shape.
1205    vec<std::int32_t, detail::traits<A>::size> powers; // Use the selected vector or matrix shape for this value.
1206    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) { // Visit each component needed by this calculation.
1207        int e = 0; // Prepare a signed exponent for this component.
1208        out[i] = std::frexp(input[i], &e); // Store the computed component in the independent result.
1209        powers[i] = e; // Store the binary exponent for this component.
1210    } // Finish this component or matrix pass.
1211    exponent = powers; // Publish all exponents after reading the input.
1212    return out; // Return the completed result.
1213} // Finish the frexp operation.
1214template <class T> // Accept the matching input types and dimensions.
1215typename std::enable_if<std::is_floating_point<T>::value, T>::type ldexp(T x, int exponent) { // Enable this overload only for compatible input types.
1216    return std::ldexp(x, exponent); // Scale a significand by a power of two.
1217} // Finish the ldexp operation.
1218/** @brief Multiply each component by two raised to its signed integer exponent. */
1219template <class A, class B> // Accept the matching input types and dimensions.
1220typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector, // Enable this overload only for compatible input types.
1221                        typename detail::result<A>::type>::type // Preserve the selected component type and result shape.
1222ldexp(const A& x, const B& exponent) { // Scale a significand by a power of two.
1223    static_assert(detail::traits<A>::size == detail::traits<B>::size, "ldexp dimensions mismatch"); // Require matching component counts.
1224    static_assert(std::is_same<typename detail::traits<B>::scalar, std::int32_t>::value, // Check this type or dimension requirement at compile time.
1225                  "ldexp requires signed integer exponent components"); // Explain the rejected input: ldexp requires signed integer exponent components.
1226    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1227    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1228        out[i] = std::ldexp(x[i], exponent[i]); // Store the computed component in the independent result.
1229    return out; // Return the completed result.
1230} // Finish the ldexp operation.
1231/** @} */
1232
1233/** @name Geometry
1234 * Geometry uses scalar dot products and GLSL's usual component formulas.
1235 * normalize requires nonzero length. Inputs to reflect, refract and faceforward
1236 * should obey GLSL's normalized-normal requirements.
1237 * @{ */
1238template <class T> // Accept the matching input types and dimensions.
1239typename std::enable_if<std::is_floating_point<T>::value, T>::type dot(T a, T b) { // Enable this overload only for compatible input types.
1240    return a * b; // Sum products of corresponding components.
1241} // Finish the dot operation.
1242template <class A, class B> // Accept the matching input types and dimensions.
1243typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector, // Enable this overload only for compatible input types.
1244                        typename detail::traits<A>::scalar>::type // Preserve the selected component type and result shape.
1245dot(const A& a, const B& b) { // Sum products of corresponding components.
1246    static_assert(detail::traits<A>::size == detail::traits<B>::size, "dot dimensions mismatch"); // Require matching component counts.
1247    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1248    T out(0); // Start the scalar accumulator at zero.
1249    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) { // Visit each component needed by this calculation.
1250        out += a[i] * b[i]; // Add this component product to the running total.
1251    } // Finish this component or matrix pass.
1252    return out; // Return the completed result.
1253} // Finish the dot operation.
1254template <class T> typename std::enable_if<std::is_floating_point<T>::value, T>::type length(T x) { // Accept the matching input types and dimensions.
1255    return glsl::abs(x); // Return the component count or geometric length.
1256} // Finish the length operation.
1257template <class A> // Accept the matching input types and dimensions.
1258typename std::enable_if<detail::traits<A>::vector, typename detail::traits<A>::scalar>::type // Enable this overload only for compatible input types.
1259length(const A& a) { // Return the component count or geometric length.
1260    return glsl::sqrt(glsl::dot(a, a)); // Return the component count or geometric length.
1261} // Finish the length operation.
1262template <class A, class B> auto distance(const A& a, const B& b) -> decltype(glsl::length(a - b)) { // Accept the matching input types and dimensions.
1263    return glsl::length(a - b); // Measure the length of the difference.
1264} // Finish the distance operation.
1265template <class A, class B> // Accept the matching input types and dimensions.
1266typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && // Enable this overload only for compatible input types.
1267                            detail::traits<A>::size == 3 && detail::traits<B>::size == 3, // Complete the type and dimension rule for this overload.
1268                        vec<typename detail::traits<A>::scalar, 3>>::type // Preserve the selected component type and result shape.
1269cross(const A& a, const B& b) { // Compute the three-dimensional cross product.
1270    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1271    return vec<T, 3>( // Compute the three-dimensional cross product.
1272        a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]); // Use the three signed two-by-two minors for the cross product.
1273} // Finish the cross operation.
1274template <class A> // Accept the matching input types and dimensions.
1275typename std::enable_if<detail::traits<A>::valid, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1276normalize(const A& a) { // Scale a nonzero value to unit length.
1277    return a / glsl::length(a); // Scale a nonzero value to unit length.
1278} // Finish the normalize operation.
1279template <class A, class B, class C> // Accept the matching input types and dimensions.
1280typename std::enable_if<detail::traits<A>::valid, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1281faceforward(const A& normal, const B& incident, const C& reference) { // Choose the normal direction facing the incident vector.
1282    return glsl::dot(reference, incident) < 0 ? normal : -normal; // Choose the normal direction facing the incident vector.
1283} // Finish the faceforward operation.
1284template <class A, class B> // Accept the matching input types and dimensions.
1285typename std::enable_if<detail::traits<A>::valid, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1286reflect(const A& incident, const B& normal) { // Reflect an incident vector around its normal.
1287    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1288    return incident - T(2) * glsl::dot(normal, incident) * normal; // Reflect an incident vector around its normal.
1289} // Finish the reflect operation.
1290template <class A, class B> // Accept the matching input types and dimensions.
1291typename std::enable_if<detail::traits<A>::valid, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1292refract(const A& incident, const B& normal, typename detail::traits<A>::scalar eta) { // Refract an incident vector using the index ratio.
1293    typedef typename detail::traits<A>::scalar T; // Keep the chosen component type for the calculation.
1294    T d = glsl::dot(normal, incident); // Measure the incident component along the normal.
1295    T k = T(1) - eta * eta * (T(1) - d * d); // Compute the refraction discriminant before taking its root.
1296    return k < T(0) ? typename detail::result<A>::type(T(0)) // Refract an incident vector using the index ratio.
1297                    : eta * incident - (eta * d + glsl::sqrt(k)) * normal; // Apply the transmitted-direction formula when refraction is possible.
1298} // Finish the refract operation.
1299/** @} */
1300
1301/** @name Vector relational functions
1302 * operator== compares the whole vector and returns bool. These builtins return
1303 * component masks. logicalNot is the C++ spelling of GLSL's reserved `not`.
1304 * @{ */
1305#define SHDR_DETAIL_RELATIONAL(NAME, OP) /* Generate the matching scalar and vector overloads. */ \
1306    template <class A, class B> /* Accept the matching input types and dimensions. */ \
1307    typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector, /* Enable this overload only for compatible input types. */ \
1308                            vec<bool, detail::traits<A>::size>>::type /* Use the selected vector or matrix shape for this value. */ \
1309    NAME(const A& a, const B& b) { /* Start the matching math overload. */ \
1310        static_assert(detail::traits<A>::size == detail::traits<B>::size, /* Require matching component counts. */ \
1311                      "relational dimensions mismatch"); /* Explain the rejected input: relational dimensions mismatch. */ \
1312        vec<bool, detail::traits<A>::size> out; /* Keep an independent value for the result or aliased inputs. */ \
1313        for (std::size_t i = 0; i < detail::traits<A>::size; ++i) /* Visit each component needed by this calculation. */ \
1314            out[i] = a[i] OP b[i]; /* Store the computed component in the independent result. */ \
1315        return out; /* Return the completed result. */ \
1316    } /* Finish this generated overload. */
1317SHDR_DETAIL_RELATIONAL(lessThan, <) // Provide the requested component operation.
1318SHDR_DETAIL_RELATIONAL(lessThanEqual, <=) // Provide the requested component operation.
1319SHDR_DETAIL_RELATIONAL(greaterThan, >) // Provide the requested component operation.
1320SHDR_DETAIL_RELATIONAL(greaterThanEqual, >=) // Provide the requested component operation.
1321SHDR_DETAIL_RELATIONAL(equal, ==) // Provide the requested component operation.
1322SHDR_DETAIL_RELATIONAL(notEqual, !=) // Provide the requested component operation.
1323#undef SHDR_DETAIL_RELATIONAL // Remove this local code generator macro.
1324template <class A> typename std::enable_if<detail::traits<A>::vector, bool>::type any(const A& a) { // Accept the matching input types and dimensions.
1325    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1326        if (a[i]) // Handle the exceptional or boundary case before continuing.
1327            return true; // Report that every required component matched.
1328    return false; // Report that at least one component differs.
1329} // Finish the any operation.
1330template <class A> typename std::enable_if<detail::traits<A>::vector, bool>::type all(const A& a) { // Accept the matching input types and dimensions.
1331    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1332        if (!a[i]) // Handle the exceptional or boundary case before continuing.
1333            return false; // Report that at least one component differs.
1334    return true; // Report that every required component matched.
1335} // Finish the all operation.
1336template <class A> // Accept the matching input types and dimensions.
1337typename std::enable_if<detail::traits<A>::vector, vec<bool, detail::traits<A>::size>>::type // Enable this overload only for compatible input types.
1338logicalNot(const A& a) { // Invert each boolean component.
1339    vec<bool, detail::traits<A>::size> out; // Keep an independent value for the result or aliased inputs.
1340    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1341        out[i] = !a[i]; // Store the computed component in the independent result.
1342    return out; // Return the completed result.
1343} // Finish the logicalNot operation.
1344template <class A> // Accept the matching input types and dimensions.
1345typename std::enable_if<detail::traits<A>::vector, vec<bool, detail::traits<A>::size>>::type // Enable this overload only for compatible input types.
1346_not(const A& a) { // Start the matching math overload.
1347    return glsl::logicalNot(a); // Invert each boolean component.
1348} // Finish the _not operation.
1349/** @} */
1350/** @name 32-bit bit operations
1351 * Reinterpretation uses memcpy and requires IEEE binary32 floats and 32-bit
1352 * integers. Bitfield ranges must satisfy 0 <= offset,bits and offset+bits<=32.
1353 * The 64-bit host intermediates in extended multiplication are never exposed
1354 * to shared shaders. Bit searches and counts return signed integer results.
1355 * @{ */
1356namespace detail { // Keep these names inside the detail namespace.
1357template <class To, class From> To bit_copy(const From& value) { // Accept the matching input types and dimensions.
1358    static_assert(sizeof(To) == sizeof(From), "bit conversion requires equal sizes"); // Check this type or dimension requirement at compile time.
1359    To out; // Allocate a destination with the same bit width.
1360    std::memcpy(&out, &value, sizeof(out)); // Copy the bits with the alias-safe byte-copy operation.
1361    return out; // Return the completed result.
1362} // Finish the bit_copy operation.
1363inline std::uint32_t bit_mask(int bits) { // Start the matching math overload.
1364    return bits == 32 ? UINT32_MAX : (bits == 0 ? 0u : (std::uint32_t(1) << bits) - 1u); // Invert each boolean component.
1365} // Finish the bit_mask operation.
1366template <class T> // Accept the matching input types and dimensions.
1367struct integer32 : std::integral_constant<bool, // Describe this input or selection at compile time.
1368                                          std::is_integral<T>::value && // Require integer components for the bit operation.
1369                                              !std::is_same<T, bool>::value && sizeof(T) == 4> {}; // Complete the type and dimension rule for this overload.
1370} // namespace detail
1371inline std::uint32_t floatBitsToUint(float x) { // Copy float bits into an unsigned integer.
1372    static_assert(sizeof(float) == 4 && std::numeric_limits<float>::is_iec559, // Check this type or dimension requirement at compile time.
1373                  "IEEE binary32 float required"); // Explain the rejected input: IEEE binary32 float required.
1374    return detail::bit_copy<std::uint32_t>(x); // Copy float bits into an unsigned integer.
1375} // Finish the floatBitsToUint operation.
1376inline std::int32_t floatBitsToInt(float x) { // Copy float bits into a signed integer.
1377    return detail::bit_copy<std::int32_t>(x); // Copy float bits into a signed integer.
1378} // Finish the floatBitsToInt operation.
1379inline float uintBitsToFloat(std::uint32_t x) { // Copy unsigned integer bits into a float.
1380    return detail::bit_copy<float>(x); // Copy unsigned integer bits into a float.
1381} // Finish the uintBitsToFloat operation.
1382inline float intBitsToFloat(std::int32_t x) { // Copy signed integer bits into a float.
1383    return detail::bit_copy<float>(x); // Copy signed integer bits into a float.
1384} // Finish the intBitsToFloat operation.
1385#define SHDR_DETAIL_BIT_VECTOR(NAME, OUT_T) /* Generate the matching scalar and vector overloads. */ \
1386    template <class A> /* Accept the matching input types and dimensions. */ \
1387    typename std::enable_if<detail::traits<A>::vector, vec<OUT_T, detail::traits<A>::size>>::type /* Enable this overload only for compatible input types. */ \
1388    NAME(const A& a) { /* Start the matching math overload. */ \
1389        vec<OUT_T, detail::traits<A>::size> out; /* Keep an independent value for the result or aliased inputs. */ \
1390        for (std::size_t i = 0; i < detail::traits<A>::size; ++i) /* Visit each component needed by this calculation. */ \
1391            out[i] = glsl::NAME(a[i]); /* Store the computed component in the independent result. */ \
1392        return out; /* Return the completed result. */ \
1393    } /* Finish this generated overload. */
1394SHDR_DETAIL_BIT_VECTOR(floatBitsToUint, std::uint32_t) // Copy float bits into an unsigned integer.
1395SHDR_DETAIL_BIT_VECTOR(floatBitsToInt, std::int32_t) // Copy float bits into a signed integer.
1396SHDR_DETAIL_BIT_VECTOR(uintBitsToFloat, float) // Copy unsigned integer bits into a float.
1397SHDR_DETAIL_BIT_VECTOR(intBitsToFloat, float) // Copy signed integer bits into a float.
1398template <class T> // Accept the matching input types and dimensions.
1399typename std::enable_if<detail::integer32<T>::value, std::int32_t>::type bitCount(T x) { // Enable this overload only for compatible input types.
1400    std::uint32_t v = static_cast<std::uint32_t>(x); // Hold the exact integer bits used by this operation.
1401    std::int32_t count = 0; // Hold the exact integer bits used by this operation.
1402    while (v) { // Continue until the remaining bits reach the required form.
1403        v &= v - 1u; // Remove the least significant set bit.
1404        ++count; // Count the set bit that was removed.
1405    } // Finish this component or matrix pass.
1406    return count; // Count the set bits in a 32-bit value.
1407} // Finish the bitCount operation.
1408template <class T> // Accept the matching input types and dimensions.
1409typename std::enable_if<detail::integer32<T>::value, std::int32_t>::type findLSB(T x) { // Enable this overload only for compatible input types.
1410    std::uint32_t v = static_cast<std::uint32_t>(x); // Hold the exact integer bits used by this operation.
1411    if (!v) // Handle the exceptional or boundary case before continuing.
1412        return -1; // Find the first set bit from the least significant end.
1413    std::int32_t position = 0; // Hold the exact integer bits used by this operation.
1414    while (!(v & 1u)) { // Continue until the remaining bits reach the required form.
1415        v >>= 1; // Move the next bit into the least significant position.
1416        ++position; // Advance the bit position being tested.
1417    } // Finish this component or matrix pass.
1418    return position; // Find the first set bit from the least significant end.
1419} // Finish the findLSB operation.
1420template <class T> // Accept the matching input types and dimensions.
1421typename std::enable_if<detail::integer32<T>::value, std::int32_t>::type findMSB(T x) { // Enable this overload only for compatible input types.
1422    std::uint32_t v = static_cast<std::uint32_t>(x); // Hold the exact integer bits used by this operation.
1423    if (std::is_signed<T>::value && x < T(0)) // Handle the exceptional or boundary case before continuing.
1424        v = ~v; // For negative values, search for the highest zero bit.
1425    std::int32_t position = -1; // Hold the exact integer bits used by this operation.
1426    while (v) { // Continue until the remaining bits reach the required form.
1427        v >>= 1; // Move the next bit into the least significant position.
1428        ++position; // Advance the bit position being tested.
1429    } // Finish this component or matrix pass.
1430    return position; // Find the highest bit that differs from the sign bit.
1431} // Finish the findMSB operation.
1432SHDR_DETAIL_BIT_VECTOR(bitCount, std::int32_t) // Count the set bits in a 32-bit value.
1433SHDR_DETAIL_BIT_VECTOR(findLSB, std::int32_t) // Find the first set bit from the least significant end.
1434SHDR_DETAIL_BIT_VECTOR(findMSB, std::int32_t) // Find the highest bit that differs from the sign bit.
1435#undef SHDR_DETAIL_BIT_VECTOR // Remove this local code generator macro.
1436template <class T> // Accept the matching input types and dimensions.
1437typename std::enable_if<detail::integer32<T>::value, T>::type bitfieldReverse(T x) { // Enable this overload only for compatible input types.
1438    std::uint32_t v = static_cast<std::uint32_t>(x), out = 0; // Hold the exact integer bits used by this operation.
1439    for (int i = 0; i < 32; ++i) { // Visit all 32 bits of the value.
1440        out = (out << 1) | (v & 1u); // Append the current low bit in reversed order.
1441        v >>= 1; // Move the next bit into the least significant position.
1442    } // Finish this component or matrix pass.
1443    return detail::bit_copy<T>(out); // Reverse all 32 bits.
1444} // Finish the bitfieldReverse operation.
1445template <class A> // Accept the matching input types and dimensions.
1446typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1447bitfieldReverse(const A& a) { // Reverse all 32 bits.
1448    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1449    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1450        out[i] = glsl::bitfieldReverse(a[i]); // Store the computed component in the independent result.
1451    return out; // Return the completed result.
1452} // Finish the bitfieldReverse operation.
1453template <class T> // Accept the matching input types and dimensions.
1454typename std::enable_if<detail::integer32<T>::value, T>::type // Enable this overload only for compatible input types.
1455bitfieldExtract(T value, int offset, int bits) { // Extract the requested bit range.
1456    if (bits == 0 || offset < 0 || bits < 0 || offset > 32 - bits) // Handle an empty bit field separately.
1457        return T(0); // Extract the requested bit range.
1458    std::uint32_t mask = detail::bit_mask(bits), // Prepare the mask for the requested bit range.
1459                  out = (static_cast<std::uint32_t>(value) >> offset) & mask; // Shift the selected field down and discard other bits.
1460    if (std::is_signed<T>::value && bits < 32 && (out & (std::uint32_t(1) << (bits - 1)))) // Handle the exceptional or boundary case before continuing.
1461        out |= ~mask; // Add the encoded field to its packed bit position.
1462    return detail::bit_copy<T>(out); // Extract the requested bit range.
1463} // Finish the bitfieldExtract operation.
1464template <class A> // Accept the matching input types and dimensions.
1465typename std::enable_if<detail::traits<A>::vector, typename detail::result<A>::type>::type // Enable this overload only for compatible input types.
1466bitfieldExtract(const A& a, int offset, int bits) { // Extract the requested bit range.
1467    typename detail::result<A>::type out; // Allocate an independent result with the correct shape.
1468    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1469        out[i] = glsl::bitfieldExtract(a[i], offset, bits); // Store the computed component in the independent result.
1470    return out; // Return the completed result.
1471} // Finish the bitfieldExtract operation.
1472template <class T> // Accept the matching input types and dimensions.
1473typename std::enable_if<detail::integer32<T>::value, T>::type // Enable this overload only for compatible input types.
1474bitfieldInsert(T base, T insert, int offset, int bits) { // Replace the requested bit range.
1475    if (bits == 0 || offset < 0 || bits < 0 || offset > 32 - bits) // Handle an empty bit field separately.
1476        return base; // Replace the requested bit range.
1477    std::uint32_t mask = detail::bit_mask(bits) << offset; // Prepare the mask for the requested bit range.
1478    std::uint32_t out = (static_cast<std::uint32_t>(base) & ~mask) | // Prepare the mask for the requested bit range.
1479                        ((static_cast<std::uint32_t>(insert) << offset) & mask); // Keep only insertion bits that belong to the selected field.
1480    return detail::bit_copy<T>(out); // Replace the requested bit range.
1481} // Finish the bitfieldInsert operation.
1482template <class A, class B> // Accept the matching input types and dimensions.
1483typename std::enable_if<detail::binary<A, B>::valid, typename detail::binary<A, B>::result>::type // Enable this overload only for compatible input types.
1484bitfieldInsert(const A& base, const B& insert, int offset, int bits) { // Replace the requested bit range.
1485    typedef typename detail::binary<A, B>::scalar T; // Keep the chosen component type for the calculation.
1486    typename detail::binary<A, B>::result out; // Allocate an independent result with the correct shape.
1487    for (std::size_t i = 0; i < detail::binary<A, B>::size; ++i) // Visit each component needed by this calculation.
1488        out[i] = glsl::bitfieldInsert(static_cast<T>(detail::component(base, i)), // Store the computed component in the independent result.
1489                                      static_cast<T>(detail::component(insert, i)), // Use this component as the replacement bit pattern.
1490                                      offset, // Use the requested first bit position.
1491                                      bits); // Use the requested number of replacement bits.
1492    return out; // Return the completed result.
1493} // Finish the bitfieldInsert operation.
1494inline std::uint32_t uaddCarry(std::uint32_t x, std::uint32_t y, std::uint32_t& carry) { // Add unsigned values and report the carry.
1495    std::uint64_t sum = std::uint64_t(x) + y; // Use a wider integer to retain carry or product bits.
1496    carry = std::uint32_t(sum >> 32); // Publish the extra word after the input values have been copied.
1497    return std::uint32_t(sum); // Add unsigned values and report the carry.
1498} // Finish the uaddCarry operation.
1499inline std::uint32_t usubBorrow(std::uint32_t x, std::uint32_t y, std::uint32_t& borrow) { // Subtract unsigned values and report the borrow.
1500    borrow = x < y ? 1u : 0u; // Publish the extra word after the input values have been copied.
1501    return x - y; // Subtract unsigned values and report the borrow.
1502} // Finish the usubBorrow operation.
1503inline void umulExtended(std::uint32_t x, std::uint32_t y, std::uint32_t& msb, std::uint32_t& lsb) { // Split a full unsigned product into two words.
1504    std::uint64_t product = std::uint64_t(x) * y; // Use a wider integer to retain carry or product bits.
1505    msb = std::uint32_t(product >> 32); // Publish the extra word after the input values have been copied.
1506    lsb = std::uint32_t(product); // Publish the extra word after the input values have been copied.
1507} // Finish the umulExtended operation.
1508inline void imulExtended(std::int32_t x, std::int32_t y, std::int32_t& msb, std::int32_t& lsb) { // Split a full signed product into two words.
1509    std::uint64_t product = static_cast<std::uint64_t>(std::int64_t(x) * y); // Use a wider integer to retain carry or product bits.
1510    msb = detail::bit_copy<std::int32_t>(std::uint32_t(product >> 32)); // Publish the extra word after the input values have been copied.
1511    lsb = detail::bit_copy<std::int32_t>(std::uint32_t(product)); // Publish the extra word after the input values have been copied.
1512} // Finish the imulExtended operation.
1513/** @brief Add unsigned vectors modulo 2^32 and write their carry flags. */
1514template <class A, class B, class C> // Accept the matching input types and dimensions.
1515typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && // Enable this overload only for compatible input types.
1516                            detail::traits<C>::vector, // Complete the type and dimension rule for this overload.
1517                        vec<std::uint32_t, detail::traits<A>::size>>::type // Use the selected vector or matrix shape for this value.
1518uaddCarry(const A& x, const B& y, C&& carry) { // Add unsigned values and report the carry.
1519    static_assert(detail::traits<A>::size == detail::traits<B>::size && // Require matching component counts.
1520                      detail::traits<A>::size == detail::traits<C>::size, // Complete the type and dimension rule for this overload.
1521                  "uaddCarry dimensions mismatch"); // Explain the rejected input: uaddCarry dimensions mismatch.
1522    static_assert(std::is_same<typename detail::traits<A>::scalar, std::uint32_t>::value && // Check this type or dimension requirement at compile time.
1523                      std::is_same<typename detail::traits<B>::scalar, std::uint32_t>::value && // Require the second input to contain unsigned 32-bit components.
1524                      std::is_same<typename detail::traits<C>::scalar, std::uint32_t>::value, // Require an unsigned 32-bit carry or borrow output.
1525                  "uaddCarry requires unsigned integer components"); // Explain the rejected input: uaddCarry requires unsigned integer components.
1526    static_assert(detail::writable<C>::value, // Require distinct writable output components.
1527                  "uaddCarry output requires writable unique components"); // Explain the rejected input: uaddCarry output requires writable unique components.
1528    vec<std::uint32_t, detail::traits<A>::size> a(x), b(y), out, flags; // Keep an independent value for the result or aliased inputs.
1529    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1530        out[i] = glsl::uaddCarry(a[i], b[i], flags[i]); // Store the computed component in the independent result.
1531    carry = flags; // Publish the extra word after the input values have been copied.
1532    return out; // Return the completed result.
1533} // Finish the uaddCarry operation.
1534/** @brief Subtract unsigned vectors modulo 2^32 and write their borrow flags. */
1535template <class A, class B, class C> // Accept the matching input types and dimensions.
1536typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && // Enable this overload only for compatible input types.
1537                            detail::traits<C>::vector, // Complete the type and dimension rule for this overload.
1538                        vec<std::uint32_t, detail::traits<A>::size>>::type // Use the selected vector or matrix shape for this value.
1539usubBorrow(const A& x, const B& y, C&& borrow) { // Subtract unsigned values and report the borrow.
1540    static_assert(detail::traits<A>::size == detail::traits<B>::size && // Require matching component counts.
1541                      detail::traits<A>::size == detail::traits<C>::size, // Complete the type and dimension rule for this overload.
1542                  "usubBorrow dimensions mismatch"); // Explain the rejected input: usubBorrow dimensions mismatch.
1543    static_assert(std::is_same<typename detail::traits<A>::scalar, std::uint32_t>::value && // Check this type or dimension requirement at compile time.
1544                      std::is_same<typename detail::traits<B>::scalar, std::uint32_t>::value && // Require the second input to contain unsigned 32-bit components.
1545                      std::is_same<typename detail::traits<C>::scalar, std::uint32_t>::value, // Require an unsigned 32-bit carry or borrow output.
1546                  "usubBorrow requires unsigned integer components"); // Explain the rejected input: usubBorrow requires unsigned integer components.
1547    static_assert(detail::writable<C>::value, // Require distinct writable output components.
1548                  "usubBorrow output requires writable unique components"); // Explain the rejected input: usubBorrow output requires writable unique components.
1549    vec<std::uint32_t, detail::traits<A>::size> a(x), b(y), out, flags; // Keep an independent value for the result or aliased inputs.
1550    for (std::size_t i = 0; i < detail::traits<A>::size; ++i) // Visit each component needed by this calculation.
1551        out[i] = glsl::usubBorrow(a[i], b[i], flags[i]); // Store the computed component in the independent result.
1552    borrow = flags; // Publish the extra word after the input values have been copied.
1553    return out; // Return the completed result.
1554} // Finish the usubBorrow operation.
1555#define SHDR_DETAIL_EXTENDED(NAME, T) /* Generate the matching scalar and vector overloads. */ \
1556    template <class A, class B, class C, class D> /* Accept the matching input types and dimensions. */ \
1557    typename std::enable_if<detail::traits<A>::vector && detail::traits<B>::vector && /* Enable this overload only for compatible input types. */ \
1558                            detail::traits<C>::vector && detail::traits<D>::vector>::type /* Complete the type and dimension rule for this overload. */ \
1559    NAME(const A& x, const B& y, C&& msb, D&& lsb) { /* Start the matching math overload. */ \
1560        static_assert(detail::traits<A>::size == detail::traits<B>::size && /* Require matching component counts. */ \
1561                          detail::traits<A>::size == detail::traits<C>::size && /* Complete the type and dimension rule for this overload. */ \
1562                          detail::traits<A>::size == detail::traits<D>::size, /* Complete the type and dimension rule for this overload. */ \
1563                      "extended multiplication dimensions mismatch"); /* Explain the rejected input: extended multiplication dimensions mismatch. */ \
1564        static_assert(std::is_same<typename detail::traits<A>::scalar, T>::value && /* Check this type or dimension requirement at compile time. */ \
1565                          std::is_same<typename detail::traits<B>::scalar, T>::value && /* Require the second input to use the selected integer type. */ \
1566                          std::is_same<typename detail::traits<C>::scalar, T>::value && /* Require the high output word to use the selected integer type. */ \
1567                          std::is_same<typename detail::traits<D>::scalar, T>::value, /* Require the low output word to use the selected integer type. */ \
1568                      "extended multiplication component types must match"); /* Explain the rejected input: extended multiplication component types must match. */ \
1569        static_assert(detail::writable<C>::value && detail::writable<D>::value, /* Require distinct writable output components. */ \
1570                      "extended multiplication requires writable unique output components"); /* Explain the rejected input: extended multiplication requires writable unique output components. */ \
1571        vec<T, detail::traits<A>::size> a(x), b(y), high, low; /* Keep an independent value for the result or aliased inputs. */ \
1572        for (std::size_t i = 0; i < detail::traits<A>::size; ++i) { /* Visit each component needed by this calculation. */ \
1573            glsl::NAME(a[i], b[i], high[i], low[i]); /* Compute both words for this pair of copied components. */ \
1574        } /* Finish this component or matrix pass. */ \
1575        msb = high; /* Publish the extra word after the input values have been copied. */ \
1576        lsb = low; /* Publish the extra word after the input values have been copied. */ \
1577    } /* Finish this generated overload. */
1578SHDR_DETAIL_EXTENDED(umulExtended, std::uint32_t) // Split a full unsigned product into two words.
1579SHDR_DETAIL_EXTENDED(imulExtended, std::int32_t) // Split a full signed product into two words.
1580#undef SHDR_DETAIL_EXTENDED // Remove this local code generator macro.
1581/** @} */
1582
1583/** @name Packing
1584 * Normalized packing follows the GLSL clamp-and-round formulas.  unpacking
1585 * places the least significant byte/halfword in x. Half-float encoding rounds
1586 * to nearest even and preserves infinities and a quiet-NaN representation.
1587 * @{ */
1588inline std::uint32_t packUnorm2x16(const vec2& v) { // Pack two normalized values into 16-bit fields.
1589    std::uint32_t x = std::uint32_t(std::round(glsl::clamp(v.x, 0.0f, 1.0f) * 65535.0f)); // Hold the exact integer bits used by this operation.
1590    std::uint32_t y = std::uint32_t(std::round(glsl::clamp(v.y, 0.0f, 1.0f) * 65535.0f)); // Hold the exact integer bits used by this operation.
1591    return x | (y << 16); // Pack two normalized values into 16-bit fields.
1592} // Finish the packUnorm2x16 operation.
1593inline vec2 unpackUnorm2x16(std::uint32_t p) { // Decode two unsigned normalized 16-bit fields.
1594    return vec2(float(p & 65535u), float(p >> 16)) / 65535.0f; // Decode two unsigned normalized 16-bit fields.
1595} // Finish the unpackUnorm2x16 operation.
1596inline std::uint32_t packSnorm2x16(const vec2& v) { // Pack two signed normalized values into 16-bit fields.
1597    std::int32_t x = std::int32_t(std::round(glsl::clamp(v.x, -1.0f, 1.0f) * 32767.0f)); // Hold the exact integer bits used by this operation.
1598    std::int32_t y = std::int32_t(std::round(glsl::clamp(v.y, -1.0f, 1.0f) * 32767.0f)); // Hold the exact integer bits used by this operation.
1599    return (std::uint32_t(x) & 65535u) | (std::uint32_t(y) << 16); // Pack two signed normalized values into 16-bit fields.
1600} // Finish the packSnorm2x16 operation.
1601inline vec2 unpackSnorm2x16(std::uint32_t p) { // Decode two signed normalized 16-bit fields.
1602    std::int32_t x = std::int32_t(p & 65535u), y = std::int32_t(p >> 16); // Hold the exact integer bits used by this operation.
1603    if (x & 32768) // Handle the exceptional or boundary case before continuing.
1604        x -= 65536; // Extend the stored signed field into a signed scalar.
1605    if (y & 32768) // Handle the exceptional or boundary case before continuing.
1606        y -= 65536; // Extend the stored signed field into a signed scalar.
1607    return glsl::clamp(vec2(x, y) / 32767.0f, -1.0f, 1.0f); // Decode two signed normalized 16-bit fields.
1608} // Finish the unpackSnorm2x16 operation.
1609inline std::uint32_t packUnorm4x8(const vec4& v) { // Pack four normalized values into bytes.
1610    std::uint32_t out = 0; // Hold the exact integer bits used by this operation.
1611    for (std::size_t i = 0; i < 4; ++i) // Visit each component needed by this calculation.
1612        out |= std::uint32_t(std::round(glsl::clamp(v[i], 0.0f, 1.0f) * 255.0f)) << (i * 8); // Add the encoded field to its packed bit position.
1613    return out; // Return the completed result.
1614} // Finish the packUnorm4x8 operation.
1615inline vec4 unpackUnorm4x8(std::uint32_t p) { // Decode four unsigned normalized bytes.
1616    vec4 out; // Allocate four independent unpacked components.
1617    for (std::size_t i = 0; i < 4; ++i) // Visit each component needed by this calculation.
1618        out[i] = float((p >> (i * 8)) & 255u) / 255.0f; // Store the computed component in the independent result.
1619    return out; // Return the completed result.
1620} // Finish the unpackUnorm4x8 operation.
1621inline std::uint32_t packSnorm4x8(const vec4& v) { // Pack four signed normalized values into bytes.
1622    std::uint32_t out = 0; // Hold the exact integer bits used by this operation.
1623    for (std::size_t i = 0; i < 4; ++i) // Visit each component needed by this calculation.
1624        out |= (std::uint32_t(std::int32_t(std::round(glsl::clamp(v[i], -1.0f, 1.0f) * 127.0f))) & // Add the encoded field to its packed bit position.
1625                255u) // Keep only the low byte of the signed normalized encoding.
1626               << (i * 8); // Move that byte into its component position.
1627    return out; // Return the completed result.
1628} // Finish the packSnorm4x8 operation.
1629inline vec4 unpackSnorm4x8(std::uint32_t p) { // Decode four signed normalized bytes.
1630    vec4 out; // Allocate four independent unpacked components.
1631    for (std::size_t i = 0; i < 4; ++i) { // Visit each component needed by this calculation.
1632        int v = int((p >> (i * 8)) & 255u); // Extract this byte into a signed-capable scalar.
1633        if (v & 128) // Handle the exceptional or boundary case before continuing.
1634            v -= 256; // Extend an eight-bit negative value to the scalar type.
1635        out[i] = glsl::max(float(v) / 127.0f, -1.0f); // Store the computed component in the independent result.
1636    } // Finish this component or matrix pass.
1637    return out; // Return the completed result.
1638} // Finish the unpackSnorm4x8 operation.
1639namespace detail { // Keep these names inside the detail namespace.
1640inline std::uint16_t float_to_half(float value) { // Encode an IEEE half with ties rounded to even.
1641    std::uint32_t bits = glsl::floatBitsToUint(value), sign = (bits >> 16) & 32768u; // Separate the sign and payload bits for the conversion.
1642    int exponent = int((bits >> 23) & 255u) - 127 + 15; // Translate the exponent bias to the target float format.
1643    std::uint32_t mantissa = bits & 8388607u; // Keep the floating-point significand bits for encoding.
1644    if (((bits >> 23) & 255u) == 255u) // Handle the exceptional or boundary case before continuing.
1645        return std::uint16_t(sign | 31744u | (mantissa ? 512u : 0u)); // Encode an IEEE half with ties rounded to even.
1646    if (exponent >= 31) // Select the matching half-float exponent range.
1647        return std::uint16_t(sign | 31744u); // Encode an IEEE half with ties rounded to even.
1648    if (exponent <= 0) { // Select the matching half-float exponent range.
1649        if (exponent < -10) // Select the matching half-float exponent range.
1650            return std::uint16_t(sign); // Encode an IEEE half with ties rounded to even.
1651        mantissa |= 8388608u; // Restore the implicit leading significand bit.
1652        unsigned shift = unsigned(14 - exponent); // Choose the right shift for a half-float subnormal.
1653        std::uint32_t truncated = mantissa >> shift, remainder = mantissa & ((1u << shift) - 1u), // Keep the floating-point significand bits for encoding.
1654                      halfway = 1u << (shift - 1); // Identify the exact halfway rounding bit.
1655        if (remainder > halfway || (remainder == halfway && (truncated & 1u))) // Round up above halfway or for an odd halfway result.
1656            ++truncated; // Round the retained encoding to the next representable value.
1657        return std::uint16_t(sign | truncated); // Encode an IEEE half with ties rounded to even.
1658    } // Finish handling this condition.
1659    std::uint32_t truncated = (std::uint32_t(exponent) << 10) | (mantissa >> 13), // Keep the floating-point significand bits for encoding.
1660                  remainder = mantissa & 8191u; // Retain the discarded low bits for the rounding decision.
1661    if (remainder > 4096u || (remainder == 4096u && (truncated & 1u))) // Round up above halfway or for an odd halfway result.
1662        ++truncated; // Round the retained encoding to the next representable value.
1663    return std::uint16_t(sign | truncated); // Encode an IEEE half with ties rounded to even.
1664} // Finish the float_to_half operation.
1665inline float half_to_float(std::uint16_t h) { // Expand an IEEE half into a float.
1666    std::uint32_t sign = (std::uint32_t(h) & 32768u) << 16, mantissa = h & 1023u; // Separate the sign and payload bits for the conversion.
1667    int exponent = (h >> 10) & 31; // Translate the exponent bias to the target float format.
1668    if (exponent == 0) { // Select the matching half-float exponent range.
1669        if (!mantissa) // Handle the exceptional or boundary case before continuing.
1670            return glsl::uintBitsToFloat(sign); // Expand an IEEE half into a float.
1671        exponent = -14; // Set the exponent for a subnormal source value.
1672        while (!(mantissa & 1024u)) { // Continue until the remaining bits reach the required form.
1673            mantissa <<= 1; // Move the first significand bit toward the normalized position.
1674            --exponent; // Adjust the exponent while normalizing the significand.
1675        } // Finish this component or matrix pass.
1676        mantissa &= 1023u; // Remove the leading bit before storing the fraction.
1677        return glsl::uintBitsToFloat(sign | (std::uint32_t(exponent + 127) << 23) | // Expand an IEEE half into a float.
1678                                     (mantissa << 13)); // Place the expanded significand in the float fraction field.
1679    } // Finish handling this condition.
1680    if (exponent == 31) // Select the matching half-float exponent range.
1681        return glsl::uintBitsToFloat(sign | 2139095040u | (mantissa << 13)); // Expand an IEEE half into a float.
1682    return glsl::uintBitsToFloat(sign | (std::uint32_t(exponent - 15 + 127) << 23) | // Expand an IEEE half into a float.
1683                                 (mantissa << 13)); // Place the expanded significand in the float fraction field.
1684} // Finish the half_to_float operation.
1685} // namespace detail
1686inline std::uint32_t packHalf2x16(const vec2& v) { // Pack two IEEE half encodings into one word.
1687    return std::uint32_t(detail::float_to_half(v.x)) | // Pack two IEEE half encodings into one word.
1688           (std::uint32_t(detail::float_to_half(v.y)) << 16); // Place the second half encoding in the upper word.
1689} // Finish the packHalf2x16 operation.
1690inline vec2 unpackHalf2x16(std::uint32_t v) { // Expand the two IEEE half encodings.
1691    return vec2(detail::half_to_float(std::uint16_t(v)), // Expand the two IEEE half encodings.
1692                detail::half_to_float(std::uint16_t(v >> 16))); // Expand the upper half encoding into the second component.
1693} // Finish the unpackHalf2x16 operation.
1694/** @} */
1695} // namespace glsl
1696} // namespace shdr
1697#endif // Finish the math layer include guard.
1698
1699// ---- runtime.hpp ----
1700#ifndef SHDR_RUNTIME_HPP // Skip this section if it was already included.
1701#define SHDR_RUNTIME_HPP /* Mark this section as included. */
1702
1703/** @brief Major version of shdr. */
1704#define SHDR_VERSION_MAJOR 1 // Identify the public API's major release series.
1705/** @brief Minor version within the current major release. */
1706#define SHDR_VERSION_MINOR 0 // Identify additions within the public API's release series.
1707/** @brief Patch version within the current minor release. */
1708#define SHDR_VERSION_PATCH 0 // Identify corrections within this minor release.
1709/** @brief The library release version as a string. */
1710#define SHDR_VERSION "1.0.0" // Expose the library release as a compile-time string.
1711
1712#include <algorithm> // Use standard searches, bounds, and resource copying.
1713#include <cstddef> // Use portable pointer sizes and offsets.
1714#include <cstdint> // Use integer widths that match GLSL values.
1715#include <cctype> // Recognize characters in embedded shader declarations.
1716#include <cstring> // Copy bytes and function addresses with std::memcpy.
1717#include <functional> // Store GL resolvers and deferred cleanup callbacks.
1718#include <initializer_list> // Accept concise resource initialization from application values.
1719#include <limits> // Check arithmetic against the type limits.
1720#include <map> // Find registered shader factories and shared kernel snapshots.
1721#include <memory> // Retain resources while pipelines and queued jobs use them.
1722#include <mutex> // Protect shared work queues and deferred deletion.
1723#include <thread> // Track the context thread and start CPU workers.
1724#include <sstream> // Build readable shader and driver diagnostics.
1725#include <stdexcept> // Report invalid resources and failed execution.
1726#include <string> // Keep embedded shader text and named interfaces.
1727#include <type_traits> // Check shader storage and port types at compile time.
1728#include <vector> // Store ordered stages, ports, and resource values.
1729
1730/** @brief Portable, header-only CPU/OpenGL compute pipelines. */
1731namespace shdr { // Group these definitions in the shdr namespace.
1732/** @brief A shader, resource, context or dispatch validation failure. */
1733struct error : std::runtime_error { // Keep the error values and operations together.
1734    explicit error(const std::string& s) : std::runtime_error(s) { // Preserve the supplied validation or driver diagnostic.
1735    } // End this scope in runtime.
1736}; // End this scope in runtime.
1737
1738/** @brief Three unsigned dimensions. dispatch dimensions count work groups. */
1739struct extent { // Keep the extent values and operations together.
1740    unsigned x, y, z; // Keep the three unsigned dispatch or local dimensions.
1741    /** @brief Construct three workgroup counts, defaulting each dimension to one. */
1742    explicit extent(unsigned x_ = 1, unsigned y_ = 1, unsigned z_ = 1) : x(x_), y(y_), z(z_) { // Initialize all three positive-or-zero dimensions supplied by the caller.
1743    } // End this scope in runtime.
1744}; // End this scope in runtime.
1745/** @brief Minimum shader language selected independently of the context's actual version. */
1746enum class profile { es31, es32, gl43, gl45, gl46 }; // Name the supported shader language profiles.
1747/** @brief Automatic uses CPU execution for run() and GPU execution for run(device). */
1748enum class backend { automatic, cpu, gpu }; // Select automatic, explicit CPU or explicit GPU execution.
1749/** @brief Resource access qualifiers. readonly also prevents CPU writes at compile time. */
1750enum class access { readonly, writeonly, readwrite }; // Express how a shader may access a bound resource.
1751
1752namespace detail { // Group these definitions in the detail namespace.
1753inline bool identifier_char(char c) { // Recognize the letters, digits, and underscore allowed in an identifier.
1754    return std::isalnum(static_cast<unsigned char>(c)) || c == '_'; // Recognize the letters, digits, and underscore allowed in an identifier.
1755} // End this scope in identifier char.
1756inline std::string trim(const std::string& text) { // Remove surrounding whitespace from one resource argument.
1757    const std::size_t first = text.find_first_not_of(" \t\r\n"); // Set the first non-space character.
1758    return first == std::string::npos // Remove surrounding whitespace from one resource argument.
1759               ? std::string() // Select the value for this branch of the condition.
1760               : text.substr(first, text.find_last_not_of(" \t\r\n") - first + 1); // Copy only the non-whitespace portion of this argument.
1761} // End this scope in trim.
1762 // ESSL forbids token-pasting macros. Expand only resource declarations in the host,
1763 // preserving comments, string literals, shader statements and original line numbers.
1764inline std::string expand_declarations(const std::string& source, bool es) { // Expand host resource declarations into native GLSL interfaces.
1765    std::string out; // Keep the assembled shader text.
1766    for (std::size_t i = 0; i < source.size();) { // Walk the embedded shader text while respecting its token boundaries.
1767        const std::size_t start = i; // Set the beginning of the current token or range.
1768        if (source.compare(i, 2, "//") == 0) { // Copy the line comment verbatim.
1769            const std::size_t end = source.find('\n', i); // Set the end of the current range.
1770            i = end == std::string::npos ? source.size() : end + 1; // Advance beyond the preserved comment or declaration.
1771        } else if (source.compare(i, 2, "/*") == 0) { // Copy the block comment verbatim.
1772            const std::size_t end = source.find("*/", i + 2); // Set the end of the current range.
1773            i = end == std::string::npos ? source.size() : end + 2; // Advance beyond the preserved comment or declaration.
1774        } else if (source[i] == '\"' || source[i] == '\'') { // Copy quoted shader text as one lexical unit.
1775            const char quote = source[i++]; // Remember which quote terminates this shader literal.
1776            while (i < source.size()) { // Walk the embedded shader text while respecting its token boundaries.
1777                if (source[i] == '\\') { // Treat an escaped character as part of the quoted shader text.
1778                    i = (std::min)(i + 2, source.size()); // Advance past the escaped character within the source bounds.
1779                    continue; // Continue with the next token or work item.
1780                } // End this scope in expand declarations.
1781                if (source[i++] == quote) // Choose this branch when source[i++] equals quote.
1782                    break; // Stop this search or loop once its current item is complete.
1783            } // End this scope in expand declarations.
1784        } else if (identifier_char(source[i])) { // Recognize the letters, digits, and underscore allowed in an identifier.
1785            while (i < source.size() && identifier_char(source[i])) // Walk the embedded shader text while respecting its token boundaries.
1786                ++i; // Expand host resource declarations into native GLSL interfaces.
1787            const std::string token = source.substr(start, i - start); // Set the current shader identifier.
1788            if (token == "SHDR_BUFFER" || token == "SHDR_IMAGE2D") { // Choose this branch when token equals "SHDR BUFFER" or token equals "SHDR IMAGE2D".
1789                std::size_t open = i; // Set the opening parenthesis of a resource declaration.
1790                while (open < source.size() && // Walk the embedded shader text while respecting its token boundaries.
1791                       std::isspace(static_cast<unsigned char>(source[open]))) // Keep the opening parenthesis of a resource declaration.
1792                    ++open; // Keep the opening parenthesis of a resource declaration.
1793                if (open >= source.size() || source[open] != '(') // Check resource size or driver limits before accessing storage.
1794                    throw error("resource declaration requires parentheses: " + token); // Report resource declaration requires parentheses: .
1795                std::size_t end = open + 1, argument = end; // Set the end of the current range.
1796                unsigned depth = 1; // Set the current parenthesis nesting.
1797                std::vector<std::string> args; // Keep the parsed declaration arguments.
1798                for (; end < source.size(); ++end) { // Walk the embedded shader text while respecting its token boundaries.
1799                    if (source[end] == '(') // Choose this branch when source[end] equals '('.
1800                        ++depth; // Keep the current parenthesis nesting.
1801                    if (source[end] == ')') // Choose this branch when source[end] equals ')'.
1802                        --depth; // Keep the current parenthesis nesting.
1803                    if ((source[end] == ',' && depth == 1) || depth == 0) { // Choose this branch when (source[end] equals ',' and depth equals 1) or depth equals 0.
1804                        args.push_back(trim(source.substr(argument, end - argument))); // Retain this entry in the ordered resource or work collection.
1805                        argument = end + 1; // Set the beginning of the next resource argument.
1806                    } // End this scope in expand declarations.
1807                    if (!depth) // Finish the argument list at its matching closing parenthesis.
1808                        break; // Stop this search or loop once its current item is complete.
1809                } // End this scope in expand declarations.
1810                const bool image = token == "SHDR_IMAGE2D"; // Choose image or storage-buffer declaration syntax.
1811                if (depth || args.size() != (image ? 5u : 4u)) // Check resource size or driver limits before accessing storage.
1812                    throw error("invalid resource declaration: " + token); // Report invalid resource declaration: .
1813                const std::string mode = args.back(); // Set the declared shader resource access.
1814                if (mode != "readonly" && mode != "writeonly" && mode != "readwrite") // Choose the branch matching this interface or resource access.
1815                    throw error("invalid resource access: " + mode); // Report invalid resource access: .
1816                const std::string qualifier = mode == "readwrite" ? "" : mode + " "; // Set the access qualifier emitted into GLSL.
1817                if (image) { // Choose this branch when image.
1818                    if (es && mode == "readwrite" && args[1].compare(0, 4, "rgba") == 0) // Choose the branch matching this interface or resource access.
1819                        throw error( // Report the invalid operation.
1820                            "GLES RGBA images require readonly or writeonly declarations: " + // Append this literal GLSL source fragment.
1821                            args[3]); // Expand host resource declarations into native GLSL interfaces.
1822                    out += "layout(" + args[1] + ",binding=" + args[0] + ") " + qualifier + // Set the assembled shader text.
1823                           "uniform highp " + args[2] + " " + args[3] + ";"; // Append this literal GLSL source fragment.
1824                } else // Handle the alternative resource or completion case.
1825                    out += "layout(std430,binding=" + args[0] + ") " + qualifier + // Set the assembled shader text.
1826                           "buffer shdr_block_" + args[2] + " { " + args[1] + " " + args[2] + // Append this literal GLSL source fragment.
1827                           "[]; };"; // Append this literal GLSL source fragment.
1828                out.append(static_cast<std::size_t>( // Restore the original declaration's line count after expansion.
1829                               std::count(source.begin() + static_cast<std::ptrdiff_t>(start), // Keep the beginning of the current token or range.
1830                                          source.begin() + static_cast<std::ptrdiff_t>(end + 1), // Stop counting at the end of the replaced resource declaration.
1831                                          '\n')), // Count the newlines originally present in this declaration.
1832                           '\n'); // Append one newline for each removed original newline.
1833                i = end + 1; // Advance beyond the preserved comment or declaration.
1834                continue; // Continue with the next token or work item.
1835            } // End this scope in expand declarations.
1836        } else // Handle the alternative resource or completion case.
1837            ++i; // Expand host resource declarations into native GLSL interfaces.
1838        out.append(source, start, i - start); // Preserve this untouched token or comment in the exported GLSL.
1839    } // End this scope in expand declarations.
1840    return out; // Return the assembled shader text.
1841} // End this scope in expand declarations.
1842} // namespace detail
1843
1844/** @internal Export an embedded shader as standard GLSL, with version and declaration macros.
1845 * This function supplies the version directive. Guard the body's C++ include
1846 * with #ifdef __cplusplus. The exported source contains the selected version
1847 * and expanded declarations.
1848 */
1849inline std::string glsl_source(const std::string& source, profile p) { // Add the selected GLSL version and shared-declaration definitions.
1850    std::istringstream lines(source); // Read the embedded shader one line at a time.
1851    std::string line; // Read each embedded source line while checking version directives.
1852    while (std::getline(lines, line)) { // Inspect each source line for an unsupported version directive.
1853        std::size_t start = line.find_first_not_of(" \t\r"); // Set the beginning of the current token or range.
1854        if (start != std::string::npos && line[start] == '#') { // Choose this branch when start differs from std::string::npos and line[start] equals '#'.
1855            start = line.find_first_not_of(" \t", start + 1); // Set the beginning of the current token or range.
1856            if (start != std::string::npos && line.compare(start, 7, "version") == 0) // Choose this branch when start differs from std::string::npos and line.compare(start, 7, "version") equals 0.
1857                throw error("shared shaders must omit #version; glsl_source supplies it"); // Report shared shaders must omit #version. glsl_source supplies it.
1858        } // End this scope in glsl source.
1859    } // End this scope in glsl source.
1860    const char* version = p == profile::es31   ? "310 es" // Set the current GL version text.
1861                          : p == profile::es32 ? "320 es" // Select the version associated with this shader profile.
1862                          : p == profile::gl43 ? "430 core" // Select the version associated with this shader profile.
1863                          : p == profile::gl45 ? "450 core" // Select the version associated with this shader profile.
1864                                               : "460 core"; // Select desktop GLSL 4.60 for the remaining profile.
1865    std::string out = std::string("#version ") + version + "\n"; // Set the assembled shader text.
1866    if (p == profile::es31 || p == profile::es32) // Choose this branch when p equals profile::es31 or p equals profile::es32.
1867        out += "precision highp float;\nprecision highp int;\n"; // Set the assembled shader text.
1868    out += // Set the assembled shader text.
1869        "#define SHDR_BEGIN(name,x,y,z) layout(local_size_x=x,local_size_y=y,local_size_z=z) in;\n" // Emit a native workgroup declaration for this shader.
1870        "#define SHDR_END()\n" // Remove the host-only shader wrapper terminator.
1871        "#define SHDR_MAIN() void main()\n" // Map the shared entry-point spelling to native GLSL main.
1872        "#define SHDR_UNIFORM(t,n) uniform t n;\n" // Emit a native typed uniform declaration.
1873        "#define SHDR_SWIZZLE(v,s) (v).s\n" // Map shared swizzle syntax to native GLSL component selection.
1874        "#define SHDR_NOT(v) not(v)\n" // Map shared boolean negation to the native GLSL builtin.
1875        "#define SHDR_IN(t,n) in t n\n" // Emit a native input parameter qualifier.
1876        "#define SHDR_OUT(t,n) out t n\n" // Emit a native output parameter qualifier.
1877        "#define SHDR_INOUT(t,n) inout t n\n" // Emit a native input-output parameter qualifier.
1878        "#line 1\n"; // Restore shader line numbering before appending the original source.
1879 // Desktop GLSL accepts highp precision qualifiers from GLSL 4.10 onward.
1880    return out + detail::expand_declarations(source, p == profile::es31 || p == profile::es32); // Add the selected GLSL version and shared-declaration definitions.
1881} // End this scope in glsl source.
1882
1883namespace detail { // Group these definitions in the detail namespace.
1884 // Private GL types and entry points keep the default header compatible with standard C++11.
1885typedef unsigned int GLenum; // Name the representation used by this GL or shader interface.
1886typedef unsigned int GLuint; // Name the representation used by this GL or shader interface.
1887typedef int GLint; // Name the representation used by this GL or shader interface.
1888typedef int GLsizei; // Name the representation used by this GL or shader interface.
1889typedef unsigned int GLbitfield; // Name the representation used by this GL or shader interface.
1890typedef unsigned char GLboolean; // Name the representation used by this GL or shader interface.
1891typedef std::ptrdiff_t GLsizeiptr; // Name the representation used by this GL or shader interface.
1892typedef std::ptrdiff_t GLintptr; // Name the representation used by this GL or shader interface.
1893typedef std::uint64_t GLuint64; // Name the representation used by this GL or shader interface.
1894typedef void* GLsync; // Name the representation used by this GL or shader interface.
1895#if defined(_WIN32) // Compile this branch only when its platform or backend condition holds.
1896#define SHDR_GL_CALL __stdcall /* Match the calling convention of the GL entry points. */
1897#else // Use the alternative platform or backend definition.
1898#define SHDR_GL_CALL /* Match the calling convention of the GL entry points. */
1899#endif // Finish this conditional section.
1900enum : unsigned { // Name the profile, access, or completion values accepted by this section.
1901    VERSION = 0x1F02, // Use the GL numeric code for version.
1902    MAJOR_VERSION = 0x821B, // Use the GL numeric code for major version.
1903    MINOR_VERSION = 0x821C, // Use the GL numeric code for minor version.
1904    COMPUTE_SHADER = 0x91B9, // Use the GL numeric code for compute shader.
1905    COMPILE_STATUS = 0x8B81, // Use the GL numeric code for compile status.
1906    LINK_STATUS = 0x8B82, // Use the GL numeric code for link status.
1907    INFO_LOG_LENGTH = 0x8B84, // Use the GL numeric code for info log length.
1908    COMPUTE_WORK_GROUP_SIZE = 0x8267, // Use the GL numeric code for compute work group size.
1909    MAX_COMPUTE_WORK_GROUP_COUNT = 0x91BE, // Use the GL numeric code for max compute work group count.
1910    MAX_COMPUTE_WORK_GROUP_SIZE = 0x91BF, // Use the GL numeric code for max compute work group size.
1911    MAX_COMPUTE_WORK_GROUP_INVOCATIONS = 0x90EB, // Use the GL numeric code for max compute work group invocations.
1912    MAX_SHADER_STORAGE_BUFFER_BINDINGS = 0x90DD, // Use the GL numeric code for max shader storage buffer bindings.
1913    MAX_IMAGE_UNITS = 0x8F38, // Use the GL numeric code for max image units.
1914    SHADER_STORAGE_BUFFER = 0x90D2, // Use the GL numeric code for shader storage buffer.
1915    DYNAMIC_DRAW = 0x88E8, // Use the GL numeric code for dynamic draw.
1916    MAP_READ_BIT = 1, // Use the GL numeric code for map read bit.
1917    ALL_BARRIER_BITS = 0xFFFFFFFFu, // Use the GL numeric code for all barrier bits.
1918    TEXTURE_2D = 0x0DE1, // Identify a two-dimensional texture target.
1919    FLOAT = 0x1406, // Use the GL numeric code for float.
1920    INT = 0x1404, // Use the GL numeric code for int.
1921    UNSIGNED_INT = 0x1405, // Use the GL numeric code for unsigned int.
1922    RED = 0x1903, // Use the GL numeric code for red.
1923    RGBA = 0x1908, // Use the GL numeric code for rgba.
1924    RED_INTEGER = 0x8D94, // Use the GL numeric code for red integer.
1925    RGBA_INTEGER = 0x8D99, // Use the GL numeric code for rgba integer.
1926    R32F = 0x822E, // Store one 32-bit floating-point component per pixel.
1927    R32I = 0x8235, // Store one signed 32-bit component per pixel.
1928    R32UI = 0x8236, // Store one unsigned 32-bit component per pixel.
1929    RGBA32F = 0x8814, // Store four 32-bit floating-point components per pixel.
1930    RGBA32I = 0x8D82, // Store four signed 32-bit components per pixel.
1931    RGBA32UI = 0x8D70, // Store four unsigned 32-bit components per pixel.
1932    READ_ONLY = 0x88B8, // Use the GL numeric code for read only.
1933    WRITE_ONLY = 0x88B9, // Use the GL numeric code for write only.
1934    READ_WRITE = 0x88BA, // Use the GL numeric code for read write.
1935    UNPACK_ALIGNMENT = 0x0CF5, // Use the GL numeric code for unpack alignment.
1936    UNPACK_ROW_LENGTH = 0x0CF2, // Use the GL numeric code for unpack row length.
1937    UNPACK_SKIP_ROWS = 0x0CF3, // Use the GL numeric code for unpack skip rows.
1938    UNPACK_SKIP_PIXELS = 0x0CF4, // Use the GL numeric code for unpack skip pixels.
1939    PIXEL_UNPACK_BUFFER = 0x88EC, // Use the GL numeric code for pixel unpack buffer.
1940    SYNC_GPU_COMMANDS_COMPLETE = 0x9117, // Use the GL numeric code for sync gpu commands complete.
1941    ALREADY_SIGNALED = 0x911A, // Use the GL numeric code for already signaled.
1942    TIMEOUT_EXPIRED = 0x911B, // Use the GL numeric code for timeout expired.
1943    CONDITION_SATISFIED = 0x911C, // Use the GL numeric code for condition satisfied.
1944    WAIT_FAILED = 0x911D, // Use the GL numeric code for wait failed.
1945    SYNC_FLUSH_COMMANDS_BIT = 1 // Use the GL numeric code for sync flush commands bit.
1946}; // End this scope in runtime.
1947
1948struct gl_api { // Keep the gl api values and operations together.
1949#define SHDR_GL_PROC(ret, n, args) /* Declare a GL function pointer with its exact argument types. */ \
1950    typedef ret(SHDR_GL_CALL* n##_type) args; /* Name the representation used by this GL or shader interface. */ \
1951    n##_type n; /* Store the resolved function pointer for this GL entry point. */
1952    SHDR_GL_PROC(const unsigned char*, GetString, (GLenum)) // Declare a function to read the driver version or renderer text.
1953    SHDR_GL_PROC(void, GetIntegerv, (GLenum, GLint*)) // Declare a function to read a scalar device limit or current binding.
1954    SHDR_GL_PROC(void, GetIntegeri_v, (GLenum, GLuint, GLint*)) // Declare a function to read the limit for a selected compute axis.
1955    SHDR_GL_PROC(GLenum, GetError, ()) // Declare a function to read the pending GL error code.
1956    SHDR_GL_PROC(GLuint, CreateShader, (GLenum)) // Declare a function to allocate a compute shader object.
1957    SHDR_GL_PROC(void, ShaderSource, (GLuint, GLsizei, const char* const*, const GLint*)) // Declare a function to supply the embedded shader text to the driver.
1958    SHDR_GL_PROC(void, CompileShader, (GLuint)) // Declare a function to ask the driver to compile the compute shader.
1959    SHDR_GL_PROC(void, GetShaderiv, (GLuint, GLenum, GLint*)) // Declare a function to read shader compilation status or log length.
1960    SHDR_GL_PROC(void, GetShaderInfoLog, (GLuint, GLsizei, GLsizei*, char*)) // Declare a function to read the driver explanation of a shader compilation failure.
1961    SHDR_GL_PROC(void, DeleteShader, (GLuint)) // Declare a function to release the temporary shader object.
1962    SHDR_GL_PROC(GLuint, CreateProgram, ()) // Declare a function to allocate the linked compute program.
1963    SHDR_GL_PROC(void, AttachShader, (GLuint, GLuint)) // Declare a function to attach the compute shader before linking.
1964    SHDR_GL_PROC(void, LinkProgram, (GLuint)) // Declare a function to link the compiled compute program.
1965    SHDR_GL_PROC(void, GetProgramiv, (GLuint, GLenum, GLint*)) // Declare a function to read linked-program status, log length, or local dimensions.
1966    SHDR_GL_PROC(void, GetProgramInfoLog, (GLuint, GLsizei, GLsizei*, char*)) // Declare a function to read the driver explanation of a program-link failure.
1967    SHDR_GL_PROC(void, DeleteProgram, (GLuint)) // Declare a function to release the GL program after its owners finish using it.
1968    SHDR_GL_PROC(void, UseProgram, (GLuint)) // Declare a function to select the compute program for the next dispatch.
1969    SHDR_GL_PROC(GLint, GetUniformLocation, (GLuint, const char*)) // Declare a function to find a named uniform in the linked program.
1970    SHDR_GL_PROC(void, Uniform1f, (GLint, float)) // Declare a function to assign a float uniform.
1971    SHDR_GL_PROC(void, Uniform1i, (GLint, GLint)) // Declare a function to assign an integer or boolean uniform.
1972    SHDR_GL_PROC(void, Uniform1ui, (GLint, GLuint)) // Declare a function to assign an unsigned integer uniform.
1973#define SHDR_GL_UNIFORM(n) /* Define the SHDR_GL_UNIFORM helper for this group of declarations. */ \
1974    SHDR_GL_PROC(void, Uniform##n##fv, (GLint, GLsizei, const float*)) /* Declare a function to send this typed uniform to GL. */ \
1975    SHDR_GL_PROC(void, Uniform##n##iv, (GLint, GLsizei, const GLint*)) /* Declare a function to send this typed uniform to GL. */ \
1976    SHDR_GL_PROC(void, Uniform##n##uiv, (GLint, GLsizei, const GLuint*)) /* Declare a function to send this typed uniform to GL. */
1977    SHDR_GL_UNIFORM(2) // Declare the GL functions for vectors with this component count.
1978    SHDR_GL_UNIFORM(3) // Declare the GL functions for vectors with this component count.
1979    SHDR_GL_UNIFORM(4) // Declare the GL functions for vectors with this component count.
1980#undef SHDR_GL_UNIFORM // Remove this temporary macro after its declarations are complete.
1981#define SHDR_GL_MATRIX(n) /* Define the SHDR_GL_MATRIX helper for this group of declarations. */ \
1982    SHDR_GL_PROC(void, UniformMatrix##n##fv, (GLint, GLsizei, GLboolean, const float*)) /* Declare a function to send this typed uniform to GL. */
1983    SHDR_GL_MATRIX(2) // Declare the GL function for this column-major matrix shape.
1984    SHDR_GL_MATRIX(3) // Declare the GL function for this column-major matrix shape.
1985    SHDR_GL_MATRIX(4) // Declare the GL function for this column-major matrix shape.
1986    SHDR_GL_MATRIX(2x3) // Declare the GL function for this column-major matrix shape.
1987    SHDR_GL_MATRIX(2x4) // Declare the GL function for this column-major matrix shape.
1988    SHDR_GL_MATRIX(3x2) // Declare the GL function for this column-major matrix shape.
1989    SHDR_GL_MATRIX(3x4) // Declare the GL function for this column-major matrix shape.
1990    SHDR_GL_MATRIX(4x2) // Declare the GL function for this column-major matrix shape.
1991    SHDR_GL_MATRIX(4x3) // Declare the GL function for this column-major matrix shape.
1992#undef SHDR_GL_MATRIX // Remove this temporary macro after its declarations are complete.
1993    SHDR_GL_PROC(void, GenBuffers, (GLsizei, GLuint*)) // Declare a function to allocate names for GL storage buffers.
1994    SHDR_GL_PROC(void, DeleteBuffers, (GLsizei, const GLuint*)) // Declare a function to release owned GL buffer names.
1995    SHDR_GL_PROC(void, BindBuffer, (GLenum, GLuint)) // Declare a function to select a buffer for allocation or transfer.
1996    SHDR_GL_PROC(void, BufferData, (GLenum, GLsizeiptr, const void*, GLenum)) // Declare a function to allocate buffer storage and supply its initial host values.
1997    SHDR_GL_PROC(void, BufferSubData, (GLenum, GLintptr, GLsizeiptr, const void*)) // Declare a function to upload the current host buffer values.
1998    SHDR_GL_PROC(void, BindBufferBase, (GLenum, GLuint, GLuint)) // Declare a function to bind storage to the shader interface index.
1999    SHDR_GL_PROC(void*, MapBufferRange, (GLenum, GLintptr, GLsizeiptr, GLbitfield)) // Declare a function to map completed GPU buffer values for a host readback.
2000    SHDR_GL_PROC(GLboolean, UnmapBuffer, (GLenum)) // Declare a function to finish reading the mapped GPU buffer.
2001    SHDR_GL_PROC(void, DispatchCompute, (GLuint, GLuint, GLuint)) // Declare a function to queue the shader workgroups.
2002    SHDR_GL_PROC(void, MemoryBarrier, (GLbitfield)) // Declare a function to make earlier resource writes visible to following GPU commands.
2003    SHDR_GL_PROC(void, Finish, ()) // Declare a function to explicitly wait until queued GPU commands complete.
2004    SHDR_GL_PROC(GLsync, FenceSync, (GLenum, GLbitfield)) // Declare a function to insert a completion fence after queued compute work.
2005    SHDR_GL_PROC(GLenum, ClientWaitSync, (GLsync, GLbitfield, GLuint64)) // Declare a function to check a GPU fence with the caller-selected timeout.
2006    SHDR_GL_PROC(void, DeleteSync, (GLsync)) // Declare the GL completion-fence deletion entry point.
2007    SHDR_GL_PROC(void, Flush, ()) // Declare the GL command-flush entry point.
2008    SHDR_GL_PROC(void, GenTextures, (GLsizei, GLuint*)) // Declare a function to allocate names for owned GL images.
2009    SHDR_GL_PROC(void, DeleteTextures, (GLsizei, const GLuint*)) // Declare a function to release owned GL image names.
2010    SHDR_GL_PROC(void, BindTexture, (GLenum, GLuint)) // Declare a function to select the image for allocation or upload.
2011    SHDR_GL_PROC(void, TexStorage2D, (GLenum, GLsizei, GLenum, GLsizei, GLsizei)) // Declare a function to allocate immutable two-dimensional image storage.
2012    SHDR_GL_PROC(void, // Declare the next dynamically resolved GL function signature.
2013                 TexSubImage2D, // Name the function that uploads pixels into an existing texture.
2014                 (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const void*)) // Match the argument order required by this GL entry point.
2015    SHDR_GL_PROC(void, BindImageTexture, (GLuint, GLuint, GLint, GLboolean, GLint, GLenum, GLenum)) // Declare a function to bind a typed image to its shader interface index.
2016    SHDR_GL_PROC(void, PixelStorei, (GLenum, GLint)) // Declare a function to set or restore the application pixel-transfer layout.
2017#undef SHDR_GL_PROC // Remove this temporary macro after its declarations are complete.
2018    explicit gl_api(const std::function<void*(const char*)>& resolver) { // Resolve the GL calls used by resource transfers and dispatches.
2019#define SHDR_LOAD(n) /* Resolve one GL entry point and reject missing functions. */ \
2020    { /* Begin the protected scope for this operation. */ \
2021        void* p = resolver("gl" #n); /* Resolve the address of this named GL entry point. */ \
2022        if (!p) /* Reject a missing dynamically resolved GL function. */ \
2023            throw error("missing GL entry point: gl" #n); /* Report missing gl entry point: gl. */ \
2024        static_assert(sizeof(p) == sizeof(n), "function pointer size unsupported"); /* Require a representation that matches the shader interface. */ \
2025        std::memcpy(&n, &p, sizeof(n)); /* Copy the representation with the alias-safe byte-copy operation. */ \
2026    } /* End this scope in gl api. */
2027        SHDR_LOAD(GetString) // Load the function to read the driver version or renderer text.
2028        SHDR_LOAD(GetIntegerv) // Load the function to read a scalar device limit or current binding.
2029        SHDR_LOAD(GetIntegeri_v) // Load the function to read the limit for a selected compute axis.
2030        SHDR_LOAD(GetError) // Load the function to read the pending GL error code.
2031        SHDR_LOAD(CreateShader) // Load the function to allocate a compute shader object.
2032        SHDR_LOAD(ShaderSource) // Load the function to supply the embedded shader text to the driver.
2033        SHDR_LOAD(CompileShader) // Load the function to ask the driver to compile the compute shader.
2034        SHDR_LOAD(GetShaderiv) // Load the function to read shader compilation status or log length.
2035        SHDR_LOAD(GetShaderInfoLog) // Load the function to read the driver explanation of a shader compilation failure.
2036        SHDR_LOAD(DeleteShader) // Load the function to release the temporary shader object.
2037        SHDR_LOAD(CreateProgram) // Load the function to allocate the linked compute program.
2038        SHDR_LOAD(AttachShader) // Load the function to attach the compute shader before linking.
2039        SHDR_LOAD(LinkProgram) // Load the function to link the compiled compute program.
2040        SHDR_LOAD(GetProgramiv) // Load the function to read linked-program status, log length, or local dimensions.
2041        SHDR_LOAD(GetProgramInfoLog) // Load the function to read the driver explanation of a program-link failure.
2042        SHDR_LOAD(DeleteProgram) // Load the function to release the GL program after its owners finish using it.
2043        SHDR_LOAD(UseProgram) // Load the function to select the compute program for the next dispatch.
2044        SHDR_LOAD(GetUniformLocation) // Load the function to find a named uniform in the linked program.
2045        SHDR_LOAD(Uniform1f) // Load the function to assign a float uniform.
2046        SHDR_LOAD(Uniform1i) // Load the function to assign an integer or boolean uniform.
2047        SHDR_LOAD(Uniform1ui) // Load the function to assign an unsigned integer uniform.
2048#define SHDR_LOAD_UNIFORM(n) /* Load the float, signed and unsigned uniform functions for this vector width. */ \
2049    SHDR_LOAD(Uniform##n##fv) /* Load the function to send this typed uniform to GL. */ \
2050    SHDR_LOAD(Uniform##n##iv) /* Load the function to send this typed uniform to GL. */ \
2051    SHDR_LOAD(Uniform##n##uiv) /* Load the function to send this typed uniform to GL. */
2052        SHDR_LOAD_UNIFORM(2) // Load the float, signed and unsigned uniform functions for this vector width.
2053        SHDR_LOAD_UNIFORM(3) // Load the float, signed and unsigned uniform functions for this vector width.
2054        SHDR_LOAD_UNIFORM(4) // Load the float, signed and unsigned uniform functions for this vector width.
2055#undef SHDR_LOAD_UNIFORM // Remove this temporary macro after its declarations are complete.
2056        SHDR_LOAD(UniformMatrix2fv) // Load the function to send this typed uniform to GL.
2057        SHDR_LOAD(UniformMatrix3fv) // Load the function to send this typed uniform to GL.
2058        SHDR_LOAD(UniformMatrix4fv) // Load the function to send this typed uniform to GL.
2059        SHDR_LOAD(UniformMatrix2x3fv) // Load the function to send this typed uniform to GL.
2060        SHDR_LOAD(UniformMatrix2x4fv) // Load the function to send this typed uniform to GL.
2061        SHDR_LOAD(UniformMatrix3x2fv) // Load the function to send this typed uniform to GL.
2062        SHDR_LOAD(UniformMatrix3x4fv) // Load the function to send this typed uniform to GL.
2063        SHDR_LOAD(UniformMatrix4x2fv) // Load the function to send this typed uniform to GL.
2064        SHDR_LOAD(UniformMatrix4x3fv) // Load the function to send this typed uniform to GL.
2065        SHDR_LOAD(GenBuffers) // Load the function to allocate names for GL storage buffers.
2066        SHDR_LOAD(DeleteBuffers) // Load the function to release owned GL buffer names.
2067        SHDR_LOAD(BindBuffer) // Load the function to select a buffer for allocation or transfer.
2068        SHDR_LOAD(BufferData) // Load the function to allocate buffer storage and supply its initial host values.
2069        SHDR_LOAD(BufferSubData) // Load the function to upload the current host buffer values.
2070        SHDR_LOAD(BindBufferBase) // Load the function to bind storage to the shader interface index.
2071        SHDR_LOAD(MapBufferRange) // Load the function to map completed GPU buffer values for a host readback.
2072        SHDR_LOAD(UnmapBuffer) // Load the function to finish reading the mapped GPU buffer.
2073        SHDR_LOAD(DispatchCompute) // Load the function to queue the shader workgroups.
2074        SHDR_LOAD(MemoryBarrier) // Load the function to make earlier resource writes visible to following GPU commands.
2075        SHDR_LOAD(Finish) // Load the function to explicitly wait until queued GPU commands complete.
2076        SHDR_LOAD(GenTextures) // Load the function to allocate names for owned GL images.
2077        SHDR_LOAD(DeleteTextures) // Load the function to release owned GL image names.
2078        SHDR_LOAD(FenceSync) // Load the function to insert a completion fence after queued compute work.
2079        SHDR_LOAD(ClientWaitSync) // Load the function to check a GPU fence with the caller-selected timeout.
2080        SHDR_LOAD(DeleteSync) // Resolve the GL completion-fence deletion entry point.
2081        SHDR_LOAD(Flush) // Resolve the GL command-flush entry point.
2082        SHDR_LOAD(BindTexture) // Load the function to select the image for allocation or upload.
2083        SHDR_LOAD(TexStorage2D) // Load the function to allocate immutable two-dimensional image storage.
2084        SHDR_LOAD(TexSubImage2D) // Load the function to upload the current host pixel values.
2085        SHDR_LOAD(BindImageTexture) // Load the function to bind a typed image to its shader interface index.
2086        SHDR_LOAD(PixelStorei) // Load the function to set or restore the application pixel-transfer layout.
2087#undef SHDR_LOAD // Remove this temporary macro after its declarations are complete.
2088    } // End this scope in gl api.
2089    void check(const std::string& operation) const { // Check for a driver error from the preceding GL operation.
2090        const unsigned code = GetError(); // Read the pending GL error code.
2091        if (code) { // Choose this branch when code.
2092            std::ostringstream s; // Build a readable diagnostic containing the operation and GL error.
2093            s << operation << ": GL error 0x" << std::hex << code; // Combine the operation name and hexadecimal driver error.
2094            throw error(s.str()); // Report the invalid operation.
2095        } // End this scope in runtime.
2096    } // End this scope in runtime.
2097}; // End this scope in runtime.
2098#undef SHDR_GL_CALL // Remove this temporary macro after its declarations are complete.
2099
2100struct device_state { // Retain GL functions, context ownership, limits, and pending cleanup.
2101    gl_api gl; // Keep the retained GL function table.
2102    profile language; // Keep the selected shader profile.
2103    unsigned max_groups[3], max_local[3], max_invocations, max_buffers, max_images; // Keep work group dimensions, invocation and resource binding limits.
2104    std::shared_ptr<void> context_keepalive; // Keep the retained headless context.
2105    std::function<void()> activate_context; // Keep the callback that makes this device context current.
2106    std::thread::id context_thread; // Keep the thread allowed to issue GL commands.
2107    std::mutex retirement_mutex; // Keep the lock for deferred resource cleanup.
2108    std::vector<std::function<void(gl_api&)>> retirements; // Keep GL deletions requested by another thread.
2109    struct deferred { // Keep the deferred values and operations together.
2110        std::function<bool(gl_api&)> poll; // Keep the zero-time completion callback.
2111        std::function<void(gl_api&)> cancel; // Keep the fence-deletion callback used at shutdown.
2112    }; // End this scope in runtime.
2113    std::vector<deferred> pending_work; // Keep discarded submissions awaiting completion.
2114    bool retirements_closed; // Keep whether device teardown has stopped retaining submissions.
2115    device_state(const std::function<void*(const char*)>& resolver, profile p) // Load GL entry points and validate the selected compute profile.
2116        : gl(resolver), language(p), context_thread(std::this_thread::get_id()), // Resolve GL functions and record this context's profile and owning thread.
2117          retirements_closed(false) { // Allow pending completion leases until the public device is destroyed.
2118        const unsigned char* version = gl.GetString(VERSION); // Read the current context version before checking the requested profile.
2119        if (!version) // Require a version string from the current context.
2120            throw error("device requires a current GL context"); // Report device requires a current gl context.
2121        const bool es = std::string(reinterpret_cast<const char*>(version)).find("OpenGL ES") != // Set whether the current context uses OpenGL ES.
2122                        std::string::npos; // Detect the GLES marker anywhere in the driver version string.
2123        const bool requested_es = p == profile::es31 || p == profile::es32; // Set whether the requested profile uses GLES.
2124        if (es != requested_es) // Choose this branch when es differs from requested es.
2125            throw error("shader profile does not match current GL/ES context"); // Report a mismatch between the selected profile and the current context.
2126        GLint major = 0, minor = 0; // Prepare both parts of the current GL version query.
2127        gl.GetIntegerv(MAJOR_VERSION, &major); // Read a scalar device limit or current binding.
2128        gl.GetIntegerv(MINOR_VERSION, &minor); // Read a scalar device limit or current binding.
2129        const int required_major = es ? 3 : 4; // Set the minimum GL major version for this profile.
2130        const int required_minor = p == profile::es31   ? 1 // Set the minimum GL minor version for this profile.
2131                                   : p == profile::es32 ? 2 // Select the version associated with this shader profile.
2132                                   : p == profile::gl43 ? 3 // Select the version associated with this shader profile.
2133                                   : p == profile::gl45 ? 5 // Select the version associated with this shader profile.
2134                                                        : 6; // Select minor version six for the desktop GL 4.6 profile.
2135        if (major < required_major || (major == required_major && minor < required_minor)) // Choose this branch when major < required major or (major equals required major and minor < required minor).
2136            throw error("current context is older than requested compute profile"); // Report current context is older than requested compute profile.
2137        for (unsigned i = 0; i < 3; ++i) { // Validate or query each of the three compute dimensions.
2138            GLint n = 0; // Set the queried GL limit or element count.
2139            gl.GetIntegeri_v(MAX_COMPUTE_WORK_GROUP_COUNT, i, &n); // Read the limit for a selected compute axis.
2140            max_groups[i] = static_cast<unsigned>(n); // Set the device workgroup-count limits.
2141            gl.GetIntegeri_v(MAX_COMPUTE_WORK_GROUP_SIZE, i, &n); // Read the limit for a selected compute axis.
2142            max_local[i] = static_cast<unsigned>(n); // Set the device local-size limits.
2143        } // End this scope in device state.
2144        GLint n = 0; // Set the queried GL limit or element count.
2145        gl.GetIntegerv(MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &n); // Read a scalar device limit or current binding.
2146        max_invocations = static_cast<unsigned>(n); // Set the maximum invocations in one workgroup.
2147        gl.GetIntegerv(MAX_SHADER_STORAGE_BUFFER_BINDINGS, &n); // Read a scalar device limit or current binding.
2148        max_buffers = static_cast<unsigned>(n); // Set the storage-buffer binding limit.
2149        gl.GetIntegerv(MAX_IMAGE_UNITS, &n); // Read a scalar device limit or current binding.
2150        max_images = static_cast<unsigned>(n); // Set the image binding limit.
2151        gl.check("query compute capabilities"); // Check for a driver error from the preceding GL operation.
2152    } // End this scope in device state.
2153    void require_thread() { // Require the device context thread and activate its headless context.
2154        if (std::this_thread::get_id() != context_thread) // Check that the operation uses the context or lifecycle thread.
2155            throw error("GL operations require the device's context thread"); // Report gl operations require the device's context thread.
2156        if (activate_context) // Choose this branch when activate context.
2157            activate_context(); // Keep the callback that makes this device context current.
2158    } // End this scope in require thread.
2159    void collect() { // Run queued deletions and zero-time completion checks.
2160        require_thread(); // Require the device context thread and activate its headless context.
2161        std::vector<std::function<void(gl_api&)>> pending; // Keep the queued work or cleanup callbacks awaiting processing.
2162        std::vector<deferred> polls, unfinished; // Keep completion polls that must be checked again.
2163        { // Begin the protected scope for this operation.
2164            std::lock_guard<std::mutex> lock(retirement_mutex); // Hold the mutex while this shared state is accessed.
2165            pending.swap(retirements); // Take the shared entries into a local collection for unlocked processing.
2166            polls.swap(pending_work); // Take the shared entries into a local collection for unlocked processing.
2167        } // End this scope in collect.
2168        for (std::size_t i = 0; i < pending.size(); ++i) // Process the cleanup or completion callbacks taken from the queue.
2169            pending[i](gl); // Keep the retained GL function table.
2170        for (std::size_t i = 0; i < polls.size(); ++i) // Process the cleanup or completion callbacks taken from the queue.
2171            if (!polls[i].poll(gl)) // Retain a completion callback while its work is pending.
2172                unfinished.push_back(std::move(polls[i])); // Retain this entry in the ordered resource or work collection.
2173        if (!unfinished.empty()) { // Keep the remaining callbacks for the next collection pass.
2174            std::lock_guard<std::mutex> lock(retirement_mutex); // Hold the mutex while this shared state is accessed.
2175            pending_work.insert(pending_work.end(), // Retain this entry in the ordered resource or work collection.
2176                                std::make_move_iterator(unfinished.begin()), // Supply the next value for the current call or declaration.
2177                                std::make_move_iterator(unfinished.end())); // Keep the end of the current range.
2178        } // End this scope in collect.
2179    } // End this scope in collect.
2180    void defer_poll(const std::function<bool(gl_api&)>& poll, // Retain a completion check until its fence signals.
2181                    const std::function<void(gl_api&)>& cancel = std::function<void(gl_api&)>()) { // Set the fence-deletion callback used at shutdown.
2182        { // Begin the protected scope for this operation.
2183            std::lock_guard<std::mutex> lock(retirement_mutex); // Hold the mutex while this shared state is accessed.
2184            if (!retirements_closed) { // Check whether teardown still allows retained completion callbacks.
2185                pending_work.push_back(deferred{poll, cancel}); // Retain this entry in the ordered resource or work collection.
2186                return; // Finish this operation.
2187            } // End this scope in defer poll.
2188        } // End this scope in defer poll.
2189 // Handles may outlive the public device wrapper. After wrapper teardown,
2190 // schedule their fence deletion directly on the context thread.
2191        if (cancel) // Choose this branch when cancel.
2192            retire(cancel); // Delete on the context thread or defer deletion to that thread.
2193    } // End this scope in defer poll.
2194    void close_retirements() { // Stop retaining new submission bundles during device teardown.
2195        { // Begin the protected scope for this operation.
2196            std::lock_guard<std::mutex> lock(retirement_mutex); // Hold the mutex while this shared state is accessed.
2197            retirements_closed = true; // Set whether device teardown has stopped retaining submissions.
2198        } // End this scope in close retirements.
2199        cancel_pending(); // Schedule deferred-fence deletion on the context thread.
2200    } // End this scope in close retirements.
2201    void cancel_pending() { // Schedule deferred-fence deletion on the context thread.
2202        require_thread(); // Require the device context thread and activate its headless context.
2203        std::vector<deferred> pending; // Keep the queued work or cleanup callbacks awaiting processing.
2204        { // Begin the protected scope for this operation.
2205            std::lock_guard<std::mutex> lock(retirement_mutex); // Hold the mutex while this shared state is accessed.
2206            pending.swap(pending_work); // Take the shared entries into a local collection for unlocked processing.
2207        } // End this scope in cancel pending.
2208        for (std::size_t i = 0; i < pending.size(); ++i) // Process the cleanup or completion callbacks taken from the queue.
2209            if (pending[i].cancel) // Check the queue state before accepting or executing work.
2210                pending[i].cancel(gl); // Keep the retained GL function table.
2211        pending.clear(); // Release the retained entries after their work or cleanup is complete.
2212        collect(); // Run queued deletions and zero-time completion checks.
2213    } // End this scope in cancel pending.
2214    void retire(const std::function<void(gl_api&)>& deletion) { // Delete on the context thread or defer deletion to that thread.
2215        if (std::this_thread::get_id() == context_thread) { // Check that the operation uses the context or lifecycle thread.
2216            require_thread(); // Require the device context thread and activate its headless context.
2217            deletion(gl); // Keep the retained GL function table.
2218        } else { // Handle the alternative resource or completion case.
2219            std::lock_guard<std::mutex> lock(retirement_mutex); // Hold the mutex while this shared state is accessed.
2220            retirements.push_back(deletion); // Retain this entry in the ordered resource or work collection.
2221        } // End this scope in retire.
2222    } // End this scope in retire.
2223    ~device_state() noexcept { // Close pending retirement leases on the context thread.
2224        if (std::this_thread::get_id() == context_thread) { // Check that the operation uses the context or lifecycle thread.
2225            try { // Keep cleanup available if an allocation, shader, or driver operation fails.
2226                close_retirements(); // Stop retaining new submission bundles during device teardown.
2227            } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
2228            } // End this scope in device state.
2229        } // End this scope in device state.
2230    } // End this scope in device state.
2231    GLuint compile(const std::string& source, const std::string& name) { // Compile and link the embedded compute source with driver diagnostics.
2232        if (source.size() > static_cast<std::size_t>((std::numeric_limits<GLint>::max)())) // Check resource size or driver limits before accessing storage.
2233            throw error("shader source too large"); // Report shader source too large.
2234        GLuint shader = gl.CreateShader(COMPUTE_SHADER), program = 0; // Allocate a compute shader object.
2235        if (!shader) // Check that the driver allocated a shader object.
2236            throw error("cannot create compute shader"); // Report compute-shader allocation failure.
2237        try { // Keep cleanup available if an allocation, shader, or driver operation fails.
2238            const char* text = source.c_str(); // Give GL a pointer to the retained shader characters.
2239            GLint len = static_cast<GLint>(source.size()); // Pass the validated shader character count to GL.
2240            gl.ShaderSource(shader, 1, &text, &len); // Supply the embedded shader text to the driver.
2241            gl.CompileShader(shader); // Ask the driver to compile the compute shader.
2242            GLint success = 0; // Prepare the compile or link status returned by GL.
2243            gl.GetShaderiv(shader, COMPILE_STATUS, &success); // Read shader compilation status or log length.
2244            if (!success) { // Read the driver diagnostic for this failed operation.
2245                GLint size = 0; // Prepare the driver diagnostic log length.
2246                gl.GetShaderiv(shader, INFO_LOG_LENGTH, &size); // Read shader compilation status or log length.
2247                std::vector<char> log(static_cast<std::size_t>((std::max)(size, 1)), 0); // Allocate enough characters for the driver diagnostic and terminator.
2248                gl.GetShaderInfoLog(shader, size, 0, log.data()); // Read the driver explanation of a shader compilation failure.
2249                throw error(name + ": shader compilation failed\n" + log.data()); // Report : shader compilation failed\n.
2250            } // End this scope in compile.
2251            program = gl.CreateProgram(); // Allocate the linked compute program.
2252            if (!program) // Check that the driver allocated a program object.
2253                throw error("cannot create compute program"); // Report compute-program allocation failure.
2254            gl.AttachShader(program, shader); // Attach the compute shader before linking.
2255            gl.LinkProgram(program); // Link the compiled compute program.
2256            gl.GetProgramiv(program, LINK_STATUS, &success); // Read linked-program status, log length, or local dimensions.
2257            if (!success) { // Read the driver diagnostic for this failed operation.
2258                GLint size = 0; // Prepare the driver diagnostic log length.
2259                gl.GetProgramiv(program, INFO_LOG_LENGTH, &size); // Read linked-program status, log length, or local dimensions.
2260                std::vector<char> log(static_cast<std::size_t>((std::max)(size, 1)), 0); // Allocate enough characters for the driver diagnostic and terminator.
2261                gl.GetProgramInfoLog(program, size, 0, log.data()); // Read the driver explanation of a program-link failure.
2262                throw error(name + ": program link failed\n" + log.data()); // Report : program link failed\n.
2263            } // End this scope in compile.
2264            gl.DeleteShader(shader); // Release the temporary shader object.
2265            shader = 0; // Set the shader used by this dispatch.
2266            gl.check("link " + name); // Keep the resource or entry-point name.
2267            return program; // Compile and link the embedded compute source with driver diagnostics.
2268        } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
2269            if (shader) // Choose this branch when shader.
2270                gl.DeleteShader(shader); // Release the temporary shader object.
2271            if (program) // Choose this branch when program.
2272                gl.DeleteProgram(program); // Release the GL program after its owners finish using it.
2273            throw; // Rethrow the original failure after arranging the necessary cleanup.
2274        } // End this scope in compile.
2275    } // End this scope in compile.
2276}; // End this scope in runtime.
2277struct program_state { // Keep the program state values and operations together.
2278    std::shared_ptr<device_state> owner; // Keep the device that owns the GL resource.
2279    GLuint id; // Keep the compiled GL program name.
2280    program_state(const std::shared_ptr<device_state>& d, GLuint id_) : owner(d), id(id_) { // Expose the retained compiled program for asynchronous ownership.
2281    } // End this scope in program state.
2282    ~program_state() { // Release this object's owned resources at teardown.
2283        if (id) { // Choose this branch when id.
2284            const GLuint name = id; // Set the resource or entry-point name.
2285            owner->retire([name](gl_api& gl) { // Delete on the context thread or defer deletion to that thread.
2286                gl.DeleteProgram(name); // Release the GL program after its owners finish using it.
2287            }); // End this scope in program state.
2288        } // End this scope in program state.
2289    } // End this scope in program state.
2290}; // End this scope in runtime.
2291
2292inline std::size_t checked_product(std::size_t a, std::size_t b) { // Reject resource-size multiplication that would overflow.
2293    if (b && a > (std::numeric_limits<std::size_t>::max)() / b) // Check resource size or driver limits before accessing storage.
2294        throw error("resource size overflow"); // Report resource size overflow.
2295    return a * b; // Reject resource-size multiplication that would overflow.
2296} // End this scope in checked product.
2297inline GLsizeiptr gl_size(std::size_t size) { // Require a byte count representable by the GL buffer API.
2298    if (size > static_cast<std::size_t>((std::numeric_limits<GLsizeiptr>::max)())) // Check resource size or driver limits before accessing storage.
2299        throw error("resource exceeds GLsizeiptr"); // Report resource exceeds glsizeiptr.
2300    return static_cast<GLsizeiptr>(size); // Require a byte count representable by the GL buffer API.
2301} // End this scope in gl size.
2302enum class authority { host, gpu, both }; // Name the profile, access, or completion values accepted by this section.
2303enum class resource_kind { buffer, image }; // Name the profile, access, or completion values accepted by this section.
2304struct resource_state { // Track shared storage and which backend has the newest values.
2305    resource_kind kind; // Keep the buffer, image, or uniform interface kind.
2306    authority latest; // Keep which copy contains the latest resource values.
2307    std::shared_ptr<device_state> owner; // Keep the device that owns the GL resource.
2308    GLuint handle; // Keep the GL buffer or texture name.
2309    bool borrowed; // Keep whether the application owns the supplied GL object.
2310    unsigned width, height, components, format, scalar; // Keep the GL scalar representation.
2311    resource_state(resource_kind k) // Initialize ownership and synchronization for one resource.
2312        : kind(k), latest(authority::host), handle(0), borrowed(false), width(0), height(0), // Start with authoritative host data and allocate GL storage on demand.
2313          components(0), format(0), scalar(0) { // Initialize image layout metadata to zero.
2314    } // End this scope in resource state.
2315    virtual ~resource_state() { // Release this object's owned resources at teardown.
2316        if (handle && !borrowed) { // Delete the resource when its GL handle is owned by this object.
2317            const GLuint name = handle; // Set the resource or entry-point name.
2318            if (kind == resource_kind::buffer) // Choose the branch matching this interface or resource access.
2319                owner->retire([name](gl_api& gl) { // Delete on the context thread or defer deletion to that thread.
2320                    gl.DeleteBuffers(1, &name); // Release owned GL buffer names.
2321                }); // End this scope in resource state.
2322            else // Handle the other resource, platform, or completion case.
2323                owner->retire([name](gl_api& gl) { // Delete on the context thread or defer deletion to that thread.
2324                    gl.DeleteTextures(1, &name); // Release owned GL image names.
2325                }); // End this scope in resource state.
2326        } // End this scope in resource state.
2327    } // End this scope in resource state.
2328    virtual void* host_pointer() = 0; // Require each resource type to expose its host storage.
2329    virtual std::size_t bytes() const = 0; // Require each resource type to report its byte count.
2330    void ensure_host(); // Download newer GPU values only when host access needs them.
2331    void ensure_gpu(const std::shared_ptr<device_state>& d) { // Allocate or upload GPU storage when its host copy is newer.
2332        d->collect(); // Run queued deletions and zero-time completion checks.
2333        if (owner && owner != d) // Check that this storage belongs to the requested device.
2334            throw error("resource belongs to a different device"); // Report resource belongs to a different device.
2335        owner = d; // Set the device that owns the GL resource.
2336        const gl_api& gl = d->gl; // Set the retained GL function table.
2337        if (!handle) { // Allocate GPU storage on the first device access.
2338            if (kind == resource_kind::buffer) { // Choose the branch matching this interface or resource access.
2339                gl.GenBuffers(1, &handle); // Allocate names for GL storage buffers.
2340                gl.BindBuffer(SHADER_STORAGE_BUFFER, handle); // Select a buffer for allocation or transfer.
2341                gl.BufferData(SHADER_STORAGE_BUFFER, // Allocate buffer storage and supply its initial host values.
2342                              gl_size(bytes()), // Require a byte count representable by the GL buffer API.
2343                              bytes() ? host_pointer() : 0, // Supply the next value for the current call or declaration.
2344                              DYNAMIC_DRAW); // Require a byte count representable by the GL buffer API.
2345            } else { // Handle the alternative resource or completion case.
2346                gl.GenTextures(1, &handle); // Allocate names for owned GL images.
2347                gl.BindTexture(TEXTURE_2D, handle); // Select the image for allocation or upload.
2348                gl.TexStorage2D(TEXTURE_2D, // Allocate immutable two-dimensional image storage.
2349                                1, // Supply the next value for the current call or declaration.
2350                                format, // Visit the values or interfaces needed by ensure gpu.
2351                                static_cast<GLsizei>(width), // Keep the image width in pixels.
2352                                static_cast<GLsizei>(height)); // Keep the image height in pixels.
2353            } // End this scope in ensure gpu.
2354            gl.check("allocate compute resource"); // Check for a driver error from the preceding GL operation.
2355            if (kind == resource_kind::buffer) // Choose the branch matching this interface or resource access.
2356                latest = authority::both; // Record which backend now owns the newest resource values.
2357        } // End this scope in ensure gpu.
2358        if (latest == authority::host) { // Check which resource copy must be synchronized.
2359            if (kind == resource_kind::buffer) { // Choose the branch matching this interface or resource access.
2360                gl.BindBuffer(SHADER_STORAGE_BUFFER, handle); // Select a buffer for allocation or transfer.
2361                if (bytes()) // Check resource size or driver limits before accessing storage.
2362                    gl.BufferSubData(SHADER_STORAGE_BUFFER, 0, gl_size(bytes()), host_pointer()); // Upload the current host buffer values.
2363            } else { // Handle the alternative resource or completion case.
2364 // Make upload independent of caller pixel unpack state and restore that state.
2365                GLint alignment = 0, row = 0, skip_rows = 0, skip_pixels = 0, pbo = 0; // Save the complete pixel-unpack layout and bound transfer buffer.
2366                gl.GetIntegerv(UNPACK_ALIGNMENT, &alignment); // Read a scalar device limit or current binding.
2367                gl.GetIntegerv(UNPACK_ROW_LENGTH, &row); // Read a scalar device limit or current binding.
2368                gl.GetIntegerv(UNPACK_SKIP_ROWS, &skip_rows); // Read a scalar device limit or current binding.
2369                gl.GetIntegerv(UNPACK_SKIP_PIXELS, &skip_pixels); // Read a scalar device limit or current binding.
2370                gl.GetIntegerv(0x88EF, &pbo); // GL_PIXEL_UNPACK_BUFFER_BINDING
2371                gl.BindBuffer(PIXEL_UNPACK_BUFFER, 0); // Select a buffer for allocation or transfer.
2372                gl.PixelStorei(UNPACK_ALIGNMENT, 1); // Set or restore the application pixel-transfer layout.
2373                gl.PixelStorei(UNPACK_ROW_LENGTH, 0); // Set or restore the application pixel-transfer layout.
2374                gl.PixelStorei(UNPACK_SKIP_ROWS, 0); // Set or restore the application pixel-transfer layout.
2375                gl.PixelStorei(UNPACK_SKIP_PIXELS, 0); // Set or restore the application pixel-transfer layout.
2376                gl.BindTexture(TEXTURE_2D, handle); // Select the image for allocation or upload.
2377                const GLenum channels = scalar == FLOAT // Choose the float or integer pixel-transfer channel representation.
2378                                            ? (components == 1 ? RED : RGBA) // Set the number of scalar values per pixel.
2379                                            : (components == 1 ? RED_INTEGER : RGBA_INTEGER); // Choose the upload pixel format matching integer channels.
2380                gl.TexSubImage2D(TEXTURE_2D, // Upload the current host pixel values.
2381                                 0, // Supply the next value for the current call or declaration.
2382                                 0, // Supply the next value for the current call or declaration.
2383                                 0, // Supply the next value for the current call or declaration.
2384                                 static_cast<GLsizei>(width), // Keep the image width in pixels.
2385                                 static_cast<GLsizei>(height), // Keep the image height in pixels.
2386                                 channels, // Supply the next value for the current call or declaration.
2387                                 scalar, // Keep the GL scalar representation.
2388                                 host_pointer()); // Expose this resource's borrowed or owned host storage.
2389                gl.PixelStorei(UNPACK_ALIGNMENT, alignment); // Set or restore the application pixel-transfer layout.
2390                gl.PixelStorei(UNPACK_ROW_LENGTH, row); // Set or restore the application pixel-transfer layout.
2391                gl.PixelStorei(UNPACK_SKIP_ROWS, skip_rows); // Set or restore the application pixel-transfer layout.
2392                gl.PixelStorei(UNPACK_SKIP_PIXELS, skip_pixels); // Set or restore the application pixel-transfer layout.
2393                gl.BindBuffer(PIXEL_UNPACK_BUFFER, static_cast<GLuint>(pbo)); // Select a buffer for allocation or transfer.
2394            } // End this scope in ensure gpu.
2395            gl.check("upload compute resource"); // Check for a driver error from the preceding GL operation.
2396            latest = authority::both; // Record which backend now owns the newest resource values.
2397        } // End this scope in ensure gpu.
2398    } // End this scope in ensure gpu.
2399}; // End this scope in runtime.
2400
2401 // Image readback uses a compute copy on both desktop GL and GLES.
2402inline void resource_state::ensure_host() { // Download newer GPU values only when host access needs them.
2403    if (latest != authority::gpu) // Check which resource copy must be synchronized.
2404        return; // Finish this operation.
2405    owner->collect(); // Run queued deletions and zero-time completion checks.
2406    const gl_api& gl = owner->gl; // Set the retained GL function table.
2407    if (!bytes()) { // Check resource size or driver limits before accessing storage.
2408        latest = authority::both; // Record which backend now owns the newest resource values.
2409        return; // Finish this operation.
2410    } // End this scope in ensure host.
2411    GLuint staging = 0, program = 0; // Track the temporary readback buffer and copy program for cleanup.
2412    try { // Keep cleanup available if an allocation, shader, or driver operation fails.
2413        gl.MemoryBarrier(ALL_BARRIER_BITS); // Make earlier resource writes visible to following GPU commands.
2414        if (kind == resource_kind::buffer) // Choose the branch matching this interface or resource access.
2415            gl.BindBuffer(SHADER_STORAGE_BUFFER, handle); // Select a buffer for allocation or transfer.
2416        else { // Handle the other resource, platform, or completion case.
2417            const char* scalar_name = scalar == FLOAT ? "float" : scalar == INT ? "int" : "uint"; // Choose the GLSL scalar spelling matching these image pixels.
2418            const char* vector_name = scalar == FLOAT ? "vec4" : scalar == INT ? "ivec4" : "uvec4"; // Choose the four-component GLSL value used by imageLoad.
2419            const char* image_name = scalar == FLOAT ? "image2D" // Choose the matching float, signed or unsigned storage-image type.
2420                                     : scalar == INT ? "iimage2D" // Choose the shader image type matching the resource's scalar representation.
2421                                                     : "uimage2D"; // Choose the shader image type matching the resource's scalar representation.
2422            const char* format_name = components == 1 ? (scalar == FLOAT ? "r32f" // Choose the declared storage-image format for the copy shader.
2423                                                         : scalar == INT ? "r32i" // Choose the shader format matching scalar type and channel count.
2424                                                                         : "r32ui") // Choose the shader format matching scalar type and channel count.
2425                                                      : (scalar == FLOAT ? "rgba32f" // Choose the shader format matching scalar type and channel count.
2426                                                         : scalar == INT ? "rgba32i" // Choose the shader format matching scalar type and channel count.
2427                                                                         : "rgba32ui"); // Choose the shader format matching scalar type and channel count.
2428            std::ostringstream body; // Download newer GPU values only when host access needs them.
2429            body << "SHDR_BEGIN(shdr_readback,8,8,1)\nSHDR_IMAGE2D(0," << format_name << ',' // Download newer GPU values only when host access needs them.
2430                 << image_name << ",src,readonly)\n" // Download newer GPU values only when host access needs them.
2431                 << "SHDR_BUFFER(0," << scalar_name // Download newer GPU values only when host access needs them.
2432                 << ",dst,writeonly)\nSHDR_MAIN(){uvec2 p=gl_GlobalInvocationID.xy;" // Download newer GPU values only when host access needs them.
2433                 << "ivec2 s=imageSize(src);if(p.x>=uint(s.x)||p.y>=uint(s.y))return;" // Download newer GPU values only when host access needs them.
2434                 << vector_name << " v=imageLoad(src,ivec2(p));uint i=(p.y*uint(s.x)+p.x)*" // Download newer GPU values only when host access needs them.
2435                 << components << "u;"; // Download newer GPU values only when host access needs them.
2436            for (unsigned c = 0; c < components; ++c) // Visit the values or interfaces needed by ensure host.
2437                body << "dst[i+" << c << "u]=v[" << c << "];"; // Download newer GPU values only when host access needs them.
2438            body << "} SHDR_END()\n"; // Download newer GPU values only when host access needs them.
2439            program = owner->compile(glsl_source(body.str(), owner->language), "image readback"); // Compile the portable image-to-buffer readback shader.
2440            gl.GenBuffers(1, &staging); // Allocate names for GL storage buffers.
2441            gl.BindBuffer(SHADER_STORAGE_BUFFER, staging); // Select a buffer for allocation or transfer.
2442            gl.BufferData(SHADER_STORAGE_BUFFER, gl_size(bytes()), 0, DYNAMIC_DRAW); // Allocate buffer storage and supply its initial host values.
2443            gl.UseProgram(program); // Select the compute program for the next dispatch.
2444            gl.BindBufferBase(SHADER_STORAGE_BUFFER, 0, staging); // Bind storage to the shader interface index.
2445            gl.BindImageTexture(0, handle, 0, 0, 0, READ_ONLY, format); // Bind a typed image to its shader interface index.
2446            gl.DispatchCompute((width + 7) / 8, (height + 7) / 8, 1); // Queue the shader workgroups.
2447            gl.MemoryBarrier(ALL_BARRIER_BITS); // Make earlier resource writes visible to following GPU commands.
2448            gl.check("copy image to host staging buffer"); // Check for a driver error from the preceding GL operation.
2449            gl.BindBuffer(SHADER_STORAGE_BUFFER, staging); // Select a buffer for allocation or transfer.
2450        } // End this scope in ensure host.
2451        void* mapped = gl.MapBufferRange(SHADER_STORAGE_BUFFER, 0, gl_size(bytes()), MAP_READ_BIT); // Map completed GPU buffer values for a host readback.
2452        if (!mapped) { // Check that GL returned a readable mapped range.
2453            gl.check("map compute readback"); // Check for a driver error from the preceding GL operation.
2454            throw error("cannot map compute readback"); // Report readback mapping failure.
2455        } // End this scope in ensure host.
2456        std::memcpy(host_pointer(), mapped, bytes()); // Copy the representation with the alias-safe byte-copy operation.
2457        if (!gl.UnmapBuffer(SHADER_STORAGE_BUFFER)) // Finish reading the mapped GPU buffer.
2458            throw error("compute readback buffer contents corrupted"); // Report compute readback buffer contents corrupted.
2459        gl.check("read back compute resource"); // Check for a driver error from the preceding GL operation.
2460        latest = authority::both; // Record which backend now owns the newest resource values.
2461        if (staging) // Choose this branch when staging.
2462            gl.DeleteBuffers(1, &staging); // Release owned GL buffer names.
2463        if (program) // Choose this branch when program.
2464            gl.DeleteProgram(program); // Release the GL program after its owners finish using it.
2465    } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
2466        if (staging) // Choose this branch when staging.
2467            gl.DeleteBuffers(1, &staging); // Release owned GL buffer names.
2468        if (program) // Choose this branch when program.
2469            gl.DeleteProgram(program); // Release the GL program after its owners finish using it.
2470        throw; // Rethrow the original failure after arranging the necessary cleanup.
2471    } // End this scope in ensure host.
2472} // End this scope in ensure host.
2473
2474 // Only layouts identical to std430 arrays are accepted. vec3, bool and arbitrary structs need explicit packing.
2475template <class T> // Select the scalar, dimension, or access type at compile time.
2476struct storage_type // Keep the storage type values and operations together.
2477    : std::integral_constant<bool, // Expose the following storage-layout checks as a compile-time boolean.
2478                             std::is_same<T, float>::value || std::is_same<T, int>::value || // Accept the supported 32-bit float and signed integer storage types.
2479                                 std::is_same<T, unsigned>::value> {}; // Also accept the supported 32-bit unsigned storage type.
2480template <class T, std::size_t N> // Select the scalar, dimension, or access type at compile time.
2481struct storage_type<glsl::vec<T, N>> // Keep the storage type values and operations together.
2482    : std::integral_constant<bool, // Expose the following storage-layout checks as a compile-time boolean.
2483                             storage_type<T>::value && (N == 2 || N == 4) && // Require a supported scalar and a two- or four-component vector.
2484                                 sizeof(glsl::vec<T, N>) == sizeof(T) * N> {}; // Require a tightly packed vector that matches its std430 array stride.
2485template <class T> struct buffer_state : resource_state { // Select the scalar, dimension, or access type at compile time.
2486    std::vector<T> owned; // Keep host storage allocated by this resource.
2487    T* external; // Point to application-owned host memory.
2488    std::size_t count; // Keep the element or configuration count.
2489    explicit buffer_state(std::size_t n) // Allocate owned host storage for this number of elements.
2490        : resource_state(resource_kind::buffer), owned(n), external(0), count(n) { // Initialize ownership and synchronization for one resource.
2491    } // End this scope in runtime.
2492    buffer_state(T* p, std::size_t n) // Retain a reference to an application-owned host range.
2493        : resource_state(resource_kind::buffer), external(p), count(n) { // Initialize ownership and synchronization for one resource.
2494        if (!p && n) // Require a valid pointer for a nonempty borrowed range.
2495            throw error("null borrowed CPU buffer"); // Report null borrowed cpu buffer.
2496    } // End this scope in runtime.
2497    void* host_pointer() override { // Expose this resource's borrowed or owned host storage.
2498        return external ? external : owned.data(); // Use borrowed host memory when present and owned memory otherwise.
2499    } // End this scope in runtime.
2500    std::size_t bytes() const override { // Report this resource's byte count with overflow checking.
2501        return checked_product(count, sizeof(T)); // Calculate the byte count with checked size arithmetic.
2502    } // End this scope in runtime.
2503}; // End this scope in runtime.
2504template <class T> struct image_state : resource_state { // Select the scalar, dimension, or access type at compile time.
2505    std::vector<T> owned; // Keep host storage allocated by this resource.
2506    image_state(unsigned w, unsigned h, unsigned c) : resource_state(resource_kind::image) { // Initialize ownership and synchronization for one resource.
2507        if (!w || !h || w > static_cast<unsigned>((std::numeric_limits<GLsizei>::max)()) || // Check resource size or driver limits before accessing storage.
2508            h > static_cast<unsigned>((std::numeric_limits<GLsizei>::max)())) // Require the image height to fit the GL signed dimension type.
2509            throw error("image dimensions must be positive GLsizei values"); // Report image dimensions must be positive glsizei values.
2510        width = w; // Set the image width in pixels.
2511        height = h; // Set the image height in pixels.
2512        components = c; // Set the number of scalar values per pixel.
2513        scalar = std::is_same<T, float>::value ? FLOAT // Set the GL scalar representation.
2514                 : std::is_same<T, int>::value ? INT // Choose the GL scalar type matching the host pixel representation.
2515                                               : UNSIGNED_INT; // Choose the GL scalar type matching the host pixel representation.
2516        format = c == 1 ? (scalar == FLOAT ? R32F // Visit the values or interfaces needed by runtime.
2517                           : scalar == INT ? R32I // Choose the GL internal image format matching scalar type and channel count.
2518                                           : R32UI) // Choose the GL internal image format matching scalar type and channel count.
2519                        : (scalar == FLOAT ? RGBA32F // Choose the GL internal image format matching scalar type and channel count.
2520                           : scalar == INT ? RGBA32I // Choose the GL internal image format matching scalar type and channel count.
2521                                           : RGBA32UI); // Choose the GL internal image format matching scalar type and channel count.
2522        owned.resize(checked_product(checked_product(w, h), c)); // Reject resource-size multiplication that would overflow.
2523    } // End this scope in runtime.
2524    void* host_pointer() override { // Expose this resource's borrowed or owned host storage.
2525        return owned.data(); // Expose the contiguous host storage owned by this resource.
2526    } // End this scope in runtime.
2527    std::size_t bytes() const override { // Report this resource's byte count with overflow checking.
2528        return checked_product(owned.size(), sizeof(T)); // Calculate the byte count with checked size arithmetic.
2529    } // End this scope in runtime.
2530}; // End this scope in runtime.
2531} // namespace detail
2532
2533/** @brief An application's current GL context, accessed through its function resolver.
2534 * The context must remain current on this thread during operations and destruction of GL objects.
2535 * The default header uses standard C++11 declarations. The optional
2536 * headless_device supplies EGL context creation when SHDR_ENABLE_EGL is enabled.
2537 */
2538class device { // Keep the device values and operations together.
2539    std::shared_ptr<detail::device_state> state_; // Keep the state shared by this wrapper and its retained owners.
2540
2541  public: // Expose the operations callers can use.
2542    /** @brief Load GL entry points and validate the current context against a profile.
2543     * @param resolver Callable returning the address of a named GL function, or null.
2544     * @param p Minimum GLSL and GL/ES profile. defaults to ES 3.1.
2545     * @throws error If function resolution or current-context validation fails.
2546     */
2547    explicit device(const std::function<void*(const char*)>& resolver, profile p = profile::es31) // Create a compute device using the caller's current context and function resolver.
2548        : state_(std::make_shared<detail::device_state>(resolver, p)) { // Retain the resolved GL functions, profile and device limits.
2549    } // End this scope in device.
2550    /** @brief Release deferred completion handles through context-thread cleanup.
2551     * Destroy devices on their context thread after CPU workers have stopped.
2552     */
2553    virtual ~device() noexcept { // Close pending retirement leases on the context thread.
2554        if (std::this_thread::get_id() == state_->context_thread) { // Check that the operation uses the context or lifecycle thread.
2555            try { // Keep cleanup available if an allocation, shader, or driver operation fails.
2556                state_->close_retirements(); // Stop retaining new submission bundles during device teardown.
2557            } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
2558            } // End this scope in device.
2559        } // End this scope in device.
2560    } // End this scope in device.
2561    device(const device&) = delete; // Prevent copying this object and duplicating its retained identity.
2562    device& operator=(const device&) = delete; // Prevent copying this object and duplicating its retained identity.
2563    /** @brief Return the shader language profile selected for this device. */
2564    profile shader_profile() const { // Return the device profile used to generate shader source.
2565        return state_->language; // Return the device profile used to generate shader source.
2566    } // End this scope in shader profile.
2567    /** @brief Wait for submitted GPU work to complete, including for accurate wall-clock benchmarks. */
2568    void synchronize() { // Explicitly wait for completed GPU commands.
2569        state_->collect(); // Run queued deletions and zero-time completion checks.
2570        state_->gl.Finish(); // Explicitly wait until queued GPU commands complete.
2571        state_->gl.check("wait for GPU completion"); // Check for a driver error from the preceding GL operation.
2572    } // End this scope in synchronize.
2573    /** @brief Delete GL objects retired by CPU workers and poll pending completions. */
2574    void collect_garbage() { // Collect deferred GL deletions and poll completion fences.
2575        state_->collect(); // Run queued deletions and zero-time completion checks.
2576    } // End this scope in collect garbage.
2577    /** @brief Current GL renderer name, for diagnostics and reproducible benchmark reports. */
2578    std::string renderer() const { // Read the current renderer name for reproducible diagnostics.
2579        state_->require_thread(); // Require the device context thread and activate its headless context.
2580        const unsigned char* s = state_->gl.GetString(0x1F01); // Read the driver version or renderer text.
2581        if (!s) // Validate the renderer query from the current context.
2582            throw error("no current GL context"); // Report that the renderer query requires a current GL context.
2583        return reinterpret_cast<const char*>(s); // Read the current renderer name for reproducible diagnostics.
2584    } // End this scope in renderer.
2585    /** @internal Runtime access to the retained GL function table and device limits. */
2586    const std::shared_ptr<detail::device_state>& state() const { // Expose retained runtime state to the resource and backend helpers.
2587        return state_; // Return the storage or execution state retained by this wrapper.
2588    } // End this scope in state.
2589}; // End this scope in runtime.
2590
2591/** @brief Shared typed std430 storage, owned or borrowed, with automatic CPU/GPU synchronization.
2592 * Copying a buffer shares its storage. Mutable data() marks host data authoritative.
2593 * Obtain a fresh data() pointer after a GPU dispatch before accessing host values.
2594 * GPU handles belong to one device.
2595 */
2596template <class T> class buffer { // Select the scalar, dimension, or access type at compile time.
2597    static_assert(detail::storage_type<T>::value, // Require a representation that matches the shader interface.
2598                  "buffer requires float/int/uint or matching vec2/vec4 std430 layout"); // Explain which element types match the supported storage-buffer layout.
2599    static_assert(sizeof(float) == 4 && sizeof(int) == 4 && sizeof(unsigned) == 4, // Require a representation that matches the shader interface.
2600                  "shdr requires 32-bit GLSL scalars"); // Require the host scalar representation to match GLSL storage.
2601    std::shared_ptr<detail::buffer_state<T>> state_; // Keep the state shared by this wrapper and its retained owners.
2602
2603  public: // Expose the operations callers can use.
2604    /** @brief Allocate a zero-initialized host buffer containing n elements.
2605     * GPU storage is allocated lazily. Zero-length buffers are valid on the CPU.
2606     * GPU storage-buffer bindings require at least one element.
2607     */
2608    explicit buffer(std::size_t n = 0) : state_(std::make_shared<detail::buffer_state<T>>(n)) { // Create a typed buffer with owned host storage.
2609        if (n > static_cast<std::size_t>((std::numeric_limits<unsigned>::max)())) // Check resource size or driver limits before accessing storage.
2610            throw error("buffer length exceeds GLSL uint"); // Report buffer length exceeds glsl uint.
2611        detail::gl_size(state_->bytes()); // Require a byte count representable by the GL buffer API.
2612    } // End this scope in buffer.
2613    /** @brief Borrow n elements stored in application-owned host memory.
2614     * Keep the memory alive while any resource copy or shader port retains it.
2615     * Call mark_host_modified() after writing through the original pointer.
2616     */
2617    buffer(T* p, std::size_t n) : state_(std::make_shared<detail::buffer_state<T>>(p, n)) { // Initialize the typed resource storage and validate its size.
2618        if (n > static_cast<std::size_t>((std::numeric_limits<unsigned>::max)())) // Check resource size or driver limits before accessing storage.
2619            throw error("buffer length exceeds GLSL uint"); // Report buffer length exceeds glsl uint.
2620        detail::gl_size(state_->bytes()); // Require a byte count representable by the GL buffer API.
2621    } // End this scope in buffer.
2622    /** @brief Allocate owned host storage and copy an initializer list into it. */
2623    buffer(std::initializer_list<T> values) : buffer(values.size()) { // Initialize the typed resource storage and validate its size.
2624        std::copy(values.begin(), values.end(), data()); // Access host values after bringing their resource copy up to date.
2625    } // End this scope in buffer.
2626    /** @brief Return the stored element count. */
2627    std::size_t size() const { // Read the stored element or stage count.
2628        return state_->count; // Return the result of this check or operation.
2629    } // End this scope in runtime.
2630    /** @brief Synchronize newer GPU contents and return mutable host elements.
2631     * Marks host data modified. Reacquire this pointer after GPU work before using it.
2632     */
2633    T* data() { // Access host values after bringing their resource copy up to date.
2634        state_->ensure_host(); // Download newer GPU values only when host access needs them.
2635        state_->latest = detail::authority::host; // Record which backend now owns the newest resource values.
2636        return static_cast<T*>(state_->host_pointer()); // Access host values after bringing their resource copy up to date.
2637    } // End this scope in data.
2638    /** @brief Synchronize newer GPU contents and return readonly host elements. */
2639    const T* data() const { // Access host values after bringing their resource copy up to date.
2640        state_->ensure_host(); // Download newer GPU values only when host access needs them.
2641        return static_cast<const T*>(state_->host_pointer()); // Access host values after bringing their resource copy up to date.
2642    } // End this scope in data.
2643    /** @brief Access one host element after synchronization. reject an out-of-range index. */
2644    T& operator[](std::size_t i) { // Bounds-check this host element before returning its typed reference.
2645        if (i >= size()) // Check resource size or driver limits before accessing storage.
2646            throw error("host buffer index out of range"); // Report host buffer index out of range.
2647        return data()[i]; // Return the result of this check or operation.
2648    } // End this scope in runtime.
2649    /** @brief Read one host element after synchronization. reject an out-of-range index. */
2650    const T& operator[](std::size_t i) const { // Bounds-check this host element before returning its typed reference.
2651        if (i >= size()) // Check resource size or driver limits before accessing storage.
2652            throw error("host buffer index out of range"); // Report host buffer index out of range.
2653        return data()[i]; // Return the result of this check or operation.
2654    } // End this scope in runtime.
2655    /** @brief Ensure this device has the latest contents, allocating or uploading as needed. */
2656    void upload(device& d) { // Explicitly make current host values available to the GPU.
2657        state_->ensure_gpu(d.state()); // Allocate or upload GPU storage when its host copy is newer.
2658    } // End this scope in upload.
2659    /** @brief Download newer GPU contents. reject a different owning device. */
2660    void download(device& d) { // Explicitly bring newer GPU values back to host storage.
2661        if (state_->owner && state_->owner != d.state()) // Check that this storage belongs to the requested device.
2662            throw error("resource belongs to a different device"); // Report resource belongs to a different device.
2663        state_->ensure_host(); // Download newer GPU values only when host access needs them.
2664    } // End this scope in download.
2665    /** @brief Obtain the synchronized GL SSBO handle for application interop. */
2666    unsigned gl_handle(device& d) { // Expose a synchronized GL resource handle for interoperation.
2667        upload(d); // Explicitly make current host values available to the GPU.
2668        return state_->handle; // Expose a synchronized GL resource handle for interoperation.
2669    } // End this scope in gl handle.
2670    /** @brief Notify shdr after the application writes the GL buffer. its context must be current. */
2671    void mark_gpu_modified(device& d) { // Record a write performed by application GL commands.
2672        if (state_->owner != d.state() || !state_->handle) // Check that this storage belongs to the requested device.
2673            throw error("resource has no handle on this device"); // Report a mismatch between the resource handle and the device.
2674        state_->latest = detail::authority::gpu; // Record which backend now owns the newest resource values.
2675    } // End this scope in mark gpu modified.
2676    /** @brief Notify shdr after changing previously obtained or borrowed host memory.
2677     * Call data() before editing if GPU data must first be preserved.
2678     */
2679    void mark_host_modified() { // Record a write through retained or borrowed host memory.
2680        state_->latest = detail::authority::host; // Record which backend now owns the newest resource values.
2681    } // End this scope in mark host modified.
2682    /** @brief Borrow an existing SSBO. Its contents initially belong to the GPU. caller retains ownership. */
2683    static buffer from_gl(device& d, unsigned handle, std::size_t count) { // Borrow an application-owned GL object.
2684        if (!handle) // Validate the resource handle before using it.
2685            throw error("cannot borrow GL buffer zero"); // Require a nonzero GL buffer handle.
2686        buffer result(count); // Keep the element or configuration count.
2687        result.state_->owner = d.state(); // Set the device that owns the GL resource.
2688        result.state_->handle = handle; // Set the GL buffer or texture name.
2689        result.state_->borrowed = true; // Set whether the application owns the supplied GL object.
2690        result.state_->latest = detail::authority::gpu; // Record which backend now owns the newest resource values.
2691        return result; // Return the value returned by this operation.
2692    } // End this scope in from gl.
2693    /** @internal Runtime access to shared resource storage and synchronization state. */
2694    const std::shared_ptr<detail::buffer_state<T>>& state() const { // Expose retained runtime state to the resource and backend helpers.
2695        return state_; // Return the storage or execution state retained by this wrapper.
2696    } // End this scope in state.
2697}; // End this scope in runtime.
2698
2699/** @brief Interleaved 32-bit scalar or RGBA image shared between CPU and GPU.
2700 * C is 1 or 4. T is float, int, or unsigned. Use matching r32f/r32i/r32ui or
2701 * rgba32f/rgba32i/rgba32ui GLSL declarations. Copies and bound ports alias storage.
2702 */
2703template <class T, unsigned C = 1> class image2d { // Select the scalar, dimension, or access type at compile time.
2704    static_assert(detail::storage_type<T>::value && std::is_arithmetic<T>::value, // Require a representation that matches the shader interface.
2705                  "image requires float/int/uint"); // Require an image scalar type supported by the runtime.
2706    static_assert(C == 1 || C == 4, "portable image formats have one or four components"); // Require a representation that matches the shader interface.
2707    std::shared_ptr<detail::image_state<T>> state_; // Keep the state shared by this wrapper and its retained owners.
2708
2709  public: // Expose the operations callers can use.
2710    /** @brief Allocate a zero-initialized image with positive width and height in pixels. */
2711    image2d(unsigned w, unsigned h) : state_(std::make_shared<detail::image_state<T>>(w, h, C)) { // Initialize the image geometry and typed pixel storage.
2712    } // End this scope in image2d.
2713    /** @brief Return the stored number of pixels in each row. */
2714    unsigned width() const { // Return the image width in pixels.
2715        return state_->width; // Return the result of this check or operation.
2716    } // End this scope in runtime.
2717    /** @brief Return the stored number of pixel rows. */
2718    unsigned height() const { // Return the image height in pixels.
2719        return state_->height; // Return the result of this check or operation.
2720    } // End this scope in runtime.
2721    /** @brief Synchronize newer GPU contents and return mutable interleaved host pixels.
2722     * Index component c at (x,y) as data()[(y*width()+x)*C+c]. Marks host data
2723     * modified. reacquire the pointer after GPU work before using it.
2724     */
2725    T* data() { // Access host values after bringing their resource copy up to date.
2726        state_->ensure_host(); // Download newer GPU values only when host access needs them.
2727        state_->latest = detail::authority::host; // Record which backend now owns the newest resource values.
2728        return static_cast<T*>(state_->host_pointer()); // Access host values after bringing their resource copy up to date.
2729    } // End this scope in data.
2730    /** @brief Synchronize newer GPU contents and return readonly interleaved host pixels. */
2731    const T* data() const { // Access host values after bringing their resource copy up to date.
2732        state_->ensure_host(); // Download newer GPU values only when host access needs them.
2733        return static_cast<const T*>(state_->host_pointer()); // Access host values after bringing their resource copy up to date.
2734    } // End this scope in data.
2735    /** @brief Ensure this device has the latest pixels, allocating or uploading as needed. */
2736    void upload(device& d) { // Explicitly make current host values available to the GPU.
2737        state_->ensure_gpu(d.state()); // Allocate or upload GPU storage when its host copy is newer.
2738    } // End this scope in upload.
2739    /** @brief Download newer GPU pixels through a portable compute-to-buffer copy. */
2740    void download(device& d) { // Explicitly bring newer GPU values back to host storage.
2741        if (state_->owner && state_->owner != d.state()) // Check that this storage belongs to the requested device.
2742            throw error("resource belongs to a different device"); // Report resource belongs to a different device.
2743        state_->ensure_host(); // Download newer GPU values only when host access needs them.
2744    } // End this scope in download.
2745    /** @brief Obtain the synchronized level-zero GL texture handle for application interop. */
2746    unsigned gl_handle(device& d) { // Expose a synchronized GL resource handle for interoperation.
2747        upload(d); // Explicitly make current host values available to the GPU.
2748        return state_->handle; // Expose a synchronized GL resource handle for interoperation.
2749    } // End this scope in gl handle.
2750    /** @brief Notify shdr after the application writes the GL texture. its context must be current. */
2751    void mark_gpu_modified(device& d) { // Record a write performed by application GL commands.
2752        if (state_->owner != d.state() || !state_->handle) // Check that this storage belongs to the requested device.
2753            throw error("resource has no handle on this device"); // Report a mismatch between the resource handle and the device.
2754        state_->latest = detail::authority::gpu; // Record which backend now owns the newest resource values.
2755    } // End this scope in mark gpu modified.
2756    /** @brief Notify shdr after changing a retained host pixel pointer. */
2757    void mark_host_modified() { // Record a write through retained or borrowed host memory.
2758        state_->latest = detail::authority::host; // Record which backend now owns the newest resource values.
2759    } // End this scope in mark host modified.
2760    /** @brief Borrow a matching immutable-format, level-zero 2D GL texture. caller retains ownership. */
2761    static image2d from_gl(device& d, unsigned handle, unsigned w, unsigned h) { // Borrow an application-owned GL object.
2762        if (!handle) // Validate the resource handle before using it.
2763            throw error("cannot borrow GL texture zero"); // Require a nonzero GL texture handle.
2764        image2d result(w, h); // Allocate host pixel storage before attaching the borrowed texture.
2765        result.state_->owner = d.state(); // Set the device that owns the GL resource.
2766        result.state_->handle = handle; // Set the GL buffer or texture name.
2767        result.state_->borrowed = true; // Set whether the application owns the supplied GL object.
2768        result.state_->latest = detail::authority::gpu; // Record which backend now owns the newest resource values.
2769        return result; // Return the value returned by this operation.
2770    } // End this scope in from gl.
2771    /** @internal Runtime access to shared image storage and synchronization state. */
2772    const std::shared_ptr<detail::image_state<T>>& state() const { // Expose retained runtime state to the resource and backend helpers.
2773        return state_; // Return the storage or execution state retained by this wrapper.
2774    } // End this scope in state.
2775}; // End this scope in runtime.
2776
2777class kernel; // Keep the kernel values and operations together.
2778namespace detail { // Group these definitions in the detail namespace.
2779enum class port_kind { buffer, image, uniform }; // Name the profile, access, or completion values accepted by this section.
2780struct port_base { // Keep the port base values and operations together.
2781    kernel& parent; // Keep the shader instance that owns this interface.
2782    std::string name; // Keep the resource or entry-point name.
2783    unsigned binding; // Keep the numeric shader resource binding.
2784    access mode; // Keep the declared shader resource access.
2785    port_kind kind; // Keep the buffer, image, or uniform interface kind.
2786    port_base(kernel&, const char*, unsigned, access, port_kind); // Register the named interface with its owning shader.
2787    virtual ~port_base() { // Allow typed interfaces to be destroyed through this base interface.
2788    } // End this scope in runtime.
2789    virtual std::shared_ptr<resource_state> resource() const { // Expose the retained storage used by this port.
2790        return std::shared_ptr<resource_state>(); // Represent a uniform-only interface with an empty resource reference.
2791    } // End this scope in runtime.
2792    virtual void bind_gpu(device_state&, GLuint) { // Bind this interface or assign its uniform before dispatch.
2793    } // End this scope in bind gpu.
2794    virtual void validate() const { // Check that this resource binding satisfies the shader declaration.
2795    } // End this scope in validate.
2796    virtual void copy_to(port_base&) const { // Copy the typed port into a matching snapshot interface.
2797        throw error("shader port does not support snapshots"); // Report that this port requires snapshot support.
2798    } // End this scope in copy to.
2799}; // End this scope in runtime.
2800} // namespace detail
2801
2802/** @brief Base for compiled shader objects, owning resource declarations and invocation builtins.
2803 * Shader objects are neither copyable nor movable because their ports refer to their instance.
2804 * CMake-generated adapters embed their native GLSL source automatically.
2805 */
2806class kernel { // Keep the kernel values and operations together.
2807    std::string name_, source_; // Keep the diagnostic shader name and its embedded GLSL text.
2808    extent local_; // Keep the fixed workgroup dimensions.
2809    std::vector<detail::port_base*> ports_; // Keep the registered resource and uniform interfaces.
2810    std::shared_ptr<detail::program_state> program_; // Keep the retained compiled compute program.
2811
2812  protected: // Allow derived kernels to initialize their embedded source.
2813 // Generated shader constructors install their build-embedded GLSL through this method.
2814    void set_embedded_source(const char* text) { // Retain the build-generated GLSL text inside the shader.
2815        source_ = text; // Set the automatically embedded shader text.
2816    } // End this scope in runtime.
2817
2818  public: // Expose the operations callers can use.
2819    glsl::uvec3 gl_GlobalInvocationID, gl_LocalInvocationID, gl_WorkGroupID, gl_NumWorkGroups, // Keep CPU global, local, group and dispatch coordinates for GLSL builtins.
2820        gl_WorkGroupSize; // Keep the fixed local dimensions exposed to CPU shader code.
2821    unsigned gl_LocalInvocationIndex; // Keep the flattened index within the current CPU work group.
2822    /** @brief Construct a kernel identity and positive local workgroup dimensions.
2823     * SHDR_BEGIN emits this constructor for shared shader classes.
2824     */
2825    kernel(const std::string& name, extent local) // Initialize the shader name, local dimensions, and invocation values.
2826        : name_(name), local_(local), gl_LocalInvocationIndex(0) { // Remember the shader name and local size with initially zero CPU invocation state.
2827        if (!local.x || !local.y || !local.z) // Require positive local dimensions on every axis.
2828            throw error("local work group dimensions must be positive"); // Report local work group dimensions must be positive.
2829        gl_WorkGroupSize = glsl::uvec3(local.x, local.y, local.z); // Publish the fixed local dimensions to CPU shader builtins.
2830    } // End this scope in kernel.
2831    virtual ~kernel() { // Allow derived shader instances to be destroyed through the base interface.
2832    } // End this scope in kernel.
2833    kernel(const kernel&) = delete; // Prevent copying this object and duplicating its retained identity.
2834    kernel& operator=(const kernel&) = delete; // Prevent copying this object and duplicating its retained identity.
2835    /** @brief Execute one CPU invocation. SHDR_MAIN supplies the override.
2836     * Dispatch through a stage or pipeline to initialize builtins and synchronize resources.
2837     */
2838    virtual void main() = 0; // Require a compiled shader to supply its CPU invocation method.
2839    /** @brief Make an independent shader instance with a snapshot of its resource bindings and uniforms. */
2840    virtual std::unique_ptr<kernel> clone() const { // Create an independent shader instance for deferred CPU execution.
2841        throw error("shader does not support snapshots"); // Report that this shader requires snapshot support.
2842    } // End this scope in runtime.
2843    /** @internal Copy registered interfaces into a newly constructed instance. */
2844    void copy_interfaces(kernel& destination) const { // Copy resource bindings and uniforms into a fresh shader clone.
2845        if (ports_.size() != destination.ports_.size()) // Check resource size or driver limits before accessing storage.
2846            throw error("shader snapshot interface mismatch"); // Report shader snapshot interface mismatch.
2847        for (std::size_t i = 0; i < ports_.size(); ++i) // Visit every registered resource and uniform interface.
2848            ports_[i]->copy_to(*destination.ports_[i]); // Copy the typed port into a matching snapshot interface.
2849    } // End this scope in copy interfaces.
2850    /** @internal Retain all resources used by an enqueued dispatch. */
2851    std::vector<std::shared_ptr<detail::resource_state>> resources() const { // Collect the shared storage used by this shader.
2852        std::vector<std::shared_ptr<detail::resource_state>> result; // Keep the value returned by this operation.
2853        for (std::size_t i = 0; i < ports_.size(); ++i) { // Visit every registered resource and uniform interface.
2854            auto r = ports_[i]->resource(); // Get the shared storage behind this resource interface.
2855            if (r) // Choose this branch when r.
2856                result.push_back(r); // Retain this entry in the ordered resource or work collection.
2857        } // End this scope in resources.
2858        return result; // Return the value returned by this operation.
2859    } // End this scope in resources.
2860    /** @internal Retain a compiled program during asynchronous execution. */
2861    const std::shared_ptr<detail::program_state>& program_state() const { // Expose the retained compiled program for asynchronous ownership.
2862        return program_; // Return the retained compiled compute program.
2863    } // End this scope in program state.
2864    /** @brief Return the kernel's diagnostic name. */
2865    const std::string& name() const { // Return the diagnostic shader name.
2866        return name_; // Return the kernel or registration name.
2867    } // End this scope in runtime.
2868    /** @brief Return the fixed local workgroup dimensions declared by SHDR_BEGIN. */
2869    extent local_size() const { // Return the fixed local work group dimensions.
2870        return local_; // Return the fixed workgroup dimensions.
2871    } // End this scope in runtime.
2872    /** @brief Export this shader's automatically embedded source for compiler diagnostics or tooling. */
2873    std::string glsl(profile p) const { // Export the embedded shader for the requested language profile.
2874        if (source_.empty()) // Choose this branch when source .empty().
2875            throw error("shader has no embedded GPU source: " + name_); // Report that this shader requires an embedded GPU program.
2876        return glsl_source(source_, p); // Return the result of this check or operation.
2877    } // End this scope in runtime.
2878    /** @internal Register declarations emitted by the shared shader macros. */
2879    void register_port(detail::port_base& port) { // Register one named resource or uniform with duplicate checks.
2880        for (std::size_t i = 0; i < ports_.size(); ++i) { // Visit every registered resource and uniform interface.
2881            if (ports_[i]->name == port.name) // Choose this branch when ports [i]->name equals port.name.
2882                throw error("duplicate shader port: " + port.name); // Report duplicate shader port: .
2883            if (port.kind != detail::port_kind::uniform && ports_[i]->kind == port.kind && // Choose the branch matching this interface or resource access.
2884                ports_[i]->binding == port.binding) // Set the numeric shader resource binding.
2885                throw error("duplicate shader resource binding: " + port.name); // Report duplicate shader resource binding: .
2886        } // End this scope in register port.
2887        ports_.push_back(&port); // Retain this entry in the ordered resource or work collection.
2888    } // End this scope in register port.
2889    /** @brief Bind by name, for runtime-selected shader modules. Type mismatches throw error. */
2890    template <class T> kernel& bind(const std::string& name, const buffer<T>& resource); // Select the scalar, dimension, or access type at compile time.
2891    /** @brief Bind an image by name. scalar type and component count must match its port. */
2892    template <class T, unsigned C> // Select the scalar, dimension, or access type at compile time.
2893    kernel& bind(const std::string& name, const image2d<T, C>& resource); // Rebind a named resource port while preserving its declared type.
2894    /** @brief Assign a uniform by name. T must exactly match its declared shader type. */
2895    template <class T> kernel& set(const std::string& name, const T& value); // Select the scalar, dimension, or access type at compile time.
2896    /** @internal Find a registered port for runtime binding and uniform assignment. */
2897    detail::port_base& find_port(const std::string& name) { // Resolve the named shader interface.
2898        for (std::size_t i = 0; i < ports_.size(); ++i) // Visit every registered resource and uniform interface.
2899            if (ports_[i]->name == name) // Choose this branch when ports [i]->name equals name.
2900                return *ports_[i]; // Resolve the named shader interface.
2901        throw error("unknown shader port: " + name); // Report unknown shader port: .
2902    } // End this scope in find port.
2903    /** @brief Execute one dispatch with workgroup counts on a device, or on the CPU if null.
2904     * Normally called by pipeline.run(). GPU work uses the embedded shader and a current context.
2905     */
2906    void run(extent groups, device* d); // Keep the target device.
2907    /** @brief Compile and allocate GPU resources before entering a latency-sensitive dispatch loop. */
2908    void prepare(device& d); // Compile the program and prepare its bound GPU resources.
2909}; // End this scope in runtime.
2910
2911namespace detail { // Group these definitions in the detail namespace.
2912inline port_base::port_base(kernel& p, const char* n, unsigned b, access a, port_kind k) // Register the named interface with its owning shader.
2913    : parent(p), name(n), binding(b), mode(a), kind(k) { // Record the owning kernel, interface name, binding, access and resource kind.
2914    parent.register_port(*this); // Register one named resource or uniform with duplicate checks.
2915} // End this scope in runtime.
2916} // namespace detail
2917
2918/** @brief Typed shader SSBO declaration. assign a buffer to bind or rebind it. */
2919template <class T, access A = access::readwrite> class buffer_port : public detail::port_base { // Select the scalar, dimension, or access type at compile time.
2920    std::shared_ptr<detail::buffer_state<T>> state_; // Keep the state shared by this wrapper and its retained owners.
2921    unsigned fixed_length_; // Keep the fixed array length declared by the shader.
2922
2923  public: // Expose the operations callers can use.
2924    /** @brief Declare a typed buffer port on a kernel, usually through SHDR_BUFFER. */
2925    buffer_port(kernel& p, unsigned b, const char* n, unsigned fixed = 0) // Register a typed buffer interface and any fixed shader array length.
2926        : port_base(p, n, b, A, detail::port_kind::buffer), fixed_length_(fixed) { // Record the buffer interface and its optional fixed shader length.
2927    } // End this scope in runtime.
2928    /** @brief Bind or rebind this port to the buffer's retained shared storage. */
2929    buffer_port& operator=(const buffer<T>& b) { // Retain the newly bound typed resource in this shader interface.
2930        state_ = b.state(); // Set the state shared by this wrapper and its retained owners.
2931        return *this; // Allow another operation to follow in the same expression.
2932    } // End this scope in runtime.
2933    void copy_to(detail::port_base& destination) const override { // Copy the typed port into a matching snapshot interface.
2934        buffer_port* p = dynamic_cast<buffer_port*>(&destination); // Require a snapshot port with the same buffer type and access qualifier.
2935        if (!p) // Validate the typed interface pointer before accessing it.
2936            throw error("buffer snapshot type mismatch: " + name); // Report buffer snapshot type mismatch: .
2937        p->state_ = state_; // Set the state shared by this wrapper and its retained owners.
2938    } // End this scope in copy to.
2939    /** @brief Return the bound buffer's element count, matching GLSL array length(). */
2940    unsigned length() const { // Return the GLSL-visible array length after validating its binding.
2941        validate(); // Check that this resource binding satisfies the shader declaration.
2942        return fixed_length_ ? fixed_length_ : static_cast<unsigned>(state_->count); // Return the GLSL-visible array length after validating its binding.
2943    } // End this scope in length.
2944    /** @brief Access an element during CPU execution, checking bounds and declared access.
2945     * Readonly ports return const references. Pipeline execution synchronizes host contents.
2946     */
2947    typename std::conditional<A == access::readonly, const T&, T&>::type operator[](std::size_t i) { // Expose a const component for readonly ports and a mutable one otherwise.
2948        validate(); // Check that this resource binding satisfies the shader declaration.
2949        const std::size_t limit = fixed_length_ ? fixed_length_ : state_->count; // Use the declared array size or the full bound buffer length.
2950        if (i >= limit) // Choose this branch when i >= limit.
2951            throw error("CPU SSBO index out of bounds: " + name); // Report cpu ssbo index out of bounds: .
2952        return static_cast<T*>(state_->host_pointer())[i]; // Return the result of this check or operation.
2953    } // End this scope in runtime.
2954    void validate() const override { // Check that this resource binding satisfies the shader declaration.
2955        if (!state_) // Require retained storage for this interface.
2956            throw error("unbound shader buffer: " + name); // Report unbound shader buffer: .
2957        if (fixed_length_ && state_->count < fixed_length_) // Check resource size or driver limits before accessing storage.
2958            throw error("buffer is smaller than the shader's fixed array: " + name); // Report buffer is smaller than the shader's fixed array: .
2959    } // End this scope in validate.
2960    std::shared_ptr<detail::resource_state> resource() const override { // Expose the retained storage used by this port.
2961        return state_; // Return the storage or execution state retained by this wrapper.
2962    } // End this scope in runtime.
2963    void bind_gpu(detail::device_state& d, unsigned) override { // Bind this interface or assign its uniform before dispatch.
2964        if (binding >= d.max_buffers) // Choose this branch when binding >= d.max buffers.
2965            throw error("SSBO binding exceeds device limit: " + name); // Report ssbo binding exceeds device limit: .
2966        if (!state_->bytes()) // Check resource size or driver limits before accessing storage.
2967            throw error("GPU SSBO bindings require a nonempty buffer: " + name); // Report gpu ssbo bindings require a nonempty buffer: .
2968        d.gl.BindBufferBase(detail::SHADER_STORAGE_BUFFER, binding, state_->handle); // Bind storage to the shader interface index.
2969    } // End this scope in bind gpu.
2970}; // End this scope in runtime.
2971
2972namespace detail { // Group these definitions in the detail namespace.
2973inline void uniform_value(gl_api& gl, GLint loc, float v) { // Send the typed uniform value through its matching GL call.
2974    gl.Uniform1f(loc, v); // Assign a float uniform.
2975} // End this scope in uniform value.
2976inline void uniform_value(gl_api& gl, GLint loc, int v) { // Send the typed uniform value through its matching GL call.
2977    gl.Uniform1i(loc, v); // Assign an integer or boolean uniform.
2978} // End this scope in uniform value.
2979inline void uniform_value(gl_api& gl, GLint loc, unsigned v) { // Send the typed uniform value through its matching GL call.
2980    gl.Uniform1ui(loc, v); // Assign an unsigned integer uniform.
2981} // End this scope in uniform value.
2982inline void uniform_value(gl_api& gl, GLint loc, bool v) { // Send the typed uniform value through its matching GL call.
2983    gl.Uniform1i(loc, v ? 1 : 0); // Assign an integer or boolean uniform.
2984} // End this scope in uniform value.
2985#define SHDR_UNIFORM_VEC(n, t, suffix) /* Define the SHDR_UNIFORM_VEC helper for this group of declarations. */ \
2986    inline void uniform_value(gl_api& gl, GLint loc, const glsl::vec<t, n>& v) { /* Send the typed uniform value through its matching GL call. */ \
2987        t packed[n]; /* Pack the vector components contiguously for the GL uniform call. */ \
2988        for (unsigned i = 0; i < n; ++i) /* Visit the values or interfaces needed by uniform value. */ \
2989            packed[i] = v[i]; /* Copy the component into the contiguous GL uniform payload. */ \
2990        gl.Uniform##n##suffix(loc, 1, packed); /* Send the packed vector components through their matching GL function. */ \
2991    } /* End this scope in uniform value. */
2992SHDR_UNIFORM_VEC(2, float, fv) // Define the listed float, signed or unsigned vector uniform overloads.
2993SHDR_UNIFORM_VEC(3, float, fv) SHDR_UNIFORM_VEC(4, float, fv) SHDR_UNIFORM_VEC(2, int, iv) // Define the listed float, signed or unsigned vector uniform overloads.
2994    SHDR_UNIFORM_VEC(3, int, iv) SHDR_UNIFORM_VEC(4, int, iv) SHDR_UNIFORM_VEC(2, unsigned, uiv) // Define the listed float, signed or unsigned vector uniform overloads.
2995        SHDR_UNIFORM_VEC(3, unsigned, uiv) SHDR_UNIFORM_VEC(4, unsigned, uiv) // Define the listed float, signed or unsigned vector uniform overloads.
2996#undef SHDR_UNIFORM_VEC // Remove this temporary macro after its declarations are complete.
2997            template <std::size_t N> // Select the scalar, dimension, or access type at compile time.
2998            inline void uniform_value(gl_api& gl, GLint loc, const glsl::vec<bool, N>& v) { // Send the typed uniform value through its matching GL call.
2999    GLint packed[N]; // Pack boolean components as the integer values expected by GL.
3000    for (unsigned i = 0; i < N; ++i) // Visit the values or interfaces needed by uniform value.
3001        packed[i] = v[i] ? 1 : 0; // Represent a boolean uniform component as a GL integer.
3002    if (N == 2) // Choose this branch when N equals 2.
3003        gl.Uniform2iv(loc, 1, packed); // Send two integer-represented boolean components to GL.
3004    else if (N == 3) // Choose this branch when N equals 3.
3005        gl.Uniform3iv(loc, 1, packed); // Send three integer-represented boolean components to GL.
3006    else // Handle the other resource, platform, or completion case.
3007        gl.Uniform4iv(loc, 1, packed); // Send four integer-represented boolean components to GL.
3008} // End this scope in uniform value.
3009#define SHDR_UNIFORM_MATRIX(c, r, n) /* Define the SHDR_UNIFORM_MATRIX helper for this group of declarations. */ \
3010    inline void uniform_value(gl_api& gl, GLint loc, const glsl::mat<float, c, r>& m) { /* Send the typed uniform value through its matching GL call. */ \
3011        float packed[c * r]; /* Send the typed uniform value through its matching GL call. */ \
3012        for (unsigned i = 0; i < c; ++i) /* Visit the values or interfaces needed by uniform value. */ \
3013            for (unsigned j = 0; j < r; ++j) /* Visit the values or interfaces needed by uniform value. */ \
3014                packed[i * r + j] = m[i][j]; /* Flatten the matrix in GLSL column order. */ \
3015        gl.UniformMatrix##n##fv(loc, 1, 0, packed); /* Upload the column-major matrix with the transpose flag set to false. */ \
3016    } /* End this scope in uniform value. */
3017SHDR_UNIFORM_MATRIX(2, 2, 2) // Define the listed column-major matrix uniform overloads.
3018SHDR_UNIFORM_MATRIX(3, 3, 3) SHDR_UNIFORM_MATRIX(4, 4, 4) SHDR_UNIFORM_MATRIX(2, 3, 2x3) // Define the listed column-major matrix uniform overloads.
3019    SHDR_UNIFORM_MATRIX(2, 4, 2x4) SHDR_UNIFORM_MATRIX(3, 2, 3x2) SHDR_UNIFORM_MATRIX(3, 4, 3x4) // Define the listed column-major matrix uniform overloads.
3020        SHDR_UNIFORM_MATRIX(4, 2, 4x2) SHDR_UNIFORM_MATRIX(4, 3, 4x3) // Define the listed column-major matrix uniform overloads.
3021#undef SHDR_UNIFORM_MATRIX // Remove this temporary macro after its declarations are complete.
3022} // namespace detail
3023
3024/** @brief A zero-initialized typed shader uniform, assigned with ordinary C++ syntax. */
3025template <class T> class uniform_port : public detail::port_base { // Select the scalar, dimension, or access type at compile time.
3026    T owned_; // Keep the uniform value stored by the port.
3027    T* value_; // Keep the current uniform field.
3028
3029  public: // Expose the operations callers can use.
3030    /** @brief Declare a zero-initialized uniform backed by this port's own value. */
3031    uniform_port(kernel& p, const char* n) // Register a typed uniform backed by this port's own zero-initialized value.
3032        : port_base(p, n, 0, access::readonly, detail::port_kind::uniform), owned_(), // Keep the uniform value stored by the port.
3033          value_(&owned_) { // Keep the uniform value stored by the port.
3034    } // End this scope in runtime.
3035    /** @brief Register an existing typed kernel field as a uniform. emitted by SHDR_UNIFORM. */
3036    uniform_port(kernel& p, const char* n, T& value) // Register a uniform and refer to its shader member value.
3037        : port_base(p, n, 0, access::readonly, detail::port_kind::uniform), owned_(), // Keep the uniform value stored by the port.
3038          value_(&value) { // Refer to the uniform member owned by this shader instance.
3039    } // End this scope in runtime.
3040    /** @brief Set the uniform value uploaded at the next dispatch. */
3041    uniform_port& operator=(const T& value) { // Assign the shader member referred to by this uniform interface.
3042        *value_ = value; // Set the current uniform field.
3043        return *this; // Allow another operation to follow in the same expression.
3044    } // End this scope in runtime.
3045    /** @brief Read the uniform as its declared shader type during CPU execution. */
3046    operator T() const { // Read the uniform member as an ordinary value of its declared type.
3047        return *value_; // Return the result of this check or operation.
3048    } // End this scope in runtime.
3049    /** @brief Return the stored uniform value. */
3050    const T& value() const { // Read the shader member referred to by this uniform port.
3051        return *value_; // Return the result of this check or operation.
3052    } // End this scope in runtime.
3053    void copy_to(detail::port_base& destination) const override { // Copy the typed port into a matching snapshot interface.
3054        uniform_port* p = dynamic_cast<uniform_port*>(&destination); // Require a snapshot port with the same uniform type.
3055        if (!p) // Validate the typed interface pointer before accessing it.
3056            throw error("uniform snapshot type mismatch: " + name); // Report uniform snapshot type mismatch: .
3057        *p->value_ = *value_; // Set the current uniform field.
3058    } // End this scope in copy to.
3059    void bind_gpu(detail::device_state& d, unsigned program) override { // Bind this interface or assign its uniform before dispatch.
3060        const int loc = d.gl.GetUniformLocation(program, name.c_str()); // Find a named uniform in the linked program.
3061        if (loc >= 0) // Choose this branch when loc >= 0.
3062            detail::uniform_value(d.gl, loc, *value_); // Send the typed uniform value through its matching GL call.
3063    } // End this scope in bind gpu.
3064}; // End this scope in runtime.
3065
3066/** @brief A typed image declaration with format/access matching its shared shader. */
3067template <class T, unsigned C, access A> class image_port : public detail::port_base { // Select the scalar, dimension, or access type at compile time.
3068    std::shared_ptr<detail::image_state<T>> state_; // Keep the state shared by this wrapper and its retained owners.
3069
3070  public: // Expose the operations callers can use.
3071    /** @brief Declare an image port, usually through SHDR_IMAGE2D. */
3072    image_port(kernel& p, unsigned b, const char* n) // Register a typed image interface at the specified binding.
3073        : port_base(p, n, b, A, detail::port_kind::image) { // Record the image interface and its declared access qualifier.
3074    } // End this scope in runtime.
3075    /** @brief Bind or rebind this port to the image's retained shared storage. */
3076    image_port& operator=(const image2d<T, C>& image) { // Retain the newly bound typed resource in this shader interface.
3077        state_ = image.state(); // Set the state shared by this wrapper and its retained owners.
3078        return *this; // Allow another operation to follow in the same expression.
3079    } // End this scope in runtime.
3080    void copy_to(detail::port_base& destination) const override { // Copy the typed port into a matching snapshot interface.
3081        image_port* p = dynamic_cast<image_port*>(&destination); // Require a snapshot port with the same image type and access qualifier.
3082        if (!p) // Validate the typed interface pointer before accessing it.
3083            throw error("image snapshot type mismatch: " + name); // Report image snapshot type mismatch: .
3084        p->state_ = state_; // Set the state shared by this wrapper and its retained owners.
3085    } // End this scope in copy to.
3086    void validate() const override { // Check that this resource binding satisfies the shader declaration.
3087        if (!state_) // Require retained storage for this interface.
3088            throw error("unbound shader image: " + name); // Report unbound shader image: .
3089    } // End this scope in validate.
3090    std::shared_ptr<detail::resource_state> resource() const override { // Expose the retained storage used by this port.
3091        return state_; // Return the storage or execution state retained by this wrapper.
3092    } // End this scope in runtime.
3093    /** @internal Read image state for the CPU imageLoad/imageStore/imageSize helpers. */
3094    const std::shared_ptr<detail::image_state<T>>& image_state() const { // Expose the validated image storage to CPU image helpers.
3095        validate(); // Check that this resource binding satisfies the shader declaration.
3096        return state_; // Return the storage or execution state retained by this wrapper.
3097    } // End this scope in runtime.
3098    void bind_gpu(detail::device_state& d, unsigned) override { // Bind this interface or assign its uniform before dispatch.
3099        if (binding >= d.max_images) // Choose this branch when binding >= d.max images.
3100            throw error("image binding exceeds device limit: " + name); // Report image binding exceeds device limit: .
3101        d.gl.BindImageTexture(binding, // Bind a typed image to its shader interface index.
3102                              state_->handle, // Keep the GL buffer or texture name.
3103                              0, // Supply the next value for the current call or declaration.
3104                              0, // Supply the next value for the current call or declaration.
3105                              0, // Supply the next value for the current call or declaration.
3106                              A == access::readonly    ? detail::READ_ONLY // Select the GL read or write qualifier matching this typed image port.
3107                              : A == access::writeonly ? detail::WRITE_ONLY // Choose the GL image access matching the shader qualifier.
3108                                                       : detail::READ_WRITE, // Choose the GL image access matching the shader qualifier.
3109                              state_->format); // Keep the image storage format.
3110    } // End this scope in bind gpu.
3111}; // End this scope in runtime.
3112
3113/** @brief GLSL image dimensions in pixels. */
3114template <class T, unsigned C, access A> // Select the scalar, dimension, or access type at compile time.
3115inline glsl::ivec2 imageSize(const image_port<T, C, A>& image) { // Return the bound image dimensions as GLSL integers.
3116    return glsl::ivec2(image.image_state()->width, image.image_state()->height); // Return the bound image dimensions as GLSL integers.
3117} // End this scope in imageSize.
3118/** @brief Load one texel. Missing RGB components are zero and missing alpha is one.
3119 * Out-of-range coordinates return zero. loading a writeonly image is a compile error.
3120 */
3121template <class T, unsigned C, access A> // Select the scalar, dimension, or access type at compile time.
3122inline glsl::vec<T, 4> imageLoad(const image_port<T, C, A>& image, glsl::ivec2 pos) { // Load one pixel while enforcing readonly access and image bounds.
3123    static_assert(A != access::writeonly, "cannot imageLoad a writeonly image"); // Require a representation that matches the shader interface.
3124    const std::shared_ptr<detail::image_state<T>>& s = image.image_state(); // Access the retained image geometry and host pixel storage.
3125    if (pos.x < 0 || pos.y < 0 || static_cast<unsigned>(pos.x) >= s->width || // Choose this branch when pos.x < 0 or pos.y < 0 or static cast<unsigned>(pos.x) >= s->width or .
3126        static_cast<unsigned>(pos.y) >= s->height) // Reject an image row outside the allocated pixel storage.
3127        return glsl::vec<T, 4>(T(0)); // Load one pixel while enforcing readonly access and image bounds.
3128    glsl::vec<T, 4> result(T(0)); // Start the loaded texel with zero components before filling its channels.
3129    result[3] = T(1); // Set the value returned by this operation.
3130    const std::size_t start = // Set the beginning of the current token or range.
3131        (static_cast<std::size_t>(pos.y) * s->width + static_cast<unsigned>(pos.x)) * C; // Load one pixel while enforcing readonly access and image bounds.
3132    for (unsigned c = 0; c < C; ++c) // Visit the values or interfaces needed by imageLoad.
3133        result[c] = s->owned[start + c]; // Set the value returned by this operation.
3134    return result; // Return the value returned by this operation.
3135} // End this scope in imageLoad.
3136/** @brief Store a texel, ignoring out-of-range coordinates. Readonly stores are a compile error. */
3137template <class T, unsigned C, access A> // Select the scalar, dimension, or access type at compile time.
3138inline void imageStore(image_port<T, C, A>& image, glsl::ivec2 pos, const glsl::vec<T, 4>& value) { // Store one pixel while enforcing writable access and image bounds.
3139    static_assert(A != access::readonly, "cannot imageStore a readonly image"); // Require a representation that matches the shader interface.
3140    const std::shared_ptr<detail::image_state<T>>& s = image.image_state(); // Access the retained image geometry and host pixel storage.
3141    if (pos.x < 0 || pos.y < 0 || static_cast<unsigned>(pos.x) >= s->width || // Choose this branch when pos.x < 0 or pos.y < 0 or static cast<unsigned>(pos.x) >= s->width or .
3142        static_cast<unsigned>(pos.y) >= s->height) // Reject an image row outside the allocated pixel storage.
3143        return; // Finish this operation.
3144    const std::size_t start = // Set the beginning of the current token or range.
3145        (static_cast<std::size_t>(pos.y) * s->width + static_cast<unsigned>(pos.x)) * C; // Store one pixel while enforcing writable access and image bounds.
3146    for (unsigned c = 0; c < C; ++c) // Visit the values or interfaces needed by imageStore.
3147        s->owned[start + c] = value[c]; // Set host storage allocated by this resource.
3148} // End this scope in imageStore.
3149
3150template <class T> inline kernel& kernel::bind(const std::string& name, const buffer<T>& b) { // Select the scalar, dimension, or access type at compile time.
3151    detail::port_base& p = find_port(name); // Find the declared shader interface with this resource name.
3152    if (buffer_port<T, access::readonly>* v = dynamic_cast<buffer_port<T, access::readonly>*>(&p)) // Choose this branch when buffer port<T, access::readonly>* v = dynamic cast<buffer port<T, access::readonly>*>(&p).
3153        *v = b; // Store the current v value for this operation.
3154    else if (buffer_port<T, access::writeonly>* v = // Choose this branch when buffer port<T, access::writeonly>* v =.
3155                 dynamic_cast<buffer_port<T, access::writeonly>*>(&p)) // Try the matching typed write-only buffer interface.
3156        *v = b; // Store the current v value for this operation.
3157    else if (buffer_port<T, access::readwrite>* v = // Choose this branch when buffer port<T, access::readwrite>* v =.
3158                 dynamic_cast<buffer_port<T, access::readwrite>*>(&p)) // Try the matching typed read-write buffer interface.
3159        *v = b; // Store the current v value for this operation.
3160    else // Handle the other resource, platform, or completion case.
3161        throw error("buffer type mismatch: " + name); // Report buffer type mismatch: .
3162    return *this; // Allow another operation to follow in the same expression.
3163} // End this scope in runtime.
3164template <class T, unsigned C> // Select the scalar, dimension, or access type at compile time.
3165inline kernel& kernel::bind(const std::string& name, const image2d<T, C>& b) { // Rebind a named resource port while preserving its declared type.
3166    detail::port_base& p = find_port(name); // Find the declared shader interface with this resource name.
3167    if (image_port<T, C, access::readonly>* v = // Choose this branch when image port<T, C, access::readonly>* v =.
3168            dynamic_cast<image_port<T, C, access::readonly>*>(&p)) // Try the matching typed read-only image interface.
3169        *v = b; // Store the current v value for this operation.
3170    else if (image_port<T, C, access::writeonly>* v = // Choose this branch when image port<T, C, access::writeonly>* v =.
3171                 dynamic_cast<image_port<T, C, access::writeonly>*>(&p)) // Try the matching typed write-only image interface.
3172        *v = b; // Store the current v value for this operation.
3173    else if (image_port<T, C, access::readwrite>* v = // Choose this branch when image port<T, C, access::readwrite>* v =.
3174                 dynamic_cast<image_port<T, C, access::readwrite>*>(&p)) // Try the matching typed read-write image interface.
3175        *v = b; // Store the current v value for this operation.
3176    else // Handle the other resource, platform, or completion case.
3177        throw error("image type mismatch: " + name); // Report image type mismatch: .
3178    return *this; // Allow another operation to follow in the same expression.
3179} // End this scope in runtime.
3180template <class T> inline kernel& kernel::set(const std::string& name, const T& value) { // Select the scalar, dimension, or access type at compile time.
3181    uniform_port<T>* p = dynamic_cast<uniform_port<T>*>(&find_port(name)); // Require the named uniform to have the supplied value's type.
3182    if (!p) // Validate the typed interface pointer before accessing it.
3183        throw error("uniform type mismatch: " + name); // Report uniform type mismatch: .
3184    *p = value; // Update the typed uniform value for subsequent dispatches.
3185    return *this; // Allow another operation to follow in the same expression.
3186} // End this scope in runtime.
3187
3188inline void kernel::prepare(device& d) { // Compile the program and prepare its bound GPU resources.
3189    const auto& state = d.state(); // Set the shared device or worker state.
3190    state->collect(); // Run queued deletions and zero-time completion checks.
3191    for (std::size_t i = 0; i < ports_.size(); ++i) // Visit every registered resource and uniform interface.
3192        ports_[i]->validate(); // Check that this resource binding satisfies the shader declaration.
3193    if (!program_) { // Compile the shader when its cached program is empty.
3194        if (source_.empty()) // Choose this branch when source .empty().
3195            throw error("shader has no embedded GPU source: " + name_); // Report that this shader requires an embedded GPU program.
3196        program_ = std::make_shared<detail::program_state>( // Set the retained compiled compute program.
3197            state, state->compile(glsl_source(source_, state->language), name_)); // Add the selected GLSL version and shared-declaration definitions.
3198        detail::GLint actual[3] = {0, 0, 0}; // Prepare all three local dimensions reported by the linked program.
3199        state->gl.GetProgramiv(program_->id, detail::COMPUTE_WORK_GROUP_SIZE, actual); // Read linked-program status, log length, or local dimensions.
3200        if (actual[0] != static_cast<int>(local_.x) || actual[1] != static_cast<int>(local_.y) || // Choose this branch when actual[0] differs from static cast<int>(local .x) or actual[1] differs from static cast<int>(local .y) or .
3201            actual[2] != static_cast<int>(local_.z)) { // Require the linked program's third local dimension to match the CPU shader.
3202            program_.reset(); // Release or replace the owned object at this lifecycle boundary.
3203            throw error("GPU source and C++ local sizes differ: " + name_); // Report gpu source and c++ local sizes differ: .
3204        } // End this scope in prepare.
3205    } // End this scope in prepare.
3206    if (program_->owner != state) // Check that this storage belongs to the requested device.
3207        throw error("shader program belongs to a different device; create a new shader instance"); // Report shader program belongs to a different device. create a new shader instance.
3208    for (std::size_t i = 0; i < ports_.size(); ++i) { // Visit every registered resource and uniform interface.
3209        auto r = ports_[i]->resource(); // Get the shared storage behind this resource interface.
3210        if (r) // Choose this branch when r.
3211            r->ensure_gpu(state); // Allocate or upload GPU storage when its host copy is newer.
3212    } // End this scope in prepare.
3213} // End this scope in prepare.
3214
3215inline void kernel::run(extent groups, device* d) { // Keep the target device.
3216    if (!groups.x || !groups.y || !groups.z) // Finish an empty dispatch before submitting GL commands.
3217        return; // Finish this operation.
3218    const unsigned g[3] = {groups.x, groups.y, groups.z}, l[3] = {local_.x, local_.y, local_.z}; // Keep dispatch counts and local dimensions for validation and CPU indexing.
3219    for (unsigned i = 0; i < 3; ++i) // Validate or query each of the three compute dimensions.
3220        if (g[i] > (std::numeric_limits<unsigned>::max)() / l[i]) // Choose this branch when g[i] > (std::numeric limits<unsigned>::max)() / l[i].
3221            throw error("global invocation index overflow"); // Report global invocation index overflow.
3222    std::vector<std::shared_ptr<detail::resource_state>> outputs; // Retain the writable resources whose authority changes after this dispatch.
3223    for (std::size_t i = 0; i < ports_.size(); ++i) { // Visit every registered resource and uniform interface.
3224        ports_[i]->validate(); // Check that this resource binding satisfies the shader declaration.
3225        std::shared_ptr<detail::resource_state> r = ports_[i]->resource(); // Get the shared storage behind this resource interface.
3226        if (r && ports_[i]->mode != access::readonly) // Choose the branch matching this interface or resource access.
3227            outputs.push_back(r); // Retain this entry in the ordered resource or work collection.
3228    } // End this scope in runtime.
3229    if (d) { // Choose this branch when d.
3230        const std::shared_ptr<detail::device_state>& state = d->state(); // Set the shared device or worker state.
3231        for (unsigned i = 0; i < 3; ++i) { // Validate or query each of the three compute dimensions.
3232            if (g[i] > state->max_groups[i]) // Choose this branch when g[i] > state->max groups[i].
3233                throw error("dispatch exceeds device work group count"); // Report dispatch exceeds device work group count.
3234            if (l[i] > state->max_local[i]) // Choose this branch when l[i] > state->max local[i].
3235                throw error("local work group dimension exceeds device limit"); // Report local work group dimension exceeds device limit.
3236        } // End this scope in runtime.
3237        const std::size_t invocations = // Count the shader invocations in one local work group.
3238            detail::checked_product(detail::checked_product(l[0], l[1]), l[2]); // Reject resource-size multiplication that would overflow.
3239        if (invocations > state->max_invocations) // Choose this branch when invocations > state->max invocations.
3240            throw error("local invocation count exceeds device limit"); // Report local invocation count exceeds device limit.
3241        prepare(*d); // Compile the program and prepare its bound GPU resources.
3242        state->gl.UseProgram(program_->id); // Select the compute program for the next dispatch.
3243        for (std::size_t i = 0; i < ports_.size(); ++i) // Visit every registered resource and uniform interface.
3244            ports_[i]->bind_gpu(*state, program_->id); // Bind this interface or assign its uniform before dispatch.
3245        state->gl.check("bind shader " + name_); // Keep the kernel or registration name.
3246        state->gl.DispatchCompute(groups.x, groups.y, groups.z); // Queue the shader workgroups.
3247        state->gl.MemoryBarrier(detail::ALL_BARRIER_BITS); // Make earlier resource writes visible to following GPU commands.
3248 // Conservatively record GPU authority even if an error follows a submitted dispatch.
3249        for (std::size_t i = 0; i < outputs.size(); ++i) // Visit this axis of the dispatch or current workgroup.
3250            outputs[i]->latest = detail::authority::gpu; // Record which backend now owns the newest resource values.
3251        state->gl.check("dispatch shader " + name_); // Keep the kernel or registration name.
3252    } else { // Handle the alternative resource or completion case.
3253        for (std::size_t i = 0; i < ports_.size(); ++i) { // Visit every registered resource and uniform interface.
3254            std::shared_ptr<detail::resource_state> r = ports_[i]->resource(); // Get the shared storage behind this resource interface.
3255            if (r) // Choose this branch when r.
3256                r->ensure_host(); // Download newer GPU values only when host access needs them.
3257        } // End this scope in runtime.
3258        gl_NumWorkGroups = glsl::uvec3(groups.x, groups.y, groups.z); // Publish the dispatch dimensions to CPU shader builtins.
3259        try { // Keep cleanup available if an allocation, shader, or driver operation fails.
3260            for (unsigned gz = 0; gz < groups.z; ++gz) // Visit this axis of the dispatch or current workgroup.
3261                for (unsigned gy = 0; gy < groups.y; ++gy) // Visit this axis of the dispatch or current workgroup.
3262                    for (unsigned gx = 0; gx < groups.x; ++gx) { // Visit this axis of the dispatch or current workgroup.
3263                        gl_WorkGroupID = glsl::uvec3(gx, gy, gz); // Publish the CPU work group currently being executed.
3264                        for (unsigned z = 0; z < local_.z; ++z) // Visit this axis of the dispatch or current workgroup.
3265                            for (unsigned y = 0; y < local_.y; ++y) // Visit this axis of the dispatch or current workgroup.
3266                                for (unsigned x = 0; x < local_.x; ++x) { // Visit this axis of the dispatch or current workgroup.
3267                                    gl_LocalInvocationID = glsl::uvec3(x, y, z); // Publish the invocation coordinates inside this work group.
3268                                    gl_GlobalInvocationID = glsl::uvec3( // Combine work group and local coordinates into global indices.
3269                                        gx * local_.x + x, gy * local_.y + y, gz * local_.z + z); // Use the local size to place this invocation in the complete dispatch.
3270                                    gl_LocalInvocationIndex = (z * local_.y + y) * local_.x + x; // Flatten the local coordinates with X changing fastest.
3271                                    main(); // Execute the shader with all CPU invocation builtins initialized.
3272                                } // End this scope in runtime.
3273                    } // End this scope in runtime.
3274        } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
3275            for (std::size_t i = 0; i < outputs.size(); ++i) // Visit this axis of the dispatch or current workgroup.
3276                outputs[i]->latest = detail::authority::host; // Record which backend now owns the newest resource values.
3277            throw; // Rethrow the original failure after arranging the necessary cleanup.
3278        } // End this scope in runtime.
3279        for (std::size_t i = 0; i < outputs.size(); ++i) // Visit this axis of the dispatch or current workgroup.
3280            outputs[i]->latest = detail::authority::host; // Record which backend now owns the newest resource values.
3281    } // End this scope in runtime.
3282} // End this scope in runtime.
3283
3284/** @brief One dispatch retaining a reference to its shader. Keep that shader alive during execution. */
3285struct stage { // Keep the stage values and operations together.
3286    kernel* shader; // Keep the shader used by this dispatch.
3287    extent groups; // Keep the number of workgroups to dispatch.
3288    backend target; // Keep the chosen CPU or GPU backend.
3289    std::shared_ptr<kernel> owner; // Retain an owned kernel while this stage uses it.
3290    /** @brief Retain a kernel reference with workgroup counts and a backend override. */
3291    stage(kernel& k, extent g, backend b) : shader(&k), groups(g), target(b) { // Keep the shader reference, work group counts and backend choice.
3292    } // End this scope in runtime.
3293    stage(std::shared_ptr<kernel> k, extent g, backend b) // Keep the shader reference, work group counts and backend choice.
3294        : shader(k.get()), groups(g), target(b), owner(k) { // Retain the kernel owner together with dispatch dimensions and backend choice.
3295        if (!shader) // Require a retained kernel for this dispatch.
3296            throw error("cannot dispatch a null shader"); // Require a valid kernel for this dispatch.
3297    } // End this scope in runtime.
3298}; // End this scope in runtime.
3299/** @brief Build a dispatch using work group counts, with an optional per-stage backend override. */
3300inline stage dispatch(kernel& shader, extent groups, backend b = backend::automatic) { // Build one ordered dispatch with the requested backend choice.
3301    return stage(shader, groups, b); // Return the result of this check or operation.
3302} // End this scope in runtime.
3303/** @brief Build a dispatch that also retains ownership of its shader. */
3304inline stage // Return a dispatch value that retains its shader owner.
3305dispatch(std::shared_ptr<kernel> shader, extent groups, backend b = backend::automatic) { // Build one ordered dispatch with the requested backend choice.
3306    return stage(shader, groups, b); // Return the result of this check or operation.
3307} // End this scope in runtime.
3308
3309class submission; // Keep the submission values and operations together.
3310
3311/** @brief An ordered pipeline, composed with >> or +=. Resources link stages by shared storage.
3312 * GPU stages issue memory barriers. CPU/GPU transitions transfer authoritative resource contents.
3313 * Running again observes updated uniforms and resource bindings. CPU execution
3314 * completes each stage before returning. GPU execution queues stages in order.
3315 * Request host data or use an explicit wait to observe GPU completion.
3316 */
3317class pipeline { // Keep the pipeline values and operations together.
3318    std::vector<stage> stages_; // Keep the dispatches in execution order.
3319    void execute(device* d) const { // Run stages in order while honoring their backend choices.
3320        for (std::size_t i = 0; i < stages_.size(); ++i) { // Visit every dispatch in processing order.
3321            const stage& s = stages_[i]; // Inspect the next dispatch, its dimensions and backend choice.
3322            if (s.target == backend::gpu && !d) // Require a device for an explicitly GPU stage.
3323                throw error("GPU stage requires a device"); // Report gpu stage requires a device.
3324            s.shader->run(s.groups, s.target == backend::cpu ? 0 : d); // Dispatch this stage on its selected CPU or GPU backend.
3325        } // End this scope in execute.
3326    } // End this scope in execute.
3327
3328  public: // Expose the operations callers can use.
3329    /** @brief Construct an empty pipeline. append dispatches with operator+=. */
3330    pipeline() { // Create the ordered dispatch container.
3331    } // End this scope in runtime.
3332    /** @brief Construct a pipeline containing one dispatch. */
3333    pipeline(stage s) { // Create a pipeline containing this initial dispatch.
3334        stages_.push_back(s); // Keep this dispatch at the end of the processing order.
3335    } // End this scope in runtime.
3336    /** @brief Append a dispatch in execution order and return this pipeline. */
3337    pipeline& operator+=(stage s) { // Append one dispatch while retaining its optional kernel owner.
3338        stages_.push_back(s); // Keep this dispatch at the end of the processing order.
3339        return *this; // Allow another operation to follow in the same expression.
3340    } // End this scope in runtime.
3341    /** @brief Append every dispatch from another pipeline, including a safe copy of this pipeline. */
3342    pipeline& operator+=(const pipeline& other) { // Compose complete processing blocks in their original stage order.
3343        const std::vector<stage> additions(other.stages_); // Preserve the source range before self-append can reallocate it.
3344        stages_.insert(stages_.end(), additions.begin(), additions.end()); // Retain each dispatch's kernel ownership and backend choice.
3345        return *this; // Allow another stage or pipeline to follow in the same expression.
3346    } // Appending copies dispatch references and preserves the stages for later execution.
3347    /** @brief Return the number of stages. */
3348    std::size_t size() const { // Read the stored element or stage count.
3349        return stages_.size(); // Return the result of this check or operation.
3350    } // End this scope in runtime.
3351    /** @brief Run automatic and CPU stages on the CPU. explicit GPU stages need a device. */
3352    void run() const { // Execute the pipeline using the selected CPU or GPU backend.
3353        execute(0); // Run stages in order while honoring their backend choices.
3354    } // End this scope in runtime.
3355    /** @brief Run automatic and GPU stages on the device, respecting explicit CPU stages.
3356     * Host readback completes queued GPU writes when resource data is requested.
3357     */
3358    void run(device& d) const { // Execute the pipeline using the selected CPU or GPU backend.
3359        execute(&d); // Run stages in order while honoring their backend choices.
3360    } // End this scope in runtime.
3361    /** @brief Compile GPU programs and upload resources before steady-state submission. */
3362    void prepare(device& d) const { // Compile the program and prepare its bound GPU resources.
3363        for (std::size_t i = 0; i < stages_.size(); ++i) // Visit every dispatch in processing order.
3364            if (stages_[i].target != backend::cpu) // Precompile and upload stages that can execute on the GPU.
3365                stages_[i].shader->prepare(d); // Compile the program and prepare its bound GPU resources.
3366    } // End this scope in prepare.
3367    /** @brief Enqueue GPU stages and return a fence for zero-timeout completion polls. */
3368    submission submit(device& d) const; // Queue compute work and return its completion handle.
3369    /** @internal Access dispatches for submission and snapshot handling. */
3370    const std::vector<stage>& stages() const { // Expose the ordered dispatches for submission and snapshot handling.
3371        return stages_; // Return the dispatches in execution order.
3372    } // End this scope in runtime.
3373    /** @brief Snapshot shader instances, uniforms and bindings for deferred CPU execution. */
3374    pipeline snapshot() const { // Clone kernels and retain the current binding and uniform values.
3375        pipeline result; // Keep the value returned by this operation.
3376        std::map<kernel*, std::shared_ptr<kernel>> copies; // Keep the shader clones reused by repeated stages.
3377        for (std::size_t i = 0; i < stages_.size(); ++i) { // Visit every dispatch in processing order.
3378            const stage& s = stages_[i]; // Inspect the next dispatch, its dimensions and backend choice.
3379            auto& copy = copies[s.shader]; // Reuse one clone for every occurrence of the same source kernel.
3380            if (!copy) // Create a clone only on the source kernel's first occurrence.
3381                copy = std::shared_ptr<kernel>(s.shader->clone().release()); // Own an isolated clone of this kernel's current interfaces.
3382            result += stage(copy, s.groups, s.target); // Retain the cloned kernel with its original dimensions and backend choice.
3383        } // End this scope in snapshot.
3384        return result; // Return the value returned by this operation.
3385    } // End this scope in snapshot.
3386    /** @brief Validate CPU execution support and current host data for a deferred job. */
3387    void require_host_ready() const { // Validate CPU stages and host-ready resources.
3388        for (std::size_t i = 0; i < stages_.size(); ++i) { // Visit every dispatch in processing order.
3389            if (stages_[i].target == backend::gpu) // Reject GPU-only stages before submitting work to a CPU worker.
3390                throw error("CPU executor cannot execute a GPU-only stage"); // Require CPU-compatible stages for the CPU executor.
3391            auto resources = stages_[i].shader->resources(); // Inspect the resources bound to this stage.
3392            for (std::size_t r = 0; r < resources.size(); ++r) // Check every bound resource for data requiring GPU readback.
3393                if (resources[r]->latest == detail::authority::gpu) // Require the caller to download newer GPU contents on the context thread.
3394                    throw error( // Report the invalid operation.
3395                        "download GPU data on its context thread before submitting CPU work"); // Explain how to make this resource ready for CPU execution.
3396        } // End this scope in require host ready.
3397    } // End this scope in require host ready.
3398}; // End this scope in runtime.
3399/** @brief Compose ordered stages into a reusable pipeline. */
3400inline pipeline operator>>(stage a, stage b) { // Compose these dispatches in their execution order.
3401    pipeline p(a); // Start the pipeline with the first dispatch.
3402    p += b; // Append the following dispatch to the ordered pipeline.
3403    return p; // Return the composed pipeline for later execution.
3404} // End this scope in runtime.
3405/** @brief Append a stage to a pipeline value, retaining references to the same kernels. */
3406inline pipeline operator>>(pipeline p, stage b) { // Compose these dispatches in their execution order.
3407    p += b; // Append the following dispatch to the ordered pipeline.
3408    return p; // Return the composed pipeline for later execution.
3409} // End this scope in runtime.
3410/** @brief Prepend a stage to a pipeline while retaining the same linked shader resources. */
3411inline pipeline operator>>(stage a, const pipeline& b) { // Place the independent dispatch before all existing processing stages.
3412    pipeline result(a); // Start with the supplied dispatch and its retained kernel owner.
3413    result += b; // Append the complete processing block in its original order.
3414    return result; // Return the reusable pipeline for later execution.
3415} // The source pipeline remains available for further composition or execution.
3416/** @brief Join two complete processing pipelines in execution order. */
3417inline pipeline operator>>(pipeline a, const pipeline& b) { // Compose reusable algorithm blocks with ordinary shader dispatches.
3418    a += b; // Append a copy of the second block's dispatch references.
3419    return a; // Return the combined ordered processing plan.
3420} // Resource sharing follows the same rules as individual stage composition.
3421
3422namespace detail { // Group these definitions in the detail namespace.
3423typedef kernel* (*kernel_factory)(); // Name the representation used by this GL or shader interface.
3424inline std::map<std::string, std::vector<kernel_factory>>& shader_registry() { // Share the compiled shader factories discovered during startup.
3425    static std::map<std::string, std::vector<kernel_factory>> registry; // Keep the shared display lifetime registry.
3426    return registry; // Return the shared display lifetime registry.
3427} // End this scope in shader registry.
3428 // Generated shader translation units register factories directly in their target.
3429 // Unregistering makes plugin unload safe for future lookups. existing shader objects
3430 // still require the plugin to stay loaded through destruction.
3431class shader_registration { // Keep the shader registration values and operations together.
3432    std::string name_; // Keep the kernel or registration name.
3433    kernel_factory factory_; // Keep the compiled shader construction callback.
3434
3435  public: // Expose the operations callers can use.
3436    shader_registration(const char* name, kernel_factory factory) : name_(name), factory_(factory) { // Keep the callback used to create a registered shader.
3437        shader_registry()[name_].push_back(factory_); // Retain this entry in the ordered resource or work collection.
3438    } // End this scope in runtime.
3439    ~shader_registration() { // Unregister this factory before its dynamic module is unloaded.
3440        std::vector<kernel_factory>& entries = shader_registry()[name_]; // Find the registered factories using this shader name.
3441        const std::vector<kernel_factory>::iterator it = // Find this module's factory among the registrations.
3442            std::find(entries.begin(), entries.end(), factory_); // Keep the compiled shader construction callback.
3443        if (it != entries.end()) // Choose this branch when it differs from entries.end().
3444            entries.erase(it); // Remove this module's registration and preserve the other factories.
3445        if (entries.empty()) // Choose this branch when entries.empty().
3446            shader_registry().erase(name_); // Share the compiled shader factories discovered during startup.
3447    } // End this scope in runtime.
3448    shader_registration(const shader_registration&) = delete; // Prevent copying this object and duplicating its retained identity.
3449    shader_registration& operator=(const shader_registration&) = delete; // Prevent copying this object and duplicating its retained identity.
3450}; // End this scope in runtime.
3451} // namespace detail
3452
3453/** @brief Create a shader compiled and embedded by shdr_target_shaders during the CMake build.
3454 * A file named scale.cpp registers scale_kernel. The returned instance owns its CPU/GPU program
3455 * and exposes resource binding through bind() and set(). Both programs are part of the binary.
3456 * Unknown or ambiguous names throw error. Call from one application thread after startup.
3457 */
3458inline std::unique_ptr<kernel> make_kernel(const std::string& name) { // Create one automatically registered shader by its build-time name.
3459    const std::map<std::string, std::vector<detail::kernel_factory>>& registry = // Set the shared display lifetime registry.
3460        detail::shader_registry(); // Share the compiled shader factories discovered during startup.
3461    const std::map<std::string, std::vector<detail::kernel_factory>>::const_iterator it = // Find the unique compiled factory requested by the application.
3462        registry.find(name); // Keep the resource or entry-point name.
3463    if (it == registry.end()) // Choose this branch when it equals registry.end().
3464        throw error("unknown compiled shader: " + name); // Report unknown compiled shader: .
3465    if (it->second.size() != 1) // Check resource size or driver limits before accessing storage.
3466        throw error("ambiguous compiled shader name: " + name); // Report ambiguous compiled shader name: .
3467    return std::unique_ptr<kernel>(it->second.front()()); // Create one automatically registered shader by its build-time name.
3468} // End this scope in make kernel.
3469} // namespace shdr
3470
3471 // A short namespace alias keeps host-side mathematical expressions readable.
3472namespace glsl = shdr::glsl; // Group these definitions in the glsl namespace.
3473#endif // SHDR_RUNTIME_HPP
3474
3475// ---- async.hpp ----
3476/** @file async.hpp
3477 * @brief Nonblocking GPU completion handles and bounded CPU work queues.
3478 * Prepare GPU pipelines before a hot loop, keep a ring of independent resource
3479 * sets, and poll completion before reading or recycling a result. GPU calls
3480 * use the device's context thread. CPU workers execute independent snapshots
3481 * and require host-ready resources. Complete GPU readback on the context thread
3482 * before submitting a CPU job.
3483 */
3484#ifndef SHDR_ASYNC_HPP // Skip this section if it was already included.
3485#define SHDR_ASYNC_HPP /* Mark this section as included. */
3486#ifndef SHDR_RUNTIME_HPP // Skip this section if it was already included.
3487#include "math.hpp" // Use the portable GLSL scalar, vector, and matrix types.
3488#include "runtime.hpp" // Use the kernel, resource, and ordered pipeline definitions.
3489#endif // Finish this conditional section.
3490#include <chrono> // Express explicit waits and zero-time completion polls.
3491#include <condition_variable> // Wake CPU workers when jobs arrive or shutdown begins.
3492#include <deque> // Keep pending CPU jobs in submission order.
3493#include <exception> // Pass worker failures back through completion futures.
3494#include <future> // Give callers a completion result for each CPU job.
3495#include <mutex> // Protect shared work queues and deferred deletion.
3496#include <thread> // Track the context thread and start CPU workers.
3497#include <utility> // Move job and resource ownership between runtime objects.
3498
3499namespace shdr { // Group these definitions in the shdr namespace.
3500
3501/** @brief Result of a completion query: completed work or an expired timeout. */
3502enum class wait_status { ready, timeout }; // Name the two outcomes of a GPU completion query.
3503
3504namespace detail { // Group these definitions in the detail namespace.
3505struct submission_resources { // Keep the submission resources values and operations together.
3506    std::vector<std::shared_ptr<resource_state>> resources; // Keep the resource storage retained until queued work completes.
3507    std::vector<std::shared_ptr<program_state>> programs; // Keep the compiled programs retained by a submission.
3508}; // End this scope in async.
3509
3510struct submission_state { // Keep a GPU fence and its resources alive until retirement.
3511    std::shared_ptr<device_state> owner; // Keep the device that owns the GL resource.
3512    GLsync fence; // Keep the GL completion fence.
3513    std::shared_ptr<submission_resources> retained; // Keep the submission resource bundle.
3514    bool completed; // Cache whether this submission fence has already signaled.
3515    explicit submission_state(const std::shared_ptr<device_state>& d) // Retain the device, fence, and queued resource bundle.
3516        : owner(d), fence(0), retained(std::make_shared<submission_resources>()), completed(false) { // Retain the device and create an empty pending-completion resource bundle.
3517    } // End this scope in submission state.
3518    ~submission_state() noexcept { // Retire completed fences and defer pending fence cleanup.
3519        if (!fence) // Finish immediately for an empty fence.
3520            return; // Finish this operation.
3521        const GLsync sync = fence; // Copy the fence handle into the deferred cleanup callback.
3522        const std::shared_ptr<submission_resources> keep = retained; // Retain buffers and programs until deferred cleanup releases this bundle.
3523        try { // Keep cleanup available if an allocation, shader, or driver operation fails.
3524            if (completed) { // Retire a fence whose completion has already been observed.
3525                owner->retire([sync, keep](gl_api& gl) { // Delete on the context thread or defer deletion to that thread.
3526                    gl.DeleteSync(sync); // Delete the GL completion fence.
3527                    (void)keep; // Keep the resource references captured for this cleanup.
3528                }); // End this scope in submission state.
3529            } else { // Handle the alternative resource or completion case.
3530 // The context thread checks this retirement entry with a zero timeout.
3531                owner->defer_poll( // Retain a completion check until its fence signals.
3532                    [sync, keep](gl_api& gl) -> bool { // Retain these captures until the queued callback finishes.
3533                        const GLenum status = gl.ClientWaitSync(sync, 0, 0); // Poll the discarded fence with zero flags and a zero timeout.
3534                        if (status == TIMEOUT_EXPIRED) // Check the driver result before marking GPU completion.
3535                            return false; // Keep the discarded submission pending while its fence is unsignaled.
3536                        gl.DeleteSync(sync); // Delete the GL completion fence.
3537                        (void)keep; // Keep the resource references captured for this cleanup.
3538                        return true; // Remove the retired fence and release its retained resource bundle.
3539                    }, // End this scope in submission state.
3540                    [sync](gl_api& gl) { // Keep only the fence handle for nonblocking shutdown cancellation.
3541                        gl.DeleteSync(sync); // Delete the GL completion fence.
3542                    }); // End this scope in submission state.
3543            } // End this scope in submission state.
3544        } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
3545 // Destruction defers pending fence cleanup. GL command references keep
3546 // already queued operations valid if allocating a retirement entry fails.
3547        } // End this scope in submission state.
3548    } // End this scope in submission state.
3549    wait_status query(GLuint64 timeout) { // Check completion with the requested driver timeout.
3550        owner->require_thread(); // Require the device context thread and activate its headless context.
3551        if (completed) // Reuse the cached completion result after checking the context thread.
3552            return wait_status::ready; // Tell the caller that queued GPU commands have completed.
3553        const GLenum result = owner->gl.ClientWaitSync(fence, 0, timeout); // Check a GPU fence with the caller-selected timeout.
3554        if (result == ALREADY_SIGNALED || result == CONDITION_SATISFIED) { // Check the driver result before marking GPU completion.
3555            completed = true; // Set whether the GPU fence has already signaled.
3556            return wait_status::ready; // Tell the caller that queued GPU commands have completed.
3557        } // End this scope in query.
3558        if (result == TIMEOUT_EXPIRED) // Check the driver result before marking GPU completion.
3559            return wait_status::timeout; // Tell the caller that the explicit wait expired before completion.
3560        owner->gl.check("query GPU submission"); // Check for a driver error from the preceding GL operation.
3561        throw error("GPU completion query failed"); // Report gpu completion query failed.
3562    } // End this scope in query.
3563}; // End this scope in async.
3564} // namespace detail
3565
3566/** @brief A movable handle for one queued GPU pipeline.
3567 * ready() performs a zero-timeout fence query. wait(timeout) bounds the requested
3568 * driver wait. wait() explicitly waits for completion. Destroying a handle
3569 * schedules pending fence and resource cleanup on the device context thread.
3570 * Device garbage collection releases those retained resources after completion.
3571 * Keep the GL context alive until retained work and resources have been retired.
3572 */
3573class submission { // Keep the submission values and operations together.
3574    std::unique_ptr<detail::submission_state> state_; // Own this completion handle and its retained GPU resources.
3575    explicit submission(std::unique_ptr<detail::submission_state> state) // Accept sole ownership of this fence and its retained resource bundle.
3576        : state_(std::move(state)) { // Move the fence state into this completion handle.
3577    } // End this scope in async.
3578    friend class pipeline; // Allow the related pipeline or resource helper to access this retained state.
3579
3580  public: // Expose the operations callers can use.
3581    /** @brief Construct an empty, already-complete handle. */
3582    submission() { // Create an empty handle that is already complete.
3583    } // End this scope in async.
3584    submission(submission&&) noexcept = default; // Move the completion state into the new handle.
3585    submission& operator=(submission&&) noexcept = default; // Retire the old handle and move in the new completion state.
3586    submission(const submission&) = delete; // Prevent copying this object and duplicating its retained identity.
3587    submission& operator=(const submission&) = delete; // Prevent copying this object and duplicating its retained identity.
3588    /** @brief Return whether this handle represents submitted GPU commands. */
3589    bool valid() const { // Check whether this handle represents actual submitted GPU work.
3590        return bool(state_); // Return whether this handle retains a submission state.
3591    } // End this scope in async.
3592    /** @brief Query completion with a zero timeout on the device context thread. */
3593    bool ready() { // Check whether queued work has completed using a zero-timeout poll.
3594        return !state_ || state_->query(0) == wait_status::ready; // Check whether queued work has completed using a zero-timeout poll.
3595    } // End this scope in ready.
3596    /** @brief Request a driver wait with a nonnegative timeout in nanoseconds. */
3597    wait_status wait(std::chrono::nanoseconds timeout) { // Apply the explicit completion wait selected by the caller.
3598        if (timeout.count() < 0) // Require a nonnegative wait duration.
3599            throw error("GPU submission timeout must be nonnegative"); // Report gpu submission timeout must be nonnegative.
3600        if (!state_) // Treat an empty handle as already completed.
3601            return wait_status::ready; // Tell the caller that queued GPU commands have completed.
3602        return state_->query(static_cast<detail::GLuint64>(timeout.count())); // Apply the explicit completion wait selected by the caller.
3603    } // End this scope in wait.
3604    /** @brief Explicitly wait until submitted commands complete. */
3605    wait_status wait() { // Apply the explicit completion wait selected by the caller.
3606        if (!state_) // Treat an empty handle as already completed.
3607            return wait_status::ready; // Tell the caller that queued GPU commands have completed.
3608        while (state_->query((std::numeric_limits<detail::GLuint64>::max)()) == // Use the caller's explicit blocking wait until the fence completes.
3609               wait_status::timeout) { // Repeat only if the implementation still reports an incomplete wait.
3610        } // End this scope in wait.
3611        return wait_status::ready; // Tell the caller that queued GPU commands have completed.
3612    } // End this scope in wait.
3613}; // End this scope in async.
3614
3615/** @brief Enqueue all GPU stages and return a fence for polling or explicit waits.
3616 * Each stage must support GPU execution. Call prepare()
3617 * before entering a latency-sensitive loop to compile shaders and allocate/upload
3618 * resources in advance. Subsequent host edits can still require an upload.
3619 * Uniform and binding changes after return affect subsequent submissions.
3620 */
3621inline submission pipeline::submit(device& d) const { // Queue compute work and return its completion handle.
3622    d.state()->require_thread(); // Require the device context thread and activate its headless context.
3623    const std::vector<stage>& commands = stages(); // Read the ordered stages that this submission will queue.
3624    for (std::size_t i = 0; i < commands.size(); ++i) // Visit each ordered GPU stage in this submission.
3625        if (commands[i].target == backend::cpu) // Reject explicit CPU stages before queueing any GPU commands.
3626            throw error("GPU submission cannot contain CPU stages"); // Require GPU stages for GPU submission.
3627    if (commands.empty()) // Skip fence creation for an empty pipeline.
3628        return submission(); // Represent an empty pipeline with an already completed handle.
3629    std::unique_ptr<detail::submission_state> completion(new detail::submission_state(d.state())); // Retain the device, fence, and queued resource bundle.
3630    completion->retained->programs.reserve(commands.size()); // Reserve room to retain one compiled program per stage.
3631    prepare(d); // Compile the program and prepare its bound GPU resources.
3632    for (std::size_t i = 0; i < commands.size(); ++i) { // Visit each ordered GPU stage in this submission.
3633        const std::vector<std::shared_ptr<detail::resource_state>> resources = // Set the resource storage retained until queued work completes.
3634            commands[i].shader->resources(); // Collect the shared storage used by this shader.
3635        completion->retained->resources.insert( // Retain this entry in the ordered resource or work collection.
3636            completion->retained->resources.end(), resources.begin(), resources.end()); // Keep the end of the current range.
3637        completion->retained->programs.push_back(commands[i].shader->program_state()); // Retain this entry in the ordered resource or work collection.
3638    } // End this scope in submit.
3639    try { // Keep cleanup available if an allocation, shader, or driver operation fails.
3640        run(d); // Queue all validated GPU stages in pipeline order.
3641    } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
3642 // A later dispatch can fail after an earlier dispatch was queued.
3643        completion->fence = d.state()->gl.FenceSync(detail::SYNC_GPU_COMMANDS_COMPLETE, 0); // Insert a completion fence after queued compute work.
3644        d.state()->gl.Flush(); // Flush queued GPU commands for driver execution.
3645        throw; // Rethrow the original failure after arranging the necessary cleanup.
3646    } // End this scope in submit.
3647    completion->fence = d.state()->gl.FenceSync(detail::SYNC_GPU_COMMANDS_COMPLETE, 0); // Insert a completion fence after queued compute work.
3648    if (!completion->fence) { // Check that the driver allocated a valid completion fence.
3649        d.state()->gl.check("create GPU submission fence"); // Expose retained runtime state to the resource and backend helpers.
3650        throw error("cannot create GPU submission fence"); // Report completion-fence allocation failure.
3651    } // End this scope in submit.
3652    d.state()->gl.Flush(); // Flush queued GPU commands for driver execution.
3653    d.state()->gl.check("submit GPU pipeline"); // Expose retained runtime state to the resource and backend helpers.
3654    return submission(std::move(completion)); // Queue compute work and return its completion handle.
3655} // End this scope in submit.
3656
3657/** @brief A bounded CPU executor for independent pipeline jobs.
3658 * Each submit() snapshots kernels, uniforms and resource bindings. Snapshots
3659 * have independent invocation state, while buffers and images retain shared
3660 * storage. Give concurrent jobs distinct writable resources, such as ring slots.
3661 * Queue saturation throws immediately. Futures report results or exceptions.
3662 * Destroying a future releases its result handle, while the executor retains
3663 * the job until completion. shutdown() drains accepted jobs and joins workers.
3664 * Executor destruction also drains and joins them.
3665 */
3666class executor { // Keep the executor values and operations together.
3667    struct job { // Keep the job values and operations together.
3668        std::function<void()> function; // Keep the application function executed by a CPU worker.
3669        std::promise<void> completion; // Keep the completion result that the caller will receive.
3670        explicit job(const std::function<void()>& fn) : function(fn) { // Keep the accepted CPU function and its promise result.
3671        } // End this scope in async.
3672    }; // End this scope in async.
3673    struct queue_state { // Share the bounded queue between its producer and workers.
3674        std::mutex mutex; // Keep the lock protecting shared state.
3675        std::condition_variable changed; // Wake sleeping workers when work or shutdown state changes.
3676        std::deque<std::shared_ptr<job>> jobs; // Keep accepted CPU work awaiting an available worker.
3677        std::vector<std::thread::id> worker_ids; // Keep the worker thread identifiers used to reject self-joining.
3678        std::size_t pending, capacity; // Keep the current pending count and the maximum queue size.
3679        bool closing; // Keep whether the CPU executor is draining for shutdown.
3680        explicit queue_state(std::size_t n) : pending(0), capacity(n), closing(false) { // Start an empty queue with the chosen pending-job capacity.
3681        } // End this scope in async.
3682    }; // End this scope in async.
3683    std::shared_ptr<queue_state> state_; // Share the bounded queue between the executor and its workers.
3684    std::vector<std::thread> workers_; // Keep the threads that execute accepted CPU jobs.
3685    std::mutex shutdown_mutex_; // Keep the lock that serializes executor shutdown.
3686
3687    static void consume(const std::shared_ptr<queue_state>& state) { // Take accepted jobs from the queue and execute them on this worker.
3688        for (;;) { // Keep this worker available until its queue is drained for shutdown.
3689            std::shared_ptr<job> next; // Keep the CPU job selected by this worker.
3690            { // Begin the protected scope for this operation.
3691                std::unique_lock<std::mutex> lock(state->mutex); // Hold the mutex while this shared state is accessed.
3692                state->changed.wait(lock, [&] { // Release the queue lock while sleeping until work or shutdown arrives.
3693                    return state->closing || !state->jobs.empty(); // Wake the worker for a queued job or an explicit shutdown.
3694                }); // End this scope in consume.
3695                if (state->jobs.empty()) // Exit only when shutdown has awakened an empty queue.
3696                    return; // Finish this operation.
3697                next = state->jobs.front(); // Set the CPU job selected by this worker.
3698                state->jobs.pop_front(); // Remove this accepted job from the pending queue.
3699                --state->pending; // Release its pending slot before executing the job.
3700            } // End this scope in consume.
3701            try { // Keep cleanup available if an allocation, shader, or driver operation fails.
3702                next->function(); // Execute the selected application function or CPU pipeline snapshot.
3703                next->function = std::function<void()>(); // Release kernel and resource captures before publishing completion.
3704                next->completion.set_value(); // Publish successful completion after the job releases its captures.
3705            } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
3706                const std::exception_ptr failure = std::current_exception(); // Set the exception captured from a CPU job.
3707                next->function = std::function<void()>(); // Release kernel and resource captures before publishing completion.
3708                next->completion.set_exception(failure); // Deliver the worker failure through the caller completion future.
3709            } // End this scope in consume.
3710        } // End this scope in consume.
3711    } // End this scope in consume.
3712    void reserve() { // Reserve capacity and report a full queue immediately.
3713        std::lock_guard<std::mutex> lock(state_->mutex); // Hold the mutex while this shared state is accessed.
3714        if (state_->closing) // Check the queue state before accepting or executing work.
3715            throw error("CPU executor is shut down"); // Report cpu executor is shut down.
3716        if (state_->pending == state_->capacity) // Check the queue state before accepting or executing work.
3717            throw error("CPU executor queue is full"); // Report cpu executor queue is full.
3718        ++state_->pending; // Count the accepted job against the pending queue capacity.
3719    } // End this scope in reserve.
3720    void abandon() noexcept { // Release the reserved slot after a submission failure.
3721        std::lock_guard<std::mutex> lock(state_->mutex); // Hold the mutex while this shared state is accessed.
3722        --state_->pending; // Return the queue slot reserved by an unsuccessful submission.
3723    } // End this scope in abandon.
3724    std::future<void> append_reserved(const std::function<void()>& function) { // Attach the accepted CPU job to its reserved queue slot.
3725        std::shared_ptr<job> work(new job(function)); // Keep the application function executed by a CPU worker.
3726        std::future<void> result = work->completion.get_future(); // Set the value returned by this operation.
3727        { // Begin the protected scope for this operation.
3728            std::lock_guard<std::mutex> lock(state_->mutex); // Hold the mutex while this shared state is accessed.
3729            if (state_->closing) // Check the queue state before accepting or executing work.
3730                throw error("CPU executor is shut down"); // Report cpu executor is shut down.
3731            state_->jobs.push_back(work); // Retain this entry in the ordered resource or work collection.
3732        } // End this scope in append reserved.
3733        state_->changed.notify_one(); // Wake workers so they can observe new queue or shutdown state.
3734        return result; // Return the value returned by this operation.
3735    } // End this scope in append reserved.
3736
3737  public: // Expose the operations callers can use.
3738    /** @brief Start workers with room for at most capacity pending jobs.
3739     * Capacity counts jobs waiting for a worker. Both arguments must be positive.
3740     */
3741    explicit executor(std::size_t workers = 1, std::size_t capacity = 64) // Start a fixed number of workers with a bounded pending-job queue.
3742        : state_(std::make_shared<queue_state>(capacity)) { // Keep the maximum number of pending CPU jobs.
3743        if (!workers || !capacity) // Require positive worker and queue counts.
3744            throw error("CPU executor requires positive worker and queue counts"); // Report cpu executor requires positive worker and queue counts.
3745        workers_.reserve(workers); // Allocate space for every worker thread handle.
3746        state_->worker_ids.reserve(workers); // Allocate space for every worker thread identifier.
3747        try { // Keep cleanup available if an allocation, shader, or driver operation fails.
3748            for (std::size_t i = 0; i < workers; ++i) { // Visit this axis of the dispatch or current workgroup.
3749                const std::shared_ptr<queue_state> state = state_; // Set the shared device or worker state.
3750                workers_.push_back(std::thread([state] { // Retain this entry in the ordered resource or work collection.
3751                    consume(state); // Take accepted jobs from the queue and execute them on this worker.
3752                })); // End this scope in executor.
3753                state_->worker_ids.push_back(workers_.back().get_id()); // Retain this entry in the ordered resource or work collection.
3754            } // End this scope in executor.
3755        } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
3756            shutdown(); // Drain accepted CPU work and join the workers from an application thread.
3757            throw; // Rethrow the original failure after arranging the necessary cleanup.
3758        } // End this scope in executor.
3759    } // End this scope in executor.
3760    ~executor() { // Drain accepted work and join the CPU workers at explicit pool teardown.
3761        shutdown(); // Drain accepted CPU work and join the workers from an application thread.
3762    } // End this scope in executor.
3763    executor(const executor&) = delete; // Prevent copying this object and duplicating its retained identity.
3764    executor& operator=(const executor&) = delete; // Prevent copying this object and duplicating its retained identity.
3765    /** @brief Snapshot a host-ready CPU pipeline, enqueue it and return a future.
3766     * Each stage must support CPU execution and have current host data.
3767     */
3768    std::future<void> submit(const pipeline& source) { // Queue compute work and return its completion handle.
3769        reserve(); // Reserve capacity and report a full queue immediately.
3770        try { // Keep cleanup available if an allocation, shader, or driver operation fails.
3771            source.require_host_ready(); // Validate CPU stages and host-ready resources before queueing.
3772            const pipeline copy = source.snapshot(); // Capture isolated kernel interfaces and the current bindings and uniforms.
3773            return append_reserved([copy] { // Queue compute work and return its completion handle.
3774                copy.run(); // Execute the retained CPU snapshot on its worker thread.
3775            }); // End this scope in submit.
3776        } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
3777            abandon(); // Release the reserved slot after a submission failure.
3778            throw; // Rethrow the original failure after arranging the necessary cleanup.
3779        } // End this scope in submit.
3780    } // End this scope in submit.
3781    /** @brief Enqueue an application CPU function on the same bounded queue.
3782     * Run host operations in the callback and keep device operations on their context thread.
3783     */
3784    template <class Function> std::future<void> enqueue(Function function) { // Select the scalar, dimension, or access type at compile time.
3785        reserve(); // Reserve capacity and report a full queue immediately.
3786        try { // Keep cleanup available if an allocation, shader, or driver operation fails.
3787            return append_reserved(std::function<void()>(function)); // Queue the application callback on the bounded CPU executor.
3788        } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
3789            abandon(); // Release the reserved slot after a submission failure.
3790            throw; // Rethrow the original failure after arranging the necessary cleanup.
3791        } // End this scope in enqueue.
3792    } // End this scope in enqueue.
3793    /** @brief Return the count of queued or currently being constructed jobs. */
3794    std::size_t pending() const { // Read the count of jobs waiting for a worker.
3795        std::lock_guard<std::mutex> lock(state_->mutex); // Hold the mutex while this shared state is accessed.
3796        return state_->pending; // Read the count of jobs waiting for a worker.
3797    } // End this scope in pending.
3798    /** @brief Return the maximum number of pending jobs. */
3799    std::size_t capacity() const { // Return the configured pending-job limit.
3800        return state_->capacity; // Return the configured pending-job limit.
3801    } // End this scope in capacity.
3802    /** @brief Return the number of worker threads. */
3803    std::size_t workers() const { // Return the number of worker threads.
3804        return workers_.size(); // Return the number of worker threads.
3805    } // End this scope in workers.
3806    /** @brief Drain accepted jobs and join all workers. later submissions fail.
3807     * Call from an application thread so it can join every worker.
3808     */
3809    void shutdown() { // Drain accepted CPU work and join the workers from an application thread.
3810        if (std::find(state_->worker_ids.begin(), // Choose this branch when std::find(state ->worker ids.begin(),.
3811                      state_->worker_ids.end(), // Keep the end of the current range.
3812                      std::this_thread::get_id()) != state_->worker_ids.end()) // Reject joining the current executor worker from its own job.
3813            throw error("CPU executor shutdown requires an application thread"); // Report cpu executor shutdown requires an application thread.
3814        std::lock_guard<std::mutex> lifecycle(shutdown_mutex_); // Hold the mutex while this shared state is accessed.
3815        { // Begin the protected scope for this operation.
3816            std::lock_guard<std::mutex> lock(state_->mutex); // Hold the mutex while this shared state is accessed.
3817            state_->closing = true; // Set whether the CPU executor is draining for shutdown.
3818        } // End this scope in shutdown.
3819        state_->changed.notify_all(); // Wake workers so they can observe new queue or shutdown state.
3820        for (std::size_t i = 0; i < workers_.size(); ++i) // Visit each CPU worker during lifecycle handling.
3821            if (workers_[i].joinable()) // Choose this branch when workers [i].joinable().
3822                workers_[i].join(); // Join this CPU worker after accepted work has drained.
3823    } // End this scope in shutdown.
3824}; // End this scope in async.
3825} // namespace shdr
3826#endif // SHDR_ASYNC_HPP
3827
3828// ---- egl.hpp ----
3829#ifndef SHDR_EGL_HPP // Skip this section if it was already included.
3830#define SHDR_EGL_HPP /* Mark this section as included. */
3831
3832 // Enable this optional backend before including shdr.h and link an EGL library.
3833#if defined(SHDR_ENABLE_EGL) && SHDR_ENABLE_EGL // Compile this branch only when its platform or backend condition holds.
3834#include <EGL/egl.h> // Load the EGL display, context, and surface API.
3835#include <EGL/eglext.h> // Use the available EGL context and platform extensions.
3836
3837namespace shdr { // Group these definitions in the shdr namespace.
3838
3839/** @brief The requested graphics backend or context is unavailable.
3840 * This exception identifies display, configuration, context and GL entry-point
3841 * failures. Shader compilation and dispatch errors remain ordinary shdr::error.
3842 */
3843class backend_unavailable : public error { // Keep the backend unavailable values and operations together.
3844  public: // Expose the operations callers can use.
3845    /** @brief Describe the unavailable graphics infrastructure. */
3846    explicit backend_unavailable(const std::string& message) : error(message) { // Keep the graphics initialization failure as an ordinary exception.
3847    } // End this scope in egl.
3848}; // End this scope in egl.
3849
3850namespace detail { // Group these definitions in the detail namespace.
3851
3852inline backend_unavailable egl_failure(const char* operation) { // Build a readable diagnostic from the EGL error code.
3853    const EGLint code = eglGetError(); // Read the EGL error belonging to the failed context operation.
3854    std::ostringstream message; // Build a readable diagnostic from the EGL error code.
3855    message << operation << " unavailable (EGL error 0x" << std::hex << code << ')'; // Build a readable diagnostic from the EGL error code.
3856    return backend_unavailable(message.str()); // Build a readable diagnostic from the EGL error code.
3857} // End this scope in egl failure.
3858
3859 // Initialization and the last termination share a lock, including during weak-pointer expiry.
3860struct egl_display_registry { // Keep the egl display registry values and operations together.
3861    std::mutex mutex; // Keep the lock protecting shared state.
3862    EGLDisplay display; // Keep the initialized EGL display.
3863    std::size_t owners; // Keep the number of contexts retaining this display.
3864    egl_display_registry() : display(EGL_NO_DISPLAY), owners(0) { // Start the initialized-display owner count at zero.
3865    } // End this scope in egl.
3866}; // End this scope in egl.
3867inline egl_display_registry& egl_displays() { // Share the display-lifetime registry among headless devices.
3868    static egl_display_registry registry; // Keep the shared display lifetime registry.
3869    return registry; // Return the shared display lifetime registry.
3870} // End this scope in egl displays.
3871
3872 // Contexts share one initialized display. the last context releases it.
3873struct egl_display_state { // Keep the egl display state values and operations together.
3874    EGLDisplay display; // Keep the initialized EGL display.
3875    egl_display_state() : display(EGL_NO_DISPLAY) { // Retain one initialized EGL display for living contexts.
3876        egl_display_registry& registry = egl_displays(); // Set the shared display lifetime registry.
3877        std::lock_guard<std::mutex> lock(registry.mutex); // Hold the mutex while this shared state is accessed.
3878        if (registry.owners) { // Reuse this display when another context already retains its initialization.
3879            display = registry.display; // Set the initialized EGL display.
3880            ++registry.owners; // Retain the existing initialized display for this new owner.
3881            return; // Finish this operation.
3882        } // End this scope in egl display state.
3883        typedef EGLDisplay(EGLAPIENTRYP platform_display_fn)(EGLenum, void*, const EGLint*); // Name the representation used by this GL or shader interface.
3884        const platform_display_fn platform_display = // Resolve the optional surfaceless display entry point.
3885            reinterpret_cast<platform_display_fn>(eglGetProcAddress("eglGetPlatformDisplayEXT")); // Look up the requested GL entry point through EGL.
3886        if (platform_display) { // Choose this branch when platform display.
3887 // Mesa's surfaceless platform creates an offscreen display on supported drivers.
3888            display = platform_display(0x31DD, EGL_DEFAULT_DISPLAY, 0); // Set the initialized EGL display.
3889            if (display != EGL_NO_DISPLAY && !eglInitialize(display, 0, 0)) // Prepare the default-display fallback if surfaceless initialization fails.
3890                display = EGL_NO_DISPLAY; // Set the initialized EGL display.
3891        } // End this scope in egl display state.
3892        if (display == EGL_NO_DISPLAY) { // Try the default display after the surfaceless path.
3893            display = eglGetDisplay(EGL_DEFAULT_DISPLAY); // Set the initialized EGL display.
3894            if (display == EGL_NO_DISPLAY || !eglInitialize(display, 0, 0)) { // Report failure to acquire and initialize the default display.
3895                display = EGL_NO_DISPLAY; // Set the initialized EGL display.
3896                throw egl_failure("EGL display"); // Report egl display.
3897            } // End this scope in egl display state.
3898        } // End this scope in egl display state.
3899        registry.display = display; // Set the initialized EGL display.
3900        registry.owners = 1; // Set the number of contexts retaining this display.
3901    } // End this scope in egl display state.
3902    ~egl_display_state() { // Release this object's owned resources at teardown.
3903        egl_display_registry& registry = egl_displays(); // Set the shared display lifetime registry.
3904        std::lock_guard<std::mutex> lock(registry.mutex); // Hold the mutex while this shared state is accessed.
3905        if (display != EGL_NO_DISPLAY && --registry.owners == 0) { // Terminate an initialized display after its final context owner releases it.
3906            eglTerminate(display); // Terminate the display after its last context owner is released.
3907            registry.display = EGL_NO_DISPLAY; // Set the initialized EGL display.
3908        } // End this scope in egl display state.
3909    } // End this scope in egl display state.
3910    egl_display_state(const egl_display_state&) = delete; // Prevent copying this object and duplicating its retained identity.
3911    egl_display_state& operator=(const egl_display_state&) = delete; // Prevent copying this object and duplicating its retained identity.
3912}; // End this scope in egl.
3913
3914inline std::shared_ptr<egl_display_state> acquire_egl_display() { // Reuse the initialized display while any context retains it.
3915    static std::mutex mutex; // Keep the lock protecting shared state.
3916    static std::weak_ptr<egl_display_state> cached; // Keep the weak reference to the shared EGL display.
3917    std::lock_guard<std::mutex> lock(mutex); // Hold the mutex while this shared state is accessed.
3918    std::shared_ptr<egl_display_state> display = cached.lock(); // Set the initialized EGL display.
3919    if (!display) { // Create the shared display state for its first owner.
3920        display = std::make_shared<egl_display_state>(); // Set the initialized EGL display.
3921        cached = display; // Set the weak reference to the shared EGL display.
3922    } // End this scope in acquire egl display.
3923    return display; // Return the initialized EGL display.
3924} // End this scope in acquire egl display.
3925
3926struct egl_context_state { // Retain one headless EGL display, context, and pbuffer.
3927    std::shared_ptr<egl_display_state> display; // Keep the initialized EGL display.
3928    EGLContext context; // Keep the EGL context used for compute commands.
3929    EGLSurface surface; // Keep the one-pixel EGL pbuffer.
3930    EGLenum api; // Keep the selected desktop GL or GLES API.
3931    std::thread::id thread; // Keep the thread that created this EGL context.
3932
3933    explicit egl_context_state(profile p) // Create a pbuffer context for the requested shader profile.
3934        : display(acquire_egl_display()), context(EGL_NO_CONTEXT), surface(EGL_NO_SURFACE), // Reuse the initialized display while any context retains it.
3935          api(p == profile::es31 || p == profile::es32 ? EGL_OPENGL_ES_API : EGL_OPENGL_API), // Choose the EGL client API matching the requested shader profile.
3936          thread(std::this_thread::get_id()) { // Remember the only thread allowed to use this EGL context.
3937        try { // Keep cleanup available if an allocation, shader, or driver operation fails.
3938            const bool desktop = p != profile::es31 && p != profile::es32; // Select the API family for the requested profile.
3939            if (!eglBindAPI(api)) // Check that EGL accepts the selected graphics API.
3940                throw egl_failure("EGL graphics API"); // Report egl graphics api.
3941            const EGLint config_attributes[] = {EGL_SURFACE_TYPE, // Request a pbuffer configuration with the chosen client API.
3942                                                EGL_PBUFFER_BIT, // Request a configuration capable of creating a small offscreen surface.
3943                                                EGL_RENDERABLE_TYPE, // Select the client API supported by the framebuffer configuration.
3944                                                desktop ? EGL_OPENGL_BIT : 0x0040, // Request desktop GL or an OpenGL ES 3-capable configuration.
3945                                                EGL_RED_SIZE, // Specify the number of red bits in the offscreen surface.
3946                                                8, // Request eight bits for this color component.
3947                                                EGL_GREEN_SIZE, // Specify the number of green bits in the offscreen surface.
3948                                                8, // Request eight bits for this color component.
3949                                                EGL_BLUE_SIZE, // Specify the number of blue bits in the offscreen surface.
3950                                                8, // Request eight bits for this color component.
3951                                                EGL_NONE}; // Create a pbuffer context for the requested shader profile.
3952            EGLConfig config = 0; // Set the selected EGL framebuffer configuration.
3953            EGLint count = 0; // Set the element or configuration count.
3954            if (!eglChooseConfig(display->display, config_attributes, &config, 1, &count) || !count) // Check resource size or driver limits before accessing storage.
3955                throw egl_failure("EGL framebuffer configuration"); // Report egl framebuffer configuration.
3956            const EGLint major = desktop ? 4 : 3; // Set the GL major version.
3957            const EGLint minor = p == profile::es31   ? 1 // Set the GL minor version.
3958                                 : p == profile::es32 ? 2 // Select the version associated with this shader profile.
3959                                 : p == profile::gl43 ? 3 // Select the version associated with this shader profile.
3960                                 : p == profile::gl45 ? 5 // Select the version associated with this shader profile.
3961                                                      : 6; // Select minor version six for the desktop GL 4.6 profile.
3962 // These KHR_create_context attributes are also core in EGL 1.5.
3963            const EGLint desktop_attributes[] = { // Request the selected desktop version and core profile.
3964                0x3098, major, 0x30FB, minor, 0x30FD, 0x00000001, EGL_NONE}; // Create a pbuffer context for the requested shader profile.
3965            const EGLint es_attributes[] = {0x3098, major, 0x30FB, minor, EGL_NONE}; // Request the selected GLES major and minor versions.
3966            context = eglCreateContext(display->display, // Create a compute context for the requested GL or GLES version.
3967                                       config, // Keep the selected EGL framebuffer configuration.
3968                                       EGL_NO_CONTEXT, // Create a context with its own GL object namespace.
3969                                       desktop ? desktop_attributes : es_attributes); // Create a pbuffer context for the requested shader profile.
3970            if (context == EGL_NO_CONTEXT) // Check that the driver created the requested context.
3971                throw egl_failure("Requested GL context"); // Report requested gl context.
3972            const EGLint surface_attributes[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; // Create a one-pixel offscreen pbuffer for compute commands.
3973            surface = eglCreatePbufferSurface(display->display, config, surface_attributes); // Set the one-pixel EGL pbuffer.
3974            if (surface == EGL_NO_SURFACE) // Check that the driver created the offscreen pbuffer.
3975                throw egl_failure("EGL pbuffer"); // Report egl pbuffer.
3976            make_current(); // Select this context on its creating thread.
3977        } catch (...) { // Preserve cleanup or exception propagation for this failed operation.
3978            release(); // Release this surface and context while preserving other active contexts.
3979            throw; // Rethrow the original failure after arranging the necessary cleanup.
3980        } // End this scope in egl context state.
3981    } // End this scope in egl context state.
3982    void make_current() const { // Select this context on its creating thread.
3983        if (std::this_thread::get_id() != thread) // Check that the operation uses the context or lifecycle thread.
3984            throw error("headless EGL operations require the context's creating thread"); // Report headless egl operations require the context's creating thread.
3985        if (!eglBindAPI(api)) // Check that EGL accepts the selected graphics API.
3986            throw egl_failure("EGL graphics API"); // Report egl graphics api.
3987        if (eglGetCurrentContext() == context && eglGetCurrentDisplay() == display->display) // Choose this branch when eglGetCurrentContext() equals context and eglGetCurrentDisplay() equals display->display.
3988            return; // Finish this operation.
3989        if (!eglMakeCurrent(display->display, surface, surface, context)) // Check that EGL activates this context and its pbuffer.
3990            throw egl_failure("Current EGL context"); // Report current egl context.
3991    } // End this scope in make current.
3992    void release() { // Release this surface and context while preserving other active contexts.
3993 // Unbind this context only when it is current on this thread.
3994        const EGLenum previous_api = eglQueryAPI(); // Set the EGL API current before context release.
3995        eglBindAPI(api); // Select the desktop GL or GLES API for this EGL operation.
3996        if (context != EGL_NO_CONTEXT && eglGetCurrentContext() == context) // Unbind this context when it is current.
3997            eglMakeCurrent(display->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); // Make this pbuffer context current on its owning thread.
3998        if (surface != EGL_NO_SURFACE) // Destroy the pbuffer allocated by this state.
3999            eglDestroySurface(display->display, surface); // Release the EGL object after its context-thread owners finish.
4000        if (context != EGL_NO_CONTEXT) // Destroy the context allocated by this state.
4001            eglDestroyContext(display->display, context); // Release the EGL object after its context-thread owners finish.
4002        if (previous_api != api) // Choose this branch when previous api differs from api.
4003            eglBindAPI(previous_api); // Restore the API binding that belonged to the other live context.
4004        surface = EGL_NO_SURFACE; // Set the one-pixel EGL pbuffer.
4005        context = EGL_NO_CONTEXT; // Set the EGL context used for compute commands.
4006    } // End this scope in release.
4007    ~egl_context_state() { // Release this object's owned resources at teardown.
4008        release(); // Release this surface and context while preserving other active contexts.
4009    } // End this scope in egl context state.
4010    egl_context_state(const egl_context_state&) = delete; // Prevent copying this object and duplicating its retained identity.
4011    egl_context_state& operator=(const egl_context_state&) = delete; // Prevent copying this object and duplicating its retained identity.
4012}; // End this scope in egl.
4013
4014inline std::shared_ptr<egl_context_state> make_egl_context(profile p) { // Create and retain the headless EGL context.
4015    return std::make_shared<egl_context_state>(p); // Create and retain the headless EGL context.
4016} // End this scope in make egl context.
4017} // namespace detail
4018
4019/** @brief An optional, headless EGL pbuffer context for a selected compute profile.
4020 * Define SHDR_ENABLE_EGL=1 before including shdr.h and link EGL to use this class.
4021 * It prefers a surfaceless display and otherwise uses EGL's default display.
4022 * Create, use and finally release the context on its creating thread. Displays
4023 * are shared among living shdr contexts. Let shdr manage their display lifetime.
4024 */
4025class headless_context { // Keep the headless context values and operations together.
4026    std::shared_ptr<detail::egl_context_state> context_; // Keep the retained headless context state.
4027
4028  public: // Expose the operations callers can use.
4029    /** @brief Create a 1-by-1 pbuffer and make its context current.
4030     * @param p Minimum GL or GLES version. defaults to OpenGL ES 3.1.
4031     * @throws backend_unavailable If backend initialization fails.
4032     */
4033    explicit headless_context(profile p = profile::es31) : context_(detail::make_egl_context(p)) { // Create and retain an EGL context for the requested compute profile.
4034    } // End this scope in egl.
4035    /** @brief Make this context current on its creating thread. */
4036    void make_current() const { // Select this context on its creating thread.
4037        context_->make_current(); // Select this context on its creating thread.
4038    } // End this scope in make current.
4039    /** @brief Resolve a GL entry point through EGL, for shdr::device or external GL calls. */
4040    static void* resolve(const char* name) { // Resolve a named GL function through EGL.
4041        const __eglMustCastToProperFunctionPointerType function = eglGetProcAddress(name); // Look up the requested GL entry point through EGL.
4042        static_assert(sizeof(function) == sizeof(void*), // Require a representation that matches the shader interface.
4043                      "EGL function addresses must fit in void*"); // Require EGL function addresses to fit the portable resolver representation.
4044        void* address = 0; // Set the resolved GL function address.
4045        std::memcpy(&address, &function, sizeof(address)); // Copy the representation with the alias-safe byte-copy operation.
4046        return address; // Return the resolved GL function address.
4047    } // End this scope in resolve.
4048    headless_context(const headless_context&) = delete; // Prevent copying this object and duplicating its retained identity.
4049    headless_context& operator=(const headless_context&) = delete; // Prevent copying this object and duplicating its retained identity.
4050}; // End this scope in egl.
4051
4052/** @brief A compute device that creates and retains its own headless EGL context.
4053 * Define SHDR_ENABLE_EGL=1 and link EGL. Construct this device on the thread that
4054 * performs its GPU operations. Its context remains alive while GPU resources,
4055 * programs and submissions retain the device state. release those objects on
4056 * that thread before shutdown. CPU execution uses host resources.
4057 */
4058class headless_device : public device { // Keep the headless device values and operations together.
4059    std::shared_ptr<detail::egl_context_state> context_; // Keep the retained headless context state.
4060    headless_device(const std::shared_ptr<detail::egl_context_state>& context, profile p) try // Connect the retained EGL context to the GL runtime.
4061        : device(headless_context::resolve, p), context_(context) { // Retain a validated GL device state.
4062        state()->context_keepalive = context; // Set the retained headless context.
4063        state()->activate_context = [context] { // Set the callback that makes this device context current.
4064            context->make_current(); // Select this context on its creating thread.
4065        }; // End this scope in state.
4066    } catch (const backend_unavailable&) { // Clean up objects allocated before the operation failed.
4067        throw; // Rethrow the original failure after arranging the necessary cleanup.
4068    } catch (const error& failure) { // Translate device-initialization failures into an unavailable-backend result.
4069        throw backend_unavailable(failure.what()); // Preserve the initialization diagnostic in the backend exception.
4070    } // End this scope in egl.
4071
4072  public: // Expose the operations callers can use.
4073    /** @brief Create a headless context and initialize its compute device.
4074     * @param p Minimum shader and context profile. defaults to OpenGL ES 3.1.
4075     * @throws backend_unavailable If context creation or entry-point loading fails.
4076     */
4077    explicit headless_device(profile p = profile::es31) // Create a compute device with its own retained EGL context.
4078        : headless_device(detail::make_egl_context(p), p) { // Connect the retained EGL context to the GL runtime.
4079    } // End this scope in headless device.
4080    /** @brief Make the owned context current for external GL interoperability. */
4081    void make_current() const { // Select this context on its creating thread.
4082        context_->make_current(); // Select this context on its creating thread.
4083    } // End this scope in make current.
4084    headless_device(const headless_device&) = delete; // Prevent copying this object and duplicating its retained identity.
4085    headless_device& operator=(const headless_device&) = delete; // Prevent copying this object and duplicating its retained identity.
4086}; // End this scope in egl.
4087
4088} // namespace shdr
4089#endif // SHDR_ENABLE_EGL
4090#endif // SHDR_EGL_HPP
4091
4092// ---- macros.hpp ----
4093#ifndef SHDR_MACROS_HPP // Include these helper macros only once.
4094#define SHDR_MACROS_HPP // Remember that the helper macros are available.
4095
4096/** @brief Begin one shared shader declaration with a fixed local work group size. */
4097#define SHDR_BEGIN(name, x, y, z) /* Start the shared shader type and its CPU snapshot method. */ \
4098    using namespace ::shdr::glsl; /* Make the GLSL math names available inside this shader. */ \
4099    struct name : ::shdr::kernel { /* Give the shared shader the CPU kernel interface. */ \
4100        name() : ::shdr::kernel(#name, ::shdr::extent(x, y, z)) { /* Store the shader name and fixed local work group size. */ \
4101        } /* Close the generated method or shader declaration. */ \
4102        std::unique_ptr<::shdr::kernel> clone() const override { /* Build an independent CPU instance for deferred execution. */ \
4103            std::unique_ptr<name> copy(new name); /* Allocate the shader instance that will hold the snapshot. */ \
4104            copy_interfaces(*copy); /* Copy uniform values and resource bindings into that instance. */ \
4105            return std::unique_ptr<::shdr::kernel>(copy.release()); /* Return ownership through the common kernel interface. */ \
4106        } /* Close the generated method or shader declaration. */
4107/** @brief End a shared shader declaration. */
4108#define SHDR_END() /* Close the shared shader type. */ \
4109    } /* Close the generated method or shader declaration. */ \
4110    ; /* Finish the generated shader type declaration. */
4111/** @brief Declare the shared entry point, executed once per invocation on CPU or GPU. */
4112#define SHDR_MAIN() void main() override // Make the shader entry point override the CPU kernel method.
4113/** @brief Declare a typed std430 SSBO with readonly/writeonly/readwrite access. */
4114#define SHDR_BUFFER(binding, type, name, mode) /* Create a named storage buffer port with the chosen access mode. */ \
4115    ::shdr::buffer_port<type, ::shdr::access::mode> name{*this, binding, #name}; /* Register this typed buffer port with its owning shader. */
4116/** @brief Declare a typed scalar, vector or float matrix uniform. */
4117#define SHDR_UNIFORM(type, name) /* Create a uniform value and its binding descriptor. */ \
4118    type name{}; /* Initialize the uniform value to its default value. */ \
4119    ::shdr::uniform_port<type> shdr_uniform_##name{*this, #name, name}; /* Register the uniform so host code can set it by name. */
4120/** @brief Declare a 2D storage image. Supported formats are r32f/i/ui and rgba32f/i/ui. */
4121#define SHDR_IMAGE2D(binding, format, type, name, mode) /* Choose the matching image scalar type and component count. */ \
4122    SHDR_DETAIL_IMAGE_##type(::shdr::access::mode, SHDR_DETAIL_FORMAT_##format, name, binding) /* Expand the selected image helper with its access and binding. */
4123#define SHDR_DETAIL_IMAGE_image2D(mode, format, name, binding) /* Define the CPU image port for this GLSL image type. */ \
4124    ::shdr::image_port<float, format, mode> name{*this, binding, #name}; /* Register the image port with its owning shader. */
4125#define SHDR_DETAIL_IMAGE_iimage2D(mode, format, name, binding) /* Define the CPU image port for this GLSL image type. */ \
4126    ::shdr::image_port<int, format, mode> name{*this, binding, #name}; /* Register the image port with its owning shader. */
4127#define SHDR_DETAIL_IMAGE_uimage2D(mode, format, name, binding) /* Define the CPU image port for this GLSL image type. */ \
4128    ::shdr::image_port<unsigned, format, mode> name{*this, binding, #name}; /* Register the image port with its owning shader. */
4129#define SHDR_DETAIL_FORMAT_r32f 1 // Use one scalar component for this image format.
4130#define SHDR_DETAIL_FORMAT_r32i 1 // Use one scalar component for this image format.
4131#define SHDR_DETAIL_FORMAT_r32ui 1 // Use one scalar component for this image format.
4132#define SHDR_DETAIL_FORMAT_rgba32f 4 // Use four scalar components for this image format.
4133#define SHDR_DETAIL_FORMAT_rgba32i 4 // Use four scalar components for this image format.
4134#define SHDR_DETAIL_FORMAT_rgba32ui 4 // Use four scalar components for this image format.
4135/** @brief GLSL-style component selection, with safe simultaneous CPU swizzle assignment.
4136 * Use xyzw, rgba or stpq consistently. Duplicate components are read-only.
4137 */
4138#define SHDR_SWIZZLE(value, pattern) (value).template swizzle<SHDR_DETAIL_SWIZZLE_##pattern>() // Translate component letters into a safe CPU component selection.
4139/** @brief Portable spelling of GLSL's boolean vector not builtin. */
4140#define SHDR_NOT(value) ::shdr::glsl::logicalNot(value) // Invert every component of a boolean vector.
4141/** @brief Declare a shared helper function input parameter. */
4142#define SHDR_IN(type, name) const type& name // Pass a helper input through a const reference.
4143/** @brief Declare a shared helper function output parameter. */
4144#define SHDR_OUT(type, name) type& name // Let the helper write its output argument.
4145/** @brief Declare a shared helper function input/output parameter. */
4146#define SHDR_INOUT(type, name) type& name // Let the helper read and update its argument.
4147#define SHDR_DETAIL_SWIZZLE_x 0 // Select the x component.
4148#define SHDR_DETAIL_SWIZZLE_y 1 // Select the y component.
4149#define SHDR_DETAIL_SWIZZLE_z 2 // Select the z component.
4150#define SHDR_DETAIL_SWIZZLE_w 3 // Select the w component.
4151#define SHDR_DETAIL_SWIZZLE_xx 0, 0 // Select x, then x in that order.
4152#define SHDR_DETAIL_SWIZZLE_xy 0, 1 // Select x, then y in that order.
4153#define SHDR_DETAIL_SWIZZLE_xz 0, 2 // Select x, then z in that order.
4154#define SHDR_DETAIL_SWIZZLE_xw 0, 3 // Select x, then w in that order.
4155#define SHDR_DETAIL_SWIZZLE_yx 1, 0 // Select y, then x in that order.
4156#define SHDR_DETAIL_SWIZZLE_yy 1, 1 // Select y, then y in that order.
4157#define SHDR_DETAIL_SWIZZLE_yz 1, 2 // Select y, then z in that order.
4158#define SHDR_DETAIL_SWIZZLE_yw 1, 3 // Select y, then w in that order.
4159#define SHDR_DETAIL_SWIZZLE_zx 2, 0 // Select z, then x in that order.
4160#define SHDR_DETAIL_SWIZZLE_zy 2, 1 // Select z, then y in that order.
4161#define SHDR_DETAIL_SWIZZLE_zz 2, 2 // Select z, then z in that order.
4162#define SHDR_DETAIL_SWIZZLE_zw 2, 3 // Select z, then w in that order.
4163#define SHDR_DETAIL_SWIZZLE_wx 3, 0 // Select w, then x in that order.
4164#define SHDR_DETAIL_SWIZZLE_wy 3, 1 // Select w, then y in that order.
4165#define SHDR_DETAIL_SWIZZLE_wz 3, 2 // Select w, then z in that order.
4166#define SHDR_DETAIL_SWIZZLE_ww 3, 3 // Select w, then w in that order.
4167#define SHDR_DETAIL_SWIZZLE_xxx 0, 0, 0 // Select x, then x, then x in that order.
4168#define SHDR_DETAIL_SWIZZLE_xxy 0, 0, 1 // Select x, then x, then y in that order.
4169#define SHDR_DETAIL_SWIZZLE_xxz 0, 0, 2 // Select x, then x, then z in that order.
4170#define SHDR_DETAIL_SWIZZLE_xxw 0, 0, 3 // Select x, then x, then w in that order.
4171#define SHDR_DETAIL_SWIZZLE_xyx 0, 1, 0 // Select x, then y, then x in that order.
4172#define SHDR_DETAIL_SWIZZLE_xyy 0, 1, 1 // Select x, then y, then y in that order.
4173#define SHDR_DETAIL_SWIZZLE_xyz 0, 1, 2 // Select x, then y, then z in that order.
4174#define SHDR_DETAIL_SWIZZLE_xyw 0, 1, 3 // Select x, then y, then w in that order.
4175#define SHDR_DETAIL_SWIZZLE_xzx 0, 2, 0 // Select x, then z, then x in that order.
4176#define SHDR_DETAIL_SWIZZLE_xzy 0, 2, 1 // Select x, then z, then y in that order.
4177#define SHDR_DETAIL_SWIZZLE_xzz 0, 2, 2 // Select x, then z, then z in that order.
4178#define SHDR_DETAIL_SWIZZLE_xzw 0, 2, 3 // Select x, then z, then w in that order.
4179#define SHDR_DETAIL_SWIZZLE_xwx 0, 3, 0 // Select x, then w, then x in that order.
4180#define SHDR_DETAIL_SWIZZLE_xwy 0, 3, 1 // Select x, then w, then y in that order.
4181#define SHDR_DETAIL_SWIZZLE_xwz 0, 3, 2 // Select x, then w, then z in that order.
4182#define SHDR_DETAIL_SWIZZLE_xww 0, 3, 3 // Select x, then w, then w in that order.
4183#define SHDR_DETAIL_SWIZZLE_yxx 1, 0, 0 // Select y, then x, then x in that order.
4184#define SHDR_DETAIL_SWIZZLE_yxy 1, 0, 1 // Select y, then x, then y in that order.
4185#define SHDR_DETAIL_SWIZZLE_yxz 1, 0, 2 // Select y, then x, then z in that order.
4186#define SHDR_DETAIL_SWIZZLE_yxw 1, 0, 3 // Select y, then x, then w in that order.
4187#define SHDR_DETAIL_SWIZZLE_yyx 1, 1, 0 // Select y, then y, then x in that order.
4188#define SHDR_DETAIL_SWIZZLE_yyy 1, 1, 1 // Select y, then y, then y in that order.
4189#define SHDR_DETAIL_SWIZZLE_yyz 1, 1, 2 // Select y, then y, then z in that order.
4190#define SHDR_DETAIL_SWIZZLE_yyw 1, 1, 3 // Select y, then y, then w in that order.
4191#define SHDR_DETAIL_SWIZZLE_yzx 1, 2, 0 // Select y, then z, then x in that order.
4192#define SHDR_DETAIL_SWIZZLE_yzy 1, 2, 1 // Select y, then z, then y in that order.
4193#define SHDR_DETAIL_SWIZZLE_yzz 1, 2, 2 // Select y, then z, then z in that order.
4194#define SHDR_DETAIL_SWIZZLE_yzw 1, 2, 3 // Select y, then z, then w in that order.
4195#define SHDR_DETAIL_SWIZZLE_ywx 1, 3, 0 // Select y, then w, then x in that order.
4196#define SHDR_DETAIL_SWIZZLE_ywy 1, 3, 1 // Select y, then w, then y in that order.
4197#define SHDR_DETAIL_SWIZZLE_ywz 1, 3, 2 // Select y, then w, then z in that order.
4198#define SHDR_DETAIL_SWIZZLE_yww 1, 3, 3 // Select y, then w, then w in that order.
4199#define SHDR_DETAIL_SWIZZLE_zxx 2, 0, 0 // Select z, then x, then x in that order.
4200#define SHDR_DETAIL_SWIZZLE_zxy 2, 0, 1 // Select z, then x, then y in that order.
4201#define SHDR_DETAIL_SWIZZLE_zxz 2, 0, 2 // Select z, then x, then z in that order.
4202#define SHDR_DETAIL_SWIZZLE_zxw 2, 0, 3 // Select z, then x, then w in that order.
4203#define SHDR_DETAIL_SWIZZLE_zyx 2, 1, 0 // Select z, then y, then x in that order.
4204#define SHDR_DETAIL_SWIZZLE_zyy 2, 1, 1 // Select z, then y, then y in that order.
4205#define SHDR_DETAIL_SWIZZLE_zyz 2, 1, 2 // Select z, then y, then z in that order.
4206#define SHDR_DETAIL_SWIZZLE_zyw 2, 1, 3 // Select z, then y, then w in that order.
4207#define SHDR_DETAIL_SWIZZLE_zzx 2, 2, 0 // Select z, then z, then x in that order.
4208#define SHDR_DETAIL_SWIZZLE_zzy 2, 2, 1 // Select z, then z, then y in that order.
4209#define SHDR_DETAIL_SWIZZLE_zzz 2, 2, 2 // Select z, then z, then z in that order.
4210#define SHDR_DETAIL_SWIZZLE_zzw 2, 2, 3 // Select z, then z, then w in that order.
4211#define SHDR_DETAIL_SWIZZLE_zwx 2, 3, 0 // Select z, then w, then x in that order.
4212#define SHDR_DETAIL_SWIZZLE_zwy 2, 3, 1 // Select z, then w, then y in that order.
4213#define SHDR_DETAIL_SWIZZLE_zwz 2, 3, 2 // Select z, then w, then z in that order.
4214#define SHDR_DETAIL_SWIZZLE_zww 2, 3, 3 // Select z, then w, then w in that order.
4215#define SHDR_DETAIL_SWIZZLE_wxx 3, 0, 0 // Select w, then x, then x in that order.
4216#define SHDR_DETAIL_SWIZZLE_wxy 3, 0, 1 // Select w, then x, then y in that order.
4217#define SHDR_DETAIL_SWIZZLE_wxz 3, 0, 2 // Select w, then x, then z in that order.
4218#define SHDR_DETAIL_SWIZZLE_wxw 3, 0, 3 // Select w, then x, then w in that order.
4219#define SHDR_DETAIL_SWIZZLE_wyx 3, 1, 0 // Select w, then y, then x in that order.
4220#define SHDR_DETAIL_SWIZZLE_wyy 3, 1, 1 // Select w, then y, then y in that order.
4221#define SHDR_DETAIL_SWIZZLE_wyz 3, 1, 2 // Select w, then y, then z in that order.
4222#define SHDR_DETAIL_SWIZZLE_wyw 3, 1, 3 // Select w, then y, then w in that order.
4223#define SHDR_DETAIL_SWIZZLE_wzx 3, 2, 0 // Select w, then z, then x in that order.
4224#define SHDR_DETAIL_SWIZZLE_wzy 3, 2, 1 // Select w, then z, then y in that order.
4225#define SHDR_DETAIL_SWIZZLE_wzz 3, 2, 2 // Select w, then z, then z in that order.
4226#define SHDR_DETAIL_SWIZZLE_wzw 3, 2, 3 // Select w, then z, then w in that order.
4227#define SHDR_DETAIL_SWIZZLE_wwx 3, 3, 0 // Select w, then w, then x in that order.
4228#define SHDR_DETAIL_SWIZZLE_wwy 3, 3, 1 // Select w, then w, then y in that order.
4229#define SHDR_DETAIL_SWIZZLE_wwz 3, 3, 2 // Select w, then w, then z in that order.
4230#define SHDR_DETAIL_SWIZZLE_www 3, 3, 3 // Select w, then w, then w in that order.
4231#define SHDR_DETAIL_SWIZZLE_xxxx 0, 0, 0, 0 // Select x, then x, then x, then x in that order.
4232#define SHDR_DETAIL_SWIZZLE_xxxy 0, 0, 0, 1 // Select x, then x, then x, then y in that order.
4233#define SHDR_DETAIL_SWIZZLE_xxxz 0, 0, 0, 2 // Select x, then x, then x, then z in that order.
4234#define SHDR_DETAIL_SWIZZLE_xxxw 0, 0, 0, 3 // Select x, then x, then x, then w in that order.
4235#define SHDR_DETAIL_SWIZZLE_xxyx 0, 0, 1, 0 // Select x, then x, then y, then x in that order.
4236#define SHDR_DETAIL_SWIZZLE_xxyy 0, 0, 1, 1 // Select x, then x, then y, then y in that order.
4237#define SHDR_DETAIL_SWIZZLE_xxyz 0, 0, 1, 2 // Select x, then x, then y, then z in that order.
4238#define SHDR_DETAIL_SWIZZLE_xxyw 0, 0, 1, 3 // Select x, then x, then y, then w in that order.
4239#define SHDR_DETAIL_SWIZZLE_xxzx 0, 0, 2, 0 // Select x, then x, then z, then x in that order.
4240#define SHDR_DETAIL_SWIZZLE_xxzy 0, 0, 2, 1 // Select x, then x, then z, then y in that order.
4241#define SHDR_DETAIL_SWIZZLE_xxzz 0, 0, 2, 2 // Select x, then x, then z, then z in that order.
4242#define SHDR_DETAIL_SWIZZLE_xxzw 0, 0, 2, 3 // Select x, then x, then z, then w in that order.
4243#define SHDR_DETAIL_SWIZZLE_xxwx 0, 0, 3, 0 // Select x, then x, then w, then x in that order.
4244#define SHDR_DETAIL_SWIZZLE_xxwy 0, 0, 3, 1 // Select x, then x, then w, then y in that order.
4245#define SHDR_DETAIL_SWIZZLE_xxwz 0, 0, 3, 2 // Select x, then x, then w, then z in that order.
4246#define SHDR_DETAIL_SWIZZLE_xxww 0, 0, 3, 3 // Select x, then x, then w, then w in that order.
4247#define SHDR_DETAIL_SWIZZLE_xyxx 0, 1, 0, 0 // Select x, then y, then x, then x in that order.
4248#define SHDR_DETAIL_SWIZZLE_xyxy 0, 1, 0, 1 // Select x, then y, then x, then y in that order.
4249#define SHDR_DETAIL_SWIZZLE_xyxz 0, 1, 0, 2 // Select x, then y, then x, then z in that order.
4250#define SHDR_DETAIL_SWIZZLE_xyxw 0, 1, 0, 3 // Select x, then y, then x, then w in that order.
4251#define SHDR_DETAIL_SWIZZLE_xyyx 0, 1, 1, 0 // Select x, then y, then y, then x in that order.
4252#define SHDR_DETAIL_SWIZZLE_xyyy 0, 1, 1, 1 // Select x, then y, then y, then y in that order.
4253#define SHDR_DETAIL_SWIZZLE_xyyz 0, 1, 1, 2 // Select x, then y, then y, then z in that order.
4254#define SHDR_DETAIL_SWIZZLE_xyyw 0, 1, 1, 3 // Select x, then y, then y, then w in that order.
4255#define SHDR_DETAIL_SWIZZLE_xyzx 0, 1, 2, 0 // Select x, then y, then z, then x in that order.
4256#define SHDR_DETAIL_SWIZZLE_xyzy 0, 1, 2, 1 // Select x, then y, then z, then y in that order.
4257#define SHDR_DETAIL_SWIZZLE_xyzz 0, 1, 2, 2 // Select x, then y, then z, then z in that order.
4258#define SHDR_DETAIL_SWIZZLE_xyzw 0, 1, 2, 3 // Select x, then y, then z, then w in that order.
4259#define SHDR_DETAIL_SWIZZLE_xywx 0, 1, 3, 0 // Select x, then y, then w, then x in that order.
4260#define SHDR_DETAIL_SWIZZLE_xywy 0, 1, 3, 1 // Select x, then y, then w, then y in that order.
4261#define SHDR_DETAIL_SWIZZLE_xywz 0, 1, 3, 2 // Select x, then y, then w, then z in that order.
4262#define SHDR_DETAIL_SWIZZLE_xyww 0, 1, 3, 3 // Select x, then y, then w, then w in that order.
4263#define SHDR_DETAIL_SWIZZLE_xzxx 0, 2, 0, 0 // Select x, then z, then x, then x in that order.
4264#define SHDR_DETAIL_SWIZZLE_xzxy 0, 2, 0, 1 // Select x, then z, then x, then y in that order.
4265#define SHDR_DETAIL_SWIZZLE_xzxz 0, 2, 0, 2 // Select x, then z, then x, then z in that order.
4266#define SHDR_DETAIL_SWIZZLE_xzxw 0, 2, 0, 3 // Select x, then z, then x, then w in that order.
4267#define SHDR_DETAIL_SWIZZLE_xzyx 0, 2, 1, 0 // Select x, then z, then y, then x in that order.
4268#define SHDR_DETAIL_SWIZZLE_xzyy 0, 2, 1, 1 // Select x, then z, then y, then y in that order.
4269#define SHDR_DETAIL_SWIZZLE_xzyz 0, 2, 1, 2 // Select x, then z, then y, then z in that order.
4270#define SHDR_DETAIL_SWIZZLE_xzyw 0, 2, 1, 3 // Select x, then z, then y, then w in that order.
4271#define SHDR_DETAIL_SWIZZLE_xzzx 0, 2, 2, 0 // Select x, then z, then z, then x in that order.
4272#define SHDR_DETAIL_SWIZZLE_xzzy 0, 2, 2, 1 // Select x, then z, then z, then y in that order.
4273#define SHDR_DETAIL_SWIZZLE_xzzz 0, 2, 2, 2 // Select x, then z, then z, then z in that order.
4274#define SHDR_DETAIL_SWIZZLE_xzzw 0, 2, 2, 3 // Select x, then z, then z, then w in that order.
4275#define SHDR_DETAIL_SWIZZLE_xzwx 0, 2, 3, 0 // Select x, then z, then w, then x in that order.
4276#define SHDR_DETAIL_SWIZZLE_xzwy 0, 2, 3, 1 // Select x, then z, then w, then y in that order.
4277#define SHDR_DETAIL_SWIZZLE_xzwz 0, 2, 3, 2 // Select x, then z, then w, then z in that order.
4278#define SHDR_DETAIL_SWIZZLE_xzww 0, 2, 3, 3 // Select x, then z, then w, then w in that order.
4279#define SHDR_DETAIL_SWIZZLE_xwxx 0, 3, 0, 0 // Select x, then w, then x, then x in that order.
4280#define SHDR_DETAIL_SWIZZLE_xwxy 0, 3, 0, 1 // Select x, then w, then x, then y in that order.
4281#define SHDR_DETAIL_SWIZZLE_xwxz 0, 3, 0, 2 // Select x, then w, then x, then z in that order.
4282#define SHDR_DETAIL_SWIZZLE_xwxw 0, 3, 0, 3 // Select x, then w, then x, then w in that order.
4283#define SHDR_DETAIL_SWIZZLE_xwyx 0, 3, 1, 0 // Select x, then w, then y, then x in that order.
4284#define SHDR_DETAIL_SWIZZLE_xwyy 0, 3, 1, 1 // Select x, then w, then y, then y in that order.
4285#define SHDR_DETAIL_SWIZZLE_xwyz 0, 3, 1, 2 // Select x, then w, then y, then z in that order.
4286#define SHDR_DETAIL_SWIZZLE_xwyw 0, 3, 1, 3 // Select x, then w, then y, then w in that order.
4287#define SHDR_DETAIL_SWIZZLE_xwzx 0, 3, 2, 0 // Select x, then w, then z, then x in that order.
4288#define SHDR_DETAIL_SWIZZLE_xwzy 0, 3, 2, 1 // Select x, then w, then z, then y in that order.
4289#define SHDR_DETAIL_SWIZZLE_xwzz 0, 3, 2, 2 // Select x, then w, then z, then z in that order.
4290#define SHDR_DETAIL_SWIZZLE_xwzw 0, 3, 2, 3 // Select x, then w, then z, then w in that order.
4291#define SHDR_DETAIL_SWIZZLE_xwwx 0, 3, 3, 0 // Select x, then w, then w, then x in that order.
4292#define SHDR_DETAIL_SWIZZLE_xwwy 0, 3, 3, 1 // Select x, then w, then w, then y in that order.
4293#define SHDR_DETAIL_SWIZZLE_xwwz 0, 3, 3, 2 // Select x, then w, then w, then z in that order.
4294#define SHDR_DETAIL_SWIZZLE_xwww 0, 3, 3, 3 // Select x, then w, then w, then w in that order.
4295#define SHDR_DETAIL_SWIZZLE_yxxx 1, 0, 0, 0 // Select y, then x, then x, then x in that order.
4296#define SHDR_DETAIL_SWIZZLE_yxxy 1, 0, 0, 1 // Select y, then x, then x, then y in that order.
4297#define SHDR_DETAIL_SWIZZLE_yxxz 1, 0, 0, 2 // Select y, then x, then x, then z in that order.
4298#define SHDR_DETAIL_SWIZZLE_yxxw 1, 0, 0, 3 // Select y, then x, then x, then w in that order.
4299#define SHDR_DETAIL_SWIZZLE_yxyx 1, 0, 1, 0 // Select y, then x, then y, then x in that order.
4300#define SHDR_DETAIL_SWIZZLE_yxyy 1, 0, 1, 1 // Select y, then x, then y, then y in that order.
4301#define SHDR_DETAIL_SWIZZLE_yxyz 1, 0, 1, 2 // Select y, then x, then y, then z in that order.
4302#define SHDR_DETAIL_SWIZZLE_yxyw 1, 0, 1, 3 // Select y, then x, then y, then w in that order.
4303#define SHDR_DETAIL_SWIZZLE_yxzx 1, 0, 2, 0 // Select y, then x, then z, then x in that order.
4304#define SHDR_DETAIL_SWIZZLE_yxzy 1, 0, 2, 1 // Select y, then x, then z, then y in that order.
4305#define SHDR_DETAIL_SWIZZLE_yxzz 1, 0, 2, 2 // Select y, then x, then z, then z in that order.
4306#define SHDR_DETAIL_SWIZZLE_yxzw 1, 0, 2, 3 // Select y, then x, then z, then w in that order.
4307#define SHDR_DETAIL_SWIZZLE_yxwx 1, 0, 3, 0 // Select y, then x, then w, then x in that order.
4308#define SHDR_DETAIL_SWIZZLE_yxwy 1, 0, 3, 1 // Select y, then x, then w, then y in that order.
4309#define SHDR_DETAIL_SWIZZLE_yxwz 1, 0, 3, 2 // Select y, then x, then w, then z in that order.
4310#define SHDR_DETAIL_SWIZZLE_yxww 1, 0, 3, 3 // Select y, then x, then w, then w in that order.
4311#define SHDR_DETAIL_SWIZZLE_yyxx 1, 1, 0, 0 // Select y, then y, then x, then x in that order.
4312#define SHDR_DETAIL_SWIZZLE_yyxy 1, 1, 0, 1 // Select y, then y, then x, then y in that order.
4313#define SHDR_DETAIL_SWIZZLE_yyxz 1, 1, 0, 2 // Select y, then y, then x, then z in that order.
4314#define SHDR_DETAIL_SWIZZLE_yyxw 1, 1, 0, 3 // Select y, then y, then x, then w in that order.
4315#define SHDR_DETAIL_SWIZZLE_yyyx 1, 1, 1, 0 // Select y, then y, then y, then x in that order.
4316#define SHDR_DETAIL_SWIZZLE_yyyy 1, 1, 1, 1 // Select y, then y, then y, then y in that order.
4317#define SHDR_DETAIL_SWIZZLE_yyyz 1, 1, 1, 2 // Select y, then y, then y, then z in that order.
4318#define SHDR_DETAIL_SWIZZLE_yyyw 1, 1, 1, 3 // Select y, then y, then y, then w in that order.
4319#define SHDR_DETAIL_SWIZZLE_yyzx 1, 1, 2, 0 // Select y, then y, then z, then x in that order.
4320#define SHDR_DETAIL_SWIZZLE_yyzy 1, 1, 2, 1 // Select y, then y, then z, then y in that order.
4321#define SHDR_DETAIL_SWIZZLE_yyzz 1, 1, 2, 2 // Select y, then y, then z, then z in that order.
4322#define SHDR_DETAIL_SWIZZLE_yyzw 1, 1, 2, 3 // Select y, then y, then z, then w in that order.
4323#define SHDR_DETAIL_SWIZZLE_yywx 1, 1, 3, 0 // Select y, then y, then w, then x in that order.
4324#define SHDR_DETAIL_SWIZZLE_yywy 1, 1, 3, 1 // Select y, then y, then w, then y in that order.
4325#define SHDR_DETAIL_SWIZZLE_yywz 1, 1, 3, 2 // Select y, then y, then w, then z in that order.
4326#define SHDR_DETAIL_SWIZZLE_yyww 1, 1, 3, 3 // Select y, then y, then w, then w in that order.
4327#define SHDR_DETAIL_SWIZZLE_yzxx 1, 2, 0, 0 // Select y, then z, then x, then x in that order.
4328#define SHDR_DETAIL_SWIZZLE_yzxy 1, 2, 0, 1 // Select y, then z, then x, then y in that order.
4329#define SHDR_DETAIL_SWIZZLE_yzxz 1, 2, 0, 2 // Select y, then z, then x, then z in that order.
4330#define SHDR_DETAIL_SWIZZLE_yzxw 1, 2, 0, 3 // Select y, then z, then x, then w in that order.
4331#define SHDR_DETAIL_SWIZZLE_yzyx 1, 2, 1, 0 // Select y, then z, then y, then x in that order.
4332#define SHDR_DETAIL_SWIZZLE_yzyy 1, 2, 1, 1 // Select y, then z, then y, then y in that order.
4333#define SHDR_DETAIL_SWIZZLE_yzyz 1, 2, 1, 2 // Select y, then z, then y, then z in that order.
4334#define SHDR_DETAIL_SWIZZLE_yzyw 1, 2, 1, 3 // Select y, then z, then y, then w in that order.
4335#define SHDR_DETAIL_SWIZZLE_yzzx 1, 2, 2, 0 // Select y, then z, then z, then x in that order.
4336#define SHDR_DETAIL_SWIZZLE_yzzy 1, 2, 2, 1 // Select y, then z, then z, then y in that order.
4337#define SHDR_DETAIL_SWIZZLE_yzzz 1, 2, 2, 2 // Select y, then z, then z, then z in that order.
4338#define SHDR_DETAIL_SWIZZLE_yzzw 1, 2, 2, 3 // Select y, then z, then z, then w in that order.
4339#define SHDR_DETAIL_SWIZZLE_yzwx 1, 2, 3, 0 // Select y, then z, then w, then x in that order.
4340#define SHDR_DETAIL_SWIZZLE_yzwy 1, 2, 3, 1 // Select y, then z, then w, then y in that order.
4341#define SHDR_DETAIL_SWIZZLE_yzwz 1, 2, 3, 2 // Select y, then z, then w, then z in that order.
4342#define SHDR_DETAIL_SWIZZLE_yzww 1, 2, 3, 3 // Select y, then z, then w, then w in that order.
4343#define SHDR_DETAIL_SWIZZLE_ywxx 1, 3, 0, 0 // Select y, then w, then x, then x in that order.
4344#define SHDR_DETAIL_SWIZZLE_ywxy 1, 3, 0, 1 // Select y, then w, then x, then y in that order.
4345#define SHDR_DETAIL_SWIZZLE_ywxz 1, 3, 0, 2 // Select y, then w, then x, then z in that order.
4346#define SHDR_DETAIL_SWIZZLE_ywxw 1, 3, 0, 3 // Select y, then w, then x, then w in that order.
4347#define SHDR_DETAIL_SWIZZLE_ywyx 1, 3, 1, 0 // Select y, then w, then y, then x in that order.
4348#define SHDR_DETAIL_SWIZZLE_ywyy 1, 3, 1, 1 // Select y, then w, then y, then y in that order.
4349#define SHDR_DETAIL_SWIZZLE_ywyz 1, 3, 1, 2 // Select y, then w, then y, then z in that order.
4350#define SHDR_DETAIL_SWIZZLE_ywyw 1, 3, 1, 3 // Select y, then w, then y, then w in that order.
4351#define SHDR_DETAIL_SWIZZLE_ywzx 1, 3, 2, 0 // Select y, then w, then z, then x in that order.
4352#define SHDR_DETAIL_SWIZZLE_ywzy 1, 3, 2, 1 // Select y, then w, then z, then y in that order.
4353#define SHDR_DETAIL_SWIZZLE_ywzz 1, 3, 2, 2 // Select y, then w, then z, then z in that order.
4354#define SHDR_DETAIL_SWIZZLE_ywzw 1, 3, 2, 3 // Select y, then w, then z, then w in that order.
4355#define SHDR_DETAIL_SWIZZLE_ywwx 1, 3, 3, 0 // Select y, then w, then w, then x in that order.
4356#define SHDR_DETAIL_SWIZZLE_ywwy 1, 3, 3, 1 // Select y, then w, then w, then y in that order.
4357#define SHDR_DETAIL_SWIZZLE_ywwz 1, 3, 3, 2 // Select y, then w, then w, then z in that order.
4358#define SHDR_DETAIL_SWIZZLE_ywww 1, 3, 3, 3 // Select y, then w, then w, then w in that order.
4359#define SHDR_DETAIL_SWIZZLE_zxxx 2, 0, 0, 0 // Select z, then x, then x, then x in that order.
4360#define SHDR_DETAIL_SWIZZLE_zxxy 2, 0, 0, 1 // Select z, then x, then x, then y in that order.
4361#define SHDR_DETAIL_SWIZZLE_zxxz 2, 0, 0, 2 // Select z, then x, then x, then z in that order.
4362#define SHDR_DETAIL_SWIZZLE_zxxw 2, 0, 0, 3 // Select z, then x, then x, then w in that order.
4363#define SHDR_DETAIL_SWIZZLE_zxyx 2, 0, 1, 0 // Select z, then x, then y, then x in that order.
4364#define SHDR_DETAIL_SWIZZLE_zxyy 2, 0, 1, 1 // Select z, then x, then y, then y in that order.
4365#define SHDR_DETAIL_SWIZZLE_zxyz 2, 0, 1, 2 // Select z, then x, then y, then z in that order.
4366#define SHDR_DETAIL_SWIZZLE_zxyw 2, 0, 1, 3 // Select z, then x, then y, then w in that order.
4367#define SHDR_DETAIL_SWIZZLE_zxzx 2, 0, 2, 0 // Select z, then x, then z, then x in that order.
4368#define SHDR_DETAIL_SWIZZLE_zxzy 2, 0, 2, 1 // Select z, then x, then z, then y in that order.
4369#define SHDR_DETAIL_SWIZZLE_zxzz 2, 0, 2, 2 // Select z, then x, then z, then z in that order.
4370#define SHDR_DETAIL_SWIZZLE_zxzw 2, 0, 2, 3 // Select z, then x, then z, then w in that order.
4371#define SHDR_DETAIL_SWIZZLE_zxwx 2, 0, 3, 0 // Select z, then x, then w, then x in that order.
4372#define SHDR_DETAIL_SWIZZLE_zxwy 2, 0, 3, 1 // Select z, then x, then w, then y in that order.
4373#define SHDR_DETAIL_SWIZZLE_zxwz 2, 0, 3, 2 // Select z, then x, then w, then z in that order.
4374#define SHDR_DETAIL_SWIZZLE_zxww 2, 0, 3, 3 // Select z, then x, then w, then w in that order.
4375#define SHDR_DETAIL_SWIZZLE_zyxx 2, 1, 0, 0 // Select z, then y, then x, then x in that order.
4376#define SHDR_DETAIL_SWIZZLE_zyxy 2, 1, 0, 1 // Select z, then y, then x, then y in that order.
4377#define SHDR_DETAIL_SWIZZLE_zyxz 2, 1, 0, 2 // Select z, then y, then x, then z in that order.
4378#define SHDR_DETAIL_SWIZZLE_zyxw 2, 1, 0, 3 // Select z, then y, then x, then w in that order.
4379#define SHDR_DETAIL_SWIZZLE_zyyx 2, 1, 1, 0 // Select z, then y, then y, then x in that order.
4380#define SHDR_DETAIL_SWIZZLE_zyyy 2, 1, 1, 1 // Select z, then y, then y, then y in that order.
4381#define SHDR_DETAIL_SWIZZLE_zyyz 2, 1, 1, 2 // Select z, then y, then y, then z in that order.
4382#define SHDR_DETAIL_SWIZZLE_zyyw 2, 1, 1, 3 // Select z, then y, then y, then w in that order.
4383#define SHDR_DETAIL_SWIZZLE_zyzx 2, 1, 2, 0 // Select z, then y, then z, then x in that order.
4384#define SHDR_DETAIL_SWIZZLE_zyzy 2, 1, 2, 1 // Select z, then y, then z, then y in that order.
4385#define SHDR_DETAIL_SWIZZLE_zyzz 2, 1, 2, 2 // Select z, then y, then z, then z in that order.
4386#define SHDR_DETAIL_SWIZZLE_zyzw 2, 1, 2, 3 // Select z, then y, then z, then w in that order.
4387#define SHDR_DETAIL_SWIZZLE_zywx 2, 1, 3, 0 // Select z, then y, then w, then x in that order.
4388#define SHDR_DETAIL_SWIZZLE_zywy 2, 1, 3, 1 // Select z, then y, then w, then y in that order.
4389#define SHDR_DETAIL_SWIZZLE_zywz 2, 1, 3, 2 // Select z, then y, then w, then z in that order.
4390#define SHDR_DETAIL_SWIZZLE_zyww 2, 1, 3, 3 // Select z, then y, then w, then w in that order.
4391#define SHDR_DETAIL_SWIZZLE_zzxx 2, 2, 0, 0 // Select z, then z, then x, then x in that order.
4392#define SHDR_DETAIL_SWIZZLE_zzxy 2, 2, 0, 1 // Select z, then z, then x, then y in that order.
4393#define SHDR_DETAIL_SWIZZLE_zzxz 2, 2, 0, 2 // Select z, then z, then x, then z in that order.
4394#define SHDR_DETAIL_SWIZZLE_zzxw 2, 2, 0, 3 // Select z, then z, then x, then w in that order.
4395#define SHDR_DETAIL_SWIZZLE_zzyx 2, 2, 1, 0 // Select z, then z, then y, then x in that order.
4396#define SHDR_DETAIL_SWIZZLE_zzyy 2, 2, 1, 1 // Select z, then z, then y, then y in that order.
4397#define SHDR_DETAIL_SWIZZLE_zzyz 2, 2, 1, 2 // Select z, then z, then y, then z in that order.
4398#define SHDR_DETAIL_SWIZZLE_zzyw 2, 2, 1, 3 // Select z, then z, then y, then w in that order.
4399#define SHDR_DETAIL_SWIZZLE_zzzx 2, 2, 2, 0 // Select z, then z, then z, then x in that order.
4400#define SHDR_DETAIL_SWIZZLE_zzzy 2, 2, 2, 1 // Select z, then z, then z, then y in that order.
4401#define SHDR_DETAIL_SWIZZLE_zzzz 2, 2, 2, 2 // Select z, then z, then z, then z in that order.
4402#define SHDR_DETAIL_SWIZZLE_zzzw 2, 2, 2, 3 // Select z, then z, then z, then w in that order.
4403#define SHDR_DETAIL_SWIZZLE_zzwx 2, 2, 3, 0 // Select z, then z, then w, then x in that order.
4404#define SHDR_DETAIL_SWIZZLE_zzwy 2, 2, 3, 1 // Select z, then z, then w, then y in that order.
4405#define SHDR_DETAIL_SWIZZLE_zzwz 2, 2, 3, 2 // Select z, then z, then w, then z in that order.
4406#define SHDR_DETAIL_SWIZZLE_zzww 2, 2, 3, 3 // Select z, then z, then w, then w in that order.
4407#define SHDR_DETAIL_SWIZZLE_zwxx 2, 3, 0, 0 // Select z, then w, then x, then x in that order.
4408#define SHDR_DETAIL_SWIZZLE_zwxy 2, 3, 0, 1 // Select z, then w, then x, then y in that order.
4409#define SHDR_DETAIL_SWIZZLE_zwxz 2, 3, 0, 2 // Select z, then w, then x, then z in that order.
4410#define SHDR_DETAIL_SWIZZLE_zwxw 2, 3, 0, 3 // Select z, then w, then x, then w in that order.
4411#define SHDR_DETAIL_SWIZZLE_zwyx 2, 3, 1, 0 // Select z, then w, then y, then x in that order.
4412#define SHDR_DETAIL_SWIZZLE_zwyy 2, 3, 1, 1 // Select z, then w, then y, then y in that order.
4413#define SHDR_DETAIL_SWIZZLE_zwyz 2, 3, 1, 2 // Select z, then w, then y, then z in that order.
4414#define SHDR_DETAIL_SWIZZLE_zwyw 2, 3, 1, 3 // Select z, then w, then y, then w in that order.
4415#define SHDR_DETAIL_SWIZZLE_zwzx 2, 3, 2, 0 // Select z, then w, then z, then x in that order.
4416#define SHDR_DETAIL_SWIZZLE_zwzy 2, 3, 2, 1 // Select z, then w, then z, then y in that order.
4417#define SHDR_DETAIL_SWIZZLE_zwzz 2, 3, 2, 2 // Select z, then w, then z, then z in that order.
4418#define SHDR_DETAIL_SWIZZLE_zwzw 2, 3, 2, 3 // Select z, then w, then z, then w in that order.
4419#define SHDR_DETAIL_SWIZZLE_zwwx 2, 3, 3, 0 // Select z, then w, then w, then x in that order.
4420#define SHDR_DETAIL_SWIZZLE_zwwy 2, 3, 3, 1 // Select z, then w, then w, then y in that order.
4421#define SHDR_DETAIL_SWIZZLE_zwwz 2, 3, 3, 2 // Select z, then w, then w, then z in that order.
4422#define SHDR_DETAIL_SWIZZLE_zwww 2, 3, 3, 3 // Select z, then w, then w, then w in that order.
4423#define SHDR_DETAIL_SWIZZLE_wxxx 3, 0, 0, 0 // Select w, then x, then x, then x in that order.
4424#define SHDR_DETAIL_SWIZZLE_wxxy 3, 0, 0, 1 // Select w, then x, then x, then y in that order.
4425#define SHDR_DETAIL_SWIZZLE_wxxz 3, 0, 0, 2 // Select w, then x, then x, then z in that order.
4426#define SHDR_DETAIL_SWIZZLE_wxxw 3, 0, 0, 3 // Select w, then x, then x, then w in that order.
4427#define SHDR_DETAIL_SWIZZLE_wxyx 3, 0, 1, 0 // Select w, then x, then y, then x in that order.
4428#define SHDR_DETAIL_SWIZZLE_wxyy 3, 0, 1, 1 // Select w, then x, then y, then y in that order.
4429#define SHDR_DETAIL_SWIZZLE_wxyz 3, 0, 1, 2 // Select w, then x, then y, then z in that order.
4430#define SHDR_DETAIL_SWIZZLE_wxyw 3, 0, 1, 3 // Select w, then x, then y, then w in that order.
4431#define SHDR_DETAIL_SWIZZLE_wxzx 3, 0, 2, 0 // Select w, then x, then z, then x in that order.
4432#define SHDR_DETAIL_SWIZZLE_wxzy 3, 0, 2, 1 // Select w, then x, then z, then y in that order.
4433#define SHDR_DETAIL_SWIZZLE_wxzz 3, 0, 2, 2 // Select w, then x, then z, then z in that order.
4434#define SHDR_DETAIL_SWIZZLE_wxzw 3, 0, 2, 3 // Select w, then x, then z, then w in that order.
4435#define SHDR_DETAIL_SWIZZLE_wxwx 3, 0, 3, 0 // Select w, then x, then w, then x in that order.
4436#define SHDR_DETAIL_SWIZZLE_wxwy 3, 0, 3, 1 // Select w, then x, then w, then y in that order.
4437#define SHDR_DETAIL_SWIZZLE_wxwz 3, 0, 3, 2 // Select w, then x, then w, then z in that order.
4438#define SHDR_DETAIL_SWIZZLE_wxww 3, 0, 3, 3 // Select w, then x, then w, then w in that order.
4439#define SHDR_DETAIL_SWIZZLE_wyxx 3, 1, 0, 0 // Select w, then y, then x, then x in that order.
4440#define SHDR_DETAIL_SWIZZLE_wyxy 3, 1, 0, 1 // Select w, then y, then x, then y in that order.
4441#define SHDR_DETAIL_SWIZZLE_wyxz 3, 1, 0, 2 // Select w, then y, then x, then z in that order.
4442#define SHDR_DETAIL_SWIZZLE_wyxw 3, 1, 0, 3 // Select w, then y, then x, then w in that order.
4443#define SHDR_DETAIL_SWIZZLE_wyyx 3, 1, 1, 0 // Select w, then y, then y, then x in that order.
4444#define SHDR_DETAIL_SWIZZLE_wyyy 3, 1, 1, 1 // Select w, then y, then y, then y in that order.
4445#define SHDR_DETAIL_SWIZZLE_wyyz 3, 1, 1, 2 // Select w, then y, then y, then z in that order.
4446#define SHDR_DETAIL_SWIZZLE_wyyw 3, 1, 1, 3 // Select w, then y, then y, then w in that order.
4447#define SHDR_DETAIL_SWIZZLE_wyzx 3, 1, 2, 0 // Select w, then y, then z, then x in that order.
4448#define SHDR_DETAIL_SWIZZLE_wyzy 3, 1, 2, 1 // Select w, then y, then z, then y in that order.
4449#define SHDR_DETAIL_SWIZZLE_wyzz 3, 1, 2, 2 // Select w, then y, then z, then z in that order.
4450#define SHDR_DETAIL_SWIZZLE_wyzw 3, 1, 2, 3 // Select w, then y, then z, then w in that order.
4451#define SHDR_DETAIL_SWIZZLE_wywx 3, 1, 3, 0 // Select w, then y, then w, then x in that order.
4452#define SHDR_DETAIL_SWIZZLE_wywy 3, 1, 3, 1 // Select w, then y, then w, then y in that order.
4453#define SHDR_DETAIL_SWIZZLE_wywz 3, 1, 3, 2 // Select w, then y, then w, then z in that order.
4454#define SHDR_DETAIL_SWIZZLE_wyww 3, 1, 3, 3 // Select w, then y, then w, then w in that order.
4455#define SHDR_DETAIL_SWIZZLE_wzxx 3, 2, 0, 0 // Select w, then z, then x, then x in that order.
4456#define SHDR_DETAIL_SWIZZLE_wzxy 3, 2, 0, 1 // Select w, then z, then x, then y in that order.
4457#define SHDR_DETAIL_SWIZZLE_wzxz 3, 2, 0, 2 // Select w, then z, then x, then z in that order.
4458#define SHDR_DETAIL_SWIZZLE_wzxw 3, 2, 0, 3 // Select w, then z, then x, then w in that order.
4459#define SHDR_DETAIL_SWIZZLE_wzyx 3, 2, 1, 0 // Select w, then z, then y, then x in that order.
4460#define SHDR_DETAIL_SWIZZLE_wzyy 3, 2, 1, 1 // Select w, then z, then y, then y in that order.
4461#define SHDR_DETAIL_SWIZZLE_wzyz 3, 2, 1, 2 // Select w, then z, then y, then z in that order.
4462#define SHDR_DETAIL_SWIZZLE_wzyw 3, 2, 1, 3 // Select w, then z, then y, then w in that order.
4463#define SHDR_DETAIL_SWIZZLE_wzzx 3, 2, 2, 0 // Select w, then z, then z, then x in that order.
4464#define SHDR_DETAIL_SWIZZLE_wzzy 3, 2, 2, 1 // Select w, then z, then z, then y in that order.
4465#define SHDR_DETAIL_SWIZZLE_wzzz 3, 2, 2, 2 // Select w, then z, then z, then z in that order.
4466#define SHDR_DETAIL_SWIZZLE_wzzw 3, 2, 2, 3 // Select w, then z, then z, then w in that order.
4467#define SHDR_DETAIL_SWIZZLE_wzwx 3, 2, 3, 0 // Select w, then z, then w, then x in that order.
4468#define SHDR_DETAIL_SWIZZLE_wzwy 3, 2, 3, 1 // Select w, then z, then w, then y in that order.
4469#define SHDR_DETAIL_SWIZZLE_wzwz 3, 2, 3, 2 // Select w, then z, then w, then z in that order.
4470#define SHDR_DETAIL_SWIZZLE_wzww 3, 2, 3, 3 // Select w, then z, then w, then w in that order.
4471#define SHDR_DETAIL_SWIZZLE_wwxx 3, 3, 0, 0 // Select w, then w, then x, then x in that order.
4472#define SHDR_DETAIL_SWIZZLE_wwxy 3, 3, 0, 1 // Select w, then w, then x, then y in that order.
4473#define SHDR_DETAIL_SWIZZLE_wwxz 3, 3, 0, 2 // Select w, then w, then x, then z in that order.
4474#define SHDR_DETAIL_SWIZZLE_wwxw 3, 3, 0, 3 // Select w, then w, then x, then w in that order.
4475#define SHDR_DETAIL_SWIZZLE_wwyx 3, 3, 1, 0 // Select w, then w, then y, then x in that order.
4476#define SHDR_DETAIL_SWIZZLE_wwyy 3, 3, 1, 1 // Select w, then w, then y, then y in that order.
4477#define SHDR_DETAIL_SWIZZLE_wwyz 3, 3, 1, 2 // Select w, then w, then y, then z in that order.
4478#define SHDR_DETAIL_SWIZZLE_wwyw 3, 3, 1, 3 // Select w, then w, then y, then w in that order.
4479#define SHDR_DETAIL_SWIZZLE_wwzx 3, 3, 2, 0 // Select w, then w, then z, then x in that order.
4480#define SHDR_DETAIL_SWIZZLE_wwzy 3, 3, 2, 1 // Select w, then w, then z, then y in that order.
4481#define SHDR_DETAIL_SWIZZLE_wwzz 3, 3, 2, 2 // Select w, then w, then z, then z in that order.
4482#define SHDR_DETAIL_SWIZZLE_wwzw 3, 3, 2, 3 // Select w, then w, then z, then w in that order.
4483#define SHDR_DETAIL_SWIZZLE_wwwx 3, 3, 3, 0 // Select w, then w, then w, then x in that order.
4484#define SHDR_DETAIL_SWIZZLE_wwwy 3, 3, 3, 1 // Select w, then w, then w, then y in that order.
4485#define SHDR_DETAIL_SWIZZLE_wwwz 3, 3, 3, 2 // Select w, then w, then w, then z in that order.
4486#define SHDR_DETAIL_SWIZZLE_wwww 3, 3, 3, 3 // Select w, then w, then w, then w in that order.
4487#define SHDR_DETAIL_SWIZZLE_r 0 // Select the r component.
4488#define SHDR_DETAIL_SWIZZLE_g 1 // Select the g component.
4489#define SHDR_DETAIL_SWIZZLE_b 2 // Select the b component.
4490#define SHDR_DETAIL_SWIZZLE_a 3 // Select the a component.
4491#define SHDR_DETAIL_SWIZZLE_rr 0, 0 // Select r, then r in that order.
4492#define SHDR_DETAIL_SWIZZLE_rg 0, 1 // Select r, then g in that order.
4493#define SHDR_DETAIL_SWIZZLE_rb 0, 2 // Select r, then b in that order.
4494#define SHDR_DETAIL_SWIZZLE_ra 0, 3 // Select r, then a in that order.
4495#define SHDR_DETAIL_SWIZZLE_gr 1, 0 // Select g, then r in that order.
4496#define SHDR_DETAIL_SWIZZLE_gg 1, 1 // Select g, then g in that order.
4497#define SHDR_DETAIL_SWIZZLE_gb 1, 2 // Select g, then b in that order.
4498#define SHDR_DETAIL_SWIZZLE_ga 1, 3 // Select g, then a in that order.
4499#define SHDR_DETAIL_SWIZZLE_br 2, 0 // Select b, then r in that order.
4500#define SHDR_DETAIL_SWIZZLE_bg 2, 1 // Select b, then g in that order.
4501#define SHDR_DETAIL_SWIZZLE_bb 2, 2 // Select b, then b in that order.
4502#define SHDR_DETAIL_SWIZZLE_ba 2, 3 // Select b, then a in that order.
4503#define SHDR_DETAIL_SWIZZLE_ar 3, 0 // Select a, then r in that order.
4504#define SHDR_DETAIL_SWIZZLE_ag 3, 1 // Select a, then g in that order.
4505#define SHDR_DETAIL_SWIZZLE_ab 3, 2 // Select a, then b in that order.
4506#define SHDR_DETAIL_SWIZZLE_aa 3, 3 // Select a, then a in that order.
4507#define SHDR_DETAIL_SWIZZLE_rrr 0, 0, 0 // Select r, then r, then r in that order.
4508#define SHDR_DETAIL_SWIZZLE_rrg 0, 0, 1 // Select r, then r, then g in that order.
4509#define SHDR_DETAIL_SWIZZLE_rrb 0, 0, 2 // Select r, then r, then b in that order.
4510#define SHDR_DETAIL_SWIZZLE_rra 0, 0, 3 // Select r, then r, then a in that order.
4511#define SHDR_DETAIL_SWIZZLE_rgr 0, 1, 0 // Select r, then g, then r in that order.
4512#define SHDR_DETAIL_SWIZZLE_rgg 0, 1, 1 // Select r, then g, then g in that order.
4513#define SHDR_DETAIL_SWIZZLE_rgb 0, 1, 2 // Select r, then g, then b in that order.
4514#define SHDR_DETAIL_SWIZZLE_rga 0, 1, 3 // Select r, then g, then a in that order.
4515#define SHDR_DETAIL_SWIZZLE_rbr 0, 2, 0 // Select r, then b, then r in that order.
4516#define SHDR_DETAIL_SWIZZLE_rbg 0, 2, 1 // Select r, then b, then g in that order.
4517#define SHDR_DETAIL_SWIZZLE_rbb 0, 2, 2 // Select r, then b, then b in that order.
4518#define SHDR_DETAIL_SWIZZLE_rba 0, 2, 3 // Select r, then b, then a in that order.
4519#define SHDR_DETAIL_SWIZZLE_rar 0, 3, 0 // Select r, then a, then r in that order.
4520#define SHDR_DETAIL_SWIZZLE_rag 0, 3, 1 // Select r, then a, then g in that order.
4521#define SHDR_DETAIL_SWIZZLE_rab 0, 3, 2 // Select r, then a, then b in that order.
4522#define SHDR_DETAIL_SWIZZLE_raa 0, 3, 3 // Select r, then a, then a in that order.
4523#define SHDR_DETAIL_SWIZZLE_grr 1, 0, 0 // Select g, then r, then r in that order.
4524#define SHDR_DETAIL_SWIZZLE_grg 1, 0, 1 // Select g, then r, then g in that order.
4525#define SHDR_DETAIL_SWIZZLE_grb 1, 0, 2 // Select g, then r, then b in that order.
4526#define SHDR_DETAIL_SWIZZLE_gra 1, 0, 3 // Select g, then r, then a in that order.
4527#define SHDR_DETAIL_SWIZZLE_ggr 1, 1, 0 // Select g, then g, then r in that order.
4528#define SHDR_DETAIL_SWIZZLE_ggg 1, 1, 1 // Select g, then g, then g in that order.
4529#define SHDR_DETAIL_SWIZZLE_ggb 1, 1, 2 // Select g, then g, then b in that order.
4530#define SHDR_DETAIL_SWIZZLE_gga 1, 1, 3 // Select g, then g, then a in that order.
4531#define SHDR_DETAIL_SWIZZLE_gbr 1, 2, 0 // Select g, then b, then r in that order.
4532#define SHDR_DETAIL_SWIZZLE_gbg 1, 2, 1 // Select g, then b, then g in that order.
4533#define SHDR_DETAIL_SWIZZLE_gbb 1, 2, 2 // Select g, then b, then b in that order.
4534#define SHDR_DETAIL_SWIZZLE_gba 1, 2, 3 // Select g, then b, then a in that order.
4535#define SHDR_DETAIL_SWIZZLE_gar 1, 3, 0 // Select g, then a, then r in that order.
4536#define SHDR_DETAIL_SWIZZLE_gag 1, 3, 1 // Select g, then a, then g in that order.
4537#define SHDR_DETAIL_SWIZZLE_gab 1, 3, 2 // Select g, then a, then b in that order.
4538#define SHDR_DETAIL_SWIZZLE_gaa 1, 3, 3 // Select g, then a, then a in that order.
4539#define SHDR_DETAIL_SWIZZLE_brr 2, 0, 0 // Select b, then r, then r in that order.
4540#define SHDR_DETAIL_SWIZZLE_brg 2, 0, 1 // Select b, then r, then g in that order.
4541#define SHDR_DETAIL_SWIZZLE_brb 2, 0, 2 // Select b, then r, then b in that order.
4542#define SHDR_DETAIL_SWIZZLE_bra 2, 0, 3 // Select b, then r, then a in that order.
4543#define SHDR_DETAIL_SWIZZLE_bgr 2, 1, 0 // Select b, then g, then r in that order.
4544#define SHDR_DETAIL_SWIZZLE_bgg 2, 1, 1 // Select b, then g, then g in that order.
4545#define SHDR_DETAIL_SWIZZLE_bgb 2, 1, 2 // Select b, then g, then b in that order.
4546#define SHDR_DETAIL_SWIZZLE_bga 2, 1, 3 // Select b, then g, then a in that order.
4547#define SHDR_DETAIL_SWIZZLE_bbr 2, 2, 0 // Select b, then b, then r in that order.
4548#define SHDR_DETAIL_SWIZZLE_bbg 2, 2, 1 // Select b, then b, then g in that order.
4549#define SHDR_DETAIL_SWIZZLE_bbb 2, 2, 2 // Select b, then b, then b in that order.
4550#define SHDR_DETAIL_SWIZZLE_bba 2, 2, 3 // Select b, then b, then a in that order.
4551#define SHDR_DETAIL_SWIZZLE_bar 2, 3, 0 // Select b, then a, then r in that order.
4552#define SHDR_DETAIL_SWIZZLE_bag 2, 3, 1 // Select b, then a, then g in that order.
4553#define SHDR_DETAIL_SWIZZLE_bab 2, 3, 2 // Select b, then a, then b in that order.
4554#define SHDR_DETAIL_SWIZZLE_baa 2, 3, 3 // Select b, then a, then a in that order.
4555#define SHDR_DETAIL_SWIZZLE_arr 3, 0, 0 // Select a, then r, then r in that order.
4556#define SHDR_DETAIL_SWIZZLE_arg 3, 0, 1 // Select a, then r, then g in that order.
4557#define SHDR_DETAIL_SWIZZLE_arb 3, 0, 2 // Select a, then r, then b in that order.
4558#define SHDR_DETAIL_SWIZZLE_ara 3, 0, 3 // Select a, then r, then a in that order.
4559#define SHDR_DETAIL_SWIZZLE_agr 3, 1, 0 // Select a, then g, then r in that order.
4560#define SHDR_DETAIL_SWIZZLE_agg 3, 1, 1 // Select a, then g, then g in that order.
4561#define SHDR_DETAIL_SWIZZLE_agb 3, 1, 2 // Select a, then g, then b in that order.
4562#define SHDR_DETAIL_SWIZZLE_aga 3, 1, 3 // Select a, then g, then a in that order.
4563#define SHDR_DETAIL_SWIZZLE_abr 3, 2, 0 // Select a, then b, then r in that order.
4564#define SHDR_DETAIL_SWIZZLE_abg 3, 2, 1 // Select a, then b, then g in that order.
4565#define SHDR_DETAIL_SWIZZLE_abb 3, 2, 2 // Select a, then b, then b in that order.
4566#define SHDR_DETAIL_SWIZZLE_aba 3, 2, 3 // Select a, then b, then a in that order.
4567#define SHDR_DETAIL_SWIZZLE_aar 3, 3, 0 // Select a, then a, then r in that order.
4568#define SHDR_DETAIL_SWIZZLE_aag 3, 3, 1 // Select a, then a, then g in that order.
4569#define SHDR_DETAIL_SWIZZLE_aab 3, 3, 2 // Select a, then a, then b in that order.
4570#define SHDR_DETAIL_SWIZZLE_aaa 3, 3, 3 // Select a, then a, then a in that order.
4571#define SHDR_DETAIL_SWIZZLE_rrrr 0, 0, 0, 0 // Select r, then r, then r, then r in that order.
4572#define SHDR_DETAIL_SWIZZLE_rrrg 0, 0, 0, 1 // Select r, then r, then r, then g in that order.
4573#define SHDR_DETAIL_SWIZZLE_rrrb 0, 0, 0, 2 // Select r, then r, then r, then b in that order.
4574#define SHDR_DETAIL_SWIZZLE_rrra 0, 0, 0, 3 // Select r, then r, then r, then a in that order.
4575#define SHDR_DETAIL_SWIZZLE_rrgr 0, 0, 1, 0 // Select r, then r, then g, then r in that order.
4576#define SHDR_DETAIL_SWIZZLE_rrgg 0, 0, 1, 1 // Select r, then r, then g, then g in that order.
4577#define SHDR_DETAIL_SWIZZLE_rrgb 0, 0, 1, 2 // Select r, then r, then g, then b in that order.
4578#define SHDR_DETAIL_SWIZZLE_rrga 0, 0, 1, 3 // Select r, then r, then g, then a in that order.
4579#define SHDR_DETAIL_SWIZZLE_rrbr 0, 0, 2, 0 // Select r, then r, then b, then r in that order.
4580#define SHDR_DETAIL_SWIZZLE_rrbg 0, 0, 2, 1 // Select r, then r, then b, then g in that order.
4581#define SHDR_DETAIL_SWIZZLE_rrbb 0, 0, 2, 2 // Select r, then r, then b, then b in that order.
4582#define SHDR_DETAIL_SWIZZLE_rrba 0, 0, 2, 3 // Select r, then r, then b, then a in that order.
4583#define SHDR_DETAIL_SWIZZLE_rrar 0, 0, 3, 0 // Select r, then r, then a, then r in that order.
4584#define SHDR_DETAIL_SWIZZLE_rrag 0, 0, 3, 1 // Select r, then r, then a, then g in that order.
4585#define SHDR_DETAIL_SWIZZLE_rrab 0, 0, 3, 2 // Select r, then r, then a, then b in that order.
4586#define SHDR_DETAIL_SWIZZLE_rraa 0, 0, 3, 3 // Select r, then r, then a, then a in that order.
4587#define SHDR_DETAIL_SWIZZLE_rgrr 0, 1, 0, 0 // Select r, then g, then r, then r in that order.
4588#define SHDR_DETAIL_SWIZZLE_rgrg 0, 1, 0, 1 // Select r, then g, then r, then g in that order.
4589#define SHDR_DETAIL_SWIZZLE_rgrb 0, 1, 0, 2 // Select r, then g, then r, then b in that order.
4590#define SHDR_DETAIL_SWIZZLE_rgra 0, 1, 0, 3 // Select r, then g, then r, then a in that order.
4591#define SHDR_DETAIL_SWIZZLE_rggr 0, 1, 1, 0 // Select r, then g, then g, then r in that order.
4592#define SHDR_DETAIL_SWIZZLE_rggg 0, 1, 1, 1 // Select r, then g, then g, then g in that order.
4593#define SHDR_DETAIL_SWIZZLE_rggb 0, 1, 1, 2 // Select r, then g, then g, then b in that order.
4594#define SHDR_DETAIL_SWIZZLE_rgga 0, 1, 1, 3 // Select r, then g, then g, then a in that order.
4595#define SHDR_DETAIL_SWIZZLE_rgbr 0, 1, 2, 0 // Select r, then g, then b, then r in that order.
4596#define SHDR_DETAIL_SWIZZLE_rgbg 0, 1, 2, 1 // Select r, then g, then b, then g in that order.
4597#define SHDR_DETAIL_SWIZZLE_rgbb 0, 1, 2, 2 // Select r, then g, then b, then b in that order.
4598#define SHDR_DETAIL_SWIZZLE_rgba 0, 1, 2, 3 // Select r, then g, then b, then a in that order.
4599#define SHDR_DETAIL_SWIZZLE_rgar 0, 1, 3, 0 // Select r, then g, then a, then r in that order.
4600#define SHDR_DETAIL_SWIZZLE_rgag 0, 1, 3, 1 // Select r, then g, then a, then g in that order.
4601#define SHDR_DETAIL_SWIZZLE_rgab 0, 1, 3, 2 // Select r, then g, then a, then b in that order.
4602#define SHDR_DETAIL_SWIZZLE_rgaa 0, 1, 3, 3 // Select r, then g, then a, then a in that order.
4603#define SHDR_DETAIL_SWIZZLE_rbrr 0, 2, 0, 0 // Select r, then b, then r, then r in that order.
4604#define SHDR_DETAIL_SWIZZLE_rbrg 0, 2, 0, 1 // Select r, then b, then r, then g in that order.
4605#define SHDR_DETAIL_SWIZZLE_rbrb 0, 2, 0, 2 // Select r, then b, then r, then b in that order.
4606#define SHDR_DETAIL_SWIZZLE_rbra 0, 2, 0, 3 // Select r, then b, then r, then a in that order.
4607#define SHDR_DETAIL_SWIZZLE_rbgr 0, 2, 1, 0 // Select r, then b, then g, then r in that order.
4608#define SHDR_DETAIL_SWIZZLE_rbgg 0, 2, 1, 1 // Select r, then b, then g, then g in that order.
4609#define SHDR_DETAIL_SWIZZLE_rbgb 0, 2, 1, 2 // Select r, then b, then g, then b in that order.
4610#define SHDR_DETAIL_SWIZZLE_rbga 0, 2, 1, 3 // Select r, then b, then g, then a in that order.
4611#define SHDR_DETAIL_SWIZZLE_rbbr 0, 2, 2, 0 // Select r, then b, then b, then r in that order.
4612#define SHDR_DETAIL_SWIZZLE_rbbg 0, 2, 2, 1 // Select r, then b, then b, then g in that order.
4613#define SHDR_DETAIL_SWIZZLE_rbbb 0, 2, 2, 2 // Select r, then b, then b, then b in that order.
4614#define SHDR_DETAIL_SWIZZLE_rbba 0, 2, 2, 3 // Select r, then b, then b, then a in that order.
4615#define SHDR_DETAIL_SWIZZLE_rbar 0, 2, 3, 0 // Select r, then b, then a, then r in that order.
4616#define SHDR_DETAIL_SWIZZLE_rbag 0, 2, 3, 1 // Select r, then b, then a, then g in that order.
4617#define SHDR_DETAIL_SWIZZLE_rbab 0, 2, 3, 2 // Select r, then b, then a, then b in that order.
4618#define SHDR_DETAIL_SWIZZLE_rbaa 0, 2, 3, 3 // Select r, then b, then a, then a in that order.
4619#define SHDR_DETAIL_SWIZZLE_rarr 0, 3, 0, 0 // Select r, then a, then r, then r in that order.
4620#define SHDR_DETAIL_SWIZZLE_rarg 0, 3, 0, 1 // Select r, then a, then r, then g in that order.
4621#define SHDR_DETAIL_SWIZZLE_rarb 0, 3, 0, 2 // Select r, then a, then r, then b in that order.
4622#define SHDR_DETAIL_SWIZZLE_rara 0, 3, 0, 3 // Select r, then a, then r, then a in that order.
4623#define SHDR_DETAIL_SWIZZLE_ragr 0, 3, 1, 0 // Select r, then a, then g, then r in that order.
4624#define SHDR_DETAIL_SWIZZLE_ragg 0, 3, 1, 1 // Select r, then a, then g, then g in that order.
4625#define SHDR_DETAIL_SWIZZLE_ragb 0, 3, 1, 2 // Select r, then a, then g, then b in that order.
4626#define SHDR_DETAIL_SWIZZLE_raga 0, 3, 1, 3 // Select r, then a, then g, then a in that order.
4627#define SHDR_DETAIL_SWIZZLE_rabr 0, 3, 2, 0 // Select r, then a, then b, then r in that order.
4628#define SHDR_DETAIL_SWIZZLE_rabg 0, 3, 2, 1 // Select r, then a, then b, then g in that order.
4629#define SHDR_DETAIL_SWIZZLE_rabb 0, 3, 2, 2 // Select r, then a, then b, then b in that order.
4630#define SHDR_DETAIL_SWIZZLE_raba 0, 3, 2, 3 // Select r, then a, then b, then a in that order.
4631#define SHDR_DETAIL_SWIZZLE_raar 0, 3, 3, 0 // Select r, then a, then a, then r in that order.
4632#define SHDR_DETAIL_SWIZZLE_raag 0, 3, 3, 1 // Select r, then a, then a, then g in that order.
4633#define SHDR_DETAIL_SWIZZLE_raab 0, 3, 3, 2 // Select r, then a, then a, then b in that order.
4634#define SHDR_DETAIL_SWIZZLE_raaa 0, 3, 3, 3 // Select r, then a, then a, then a in that order.
4635#define SHDR_DETAIL_SWIZZLE_grrr 1, 0, 0, 0 // Select g, then r, then r, then r in that order.
4636#define SHDR_DETAIL_SWIZZLE_grrg 1, 0, 0, 1 // Select g, then r, then r, then g in that order.
4637#define SHDR_DETAIL_SWIZZLE_grrb 1, 0, 0, 2 // Select g, then r, then r, then b in that order.
4638#define SHDR_DETAIL_SWIZZLE_grra 1, 0, 0, 3 // Select g, then r, then r, then a in that order.
4639#define SHDR_DETAIL_SWIZZLE_grgr 1, 0, 1, 0 // Select g, then r, then g, then r in that order.
4640#define SHDR_DETAIL_SWIZZLE_grgg 1, 0, 1, 1 // Select g, then r, then g, then g in that order.
4641#define SHDR_DETAIL_SWIZZLE_grgb 1, 0, 1, 2 // Select g, then r, then g, then b in that order.
4642#define SHDR_DETAIL_SWIZZLE_grga 1, 0, 1, 3 // Select g, then r, then g, then a in that order.
4643#define SHDR_DETAIL_SWIZZLE_grbr 1, 0, 2, 0 // Select g, then r, then b, then r in that order.
4644#define SHDR_DETAIL_SWIZZLE_grbg 1, 0, 2, 1 // Select g, then r, then b, then g in that order.
4645#define SHDR_DETAIL_SWIZZLE_grbb 1, 0, 2, 2 // Select g, then r, then b, then b in that order.
4646#define SHDR_DETAIL_SWIZZLE_grba 1, 0, 2, 3 // Select g, then r, then b, then a in that order.
4647#define SHDR_DETAIL_SWIZZLE_grar 1, 0, 3, 0 // Select g, then r, then a, then r in that order.
4648#define SHDR_DETAIL_SWIZZLE_grag 1, 0, 3, 1 // Select g, then r, then a, then g in that order.
4649#define SHDR_DETAIL_SWIZZLE_grab 1, 0, 3, 2 // Select g, then r, then a, then b in that order.
4650#define SHDR_DETAIL_SWIZZLE_graa 1, 0, 3, 3 // Select g, then r, then a, then a in that order.
4651#define SHDR_DETAIL_SWIZZLE_ggrr 1, 1, 0, 0 // Select g, then g, then r, then r in that order.
4652#define SHDR_DETAIL_SWIZZLE_ggrg 1, 1, 0, 1 // Select g, then g, then r, then g in that order.
4653#define SHDR_DETAIL_SWIZZLE_ggrb 1, 1, 0, 2 // Select g, then g, then r, then b in that order.
4654#define SHDR_DETAIL_SWIZZLE_ggra 1, 1, 0, 3 // Select g, then g, then r, then a in that order.
4655#define SHDR_DETAIL_SWIZZLE_gggr 1, 1, 1, 0 // Select g, then g, then g, then r in that order.
4656#define SHDR_DETAIL_SWIZZLE_gggg 1, 1, 1, 1 // Select g, then g, then g, then g in that order.
4657#define SHDR_DETAIL_SWIZZLE_gggb 1, 1, 1, 2 // Select g, then g, then g, then b in that order.
4658#define SHDR_DETAIL_SWIZZLE_ggga 1, 1, 1, 3 // Select g, then g, then g, then a in that order.
4659#define SHDR_DETAIL_SWIZZLE_ggbr 1, 1, 2, 0 // Select g, then g, then b, then r in that order.
4660#define SHDR_DETAIL_SWIZZLE_ggbg 1, 1, 2, 1 // Select g, then g, then b, then g in that order.
4661#define SHDR_DETAIL_SWIZZLE_ggbb 1, 1, 2, 2 // Select g, then g, then b, then b in that order.
4662#define SHDR_DETAIL_SWIZZLE_ggba 1, 1, 2, 3 // Select g, then g, then b, then a in that order.
4663#define SHDR_DETAIL_SWIZZLE_ggar 1, 1, 3, 0 // Select g, then g, then a, then r in that order.
4664#define SHDR_DETAIL_SWIZZLE_ggag 1, 1, 3, 1 // Select g, then g, then a, then g in that order.
4665#define SHDR_DETAIL_SWIZZLE_ggab 1, 1, 3, 2 // Select g, then g, then a, then b in that order.
4666#define SHDR_DETAIL_SWIZZLE_ggaa 1, 1, 3, 3 // Select g, then g, then a, then a in that order.
4667#define SHDR_DETAIL_SWIZZLE_gbrr 1, 2, 0, 0 // Select g, then b, then r, then r in that order.
4668#define SHDR_DETAIL_SWIZZLE_gbrg 1, 2, 0, 1 // Select g, then b, then r, then g in that order.
4669#define SHDR_DETAIL_SWIZZLE_gbrb 1, 2, 0, 2 // Select g, then b, then r, then b in that order.
4670#define SHDR_DETAIL_SWIZZLE_gbra 1, 2, 0, 3 // Select g, then b, then r, then a in that order.
4671#define SHDR_DETAIL_SWIZZLE_gbgr 1, 2, 1, 0 // Select g, then b, then g, then r in that order.
4672#define SHDR_DETAIL_SWIZZLE_gbgg 1, 2, 1, 1 // Select g, then b, then g, then g in that order.
4673#define SHDR_DETAIL_SWIZZLE_gbgb 1, 2, 1, 2 // Select g, then b, then g, then b in that order.
4674#define SHDR_DETAIL_SWIZZLE_gbga 1, 2, 1, 3 // Select g, then b, then g, then a in that order.
4675#define SHDR_DETAIL_SWIZZLE_gbbr 1, 2, 2, 0 // Select g, then b, then b, then r in that order.
4676#define SHDR_DETAIL_SWIZZLE_gbbg 1, 2, 2, 1 // Select g, then b, then b, then g in that order.
4677#define SHDR_DETAIL_SWIZZLE_gbbb 1, 2, 2, 2 // Select g, then b, then b, then b in that order.
4678#define SHDR_DETAIL_SWIZZLE_gbba 1, 2, 2, 3 // Select g, then b, then b, then a in that order.
4679#define SHDR_DETAIL_SWIZZLE_gbar 1, 2, 3, 0 // Select g, then b, then a, then r in that order.
4680#define SHDR_DETAIL_SWIZZLE_gbag 1, 2, 3, 1 // Select g, then b, then a, then g in that order.
4681#define SHDR_DETAIL_SWIZZLE_gbab 1, 2, 3, 2 // Select g, then b, then a, then b in that order.
4682#define SHDR_DETAIL_SWIZZLE_gbaa 1, 2, 3, 3 // Select g, then b, then a, then a in that order.
4683#define SHDR_DETAIL_SWIZZLE_garr 1, 3, 0, 0 // Select g, then a, then r, then r in that order.
4684#define SHDR_DETAIL_SWIZZLE_garg 1, 3, 0, 1 // Select g, then a, then r, then g in that order.
4685#define SHDR_DETAIL_SWIZZLE_garb 1, 3, 0, 2 // Select g, then a, then r, then b in that order.
4686#define SHDR_DETAIL_SWIZZLE_gara 1, 3, 0, 3 // Select g, then a, then r, then a in that order.
4687#define SHDR_DETAIL_SWIZZLE_gagr 1, 3, 1, 0 // Select g, then a, then g, then r in that order.
4688#define SHDR_DETAIL_SWIZZLE_gagg 1, 3, 1, 1 // Select g, then a, then g, then g in that order.
4689#define SHDR_DETAIL_SWIZZLE_gagb 1, 3, 1, 2 // Select g, then a, then g, then b in that order.
4690#define SHDR_DETAIL_SWIZZLE_gaga 1, 3, 1, 3 // Select g, then a, then g, then a in that order.
4691#define SHDR_DETAIL_SWIZZLE_gabr 1, 3, 2, 0 // Select g, then a, then b, then r in that order.
4692#define SHDR_DETAIL_SWIZZLE_gabg 1, 3, 2, 1 // Select g, then a, then b, then g in that order.
4693#define SHDR_DETAIL_SWIZZLE_gabb 1, 3, 2, 2 // Select g, then a, then b, then b in that order.
4694#define SHDR_DETAIL_SWIZZLE_gaba 1, 3, 2, 3 // Select g, then a, then b, then a in that order.
4695#define SHDR_DETAIL_SWIZZLE_gaar 1, 3, 3, 0 // Select g, then a, then a, then r in that order.
4696#define SHDR_DETAIL_SWIZZLE_gaag 1, 3, 3, 1 // Select g, then a, then a, then g in that order.
4697#define SHDR_DETAIL_SWIZZLE_gaab 1, 3, 3, 2 // Select g, then a, then a, then b in that order.
4698#define SHDR_DETAIL_SWIZZLE_gaaa 1, 3, 3, 3 // Select g, then a, then a, then a in that order.
4699#define SHDR_DETAIL_SWIZZLE_brrr 2, 0, 0, 0 // Select b, then r, then r, then r in that order.
4700#define SHDR_DETAIL_SWIZZLE_brrg 2, 0, 0, 1 // Select b, then r, then r, then g in that order.
4701#define SHDR_DETAIL_SWIZZLE_brrb 2, 0, 0, 2 // Select b, then r, then r, then b in that order.
4702#define SHDR_DETAIL_SWIZZLE_brra 2, 0, 0, 3 // Select b, then r, then r, then a in that order.
4703#define SHDR_DETAIL_SWIZZLE_brgr 2, 0, 1, 0 // Select b, then r, then g, then r in that order.
4704#define SHDR_DETAIL_SWIZZLE_brgg 2, 0, 1, 1 // Select b, then r, then g, then g in that order.
4705#define SHDR_DETAIL_SWIZZLE_brgb 2, 0, 1, 2 // Select b, then r, then g, then b in that order.
4706#define SHDR_DETAIL_SWIZZLE_brga 2, 0, 1, 3 // Select b, then r, then g, then a in that order.
4707#define SHDR_DETAIL_SWIZZLE_brbr 2, 0, 2, 0 // Select b, then r, then b, then r in that order.
4708#define SHDR_DETAIL_SWIZZLE_brbg 2, 0, 2, 1 // Select b, then r, then b, then g in that order.
4709#define SHDR_DETAIL_SWIZZLE_brbb 2, 0, 2, 2 // Select b, then r, then b, then b in that order.
4710#define SHDR_DETAIL_SWIZZLE_brba 2, 0, 2, 3 // Select b, then r, then b, then a in that order.
4711#define SHDR_DETAIL_SWIZZLE_brar 2, 0, 3, 0 // Select b, then r, then a, then r in that order.
4712#define SHDR_DETAIL_SWIZZLE_brag 2, 0, 3, 1 // Select b, then r, then a, then g in that order.
4713#define SHDR_DETAIL_SWIZZLE_brab 2, 0, 3, 2 // Select b, then r, then a, then b in that order.
4714#define SHDR_DETAIL_SWIZZLE_braa 2, 0, 3, 3 // Select b, then r, then a, then a in that order.
4715#define SHDR_DETAIL_SWIZZLE_bgrr 2, 1, 0, 0 // Select b, then g, then r, then r in that order.
4716#define SHDR_DETAIL_SWIZZLE_bgrg 2, 1, 0, 1 // Select b, then g, then r, then g in that order.
4717#define SHDR_DETAIL_SWIZZLE_bgrb 2, 1, 0, 2 // Select b, then g, then r, then b in that order.
4718#define SHDR_DETAIL_SWIZZLE_bgra 2, 1, 0, 3 // Select b, then g, then r, then a in that order.
4719#define SHDR_DETAIL_SWIZZLE_bggr 2, 1, 1, 0 // Select b, then g, then g, then r in that order.
4720#define SHDR_DETAIL_SWIZZLE_bggg 2, 1, 1, 1 // Select b, then g, then g, then g in that order.
4721#define SHDR_DETAIL_SWIZZLE_bggb 2, 1, 1, 2 // Select b, then g, then g, then b in that order.
4722#define SHDR_DETAIL_SWIZZLE_bgga 2, 1, 1, 3 // Select b, then g, then g, then a in that order.
4723#define SHDR_DETAIL_SWIZZLE_bgbr 2, 1, 2, 0 // Select b, then g, then b, then r in that order.
4724#define SHDR_DETAIL_SWIZZLE_bgbg 2, 1, 2, 1 // Select b, then g, then b, then g in that order.
4725#define SHDR_DETAIL_SWIZZLE_bgbb 2, 1, 2, 2 // Select b, then g, then b, then b in that order.
4726#define SHDR_DETAIL_SWIZZLE_bgba 2, 1, 2, 3 // Select b, then g, then b, then a in that order.
4727#define SHDR_DETAIL_SWIZZLE_bgar 2, 1, 3, 0 // Select b, then g, then a, then r in that order.
4728#define SHDR_DETAIL_SWIZZLE_bgag 2, 1, 3, 1 // Select b, then g, then a, then g in that order.
4729#define SHDR_DETAIL_SWIZZLE_bgab 2, 1, 3, 2 // Select b, then g, then a, then b in that order.
4730#define SHDR_DETAIL_SWIZZLE_bgaa 2, 1, 3, 3 // Select b, then g, then a, then a in that order.
4731#define SHDR_DETAIL_SWIZZLE_bbrr 2, 2, 0, 0 // Select b, then b, then r, then r in that order.
4732#define SHDR_DETAIL_SWIZZLE_bbrg 2, 2, 0, 1 // Select b, then b, then r, then g in that order.
4733#define SHDR_DETAIL_SWIZZLE_bbrb 2, 2, 0, 2 // Select b, then b, then r, then b in that order.
4734#define SHDR_DETAIL_SWIZZLE_bbra 2, 2, 0, 3 // Select b, then b, then r, then a in that order.
4735#define SHDR_DETAIL_SWIZZLE_bbgr 2, 2, 1, 0 // Select b, then b, then g, then r in that order.
4736#define SHDR_DETAIL_SWIZZLE_bbgg 2, 2, 1, 1 // Select b, then b, then g, then g in that order.
4737#define SHDR_DETAIL_SWIZZLE_bbgb 2, 2, 1, 2 // Select b, then b, then g, then b in that order.
4738#define SHDR_DETAIL_SWIZZLE_bbga 2, 2, 1, 3 // Select b, then b, then g, then a in that order.
4739#define SHDR_DETAIL_SWIZZLE_bbbr 2, 2, 2, 0 // Select b, then b, then b, then r in that order.
4740#define SHDR_DETAIL_SWIZZLE_bbbg 2, 2, 2, 1 // Select b, then b, then b, then g in that order.
4741#define SHDR_DETAIL_SWIZZLE_bbbb 2, 2, 2, 2 // Select b, then b, then b, then b in that order.
4742#define SHDR_DETAIL_SWIZZLE_bbba 2, 2, 2, 3 // Select b, then b, then b, then a in that order.
4743#define SHDR_DETAIL_SWIZZLE_bbar 2, 2, 3, 0 // Select b, then b, then a, then r in that order.
4744#define SHDR_DETAIL_SWIZZLE_bbag 2, 2, 3, 1 // Select b, then b, then a, then g in that order.
4745#define SHDR_DETAIL_SWIZZLE_bbab 2, 2, 3, 2 // Select b, then b, then a, then b in that order.
4746#define SHDR_DETAIL_SWIZZLE_bbaa 2, 2, 3, 3 // Select b, then b, then a, then a in that order.
4747#define SHDR_DETAIL_SWIZZLE_barr 2, 3, 0, 0 // Select b, then a, then r, then r in that order.
4748#define SHDR_DETAIL_SWIZZLE_barg 2, 3, 0, 1 // Select b, then a, then r, then g in that order.
4749#define SHDR_DETAIL_SWIZZLE_barb 2, 3, 0, 2 // Select b, then a, then r, then b in that order.
4750#define SHDR_DETAIL_SWIZZLE_bara 2, 3, 0, 3 // Select b, then a, then r, then a in that order.
4751#define SHDR_DETAIL_SWIZZLE_bagr 2, 3, 1, 0 // Select b, then a, then g, then r in that order.
4752#define SHDR_DETAIL_SWIZZLE_bagg 2, 3, 1, 1 // Select b, then a, then g, then g in that order.
4753#define SHDR_DETAIL_SWIZZLE_bagb 2, 3, 1, 2 // Select b, then a, then g, then b in that order.
4754#define SHDR_DETAIL_SWIZZLE_baga 2, 3, 1, 3 // Select b, then a, then g, then a in that order.
4755#define SHDR_DETAIL_SWIZZLE_babr 2, 3, 2, 0 // Select b, then a, then b, then r in that order.
4756#define SHDR_DETAIL_SWIZZLE_babg 2, 3, 2, 1 // Select b, then a, then b, then g in that order.
4757#define SHDR_DETAIL_SWIZZLE_babb 2, 3, 2, 2 // Select b, then a, then b, then b in that order.
4758#define SHDR_DETAIL_SWIZZLE_baba 2, 3, 2, 3 // Select b, then a, then b, then a in that order.
4759#define SHDR_DETAIL_SWIZZLE_baar 2, 3, 3, 0 // Select b, then a, then a, then r in that order.
4760#define SHDR_DETAIL_SWIZZLE_baag 2, 3, 3, 1 // Select b, then a, then a, then g in that order.
4761#define SHDR_DETAIL_SWIZZLE_baab 2, 3, 3, 2 // Select b, then a, then a, then b in that order.
4762#define SHDR_DETAIL_SWIZZLE_baaa 2, 3, 3, 3 // Select b, then a, then a, then a in that order.
4763#define SHDR_DETAIL_SWIZZLE_arrr 3, 0, 0, 0 // Select a, then r, then r, then r in that order.
4764#define SHDR_DETAIL_SWIZZLE_arrg 3, 0, 0, 1 // Select a, then r, then r, then g in that order.
4765#define SHDR_DETAIL_SWIZZLE_arrb 3, 0, 0, 2 // Select a, then r, then r, then b in that order.
4766#define SHDR_DETAIL_SWIZZLE_arra 3, 0, 0, 3 // Select a, then r, then r, then a in that order.
4767#define SHDR_DETAIL_SWIZZLE_argr 3, 0, 1, 0 // Select a, then r, then g, then r in that order.
4768#define SHDR_DETAIL_SWIZZLE_argg 3, 0, 1, 1 // Select a, then r, then g, then g in that order.
4769#define SHDR_DETAIL_SWIZZLE_argb 3, 0, 1, 2 // Select a, then r, then g, then b in that order.
4770#define SHDR_DETAIL_SWIZZLE_arga 3, 0, 1, 3 // Select a, then r, then g, then a in that order.
4771#define SHDR_DETAIL_SWIZZLE_arbr 3, 0, 2, 0 // Select a, then r, then b, then r in that order.
4772#define SHDR_DETAIL_SWIZZLE_arbg 3, 0, 2, 1 // Select a, then r, then b, then g in that order.
4773#define SHDR_DETAIL_SWIZZLE_arbb 3, 0, 2, 2 // Select a, then r, then b, then b in that order.
4774#define SHDR_DETAIL_SWIZZLE_arba 3, 0, 2, 3 // Select a, then r, then b, then a in that order.
4775#define SHDR_DETAIL_SWIZZLE_arar 3, 0, 3, 0 // Select a, then r, then a, then r in that order.
4776#define SHDR_DETAIL_SWIZZLE_arag 3, 0, 3, 1 // Select a, then r, then a, then g in that order.
4777#define SHDR_DETAIL_SWIZZLE_arab 3, 0, 3, 2 // Select a, then r, then a, then b in that order.
4778#define SHDR_DETAIL_SWIZZLE_araa 3, 0, 3, 3 // Select a, then r, then a, then a in that order.
4779#define SHDR_DETAIL_SWIZZLE_agrr 3, 1, 0, 0 // Select a, then g, then r, then r in that order.
4780#define SHDR_DETAIL_SWIZZLE_agrg 3, 1, 0, 1 // Select a, then g, then r, then g in that order.
4781#define SHDR_DETAIL_SWIZZLE_agrb 3, 1, 0, 2 // Select a, then g, then r, then b in that order.
4782#define SHDR_DETAIL_SWIZZLE_agra 3, 1, 0, 3 // Select a, then g, then r, then a in that order.
4783#define SHDR_DETAIL_SWIZZLE_aggr 3, 1, 1, 0 // Select a, then g, then g, then r in that order.
4784#define SHDR_DETAIL_SWIZZLE_aggg 3, 1, 1, 1 // Select a, then g, then g, then g in that order.
4785#define SHDR_DETAIL_SWIZZLE_aggb 3, 1, 1, 2 // Select a, then g, then g, then b in that order.
4786#define SHDR_DETAIL_SWIZZLE_agga 3, 1, 1, 3 // Select a, then g, then g, then a in that order.
4787#define SHDR_DETAIL_SWIZZLE_agbr 3, 1, 2, 0 // Select a, then g, then b, then r in that order.
4788#define SHDR_DETAIL_SWIZZLE_agbg 3, 1, 2, 1 // Select a, then g, then b, then g in that order.
4789#define SHDR_DETAIL_SWIZZLE_agbb 3, 1, 2, 2 // Select a, then g, then b, then b in that order.
4790#define SHDR_DETAIL_SWIZZLE_agba 3, 1, 2, 3 // Select a, then g, then b, then a in that order.
4791#define SHDR_DETAIL_SWIZZLE_agar 3, 1, 3, 0 // Select a, then g, then a, then r in that order.
4792#define SHDR_DETAIL_SWIZZLE_agag 3, 1, 3, 1 // Select a, then g, then a, then g in that order.
4793#define SHDR_DETAIL_SWIZZLE_agab 3, 1, 3, 2 // Select a, then g, then a, then b in that order.
4794#define SHDR_DETAIL_SWIZZLE_agaa 3, 1, 3, 3 // Select a, then g, then a, then a in that order.
4795#define SHDR_DETAIL_SWIZZLE_abrr 3, 2, 0, 0 // Select a, then b, then r, then r in that order.
4796#define SHDR_DETAIL_SWIZZLE_abrg 3, 2, 0, 1 // Select a, then b, then r, then g in that order.
4797#define SHDR_DETAIL_SWIZZLE_abrb 3, 2, 0, 2 // Select a, then b, then r, then b in that order.
4798#define SHDR_DETAIL_SWIZZLE_abra 3, 2, 0, 3 // Select a, then b, then r, then a in that order.
4799#define SHDR_DETAIL_SWIZZLE_abgr 3, 2, 1, 0 // Select a, then b, then g, then r in that order.
4800#define SHDR_DETAIL_SWIZZLE_abgg 3, 2, 1, 1 // Select a, then b, then g, then g in that order.
4801#define SHDR_DETAIL_SWIZZLE_abgb 3, 2, 1, 2 // Select a, then b, then g, then b in that order.
4802#define SHDR_DETAIL_SWIZZLE_abga 3, 2, 1, 3 // Select a, then b, then g, then a in that order.
4803#define SHDR_DETAIL_SWIZZLE_abbr 3, 2, 2, 0 // Select a, then b, then b, then r in that order.
4804#define SHDR_DETAIL_SWIZZLE_abbg 3, 2, 2, 1 // Select a, then b, then b, then g in that order.
4805#define SHDR_DETAIL_SWIZZLE_abbb 3, 2, 2, 2 // Select a, then b, then b, then b in that order.
4806#define SHDR_DETAIL_SWIZZLE_abba 3, 2, 2, 3 // Select a, then b, then b, then a in that order.
4807#define SHDR_DETAIL_SWIZZLE_abar 3, 2, 3, 0 // Select a, then b, then a, then r in that order.
4808#define SHDR_DETAIL_SWIZZLE_abag 3, 2, 3, 1 // Select a, then b, then a, then g in that order.
4809#define SHDR_DETAIL_SWIZZLE_abab 3, 2, 3, 2 // Select a, then b, then a, then b in that order.
4810#define SHDR_DETAIL_SWIZZLE_abaa 3, 2, 3, 3 // Select a, then b, then a, then a in that order.
4811#define SHDR_DETAIL_SWIZZLE_aarr 3, 3, 0, 0 // Select a, then a, then r, then r in that order.
4812#define SHDR_DETAIL_SWIZZLE_aarg 3, 3, 0, 1 // Select a, then a, then r, then g in that order.
4813#define SHDR_DETAIL_SWIZZLE_aarb 3, 3, 0, 2 // Select a, then a, then r, then b in that order.
4814#define SHDR_DETAIL_SWIZZLE_aara 3, 3, 0, 3 // Select a, then a, then r, then a in that order.
4815#define SHDR_DETAIL_SWIZZLE_aagr 3, 3, 1, 0 // Select a, then a, then g, then r in that order.
4816#define SHDR_DETAIL_SWIZZLE_aagg 3, 3, 1, 1 // Select a, then a, then g, then g in that order.
4817#define SHDR_DETAIL_SWIZZLE_aagb 3, 3, 1, 2 // Select a, then a, then g, then b in that order.
4818#define SHDR_DETAIL_SWIZZLE_aaga 3, 3, 1, 3 // Select a, then a, then g, then a in that order.
4819#define SHDR_DETAIL_SWIZZLE_aabr 3, 3, 2, 0 // Select a, then a, then b, then r in that order.
4820#define SHDR_DETAIL_SWIZZLE_aabg 3, 3, 2, 1 // Select a, then a, then b, then g in that order.
4821#define SHDR_DETAIL_SWIZZLE_aabb 3, 3, 2, 2 // Select a, then a, then b, then b in that order.
4822#define SHDR_DETAIL_SWIZZLE_aaba 3, 3, 2, 3 // Select a, then a, then b, then a in that order.
4823#define SHDR_DETAIL_SWIZZLE_aaar 3, 3, 3, 0 // Select a, then a, then a, then r in that order.
4824#define SHDR_DETAIL_SWIZZLE_aaag 3, 3, 3, 1 // Select a, then a, then a, then g in that order.
4825#define SHDR_DETAIL_SWIZZLE_aaab 3, 3, 3, 2 // Select a, then a, then a, then b in that order.
4826#define SHDR_DETAIL_SWIZZLE_aaaa 3, 3, 3, 3 // Select a, then a, then a, then a in that order.
4827#define SHDR_DETAIL_SWIZZLE_s 0 // Select the s component.
4828#define SHDR_DETAIL_SWIZZLE_t 1 // Select the t component.
4829#define SHDR_DETAIL_SWIZZLE_p 2 // Select the p component.
4830#define SHDR_DETAIL_SWIZZLE_q 3 // Select the q component.
4831#define SHDR_DETAIL_SWIZZLE_ss 0, 0 // Select s, then s in that order.
4832#define SHDR_DETAIL_SWIZZLE_st 0, 1 // Select s, then t in that order.
4833#define SHDR_DETAIL_SWIZZLE_sp 0, 2 // Select s, then p in that order.
4834#define SHDR_DETAIL_SWIZZLE_sq 0, 3 // Select s, then q in that order.
4835#define SHDR_DETAIL_SWIZZLE_ts 1, 0 // Select t, then s in that order.
4836#define SHDR_DETAIL_SWIZZLE_tt 1, 1 // Select t, then t in that order.
4837#define SHDR_DETAIL_SWIZZLE_tp 1, 2 // Select t, then p in that order.
4838#define SHDR_DETAIL_SWIZZLE_tq 1, 3 // Select t, then q in that order.
4839#define SHDR_DETAIL_SWIZZLE_ps 2, 0 // Select p, then s in that order.
4840#define SHDR_DETAIL_SWIZZLE_pt 2, 1 // Select p, then t in that order.
4841#define SHDR_DETAIL_SWIZZLE_pp 2, 2 // Select p, then p in that order.
4842#define SHDR_DETAIL_SWIZZLE_pq 2, 3 // Select p, then q in that order.
4843#define SHDR_DETAIL_SWIZZLE_qs 3, 0 // Select q, then s in that order.
4844#define SHDR_DETAIL_SWIZZLE_qt 3, 1 // Select q, then t in that order.
4845#define SHDR_DETAIL_SWIZZLE_qp 3, 2 // Select q, then p in that order.
4846#define SHDR_DETAIL_SWIZZLE_qq 3, 3 // Select q, then q in that order.
4847#define SHDR_DETAIL_SWIZZLE_sss 0, 0, 0 // Select s, then s, then s in that order.
4848#define SHDR_DETAIL_SWIZZLE_sst 0, 0, 1 // Select s, then s, then t in that order.
4849#define SHDR_DETAIL_SWIZZLE_ssp 0, 0, 2 // Select s, then s, then p in that order.
4850#define SHDR_DETAIL_SWIZZLE_ssq 0, 0, 3 // Select s, then s, then q in that order.
4851#define SHDR_DETAIL_SWIZZLE_sts 0, 1, 0 // Select s, then t, then s in that order.
4852#define SHDR_DETAIL_SWIZZLE_stt 0, 1, 1 // Select s, then t, then t in that order.
4853#define SHDR_DETAIL_SWIZZLE_stp 0, 1, 2 // Select s, then t, then p in that order.
4854#define SHDR_DETAIL_SWIZZLE_stq 0, 1, 3 // Select s, then t, then q in that order.
4855#define SHDR_DETAIL_SWIZZLE_sps 0, 2, 0 // Select s, then p, then s in that order.
4856#define SHDR_DETAIL_SWIZZLE_spt 0, 2, 1 // Select s, then p, then t in that order.
4857#define SHDR_DETAIL_SWIZZLE_spp 0, 2, 2 // Select s, then p, then p in that order.
4858#define SHDR_DETAIL_SWIZZLE_spq 0, 2, 3 // Select s, then p, then q in that order.
4859#define SHDR_DETAIL_SWIZZLE_sqs 0, 3, 0 // Select s, then q, then s in that order.
4860#define SHDR_DETAIL_SWIZZLE_sqt 0, 3, 1 // Select s, then q, then t in that order.
4861#define SHDR_DETAIL_SWIZZLE_sqp 0, 3, 2 // Select s, then q, then p in that order.
4862#define SHDR_DETAIL_SWIZZLE_sqq 0, 3, 3 // Select s, then q, then q in that order.
4863#define SHDR_DETAIL_SWIZZLE_tss 1, 0, 0 // Select t, then s, then s in that order.
4864#define SHDR_DETAIL_SWIZZLE_tst 1, 0, 1 // Select t, then s, then t in that order.
4865#define SHDR_DETAIL_SWIZZLE_tsp 1, 0, 2 // Select t, then s, then p in that order.
4866#define SHDR_DETAIL_SWIZZLE_tsq 1, 0, 3 // Select t, then s, then q in that order.
4867#define SHDR_DETAIL_SWIZZLE_tts 1, 1, 0 // Select t, then t, then s in that order.
4868#define SHDR_DETAIL_SWIZZLE_ttt 1, 1, 1 // Select t, then t, then t in that order.
4869#define SHDR_DETAIL_SWIZZLE_ttp 1, 1, 2 // Select t, then t, then p in that order.
4870#define SHDR_DETAIL_SWIZZLE_ttq 1, 1, 3 // Select t, then t, then q in that order.
4871#define SHDR_DETAIL_SWIZZLE_tps 1, 2, 0 // Select t, then p, then s in that order.
4872#define SHDR_DETAIL_SWIZZLE_tpt 1, 2, 1 // Select t, then p, then t in that order.
4873#define SHDR_DETAIL_SWIZZLE_tpp 1, 2, 2 // Select t, then p, then p in that order.
4874#define SHDR_DETAIL_SWIZZLE_tpq 1, 2, 3 // Select t, then p, then q in that order.
4875#define SHDR_DETAIL_SWIZZLE_tqs 1, 3, 0 // Select t, then q, then s in that order.
4876#define SHDR_DETAIL_SWIZZLE_tqt 1, 3, 1 // Select t, then q, then t in that order.
4877#define SHDR_DETAIL_SWIZZLE_tqp 1, 3, 2 // Select t, then q, then p in that order.
4878#define SHDR_DETAIL_SWIZZLE_tqq 1, 3, 3 // Select t, then q, then q in that order.
4879#define SHDR_DETAIL_SWIZZLE_pss 2, 0, 0 // Select p, then s, then s in that order.
4880#define SHDR_DETAIL_SWIZZLE_pst 2, 0, 1 // Select p, then s, then t in that order.
4881#define SHDR_DETAIL_SWIZZLE_psp 2, 0, 2 // Select p, then s, then p in that order.
4882#define SHDR_DETAIL_SWIZZLE_psq 2, 0, 3 // Select p, then s, then q in that order.
4883#define SHDR_DETAIL_SWIZZLE_pts 2, 1, 0 // Select p, then t, then s in that order.
4884#define SHDR_DETAIL_SWIZZLE_ptt 2, 1, 1 // Select p, then t, then t in that order.
4885#define SHDR_DETAIL_SWIZZLE_ptp 2, 1, 2 // Select p, then t, then p in that order.
4886#define SHDR_DETAIL_SWIZZLE_ptq 2, 1, 3 // Select p, then t, then q in that order.
4887#define SHDR_DETAIL_SWIZZLE_pps 2, 2, 0 // Select p, then p, then s in that order.
4888#define SHDR_DETAIL_SWIZZLE_ppt 2, 2, 1 // Select p, then p, then t in that order.
4889#define SHDR_DETAIL_SWIZZLE_ppp 2, 2, 2 // Select p, then p, then p in that order.
4890#define SHDR_DETAIL_SWIZZLE_ppq 2, 2, 3 // Select p, then p, then q in that order.
4891#define SHDR_DETAIL_SWIZZLE_pqs 2, 3, 0 // Select p, then q, then s in that order.
4892#define SHDR_DETAIL_SWIZZLE_pqt 2, 3, 1 // Select p, then q, then t in that order.
4893#define SHDR_DETAIL_SWIZZLE_pqp 2, 3, 2 // Select p, then q, then p in that order.
4894#define SHDR_DETAIL_SWIZZLE_pqq 2, 3, 3 // Select p, then q, then q in that order.
4895#define SHDR_DETAIL_SWIZZLE_qss 3, 0, 0 // Select q, then s, then s in that order.
4896#define SHDR_DETAIL_SWIZZLE_qst 3, 0, 1 // Select q, then s, then t in that order.
4897#define SHDR_DETAIL_SWIZZLE_qsp 3, 0, 2 // Select q, then s, then p in that order.
4898#define SHDR_DETAIL_SWIZZLE_qsq 3, 0, 3 // Select q, then s, then q in that order.
4899#define SHDR_DETAIL_SWIZZLE_qts 3, 1, 0 // Select q, then t, then s in that order.
4900#define SHDR_DETAIL_SWIZZLE_qtt 3, 1, 1 // Select q, then t, then t in that order.
4901#define SHDR_DETAIL_SWIZZLE_qtp 3, 1, 2 // Select q, then t, then p in that order.
4902#define SHDR_DETAIL_SWIZZLE_qtq 3, 1, 3 // Select q, then t, then q in that order.
4903#define SHDR_DETAIL_SWIZZLE_qps 3, 2, 0 // Select q, then p, then s in that order.
4904#define SHDR_DETAIL_SWIZZLE_qpt 3, 2, 1 // Select q, then p, then t in that order.
4905#define SHDR_DETAIL_SWIZZLE_qpp 3, 2, 2 // Select q, then p, then p in that order.
4906#define SHDR_DETAIL_SWIZZLE_qpq 3, 2, 3 // Select q, then p, then q in that order.
4907#define SHDR_DETAIL_SWIZZLE_qqs 3, 3, 0 // Select q, then q, then s in that order.
4908#define SHDR_DETAIL_SWIZZLE_qqt 3, 3, 1 // Select q, then q, then t in that order.
4909#define SHDR_DETAIL_SWIZZLE_qqp 3, 3, 2 // Select q, then q, then p in that order.
4910#define SHDR_DETAIL_SWIZZLE_qqq 3, 3, 3 // Select q, then q, then q in that order.
4911#define SHDR_DETAIL_SWIZZLE_ssss 0, 0, 0, 0 // Select s, then s, then s, then s in that order.
4912#define SHDR_DETAIL_SWIZZLE_ssst 0, 0, 0, 1 // Select s, then s, then s, then t in that order.
4913#define SHDR_DETAIL_SWIZZLE_sssp 0, 0, 0, 2 // Select s, then s, then s, then p in that order.
4914#define SHDR_DETAIL_SWIZZLE_sssq 0, 0, 0, 3 // Select s, then s, then s, then q in that order.
4915#define SHDR_DETAIL_SWIZZLE_ssts 0, 0, 1, 0 // Select s, then s, then t, then s in that order.
4916#define SHDR_DETAIL_SWIZZLE_sstt 0, 0, 1, 1 // Select s, then s, then t, then t in that order.
4917#define SHDR_DETAIL_SWIZZLE_sstp 0, 0, 1, 2 // Select s, then s, then t, then p in that order.
4918#define SHDR_DETAIL_SWIZZLE_sstq 0, 0, 1, 3 // Select s, then s, then t, then q in that order.
4919#define SHDR_DETAIL_SWIZZLE_ssps 0, 0, 2, 0 // Select s, then s, then p, then s in that order.
4920#define SHDR_DETAIL_SWIZZLE_sspt 0, 0, 2, 1 // Select s, then s, then p, then t in that order.
4921#define SHDR_DETAIL_SWIZZLE_sspp 0, 0, 2, 2 // Select s, then s, then p, then p in that order.
4922#define SHDR_DETAIL_SWIZZLE_sspq 0, 0, 2, 3 // Select s, then s, then p, then q in that order.
4923#define SHDR_DETAIL_SWIZZLE_ssqs 0, 0, 3, 0 // Select s, then s, then q, then s in that order.
4924#define SHDR_DETAIL_SWIZZLE_ssqt 0, 0, 3, 1 // Select s, then s, then q, then t in that order.
4925#define SHDR_DETAIL_SWIZZLE_ssqp 0, 0, 3, 2 // Select s, then s, then q, then p in that order.
4926#define SHDR_DETAIL_SWIZZLE_ssqq 0, 0, 3, 3 // Select s, then s, then q, then q in that order.
4927#define SHDR_DETAIL_SWIZZLE_stss 0, 1, 0, 0 // Select s, then t, then s, then s in that order.
4928#define SHDR_DETAIL_SWIZZLE_stst 0, 1, 0, 1 // Select s, then t, then s, then t in that order.
4929#define SHDR_DETAIL_SWIZZLE_stsp 0, 1, 0, 2 // Select s, then t, then s, then p in that order.
4930#define SHDR_DETAIL_SWIZZLE_stsq 0, 1, 0, 3 // Select s, then t, then s, then q in that order.
4931#define SHDR_DETAIL_SWIZZLE_stts 0, 1, 1, 0 // Select s, then t, then t, then s in that order.
4932#define SHDR_DETAIL_SWIZZLE_sttt 0, 1, 1, 1 // Select s, then t, then t, then t in that order.
4933#define SHDR_DETAIL_SWIZZLE_sttp 0, 1, 1, 2 // Select s, then t, then t, then p in that order.
4934#define SHDR_DETAIL_SWIZZLE_sttq 0, 1, 1, 3 // Select s, then t, then t, then q in that order.
4935#define SHDR_DETAIL_SWIZZLE_stps 0, 1, 2, 0 // Select s, then t, then p, then s in that order.
4936#define SHDR_DETAIL_SWIZZLE_stpt 0, 1, 2, 1 // Select s, then t, then p, then t in that order.
4937#define SHDR_DETAIL_SWIZZLE_stpp 0, 1, 2, 2 // Select s, then t, then p, then p in that order.
4938#define SHDR_DETAIL_SWIZZLE_stpq 0, 1, 2, 3 // Select s, then t, then p, then q in that order.
4939#define SHDR_DETAIL_SWIZZLE_stqs 0, 1, 3, 0 // Select s, then t, then q, then s in that order.
4940#define SHDR_DETAIL_SWIZZLE_stqt 0, 1, 3, 1 // Select s, then t, then q, then t in that order.
4941#define SHDR_DETAIL_SWIZZLE_stqp 0, 1, 3, 2 // Select s, then t, then q, then p in that order.
4942#define SHDR_DETAIL_SWIZZLE_stqq 0, 1, 3, 3 // Select s, then t, then q, then q in that order.
4943#define SHDR_DETAIL_SWIZZLE_spss 0, 2, 0, 0 // Select s, then p, then s, then s in that order.
4944#define SHDR_DETAIL_SWIZZLE_spst 0, 2, 0, 1 // Select s, then p, then s, then t in that order.
4945#define SHDR_DETAIL_SWIZZLE_spsp 0, 2, 0, 2 // Select s, then p, then s, then p in that order.
4946#define SHDR_DETAIL_SWIZZLE_spsq 0, 2, 0, 3 // Select s, then p, then s, then q in that order.
4947#define SHDR_DETAIL_SWIZZLE_spts 0, 2, 1, 0 // Select s, then p, then t, then s in that order.
4948#define SHDR_DETAIL_SWIZZLE_sptt 0, 2, 1, 1 // Select s, then p, then t, then t in that order.
4949#define SHDR_DETAIL_SWIZZLE_sptp 0, 2, 1, 2 // Select s, then p, then t, then p in that order.
4950#define SHDR_DETAIL_SWIZZLE_sptq 0, 2, 1, 3 // Select s, then p, then t, then q in that order.
4951#define SHDR_DETAIL_SWIZZLE_spps 0, 2, 2, 0 // Select s, then p, then p, then s in that order.
4952#define SHDR_DETAIL_SWIZZLE_sppt 0, 2, 2, 1 // Select s, then p, then p, then t in that order.
4953#define SHDR_DETAIL_SWIZZLE_sppp 0, 2, 2, 2 // Select s, then p, then p, then p in that order.
4954#define SHDR_DETAIL_SWIZZLE_sppq 0, 2, 2, 3 // Select s, then p, then p, then q in that order.
4955#define SHDR_DETAIL_SWIZZLE_spqs 0, 2, 3, 0 // Select s, then p, then q, then s in that order.
4956#define SHDR_DETAIL_SWIZZLE_spqt 0, 2, 3, 1 // Select s, then p, then q, then t in that order.
4957#define SHDR_DETAIL_SWIZZLE_spqp 0, 2, 3, 2 // Select s, then p, then q, then p in that order.
4958#define SHDR_DETAIL_SWIZZLE_spqq 0, 2, 3, 3 // Select s, then p, then q, then q in that order.
4959#define SHDR_DETAIL_SWIZZLE_sqss 0, 3, 0, 0 // Select s, then q, then s, then s in that order.
4960#define SHDR_DETAIL_SWIZZLE_sqst 0, 3, 0, 1 // Select s, then q, then s, then t in that order.
4961#define SHDR_DETAIL_SWIZZLE_sqsp 0, 3, 0, 2 // Select s, then q, then s, then p in that order.
4962#define SHDR_DETAIL_SWIZZLE_sqsq 0, 3, 0, 3 // Select s, then q, then s, then q in that order.
4963#define SHDR_DETAIL_SWIZZLE_sqts 0, 3, 1, 0 // Select s, then q, then t, then s in that order.
4964#define SHDR_DETAIL_SWIZZLE_sqtt 0, 3, 1, 1 // Select s, then q, then t, then t in that order.
4965#define SHDR_DETAIL_SWIZZLE_sqtp 0, 3, 1, 2 // Select s, then q, then t, then p in that order.
4966#define SHDR_DETAIL_SWIZZLE_sqtq 0, 3, 1, 3 // Select s, then q, then t, then q in that order.
4967#define SHDR_DETAIL_SWIZZLE_sqps 0, 3, 2, 0 // Select s, then q, then p, then s in that order.
4968#define SHDR_DETAIL_SWIZZLE_sqpt 0, 3, 2, 1 // Select s, then q, then p, then t in that order.
4969#define SHDR_DETAIL_SWIZZLE_sqpp 0, 3, 2, 2 // Select s, then q, then p, then p in that order.
4970#define SHDR_DETAIL_SWIZZLE_sqpq 0, 3, 2, 3 // Select s, then q, then p, then q in that order.
4971#define SHDR_DETAIL_SWIZZLE_sqqs 0, 3, 3, 0 // Select s, then q, then q, then s in that order.
4972#define SHDR_DETAIL_SWIZZLE_sqqt 0, 3, 3, 1 // Select s, then q, then q, then t in that order.
4973#define SHDR_DETAIL_SWIZZLE_sqqp 0, 3, 3, 2 // Select s, then q, then q, then p in that order.
4974#define SHDR_DETAIL_SWIZZLE_sqqq 0, 3, 3, 3 // Select s, then q, then q, then q in that order.
4975#define SHDR_DETAIL_SWIZZLE_tsss 1, 0, 0, 0 // Select t, then s, then s, then s in that order.
4976#define SHDR_DETAIL_SWIZZLE_tsst 1, 0, 0, 1 // Select t, then s, then s, then t in that order.
4977#define SHDR_DETAIL_SWIZZLE_tssp 1, 0, 0, 2 // Select t, then s, then s, then p in that order.
4978#define SHDR_DETAIL_SWIZZLE_tssq 1, 0, 0, 3 // Select t, then s, then s, then q in that order.
4979#define SHDR_DETAIL_SWIZZLE_tsts 1, 0, 1, 0 // Select t, then s, then t, then s in that order.
4980#define SHDR_DETAIL_SWIZZLE_tstt 1, 0, 1, 1 // Select t, then s, then t, then t in that order.
4981#define SHDR_DETAIL_SWIZZLE_tstp 1, 0, 1, 2 // Select t, then s, then t, then p in that order.
4982#define SHDR_DETAIL_SWIZZLE_tstq 1, 0, 1, 3 // Select t, then s, then t, then q in that order.
4983#define SHDR_DETAIL_SWIZZLE_tsps 1, 0, 2, 0 // Select t, then s, then p, then s in that order.
4984#define SHDR_DETAIL_SWIZZLE_tspt 1, 0, 2, 1 // Select t, then s, then p, then t in that order.
4985#define SHDR_DETAIL_SWIZZLE_tspp 1, 0, 2, 2 // Select t, then s, then p, then p in that order.
4986#define SHDR_DETAIL_SWIZZLE_tspq 1, 0, 2, 3 // Select t, then s, then p, then q in that order.
4987#define SHDR_DETAIL_SWIZZLE_tsqs 1, 0, 3, 0 // Select t, then s, then q, then s in that order.
4988#define SHDR_DETAIL_SWIZZLE_tsqt 1, 0, 3, 1 // Select t, then s, then q, then t in that order.
4989#define SHDR_DETAIL_SWIZZLE_tsqp 1, 0, 3, 2 // Select t, then s, then q, then p in that order.
4990#define SHDR_DETAIL_SWIZZLE_tsqq 1, 0, 3, 3 // Select t, then s, then q, then q in that order.
4991#define SHDR_DETAIL_SWIZZLE_ttss 1, 1, 0, 0 // Select t, then t, then s, then s in that order.
4992#define SHDR_DETAIL_SWIZZLE_ttst 1, 1, 0, 1 // Select t, then t, then s, then t in that order.
4993#define SHDR_DETAIL_SWIZZLE_ttsp 1, 1, 0, 2 // Select t, then t, then s, then p in that order.
4994#define SHDR_DETAIL_SWIZZLE_ttsq 1, 1, 0, 3 // Select t, then t, then s, then q in that order.
4995#define SHDR_DETAIL_SWIZZLE_ttts 1, 1, 1, 0 // Select t, then t, then t, then s in that order.
4996#define SHDR_DETAIL_SWIZZLE_tttt 1, 1, 1, 1 // Select t, then t, then t, then t in that order.
4997#define SHDR_DETAIL_SWIZZLE_tttp 1, 1, 1, 2 // Select t, then t, then t, then p in that order.
4998#define SHDR_DETAIL_SWIZZLE_tttq 1, 1, 1, 3 // Select t, then t, then t, then q in that order.
4999#define SHDR_DETAIL_SWIZZLE_ttps 1, 1, 2, 0 // Select t, then t, then p, then s in that order.
5000#define SHDR_DETAIL_SWIZZLE_ttpt 1, 1, 2, 1 // Select t, then t, then p, then t in that order.
5001#define SHDR_DETAIL_SWIZZLE_ttpp 1, 1, 2, 2 // Select t, then t, then p, then p in that order.
5002#define SHDR_DETAIL_SWIZZLE_ttpq 1, 1, 2, 3 // Select t, then t, then p, then q in that order.
5003#define SHDR_DETAIL_SWIZZLE_ttqs 1, 1, 3, 0 // Select t, then t, then q, then s in that order.
5004#define SHDR_DETAIL_SWIZZLE_ttqt 1, 1, 3, 1 // Select t, then t, then q, then t in that order.
5005#define SHDR_DETAIL_SWIZZLE_ttqp 1, 1, 3, 2 // Select t, then t, then q, then p in that order.
5006#define SHDR_DETAIL_SWIZZLE_ttqq 1, 1, 3, 3 // Select t, then t, then q, then q in that order.
5007#define SHDR_DETAIL_SWIZZLE_tpss 1, 2, 0, 0 // Select t, then p, then s, then s in that order.
5008#define SHDR_DETAIL_SWIZZLE_tpst 1, 2, 0, 1 // Select t, then p, then s, then t in that order.
5009#define SHDR_DETAIL_SWIZZLE_tpsp 1, 2, 0, 2 // Select t, then p, then s, then p in that order.
5010#define SHDR_DETAIL_SWIZZLE_tpsq 1, 2, 0, 3 // Select t, then p, then s, then q in that order.
5011#define SHDR_DETAIL_SWIZZLE_tpts 1, 2, 1, 0 // Select t, then p, then t, then s in that order.
5012#define SHDR_DETAIL_SWIZZLE_tptt 1, 2, 1, 1 // Select t, then p, then t, then t in that order.
5013#define SHDR_DETAIL_SWIZZLE_tptp 1, 2, 1, 2 // Select t, then p, then t, then p in that order.
5014#define SHDR_DETAIL_SWIZZLE_tptq 1, 2, 1, 3 // Select t, then p, then t, then q in that order.
5015#define SHDR_DETAIL_SWIZZLE_tpps 1, 2, 2, 0 // Select t, then p, then p, then s in that order.
5016#define SHDR_DETAIL_SWIZZLE_tppt 1, 2, 2, 1 // Select t, then p, then p, then t in that order.
5017#define SHDR_DETAIL_SWIZZLE_tppp 1, 2, 2, 2 // Select t, then p, then p, then p in that order.
5018#define SHDR_DETAIL_SWIZZLE_tppq 1, 2, 2, 3 // Select t, then p, then p, then q in that order.
5019#define SHDR_DETAIL_SWIZZLE_tpqs 1, 2, 3, 0 // Select t, then p, then q, then s in that order.
5020#define SHDR_DETAIL_SWIZZLE_tpqt 1, 2, 3, 1 // Select t, then p, then q, then t in that order.
5021#define SHDR_DETAIL_SWIZZLE_tpqp 1, 2, 3, 2 // Select t, then p, then q, then p in that order.
5022#define SHDR_DETAIL_SWIZZLE_tpqq 1, 2, 3, 3 // Select t, then p, then q, then q in that order.
5023#define SHDR_DETAIL_SWIZZLE_tqss 1, 3, 0, 0 // Select t, then q, then s, then s in that order.
5024#define SHDR_DETAIL_SWIZZLE_tqst 1, 3, 0, 1 // Select t, then q, then s, then t in that order.
5025#define SHDR_DETAIL_SWIZZLE_tqsp 1, 3, 0, 2 // Select t, then q, then s, then p in that order.
5026#define SHDR_DETAIL_SWIZZLE_tqsq 1, 3, 0, 3 // Select t, then q, then s, then q in that order.
5027#define SHDR_DETAIL_SWIZZLE_tqts 1, 3, 1, 0 // Select t, then q, then t, then s in that order.
5028#define SHDR_DETAIL_SWIZZLE_tqtt 1, 3, 1, 1 // Select t, then q, then t, then t in that order.
5029#define SHDR_DETAIL_SWIZZLE_tqtp 1, 3, 1, 2 // Select t, then q, then t, then p in that order.
5030#define SHDR_DETAIL_SWIZZLE_tqtq 1, 3, 1, 3 // Select t, then q, then t, then q in that order.
5031#define SHDR_DETAIL_SWIZZLE_tqps 1, 3, 2, 0 // Select t, then q, then p, then s in that order.
5032#define SHDR_DETAIL_SWIZZLE_tqpt 1, 3, 2, 1 // Select t, then q, then p, then t in that order.
5033#define SHDR_DETAIL_SWIZZLE_tqpp 1, 3, 2, 2 // Select t, then q, then p, then p in that order.
5034#define SHDR_DETAIL_SWIZZLE_tqpq 1, 3, 2, 3 // Select t, then q, then p, then q in that order.
5035#define SHDR_DETAIL_SWIZZLE_tqqs 1, 3, 3, 0 // Select t, then q, then q, then s in that order.
5036#define SHDR_DETAIL_SWIZZLE_tqqt 1, 3, 3, 1 // Select t, then q, then q, then t in that order.
5037#define SHDR_DETAIL_SWIZZLE_tqqp 1, 3, 3, 2 // Select t, then q, then q, then p in that order.
5038#define SHDR_DETAIL_SWIZZLE_tqqq 1, 3, 3, 3 // Select t, then q, then q, then q in that order.
5039#define SHDR_DETAIL_SWIZZLE_psss 2, 0, 0, 0 // Select p, then s, then s, then s in that order.
5040#define SHDR_DETAIL_SWIZZLE_psst 2, 0, 0, 1 // Select p, then s, then s, then t in that order.
5041#define SHDR_DETAIL_SWIZZLE_pssp 2, 0, 0, 2 // Select p, then s, then s, then p in that order.
5042#define SHDR_DETAIL_SWIZZLE_pssq 2, 0, 0, 3 // Select p, then s, then s, then q in that order.
5043#define SHDR_DETAIL_SWIZZLE_psts 2, 0, 1, 0 // Select p, then s, then t, then s in that order.
5044#define SHDR_DETAIL_SWIZZLE_pstt 2, 0, 1, 1 // Select p, then s, then t, then t in that order.
5045#define SHDR_DETAIL_SWIZZLE_pstp 2, 0, 1, 2 // Select p, then s, then t, then p in that order.
5046#define SHDR_DETAIL_SWIZZLE_pstq 2, 0, 1, 3 // Select p, then s, then t, then q in that order.
5047#define SHDR_DETAIL_SWIZZLE_psps 2, 0, 2, 0 // Select p, then s, then p, then s in that order.
5048#define SHDR_DETAIL_SWIZZLE_pspt 2, 0, 2, 1 // Select p, then s, then p, then t in that order.
5049#define SHDR_DETAIL_SWIZZLE_pspp 2, 0, 2, 2 // Select p, then s, then p, then p in that order.
5050#define SHDR_DETAIL_SWIZZLE_pspq 2, 0, 2, 3 // Select p, then s, then p, then q in that order.
5051#define SHDR_DETAIL_SWIZZLE_psqs 2, 0, 3, 0 // Select p, then s, then q, then s in that order.
5052#define SHDR_DETAIL_SWIZZLE_psqt 2, 0, 3, 1 // Select p, then s, then q, then t in that order.
5053#define SHDR_DETAIL_SWIZZLE_psqp 2, 0, 3, 2 // Select p, then s, then q, then p in that order.
5054#define SHDR_DETAIL_SWIZZLE_psqq 2, 0, 3, 3 // Select p, then s, then q, then q in that order.
5055#define SHDR_DETAIL_SWIZZLE_ptss 2, 1, 0, 0 // Select p, then t, then s, then s in that order.
5056#define SHDR_DETAIL_SWIZZLE_ptst 2, 1, 0, 1 // Select p, then t, then s, then t in that order.
5057#define SHDR_DETAIL_SWIZZLE_ptsp 2, 1, 0, 2 // Select p, then t, then s, then p in that order.
5058#define SHDR_DETAIL_SWIZZLE_ptsq 2, 1, 0, 3 // Select p, then t, then s, then q in that order.
5059#define SHDR_DETAIL_SWIZZLE_ptts 2, 1, 1, 0 // Select p, then t, then t, then s in that order.
5060#define SHDR_DETAIL_SWIZZLE_pttt 2, 1, 1, 1 // Select p, then t, then t, then t in that order.
5061#define SHDR_DETAIL_SWIZZLE_pttp 2, 1, 1, 2 // Select p, then t, then t, then p in that order.
5062#define SHDR_DETAIL_SWIZZLE_pttq 2, 1, 1, 3 // Select p, then t, then t, then q in that order.
5063#define SHDR_DETAIL_SWIZZLE_ptps 2, 1, 2, 0 // Select p, then t, then p, then s in that order.
5064#define SHDR_DETAIL_SWIZZLE_ptpt 2, 1, 2, 1 // Select p, then t, then p, then t in that order.
5065#define SHDR_DETAIL_SWIZZLE_ptpp 2, 1, 2, 2 // Select p, then t, then p, then p in that order.
5066#define SHDR_DETAIL_SWIZZLE_ptpq 2, 1, 2, 3 // Select p, then t, then p, then q in that order.
5067#define SHDR_DETAIL_SWIZZLE_ptqs 2, 1, 3, 0 // Select p, then t, then q, then s in that order.
5068#define SHDR_DETAIL_SWIZZLE_ptqt 2, 1, 3, 1 // Select p, then t, then q, then t in that order.
5069#define SHDR_DETAIL_SWIZZLE_ptqp 2, 1, 3, 2 // Select p, then t, then q, then p in that order.
5070#define SHDR_DETAIL_SWIZZLE_ptqq 2, 1, 3, 3 // Select p, then t, then q, then q in that order.
5071#define SHDR_DETAIL_SWIZZLE_ppss 2, 2, 0, 0 // Select p, then p, then s, then s in that order.
5072#define SHDR_DETAIL_SWIZZLE_ppst 2, 2, 0, 1 // Select p, then p, then s, then t in that order.
5073#define SHDR_DETAIL_SWIZZLE_ppsp 2, 2, 0, 2 // Select p, then p, then s, then p in that order.
5074#define SHDR_DETAIL_SWIZZLE_ppsq 2, 2, 0, 3 // Select p, then p, then s, then q in that order.
5075#define SHDR_DETAIL_SWIZZLE_ppts 2, 2, 1, 0 // Select p, then p, then t, then s in that order.
5076#define SHDR_DETAIL_SWIZZLE_pptt 2, 2, 1, 1 // Select p, then p, then t, then t in that order.
5077#define SHDR_DETAIL_SWIZZLE_pptp 2, 2, 1, 2 // Select p, then p, then t, then p in that order.
5078#define SHDR_DETAIL_SWIZZLE_pptq 2, 2, 1, 3 // Select p, then p, then t, then q in that order.
5079#define SHDR_DETAIL_SWIZZLE_ppps 2, 2, 2, 0 // Select p, then p, then p, then s in that order.
5080#define SHDR_DETAIL_SWIZZLE_pppt 2, 2, 2, 1 // Select p, then p, then p, then t in that order.
5081#define SHDR_DETAIL_SWIZZLE_pppp 2, 2, 2, 2 // Select p, then p, then p, then p in that order.
5082#define SHDR_DETAIL_SWIZZLE_pppq 2, 2, 2, 3 // Select p, then p, then p, then q in that order.
5083#define SHDR_DETAIL_SWIZZLE_ppqs 2, 2, 3, 0 // Select p, then p, then q, then s in that order.
5084#define SHDR_DETAIL_SWIZZLE_ppqt 2, 2, 3, 1 // Select p, then p, then q, then t in that order.
5085#define SHDR_DETAIL_SWIZZLE_ppqp 2, 2, 3, 2 // Select p, then p, then q, then p in that order.
5086#define SHDR_DETAIL_SWIZZLE_ppqq 2, 2, 3, 3 // Select p, then p, then q, then q in that order.
5087#define SHDR_DETAIL_SWIZZLE_pqss 2, 3, 0, 0 // Select p, then q, then s, then s in that order.
5088#define SHDR_DETAIL_SWIZZLE_pqst 2, 3, 0, 1 // Select p, then q, then s, then t in that order.
5089#define SHDR_DETAIL_SWIZZLE_pqsp 2, 3, 0, 2 // Select p, then q, then s, then p in that order.
5090#define SHDR_DETAIL_SWIZZLE_pqsq 2, 3, 0, 3 // Select p, then q, then s, then q in that order.
5091#define SHDR_DETAIL_SWIZZLE_pqts 2, 3, 1, 0 // Select p, then q, then t, then s in that order.
5092#define SHDR_DETAIL_SWIZZLE_pqtt 2, 3, 1, 1 // Select p, then q, then t, then t in that order.
5093#define SHDR_DETAIL_SWIZZLE_pqtp 2, 3, 1, 2 // Select p, then q, then t, then p in that order.
5094#define SHDR_DETAIL_SWIZZLE_pqtq 2, 3, 1, 3 // Select p, then q, then t, then q in that order.
5095#define SHDR_DETAIL_SWIZZLE_pqps 2, 3, 2, 0 // Select p, then q, then p, then s in that order.
5096#define SHDR_DETAIL_SWIZZLE_pqpt 2, 3, 2, 1 // Select p, then q, then p, then t in that order.
5097#define SHDR_DETAIL_SWIZZLE_pqpp 2, 3, 2, 2 // Select p, then q, then p, then p in that order.
5098#define SHDR_DETAIL_SWIZZLE_pqpq 2, 3, 2, 3 // Select p, then q, then p, then q in that order.
5099#define SHDR_DETAIL_SWIZZLE_pqqs 2, 3, 3, 0 // Select p, then q, then q, then s in that order.
5100#define SHDR_DETAIL_SWIZZLE_pqqt 2, 3, 3, 1 // Select p, then q, then q, then t in that order.
5101#define SHDR_DETAIL_SWIZZLE_pqqp 2, 3, 3, 2 // Select p, then q, then q, then p in that order.
5102#define SHDR_DETAIL_SWIZZLE_pqqq 2, 3, 3, 3 // Select p, then q, then q, then q in that order.
5103#define SHDR_DETAIL_SWIZZLE_qsss 3, 0, 0, 0 // Select q, then s, then s, then s in that order.
5104#define SHDR_DETAIL_SWIZZLE_qsst 3, 0, 0, 1 // Select q, then s, then s, then t in that order.
5105#define SHDR_DETAIL_SWIZZLE_qssp 3, 0, 0, 2 // Select q, then s, then s, then p in that order.
5106#define SHDR_DETAIL_SWIZZLE_qssq 3, 0, 0, 3 // Select q, then s, then s, then q in that order.
5107#define SHDR_DETAIL_SWIZZLE_qsts 3, 0, 1, 0 // Select q, then s, then t, then s in that order.
5108#define SHDR_DETAIL_SWIZZLE_qstt 3, 0, 1, 1 // Select q, then s, then t, then t in that order.
5109#define SHDR_DETAIL_SWIZZLE_qstp 3, 0, 1, 2 // Select q, then s, then t, then p in that order.
5110#define SHDR_DETAIL_SWIZZLE_qstq 3, 0, 1, 3 // Select q, then s, then t, then q in that order.
5111#define SHDR_DETAIL_SWIZZLE_qsps 3, 0, 2, 0 // Select q, then s, then p, then s in that order.
5112#define SHDR_DETAIL_SWIZZLE_qspt 3, 0, 2, 1 // Select q, then s, then p, then t in that order.
5113#define SHDR_DETAIL_SWIZZLE_qspp 3, 0, 2, 2 // Select q, then s, then p, then p in that order.
5114#define SHDR_DETAIL_SWIZZLE_qspq 3, 0, 2, 3 // Select q, then s, then p, then q in that order.
5115#define SHDR_DETAIL_SWIZZLE_qsqs 3, 0, 3, 0 // Select q, then s, then q, then s in that order.
5116#define SHDR_DETAIL_SWIZZLE_qsqt 3, 0, 3, 1 // Select q, then s, then q, then t in that order.
5117#define SHDR_DETAIL_SWIZZLE_qsqp 3, 0, 3, 2 // Select q, then s, then q, then p in that order.
5118#define SHDR_DETAIL_SWIZZLE_qsqq 3, 0, 3, 3 // Select q, then s, then q, then q in that order.
5119#define SHDR_DETAIL_SWIZZLE_qtss 3, 1, 0, 0 // Select q, then t, then s, then s in that order.
5120#define SHDR_DETAIL_SWIZZLE_qtst 3, 1, 0, 1 // Select q, then t, then s, then t in that order.
5121#define SHDR_DETAIL_SWIZZLE_qtsp 3, 1, 0, 2 // Select q, then t, then s, then p in that order.
5122#define SHDR_DETAIL_SWIZZLE_qtsq 3, 1, 0, 3 // Select q, then t, then s, then q in that order.
5123#define SHDR_DETAIL_SWIZZLE_qtts 3, 1, 1, 0 // Select q, then t, then t, then s in that order.
5124#define SHDR_DETAIL_SWIZZLE_qttt 3, 1, 1, 1 // Select q, then t, then t, then t in that order.
5125#define SHDR_DETAIL_SWIZZLE_qttp 3, 1, 1, 2 // Select q, then t, then t, then p in that order.
5126#define SHDR_DETAIL_SWIZZLE_qttq 3, 1, 1, 3 // Select q, then t, then t, then q in that order.
5127#define SHDR_DETAIL_SWIZZLE_qtps 3, 1, 2, 0 // Select q, then t, then p, then s in that order.
5128#define SHDR_DETAIL_SWIZZLE_qtpt 3, 1, 2, 1 // Select q, then t, then p, then t in that order.
5129#define SHDR_DETAIL_SWIZZLE_qtpp 3, 1, 2, 2 // Select q, then t, then p, then p in that order.
5130#define SHDR_DETAIL_SWIZZLE_qtpq 3, 1, 2, 3 // Select q, then t, then p, then q in that order.
5131#define SHDR_DETAIL_SWIZZLE_qtqs 3, 1, 3, 0 // Select q, then t, then q, then s in that order.
5132#define SHDR_DETAIL_SWIZZLE_qtqt 3, 1, 3, 1 // Select q, then t, then q, then t in that order.
5133#define SHDR_DETAIL_SWIZZLE_qtqp 3, 1, 3, 2 // Select q, then t, then q, then p in that order.
5134#define SHDR_DETAIL_SWIZZLE_qtqq 3, 1, 3, 3 // Select q, then t, then q, then q in that order.
5135#define SHDR_DETAIL_SWIZZLE_qpss 3, 2, 0, 0 // Select q, then p, then s, then s in that order.
5136#define SHDR_DETAIL_SWIZZLE_qpst 3, 2, 0, 1 // Select q, then p, then s, then t in that order.
5137#define SHDR_DETAIL_SWIZZLE_qpsp 3, 2, 0, 2 // Select q, then p, then s, then p in that order.
5138#define SHDR_DETAIL_SWIZZLE_qpsq 3, 2, 0, 3 // Select q, then p, then s, then q in that order.
5139#define SHDR_DETAIL_SWIZZLE_qpts 3, 2, 1, 0 // Select q, then p, then t, then s in that order.
5140#define SHDR_DETAIL_SWIZZLE_qptt 3, 2, 1, 1 // Select q, then p, then t, then t in that order.
5141#define SHDR_DETAIL_SWIZZLE_qptp 3, 2, 1, 2 // Select q, then p, then t, then p in that order.
5142#define SHDR_DETAIL_SWIZZLE_qptq 3, 2, 1, 3 // Select q, then p, then t, then q in that order.
5143#define SHDR_DETAIL_SWIZZLE_qpps 3, 2, 2, 0 // Select q, then p, then p, then s in that order.
5144#define SHDR_DETAIL_SWIZZLE_qppt 3, 2, 2, 1 // Select q, then p, then p, then t in that order.
5145#define SHDR_DETAIL_SWIZZLE_qppp 3, 2, 2, 2 // Select q, then p, then p, then p in that order.
5146#define SHDR_DETAIL_SWIZZLE_qppq 3, 2, 2, 3 // Select q, then p, then p, then q in that order.
5147#define SHDR_DETAIL_SWIZZLE_qpqs 3, 2, 3, 0 // Select q, then p, then q, then s in that order.
5148#define SHDR_DETAIL_SWIZZLE_qpqt 3, 2, 3, 1 // Select q, then p, then q, then t in that order.
5149#define SHDR_DETAIL_SWIZZLE_qpqp 3, 2, 3, 2 // Select q, then p, then q, then p in that order.
5150#define SHDR_DETAIL_SWIZZLE_qpqq 3, 2, 3, 3 // Select q, then p, then q, then q in that order.
5151#define SHDR_DETAIL_SWIZZLE_qqss 3, 3, 0, 0 // Select q, then q, then s, then s in that order.
5152#define SHDR_DETAIL_SWIZZLE_qqst 3, 3, 0, 1 // Select q, then q, then s, then t in that order.
5153#define SHDR_DETAIL_SWIZZLE_qqsp 3, 3, 0, 2 // Select q, then q, then s, then p in that order.
5154#define SHDR_DETAIL_SWIZZLE_qqsq 3, 3, 0, 3 // Select q, then q, then s, then q in that order.
5155#define SHDR_DETAIL_SWIZZLE_qqts 3, 3, 1, 0 // Select q, then q, then t, then s in that order.
5156#define SHDR_DETAIL_SWIZZLE_qqtt 3, 3, 1, 1 // Select q, then q, then t, then t in that order.
5157#define SHDR_DETAIL_SWIZZLE_qqtp 3, 3, 1, 2 // Select q, then q, then t, then p in that order.
5158#define SHDR_DETAIL_SWIZZLE_qqtq 3, 3, 1, 3 // Select q, then q, then t, then q in that order.
5159#define SHDR_DETAIL_SWIZZLE_qqps 3, 3, 2, 0 // Select q, then q, then p, then s in that order.
5160#define SHDR_DETAIL_SWIZZLE_qqpt 3, 3, 2, 1 // Select q, then q, then p, then t in that order.
5161#define SHDR_DETAIL_SWIZZLE_qqpp 3, 3, 2, 2 // Select q, then q, then p, then p in that order.
5162#define SHDR_DETAIL_SWIZZLE_qqpq 3, 3, 2, 3 // Select q, then q, then p, then q in that order.
5163#define SHDR_DETAIL_SWIZZLE_qqqs 3, 3, 3, 0 // Select q, then q, then q, then s in that order.
5164#define SHDR_DETAIL_SWIZZLE_qqqt 3, 3, 3, 1 // Select q, then q, then q, then t in that order.
5165#define SHDR_DETAIL_SWIZZLE_qqqp 3, 3, 3, 2 // Select q, then q, then q, then p in that order.
5166#define SHDR_DETAIL_SWIZZLE_qqqq 3, 3, 3, 3 // Select q, then q, then q, then q in that order.
5167
5168#endif // SHDR_MACROS_HPP
5169
5170#endif // SHDR_SINGLE_HEADER_INCLUDED