X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl_types.h;h=df5ca4629e5b1c266f97430c9f19036bc90e330e;hb=b273611bb177b1a00d292f4d7df55efdf0f4ad61;hp=f607dd8bc378d8b176b2102f0d7de4d8db47d0c0;hpb=5d83820a1d4f6b2390520d2335848d351db13fd7;p=mesa.git diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h index f607dd8bc37..df5ca4629e5 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -22,13 +22,24 @@ * DEALINGS IN THE SOFTWARE. */ -#pragma once #ifndef GLSL_TYPES_H #define GLSL_TYPES_H #include #include +#include "shader_enums.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" +#endif + +struct glsl_type; + #ifdef __cplusplus extern "C" { #endif @@ -37,14 +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(); -#ifdef __cplusplus -} -#endif +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); + +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, @@ -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,127 @@ 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; +} + +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 { @@ -82,14 +224,11 @@ enum glsl_sampler_dim { GLSL_SAMPLER_DIM_EXTERNAL, GLSL_SAMPLER_DIM_MS, GLSL_SAMPLER_DIM_SUBPASS, /* for vulkan input attachments */ + GLSL_SAMPLER_DIM_SUBPASS_MS, /* for multisampled vulkan input attachments */ }; -enum glsl_interface_packing { - GLSL_INTERFACE_PACKING_STD140, - GLSL_INTERFACE_PACKING_SHARED, - GLSL_INTERFACE_PACKING_PACKED, - GLSL_INTERFACE_PACKING_STD430 -}; +int +glsl_get_sampler_dim_coordinate_components(enum glsl_sampler_dim dim); enum glsl_matrix_layout { /** @@ -120,53 +259,42 @@ enum { }; #ifdef __cplusplus +} /* extern "C" */ + #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 +321,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 +354,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 +390,33 @@ 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; + + /** + * 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 */ 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 +433,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 +493,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 @@ -343,6 +510,23 @@ struct glsl_type { */ 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 * @@ -354,8 +538,13 @@ 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 { + return count_vec4_slots(is_gl_vertex_input, true); + } /** * Alignment in bytes of the start of this type in a std140 uniform @@ -370,6 +559,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 +583,59 @@ 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; + + /** 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? * @@ -433,7 +680,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 +700,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 +710,68 @@ 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 a 16-bit integer. + */ + bool is_integer_16() const + { + return base_type == GLSL_TYPE_UINT16 || base_type == GLSL_TYPE_INT16; + } + + /** + * 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 a type is a 16-bit or 32-bit integer + */ + bool is_integer_16_32() const + { + return is_integer_16() || is_integer_32() || is_integer_64(); + } + + /** + * Query whether or not a type is a 16-bit, 32-bit or 64-bit integer + */ + bool is_integer_16_32_64() const + { + return is_integer_16() || 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 +781,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 */ @@ -492,6 +795,56 @@ struct glsl_type { 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 float or double + */ + bool is_float_32_64() const + { + return is_float() || is_double(); + } + + bool is_int_16_32_64() const + { + return base_type == GLSL_TYPE_INT16 || + base_type == GLSL_TYPE_INT || + base_type == GLSL_TYPE_INT64; + } + + bool is_uint_16_32_64() const + { + return base_type == GLSL_TYPE_UINT16 || + base_type == GLSL_TYPE_UINT || + base_type == GLSL_TYPE_UINT64; + } + + bool is_int_16_32() const + { + return base_type == GLSL_TYPE_INT || + base_type == GLSL_TYPE_INT16; + } + + bool is_uint_16_32() const + { + return base_type == GLSL_TYPE_UINT || + base_type == GLSL_TYPE_UINT16; + } + /** * Query whether or not a type is a double type */ @@ -516,6 +869,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 +909,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 +950,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 +1030,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 +1082,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 +1100,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 +1153,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 +1188,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 +1217,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 +1252,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 +1298,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); /*@}*/ }; @@ -900,73 +1340,96 @@ struct glsl_struct_field { * -1 otherwise. */ int xfb_stride; - /** - * For interface blocks, the interpolation mode (as in - * ir_variable::interpolation). 0 otherwise. + * Layout format, applicable to image variables only. */ - unsigned interpolation:2; + enum pipe_format image_format; - /** - * 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; - - /** - * Image 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; - - /** - * 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; + 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), 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, _name) { - /* empty */ + matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED; + precision = GLSL_PRECISION_NONE; } glsl_struct_field() + : DEFAULT_CONSTRUCTORS(NULL, NULL) { - /* empty */ + matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED; + precision = GLSL_PRECISION_NONE; } +#undef DEFAULT_CONSTRUCTORS #endif };