diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-08-09 12:54:53 +0300 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2022-08-09 12:54:53 +0300 |
commit | 1bc05ef73575654c79e61390269c83a03c09b86c (patch) | |
tree | e26754e75c46fbad282dd03f9ba54f93a6fb2a1d | |
parent | 0cccd0a65a67f33922f8d0742b5930fd15353fa7 (diff) | |
parent | a9cadd4982874dda1075e57639a18702fc1f9f29 (diff) |
Merge branch 'master' of https://github.com/gpx1000/SPIRV-Cross
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 ¶m_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, |