v2: fix cl_size for arrays_of_arrays Signed-off-by: Karol Herbst <kher...@redhat.com> --- src/compiler/glsl_types.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++ src/compiler/glsl_types.h | 10 ++++++++++ src/compiler/nir_types.cpp | 12 ++++++++++++ src/compiler/nir_types.h | 4 ++++ 4 files changed, 74 insertions(+)
diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index 12a8a546938..2bf44c6fc30 100644 --- a/src/compiler/glsl_types.cpp +++ b/src/compiler/glsl_types.cpp @@ -2360,3 +2360,51 @@ decode_type_from_blob(struct blob_reader *blob) return NULL; } } + +unsigned +glsl_type::cl_alignment() const +{ + /* vectors unlike arrays are aligned to their size */ + if (this->is_scalar() || this->is_vector()) + return this->cl_size(); + else if (this->is_array()) + return this->without_array()->cl_alignment(); + else if (this->is_record()) { + /* Packed Structs are 0x1 aligned despite their size. */ + if (this->packed) + return 1; + + unsigned res = 1; + for (unsigned i = 0; i < this->length; ++i) { + struct glsl_struct_field &field = this->fields.structure[i]; + res = MAX2(res, field.type->cl_alignment()); + } + return res; + } + return 1; +} + +unsigned +glsl_type::cl_size() const +{ + if (this->is_scalar()) { + return glsl_base_get_byte_size(this->base_type); + } else if (this->is_vector()) { + unsigned vec_elemns = this->vector_elements == 3 ? 4 : this->vector_elements; + return vec_elemns * glsl_base_get_byte_size(this->base_type); + } else if (this->is_array()) { + unsigned size = this->without_array()->cl_size(); + return size * this->arrays_of_arrays_size(); + } else if (this->is_record()) { + unsigned size = 0; + for (unsigned i = 0; i < this->length; ++i) { + struct glsl_struct_field &field = this->fields.structure[i]; + /* if a struct is packed, members don't get aligned */ + if (!this->packed) + size = align(size, field.type->cl_alignment()); + size += field.type->cl_size(); + } + return size; + } + return 1; +} diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h index 2e63261090e..6fb5d3c7881 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -408,6 +408,16 @@ public: */ unsigned std430_size(bool row_major) const; + /** + * Alignment in bytes of the start of this type in OpenCL memory. + */ + unsigned cl_alignment() const; + + /** + * Size in bytes of this type in OpenCL memory + */ + unsigned cl_size() const; + /** * \brief Can this type be implicitly converted to another? * diff --git a/src/compiler/nir_types.cpp b/src/compiler/nir_types.cpp index 76a9cf2fde7..ce4ace82c1c 100644 --- a/src/compiler/nir_types.cpp +++ b/src/compiler/nir_types.cpp @@ -463,3 +463,15 @@ glsl_channel_type(const glsl_type *t) unreachable("Unhandled base type glsl_channel_type()"); } } + +unsigned +glsl_get_cl_size(const struct glsl_type *type) +{ + return type->cl_size(); +} + +unsigned +glsl_get_cl_alignment(const struct glsl_type *type) +{ + return type->cl_alignment(); +} diff --git a/src/compiler/nir_types.h b/src/compiler/nir_types.h index 033b3ae739b..47239a6b7ce 100644 --- a/src/compiler/nir_types.h +++ b/src/compiler/nir_types.h @@ -83,6 +83,10 @@ enum glsl_base_type glsl_get_sampler_result_type(const struct glsl_type *type); unsigned glsl_get_record_location_offset(const struct glsl_type *type, unsigned length); +unsigned glsl_get_cl_size(const struct glsl_type *type); + +unsigned glsl_get_cl_alignment(const struct glsl_type *type); + static inline unsigned glsl_get_bit_size(const struct glsl_type *type) { -- 2.14.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev