From ARB_gl_spirv spec: "7.6.2.spv SPIR-V Uniform Offsets and Strides
The SPIR-V decorations *GLSLShared* or *GLSLPacked* must not be used. A variable in the *Uniform* Storage Class decorated as a *Block* must be explicitly laid out using the *Offset*, *ArrayStride*, and *MatrixStride* decorations. If the variable is decorated as a *BufferBlock*, its offsets and strides must not contradict std430 alignment and minimum offset requirements. Otherwise, its offsets and strides must not contradict std140 alignment and minimum offset requirements. From that paragraph, the first conclusion is that we can rely on the content of the SPIR-V in order to compute the buffer sizes, as they are mandatory. That would make the buffer size computation easier. The second conclusion, from the last sentence, is that *we need* to do that. As if just needs to not contradict alignments and minimum offsets, providing a matrix stride of 16 when 8 is enough would be valid. This explicit matrix_stride is assumed to only be used on ARB_gl_spirv. On GLSL there is no way to set it, and it is internally handled and computed. --- src/compiler/glsl_types.cpp | 3 +++ src/compiler/glsl_types.h | 10 ++++++++-- src/compiler/nir_types.cpp | 6 ++++++ src/compiler/nir_types.h | 2 ++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index 70bce6ace8e..104a5104aaa 100644 --- a/src/compiler/glsl_types.cpp +++ b/src/compiler/glsl_types.cpp @@ -961,6 +961,9 @@ glsl_type::record_compare(const glsl_type *b, bool match_locations) const if (this->fields.structure[i].xfb_stride != b->fields.structure[i].xfb_stride) return false; + if (this->fields.structure[i].explicit_matrix_stride + != b->fields.structure[i].explicit_matrix_stride) + return false; } return true; diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h index d32b580acc1..9e8332e6cbf 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -1007,6 +1007,12 @@ struct glsl_struct_field { */ unsigned matrix_layout:2; + /** + * Explicit matrix stride. For ARB_gl_spirv, it is mandatory to set it + * explicitly. -1 otherwise. + */ + int explicit_matrix_stride; + /** * For interface blocks, 1 if this variable is a per-patch input or output * (as in ir_variable::patch). 0 otherwise. @@ -1045,7 +1051,7 @@ struct glsl_struct_field { glsl_struct_field(const struct glsl_type *_type, const char *_name) : type(_type), name(_name), location(-1), offset(0), xfb_buffer(0), xfb_stride(0), interpolation(0), centroid(0), - sample(0), matrix_layout(GLSL_MATRIX_LAYOUT_INHERITED), patch(0), + sample(0), matrix_layout(GLSL_MATRIX_LAYOUT_INHERITED), explicit_matrix_stride(-1), patch(0), precision(GLSL_PRECISION_NONE), memory_read_only(0), memory_write_only(0), memory_coherent(0), memory_volatile(0), memory_restrict(0), image_format(0), explicit_xfb_buffer(0), @@ -1057,7 +1063,7 @@ struct glsl_struct_field { glsl_struct_field() : type(NULL), name(NULL), location(0), offset(0), xfb_buffer(0), xfb_stride(0), interpolation(0), centroid(0), - sample(0), matrix_layout(0), patch(0), + sample(0), matrix_layout(0), explicit_matrix_stride(-1), patch(0), precision(0), memory_read_only(0), memory_write_only(0), memory_coherent(0), memory_volatile(0), memory_restrict(0), image_format(0), explicit_xfb_buffer(0), diff --git a/src/compiler/nir_types.cpp b/src/compiler/nir_types.cpp index 2a1ae42a9bb..b2a5da1dc6c 100644 --- a/src/compiler/nir_types.cpp +++ b/src/compiler/nir_types.cpp @@ -86,6 +86,12 @@ glsl_get_struct_field_matrix_layout(const struct glsl_type *type, return type->fields.structure[index].matrix_layout; } +const int +glsl_get_struct_field_explicit_matrix_stride(const struct glsl_type *type, + unsigned index) +{ + return type->fields.structure[index].explicit_matrix_stride; +} const glsl_type * glsl_get_function_return_type(const glsl_type *type) diff --git a/src/compiler/nir_types.h b/src/compiler/nir_types.h index 69de44c3423..d3c00ca5e1a 100644 --- a/src/compiler/nir_types.h +++ b/src/compiler/nir_types.h @@ -51,6 +51,8 @@ const int glsl_get_struct_field_offset(const struct glsl_type *type, const unsigned glsl_get_struct_field_matrix_layout(const struct glsl_type *type, unsigned index); +const int glsl_get_struct_field_explicit_matrix_stride(const struct glsl_type *type, + unsigned index); const struct glsl_type *glsl_get_array_element(const struct glsl_type *type); const struct glsl_type *glsl_without_array(const struct glsl_type *type); const struct glsl_type *glsl_without_array_or_matrix(const struct glsl_type *type); -- 2.14.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev