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:
authorHans-Kristian Arntzen <post@arntzen-software.no>2022-08-09 12:54:53 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2022-08-09 12:54:53 +0300
commit1bc05ef73575654c79e61390269c83a03c09b86c (patch)
treee26754e75c46fbad282dd03f9ba54f93a6fb2a1d
parent0cccd0a65a67f33922f8d0742b5930fd15353fa7 (diff)
parenta9cadd4982874dda1075e57639a18702fc1f9f29 (diff)
Merge branch 'master' of https://github.com/gpx1000/SPIRV-Cross
-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/opt/shaders-msl/comp/shared-struct-bool-cast.comp63
-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--reference/shaders-msl/comp/shared-struct-bool-cast.comp110
-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--shaders-msl/comp/shared-struct-bool-cast.comp35
-rw-r--r--spirv_common.hpp6
-rw-r--r--spirv_glsl.cpp6
-rw-r--r--spirv_msl.cpp268
-rw-r--r--spirv_msl.hpp3
19 files changed, 11126 insertions, 13 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/opt/shaders-msl/comp/shared-struct-bool-cast.comp b/reference/opt/shaders-msl/comp/shared-struct-bool-cast.comp
new file mode 100644
index 00000000..538ab0bd
--- /dev/null
+++ b/reference/opt/shaders-msl/comp/shared-struct-bool-cast.comp
@@ -0,0 +1,63 @@
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct S1
+{
+ int3 a;
+ uint2 b;
+ short4 c;
+ uint d;
+};
+
+struct block
+{
+ uint passed;
+};
+
+constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(1u);
+
+kernel void main0(device block& _132 [[buffer(0)]])
+{
+ threadgroup S1 s1;
+ s1.a = int3(6, 8, 8);
+ s1.b = uint2(4u);
+ s1.c = short4(bool4(false, false, false, true));
+ s1.d = 6u;
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup | mem_flags::mem_texture);
+ bool _144 = all(int3(6, 8, 8) == s1.a);
+ bool _108;
+ if (_144)
+ {
+ _108 = all(uint2(4u) == s1.b);
+ }
+ else
+ {
+ _108 = _144;
+ }
+ bool _117;
+ if (_108)
+ {
+ _117 = all(bool4(false, false, false, true) == bool4(s1.c));
+ }
+ else
+ {
+ _117 = _108;
+ }
+ bool _126;
+ if (_117)
+ {
+ _126 = 6u == s1.d;
+ }
+ else
+ {
+ _126 = _117;
+ }
+ if (_126)
+ {
+ _132.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/reference/shaders-msl/comp/shared-struct-bool-cast.comp b/reference/shaders-msl/comp/shared-struct-bool-cast.comp
new file mode 100644
index 00000000..806cb0a8
--- /dev/null
+++ b/reference/shaders-msl/comp/shared-struct-bool-cast.comp
@@ -0,0 +1,110 @@
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
+
+#include <metal_stdlib>
+#include <simd/simd.h>
+
+using namespace metal;
+
+struct S1
+{
+ int3 a;
+ uint2 b;
+ short4 c;
+ uint d;
+};
+
+struct block
+{
+ uint passed;
+};
+
+constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(1u);
+
+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_uvec2(thread const uint2& a, thread const uint2& 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_uint(thread const uint& a, thread const uint& b)
+{
+ return a == b;
+}
+
+kernel void main0(device block& _132 [[buffer(0)]])
+{
+ threadgroup S1 s1;
+ s1.a = int3(6, 8, 8);
+ s1.b = uint2(4u);
+ s1.c = short4(bool4(false, false, false, true));
+ s1.d = 6u;
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup | mem_flags::mem_texture);
+ bool allOk = true;
+ bool _99;
+ if (allOk)
+ {
+ int3 param = int3(6, 8, 8);
+ int3 param_1 = s1.a;
+ _99 = compare_ivec3(param, param_1);
+ }
+ else
+ {
+ _99 = allOk;
+ }
+ allOk = _99;
+ bool _108;
+ if (allOk)
+ {
+ uint2 param_2 = uint2(4u);
+ uint2 param_3 = s1.b;
+ _108 = compare_uvec2(param_2, param_3);
+ }
+ else
+ {
+ _108 = allOk;
+ }
+ allOk = _108;
+ bool _117;
+ if (allOk)
+ {
+ bool4 param_4 = bool4(false, false, false, true);
+ bool4 param_5 = bool4(s1.c);
+ _117 = compare_bvec4(param_4, param_5);
+ }
+ else
+ {
+ _117 = allOk;
+ }
+ allOk = _117;
+ bool _126;
+ if (allOk)
+ {
+ uint param_6 = 6u;
+ uint param_7 = s1.d;
+ _126 = compare_uint(param_6, param_7);
+ }
+ else
+ {
+ _126 = allOk;
+ }
+ allOk = _126;
+ if (allOk)
+ {
+ _132.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/shaders-msl/comp/shared-struct-bool-cast.comp b/shaders-msl/comp/shared-struct-bool-cast.comp
new file mode 100644
index 00000000..d6479b3e
--- /dev/null
+++ b/shaders-msl/comp/shared-struct-bool-cast.comp
@@ -0,0 +1,35 @@
+#version 450
+layout(local_size_x = 1) in;
+
+layout(std140, binding = 0) buffer block { highp uint passed; };
+struct S1 {
+ mediump ivec3 a;
+ highp uvec2 b;
+ bvec4 c;
+ mediump uint d;
+};
+
+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_uvec2 (highp uvec2 a, highp uvec2 b) { return a == b; }
+bool compare_bvec4 (bvec4 a, bvec4 b) { return a == b; }
+
+shared S1 s1;
+
+void main (void) {
+ s1.a = ivec3(6, 8, 8);
+ s1.b = uvec2(4u, 4u);
+ s1.c = bvec4(false, false, false, true);
+ s1.d = 6u;
+
+ barrier();
+ memoryBarrier();
+ bool allOk = true;
+ allOk = allOk && compare_ivec3(ivec3(6, 8, 8), s1.a);
+ allOk = allOk && compare_uvec2(uvec2(4u, 4u), s1.b);
+ allOk = allOk && compare_bvec4(bvec4(false, false, false, true), s1.c);
+ allOk = allOk && compare_uint(6u, s1.d);
+ 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 efd29879..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.
@@ -10907,8 +11077,8 @@ string CompilerMSL::to_struct_member(const SPIRType &type, uint32_t member_type_
array_type = type_to_array_glsl(physical_type);
}
- auto result = join(pack_pfx, type_to_glsl(*declared_type, orig_id), " ", qualifier, to_member_name(type, index),
- member_attribute_qualifier(type, index), array_type, ";");
+ auto result = join(pack_pfx, type_to_glsl(*declared_type, orig_id, true), " ", qualifier,
+ to_member_name(type, index), member_attribute_qualifier(type, index), array_type, ";");
is_using_builtin_array = false;
return result;
@@ -13581,7 +13751,7 @@ string CompilerMSL::to_qualifiers_glsl(uint32_t id)
// The optional id parameter indicates the object whose type we are trying
// to find the description for. It is optional. Most type descriptions do not
// depend on a specific object's use of that type.
-string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
+string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id, bool member)
{
string type_name;
@@ -13671,9 +13841,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
// Need to special-case threadgroup booleans. They are supposed to be logical
// storage, but MSL compilers will sometimes crash if you use threadgroup bool.
// Workaround this by using 16-bit types instead and fixup on load-store to this data.
- // FIXME: We have no sane way of working around this problem if a struct member is boolean
- // and that struct is used as a threadgroup variable, but ... sigh.
- if ((var && var->storage == StorageClassWorkgroup) || type.storage == StorageClassWorkgroup)
+ if ((var && var->storage == StorageClassWorkgroup) || type.storage == StorageClassWorkgroup || member)
type_name = "short";
else
type_name = "bool";
@@ -13735,7 +13903,24 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
// 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)
@@ -13765,6 +13950,11 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
}
}
+string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
+{
+ return type_to_glsl(type, id, false);
+}
+
string CompilerMSL::type_to_array_glsl(const SPIRType &type)
{
// Allow Metal to use the array<T> template to make arrays a value type
@@ -15786,13 +15976,40 @@ 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);
+ 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;
+ var_type = &get_variable_data_type(*var);
+ }
// Type fixups for workgroup variables if they are booleans.
- if (var && var->storage == StorageClassWorkgroup && expr_type.basetype == SPIRType::Boolean)
+ 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))
@@ -15885,17 +16102,42 @@ 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);
+ 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;
+ var_type = &get_variable_data_type(*var);
+ }
// Type fixups for workgroup variables if they are booleans.
- if (var && var->storage == StorageClassWorkgroup && expr_type.basetype == SPIRType::Boolean)
+ if (var && (var->storage == StorageClassWorkgroup || var_type->basetype == SPIRType::Struct) &&
+ expr_type.basetype == SPIRType::Boolean)
{
auto short_type = expr_type;
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 c0317c7a..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,
@@ -736,6 +737,7 @@ protected:
void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
const std::string &qualifier = "", uint32_t base_offset = 0) override;
void emit_struct_padding_target(const SPIRType &type) override;
+ std::string type_to_glsl(const SPIRType &type, uint32_t id, bool member);
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
void emit_block_hints(const SPIRBlock &block) override;
@@ -796,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,