From 44d32e62fb8d1fa9bf22c136aa41114d19b2d874 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Mon, 5 Mar 2018 15:04:32 +0100 Subject: [PATCH] glsl: add cl_size and cl_alignment Signed-off-by: Karol Herbst Reviewed-by: Erik Faye-Lund --- src/compiler/glsl_types.cpp | 48 +++++++++++++++++++++++++++++++++++++ src/compiler/glsl_types.h | 47 ++++++++++++++++++++++++++++++++++++ src/compiler/nir_types.cpp | 12 ++++++++++ src/compiler/nir_types.h | 36 ++++------------------------ 4 files changed, 112 insertions(+), 31 deletions(-) diff --git a/src/compiler/glsl_types.cpp b/src/compiler/glsl_types.cpp index 899dd16878e..90517a5b52f 100644 --- a/src/compiler/glsl_types.cpp +++ b/src/compiler/glsl_types.cpp @@ -2554,3 +2554,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_struct()) { + /* 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_type_get_bit_size(this->base_type) / 8; + } else if (this->is_vector()) { + unsigned vec_elemns = this->vector_elements == 3 ? 4 : this->vector_elements; + return vec_elemns * glsl_base_type_get_bit_size(this->base_type) / 8; + } else if (this->is_array()) { + unsigned size = this->without_array()->cl_size(); + return size * this->length; + } else if (this->is_struct()) { + 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 fb46c67b84e..1a774adb64e 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -31,6 +31,7 @@ #include "shader_enums.h" #include "blob.h" #include "c11/threads.h" +#include "util/macros.h" #ifdef __cplusplus #include "main/config.h" @@ -114,6 +115,42 @@ static inline bool glsl_base_type_is_integer(enum glsl_base_type type) type == GLSL_TYPE_IMAGE; } +static inline unsigned int +glsl_base_type_get_bit_size(const enum glsl_base_type base_type) +{ + switch (base_type) { + case GLSL_TYPE_BOOL: + return 1; + + case GLSL_TYPE_INT: + case GLSL_TYPE_UINT: + case GLSL_TYPE_FLOAT: /* TODO handle mediump */ + case GLSL_TYPE_SUBROUTINE: + return 32; + + case GLSL_TYPE_FLOAT16: + case GLSL_TYPE_UINT16: + case GLSL_TYPE_INT16: + return 16; + + case GLSL_TYPE_UINT8: + case GLSL_TYPE_INT8: + return 8; + + case GLSL_TYPE_DOUBLE: + case GLSL_TYPE_INT64: + case GLSL_TYPE_UINT64: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_SAMPLER: + return 64; + + default: + unreachable("unknown base type"); + } + + return 0; +} + enum glsl_sampler_dim { GLSL_SAMPLER_DIM_1D = 0, GLSL_SAMPLER_DIM_2D, @@ -454,6 +491,16 @@ public: */ const glsl_type *get_explicit_interface_type(bool supports_std430) 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 96b824e5141..d3e5520cd98 100644 --- a/src/compiler/nir_types.cpp +++ b/src/compiler/nir_types.cpp @@ -667,3 +667,15 @@ glsl_contains_atomic(const struct glsl_type *type) { return type->contains_atomic(); } + +int +glsl_get_cl_size(const struct glsl_type *type) +{ + return type->cl_size(); +} + +int +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 1e8fa33a9aa..eeba445a3ba 100644 --- a/src/compiler/nir_types.h +++ b/src/compiler/nir_types.h @@ -98,40 +98,14 @@ unsigned glsl_get_struct_location_offset(const struct glsl_type *type, unsigned glsl_atomic_size(const struct glsl_type *type); +int glsl_get_cl_size(const struct glsl_type *type); + +int glsl_get_cl_alignment(const struct glsl_type *type); + static inline unsigned glsl_get_bit_size(const struct glsl_type *type) { - switch (glsl_get_base_type(type)) { - case GLSL_TYPE_BOOL: - return 1; - - case GLSL_TYPE_INT: - case GLSL_TYPE_UINT: - case GLSL_TYPE_FLOAT: /* TODO handle mediump */ - case GLSL_TYPE_SUBROUTINE: - return 32; - - case GLSL_TYPE_FLOAT16: - case GLSL_TYPE_UINT16: - case GLSL_TYPE_INT16: - return 16; - - case GLSL_TYPE_UINT8: - case GLSL_TYPE_INT8: - return 8; - - case GLSL_TYPE_DOUBLE: - case GLSL_TYPE_INT64: - case GLSL_TYPE_UINT64: - case GLSL_TYPE_IMAGE: - case GLSL_TYPE_SAMPLER: - return 64; - - default: - unreachable("unknown base type"); - } - - return 0; + return glsl_base_type_get_bit_size(glsl_get_base_type(type)); } bool glsl_type_is_16bit(const struct glsl_type *type); -- 2.30.2