Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Cross.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChip Davis <chip@holochip.com>2022-08-05 11:16:45 +0300
committerChip Davis <chip@holochip.com>2022-08-08 03:31:41 +0300
commitfc4a12fd4f248d46cdce5832f7ce0ce7f5e03da8 (patch)
treee26754e75c46fbad282dd03f9ba54f93a6fb2a1d
parentfaea931de341a6de7360d9d42fccd4b7b066c0f9 (diff)
MSL: Use a wrapper type for matrices in workgroup storage.
The standard `matrix` type in MSL lacked a constructor in the `threadgroup` AS. This means that it was impossible to declare a `threadgroup` variable that contains a matrix. This appears to have been an oversight that was corrected in macOS 13/Xcode 14 beta 4. This workaround continues to be required, however, for older systems. To avoid changing interfaces unnecessarily (which shouldn't be a problem regardless because the old and new types take up the same amount of storage), only do this for structs if the struct is positively identified as being used for workgroup storage. I'm entirely aware this is inconsistent with the way packed matrices are handled. One of them should be changed to match the other. Not sure which one. Fixes 23 CTS tests under `dEQP-VK.memory_model.shared`.
-rw-r--r--reference/opt/shaders-msl/comp/shared-matrix-array-of-array.comp1353
-rw-r--r--reference/opt/shaders-msl/comp/shared-matrix-cast.comp1017
-rw-r--r--reference/opt/shaders-msl/comp/shared-matrix-nested-struct-array.comp1369
-rw-r--r--reference/opt/shaders-msl/comp/shared-matrix-nested-struct.comp1443
-rw-r--r--reference/shaders-msl/comp/shared-matrix-array-of-array.comp1286
-rw-r--r--reference/shaders-msl/comp/shared-matrix-cast.comp1065
-rw-r--r--reference/shaders-msl/comp/shared-matrix-nested-struct-array.comp1316
-rw-r--r--reference/shaders-msl/comp/shared-matrix-nested-struct.comp1473
-rw-r--r--shaders-msl/comp/shared-matrix-array-of-array.comp65
-rw-r--r--shaders-msl/comp/shared-matrix-cast.comp33
-rw-r--r--shaders-msl/comp/shared-matrix-nested-struct-array.comp87
-rw-r--r--shaders-msl/comp/shared-matrix-nested-struct.comp141
-rw-r--r--spirv_common.hpp6
-rw-r--r--spirv_glsl.cpp6
-rw-r--r--spirv_msl.cpp243
-rw-r--r--spirv_msl.hpp2
16 files changed, 10898 insertions, 7 deletions
diff --git a/reference/opt/shaders-msl/comp/shared-matrix-array-of-array.comp b/reference/opt/shaders-msl/comp/shared-matrix-array-of-array.comp
new file mode 100644
index 00000000..0e17f95c
--- /dev/null
+++ b/reference/opt/shaders-msl/comp/shared-matrix-array-of-array.comp
@@ -0,0 +1,1353 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+#pragma clang diagnostic ignored "-Wmissing-braces"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+template<typename T, size_t Num>
+struct spvUnsafeArray
+{
+ T elements[Num ? Num : 1];
+
+ thread T& operator [] (size_t pos) thread
+ {
+ return elements[pos];
+ }
+ constexpr const thread T& operator [] (size_t pos) const thread
+ {
+ return elements[pos];
+ }
+
+ device T& operator [] (size_t pos) device
+ {
+ return elements[pos];
+ }
+ constexpr const device T& operator [] (size_t pos) const device
+ {
+ return elements[pos];
+ }
+
+ constexpr const constant T& operator [] (size_t pos) const constant
+ {
+ return elements[pos];
+ }
+
+ threadgroup T& operator [] (size_t pos) threadgroup
+ {
+ return elements[pos];
+ }
+ constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
+ {
+ return elements[pos];
+ }
+};
+
+template<typename T, int Cols, int Rows=Cols>
+struct spvStorageMatrix
+{
+ vec<T, Rows> columns[Cols];
+
+ spvStorageMatrix() thread = default;
+ thread spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) thread
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const thread spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const constant spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const device spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) thread = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const thread
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const thread
+ {
+ return columns[idx];
+ }
+ thread vec<T, Rows>& operator[](size_t idx) thread
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() constant = default;
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) constant = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const constant
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const constant
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() device = default;
+ device spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) device
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const thread spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const constant spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const device spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) device = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) device = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const device
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const device
+ {
+ return columns[idx];
+ }
+ device vec<T, Rows>& operator[](size_t idx) device
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup
+ {
+ return columns[idx];
+ }
+ threadgroup vec<T, Rows>& operator[](size_t idx) threadgroup
+ {
+ return columns[idx];
+ }
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix() threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup_imageblock
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup_imageblock
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ threadgroup_imageblock vec<T, Rows>& operator[](size_t idx) threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix() ray_data = default;
+ ray_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) ray_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const ray_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const ray_data
+ {
+ return columns[idx];
+ }
+ ray_data vec<T, Rows>& operator[](size_t idx) ray_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix() object_data = default;
+ object_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) object_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) object_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) object_data = default;
+ #endif
+
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) object_data = default;
+
+ operator matrix<T, Cols, Rows>() const object_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const object_data
+ {
+ return columns[idx];
+ }
+ object_data vec<T, Rows>& operator[](size_t idx) object_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+};
+
+template<typename T, int Cols, int Rows>
+matrix<T, Rows, Cols> transpose(spvStorageMatrix<T, Cols, Rows> m)
+{
+ return transpose(matrix<T, Cols, Rows>(m));
+}
+
+typedef spvStorageMatrix<half, 2, 2> spvStorage_half2x2;
+typedef spvStorageMatrix<half, 2, 3> spvStorage_half2x3;
+typedef spvStorageMatrix<half, 2, 4> spvStorage_half2x4;
+typedef spvStorageMatrix<half, 3, 2> spvStorage_half3x2;
+typedef spvStorageMatrix<half, 3, 3> spvStorage_half3x3;
+typedef spvStorageMatrix<half, 3, 4> spvStorage_half3x4;
+typedef spvStorageMatrix<half, 4, 2> spvStorage_half4x2;
+typedef spvStorageMatrix<half, 4, 3> spvStorage_half4x3;
+typedef spvStorageMatrix<half, 4, 4> spvStorage_half4x4;
+typedef spvStorageMatrix<float, 2, 2> spvStorage_float2x2;
+typedef spvStorageMatrix<float, 2, 3> spvStorage_float2x3;
+typedef spvStorageMatrix<float, 2, 4> spvStorage_float2x4;
+typedef spvStorageMatrix<float, 3, 2> spvStorage_float3x2;
+typedef spvStorageMatrix<float, 3, 3> spvStorage_float3x3;
+typedef spvStorageMatrix<float, 3, 4> spvStorage_float3x4;
+typedef spvStorageMatrix<float, 4, 2> spvStorage_float4x2;
+typedef spvStorageMatrix<float, 4, 3> spvStorage_float4x3;
+typedef spvStorageMatrix<float, 4, 4> spvStorage_float4x4;
+
+struct S1
+{
+ spvStorage_float4x3 a[2];
+ float b;
+ spvUnsafeArray<float2, 3> c;
+};
+
+struct S2
+{
+ int4 a;
+ spvUnsafeArray<spvUnsafeArray<spvUnsafeArray<short, 3>, 1>, 3> b;
+};
+
+struct block
+{
+ uint passed;
+};
+
+constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(1u);
+
+kernel void main0(device block& _383 [[buffer(0)]])
+{
+ threadgroup S1 s1;
+ threadgroup S2 s2;
+ s1.a[0] = spvStorage_float4x3(float4x3(float3(0.0, 2.0, -8.0), float3(6.0, 7.0, 5.0), float3(-6.0, 1.0, 9.0), float3(-4.0, -3.0, 4.0)));
+ s1.a[1] = spvStorage_float4x3(float4x3(float3(4.0, 9.0, -9.0), float3(-8.0, -9.0, 8.0), float3(0.0, 4.0, -4.0), float3(7.0, 2.0, -1.0)));
+ s1.b = 7.0;
+ s1.c[0] = float2(-5.0, -4.0);
+ s1.c[1] = float2(3.0, -5.0);
+ s1.c[2] = float2(-3.0, -1.0);
+ s2.a = int4(1, 0, -3, 1);
+ s2.b[0][0][0] = short(true);
+ s2.b[0][0][1] = short(false);
+ s2.b[0][0][2] = short(false);
+ s2.b[1][0][0] = short(true);
+ s2.b[1][0][1] = short(false);
+ s2.b[1][0][2] = short(true);
+ s2.b[2][0][0] = short(false);
+ s2.b[2][0][1] = short(true);
+ s2.b[2][0][2] = short(true);
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup | mem_flags::mem_texture);
+ bool _464 = abs(-float4x3(s1.a[0])[0].x) < 0.0500000007450580596923828125;
+ bool _449;
+ if (_464)
+ {
+ _449 = abs(2.0 - float4x3(s1.a[0])[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _449 = _464;
+ }
+ bool _457;
+ if (_449)
+ {
+ _457 = abs((-8.0) - float4x3(s1.a[0])[0].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _457 = _449;
+ }
+ bool _412;
+ if (_457)
+ {
+ bool _514 = abs(6.0 - float4x3(s1.a[0])[1].x) < 0.0500000007450580596923828125;
+ bool _499;
+ if (_514)
+ {
+ _499 = abs(7.0 - float4x3(s1.a[0])[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _499 = _514;
+ }
+ bool _507;
+ if (_499)
+ {
+ _507 = abs(5.0 - float4x3(s1.a[0])[1].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _507 = _499;
+ }
+ _412 = _507;
+ }
+ else
+ {
+ _412 = _457;
+ }
+ bool _420;
+ if (_412)
+ {
+ bool _564 = abs((-6.0) - float4x3(s1.a[0])[2].x) < 0.0500000007450580596923828125;
+ bool _549;
+ if (_564)
+ {
+ _549 = abs(1.0 - float4x3(s1.a[0])[2].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _549 = _564;
+ }
+ bool _557;
+ if (_549)
+ {
+ _557 = abs(9.0 - float4x3(s1.a[0])[2].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _557 = _549;
+ }
+ _420 = _557;
+ }
+ else
+ {
+ _420 = _412;
+ }
+ bool _428;
+ if (_420)
+ {
+ bool _614 = abs((-4.0) - float4x3(s1.a[0])[3].x) < 0.0500000007450580596923828125;
+ bool _599;
+ if (_614)
+ {
+ _599 = abs((-3.0) - float4x3(s1.a[0])[3].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _599 = _614;
+ }
+ bool _607;
+ if (_599)
+ {
+ _607 = abs(4.0 - float4x3(s1.a[0])[3].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _607 = _599;
+ }
+ _428 = _607;
+ }
+ else
+ {
+ _428 = _420;
+ }
+ bool _251;
+ if (_428)
+ {
+ bool _703 = abs(4.0 - float4x3(s1.a[1])[0].x) < 0.0500000007450580596923828125;
+ bool _688;
+ if (_703)
+ {
+ _688 = abs(9.0 - float4x3(s1.a[1])[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _688 = _703;
+ }
+ bool _696;
+ if (_688)
+ {
+ _696 = abs((-9.0) - float4x3(s1.a[1])[0].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _696 = _688;
+ }
+ bool _651;
+ if (_696)
+ {
+ bool _753 = abs((-8.0) - float4x3(s1.a[1])[1].x) < 0.0500000007450580596923828125;
+ bool _738;
+ if (_753)
+ {
+ _738 = abs((-9.0) - float4x3(s1.a[1])[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _738 = _753;
+ }
+ bool _746;
+ if (_738)
+ {
+ _746 = abs(8.0 - float4x3(s1.a[1])[1].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _746 = _738;
+ }
+ _651 = _746;
+ }
+ else
+ {
+ _651 = _696;
+ }
+ bool _659;
+ if (_651)
+ {
+ bool _803 = abs(-float4x3(s1.a[1])[2].x) < 0.0500000007450580596923828125;
+ bool _788;
+ if (_803)
+ {
+ _788 = abs(4.0 - float4x3(s1.a[1])[2].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _788 = _803;
+ }
+ bool _796;
+ if (_788)
+ {
+ _796 = abs((-4.0) - float4x3(s1.a[1])[2].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _796 = _788;
+ }
+ _659 = _796;
+ }
+ else
+ {
+ _659 = _651;
+ }
+ bool _667;
+ if (_659)
+ {
+ bool _853 = abs(7.0 - float4x3(s1.a[1])[3].x) < 0.0500000007450580596923828125;
+ bool _838;
+ if (_853)
+ {
+ _838 = abs(2.0 - float4x3(s1.a[1])[3].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _838 = _853;
+ }
+ bool _846;
+ if (_838)
+ {
+ _846 = abs((-1.0) - float4x3(s1.a[1])[3].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _846 = _838;
+ }
+ _667 = _846;
+ }
+ else
+ {
+ _667 = _659;
+ }
+ _251 = _667;
+ }
+ else
+ {
+ _251 = _428;
+ }
+ bool _260;
+ if (_251)
+ {
+ _260 = abs(7.0 - s1.b) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _260 = _251;
+ }
+ bool _269;
+ if (_260)
+ {
+ bool _900 = abs((-5.0) - s1.c[0].x) < 0.0500000007450580596923828125;
+ bool _893;
+ if (_900)
+ {
+ _893 = abs((-4.0) - s1.c[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _893 = _900;
+ }
+ _269 = _893;
+ }
+ else
+ {
+ _269 = _260;
+ }
+ bool _278;
+ if (_269)
+ {
+ bool _933 = abs(3.0 - s1.c[1].x) < 0.0500000007450580596923828125;
+ bool _926;
+ if (_933)
+ {
+ _926 = abs((-5.0) - s1.c[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _926 = _933;
+ }
+ _278 = _926;
+ }
+ else
+ {
+ _278 = _269;
+ }
+ bool _287;
+ if (_278)
+ {
+ bool _966 = abs((-3.0) - s1.c[2].x) < 0.0500000007450580596923828125;
+ bool _959;
+ if (_966)
+ {
+ _959 = abs((-1.0) - s1.c[2].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _959 = _966;
+ }
+ _287 = _959;
+ }
+ else
+ {
+ _287 = _278;
+ }
+ bool _296;
+ if (_287)
+ {
+ _296 = all(int4(1, 0, -3, 1) == s2.a);
+ }
+ else
+ {
+ _296 = _287;
+ }
+ bool _305;
+ if (_296)
+ {
+ _305 = true == bool(s2.b[0][0][0]);
+ }
+ else
+ {
+ _305 = _296;
+ }
+ bool _314;
+ if (_305)
+ {
+ _314 = false == bool(s2.b[0][0][1]);
+ }
+ else
+ {
+ _314 = _305;
+ }
+ bool _323;
+ if (_314)
+ {
+ _323 = false == bool(s2.b[0][0][2]);
+ }
+ else
+ {
+ _323 = _314;
+ }
+ bool _332;
+ if (_323)
+ {
+ _332 = true == bool(s2.b[1][0][0]);
+ }
+ else
+ {
+ _332 = _323;
+ }
+ bool _341;
+ if (_332)
+ {
+ _341 = false == bool(s2.b[1][0][1]);
+ }
+ else
+ {
+ _341 = _332;
+ }
+ bool _350;
+ if (_341)
+ {
+ _350 = true == bool(s2.b[1][0][2]);
+ }
+ else
+ {
+ _350 = _341;
+ }
+ bool _359;
+ if (_350)
+ {
+ _359 = false == bool(s2.b[2][0][0]);
+ }
+ else
+ {
+ _359 = _350;
+ }
+ bool _368;
+ if (_359)
+ {
+ _368 = true == bool(s2.b[2][0][1]);
+ }
+ else
+ {
+ _368 = _359;
+ }
+ bool _377;
+ if (_368)
+ {
+ _377 = true == bool(s2.b[2][0][2]);
+ }
+ else
+ {
+ _377 = _368;
+ }
+ if (_377)
+ {
+ _383.passed++;
+ }
+}
+
diff --git a/reference/opt/shaders-msl/comp/shared-matrix-cast.comp b/reference/opt/shaders-msl/comp/shared-matrix-cast.comp
new file mode 100644
index 00000000..32c8e823
--- /dev/null
+++ b/reference/opt/shaders-msl/comp/shared-matrix-cast.comp
@@ -0,0 +1,1017 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+template<typename T, int Cols, int Rows=Cols>
+struct spvStorageMatrix
+{
+ vec<T, Rows> columns[Cols];
+
+ spvStorageMatrix() thread = default;
+ thread spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) thread
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const thread spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const constant spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const device spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) thread = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const thread
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const thread
+ {
+ return columns[idx];
+ }
+ thread vec<T, Rows>& operator[](size_t idx) thread
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() constant = default;
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) constant = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const constant
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const constant
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() device = default;
+ device spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) device
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const thread spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const constant spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const device spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) device = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) device = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const device
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const device
+ {
+ return columns[idx];
+ }
+ device vec<T, Rows>& operator[](size_t idx) device
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup
+ {
+ return columns[idx];
+ }
+ threadgroup vec<T, Rows>& operator[](size_t idx) threadgroup
+ {
+ return columns[idx];
+ }
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix() threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup_imageblock
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup_imageblock
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ threadgroup_imageblock vec<T, Rows>& operator[](size_t idx) threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix() ray_data = default;
+ ray_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) ray_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const ray_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const ray_data
+ {
+ return columns[idx];
+ }
+ ray_data vec<T, Rows>& operator[](size_t idx) ray_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix() object_data = default;
+ object_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) object_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) object_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) object_data = default;
+ #endif
+
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) object_data = default;
+
+ operator matrix<T, Cols, Rows>() const object_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const object_data
+ {
+ return columns[idx];
+ }
+ object_data vec<T, Rows>& operator[](size_t idx) object_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+};
+
+template<typename T, int Cols, int Rows>
+matrix<T, Rows, Cols> transpose(spvStorageMatrix<T, Cols, Rows> m)
+{
+ return transpose(matrix<T, Cols, Rows>(m));
+}
+
+typedef spvStorageMatrix<half, 2, 2> spvStorage_half2x2;
+typedef spvStorageMatrix<half, 2, 3> spvStorage_half2x3;
+typedef spvStorageMatrix<half, 2, 4> spvStorage_half2x4;
+typedef spvStorageMatrix<half, 3, 2> spvStorage_half3x2;
+typedef spvStorageMatrix<half, 3, 3> spvStorage_half3x3;
+typedef spvStorageMatrix<half, 3, 4> spvStorage_half3x4;
+typedef spvStorageMatrix<half, 4, 2> spvStorage_half4x2;
+typedef spvStorageMatrix<half, 4, 3> spvStorage_half4x3;
+typedef spvStorageMatrix<half, 4, 4> spvStorage_half4x4;
+typedef spvStorageMatrix<float, 2, 2> spvStorage_float2x2;
+typedef spvStorageMatrix<float, 2, 3> spvStorage_float2x3;
+typedef spvStorageMatrix<float, 2, 4> spvStorage_float2x4;
+typedef spvStorageMatrix<float, 3, 2> spvStorage_float3x2;
+typedef spvStorageMatrix<float, 3, 3> spvStorage_float3x3;
+typedef spvStorageMatrix<float, 3, 4> spvStorage_float3x4;
+typedef spvStorageMatrix<float, 4, 2> spvStorage_float4x2;
+typedef spvStorageMatrix<float, 4, 3> spvStorage_float4x3;
+typedef spvStorageMatrix<float, 4, 4> spvStorage_float4x4;
+
+struct S1
+{
+ float4 a;
+ spvStorage_float3x2 b;
+ short4 c;
+};
+
+struct block
+{
+ uint passed;
+};
+
+constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(1u);
+
+kernel void main0(device block& _212 [[buffer(0)]])
+{
+ threadgroup S1 s1;
+ s1.a = float4(1.0, -5.0, -9.0, -5.0);
+ s1.b = spvStorage_float3x2(float3x2(float2(1.0, -7.0), float2(1.0, 2.0), float2(8.0, 7.0)));
+ s1.c = short4(bool4(false, true, false, false));
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup | mem_flags::mem_texture);
+ bool _264 = abs(1.0 - s1.a.x) < 0.0500000007450580596923828125;
+ bool _241;
+ if (_264)
+ {
+ _241 = abs((-5.0) - s1.a.y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _241 = _264;
+ }
+ bool _249;
+ if (_241)
+ {
+ _249 = abs((-9.0) - s1.a.z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _249 = _241;
+ }
+ bool _257;
+ if (_249)
+ {
+ _257 = abs((-5.0) - s1.a.w) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _257 = _249;
+ }
+ bool _197;
+ if (_257)
+ {
+ bool _340 = abs(1.0 - float3x2(s1.b)[0].x) < 0.0500000007450580596923828125;
+ bool _333;
+ if (_340)
+ {
+ _333 = abs((-7.0) - float3x2(s1.b)[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _333 = _340;
+ }
+ bool _306;
+ if (_333)
+ {
+ bool _373 = abs(1.0 - float3x2(s1.b)[1].x) < 0.0500000007450580596923828125;
+ bool _366;
+ if (_373)
+ {
+ _366 = abs(2.0 - float3x2(s1.b)[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _366 = _373;
+ }
+ _306 = _366;
+ }
+ else
+ {
+ _306 = _333;
+ }
+ bool _314;
+ if (_306)
+ {
+ bool _406 = abs(8.0 - float3x2(s1.b)[2].x) < 0.0500000007450580596923828125;
+ bool _399;
+ if (_406)
+ {
+ _399 = abs(7.0 - float3x2(s1.b)[2].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _399 = _406;
+ }
+ _314 = _399;
+ }
+ else
+ {
+ _314 = _306;
+ }
+ _197 = _314;
+ }
+ else
+ {
+ _197 = _257;
+ }
+ bool _206;
+ if (_197)
+ {
+ _206 = all(bool4(false, true, false, false) == bool4(s1.c));
+ }
+ else
+ {
+ _206 = _197;
+ }
+ if (_206)
+ {
+ _212.passed++;
+ }
+}
+
diff --git a/reference/opt/shaders-msl/comp/shared-matrix-nested-struct-array.comp b/reference/opt/shaders-msl/comp/shared-matrix-nested-struct-array.comp
new file mode 100644
index 00000000..dfbd7a76
--- /dev/null
+++ b/reference/opt/shaders-msl/comp/shared-matrix-nested-struct-array.comp
@@ -0,0 +1,1369 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+#pragma clang diagnostic ignored "-Wmissing-braces"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+template<typename T, size_t Num>
+struct spvUnsafeArray
+{
+ T elements[Num ? Num : 1];
+
+ thread T& operator [] (size_t pos) thread
+ {
+ return elements[pos];
+ }
+ constexpr const thread T& operator [] (size_t pos) const thread
+ {
+ return elements[pos];
+ }
+
+ device T& operator [] (size_t pos) device
+ {
+ return elements[pos];
+ }
+ constexpr const device T& operator [] (size_t pos) const device
+ {
+ return elements[pos];
+ }
+
+ constexpr const constant T& operator [] (size_t pos) const constant
+ {
+ return elements[pos];
+ }
+
+ threadgroup T& operator [] (size_t pos) threadgroup
+ {
+ return elements[pos];
+ }
+ constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
+ {
+ return elements[pos];
+ }
+};
+
+template<typename T, int Cols, int Rows=Cols>
+struct spvStorageMatrix
+{
+ vec<T, Rows> columns[Cols];
+
+ spvStorageMatrix() thread = default;
+ thread spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) thread
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const thread spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const constant spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const device spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) thread = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const thread
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const thread
+ {
+ return columns[idx];
+ }
+ thread vec<T, Rows>& operator[](size_t idx) thread
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() constant = default;
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) constant = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const constant
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const constant
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() device = default;
+ device spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) device
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const thread spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const constant spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const device spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) device = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) device = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const device
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const device
+ {
+ return columns[idx];
+ }
+ device vec<T, Rows>& operator[](size_t idx) device
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup
+ {
+ return columns[idx];
+ }
+ threadgroup vec<T, Rows>& operator[](size_t idx) threadgroup
+ {
+ return columns[idx];
+ }
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix() threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup_imageblock
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup_imageblock
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ threadgroup_imageblock vec<T, Rows>& operator[](size_t idx) threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix() ray_data = default;
+ ray_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) ray_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const ray_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const ray_data
+ {
+ return columns[idx];
+ }
+ ray_data vec<T, Rows>& operator[](size_t idx) ray_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix() object_data = default;
+ object_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) object_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) object_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) object_data = default;
+ #endif
+
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) object_data = default;
+
+ operator matrix<T, Cols, Rows>() const object_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const object_data
+ {
+ return columns[idx];
+ }
+ object_data vec<T, Rows>& operator[](size_t idx) object_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+};
+
+template<typename T, int Cols, int Rows>
+matrix<T, Rows, Cols> transpose(spvStorageMatrix<T, Cols, Rows> m)
+{
+ return transpose(matrix<T, Cols, Rows>(m));
+}
+
+typedef spvStorageMatrix<half, 2, 2> spvStorage_half2x2;
+typedef spvStorageMatrix<half, 2, 3> spvStorage_half2x3;
+typedef spvStorageMatrix<half, 2, 4> spvStorage_half2x4;
+typedef spvStorageMatrix<half, 3, 2> spvStorage_half3x2;
+typedef spvStorageMatrix<half, 3, 3> spvStorage_half3x3;
+typedef spvStorageMatrix<half, 3, 4> spvStorage_half3x4;
+typedef spvStorageMatrix<half, 4, 2> spvStorage_half4x2;
+typedef spvStorageMatrix<half, 4, 3> spvStorage_half4x3;
+typedef spvStorageMatrix<half, 4, 4> spvStorage_half4x4;
+typedef spvStorageMatrix<float, 2, 2> spvStorage_float2x2;
+typedef spvStorageMatrix<float, 2, 3> spvStorage_float2x3;
+typedef spvStorageMatrix<float, 2, 4> spvStorage_float2x4;
+typedef spvStorageMatrix<float, 3, 2> spvStorage_float3x2;
+typedef spvStorageMatrix<float, 3, 3> spvStorage_float3x3;
+typedef spvStorageMatrix<float, 3, 4> spvStorage_float3x4;
+typedef spvStorageMatrix<float, 4, 2> spvStorage_float4x2;
+typedef spvStorageMatrix<float, 4, 3> spvStorage_float4x3;
+typedef spvStorageMatrix<float, 4, 4> spvStorage_float4x4;
+
+struct sA
+{
+ spvStorage_float2x3 mA;
+};
+
+struct sB
+{
+ spvStorage_float2x2 mA;
+ spvStorage_float3x2 mB;
+ uint3 mC;
+};
+
+struct sC
+{
+ sA mA;
+ sB mB;
+};
+
+struct sD
+{
+ sC mA;
+};
+
+struct sE
+{
+ spvStorage_float3x2 mA;
+ spvStorage_float4x3 mB;
+};
+
+struct sF
+{
+ sE mA;
+};
+
+struct sG
+{
+ sF mA;
+};
+
+struct sH
+{
+ spvUnsafeArray<short3, 2> mA;
+};
+
+struct S1
+{
+ sD a;
+ sG b;
+ spvUnsafeArray<sH, 2> c;
+};
+
+struct block
+{
+ uint passed;
+};
+
+constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(1u);
+
+kernel void main0(device block& _424 [[buffer(0)]])
+{
+ threadgroup S1 s1;
+ s1.a.mA.mA.mA = spvStorage_float2x3(float2x3(float3(6.0, 8.0, 8.0), float3(0.0, -4.0, -5.0)));
+ s1.a.mA.mB.mA = spvStorage_float2x2(float2x2(float2(9.0, -4.0), float2(-6.0, -1.0)));
+ s1.a.mA.mB.mB = spvStorage_float3x2(float3x2(float2(-1.0, -2.0), float2(1.0, 6.0), float2(5.0, 7.0)));
+ s1.a.mA.mB.mC = uint3(3u, 1u, 5u);
+ s1.b.mA.mA.mA = spvStorage_float3x2(float3x2(float2(8.0, 3.0), float2(0.0, 2.0), float2(1.0, 8.0)));
+ s1.b.mA.mA.mB = spvStorage_float4x3(float4x3(float3(0.0, 9.0, -1.0), float3(-1.0, -7.0, 7.0), float3(-4.0, -3.0, 1.0), float3(-4.0, -9.0, 1.0)));
+ s1.c[0].mA[0] = short3(bool3(true, false, false));
+ s1.c[0].mA[1] = short3(bool3(true, false, false));
+ s1.c[1].mA[0] = short3(bool3(false));
+ s1.c[1].mA[1] = short3(bool3(false));
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup | mem_flags::mem_texture);
+ bool _484 = abs(6.0 - float2x3(s1.a.mA.mA.mA)[0].x) < 0.0500000007450580596923828125;
+ bool _469;
+ if (_484)
+ {
+ _469 = abs(8.0 - float2x3(s1.a.mA.mA.mA)[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _469 = _484;
+ }
+ bool _477;
+ if (_469)
+ {
+ _477 = abs(8.0 - float2x3(s1.a.mA.mA.mA)[0].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _477 = _469;
+ }
+ bool _448;
+ if (_477)
+ {
+ bool _534 = abs(-float2x3(s1.a.mA.mA.mA)[1].x) < 0.0500000007450580596923828125;
+ bool _519;
+ if (_534)
+ {
+ _519 = abs((-4.0) - float2x3(s1.a.mA.mA.mA)[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _519 = _534;
+ }
+ bool _527;
+ if (_519)
+ {
+ _527 = abs((-5.0) - float2x3(s1.a.mA.mA.mA)[1].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _527 = _519;
+ }
+ _448 = _527;
+ }
+ else
+ {
+ _448 = _477;
+ }
+ bool _346;
+ if (_448)
+ {
+ bool _593 = abs(9.0 - float2x2(s1.a.mA.mB.mA)[0].x) < 0.0500000007450580596923828125;
+ bool _586;
+ if (_593)
+ {
+ _586 = abs((-4.0) - float2x2(s1.a.mA.mB.mA)[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _586 = _593;
+ }
+ bool _567;
+ if (_586)
+ {
+ bool _626 = abs((-6.0) - float2x2(s1.a.mA.mB.mA)[1].x) < 0.0500000007450580596923828125;
+ bool _619;
+ if (_626)
+ {
+ _619 = abs((-1.0) - float2x2(s1.a.mA.mB.mA)[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _619 = _626;
+ }
+ _567 = _619;
+ }
+ else
+ {
+ _567 = _586;
+ }
+ _346 = _567;
+ }
+ else
+ {
+ _346 = _448;
+ }
+ bool _355;
+ if (_346)
+ {
+ bool _688 = abs((-1.0) - float3x2(s1.a.mA.mB.mB)[0].x) < 0.0500000007450580596923828125;
+ bool _681;
+ if (_688)
+ {
+ _681 = abs((-2.0) - float3x2(s1.a.mA.mB.mB)[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _681 = _688;
+ }
+ bool _654;
+ if (_681)
+ {
+ bool _721 = abs(1.0 - float3x2(s1.a.mA.mB.mB)[1].x) < 0.0500000007450580596923828125;
+ bool _714;
+ if (_721)
+ {
+ _714 = abs(6.0 - float3x2(s1.a.mA.mB.mB)[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _714 = _721;
+ }
+ _654 = _714;
+ }
+ else
+ {
+ _654 = _681;
+ }
+ bool _662;
+ if (_654)
+ {
+ bool _754 = abs(5.0 - float3x2(s1.a.mA.mB.mB)[2].x) < 0.0500000007450580596923828125;
+ bool _747;
+ if (_754)
+ {
+ _747 = abs(7.0 - float3x2(s1.a.mA.mB.mB)[2].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _747 = _754;
+ }
+ _662 = _747;
+ }
+ else
+ {
+ _662 = _654;
+ }
+ _355 = _662;
+ }
+ else
+ {
+ _355 = _346;
+ }
+ bool _364;
+ if (_355)
+ {
+ _364 = all(uint3(3u, 1u, 5u) == s1.a.mA.mB.mC);
+ }
+ else
+ {
+ _364 = _355;
+ }
+ bool _373;
+ if (_364)
+ {
+ bool _822 = abs(8.0 - float3x2(s1.b.mA.mA.mA)[0].x) < 0.0500000007450580596923828125;
+ bool _815;
+ if (_822)
+ {
+ _815 = abs(3.0 - float3x2(s1.b.mA.mA.mA)[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _815 = _822;
+ }
+ bool _788;
+ if (_815)
+ {
+ bool _855 = abs(-float3x2(s1.b.mA.mA.mA)[1].x) < 0.0500000007450580596923828125;
+ bool _848;
+ if (_855)
+ {
+ _848 = abs(2.0 - float3x2(s1.b.mA.mA.mA)[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _848 = _855;
+ }
+ _788 = _848;
+ }
+ else
+ {
+ _788 = _815;
+ }
+ bool _796;
+ if (_788)
+ {
+ bool _888 = abs(1.0 - float3x2(s1.b.mA.mA.mA)[2].x) < 0.0500000007450580596923828125;
+ bool _881;
+ if (_888)
+ {
+ _881 = abs(8.0 - float3x2(s1.b.mA.mA.mA)[2].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _881 = _888;
+ }
+ _796 = _881;
+ }
+ else
+ {
+ _796 = _788;
+ }
+ _373 = _796;
+ }
+ else
+ {
+ _373 = _364;
+ }
+ bool _382;
+ if (_373)
+ {
+ bool _970 = abs(-float4x3(s1.b.mA.mA.mB)[0].x) < 0.0500000007450580596923828125;
+ bool _955;
+ if (_970)
+ {
+ _955 = abs(9.0 - float4x3(s1.b.mA.mA.mB)[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _955 = _970;
+ }
+ bool _963;
+ if (_955)
+ {
+ _963 = abs((-1.0) - float4x3(s1.b.mA.mA.mB)[0].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _963 = _955;
+ }
+ bool _918;
+ if (_963)
+ {
+ bool _1020 = abs((-1.0) - float4x3(s1.b.mA.mA.mB)[1].x) < 0.0500000007450580596923828125;
+ bool _1005;
+ if (_1020)
+ {
+ _1005 = abs((-7.0) - float4x3(s1.b.mA.mA.mB)[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1005 = _1020;
+ }
+ bool _1013;
+ if (_1005)
+ {
+ _1013 = abs(7.0 - float4x3(s1.b.mA.mA.mB)[1].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1013 = _1005;
+ }
+ _918 = _1013;
+ }
+ else
+ {
+ _918 = _963;
+ }
+ bool _926;
+ if (_918)
+ {
+ bool _1070 = abs((-4.0) - float4x3(s1.b.mA.mA.mB)[2].x) < 0.0500000007450580596923828125;
+ bool _1055;
+ if (_1070)
+ {
+ _1055 = abs((-3.0) - float4x3(s1.b.mA.mA.mB)[2].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1055 = _1070;
+ }
+ bool _1063;
+ if (_1055)
+ {
+ _1063 = abs(1.0 - float4x3(s1.b.mA.mA.mB)[2].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1063 = _1055;
+ }
+ _926 = _1063;
+ }
+ else
+ {
+ _926 = _918;
+ }
+ bool _934;
+ if (_926)
+ {
+ bool _1120 = abs((-4.0) - float4x3(s1.b.mA.mA.mB)[3].x) < 0.0500000007450580596923828125;
+ bool _1105;
+ if (_1120)
+ {
+ _1105 = abs((-9.0) - float4x3(s1.b.mA.mA.mB)[3].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1105 = _1120;
+ }
+ bool _1113;
+ if (_1105)
+ {
+ _1113 = abs(1.0 - float4x3(s1.b.mA.mA.mB)[3].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1113 = _1105;
+ }
+ _934 = _1113;
+ }
+ else
+ {
+ _934 = _926;
+ }
+ _382 = _934;
+ }
+ else
+ {
+ _382 = _373;
+ }
+ bool _391;
+ if (_382)
+ {
+ _391 = all(bool3(true, false, false) == bool3(s1.c[0].mA[0]));
+ }
+ else
+ {
+ _391 = _382;
+ }
+ bool _400;
+ if (_391)
+ {
+ _400 = all(bool3(true, false, false) == bool3(s1.c[0].mA[1]));
+ }
+ else
+ {
+ _400 = _391;
+ }
+ bool _409;
+ if (_400)
+ {
+ _409 = all(bool3(false) == bool3(s1.c[1].mA[0]));
+ }
+ else
+ {
+ _409 = _400;
+ }
+ bool _418;
+ if (_409)
+ {
+ _418 = all(bool3(false) == bool3(s1.c[1].mA[1]));
+ }
+ else
+ {
+ _418 = _409;
+ }
+ if (_418)
+ {
+ _424.passed++;
+ }
+}
+
diff --git a/reference/opt/shaders-msl/comp/shared-matrix-nested-struct.comp b/reference/opt/shaders-msl/comp/shared-matrix-nested-struct.comp
new file mode 100644
index 00000000..65655366
--- /dev/null
+++ b/reference/opt/shaders-msl/comp/shared-matrix-nested-struct.comp
@@ -0,0 +1,1443 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+template<typename T, int Cols, int Rows=Cols>
+struct spvStorageMatrix
+{
+ vec<T, Rows> columns[Cols];
+
+ spvStorageMatrix() thread = default;
+ thread spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) thread
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const thread spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const constant spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const device spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) thread = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const thread
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const thread
+ {
+ return columns[idx];
+ }
+ thread vec<T, Rows>& operator[](size_t idx) thread
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() constant = default;
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) constant = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const constant
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const constant
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() device = default;
+ device spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) device
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const thread spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const constant spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const device spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) device = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) device = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const device
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const device
+ {
+ return columns[idx];
+ }
+ device vec<T, Rows>& operator[](size_t idx) device
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup
+ {
+ return columns[idx];
+ }
+ threadgroup vec<T, Rows>& operator[](size_t idx) threadgroup
+ {
+ return columns[idx];
+ }
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix() threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup_imageblock
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup_imageblock
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ threadgroup_imageblock vec<T, Rows>& operator[](size_t idx) threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix() ray_data = default;
+ ray_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) ray_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const ray_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const ray_data
+ {
+ return columns[idx];
+ }
+ ray_data vec<T, Rows>& operator[](size_t idx) ray_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix() object_data = default;
+ object_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) object_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) object_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) object_data = default;
+ #endif
+
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) object_data = default;
+
+ operator matrix<T, Cols, Rows>() const object_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const object_data
+ {
+ return columns[idx];
+ }
+ object_data vec<T, Rows>& operator[](size_t idx) object_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+};
+
+template<typename T, int Cols, int Rows>
+matrix<T, Rows, Cols> transpose(spvStorageMatrix<T, Cols, Rows> m)
+{
+ return transpose(matrix<T, Cols, Rows>(m));
+}
+
+typedef spvStorageMatrix<half, 2, 2> spvStorage_half2x2;
+typedef spvStorageMatrix<half, 2, 3> spvStorage_half2x3;
+typedef spvStorageMatrix<half, 2, 4> spvStorage_half2x4;
+typedef spvStorageMatrix<half, 3, 2> spvStorage_half3x2;
+typedef spvStorageMatrix<half, 3, 3> spvStorage_half3x3;
+typedef spvStorageMatrix<half, 3, 4> spvStorage_half3x4;
+typedef spvStorageMatrix<half, 4, 2> spvStorage_half4x2;
+typedef spvStorageMatrix<half, 4, 3> spvStorage_half4x3;
+typedef spvStorageMatrix<half, 4, 4> spvStorage_half4x4;
+typedef spvStorageMatrix<float, 2, 2> spvStorage_float2x2;
+typedef spvStorageMatrix<float, 2, 3> spvStorage_float2x3;
+typedef spvStorageMatrix<float, 2, 4> spvStorage_float2x4;
+typedef spvStorageMatrix<float, 3, 2> spvStorage_float3x2;
+typedef spvStorageMatrix<float, 3, 3> spvStorage_float3x3;
+typedef spvStorageMatrix<float, 3, 4> spvStorage_float3x4;
+typedef spvStorageMatrix<float, 4, 2> spvStorage_float4x2;
+typedef spvStorageMatrix<float, 4, 3> spvStorage_float4x3;
+typedef spvStorageMatrix<float, 4, 4> spvStorage_float4x4;
+
+struct S1
+{
+ uint a;
+ float4 b;
+};
+
+struct sA
+{
+ spvStorage_float4x4 mA;
+ short3 mB;
+ short4 mC;
+};
+
+struct sB
+{
+ short2 mA;
+};
+
+struct sC
+{
+ float mA;
+ uint4 mB;
+ float mC;
+};
+
+struct sD
+{
+ sA mA;
+ sB mB;
+ sC mC;
+};
+
+struct sE
+{
+ sD mA;
+};
+
+struct sF
+{
+ uint3 mA;
+ short mB;
+};
+
+struct sG
+{
+ sF mA;
+ spvStorage_float3x2 mB;
+};
+
+struct sH
+{
+ sG mA;
+ float2 mB;
+};
+
+struct sI
+{
+ spvStorage_float2x2 mA;
+ short3 mB;
+ short4 mC;
+};
+
+struct sJ
+{
+ sI mA;
+ short3 mB;
+};
+
+struct sK
+{
+ short2 mA;
+ sJ mB;
+ int2 mC;
+};
+
+struct S2
+{
+ sE a;
+ int3 b;
+ sH c;
+ sK d;
+};
+
+struct block
+{
+ uint passed;
+};
+
+constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(1u);
+
+kernel void main0(device block& _612 [[buffer(0)]])
+{
+ threadgroup S1 s1;
+ threadgroup S2 s2;
+ s1.a = 0u;
+ s1.b = float4(8.0, 8.0, 0.0, -4.0);
+ s2.a.mA.mA.mA = spvStorage_float4x4(float4x4(float4(-5.0, 9.0, -4.0, -6.0), float4(-1.0, -1.0, -2.0, 1.0), float4(6.0, 5.0, 7.0, -2.0), float4(-4.0, -9.0, 8.0, 3.0)));
+ s2.a.mA.mA.mB = short3(bool3(true, false, false));
+ s2.a.mA.mA.mC = short4(bool4(true, true, true, false));
+ s2.a.mA.mB.mA = short2(bool2(true));
+ s2.a.mA.mC.mA = 7.0;
+ s2.a.mA.mC.mB = uint4(8u, 6u, 2u, 0u);
+ s2.a.mA.mC.mC = -9.0;
+ s2.b = int3(1, -4, 0);
+ s2.c.mA.mA.mA = uint3(4u, 9u, 1u);
+ s2.c.mA.mA.mB = short(false);
+ s2.c.mA.mB = spvStorage_float3x2(float3x2(float2(3.0, -5.0), float2(-1.0, -5.0), float2(-1.0, -9.0)));
+ s2.c.mB = float2(-6.0, -9.0);
+ s2.d.mA = short2(bool2(true, false));
+ s2.d.mB.mA.mA = spvStorage_float2x2(float2x2(float2(-2.0, 3.0), float2(7.0, 2.0)));
+ s2.d.mB.mA.mB = short3(bool3(false));
+ s2.d.mB.mA.mC = short4(bool4(false, false, false, true));
+ s2.d.mB.mB = short3(bool3(true, false, false));
+ s2.d.mC = int2(-9, 0);
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup | mem_flags::mem_texture);
+ bool _622 = 0u == s1.a;
+ bool _444;
+ if (_622)
+ {
+ bool _668 = abs(8.0 - s1.b.x) < 0.0500000007450580596923828125;
+ bool _645;
+ if (_668)
+ {
+ _645 = abs(8.0 - s1.b.y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _645 = _668;
+ }
+ bool _653;
+ if (_645)
+ {
+ _653 = abs(-s1.b.z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _653 = _645;
+ }
+ bool _661;
+ if (_653)
+ {
+ _661 = abs((-4.0) - s1.b.w) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _661 = _653;
+ }
+ _444 = _661;
+ }
+ else
+ {
+ _444 = _622;
+ }
+ bool _453;
+ if (_444)
+ {
+ bool _774 = abs((-5.0) - float4x4(s2.a.mA.mA.mA)[0].x) < 0.0500000007450580596923828125;
+ bool _751;
+ if (_774)
+ {
+ _751 = abs(9.0 - float4x4(s2.a.mA.mA.mA)[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _751 = _774;
+ }
+ bool _759;
+ if (_751)
+ {
+ _759 = abs((-4.0) - float4x4(s2.a.mA.mA.mA)[0].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _759 = _751;
+ }
+ bool _767;
+ if (_759)
+ {
+ _767 = abs((-6.0) - float4x4(s2.a.mA.mA.mA)[0].w) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _767 = _759;
+ }
+ bool _712;
+ if (_767)
+ {
+ bool _841 = abs((-1.0) - float4x4(s2.a.mA.mA.mA)[1].x) < 0.0500000007450580596923828125;
+ bool _818;
+ if (_841)
+ {
+ _818 = abs((-1.0) - float4x4(s2.a.mA.mA.mA)[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _818 = _841;
+ }
+ bool _826;
+ if (_818)
+ {
+ _826 = abs((-2.0) - float4x4(s2.a.mA.mA.mA)[1].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _826 = _818;
+ }
+ bool _834;
+ if (_826)
+ {
+ _834 = abs(1.0 - float4x4(s2.a.mA.mA.mA)[1].w) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _834 = _826;
+ }
+ _712 = _834;
+ }
+ else
+ {
+ _712 = _767;
+ }
+ bool _720;
+ if (_712)
+ {
+ bool _908 = abs(6.0 - float4x4(s2.a.mA.mA.mA)[2].x) < 0.0500000007450580596923828125;
+ bool _885;
+ if (_908)
+ {
+ _885 = abs(5.0 - float4x4(s2.a.mA.mA.mA)[2].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _885 = _908;
+ }
+ bool _893;
+ if (_885)
+ {
+ _893 = abs(7.0 - float4x4(s2.a.mA.mA.mA)[2].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _893 = _885;
+ }
+ bool _901;
+ if (_893)
+ {
+ _901 = abs((-2.0) - float4x4(s2.a.mA.mA.mA)[2].w) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _901 = _893;
+ }
+ _720 = _901;
+ }
+ else
+ {
+ _720 = _712;
+ }
+ bool _728;
+ if (_720)
+ {
+ bool _975 = abs((-4.0) - float4x4(s2.a.mA.mA.mA)[3].x) < 0.0500000007450580596923828125;
+ bool _952;
+ if (_975)
+ {
+ _952 = abs((-9.0) - float4x4(s2.a.mA.mA.mA)[3].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _952 = _975;
+ }
+ bool _960;
+ if (_952)
+ {
+ _960 = abs(8.0 - float4x4(s2.a.mA.mA.mA)[3].z) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _960 = _952;
+ }
+ bool _968;
+ if (_960)
+ {
+ _968 = abs(3.0 - float4x4(s2.a.mA.mA.mA)[3].w) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _968 = _960;
+ }
+ _728 = _968;
+ }
+ else
+ {
+ _728 = _720;
+ }
+ _453 = _728;
+ }
+ else
+ {
+ _453 = _444;
+ }
+ bool _462;
+ if (_453)
+ {
+ _462 = all(bool3(true, false, false) == bool3(s2.a.mA.mA.mB));
+ }
+ else
+ {
+ _462 = _453;
+ }
+ bool _471;
+ if (_462)
+ {
+ _471 = all(bool4(true, true, true, false) == bool4(s2.a.mA.mA.mC));
+ }
+ else
+ {
+ _471 = _462;
+ }
+ bool _480;
+ if (_471)
+ {
+ _480 = all(bool2(true) == bool2(s2.a.mA.mB.mA));
+ }
+ else
+ {
+ _480 = _471;
+ }
+ bool _489;
+ if (_480)
+ {
+ _489 = abs(7.0 - s2.a.mA.mC.mA) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _489 = _480;
+ }
+ bool _498;
+ if (_489)
+ {
+ _498 = all(uint4(8u, 6u, 2u, 0u) == s2.a.mA.mC.mB);
+ }
+ else
+ {
+ _498 = _489;
+ }
+ bool _507;
+ if (_498)
+ {
+ _507 = abs((-9.0) - s2.a.mA.mC.mC) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _507 = _498;
+ }
+ bool _516;
+ if (_507)
+ {
+ _516 = all(int3(1, -4, 0) == s2.b);
+ }
+ else
+ {
+ _516 = _507;
+ }
+ bool _525;
+ if (_516)
+ {
+ _525 = all(uint3(4u, 9u, 1u) == s2.c.mA.mA.mA);
+ }
+ else
+ {
+ _525 = _516;
+ }
+ bool _534;
+ if (_525)
+ {
+ _534 = false == bool(s2.c.mA.mA.mB);
+ }
+ else
+ {
+ _534 = _525;
+ }
+ bool _543;
+ if (_534)
+ {
+ bool _1106 = abs(3.0 - float3x2(s2.c.mA.mB)[0].x) < 0.0500000007450580596923828125;
+ bool _1099;
+ if (_1106)
+ {
+ _1099 = abs((-5.0) - float3x2(s2.c.mA.mB)[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1099 = _1106;
+ }
+ bool _1072;
+ if (_1099)
+ {
+ bool _1139 = abs((-1.0) - float3x2(s2.c.mA.mB)[1].x) < 0.0500000007450580596923828125;
+ bool _1132;
+ if (_1139)
+ {
+ _1132 = abs((-5.0) - float3x2(s2.c.mA.mB)[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1132 = _1139;
+ }
+ _1072 = _1132;
+ }
+ else
+ {
+ _1072 = _1099;
+ }
+ bool _1080;
+ if (_1072)
+ {
+ bool _1172 = abs((-1.0) - float3x2(s2.c.mA.mB)[2].x) < 0.0500000007450580596923828125;
+ bool _1165;
+ if (_1172)
+ {
+ _1165 = abs((-9.0) - float3x2(s2.c.mA.mB)[2].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1165 = _1172;
+ }
+ _1080 = _1165;
+ }
+ else
+ {
+ _1080 = _1072;
+ }
+ _543 = _1080;
+ }
+ else
+ {
+ _543 = _534;
+ }
+ bool _552;
+ if (_543)
+ {
+ bool _1205 = abs((-6.0) - s2.c.mB.x) < 0.0500000007450580596923828125;
+ bool _1198;
+ if (_1205)
+ {
+ _1198 = abs((-9.0) - s2.c.mB.y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1198 = _1205;
+ }
+ _552 = _1198;
+ }
+ else
+ {
+ _552 = _543;
+ }
+ bool _561;
+ if (_552)
+ {
+ _561 = all(bool2(true, false) == bool2(s2.d.mA));
+ }
+ else
+ {
+ _561 = _552;
+ }
+ bool _570;
+ if (_561)
+ {
+ bool _1263 = abs((-2.0) - float2x2(s2.d.mB.mA.mA)[0].x) < 0.0500000007450580596923828125;
+ bool _1256;
+ if (_1263)
+ {
+ _1256 = abs(3.0 - float2x2(s2.d.mB.mA.mA)[0].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1256 = _1263;
+ }
+ bool _1237;
+ if (_1256)
+ {
+ bool _1296 = abs(7.0 - float2x2(s2.d.mB.mA.mA)[1].x) < 0.0500000007450580596923828125;
+ bool _1289;
+ if (_1296)
+ {
+ _1289 = abs(2.0 - float2x2(s2.d.mB.mA.mA)[1].y) < 0.0500000007450580596923828125;
+ }
+ else
+ {
+ _1289 = _1296;
+ }
+ _1237 = _1289;
+ }
+ else
+ {
+ _1237 = _1256;
+ }
+ _570 = _1237;
+ }
+ else
+ {
+ _570 = _561;
+ }
+ bool _579;
+ if (_570)
+ {
+ _579 = all(bool3(false) == bool3(s2.d.mB.mA.mB));
+ }
+ else
+ {
+ _579 = _570;
+ }
+ bool _588;
+ if (_579)
+ {
+ _588 = all(bool4(false, false, false, true) == bool4(s2.d.mB.mA.mC));
+ }
+ else
+ {
+ _588 = _579;
+ }
+ bool _597;
+ if (_588)
+ {
+ _597 = all(bool3(true, false, false) == bool3(s2.d.mB.mB));
+ }
+ else
+ {
+ _597 = _588;
+ }
+ bool _606;
+ if (_597)
+ {
+ _606 = all(int2(-9, 0) == s2.d.mC);
+ }
+ else
+ {
+ _606 = _597;
+ }
+ if (_606)
+ {
+ _612.passed++;
+ }
+}
+
diff --git a/reference/shaders-msl/comp/shared-matrix-array-of-array.comp b/reference/shaders-msl/comp/shared-matrix-array-of-array.comp
new file mode 100644
index 00000000..173b31cd
--- /dev/null
+++ b/reference/shaders-msl/comp/shared-matrix-array-of-array.comp
@@ -0,0 +1,1286 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+#pragma clang diagnostic ignored "-Wmissing-braces"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+template<typename T, size_t Num>
+struct spvUnsafeArray
+{
+ T elements[Num ? Num : 1];
+
+ thread T& operator [] (size_t pos) thread
+ {
+ return elements[pos];
+ }
+ constexpr const thread T& operator [] (size_t pos) const thread
+ {
+ return elements[pos];
+ }
+
+ device T& operator [] (size_t pos) device
+ {
+ return elements[pos];
+ }
+ constexpr const device T& operator [] (size_t pos) const device
+ {
+ return elements[pos];
+ }
+
+ constexpr const constant T& operator [] (size_t pos) const constant
+ {
+ return elements[pos];
+ }
+
+ threadgroup T& operator [] (size_t pos) threadgroup
+ {
+ return elements[pos];
+ }
+ constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
+ {
+ return elements[pos];
+ }
+};
+
+template<typename T, int Cols, int Rows=Cols>
+struct spvStorageMatrix
+{
+ vec<T, Rows> columns[Cols];
+
+ spvStorageMatrix() thread = default;
+ thread spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) thread
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const thread spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const constant spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const device spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) thread = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const thread
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const thread
+ {
+ return columns[idx];
+ }
+ thread vec<T, Rows>& operator[](size_t idx) thread
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() constant = default;
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) constant = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const constant
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const constant
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() device = default;
+ device spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) device
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const thread spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const constant spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const device spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) device = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) device = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const device
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const device
+ {
+ return columns[idx];
+ }
+ device vec<T, Rows>& operator[](size_t idx) device
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup
+ {
+ return columns[idx];
+ }
+ threadgroup vec<T, Rows>& operator[](size_t idx) threadgroup
+ {
+ return columns[idx];
+ }
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix() threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup_imageblock
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup_imageblock
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ threadgroup_imageblock vec<T, Rows>& operator[](size_t idx) threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix() ray_data = default;
+ ray_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) ray_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const ray_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const ray_data
+ {
+ return columns[idx];
+ }
+ ray_data vec<T, Rows>& operator[](size_t idx) ray_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix() object_data = default;
+ object_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) object_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) object_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) object_data = default;
+ #endif
+
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) object_data = default;
+
+ operator matrix<T, Cols, Rows>() const object_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const object_data
+ {
+ return columns[idx];
+ }
+ object_data vec<T, Rows>& operator[](size_t idx) object_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+};
+
+template<typename T, int Cols, int Rows>
+matrix<T, Rows, Cols> transpose(spvStorageMatrix<T, Cols, Rows> m)
+{
+ return transpose(matrix<T, Cols, Rows>(m));
+}
+
+typedef spvStorageMatrix<half, 2, 2> spvStorage_half2x2;
+typedef spvStorageMatrix<half, 2, 3> spvStorage_half2x3;
+typedef spvStorageMatrix<half, 2, 4> spvStorage_half2x4;
+typedef spvStorageMatrix<half, 3, 2> spvStorage_half3x2;
+typedef spvStorageMatrix<half, 3, 3> spvStorage_half3x3;
+typedef spvStorageMatrix<half, 3, 4> spvStorage_half3x4;
+typedef spvStorageMatrix<half, 4, 2> spvStorage_half4x2;
+typedef spvStorageMatrix<half, 4, 3> spvStorage_half4x3;
+typedef spvStorageMatrix<half, 4, 4> spvStorage_half4x4;
+typedef spvStorageMatrix<float, 2, 2> spvStorage_float2x2;
+typedef spvStorageMatrix<float, 2, 3> spvStorage_float2x3;
+typedef spvStorageMatrix<float, 2, 4> spvStorage_float2x4;
+typedef spvStorageMatrix<float, 3, 2> spvStorage_float3x2;
+typedef spvStorageMatrix<float, 3, 3> spvStorage_float3x3;
+typedef spvStorageMatrix<float, 3, 4> spvStorage_float3x4;
+typedef spvStorageMatrix<float, 4, 2> spvStorage_float4x2;
+typedef spvStorageMatrix<float, 4, 3> spvStorage_float4x3;
+typedef spvStorageMatrix<float, 4, 4> spvStorage_float4x4;
+
+struct S1
+{
+ spvStorage_float4x3 a[2];
+ float b;
+ spvUnsafeArray<float2, 3> c;
+};
+
+struct S2
+{
+ int4 a;
+ spvUnsafeArray<spvUnsafeArray<spvUnsafeArray<short, 3>, 1>, 3> b;
+};
+
+struct block
+{
+ uint passed;
+};
+
+constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(1u);
+
+static inline __attribute__((always_inline))
+bool compare_float(thread const float& a, thread const float& b)
+{
+ return abs(a - b) < 0.0500000007450580596923828125;
+}
+
+static inline __attribute__((always_inline))
+bool compare_vec3(thread const float3& a, thread const float3& b)
+{
+ float param = a.x;
+ float param_1 = b.x;
+ bool _85 = compare_float(param, param_1);
+ bool _95;
+ if (_85)
+ {
+ float param_2 = a.y;
+ float param_3 = b.y;
+ _95 = compare_float(param_2, param_3);
+ }
+ else
+ {
+ _95 = _85;
+ }
+ bool _106;
+ if (_95)
+ {
+ float param_4 = a.z;
+ float param_5 = b.z;
+ _106 = compare_float(param_4, param_5);
+ }
+ else
+ {
+ _106 = _95;
+ }
+ return _106;
+}
+
+static inline __attribute__((always_inline))
+bool compare_mat4x3(thread const float4x3& a, thread const float4x3& b)
+{
+ float3 param = a[0];
+ float3 param_1 = b[0];
+ bool _116 = compare_vec3(param, param_1);
+ bool _127;
+ if (_116)
+ {
+ float3 param_2 = a[1];
+ float3 param_3 = b[1];
+ _127 = compare_vec3(param_2, param_3);
+ }
+ else
+ {
+ _127 = _116;
+ }
+ bool _138;
+ if (_127)
+ {
+ float3 param_4 = a[2];
+ float3 param_5 = b[2];
+ _138 = compare_vec3(param_4, param_5);
+ }
+ else
+ {
+ _138 = _127;
+ }
+ bool _149;
+ if (_138)
+ {
+ float3 param_6 = a[3];
+ float3 param_7 = b[3];
+ _149 = compare_vec3(param_6, param_7);
+ }
+ else
+ {
+ _149 = _138;
+ }
+ return _149;
+}
+
+static inline __attribute__((always_inline))
+bool compare_vec2(thread const float2& a, thread const float2& b)
+{
+ float param = a.x;
+ float param_1 = b.x;
+ bool _65 = compare_float(param, param_1);
+ bool _76;
+ if (_65)
+ {
+ float param_2 = a.y;
+ float param_3 = b.y;
+ _76 = compare_float(param_2, param_3);
+ }
+ else
+ {
+ _76 = _65;
+ }
+ return _76;
+}
+
+static inline __attribute__((always_inline))
+bool compare_ivec4(thread const int4& a, thread const int4& b)
+{
+ return all(a == b);
+}
+
+static inline __attribute__((always_inline))
+bool compare_bool(thread const bool& a, thread const bool& b)
+{
+ return a == b;
+}
+
+kernel void main0(device block& _383 [[buffer(0)]])
+{
+ threadgroup S1 s1;
+ threadgroup S2 s2;
+ s1.a[0] = spvStorage_float4x3(float4x3(float3(0.0, 2.0, -8.0), float3(6.0, 7.0, 5.0), float3(-6.0, 1.0, 9.0), float3(-4.0, -3.0, 4.0)));
+ s1.a[1] = spvStorage_float4x3(float4x3(float3(4.0, 9.0, -9.0), float3(-8.0, -9.0, 8.0), float3(0.0, 4.0, -4.0), float3(7.0, 2.0, -1.0)));
+ s1.b = 7.0;
+ s1.c[0] = float2(-5.0, -4.0);
+ s1.c[1] = float2(3.0, -5.0);
+ s1.c[2] = float2(-3.0, -1.0);
+ s2.a = int4(1, 0, -3, 1);
+ s2.b[0][0][0] = short(true);
+ s2.b[0][0][1] = short(false);
+ s2.b[0][0][2] = short(false);
+ s2.b[1][0][0] = short(true);
+ s2.b[1][0][1] = short(false);
+ s2.b[1][0][2] = short(true);
+ s2.b[2][0][0] = short(false);
+ s2.b[2][0][1] = short(true);
+ s2.b[2][0][2] = short(true);
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup | mem_flags::mem_texture);
+ bool allOk = true;
+ bool _242;
+ if (allOk)
+ {
+ float4x3 param = float4x3(float3(0.0, 2.0, -8.0), float3(6.0, 7.0, 5.0), float3(-6.0, 1.0, 9.0), float3(-4.0, -3.0, 4.0));
+ float4x3 param_1 = float4x3(s1.a[0]);
+ _242 = compare_mat4x3(param, param_1);
+ }
+ else
+ {
+ _242 = allOk;
+ }
+ allOk = _242;
+ bool _251;
+ if (allOk)
+ {
+ float4x3 param_2 = float4x3(float3(4.0, 9.0, -9.0), float3(-8.0, -9.0, 8.0), float3(0.0, 4.0, -4.0), float3(7.0, 2.0, -1.0));
+ float4x3 param_3 = float4x3(s1.a[1]);
+ _251 = compare_mat4x3(param_2, param_3);
+ }
+ else
+ {
+ _251 = allOk;
+ }
+ allOk = _251;
+ bool _260;
+ if (allOk)
+ {
+ float param_4 = 7.0;
+ float param_5 = s1.b;
+ _260 = compare_float(param_4, param_5);
+ }
+ else
+ {
+ _260 = allOk;
+ }
+ allOk = _260;
+ bool _269;
+ if (allOk)
+ {
+ float2 param_6 = float2(-5.0, -4.0);
+ float2 param_7 = s1.c[0];
+ _269 = compare_vec2(param_6, param_7);
+ }
+ else
+ {
+ _269 = allOk;
+ }
+ allOk = _269;
+ bool _278;
+ if (allOk)
+ {
+ float2 param_8 = float2(3.0, -5.0);
+ float2 param_9 = s1.c[1];
+ _278 = compare_vec2(param_8, param_9);
+ }
+ else
+ {
+ _278 = allOk;
+ }
+ allOk = _278;
+ bool _287;
+ if (allOk)
+ {
+ float2 param_10 = float2(-3.0, -1.0);
+ float2 param_11 = s1.c[2];
+ _287 = compare_vec2(param_10, param_11);
+ }
+ else
+ {
+ _287 = allOk;
+ }
+ allOk = _287;
+ bool _296;
+ if (allOk)
+ {
+ int4 param_12 = int4(1, 0, -3, 1);
+ int4 param_13 = s2.a;
+ _296 = compare_ivec4(param_12, param_13);
+ }
+ else
+ {
+ _296 = allOk;
+ }
+ allOk = _296;
+ bool _305;
+ if (allOk)
+ {
+ bool param_14 = true;
+ bool param_15 = bool(s2.b[0][0][0]);
+ _305 = compare_bool(param_14, param_15);
+ }
+ else
+ {
+ _305 = allOk;
+ }
+ allOk = _305;
+ bool _314;
+ if (allOk)
+ {
+ bool param_16 = false;
+ bool param_17 = bool(s2.b[0][0][1]);
+ _314 = compare_bool(param_16, param_17);
+ }
+ else
+ {
+ _314 = allOk;
+ }
+ allOk = _314;
+ bool _323;
+ if (allOk)
+ {
+ bool param_18 = false;
+ bool param_19 = bool(s2.b[0][0][2]);
+ _323 = compare_bool(param_18, param_19);
+ }
+ else
+ {
+ _323 = allOk;
+ }
+ allOk = _323;
+ bool _332;
+ if (allOk)
+ {
+ bool param_20 = true;
+ bool param_21 = bool(s2.b[1][0][0]);
+ _332 = compare_bool(param_20, param_21);
+ }
+ else
+ {
+ _332 = allOk;
+ }
+ allOk = _332;
+ bool _341;
+ if (allOk)
+ {
+ bool param_22 = false;
+ bool param_23 = bool(s2.b[1][0][1]);
+ _341 = compare_bool(param_22, param_23);
+ }
+ else
+ {
+ _341 = allOk;
+ }
+ allOk = _341;
+ bool _350;
+ if (allOk)
+ {
+ bool param_24 = true;
+ bool param_25 = bool(s2.b[1][0][2]);
+ _350 = compare_bool(param_24, param_25);
+ }
+ else
+ {
+ _350 = allOk;
+ }
+ allOk = _350;
+ bool _359;
+ if (allOk)
+ {
+ bool param_26 = false;
+ bool param_27 = bool(s2.b[2][0][0]);
+ _359 = compare_bool(param_26, param_27);
+ }
+ else
+ {
+ _359 = allOk;
+ }
+ allOk = _359;
+ bool _368;
+ if (allOk)
+ {
+ bool param_28 = true;
+ bool param_29 = bool(s2.b[2][0][1]);
+ _368 = compare_bool(param_28, param_29);
+ }
+ else
+ {
+ _368 = allOk;
+ }
+ allOk = _368;
+ bool _377;
+ if (allOk)
+ {
+ bool param_30 = true;
+ bool param_31 = bool(s2.b[2][0][2]);
+ _377 = compare_bool(param_30, param_31);
+ }
+ else
+ {
+ _377 = allOk;
+ }
+ allOk = _377;
+ if (allOk)
+ {
+ _383.passed++;
+ }
+}
+
diff --git a/reference/shaders-msl/comp/shared-matrix-cast.comp b/reference/shaders-msl/comp/shared-matrix-cast.comp
new file mode 100644
index 00000000..c764c1fd
--- /dev/null
+++ b/reference/shaders-msl/comp/shared-matrix-cast.comp
@@ -0,0 +1,1065 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+template<typename T, int Cols, int Rows=Cols>
+struct spvStorageMatrix
+{
+ vec<T, Rows> columns[Cols];
+
+ spvStorageMatrix() thread = default;
+ thread spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) thread
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const thread spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const constant spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const device spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) thread = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const thread
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const thread
+ {
+ return columns[idx];
+ }
+ thread vec<T, Rows>& operator[](size_t idx) thread
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() constant = default;
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) constant = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const constant
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const constant
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() device = default;
+ device spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) device
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const thread spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const constant spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const device spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) device = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) device = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const device
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const device
+ {
+ return columns[idx];
+ }
+ device vec<T, Rows>& operator[](size_t idx) device
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup
+ {
+ return columns[idx];
+ }
+ threadgroup vec<T, Rows>& operator[](size_t idx) threadgroup
+ {
+ return columns[idx];
+ }
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix() threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup_imageblock
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup_imageblock
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ threadgroup_imageblock vec<T, Rows>& operator[](size_t idx) threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix() ray_data = default;
+ ray_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) ray_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const ray_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const ray_data
+ {
+ return columns[idx];
+ }
+ ray_data vec<T, Rows>& operator[](size_t idx) ray_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix() object_data = default;
+ object_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) object_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) object_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) object_data = default;
+ #endif
+
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) object_data = default;
+
+ operator matrix<T, Cols, Rows>() const object_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const object_data
+ {
+ return columns[idx];
+ }
+ object_data vec<T, Rows>& operator[](size_t idx) object_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+};
+
+template<typename T, int Cols, int Rows>
+matrix<T, Rows, Cols> transpose(spvStorageMatrix<T, Cols, Rows> m)
+{
+ return transpose(matrix<T, Cols, Rows>(m));
+}
+
+typedef spvStorageMatrix<half, 2, 2> spvStorage_half2x2;
+typedef spvStorageMatrix<half, 2, 3> spvStorage_half2x3;
+typedef spvStorageMatrix<half, 2, 4> spvStorage_half2x4;
+typedef spvStorageMatrix<half, 3, 2> spvStorage_half3x2;
+typedef spvStorageMatrix<half, 3, 3> spvStorage_half3x3;
+typedef spvStorageMatrix<half, 3, 4> spvStorage_half3x4;
+typedef spvStorageMatrix<half, 4, 2> spvStorage_half4x2;
+typedef spvStorageMatrix<half, 4, 3> spvStorage_half4x3;
+typedef spvStorageMatrix<half, 4, 4> spvStorage_half4x4;
+typedef spvStorageMatrix<float, 2, 2> spvStorage_float2x2;
+typedef spvStorageMatrix<float, 2, 3> spvStorage_float2x3;
+typedef spvStorageMatrix<float, 2, 4> spvStorage_float2x4;
+typedef spvStorageMatrix<float, 3, 2> spvStorage_float3x2;
+typedef spvStorageMatrix<float, 3, 3> spvStorage_float3x3;
+typedef spvStorageMatrix<float, 3, 4> spvStorage_float3x4;
+typedef spvStorageMatrix<float, 4, 2> spvStorage_float4x2;
+typedef spvStorageMatrix<float, 4, 3> spvStorage_float4x3;
+typedef spvStorageMatrix<float, 4, 4> spvStorage_float4x4;
+
+struct S1
+{
+ float4 a;
+ spvStorage_float3x2 b;
+ short4 c;
+};
+
+struct block
+{
+ uint passed;
+};
+
+constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(1u);
+
+static inline __attribute__((always_inline))
+bool compare_float(thread const float& a, thread const float& b)
+{
+ return abs(a - b) < 0.0500000007450580596923828125;
+}
+
+static inline __attribute__((always_inline))
+bool compare_vec4(thread const float4& a, thread const float4& b)
+{
+ float param = a.x;
+ float param_1 = b.x;
+ bool _78 = compare_float(param, param_1);
+ bool _88;
+ if (_78)
+ {
+ float param_2 = a.y;
+ float param_3 = b.y;
+ _88 = compare_float(param_2, param_3);
+ }
+ else
+ {
+ _88 = _78;
+ }
+ bool _99;
+ if (_88)
+ {
+ float param_4 = a.z;
+ float param_5 = b.z;
+ _99 = compare_float(param_4, param_5);
+ }
+ else
+ {
+ _99 = _88;
+ }
+ bool _110;
+ if (_99)
+ {
+ float param_6 = a.w;
+ float param_7 = b.w;
+ _110 = compare_float(param_6, param_7);
+ }
+ else
+ {
+ _110 = _99;
+ }
+ return _110;
+}
+
+static inline __attribute__((always_inline))
+bool compare_vec2(thread const float2& a, thread const float2& b)
+{
+ float param = a.x;
+ float param_1 = b.x;
+ bool _58 = compare_float(param, param_1);
+ bool _69;
+ if (_58)
+ {
+ float param_2 = a.y;
+ float param_3 = b.y;
+ _69 = compare_float(param_2, param_3);
+ }
+ else
+ {
+ _69 = _58;
+ }
+ return _69;
+}
+
+static inline __attribute__((always_inline))
+bool compare_mat3x2(thread const float3x2& a, thread const float3x2& b)
+{
+ float2 param = a[0];
+ float2 param_1 = b[0];
+ bool _121 = compare_vec2(param, param_1);
+ bool _132;
+ if (_121)
+ {
+ float2 param_2 = a[1];
+ float2 param_3 = b[1];
+ _132 = compare_vec2(param_2, param_3);
+ }
+ else
+ {
+ _132 = _121;
+ }
+ bool _143;
+ if (_132)
+ {
+ float2 param_4 = a[2];
+ float2 param_5 = b[2];
+ _143 = compare_vec2(param_4, param_5);
+ }
+ else
+ {
+ _143 = _132;
+ }
+ return _143;
+}
+
+static inline __attribute__((always_inline))
+bool compare_bvec4(thread const bool4& a, thread const bool4& b)
+{
+ return all(a == b);
+}
+
+kernel void main0(device block& _212 [[buffer(0)]])
+{
+ threadgroup S1 s1;
+ s1.a = float4(1.0, -5.0, -9.0, -5.0);
+ s1.b = spvStorage_float3x2(float3x2(float2(1.0, -7.0), float2(1.0, 2.0), float2(8.0, 7.0)));
+ s1.c = short4(bool4(false, true, false, false));
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup | mem_flags::mem_texture);
+ bool allOk = true;
+ bool _188;
+ if (allOk)
+ {
+ float4 param = float4(1.0, -5.0, -9.0, -5.0);
+ float4 param_1 = s1.a;
+ _188 = compare_vec4(param, param_1);
+ }
+ else
+ {
+ _188 = allOk;
+ }
+ allOk = _188;
+ bool _197;
+ if (allOk)
+ {
+ float3x2 param_2 = float3x2(float2(1.0, -7.0), float2(1.0, 2.0), float2(8.0, 7.0));
+ float3x2 param_3 = float3x2(s1.b);
+ _197 = compare_mat3x2(param_2, param_3);
+ }
+ else
+ {
+ _197 = allOk;
+ }
+ allOk = _197;
+ bool _206;
+ if (allOk)
+ {
+ bool4 param_4 = bool4(false, true, false, false);
+ bool4 param_5 = bool4(s1.c);
+ _206 = compare_bvec4(param_4, param_5);
+ }
+ else
+ {
+ _206 = allOk;
+ }
+ allOk = _206;
+ if (allOk)
+ {
+ _212.passed++;
+ }
+}
+
diff --git a/reference/shaders-msl/comp/shared-matrix-nested-struct-array.comp b/reference/shaders-msl/comp/shared-matrix-nested-struct-array.comp
new file mode 100644
index 00000000..db5ed440
--- /dev/null
+++ b/reference/shaders-msl/comp/shared-matrix-nested-struct-array.comp
@@ -0,0 +1,1316 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+#pragma clang diagnostic ignored "-Wmissing-braces"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+template<typename T, size_t Num>
+struct spvUnsafeArray
+{
+ T elements[Num ? Num : 1];
+
+ thread T& operator [] (size_t pos) thread
+ {
+ return elements[pos];
+ }
+ constexpr const thread T& operator [] (size_t pos) const thread
+ {
+ return elements[pos];
+ }
+
+ device T& operator [] (size_t pos) device
+ {
+ return elements[pos];
+ }
+ constexpr const device T& operator [] (size_t pos) const device
+ {
+ return elements[pos];
+ }
+
+ constexpr const constant T& operator [] (size_t pos) const constant
+ {
+ return elements[pos];
+ }
+
+ threadgroup T& operator [] (size_t pos) threadgroup
+ {
+ return elements[pos];
+ }
+ constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
+ {
+ return elements[pos];
+ }
+};
+
+template<typename T, int Cols, int Rows=Cols>
+struct spvStorageMatrix
+{
+ vec<T, Rows> columns[Cols];
+
+ spvStorageMatrix() thread = default;
+ thread spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) thread
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const thread spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const constant spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const device spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) thread = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const thread
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const thread
+ {
+ return columns[idx];
+ }
+ thread vec<T, Rows>& operator[](size_t idx) thread
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() constant = default;
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) constant = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const constant
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const constant
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() device = default;
+ device spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) device
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const thread spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const constant spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const device spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) device = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) device = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const device
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const device
+ {
+ return columns[idx];
+ }
+ device vec<T, Rows>& operator[](size_t idx) device
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup
+ {
+ return columns[idx];
+ }
+ threadgroup vec<T, Rows>& operator[](size_t idx) threadgroup
+ {
+ return columns[idx];
+ }
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix() threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup_imageblock
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup_imageblock
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ threadgroup_imageblock vec<T, Rows>& operator[](size_t idx) threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix() ray_data = default;
+ ray_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) ray_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const ray_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const ray_data
+ {
+ return columns[idx];
+ }
+ ray_data vec<T, Rows>& operator[](size_t idx) ray_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix() object_data = default;
+ object_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) object_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) object_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) object_data = default;
+ #endif
+
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) object_data = default;
+
+ operator matrix<T, Cols, Rows>() const object_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const object_data
+ {
+ return columns[idx];
+ }
+ object_data vec<T, Rows>& operator[](size_t idx) object_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+};
+
+template<typename T, int Cols, int Rows>
+matrix<T, Rows, Cols> transpose(spvStorageMatrix<T, Cols, Rows> m)
+{
+ return transpose(matrix<T, Cols, Rows>(m));
+}
+
+typedef spvStorageMatrix<half, 2, 2> spvStorage_half2x2;
+typedef spvStorageMatrix<half, 2, 3> spvStorage_half2x3;
+typedef spvStorageMatrix<half, 2, 4> spvStorage_half2x4;
+typedef spvStorageMatrix<half, 3, 2> spvStorage_half3x2;
+typedef spvStorageMatrix<half, 3, 3> spvStorage_half3x3;
+typedef spvStorageMatrix<half, 3, 4> spvStorage_half3x4;
+typedef spvStorageMatrix<half, 4, 2> spvStorage_half4x2;
+typedef spvStorageMatrix<half, 4, 3> spvStorage_half4x3;
+typedef spvStorageMatrix<half, 4, 4> spvStorage_half4x4;
+typedef spvStorageMatrix<float, 2, 2> spvStorage_float2x2;
+typedef spvStorageMatrix<float, 2, 3> spvStorage_float2x3;
+typedef spvStorageMatrix<float, 2, 4> spvStorage_float2x4;
+typedef spvStorageMatrix<float, 3, 2> spvStorage_float3x2;
+typedef spvStorageMatrix<float, 3, 3> spvStorage_float3x3;
+typedef spvStorageMatrix<float, 3, 4> spvStorage_float3x4;
+typedef spvStorageMatrix<float, 4, 2> spvStorage_float4x2;
+typedef spvStorageMatrix<float, 4, 3> spvStorage_float4x3;
+typedef spvStorageMatrix<float, 4, 4> spvStorage_float4x4;
+
+struct sA
+{
+ spvStorage_float2x3 mA;
+};
+
+struct sB
+{
+ spvStorage_float2x2 mA;
+ spvStorage_float3x2 mB;
+ uint3 mC;
+};
+
+struct sC
+{
+ sA mA;
+ sB mB;
+};
+
+struct sD
+{
+ sC mA;
+};
+
+struct sE
+{
+ spvStorage_float3x2 mA;
+ spvStorage_float4x3 mB;
+};
+
+struct sF
+{
+ sE mA;
+};
+
+struct sG
+{
+ sF mA;
+};
+
+struct sH
+{
+ spvUnsafeArray<short3, 2> mA;
+};
+
+struct S1
+{
+ sD a;
+ sG b;
+ spvUnsafeArray<sH, 2> c;
+};
+
+struct block
+{
+ uint passed;
+};
+
+constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(1u);
+
+static inline __attribute__((always_inline))
+bool compare_float(thread const float& a, thread const float& b)
+{
+ return abs(a - b) < 0.0500000007450580596923828125;
+}
+
+static inline __attribute__((always_inline))
+bool compare_vec3(thread const float3& a, thread const float3& b)
+{
+ float param = a.x;
+ float param_1 = b.x;
+ bool _106 = compare_float(param, param_1);
+ bool _116;
+ if (_106)
+ {
+ float param_2 = a.y;
+ float param_3 = b.y;
+ _116 = compare_float(param_2, param_3);
+ }
+ else
+ {
+ _116 = _106;
+ }
+ bool _127;
+ if (_116)
+ {
+ float param_4 = a.z;
+ float param_5 = b.z;
+ _127 = compare_float(param_4, param_5);
+ }
+ else
+ {
+ _127 = _116;
+ }
+ return _127;
+}
+
+static inline __attribute__((always_inline))
+bool compare_mat2x3(thread const float2x3& a, thread const float2x3& b)
+{
+ float3 param = a[0];
+ float3 param_1 = b[0];
+ bool _158 = compare_vec3(param, param_1);
+ bool _168;
+ if (_158)
+ {
+ float3 param_2 = a[1];
+ float3 param_3 = b[1];
+ _168 = compare_vec3(param_2, param_3);
+ }
+ else
+ {
+ _168 = _158;
+ }
+ return _168;
+}
+
+static inline __attribute__((always_inline))
+bool compare_vec2(thread const float2& a, thread const float2& b)
+{
+ float param = a.x;
+ float param_1 = b.x;
+ bool _86 = compare_float(param, param_1);
+ bool _97;
+ if (_86)
+ {
+ float param_2 = a.y;
+ float param_3 = b.y;
+ _97 = compare_float(param_2, param_3);
+ }
+ else
+ {
+ _97 = _86;
+ }
+ return _97;
+}
+
+static inline __attribute__((always_inline))
+bool compare_mat2(thread const float2x2& a, thread const float2x2& b)
+{
+ float2 param = a[0];
+ float2 param_1 = b[0];
+ bool _138 = compare_vec2(param, param_1);
+ bool _149;
+ if (_138)
+ {
+ float2 param_2 = a[1];
+ float2 param_3 = b[1];
+ _149 = compare_vec2(param_2, param_3);
+ }
+ else
+ {
+ _149 = _138;
+ }
+ return _149;
+}
+
+static inline __attribute__((always_inline))
+bool compare_mat3x2(thread const float3x2& a, thread const float3x2& b)
+{
+ float2 param = a[0];
+ float2 param_1 = b[0];
+ bool _177 = compare_vec2(param, param_1);
+ bool _187;
+ if (_177)
+ {
+ float2 param_2 = a[1];
+ float2 param_3 = b[1];
+ _187 = compare_vec2(param_2, param_3);
+ }
+ else
+ {
+ _187 = _177;
+ }
+ bool _198;
+ if (_187)
+ {
+ float2 param_4 = a[2];
+ float2 param_5 = b[2];
+ _198 = compare_vec2(param_4, param_5);
+ }
+ else
+ {
+ _198 = _187;
+ }
+ return _198;
+}
+
+static inline __attribute__((always_inline))
+bool compare_uvec3(thread const uint3& a, thread const uint3& b)
+{
+ return all(a == b);
+}
+
+static inline __attribute__((always_inline))
+bool compare_mat4x3(thread const float4x3& a, thread const float4x3& b)
+{
+ float3 param = a[0];
+ float3 param_1 = b[0];
+ bool _207 = compare_vec3(param, param_1);
+ bool _217;
+ if (_207)
+ {
+ float3 param_2 = a[1];
+ float3 param_3 = b[1];
+ _217 = compare_vec3(param_2, param_3);
+ }
+ else
+ {
+ _217 = _207;
+ }
+ bool _227;
+ if (_217)
+ {
+ float3 param_4 = a[2];
+ float3 param_5 = b[2];
+ _227 = compare_vec3(param_4, param_5);
+ }
+ else
+ {
+ _227 = _217;
+ }
+ bool _238;
+ if (_227)
+ {
+ float3 param_6 = a[3];
+ float3 param_7 = b[3];
+ _238 = compare_vec3(param_6, param_7);
+ }
+ else
+ {
+ _238 = _227;
+ }
+ return _238;
+}
+
+static inline __attribute__((always_inline))
+bool compare_bvec3(thread const bool3& a, thread const bool3& b)
+{
+ return all(a == b);
+}
+
+kernel void main0(device block& _424 [[buffer(0)]])
+{
+ threadgroup S1 s1;
+ s1.a.mA.mA.mA = spvStorage_float2x3(float2x3(float3(6.0, 8.0, 8.0), float3(0.0, -4.0, -5.0)));
+ s1.a.mA.mB.mA = spvStorage_float2x2(float2x2(float2(9.0, -4.0), float2(-6.0, -1.0)));
+ s1.a.mA.mB.mB = spvStorage_float3x2(float3x2(float2(-1.0, -2.0), float2(1.0, 6.0), float2(5.0, 7.0)));
+ s1.a.mA.mB.mC = uint3(3u, 1u, 5u);
+ s1.b.mA.mA.mA = spvStorage_float3x2(float3x2(float2(8.0, 3.0), float2(0.0, 2.0), float2(1.0, 8.0)));
+ s1.b.mA.mA.mB = spvStorage_float4x3(float4x3(float3(0.0, 9.0, -1.0), float3(-1.0, -7.0, 7.0), float3(-4.0, -3.0, 1.0), float3(-4.0, -9.0, 1.0)));
+ s1.c[0].mA[0] = short3(bool3(true, false, false));
+ s1.c[0].mA[1] = short3(bool3(true, false, false));
+ s1.c[1].mA[0] = short3(bool3(false));
+ s1.c[1].mA[1] = short3(bool3(false));
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup | mem_flags::mem_texture);
+ bool allOk = true;
+ bool _337;
+ if (allOk)
+ {
+ float2x3 param = float2x3(float3(6.0, 8.0, 8.0), float3(0.0, -4.0, -5.0));
+ float2x3 param_1 = float2x3(s1.a.mA.mA.mA);
+ _337 = compare_mat2x3(param, param_1);
+ }
+ else
+ {
+ _337 = allOk;
+ }
+ allOk = _337;
+ bool _346;
+ if (allOk)
+ {
+ float2x2 param_2 = float2x2(float2(9.0, -4.0), float2(-6.0, -1.0));
+ float2x2 param_3 = float2x2(s1.a.mA.mB.mA);
+ _346 = compare_mat2(param_2, param_3);
+ }
+ else
+ {
+ _346 = allOk;
+ }
+ allOk = _346;
+ bool _355;
+ if (allOk)
+ {
+ float3x2 param_4 = float3x2(float2(-1.0, -2.0), float2(1.0, 6.0), float2(5.0, 7.0));
+ float3x2 param_5 = float3x2(s1.a.mA.mB.mB);
+ _355 = compare_mat3x2(param_4, param_5);
+ }
+ else
+ {
+ _355 = allOk;
+ }
+ allOk = _355;
+ bool _364;
+ if (allOk)
+ {
+ uint3 param_6 = uint3(3u, 1u, 5u);
+ uint3 param_7 = s1.a.mA.mB.mC;
+ _364 = compare_uvec3(param_6, param_7);
+ }
+ else
+ {
+ _364 = allOk;
+ }
+ allOk = _364;
+ bool _373;
+ if (allOk)
+ {
+ float3x2 param_8 = float3x2(float2(8.0, 3.0), float2(0.0, 2.0), float2(1.0, 8.0));
+ float3x2 param_9 = float3x2(s1.b.mA.mA.mA);
+ _373 = compare_mat3x2(param_8, param_9);
+ }
+ else
+ {
+ _373 = allOk;
+ }
+ allOk = _373;
+ bool _382;
+ if (allOk)
+ {
+ float4x3 param_10 = float4x3(float3(0.0, 9.0, -1.0), float3(-1.0, -7.0, 7.0), float3(-4.0, -3.0, 1.0), float3(-4.0, -9.0, 1.0));
+ float4x3 param_11 = float4x3(s1.b.mA.mA.mB);
+ _382 = compare_mat4x3(param_10, param_11);
+ }
+ else
+ {
+ _382 = allOk;
+ }
+ allOk = _382;
+ bool _391;
+ if (allOk)
+ {
+ bool3 param_12 = bool3(true, false, false);
+ bool3 param_13 = bool3(s1.c[0].mA[0]);
+ _391 = compare_bvec3(param_12, param_13);
+ }
+ else
+ {
+ _391 = allOk;
+ }
+ allOk = _391;
+ bool _400;
+ if (allOk)
+ {
+ bool3 param_14 = bool3(true, false, false);
+ bool3 param_15 = bool3(s1.c[0].mA[1]);
+ _400 = compare_bvec3(param_14, param_15);
+ }
+ else
+ {
+ _400 = allOk;
+ }
+ allOk = _400;
+ bool _409;
+ if (allOk)
+ {
+ bool3 param_16 = bool3(false);
+ bool3 param_17 = bool3(s1.c[1].mA[0]);
+ _409 = compare_bvec3(param_16, param_17);
+ }
+ else
+ {
+ _409 = allOk;
+ }
+ allOk = _409;
+ bool _418;
+ if (allOk)
+ {
+ bool3 param_18 = bool3(false);
+ bool3 param_19 = bool3(s1.c[1].mA[1]);
+ _418 = compare_bvec3(param_18, param_19);
+ }
+ else
+ {
+ _418 = allOk;
+ }
+ allOk = _418;
+ if (allOk)
+ {
+ _424.passed++;
+ }
+}
+
diff --git a/reference/shaders-msl/comp/shared-matrix-nested-struct.comp b/reference/shaders-msl/comp/shared-matrix-nested-struct.comp
new file mode 100644
index 00000000..2526c6c9
--- /dev/null
+++ b/reference/shaders-msl/comp/shared-matrix-nested-struct.comp
@@ -0,0 +1,1473 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+template<typename T, int Cols, int Rows=Cols>
+struct spvStorageMatrix
+{
+ vec<T, Rows> columns[Cols];
+
+ spvStorageMatrix() thread = default;
+ thread spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) thread
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const thread spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const constant spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const device spvStorageMatrix& m) thread = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) thread = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) thread = default;
+ thread spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) thread
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ thread spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) thread = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const thread
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const thread
+ {
+ return columns[idx];
+ }
+ thread vec<T, Rows>& operator[](size_t idx) thread
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() constant = default;
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) constant = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) constant = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) constant
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) constant = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const constant
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const constant
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() device = default;
+ device spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) device
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const thread spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const constant spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const device spvStorageMatrix& m) device = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) device = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) device = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) device = default;
+ device spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) device
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ device spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) device = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const device
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const device
+ {
+ return columns[idx];
+ }
+ device vec<T, Rows>& operator[](size_t idx) device
+ {
+ return columns[idx];
+ }
+
+ spvStorageMatrix() threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup = default;
+ threadgroup spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup
+ {
+ return columns[idx];
+ }
+ threadgroup vec<T, Rows>& operator[](size_t idx) threadgroup
+ {
+ return columns[idx];
+ }
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix() threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) threadgroup_imageblock
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const thread spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const constant spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const device spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) threadgroup_imageblock = default;
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) threadgroup_imageblock
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ threadgroup_imageblock spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) threadgroup_imageblock = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const threadgroup_imageblock
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ threadgroup_imageblock vec<T, Rows>& operator[](size_t idx) threadgroup_imageblock
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix() ray_data = default;
+ ray_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) ray_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) ray_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) ray_data = default;
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) ray_data = default;
+ ray_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) ray_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ ray_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) ray_data = default;
+ #endif
+
+ operator matrix<T, Cols, Rows>() const ray_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const ray_data
+ {
+ return columns[idx];
+ }
+ ray_data vec<T, Rows>& operator[](size_t idx) ray_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+ #ifdef __HAVE_MESH__
+ spvStorageMatrix() object_data = default;
+ object_data spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) object_data
+ {
+ size_t i;
+ thread vec<T, Rows>* col;
+ for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)
+ columns[i] = *col;
+ return *this;
+ }
+
+ spvStorageMatrix(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const thread spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const thread matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const thread spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const constant spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const constant matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const constant spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const device spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const device matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const device spvStorageMatrix& m) object_data = default;
+
+ spvStorageMatrix(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup spvStorageMatrix& m) object_data = default;
+
+ #ifdef __HAVE_IMAGEBLOCKS__
+ spvStorageMatrix(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const threadgroup_imageblock spvStorageMatrix& m) object_data = default;
+ #endif
+
+ #ifdef __HAVE_RAYTRACING__
+ spvStorageMatrix(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const ray_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const ray_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const ray_data spvStorageMatrix& m) object_data = default;
+ #endif
+
+ spvStorageMatrix(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ }
+ spvStorageMatrix(const object_data spvStorageMatrix& m) object_data = default;
+ object_data spvStorageMatrix& operator=(const object_data matrix<T, Cols, Rows>& m) object_data
+ {
+ for (size_t i = 0; i < Cols; ++i)
+ columns[i] = m.columns[i];
+ return *this;
+ }
+ object_data spvStorageMatrix& operator=(const object_data spvStorageMatrix& m) object_data = default;
+
+ operator matrix<T, Cols, Rows>() const object_data
+ {
+ matrix<T, Cols, Rows> m;
+ for (int i = 0; i < Cols; ++i)
+ m.columns[i] = columns[i];
+ return m;
+ }
+
+ vec<T, Rows> operator[](size_t idx) const object_data
+ {
+ return columns[idx];
+ }
+ object_data vec<T, Rows>& operator[](size_t idx) object_data
+ {
+ return columns[idx];
+ }
+ #endif
+
+};
+
+template<typename T, int Cols, int Rows>
+matrix<T, Rows, Cols> transpose(spvStorageMatrix<T, Cols, Rows> m)
+{
+ return transpose(matrix<T, Cols, Rows>(m));
+}
+
+typedef spvStorageMatrix<half, 2, 2> spvStorage_half2x2;
+typedef spvStorageMatrix<half, 2, 3> spvStorage_half2x3;
+typedef spvStorageMatrix<half, 2, 4> spvStorage_half2x4;
+typedef spvStorageMatrix<half, 3, 2> spvStorage_half3x2;
+typedef spvStorageMatrix<half, 3, 3> spvStorage_half3x3;
+typedef spvStorageMatrix<half, 3, 4> spvStorage_half3x4;
+typedef spvStorageMatrix<half, 4, 2> spvStorage_half4x2;
+typedef spvStorageMatrix<half, 4, 3> spvStorage_half4x3;
+typedef spvStorageMatrix<half, 4, 4> spvStorage_half4x4;
+typedef spvStorageMatrix<float, 2, 2> spvStorage_float2x2;
+typedef spvStorageMatrix<float, 2, 3> spvStorage_float2x3;
+typedef spvStorageMatrix<float, 2, 4> spvStorage_float2x4;
+typedef spvStorageMatrix<float, 3, 2> spvStorage_float3x2;
+typedef spvStorageMatrix<float, 3, 3> spvStorage_float3x3;
+typedef spvStorageMatrix<float, 3, 4> spvStorage_float3x4;
+typedef spvStorageMatrix<float, 4, 2> spvStorage_float4x2;
+typedef spvStorageMatrix<float, 4, 3> spvStorage_float4x3;
+typedef spvStorageMatrix<float, 4, 4> spvStorage_float4x4;
+
+struct S1
+{
+ uint a;
+ float4 b;
+};
+
+struct sA
+{
+ spvStorage_float4x4 mA;
+ short3 mB;
+ short4 mC;
+};
+
+struct sB
+{
+ short2 mA;
+};
+
+struct sC
+{
+ float mA;
+ uint4 mB;
+ float mC;
+};
+
+struct sD
+{
+ sA mA;
+ sB mB;
+ sC mC;
+};
+
+struct sE
+{
+ sD mA;
+};
+
+struct sF
+{
+ uint3 mA;
+ short mB;
+};
+
+struct sG
+{
+ sF mA;
+ spvStorage_float3x2 mB;
+};
+
+struct sH
+{
+ sG mA;
+ float2 mB;
+};
+
+struct sI
+{
+ spvStorage_float2x2 mA;
+ short3 mB;
+ short4 mC;
+};
+
+struct sJ
+{
+ sI mA;
+ short3 mB;
+};
+
+struct sK
+{
+ short2 mA;
+ sJ mB;
+ int2 mC;
+};
+
+struct S2
+{
+ sE a;
+ int3 b;
+ sH c;
+ sK d;
+};
+
+struct block
+{
+ uint passed;
+};
+
+constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(1u);
+
+static inline __attribute__((always_inline))
+bool compare_uint(thread const uint& a, thread const uint& b)
+{
+ return a == b;
+}
+
+static inline __attribute__((always_inline))
+bool compare_float(thread const float& a, thread const float& b)
+{
+ return abs(a - b) < 0.0500000007450580596923828125;
+}
+
+static inline __attribute__((always_inline))
+bool compare_vec4(thread const float4& a, thread const float4& b)
+{
+ float param = a.x;
+ float param_1 = b.x;
+ bool _147 = compare_float(param, param_1);
+ bool _157;
+ if (_147)
+ {
+ float param_2 = a.y;
+ float param_3 = b.y;
+ _157 = compare_float(param_2, param_3);
+ }
+ else
+ {
+ _157 = _147;
+ }
+ bool _168;
+ if (_157)
+ {
+ float param_4 = a.z;
+ float param_5 = b.z;
+ _168 = compare_float(param_4, param_5);
+ }
+ else
+ {
+ _168 = _157;
+ }
+ bool _179;
+ if (_168)
+ {
+ float param_6 = a.w;
+ float param_7 = b.w;
+ _179 = compare_float(param_6, param_7);
+ }
+ else
+ {
+ _179 = _168;
+ }
+ return _179;
+}
+
+static inline __attribute__((always_inline))
+bool compare_mat4(thread const float4x4& a, thread const float4x4& b)
+{
+ float4 param = a[0];
+ float4 param_1 = b[0];
+ bool _239 = compare_vec4(param, param_1);
+ bool _249;
+ if (_239)
+ {
+ float4 param_2 = a[1];
+ float4 param_3 = b[1];
+ _249 = compare_vec4(param_2, param_3);
+ }
+ else
+ {
+ _249 = _239;
+ }
+ bool _259;
+ if (_249)
+ {
+ float4 param_4 = a[2];
+ float4 param_5 = b[2];
+ _259 = compare_vec4(param_4, param_5);
+ }
+ else
+ {
+ _259 = _249;
+ }
+ bool _270;
+ if (_259)
+ {
+ float4 param_6 = a[3];
+ float4 param_7 = b[3];
+ _270 = compare_vec4(param_6, param_7);
+ }
+ else
+ {
+ _270 = _259;
+ }
+ return _270;
+}
+
+static inline __attribute__((always_inline))
+bool compare_bvec3(thread const bool3& a, thread const bool3& b)
+{
+ return all(a == b);
+}
+
+static inline __attribute__((always_inline))
+bool compare_bvec4(thread const bool4& a, thread const bool4& b)
+{
+ return all(a == b);
+}
+
+static inline __attribute__((always_inline))
+bool compare_bvec2(thread const bool2& a, thread const bool2& b)
+{
+ return all(a == b);
+}
+
+static inline __attribute__((always_inline))
+bool compare_uvec4(thread const uint4& a, thread const uint4& b)
+{
+ return all(a == b);
+}
+
+static inline __attribute__((always_inline))
+bool compare_ivec3(thread const int3& a, thread const int3& b)
+{
+ return all(a == b);
+}
+
+static inline __attribute__((always_inline))
+bool compare_uvec3(thread const uint3& a, thread const uint3& b)
+{
+ return all(a == b);
+}
+
+static inline __attribute__((always_inline))
+bool compare_bool(thread const bool& a, thread const bool& b)
+{
+ return a == b;
+}
+
+static inline __attribute__((always_inline))
+bool compare_vec2(thread const float2& a, thread const float2& b)
+{
+ float param = a.x;
+ float param_1 = b.x;
+ bool _127 = compare_float(param, param_1);
+ bool _138;
+ if (_127)
+ {
+ float param_2 = a.y;
+ float param_3 = b.y;
+ _138 = compare_float(param_2, param_3);
+ }
+ else
+ {
+ _138 = _127;
+ }
+ return _138;
+}
+
+static inline __attribute__((always_inline))
+bool compare_mat3x2(thread const float3x2& a, thread const float3x2& b)
+{
+ float2 param = a[0];
+ float2 param_1 = b[0];
+ bool _209 = compare_vec2(param, param_1);
+ bool _219;
+ if (_209)
+ {
+ float2 param_2 = a[1];
+ float2 param_3 = b[1];
+ _219 = compare_vec2(param_2, param_3);
+ }
+ else
+ {
+ _219 = _209;
+ }
+ bool _230;
+ if (_219)
+ {
+ float2 param_4 = a[2];
+ float2 param_5 = b[2];
+ _230 = compare_vec2(param_4, param_5);
+ }
+ else
+ {
+ _230 = _219;
+ }
+ return _230;
+}
+
+static inline __attribute__((always_inline))
+bool compare_mat2(thread const float2x2& a, thread const float2x2& b)
+{
+ float2 param = a[0];
+ float2 param_1 = b[0];
+ bool _189 = compare_vec2(param, param_1);
+ bool _200;
+ if (_189)
+ {
+ float2 param_2 = a[1];
+ float2 param_3 = b[1];
+ _200 = compare_vec2(param_2, param_3);
+ }
+ else
+ {
+ _200 = _189;
+ }
+ return _200;
+}
+
+static inline __attribute__((always_inline))
+bool compare_ivec2(thread const int2& a, thread const int2& b)
+{
+ return all(a == b);
+}
+
+kernel void main0(device block& _612 [[buffer(0)]])
+{
+ threadgroup S1 s1;
+ threadgroup S2 s2;
+ s1.a = 0u;
+ s1.b = float4(8.0, 8.0, 0.0, -4.0);
+ s2.a.mA.mA.mA = spvStorage_float4x4(float4x4(float4(-5.0, 9.0, -4.0, -6.0), float4(-1.0, -1.0, -2.0, 1.0), float4(6.0, 5.0, 7.0, -2.0), float4(-4.0, -9.0, 8.0, 3.0)));
+ s2.a.mA.mA.mB = short3(bool3(true, false, false));
+ s2.a.mA.mA.mC = short4(bool4(true, true, true, false));
+ s2.a.mA.mB.mA = short2(bool2(true));
+ s2.a.mA.mC.mA = 7.0;
+ s2.a.mA.mC.mB = uint4(8u, 6u, 2u, 0u);
+ s2.a.mA.mC.mC = -9.0;
+ s2.b = int3(1, -4, 0);
+ s2.c.mA.mA.mA = uint3(4u, 9u, 1u);
+ s2.c.mA.mA.mB = short(false);
+ s2.c.mA.mB = spvStorage_float3x2(float3x2(float2(3.0, -5.0), float2(-1.0, -5.0), float2(-1.0, -9.0)));
+ s2.c.mB = float2(-6.0, -9.0);
+ s2.d.mA = short2(bool2(true, false));
+ s2.d.mB.mA.mA = spvStorage_float2x2(float2x2(float2(-2.0, 3.0), float2(7.0, 2.0)));
+ s2.d.mB.mA.mB = short3(bool3(false));
+ s2.d.mB.mA.mC = short4(bool4(false, false, false, true));
+ s2.d.mB.mB = short3(bool3(true, false, false));
+ s2.d.mC = int2(-9, 0);
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup | mem_flags::mem_texture);
+ bool allOk = true;
+ bool _435;
+ if (allOk)
+ {
+ uint param = 0u;
+ uint param_1 = s1.a;
+ _435 = compare_uint(param, param_1);
+ }
+ else
+ {
+ _435 = allOk;
+ }
+ allOk = _435;
+ bool _444;
+ if (allOk)
+ {
+ float4 param_2 = float4(8.0, 8.0, 0.0, -4.0);
+ float4 param_3 = s1.b;
+ _444 = compare_vec4(param_2, param_3);
+ }
+ else
+ {
+ _444 = allOk;
+ }
+ allOk = _444;
+ bool _453;
+ if (allOk)
+ {
+ float4x4 param_4 = float4x4(float4(-5.0, 9.0, -4.0, -6.0), float4(-1.0, -1.0, -2.0, 1.0), float4(6.0, 5.0, 7.0, -2.0), float4(-4.0, -9.0, 8.0, 3.0));
+ float4x4 param_5 = float4x4(s2.a.mA.mA.mA);
+ _453 = compare_mat4(param_4, param_5);
+ }
+ else
+ {
+ _453 = allOk;
+ }
+ allOk = _453;
+ bool _462;
+ if (allOk)
+ {
+ bool3 param_6 = bool3(true, false, false);
+ bool3 param_7 = bool3(s2.a.mA.mA.mB);
+ _462 = compare_bvec3(param_6, param_7);
+ }
+ else
+ {
+ _462 = allOk;
+ }
+ allOk = _462;
+ bool _471;
+ if (allOk)
+ {
+ bool4 param_8 = bool4(true, true, true, false);
+ bool4 param_9 = bool4(s2.a.mA.mA.mC);
+ _471 = compare_bvec4(param_8, param_9);
+ }
+ else
+ {
+ _471 = allOk;
+ }
+ allOk = _471;
+ bool _480;
+ if (allOk)
+ {
+ bool2 param_10 = bool2(true);
+ bool2 param_11 = bool2(s2.a.mA.mB.mA);
+ _480 = compare_bvec2(param_10, param_11);
+ }
+ else
+ {
+ _480 = allOk;
+ }
+ allOk = _480;
+ bool _489;
+ if (allOk)
+ {
+ float param_12 = 7.0;
+ float param_13 = s2.a.mA.mC.mA;
+ _489 = compare_float(param_12, param_13);
+ }
+ else
+ {
+ _489 = allOk;
+ }
+ allOk = _489;
+ bool _498;
+ if (allOk)
+ {
+ uint4 param_14 = uint4(8u, 6u, 2u, 0u);
+ uint4 param_15 = s2.a.mA.mC.mB;
+ _498 = compare_uvec4(param_14, param_15);
+ }
+ else
+ {
+ _498 = allOk;
+ }
+ allOk = _498;
+ bool _507;
+ if (allOk)
+ {
+ float param_16 = -9.0;
+ float param_17 = s2.a.mA.mC.mC;
+ _507 = compare_float(param_16, param_17);
+ }
+ else
+ {
+ _507 = allOk;
+ }
+ allOk = _507;
+ bool _516;
+ if (allOk)
+ {
+ int3 param_18 = int3(1, -4, 0);
+ int3 param_19 = s2.b;
+ _516 = compare_ivec3(param_18, param_19);
+ }
+ else
+ {
+ _516 = allOk;
+ }
+ allOk = _516;
+ bool _525;
+ if (allOk)
+ {
+ uint3 param_20 = uint3(4u, 9u, 1u);
+ uint3 param_21 = s2.c.mA.mA.mA;
+ _525 = compare_uvec3(param_20, param_21);
+ }
+ else
+ {
+ _525 = allOk;
+ }
+ allOk = _525;
+ bool _534;
+ if (allOk)
+ {
+ bool param_22 = false;
+ bool param_23 = bool(s2.c.mA.mA.mB);
+ _534 = compare_bool(param_22, param_23);
+ }
+ else
+ {
+ _534 = allOk;
+ }
+ allOk = _534;
+ bool _543;
+ if (allOk)
+ {
+ float3x2 param_24 = float3x2(float2(3.0, -5.0), float2(-1.0, -5.0), float2(-1.0, -9.0));
+ float3x2 param_25 = float3x2(s2.c.mA.mB);
+ _543 = compare_mat3x2(param_24, param_25);
+ }
+ else
+ {
+ _543 = allOk;
+ }
+ allOk = _543;
+ bool _552;
+ if (allOk)
+ {
+ float2 param_26 = float2(-6.0, -9.0);
+ float2 param_27 = s2.c.mB;
+ _552 = compare_vec2(param_26, param_27);
+ }
+ else
+ {
+ _552 = allOk;
+ }
+ allOk = _552;
+ bool _561;
+ if (allOk)
+ {
+ bool2 param_28 = bool2(true, false);
+ bool2 param_29 = bool2(s2.d.mA);
+ _561 = compare_bvec2(param_28, param_29);
+ }
+ else
+ {
+ _561 = allOk;
+ }
+ allOk = _561;
+ bool _570;
+ if (allOk)
+ {
+ float2x2 param_30 = float2x2(float2(-2.0, 3.0), float2(7.0, 2.0));
+ float2x2 param_31 = float2x2(s2.d.mB.mA.mA);
+ _570 = compare_mat2(param_30, param_31);
+ }
+ else
+ {
+ _570 = allOk;
+ }
+ allOk = _570;
+ bool _579;
+ if (allOk)
+ {
+ bool3 param_32 = bool3(false);
+ bool3 param_33 = bool3(s2.d.mB.mA.mB);
+ _579 = compare_bvec3(param_32, param_33);
+ }
+ else
+ {
+ _579 = allOk;
+ }
+ allOk = _579;
+ bool _588;
+ if (allOk)
+ {
+ bool4 param_34 = bool4(false, false, false, true);
+ bool4 param_35 = bool4(s2.d.mB.mA.mC);
+ _588 = compare_bvec4(param_34, param_35);
+ }
+ else
+ {
+ _588 = allOk;
+ }
+ allOk = _588;
+ bool _597;
+ if (allOk)
+ {
+ bool3 param_36 = bool3(true, false, false);
+ bool3 param_37 = bool3(s2.d.mB.mB);
+ _597 = compare_bvec3(param_36, param_37);
+ }
+ else
+ {
+ _597 = allOk;
+ }
+ allOk = _597;
+ bool _606;
+ if (allOk)
+ {
+ int2 param_38 = int2(-9, 0);
+ int2 param_39 = s2.d.mC;
+ _606 = compare_ivec2(param_38, param_39);
+ }
+ else
+ {
+ _606 = allOk;
+ }
+ allOk = _606;
+ if (allOk)
+ {
+ _612.passed++;
+ }
+}
+
diff --git a/shaders-msl/comp/shared-matrix-array-of-array.comp b/shaders-msl/comp/shared-matrix-array-of-array.comp
new file mode 100644
index 00000000..3bbd4c0f
--- /dev/null
+++ b/shaders-msl/comp/shared-matrix-array-of-array.comp
@@ -0,0 +1,65 @@
+#version 450
+layout(local_size_x = 1) in;
+
+layout(std140, binding = 0) buffer block { highp uint passed; };
+struct S1 {
+ mediump mat4x3 a[2];
+ lowp float b;
+ lowp vec2 c[3];
+};
+struct S2 {
+ highp ivec4 a;
+ bool b[3][1][3];
+};
+
+bool compare_float (highp float a, highp float b) { return abs(a - b) < 0.05; }
+bool compare_vec2 (highp vec2 a, highp vec2 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y); }
+bool compare_vec3 (highp vec3 a, highp vec3 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y)&&compare_float(a.z, b.z); }
+bool compare_mat4x3 (highp mat4x3 a, highp mat4x3 b){ return compare_vec3(a[0], b[0])&&compare_vec3(a[1], b[1])&&compare_vec3(a[2], b[2])&&compare_vec3(a[3], b[3]); }
+bool compare_ivec4 (highp ivec4 a, highp ivec4 b) { return a == b; }
+bool compare_bool (bool a, bool b) { return a == b; }
+
+shared S1 s1;
+shared S2 s2;
+
+void main (void) {
+ s1.a[0] = mat4x3(0.0, 2.0, -8.0, 6.0, 7.0, 5.0, -6.0, 1.0, 9.0, -4.0, -3.0, 4.0);
+ s1.a[1] = mat4x3(4.0, 9.0, -9.0, -8.0, -9.0, 8.0, 0.0, 4.0, -4.0, 7.0, 2.0, -1.0);
+ s1.b = 7.0;
+ s1.c[0] = vec2(-5.0, -4.0);
+ s1.c[1] = vec2(3.0, -5.0);
+ s1.c[2] = vec2(-3.0, -1.0);
+ s2.a = ivec4(1, 0, -3, 1);
+ s2.b[0][0][0] = true;
+ s2.b[0][0][1] = false;
+ s2.b[0][0][2] = false;
+ s2.b[1][0][0] = true;
+ s2.b[1][0][1] = false;
+ s2.b[1][0][2] = true;
+ s2.b[2][0][0] = false;
+ s2.b[2][0][1] = true;
+ s2.b[2][0][2] = true;
+
+ barrier();
+ memoryBarrier();
+ bool allOk = true;
+ allOk = allOk && compare_mat4x3(mat4x3(0.0, 2.0, -8.0, 6.0, 7.0, 5.0, -6.0, 1.0, 9.0, -4.0, -3.0, 4.0), s1.a[0]);
+ allOk = allOk && compare_mat4x3(mat4x3(4.0, 9.0, -9.0, -8.0, -9.0, 8.0, 0.0, 4.0, -4.0, 7.0, 2.0, -1.0), s1.a[1]);
+ allOk = allOk && compare_float(7.0, s1.b);
+ allOk = allOk && compare_vec2(vec2(-5.0, -4.0), s1.c[0]);
+ allOk = allOk && compare_vec2(vec2(3.0, -5.0), s1.c[1]);
+ allOk = allOk && compare_vec2(vec2(-3.0, -1.0), s1.c[2]);
+ allOk = allOk && compare_ivec4(ivec4(1, 0, -3, 1), s2.a);
+ allOk = allOk && compare_bool(true, s2.b[0][0][0]);
+ allOk = allOk && compare_bool(false, s2.b[0][0][1]);
+ allOk = allOk && compare_bool(false, s2.b[0][0][2]);
+ allOk = allOk && compare_bool(true, s2.b[1][0][0]);
+ allOk = allOk && compare_bool(false, s2.b[1][0][1]);
+ allOk = allOk && compare_bool(true, s2.b[1][0][2]);
+ allOk = allOk && compare_bool(false, s2.b[2][0][0]);
+ allOk = allOk && compare_bool(true, s2.b[2][0][1]);
+ allOk = allOk && compare_bool(true, s2.b[2][0][2]);
+ if (allOk)
+ passed++;
+
+}
diff --git a/shaders-msl/comp/shared-matrix-cast.comp b/shaders-msl/comp/shared-matrix-cast.comp
new file mode 100644
index 00000000..7e46fed7
--- /dev/null
+++ b/shaders-msl/comp/shared-matrix-cast.comp
@@ -0,0 +1,33 @@
+#version 450
+layout(local_size_x = 1) in;
+
+layout(std140, binding = 0) buffer block { highp uint passed; };
+struct S1 {
+ mediump vec4 a;
+ highp mat3x2 b;
+ bvec4 c;
+};
+
+bool compare_float (highp float a, highp float b) { return abs(a - b) < 0.05; }
+bool compare_vec2 (highp vec2 a, highp vec2 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y); }
+bool compare_vec4 (highp vec4 a, highp vec4 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y)&&compare_float(a.z, b.z)&&compare_float(a.w, b.w); }
+bool compare_mat3x2 (highp mat3x2 a, highp mat3x2 b){ return compare_vec2(a[0], b[0])&&compare_vec2(a[1], b[1])&&compare_vec2(a[2], b[2]); }
+bool compare_bvec4 (bvec4 a, bvec4 b) { return a == b; }
+
+shared S1 s1;
+
+void main (void) {
+ s1.a = vec4(1.0, -5.0, -9.0, -5.0);
+ s1.b = mat3x2(1.0, -7.0, 1.0, 2.0, 8.0, 7.0);
+ s1.c = bvec4(false, true, false, false);
+
+ barrier();
+ memoryBarrier();
+ bool allOk = true;
+ allOk = allOk && compare_vec4(vec4(1.0, -5.0, -9.0, -5.0), s1.a);
+ allOk = allOk && compare_mat3x2(mat3x2(1.0, -7.0, 1.0, 2.0, 8.0, 7.0), s1.b);
+ allOk = allOk && compare_bvec4(bvec4(false, true, false, false), s1.c);
+ if (allOk)
+ passed++;
+
+}
diff --git a/shaders-msl/comp/shared-matrix-nested-struct-array.comp b/shaders-msl/comp/shared-matrix-nested-struct-array.comp
new file mode 100644
index 00000000..59ab24d8
--- /dev/null
+++ b/shaders-msl/comp/shared-matrix-nested-struct-array.comp
@@ -0,0 +1,87 @@
+#version 450
+layout(local_size_x = 1) in;
+
+layout(std140, binding = 0) buffer block { highp uint passed; };
+struct sA
+{
+ mediump mat2x3 mA;
+};
+struct sB
+{
+ mediump mat2 mA;
+ mediump mat3x2 mB;
+ highp uvec3 mC;
+};
+struct sC
+{
+ sA mA;
+ sB mB;
+};
+struct sD
+{
+ sC mA;
+};
+struct sE
+{
+ lowp mat3x2 mA;
+ lowp mat4x3 mB;
+};
+struct sF
+{
+ sE mA;
+};
+struct sG
+{
+ sF mA;
+};
+struct sH
+{
+ bvec3 mA[2];
+};
+struct S1 {
+ sD a;
+ sG b;
+ sH c[2];
+};
+
+bool compare_float (highp float a, highp float b) { return abs(a - b) < 0.05; }
+bool compare_vec2 (highp vec2 a, highp vec2 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y); }
+bool compare_vec3 (highp vec3 a, highp vec3 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y)&&compare_float(a.z, b.z); }
+bool compare_mat2 (highp mat2 a, highp mat2 b) { return compare_vec2(a[0], b[0])&&compare_vec2(a[1], b[1]); }
+bool compare_mat2x3 (highp mat2x3 a, highp mat2x3 b){ return compare_vec3(a[0], b[0])&&compare_vec3(a[1], b[1]); }
+bool compare_mat3x2 (highp mat3x2 a, highp mat3x2 b){ return compare_vec2(a[0], b[0])&&compare_vec2(a[1], b[1])&&compare_vec2(a[2], b[2]); }
+bool compare_mat4x3 (highp mat4x3 a, highp mat4x3 b){ return compare_vec3(a[0], b[0])&&compare_vec3(a[1], b[1])&&compare_vec3(a[2], b[2])&&compare_vec3(a[3], b[3]); }
+bool compare_uvec3 (highp uvec3 a, highp uvec3 b) { return a == b; }
+bool compare_bvec3 (bvec3 a, bvec3 b) { return a == b; }
+
+shared S1 s1;
+
+void main (void) {
+ s1.a.mA.mA.mA = mat2x3(6.0, 8.0, 8.0, 0.0, -4.0, -5.0);
+ s1.a.mA.mB.mA = mat2(9.0, -4.0, -6.0, -1.0);
+ s1.a.mA.mB.mB = mat3x2(-1.0, -2.0, 1.0, 6.0, 5.0, 7.0);
+ s1.a.mA.mB.mC = uvec3(3u, 1u, 5u);
+ s1.b.mA.mA.mA = mat3x2(8.0, 3.0, 0.0, 2.0, 1.0, 8.0);
+ s1.b.mA.mA.mB = mat4x3(0.0, 9.0, -1.0, -1.0, -7.0, 7.0, -4.0, -3.0, 1.0, -4.0, -9.0, 1.0);
+ s1.c[0].mA[0] = bvec3(true, false, false);
+ s1.c[0].mA[1] = bvec3(true, false, false);
+ s1.c[1].mA[0] = bvec3(false, false, false);
+ s1.c[1].mA[1] = bvec3(false, false, false);
+
+ barrier();
+ memoryBarrier();
+ bool allOk = true;
+ allOk = allOk && compare_mat2x3(mat2x3(6.0, 8.0, 8.0, 0.0, -4.0, -5.0), s1.a.mA.mA.mA);
+ allOk = allOk && compare_mat2(mat2(9.0, -4.0, -6.0, -1.0), s1.a.mA.mB.mA);
+ allOk = allOk && compare_mat3x2(mat3x2(-1.0, -2.0, 1.0, 6.0, 5.0, 7.0), s1.a.mA.mB.mB);
+ allOk = allOk && compare_uvec3(uvec3(3u, 1u, 5u), s1.a.mA.mB.mC);
+ allOk = allOk && compare_mat3x2(mat3x2(8.0, 3.0, 0.0, 2.0, 1.0, 8.0), s1.b.mA.mA.mA);
+ allOk = allOk && compare_mat4x3(mat4x3(0.0, 9.0, -1.0, -1.0, -7.0, 7.0, -4.0, -3.0, 1.0, -4.0, -9.0, 1.0), s1.b.mA.mA.mB);
+ allOk = allOk && compare_bvec3(bvec3(true, false, false), s1.c[0].mA[0]);
+ allOk = allOk && compare_bvec3(bvec3(true, false, false), s1.c[0].mA[1]);
+ allOk = allOk && compare_bvec3(bvec3(false, false, false), s1.c[1].mA[0]);
+ allOk = allOk && compare_bvec3(bvec3(false, false, false), s1.c[1].mA[1]);
+ if (allOk)
+ passed++;
+
+}
diff --git a/shaders-msl/comp/shared-matrix-nested-struct.comp b/shaders-msl/comp/shared-matrix-nested-struct.comp
new file mode 100644
index 00000000..c481f54a
--- /dev/null
+++ b/shaders-msl/comp/shared-matrix-nested-struct.comp
@@ -0,0 +1,141 @@
+#version 450
+layout(local_size_x = 1) in;
+
+layout(std140, binding = 0) buffer block { highp uint passed; };
+struct sA
+{
+ highp mat4 mA;
+ bvec3 mB;
+ bvec4 mC;
+};
+struct sB
+{
+ bvec2 mA;
+};
+struct sC
+{
+ highp float mA;
+ mediump uvec4 mB;
+ mediump float mC;
+};
+struct sD
+{
+ sA mA;
+ sB mB;
+ sC mC;
+};
+struct sE
+{
+ sD mA;
+};
+struct sF
+{
+ lowp uvec3 mA;
+ bool mB;
+};
+struct sG
+{
+ sF mA;
+ highp mat3x2 mB;
+};
+struct sH
+{
+ sG mA;
+ mediump vec2 mB;
+};
+struct sI
+{
+ mediump mat2 mA;
+ bvec3 mB;
+ bvec4 mC;
+};
+struct sJ
+{
+ sI mA;
+ bvec3 mB;
+};
+struct sK
+{
+ bvec2 mA;
+ sJ mB;
+ mediump ivec2 mC;
+};
+struct S1 {
+ lowp uint a;
+ mediump vec4 b;
+};
+struct S2 {
+ sE a;
+ highp ivec3 b;
+ sH c;
+ sK d;
+};
+
+bool compare_float (highp float a, highp float b) { return abs(a - b) < 0.05; }
+bool compare_vec2 (highp vec2 a, highp vec2 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y); }
+bool compare_vec4 (highp vec4 a, highp vec4 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y)&&compare_float(a.z, b.z)&&compare_float(a.w, b.w); }
+bool compare_mat2 (highp mat2 a, highp mat2 b) { return compare_vec2(a[0], b[0])&&compare_vec2(a[1], b[1]); }
+bool compare_mat3x2 (highp mat3x2 a, highp mat3x2 b){ return compare_vec2(a[0], b[0])&&compare_vec2(a[1], b[1])&&compare_vec2(a[2], b[2]); }
+bool compare_mat4 (highp mat4 a, highp mat4 b) { return compare_vec4(a[0], b[0])&&compare_vec4(a[1], b[1])&&compare_vec4(a[2], b[2])&&compare_vec4(a[3], b[3]); }
+bool compare_ivec2 (highp ivec2 a, highp ivec2 b) { return a == b; }
+bool compare_ivec3 (highp ivec3 a, highp ivec3 b) { return a == b; }
+bool compare_uint (highp uint a, highp uint b) { return a == b; }
+bool compare_uvec3 (highp uvec3 a, highp uvec3 b) { return a == b; }
+bool compare_uvec4 (highp uvec4 a, highp uvec4 b) { return a == b; }
+bool compare_bool (bool a, bool b) { return a == b; }
+bool compare_bvec2 (bvec2 a, bvec2 b) { return a == b; }
+bool compare_bvec3 (bvec3 a, bvec3 b) { return a == b; }
+bool compare_bvec4 (bvec4 a, bvec4 b) { return a == b; }
+
+shared S1 s1;
+shared S2 s2;
+
+void main (void) {
+ s1.a = 0u;
+ s1.b = vec4(8.0, 8.0, 0.0, -4.0);
+ s2.a.mA.mA.mA = mat4(-5.0, 9.0, -4.0, -6.0, -1.0, -1.0, -2.0, 1.0, 6.0, 5.0, 7.0, -2.0, -4.0, -9.0, 8.0, 3.0);
+ s2.a.mA.mA.mB = bvec3(true, false, false);
+ s2.a.mA.mA.mC = bvec4(true, true, true, false);
+ s2.a.mA.mB.mA = bvec2(true, true);
+ s2.a.mA.mC.mA = 7.0;
+ s2.a.mA.mC.mB = uvec4(8u, 6u, 2u, 0u);
+ s2.a.mA.mC.mC = -9.0;
+ s2.b = ivec3(1, -4, 0);
+ s2.c.mA.mA.mA = uvec3(4u, 9u, 1u);
+ s2.c.mA.mA.mB = false;
+ s2.c.mA.mB = mat3x2(3.0, -5.0, -1.0, -5.0, -1.0, -9.0);
+ s2.c.mB = vec2(-6.0, -9.0);
+ s2.d.mA = bvec2(true, false);
+ s2.d.mB.mA.mA = mat2(-2.0, 3.0, 7.0, 2.0);
+ s2.d.mB.mA.mB = bvec3(false, false, false);
+ s2.d.mB.mA.mC = bvec4(false, false, false, true);
+ s2.d.mB.mB = bvec3(true, false, false);
+ s2.d.mC = ivec2(-9, 0);
+
+ barrier();
+ memoryBarrier();
+ bool allOk = true;
+ allOk = allOk && compare_uint(0u, s1.a);
+ allOk = allOk && compare_vec4(vec4(8.0, 8.0, 0.0, -4.0), s1.b);
+ allOk = allOk && compare_mat4(mat4(-5.0, 9.0, -4.0, -6.0, -1.0, -1.0, -2.0, 1.0, 6.0, 5.0, 7.0, -2.0, -4.0, -9.0, 8.0, 3.0), s2.a.mA.mA.mA);
+ allOk = allOk && compare_bvec3(bvec3(true, false, false), s2.a.mA.mA.mB);
+ allOk = allOk && compare_bvec4(bvec4(true, true, true, false), s2.a.mA.mA.mC);
+ allOk = allOk && compare_bvec2(bvec2(true, true), s2.a.mA.mB.mA);
+ allOk = allOk && compare_float(7.0, s2.a.mA.mC.mA);
+ allOk = allOk && compare_uvec4(uvec4(8u, 6u, 2u, 0u), s2.a.mA.mC.mB);
+ allOk = allOk && compare_float(-9.0, s2.a.mA.mC.mC);
+ allOk = allOk && compare_ivec3(ivec3(1, -4, 0), s2.b);
+ allOk = allOk && compare_uvec3(uvec3(4u, 9u, 1u), s2.c.mA.mA.mA);
+ allOk = allOk && compare_bool(false, s2.c.mA.mA.mB);
+ allOk = allOk && compare_mat3x2(mat3x2(3.0, -5.0, -1.0, -5.0, -1.0, -9.0), s2.c.mA.mB);
+ allOk = allOk && compare_vec2(vec2(-6.0, -9.0), s2.c.mB);
+ allOk = allOk && compare_bvec2(bvec2(true, false), s2.d.mA);
+ allOk = allOk && compare_mat2(mat2(-2.0, 3.0, 7.0, 2.0), s2.d.mB.mA.mA);
+ allOk = allOk && compare_bvec3(bvec3(false, false, false), s2.d.mB.mA.mB);
+ allOk = allOk && compare_bvec4(bvec4(false, false, false, true), s2.d.mB.mA.mC);
+ allOk = allOk && compare_bvec3(bvec3(true, false, false), s2.d.mB.mB);
+ allOk = allOk && compare_ivec2(ivec2(-9, 0), s2.d.mC);
+ if (allOk)
+ passed++;
+
+}
diff --git a/spirv_common.hpp b/spirv_common.hpp
index 1c8a7253..06b1a3d8 100644
--- a/spirv_common.hpp
+++ b/spirv_common.hpp
@@ -1636,6 +1636,12 @@ enum ExtendedDecorations
// results of interpolation can.
SPIRVCrossDecorationInterpolantComponentExpr,
+ // Apply to any struct type that is used in the Workgroup storage class.
+ // This causes matrices in MSL prior to Metal 3.0 to be emitted using a special
+ // class that is convertible to the standard matrix type, to work around the
+ // lack of constructors in the 'threadgroup' address space.
+ SPIRVCrossDecorationWorkgroupStruct,
+
SPIRVCrossDecorationCount
};
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp
index f47ac62a..388ec21e 100644
--- a/spirv_glsl.cpp
+++ b/spirv_glsl.cpp
@@ -10741,9 +10741,15 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
if (expr_type.vecsize > type.vecsize)
expr = enclose_expression(expr + vector_swizzle(type.vecsize, 0));
+ if (forward && ptr_expression)
+ ptr_expression->need_transpose = old_need_transpose;
+
// We might need to cast in order to load from a builtin.
cast_from_variable_load(ptr, expr, type);
+ if (forward && ptr_expression)
+ ptr_expression->need_transpose = false;
+
// We might be trying to load a gl_Position[N], where we should be
// doing float4[](gl_in[i].gl_Position, ...) instead.
// Similar workarounds are required for input arrays in tessellation.
diff --git a/spirv_msl.cpp b/spirv_msl.cpp
index 378c09a7..0918fb40 100644
--- a/spirv_msl.cpp
+++ b/spirv_msl.cpp
@@ -1966,6 +1966,13 @@ void CompilerMSL::mark_packable_structs()
(has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock)))
mark_as_packable(type);
}
+
+ if (var.storage == StorageClassWorkgroup)
+ {
+ auto *type = &this->get<SPIRType>(var.basetype);
+ if (type->basetype == SPIRType::Struct)
+ mark_as_workgroup_struct(*type);
+ }
});
// Physical storage buffer pointers can appear outside of the context of a variable, if the address
@@ -2008,6 +2015,38 @@ void CompilerMSL::mark_as_packable(SPIRType &type)
}
}
+// If the specified type is a struct, it and any nested structs
+// are marked as used with workgroup storage using the SPIRVCrossDecorationWorkgroupStruct decoration.
+void CompilerMSL::mark_as_workgroup_struct(SPIRType &type)
+{
+ // If this is not the base type (eg. it's a pointer or array), tunnel down
+ if (type.parent_type)
+ {
+ mark_as_workgroup_struct(get<SPIRType>(type.parent_type));
+ return;
+ }
+
+ // Handle possible recursion when a struct contains a pointer to its own type nested somewhere.
+ if (type.basetype == SPIRType::Struct && !has_extended_decoration(type.self, SPIRVCrossDecorationWorkgroupStruct))
+ {
+ set_extended_decoration(type.self, SPIRVCrossDecorationWorkgroupStruct);
+
+ // Recurse
+ uint32_t mbr_cnt = uint32_t(type.member_types.size());
+ for (uint32_t mbr_idx = 0; mbr_idx < mbr_cnt; mbr_idx++)
+ {
+ uint32_t mbr_type_id = type.member_types[mbr_idx];
+ auto &mbr_type = get<SPIRType>(mbr_type_id);
+ mark_as_workgroup_struct(mbr_type);
+ if (mbr_type.type_alias)
+ {
+ auto &mbr_type_alias = get<SPIRType>(mbr_type.type_alias);
+ mark_as_workgroup_struct(mbr_type_alias);
+ }
+ }
+ }
+}
+
// If a shader input exists at the location, it is marked as being used by this shader
void CompilerMSL::mark_location_as_used_by_shader(uint32_t location, const SPIRType &type,
StorageClass storage, bool fallback)
@@ -4828,6 +4867,10 @@ void CompilerMSL::add_typedef_line(const string &line)
// Template struct like spvUnsafeArray<> need to be declared *before* any resources are declared
void CompilerMSL::emit_custom_templates()
{
+ static const string address_spaces[] = {
+ "thread", "constant", "device", "threadgroup", "threadgroup_imageblock", "ray_data", "object_data"
+ };
+
for (const auto &spv_func : spv_function_implementations)
{
switch (spv_func)
@@ -4873,6 +4916,122 @@ void CompilerMSL::emit_custom_templates()
statement("");
break;
+ case SPVFuncImplStorageMatrix:
+ statement("template<typename T, int Cols, int Rows=Cols>");
+ statement("struct spvStorageMatrix");
+ begin_scope();
+ statement("vec<T, Rows> columns[Cols];");
+ statement("");
+ for (size_t method_idx = 0; method_idx < sizeof(address_spaces) / sizeof(address_spaces[0]); ++method_idx)
+ {
+ // Some address spaces require particular features.
+ if (method_idx == 4) // threadgroup_imageblock
+ statement("#ifdef __HAVE_IMAGEBLOCKS__");
+ else if (method_idx == 5) // ray_data
+ statement("#ifdef __HAVE_RAYTRACING__");
+ else if (method_idx == 6) // object_data
+ statement("#ifdef __HAVE_MESH__");
+ const string &method_as = address_spaces[method_idx];
+ statement("spvStorageMatrix() ", method_as, " = default;");
+ if (method_idx != 1) // constant
+ {
+ statement(method_as, " spvStorageMatrix& operator=(initializer_list<vec<T, Rows>> cols) ",
+ method_as);
+ begin_scope();
+ statement("size_t i;");
+ statement("thread vec<T, Rows>* col;");
+ statement("for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)");
+ statement(" columns[i] = *col;");
+ statement("return *this;");
+ end_scope();
+ }
+ statement("");
+ for (size_t param_idx = 0; param_idx < sizeof(address_spaces) / sizeof(address_spaces[0]); ++param_idx)
+ {
+ if (param_idx != method_idx)
+ {
+ if (param_idx == 4) // threadgroup_imageblock
+ statement("#ifdef __HAVE_IMAGEBLOCKS__");
+ else if (param_idx == 5) // ray_data
+ statement("#ifdef __HAVE_RAYTRACING__");
+ else if (param_idx == 6) // object_data
+ statement("#ifdef __HAVE_MESH__");
+ }
+ const string &param_as = address_spaces[param_idx];
+ statement("spvStorageMatrix(const ", param_as, " matrix<T, Cols, Rows>& m) ", method_as);
+ begin_scope();
+ statement("for (size_t i = 0; i < Cols; ++i)");
+ statement(" columns[i] = m.columns[i];");
+ end_scope();
+ statement("spvStorageMatrix(const ", param_as, " spvStorageMatrix& m) ", method_as, " = default;");
+ if (method_idx != 1) // constant
+ {
+ statement(method_as, " spvStorageMatrix& operator=(const ", param_as,
+ " matrix<T, Cols, Rows>& m) ", method_as);
+ begin_scope();
+ statement("for (size_t i = 0; i < Cols; ++i)");
+ statement(" columns[i] = m.columns[i];");
+ statement("return *this;");
+ end_scope();
+ statement(method_as, " spvStorageMatrix& operator=(const ", param_as, " spvStorageMatrix& m) ",
+ method_as, " = default;");
+ }
+ if (param_idx != method_idx && param_idx >= 4)
+ statement("#endif");
+ statement("");
+ }
+ statement("operator matrix<T, Cols, Rows>() const ", method_as);
+ begin_scope();
+ statement("matrix<T, Cols, Rows> m;");
+ statement("for (int i = 0; i < Cols; ++i)");
+ statement(" m.columns[i] = columns[i];");
+ statement("return m;");
+ end_scope();
+ statement("");
+ statement("vec<T, Rows> operator[](size_t idx) const ", method_as);
+ begin_scope();
+ statement("return columns[idx];");
+ end_scope();
+ if (method_idx != 1) // constant
+ {
+ statement(method_as, " vec<T, Rows>& operator[](size_t idx) ", method_as);
+ begin_scope();
+ statement("return columns[idx];");
+ end_scope();
+ }
+ if (method_idx >= 4)
+ statement("#endif");
+ statement("");
+ }
+ end_scope_decl();
+ statement("");
+ statement("template<typename T, int Cols, int Rows>");
+ statement("matrix<T, Rows, Cols> transpose(spvStorageMatrix<T, Cols, Rows> m)");
+ begin_scope();
+ statement("return transpose(matrix<T, Cols, Rows>(m));");
+ end_scope();
+ statement("");
+ statement("typedef spvStorageMatrix<half, 2, 2> spvStorage_half2x2;");
+ statement("typedef spvStorageMatrix<half, 2, 3> spvStorage_half2x3;");
+ statement("typedef spvStorageMatrix<half, 2, 4> spvStorage_half2x4;");
+ statement("typedef spvStorageMatrix<half, 3, 2> spvStorage_half3x2;");
+ statement("typedef spvStorageMatrix<half, 3, 3> spvStorage_half3x3;");
+ statement("typedef spvStorageMatrix<half, 3, 4> spvStorage_half3x4;");
+ statement("typedef spvStorageMatrix<half, 4, 2> spvStorage_half4x2;");
+ statement("typedef spvStorageMatrix<half, 4, 3> spvStorage_half4x3;");
+ statement("typedef spvStorageMatrix<half, 4, 4> spvStorage_half4x4;");
+ statement("typedef spvStorageMatrix<float, 2, 2> spvStorage_float2x2;");
+ statement("typedef spvStorageMatrix<float, 2, 3> spvStorage_float2x3;");
+ statement("typedef spvStorageMatrix<float, 2, 4> spvStorage_float2x4;");
+ statement("typedef spvStorageMatrix<float, 3, 2> spvStorage_float3x2;");
+ statement("typedef spvStorageMatrix<float, 3, 3> spvStorage_float3x3;");
+ statement("typedef spvStorageMatrix<float, 3, 4> spvStorage_float3x4;");
+ statement("typedef spvStorageMatrix<float, 4, 2> spvStorage_float4x2;");
+ statement("typedef spvStorageMatrix<float, 4, 3> spvStorage_float4x3;");
+ statement("typedef spvStorageMatrix<float, 4, 4> spvStorage_float4x4;");
+ statement("");
+ break;
+
default:
break;
}
@@ -10872,12 +11031,23 @@ string CompilerMSL::to_struct_member(const SPIRType &type, uint32_t member_type_
else if (!is_scalar(physical_type)) // scalar type is already packed.
pack_pfx = "packed_";
}
- else if (row_major)
+ else if (is_matrix(physical_type))
{
- // Need to declare type with flipped vecsize/columns.
- row_major_physical_type = physical_type;
- swap(row_major_physical_type.vecsize, row_major_physical_type.columns);
- declared_type = &row_major_physical_type;
+ if (!msl_options.supports_msl_version(3, 0) &&
+ has_extended_decoration(type.self, SPIRVCrossDecorationWorkgroupStruct))
+ {
+ pack_pfx = "spvStorage_";
+ add_spv_func_and_recompile(SPVFuncImplStorageMatrix);
+ // The pack prefix causes problems with array<T> wrappers.
+ is_using_builtin_array = true;
+ }
+ if (row_major)
+ {
+ // Need to declare type with flipped vecsize/columns.
+ row_major_physical_type = physical_type;
+ swap(row_major_physical_type.vecsize, row_major_physical_type.columns);
+ declared_type = &row_major_physical_type;
+ }
}
// Very specifically, image load-store in argument buffers are disallowed on MSL on iOS.
@@ -13733,7 +13903,24 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id, bool member)
// Matrix?
if (type.columns > 1)
+ {
+ auto *var = maybe_get_backing_variable(id);
+ if (var && var->basevariable)
+ var = &get<SPIRVariable>(var->basevariable);
+
+ // Need to special-case threadgroup matrices. Due to an oversight, Metal's
+ // matrix struct prior to Metal 3 lacks constructors in the threadgroup AS,
+ // preventing us from default-constructing or initializing matrices in threadgroup storage.
+ // Work around this by using our own type as storage.
+ if (((var && var->storage == StorageClassWorkgroup) || type.storage == StorageClassWorkgroup) &&
+ !msl_options.supports_msl_version(3, 0))
+ {
+ add_spv_func_and_recompile(SPVFuncImplStorageMatrix);
+ type_name = "spvStorage_" + type_name;
+ }
+
type_name += to_string(type.columns) + "x";
+ }
// Vector or Matrix?
if (type.vecsize > 1)
@@ -15789,8 +15976,14 @@ void CompilerMSL::remap_constexpr_sampler_by_binding(uint32_t desc_set, uint32_t
void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type)
{
+ bool is_packed = has_extended_decoration(source_id, SPIRVCrossDecorationPhysicalTypePacked);
+ auto *source_expr = maybe_get<SPIRExpression>(source_id);
auto *var = maybe_get_backing_variable(source_id);
- SPIRType *var_type;
+ const SPIRType *var_type, *phys_type;
+ if (uint32_t phys_id = get_extended_decoration(source_id, SPIRVCrossDecorationPhysicalTypeID))
+ phys_type = &get<SPIRType>(phys_id);
+ else
+ phys_type = &expr_type;
if (var)
{
source_id = var->self;
@@ -15801,6 +15994,22 @@ void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr,
if (var && (var->storage == StorageClassWorkgroup || var_type->basetype == SPIRType::Struct) &&
expr_type.basetype == SPIRType::Boolean)
expr = join(type_to_glsl(expr_type), "(", expr, ")");
+ // Type fixups for workgroup variables if they are matrices.
+ // Don't do fixup for packed types; those are handled specially.
+ // FIXME: Maybe use a type like spvStorageMatrix for packed matrices?
+ if (!msl_options.supports_msl_version(3, 0) && var &&
+ (var->storage == StorageClassWorkgroup ||
+ (var_type->basetype == SPIRType::Struct &&
+ has_extended_decoration(var_type->self, SPIRVCrossDecorationWorkgroupStruct) && !is_packed)) &&
+ expr_type.columns > 1)
+ {
+ SPIRType matrix_type = *phys_type;
+ if (source_expr && source_expr->need_transpose)
+ swap(matrix_type.vecsize, matrix_type.columns);
+ matrix_type.array.clear();
+ matrix_type.array_size_literal.clear();
+ expr = join(type_to_glsl(matrix_type), "(", expr, ")");
+ }
// Only interested in standalone builtin variables in the switch below.
if (!has_decoration(source_id, DecorationBuiltIn))
@@ -15893,8 +16102,14 @@ void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr,
void CompilerMSL::cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type)
{
+ bool is_packed = has_extended_decoration(target_id, SPIRVCrossDecorationPhysicalTypePacked);
+ auto *target_expr = maybe_get<SPIRExpression>(target_id);
auto *var = maybe_get_backing_variable(target_id);
- SPIRType *var_type;
+ const SPIRType *var_type, *phys_type;
+ if (uint32_t phys_id = get_extended_decoration(target_id, SPIRVCrossDecorationPhysicalTypeID))
+ phys_type = &get<SPIRType>(phys_id);
+ else
+ phys_type = &expr_type;
if (var)
{
target_id = var->self;
@@ -15909,6 +16124,20 @@ void CompilerMSL::cast_to_variable_store(uint32_t target_id, std::string &expr,
short_type.basetype = SPIRType::Short;
expr = join(type_to_glsl(short_type), "(", expr, ")");
}
+ // Type fixups for workgroup variables if they are matrices.
+ // Don't do fixup for packed types; those are handled specially.
+ // FIXME: Maybe use a type like spvStorageMatrix for packed matrices?
+ if (!msl_options.supports_msl_version(3, 0) && var &&
+ (var->storage == StorageClassWorkgroup ||
+ (var_type->basetype == SPIRType::Struct &&
+ has_extended_decoration(var_type->self, SPIRVCrossDecorationWorkgroupStruct) && !is_packed)) &&
+ expr_type.columns > 1)
+ {
+ SPIRType matrix_type = *phys_type;
+ if (target_expr && target_expr->need_transpose)
+ swap(matrix_type.vecsize, matrix_type.columns);
+ expr = join("spvStorage_", type_to_glsl(matrix_type), "(", expr, ")");
+ }
// Only interested in standalone builtin variables.
if (!has_decoration(target_id, DecorationBuiltIn))
diff --git a/spirv_msl.hpp b/spirv_msl.hpp
index 920f9fc0..c15159cf 100644
--- a/spirv_msl.hpp
+++ b/spirv_msl.hpp
@@ -665,6 +665,7 @@ protected:
SPVFuncImplQuantizeToF16,
SPVFuncImplCubemapTo2DArrayFace,
SPVFuncImplUnsafeArray, // Allow Metal to use the array<T> template to make arrays a value type
+ SPVFuncImplStorageMatrix, // Allow threadgroup construction of matrices
SPVFuncImplInverse4x4,
SPVFuncImplInverse3x3,
SPVFuncImplInverse2x2,
@@ -797,6 +798,7 @@ protected:
void extract_global_variables_from_functions();
void mark_packable_structs();
void mark_as_packable(SPIRType &type);
+ void mark_as_workgroup_struct(SPIRType &type);
std::unordered_map<uint32_t, std::set<uint32_t>> function_global_vars;
void extract_global_variables_from_function(uint32_t func_id, std::set<uint32_t> &added_arg_ids,