X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl_types.h;h=aa1a4cec324b842213b57532827075aa5cf49650;hb=6f2e95f24d80c797389b5c558e0590ed10e0c0e7;hp=56e5de7cd9123912b4ff0e77de3f56e9d4ad65ed;hpb=e16a27fcf867c8be5ba94470d78f76348f1e8c07;p=mesa.git diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h index 56e5de7cd91..aa1a4cec324 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -29,8 +29,10 @@ #include #include "shader_enums.h" -#include "blob.h" #include "c11/threads.h" +#include "util/blob.h" +#include "util/format/u_format.h" +#include "util/macros.h" #ifdef __cplusplus #include "main/config.h" @@ -46,18 +48,20 @@ struct _mesa_glsl_parse_state; struct glsl_symbol_table; extern void -_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state); +glsl_type_singleton_init_or_ref(); extern void -_mesa_glsl_release_types(void); +glsl_type_singleton_decref(); + +extern void +_mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state); void encode_type_to_blob(struct blob *blob, const struct glsl_type *type); const struct glsl_type *decode_type_from_blob(struct blob_reader *blob); -#ifdef __cplusplus -} -#endif +typedef void (*glsl_type_size_align_func)(const struct glsl_type *type, + unsigned *size, unsigned *align); enum glsl_base_type { /* Note: GLSL_TYPE_UINT, GLSL_TYPE_INT, and GLSL_TYPE_FLOAT must be 0, 1, @@ -87,25 +91,64 @@ enum glsl_base_type { GLSL_TYPE_ERROR }; +/* Return the bit size of a type. Note that this differs from + * glsl_get_bit_size in that it returns 32 bits for bools, whereas at + * the NIR level we would want to return 1 bit for bools. + */ +static unsigned glsl_base_type_bit_size(enum glsl_base_type type) +{ + switch (type) { + case GLSL_TYPE_BOOL: + 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: + /* For GLSL_TYPE_STRUCT etc, it should be ok to return 0. This usually + * happens when calling this method through is_64bit and is_16bit + * methods + */ + return 0; + } + + return 0; +} + static inline bool glsl_base_type_is_16bit(enum glsl_base_type type) { - return type == GLSL_TYPE_FLOAT16 || - type == GLSL_TYPE_UINT16 || - type == GLSL_TYPE_INT16; + return glsl_base_type_bit_size(type) == 16; } static inline bool glsl_base_type_is_64bit(enum glsl_base_type type) { - return type == GLSL_TYPE_DOUBLE || - type == GLSL_TYPE_UINT64 || - type == GLSL_TYPE_INT64 || - type == GLSL_TYPE_IMAGE || - type == GLSL_TYPE_SAMPLER; + return glsl_base_type_bit_size(type) == 64; } static inline bool glsl_base_type_is_integer(enum glsl_base_type type) { - return type == GLSL_TYPE_UINT || + return type == GLSL_TYPE_UINT8 || + type == GLSL_TYPE_INT8 || + type == GLSL_TYPE_UINT16 || + type == GLSL_TYPE_INT16 || + type == GLSL_TYPE_UINT || type == GLSL_TYPE_INT || type == GLSL_TYPE_UINT64 || type == GLSL_TYPE_INT64 || @@ -114,6 +157,63 @@ 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; +} + +static inline enum glsl_base_type +glsl_unsigned_base_type_of(enum glsl_base_type type) +{ + switch (type) { + case GLSL_TYPE_INT: + return GLSL_TYPE_UINT; + case GLSL_TYPE_INT8: + return GLSL_TYPE_UINT8; + case GLSL_TYPE_INT16: + return GLSL_TYPE_UINT16; + case GLSL_TYPE_INT64: + return GLSL_TYPE_UINT64; + default: + assert(type == GLSL_TYPE_UINT || + type == GLSL_TYPE_UINT8 || + type == GLSL_TYPE_UINT16 || + type == GLSL_TYPE_UINT64); + return type; + } +} + enum glsl_sampler_dim { GLSL_SAMPLER_DIM_1D = 0, GLSL_SAMPLER_DIM_2D, @@ -127,6 +227,9 @@ enum glsl_sampler_dim { GLSL_SAMPLER_DIM_SUBPASS_MS, /* for multisampled vulkan input attachments */ }; +int +glsl_get_sampler_dim_coordinate_components(enum glsl_sampler_dim dim); + enum glsl_matrix_layout { /** * The layout of the matrix is inherited from the object containing the @@ -156,6 +259,8 @@ enum { }; #ifdef __cplusplus +} /* extern "C" */ + #include "GL/gl.h" #include "util/ralloc.h" #include "main/menums.h" /* for gl_texture_index, C++'s enum rules are broken */ @@ -176,6 +281,13 @@ struct glsl_type { unsigned interface_packing:2; unsigned interface_row_major:1; + /** + * For \c GLSL_TYPE_STRUCT this specifies if the struct is packed or not. + * + * Only used for Compute kernels + */ + unsigned packed:1; + private: glsl_type() : mem_ctx(NULL) { @@ -283,6 +395,21 @@ public: */ const glsl_type *get_bare_type() const; + /** + * Gets the float16 version of this type. + */ + const glsl_type *get_float16_type() const; + + /** + * Gets the int16 version of this type. + */ + const glsl_type *get_int16_type() const; + + /** + * Gets the uint16 version of this type. + */ + const glsl_type *get_uint16_type() const; + /** * Get the instance of a built-in scalar, vector, or matrix type */ @@ -314,7 +441,8 @@ public: */ static const glsl_type *get_struct_instance(const glsl_struct_field *fields, unsigned num_fields, - const char *name); + const char *name, + bool packed = false); /** * Get the instance of an interface block type @@ -382,6 +510,23 @@ public: */ unsigned varying_count() const; + /** + * Calculate the number of vec4 slots required to hold this type. + * + * This is the underlying recursive type_size function for + * count_attribute_slots() (vertex inputs and varyings) but also for + * gallium's !PIPE_CAP_PACKED_UNIFORMS case. + */ + unsigned count_vec4_slots(bool is_gl_vertex_input, bool bindless) const; + + /** + * Calculate the number of vec4 slots required to hold this type. + * + * This is the underlying recursive type_size function for + * gallium's PIPE_CAP_PACKED_UNIFORMS case. + */ + unsigned count_dword_slots(bool bindless) const; + /** * Calculate the number of attribute slots required to hold this type * @@ -397,7 +542,9 @@ public: * Vulkan doesn’t make this distinction so the argument should always be * false. */ - unsigned count_attribute_slots(bool is_gl_vertex_input) const; + unsigned count_attribute_slots(bool is_gl_vertex_input) const { + return count_vec4_slots(is_gl_vertex_input, true); + } /** * Alignment in bytes of the start of this type in a std140 uniform @@ -412,6 +559,11 @@ public: */ unsigned std140_size(bool row_major) const; + /** + * Gets an explicitly laid out type with the std140 layout. + */ + const glsl_type *get_explicit_std140_type(bool row_major) const; + /** * Alignment in bytes of the start of this type in a std430 shader * storage block. @@ -431,6 +583,59 @@ public: */ unsigned std430_size(bool row_major) const; + /** + * Gets an explicitly laid out type with the std430 layout. + */ + const glsl_type *get_explicit_std430_type(bool row_major) const; + + /** + * Gets an explicitly laid out interface type. + */ + const glsl_type *get_explicit_interface_type(bool supports_std430) const; + + /** Returns an explicitly laid out type given a type and size/align func + * + * The size/align func is only called for scalar and vector types and the + * returned type is otherwise laid out in the natural way as follows: + * + * - Arrays and matrices have a stride of ALIGN(elem_size, elem_align). + * + * - Structure types have their elements in-order and as tightly packed as + * possible following the alignment required by the size/align func. + * + * - All composite types (structures, matrices, and arrays) have an + * alignment equal to the highest alighment of any member of the composite. + * + * The types returned by this function are likely not suitable for most UBO + * or SSBO layout because they do not add the extra array and substructure + * alignment that is required by std140 and std430. + */ + const glsl_type *get_explicit_type_for_size_align(glsl_type_size_align_func type_info, + unsigned *size, unsigned *align) 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; + + /** + * Size in bytes of this type based on its explicit data. + * + * When using SPIR-V shaders (ARB_gl_spirv), memory layouts are expressed + * through explicit offset, stride and matrix layout, so the size + * can/should be computed used those values. + * + * Note that the value returned by this method is only correct if such + * values are set, so only with SPIR-V shaders. Should not be used with + * GLSL shaders. + */ + unsigned explicit_size(bool align_to_stride=false) const; + /** * \brief Can this type be implicitly converted to another? * @@ -509,9 +714,17 @@ public: } /** - * Query whether or not a type is an integral type + * Query whether or not a type is an integer. */ bool is_integer() const + { + return glsl_base_type_is_integer(base_type); + } + + /** + * Query whether or not a type is an 32-bit integer. + */ + bool is_integer_32() const { return (base_type == GLSL_TYPE_UINT) || (base_type == GLSL_TYPE_INT); } @@ -529,7 +742,7 @@ public: */ bool is_integer_32_64() const { - return is_integer() || is_integer_64(); + return is_integer_32() || is_integer_64(); } /** @@ -558,6 +771,22 @@ public: return base_type == GLSL_TYPE_FLOAT; } + /** + * Query whether or not a type is a half-float or float type + */ + bool is_float_16_32() const + { + return base_type == GLSL_TYPE_FLOAT16 || is_float(); + } + + /** + * Query whether or not a type is a half-float, float or double + */ + bool is_float_16_32_64() const + { + return base_type == GLSL_TYPE_FLOAT16 || is_float() || is_double(); + } + /** * Query whether or not a type is a double type */ @@ -743,6 +972,15 @@ public: return size; } + /** + * Return bit size for this type. + */ + unsigned bit_size() const + { + return glsl_base_type_bit_size(this->base_type); + } + + /** * Query whether or not a type is an atomic_uint. */ @@ -861,14 +1099,28 @@ public: */ int coordinate_components() const; + /** + * Compares whether this type matches another type without taking into + * account the precision in structures. + * + * This is applied recursively so that structures containing structure + * members can also ignore the precision. + */ + bool compare_no_precision(const glsl_type *b) const; + /** * Compare a record type against another record type. * - * This is useful for matching record types declared across shader stages. + * This is useful for matching record types declared on the same shader + * stage as well as across different shader stages. + * The option to not match name is needed for matching record types + * declared across different shader stages. * The option to not match locations is to deal with places where the * same struct is defined in a block which has a location set on it. */ - bool record_compare(const glsl_type *b, bool match_locations = true) const; + bool record_compare(const glsl_type *b, bool match_name, + bool match_locations = true, + bool match_precision = true) const; /** * Get the type interface packing. @@ -931,7 +1183,7 @@ private: /** Constructor for record types */ glsl_type(const glsl_struct_field *fields, unsigned num_fields, - const char *name); + const char *name, bool packed = false); /** Constructor for interface types */ glsl_type(const glsl_struct_field *fields, unsigned num_fields, @@ -988,8 +1240,9 @@ private: * data. */ /*@{*/ + friend void glsl_type_singleton_init_or_ref(void); + friend void glsl_type_singleton_decref(void); friend void _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *); - friend void _mesa_glsl_release_types(void); /*@}*/ }; @@ -1029,88 +1282,96 @@ struct glsl_struct_field { * -1 otherwise. */ int xfb_stride; - - /** - * For interface blocks, the interpolation mode (as in - * ir_variable::interpolation). 0 otherwise. - */ - unsigned interpolation:2; - - /** - * For interface blocks, 1 if this variable uses centroid interpolation (as - * in ir_variable::centroid). 0 otherwise. - */ - unsigned centroid:1; - - /** - * For interface blocks, 1 if this variable uses sample interpolation (as - * in ir_variable::sample). 0 otherwise. - */ - unsigned sample:1; - - /** - * Layout of the matrix. Uses glsl_matrix_layout values. - */ - unsigned matrix_layout:2; - - /** - * For interface blocks, 1 if this variable is a per-patch input or output - * (as in ir_variable::patch). 0 otherwise. - */ - unsigned patch:1; - - /** - * Precision qualifier - */ - unsigned precision:2; - - /** - * Memory qualifiers, applicable to buffer variables defined in shader - * storage buffer objects (SSBOs) - */ - unsigned memory_read_only:1; - unsigned memory_write_only:1; - unsigned memory_coherent:1; - unsigned memory_volatile:1; - unsigned memory_restrict:1; - /** * Layout format, applicable to image variables only. */ - unsigned image_format:16; - - /** - * Any of the xfb_* qualifiers trigger the shader to be in transform - * feedback mode so we need to keep track of whether the buffer was - * explicitly set or if its just been assigned the default global value. - */ - unsigned explicit_xfb_buffer:1; + enum pipe_format image_format; - unsigned implicit_sized_array:1; + union { + struct { + /** + * For interface blocks, the interpolation mode (as in + * ir_variable::interpolation). 0 otherwise. + */ + unsigned interpolation:3; + + /** + * For interface blocks, 1 if this variable uses centroid interpolation (as + * in ir_variable::centroid). 0 otherwise. + */ + unsigned centroid:1; + + /** + * For interface blocks, 1 if this variable uses sample interpolation (as + * in ir_variable::sample). 0 otherwise. + */ + unsigned sample:1; + + /** + * Layout of the matrix. Uses glsl_matrix_layout values. + */ + unsigned matrix_layout:2; + + /** + * For interface blocks, 1 if this variable is a per-patch input or output + * (as in ir_variable::patch). 0 otherwise. + */ + unsigned patch:1; + + /** + * Precision qualifier + */ + unsigned precision:2; + + /** + * Memory qualifiers, applicable to buffer variables defined in shader + * storage buffer objects (SSBOs) + */ + unsigned memory_read_only:1; + unsigned memory_write_only:1; + unsigned memory_coherent:1; + unsigned memory_volatile:1; + unsigned memory_restrict:1; + + /** + * Any of the xfb_* qualifiers trigger the shader to be in transform + * feedback mode so we need to keep track of whether the buffer was + * explicitly set or if its just been assigned the default global value. + */ + unsigned explicit_xfb_buffer:1; + + unsigned implicit_sized_array:1; + }; + unsigned flags; + }; #ifdef __cplusplus +#define DEFAULT_CONSTRUCTORS(_type, _name) \ + type(_type), name(_name), location(-1), offset(-1), xfb_buffer(0), \ + xfb_stride(0), image_format(PIPE_FORMAT_NONE), flags(0) \ + + glsl_struct_field(const struct glsl_type *_type, + int _precision, + const char *_name) + : DEFAULT_CONSTRUCTORS(_type, _name) + { + matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED; + precision = _precision; + } + glsl_struct_field(const struct glsl_type *_type, const char *_name) - : type(_type), name(_name), location(-1), offset(-1), xfb_buffer(0), - xfb_stride(0), interpolation(0), centroid(0), - sample(0), matrix_layout(GLSL_MATRIX_LAYOUT_INHERITED), 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), - implicit_sized_array(0) + : DEFAULT_CONSTRUCTORS(_type, _name) { - /* empty */ + matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED; + precision = GLSL_PRECISION_NONE; } glsl_struct_field() - : type(NULL), name(NULL), location(-1), offset(-1), xfb_buffer(0), - xfb_stride(0), interpolation(0), centroid(0), - sample(0), matrix_layout(0), 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), - implicit_sized_array(0) + : DEFAULT_CONSTRUCTORS(NULL, NULL) { - /* empty */ + matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED; + precision = GLSL_PRECISION_NONE; } +#undef DEFAULT_CONSTRUCTORS #endif };