X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl_types.h;h=40f148a217147f16b0775c44c4ce3bd399ad3ce6;hb=3a5950f50174390e817c619f972b8b8ea21c6705;hp=f607dd8bc378d8b176b2102f0d7de4d8db47d0c0;hpb=5d83820a1d4f6b2390520d2335848d351db13fd7;p=mesa.git diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h index f607dd8bc37..40f148a2171 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -22,13 +22,23 @@ * DEALINGS IN THE SOFTWARE. */ -#pragma once #ifndef GLSL_TYPES_H #define GLSL_TYPES_H #include #include +#include "shader_enums.h" +#include "blob.h" +#include "c11/threads.h" +#include "util/macros.h" + +#ifdef __cplusplus +#include "main/config.h" +#endif + +struct glsl_type; + #ifdef __cplusplus extern "C" { #endif @@ -37,10 +47,17 @@ 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 +glsl_type_singleton_decref(); extern void -_mesa_glsl_release_types(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 } @@ -53,7 +70,14 @@ enum glsl_base_type { GLSL_TYPE_UINT = 0, GLSL_TYPE_INT, GLSL_TYPE_FLOAT, + GLSL_TYPE_FLOAT16, GLSL_TYPE_DOUBLE, + GLSL_TYPE_UINT8, + GLSL_TYPE_INT8, + GLSL_TYPE_UINT16, + GLSL_TYPE_INT16, + GLSL_TYPE_UINT64, + GLSL_TYPE_INT64, GLSL_TYPE_BOOL, GLSL_TYPE_SAMPLER, GLSL_TYPE_IMAGE, @@ -67,9 +91,106 @@ 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 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; + 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_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 || + type == GLSL_TYPE_BOOL || + type == GLSL_TYPE_SAMPLER || + 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 { @@ -82,13 +203,7 @@ enum glsl_sampler_dim { GLSL_SAMPLER_DIM_EXTERNAL, GLSL_SAMPLER_DIM_MS, GLSL_SAMPLER_DIM_SUBPASS, /* for vulkan input attachments */ -}; - -enum glsl_interface_packing { - GLSL_INTERFACE_PACKING_STD140, - GLSL_INTERFACE_PACKING_SHARED, - GLSL_INTERFACE_PACKING_PACKED, - GLSL_INTERFACE_PACKING_STD430 + GLSL_SAMPLER_DIM_SUBPASS_MS, /* for multisampled vulkan input attachments */ }; enum glsl_matrix_layout { @@ -122,51 +237,38 @@ enum { #ifdef __cplusplus #include "GL/gl.h" #include "util/ralloc.h" -#include "main/mtypes.h" /* for gl_texture_index, C++'s enum rules are broken */ +#include "main/menums.h" /* for gl_texture_index, C++'s enum rules are broken */ struct glsl_type { GLenum gl_type; - glsl_base_type base_type; + glsl_base_type base_type:8; + + glsl_base_type sampled_type:8; /**< Type of data returned using this + * sampler or image. Only \c + * GLSL_TYPE_FLOAT, \c GLSL_TYPE_INT, + * and \c GLSL_TYPE_UINT are valid. + */ unsigned sampler_dimensionality:4; /**< \see glsl_sampler_dim */ unsigned sampler_shadow:1; unsigned sampler_array:1; - unsigned sampled_type:2; /**< Type of data returned using this - * sampler or image. Only \c - * GLSL_TYPE_FLOAT, \c GLSL_TYPE_INT, - * and \c GLSL_TYPE_UINT are valid. - */ unsigned interface_packing:2; unsigned interface_row_major:1; - /* Callers of this ralloc-based new need not call delete. It's - * easier to just ralloc_free 'mem_ctx' (or any of its ancestors). */ - static void* operator new(size_t size) - { - mtx_lock(&glsl_type::mutex); - - /* mem_ctx should have been created by the static members */ - assert(glsl_type::mem_ctx != NULL); - - void *type; - - type = ralloc_size(glsl_type::mem_ctx, size); - assert(type != NULL); - - mtx_unlock(&glsl_type::mutex); - - return type; - } + /** + * For \c GLSL_TYPE_STRUCT this specifies if the struct is packed or not. + * + * Only used for Compute kernels + */ + unsigned packed:1; - /* If the user *does* call delete, that's OK, we will just - * ralloc_free in that case. */ - static void operator delete(void *type) +private: + glsl_type() : mem_ctx(NULL) { - mtx_lock(&glsl_type::mutex); - ralloc_free(type); - mtx_unlock(&glsl_type::mutex); + // Dummy constructor, just for the sake of ASSERT_BITFIELD_SIZE. } +public: /** * \name Vector and matrix element counts * @@ -193,6 +295,13 @@ struct glsl_type { */ const char *name; + /** + * Explicit array, matrix, or vector stride. This is used to communicate + * explicit array layouts from SPIR-V. Should be 0 if the type has no + * explicit stride. + */ + unsigned explicit_stride; + /** * Subtype of composite data types. */ @@ -219,11 +328,19 @@ struct glsl_type { * Convenience accessors for vector types (shorter than get_instance()). * @{ */ + static const glsl_type *vec(unsigned components, const glsl_type *const ts[]); static const glsl_type *vec(unsigned components); + static const glsl_type *f16vec(unsigned components); static const glsl_type *dvec(unsigned components); static const glsl_type *ivec(unsigned components); static const glsl_type *uvec(unsigned components); static const glsl_type *bvec(unsigned components); + static const glsl_type *i64vec(unsigned components); + static const glsl_type *u64vec(unsigned components); + static const glsl_type *i16vec(unsigned components); + static const glsl_type *u16vec(unsigned components); + static const glsl_type *i8vec(unsigned components); + static const glsl_type *u8vec(unsigned components); /**@}*/ /** @@ -247,11 +364,18 @@ struct glsl_type { */ const glsl_type *get_scalar_type() const; + /** + * Gets the "bare" type without any decorations or layout information. + */ + const glsl_type *get_bare_type() const; + /** * Get the instance of a built-in scalar, vector, or matrix type */ static const glsl_type *get_instance(unsigned base_type, unsigned rows, - unsigned columns); + unsigned columns, + unsigned explicit_stride = 0, + bool row_major = false); /** * Get the instance of a sampler type @@ -268,14 +392,16 @@ struct glsl_type { * Get the instance of an array type */ static const glsl_type *get_array_instance(const glsl_type *base, - unsigned elements); + unsigned elements, + unsigned explicit_stride = 0); /** * Get the instance of a record type */ - static const glsl_type *get_record_instance(const glsl_struct_field *fields, + 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 @@ -326,7 +452,7 @@ struct glsl_type { * For the initial call, length is the index of the member to find the * offset for. */ - unsigned record_location_offset(unsigned length) const; + unsigned struct_location_offset(unsigned length) const; /** * Calculate the number of unique values from glGetUniformLocation for the @@ -354,8 +480,11 @@ struct glsl_type { * * For vertex shader attributes - doubles only take one slot. * For inter-shader varyings - dvec3/dvec4 take two slots. + * + * Vulkan doesn’t make this distinction so the argument should always be + * false. */ - unsigned count_attribute_slots(bool is_vertex_input) const; + unsigned count_attribute_slots(bool is_gl_vertex_input) const; /** * Alignment in bytes of the start of this type in a std140 uniform @@ -370,6 +499,11 @@ struct glsl_type { */ 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. @@ -389,6 +523,39 @@ struct glsl_type { */ 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; + + /** + * 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? * @@ -433,7 +600,7 @@ struct glsl_type { { return (vector_elements == 1) && (base_type >= GLSL_TYPE_UINT) - && (base_type <= GLSL_TYPE_BOOL); + && (base_type <= GLSL_TYPE_IMAGE); } /** @@ -453,7 +620,9 @@ struct glsl_type { bool is_matrix() const { /* GLSL only has float matrices. */ - return (matrix_columns > 1) && (base_type == GLSL_TYPE_FLOAT || base_type == GLSL_TYPE_DOUBLE); + return (matrix_columns > 1) && (base_type == GLSL_TYPE_FLOAT || + base_type == GLSL_TYPE_DOUBLE || + base_type == GLSL_TYPE_FLOAT16); } /** @@ -461,20 +630,44 @@ struct glsl_type { */ bool is_numeric() const { - return (base_type >= GLSL_TYPE_UINT) && (base_type <= GLSL_TYPE_DOUBLE); + return (base_type >= GLSL_TYPE_UINT) && (base_type <= GLSL_TYPE_INT64); } /** - * 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); } /** - * Query whether or not type is an integral type, or for struct, interface - * and array types, contains an integral type. + * Query whether or not a type is a 64-bit integer. + */ + bool is_integer_64() const + { + return base_type == GLSL_TYPE_UINT64 || base_type == GLSL_TYPE_INT64; + } + + /** + * Query whether or not a type is a 32-bit or 64-bit integer + */ + bool is_integer_32_64() const + { + return is_integer_32() || is_integer_64(); + } + + /** + * Query whether or not type is an integral type, or for struct and array + * types, contains an integral type. */ bool contains_integer() const; @@ -484,6 +677,12 @@ struct glsl_type { */ bool contains_double() const; + /** + * Query whether or not type is a 64-bit type, or for struct, interface and + * array types, contains a double type. + */ + bool contains_64bit() const; + /** * Query whether or not a type is a float type */ @@ -516,6 +715,24 @@ struct glsl_type { return glsl_base_type_is_64bit(base_type); } + /** + * Query whether or not a type is 16-bit + */ + bool is_16bit() const + { + return glsl_base_type_is_16bit(base_type); + } + + /** + * Query whether or not a type is 32-bit + */ + bool is_32bit() const + { + return base_type == GLSL_TYPE_UINT || + base_type == GLSL_TYPE_INT || + base_type == GLSL_TYPE_FLOAT; + } + /** * Query whether or not a type is a non-array boolean type */ @@ -538,6 +755,12 @@ struct glsl_type { */ bool contains_sampler() const; + /** + * Query whether or not type is an array or for struct, interface and + * array types, contains an array. + */ + bool contains_array() const; + /** * Get the Mesa texture target index for a sampler type. */ @@ -573,7 +796,7 @@ struct glsl_type { /** * Query whether or not a type is a record */ - bool is_record() const + bool is_struct() const { return base_type == GLSL_TYPE_STRUCT; } @@ -653,12 +876,29 @@ struct glsl_type { 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. + */ + bool is_atomic_uint() const + { + return base_type == GLSL_TYPE_ATOMIC_UINT; + } + /** * Return the amount of atomic counter storage required for a type. */ unsigned atomic_size() const { - if (base_type == GLSL_TYPE_ATOMIC_UINT) + if (is_atomic_uint()) return ATOMIC_COUNTER_SIZE; else if (is_array()) return length * fields.array->atomic_size(); @@ -688,9 +928,13 @@ struct glsl_type { */ const glsl_type *row_type() const { - return is_matrix() - ? get_instance(base_type, matrix_columns, 1) - : error_type; + if (!is_matrix()) + return error_type; + + if (explicit_stride && !interface_row_major) + return get_instance(base_type, matrix_columns, 1, explicit_stride); + else + return get_instance(base_type, matrix_columns, 1); } /** @@ -702,9 +946,13 @@ struct glsl_type { */ const glsl_type *column_type() const { - return is_matrix() - ? get_instance(base_type, vector_elements, 1) - : error_type; + if (!is_matrix()) + return error_type; + + if (explicit_stride && interface_row_major) + return get_instance(base_type, vector_elements, 1, explicit_stride); + else + return get_instance(base_type, vector_elements, 1); } /** @@ -751,18 +999,32 @@ struct glsl_type { * * Note that this is often different than actual coordinate type used in * a texturing built-in function, since those pack additional values (such - * as the shadow comparitor or projector) into the coordinate type. + * as the shadow comparator or projector) into the coordinate type. */ 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. @@ -772,6 +1034,27 @@ struct glsl_type { return (enum glsl_interface_packing)interface_packing; } + /** + * Get the type interface packing used internally. For shared and packing + * layouts this is implementation defined. + */ + enum glsl_interface_packing get_internal_ifc_packing(bool std430_supported) const + { + enum glsl_interface_packing packing = this->get_interface_packing(); + if (packing == GLSL_INTERFACE_PACKING_STD140 || + (!std430_supported && + (packing == GLSL_INTERFACE_PACKING_SHARED || + packing == GLSL_INTERFACE_PACKING_PACKED))) { + return GLSL_INTERFACE_PACKING_STD140; + } else { + assert(packing == GLSL_INTERFACE_PACKING_STD430 || + (std430_supported && + (packing == GLSL_INTERFACE_PACKING_SHARED || + packing == GLSL_INTERFACE_PACKING_PACKED))); + return GLSL_INTERFACE_PACKING_STD430; + } + } + /** * Check if the type interface is row major */ @@ -780,32 +1063,31 @@ struct glsl_type { return (bool) interface_row_major; } + ~glsl_type(); + private: - static mtx_t mutex; + static mtx_t hash_mutex; /** - * ralloc context for all glsl_type allocations - * - * Set on the first call to \c glsl_type::new. + * ralloc context for the type itself. */ - static void *mem_ctx; - - void init_ralloc_type_ctx(void); + void *mem_ctx; /** Constructor for vector and matrix types */ glsl_type(GLenum gl_type, - glsl_base_type base_type, unsigned vector_elements, - unsigned matrix_columns, const char *name); + glsl_base_type base_type, unsigned vector_elements, + unsigned matrix_columns, const char *name, + unsigned explicit_stride = 0, bool row_major = false); /** Constructor for sampler or image types */ glsl_type(GLenum gl_type, glsl_base_type base_type, enum glsl_sampler_dim dim, bool shadow, bool array, - unsigned type, const char *name); + glsl_base_type type, const char *name); /** 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, @@ -816,17 +1098,20 @@ private: glsl_type(const glsl_type *return_type, const glsl_function_param *params, unsigned num_params); - /** Constructor for array types */ - glsl_type(const glsl_type *array, unsigned length); + /** Constructors for array types */ + glsl_type(const glsl_type *array, unsigned length, unsigned explicit_stride); /** Constructor for subroutine types */ glsl_type(const char *name); + /** Hash table containing the known explicit matrix and vector types. */ + static struct hash_table *explicit_matrix_types; + /** Hash table containing the known array types. */ static struct hash_table *array_types; - /** Hash table containing the known record types. */ - static struct hash_table *record_types; + /** Hash table containing the known struct types. */ + static struct hash_table *struct_types; /** Hash table containing the known interface types. */ static struct hash_table *interface_types; @@ -859,8 +1144,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); /*@}*/ }; @@ -936,14 +1222,19 @@ struct glsl_struct_field { unsigned precision:2; /** - * Image qualifiers, applicable to buffer variables defined in shader + * Memory qualifiers, applicable to buffer variables defined in shader * storage buffer objects (SSBOs) */ - unsigned image_read_only:1; - unsigned image_write_only:1; - unsigned image_coherent:1; - unsigned image_volatile:1; - unsigned image_restrict:1; + 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 @@ -954,19 +1245,35 @@ struct glsl_struct_field { unsigned implicit_sized_array:1; #ifdef __cplusplus +#define DEFAULT_CONSTRUCTORS(_type, _precision, _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(_precision), 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) + + glsl_struct_field(const struct glsl_type *_type, + int _precision, + const char *_name) + : DEFAULT_CONSTRUCTORS(_type, _precision, _name) + { + /* empty */ + } + glsl_struct_field(const struct glsl_type *_type, const char *_name) - : type(_type), name(_name), location(-1), interpolation(0), centroid(0), - sample(0), matrix_layout(GLSL_MATRIX_LAYOUT_INHERITED), patch(0), - precision(GLSL_PRECISION_NONE), image_read_only(0), image_write_only(0), - image_coherent(0), image_volatile(0), image_restrict(0) + : DEFAULT_CONSTRUCTORS(_type, GLSL_PRECISION_NONE, _name) { /* empty */ } glsl_struct_field() + : DEFAULT_CONSTRUCTORS(NULL, GLSL_PRECISION_NONE, NULL) { /* empty */ } +#undef DEFAULT_CONSTRUCTORS #endif };