X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl%2Fir.h;h=2ec78f7bdfd9db931dcae17f4051103d20ef17f1;hb=3719b69dfc496cdacfe857e1a42984c435eb8a6c;hp=3d28dd5731ff8d7cd245dfcc24e59dc1b3c49abd;hpb=7c0c3740f01179cc2929cb3343e098d35c927092;p=mesa.git diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h index 3d28dd5731f..2ec78f7bdfd 100644 --- a/src/compiler/glsl/ir.h +++ b/src/compiler/glsl/ir.h @@ -22,7 +22,6 @@ * DEALINGS IN THE SOFTWARE. */ -#pragma once #ifndef IR_H #define IR_H @@ -30,11 +29,12 @@ #include #include "util/ralloc.h" +#include "util/format/u_format.h" +#include "util/half_float.h" #include "compiler/glsl_types.h" #include "list.h" #include "ir_visitor.h" #include "ir_hierarchical_visitor.h" -#include "main/mtypes.h" #ifdef __cplusplus @@ -76,6 +76,7 @@ enum ir_node_type { ir_type_loop_jump, ir_type_return, ir_type_discard, + ir_type_demote, ir_type_emit_vertex, ir_type_end_primitive, ir_type_barrier, @@ -230,11 +231,12 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); - virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); + virtual ir_constant *constant_expression_value(void *mem_ctx, + struct hash_table *variable_context = NULL); ir_rvalue *as_rvalue_to_saturate(); - virtual bool is_lvalue() const + virtual bool is_lvalue(const struct _mesa_glsl_parse_state * = NULL) const { return false; } @@ -397,7 +399,7 @@ depth_layout_string(ir_depth_layout layout); * \sa ir_variable::state_slots */ struct ir_state_slot { - int tokens[5]; + gl_state_index16 tokens[STATE_LENGTH]; int swizzle; }; @@ -457,7 +459,7 @@ public: * * For the first declaration below, there will be an \c ir_variable named * "instance" whose type and whose instance_type will be the same - * \cglsl_type. For the second declaration, there will be an \c ir_variable + * \c glsl_type. For the second declaration, there will be an \c ir_variable * named "f" whose type is float and whose instance_type is B2. * * "instance" is an interface instance variable, but "f" is not. @@ -475,6 +477,17 @@ public: return this->type->without_array() == this->interface_type; } + /** + * Return whether this variable contains a bindless sampler/image. + */ + inline bool contains_bindless() const + { + if (!this->type->contains_sampler() && !this->type->contains_image()) + return false; + + return this->data.bindless || this->data.mode != ir_var_uniform; + } + /** * Set this->interface_type on a newly created variable. */ @@ -599,7 +612,8 @@ public: inline bool is_name_ralloced() const { - return this->name != ir_variable::tmp_name; + return this->name != ir_variable::tmp_name && + this->name != this->name_storage; } /** @@ -624,6 +638,16 @@ public: */ const char *name; +private: + /** + * If the name length fits into name_storage, it's used, otherwise + * the name is ralloc'd. shader-db mining showed that 70% of variables + * fit here. This is a win over ralloc where only ralloc_header has + * 20 bytes on 64-bit (28 bytes with DEBUG), and we can also skip malloc. + */ + char name_storage[16]; + +public: struct ir_variable_data { /** @@ -636,6 +660,19 @@ public: unsigned centroid:1; unsigned sample:1; unsigned patch:1; + /** + * Was an 'invariant' qualifier explicitly set in the shader? + * + * This is used to cross validate qualifiers. + */ + unsigned explicit_invariant:1; + /** + * Is the variable invariant? + * + * It can happen either by having the 'invariant' qualifier + * explicitly set in the shader or by being used in calculations + * of other invariant variables. + */ unsigned invariant:1; unsigned precise:1; @@ -646,8 +683,8 @@ public: * variable has been used. For example, it is an error to redeclare a * variable as invariant after it has been used. * - * This is only maintained in the ast_to_hir.cpp path, not in - * Mesa's fixed function or ARB program paths. + * This is maintained in the ast_to_hir.cpp path and during linking, + * but not in Mesa's fixed function or ARB program paths. */ unsigned used:1; @@ -690,14 +727,6 @@ public: */ unsigned interpolation:2; - /** - * \name ARB_fragment_coord_conventions - * @{ - */ - unsigned origin_upper_left:1; - unsigned pixel_center_integer:1; - /*@}*/ - /** * Was the location explicitly set in the shader? * @@ -729,6 +758,11 @@ public: */ unsigned has_initializer:1; + /** + * Is the initializer created by the compiler (glsl_zero_init) + */ + unsigned is_implicit_initializer:1; + /** * Is this variable a generic output or input that has not yet been matched * up to a variable in another stage of the pipeline? @@ -738,6 +772,13 @@ public: */ unsigned is_unmatched_generic_inout:1; + /** + * Is this varying used by transform feedback? + * + * This is used by the linker to decide if it's safe to pack the varying. + */ + unsigned is_xfb:1; + /** * Is this varying used only by transform feedback? * @@ -746,17 +787,17 @@ public: unsigned is_xfb_only:1; /** - * Was a transfor feedback buffer set in the shader? + * Was a transform feedback buffer set in the shader? */ unsigned explicit_xfb_buffer:1; /** - * Was a transfor feedback offset set in the shader? + * Was a transform feedback offset set in the shader? */ unsigned explicit_xfb_offset:1; /** - * Was a transfor feedback stride set in the shader? + * Was a transform feedback stride set in the shader? */ unsigned explicit_xfb_stride:1; @@ -817,13 +858,13 @@ public: ir_depth_layout depth_layout:3; /** - * ARB_shader_image_load_store qualifiers. + * Memory qualifiers. */ - unsigned image_read_only:1; /**< "readonly" qualifier. */ - unsigned image_write_only:1; /**< "writeonly" qualifier. */ - unsigned image_coherent:1; - unsigned image_volatile:1; - unsigned image_restrict:1; + unsigned memory_read_only:1; /**< "readonly" qualifier. */ + unsigned memory_write_only:1; /**< "writeonly" qualifier. */ + unsigned memory_coherent:1; + unsigned memory_volatile:1; + unsigned memory_restrict:1; /** * ARB_shader_storage_buffer_object @@ -839,6 +880,18 @@ public: */ unsigned fb_fetch_output:1; + /** + * Non-zero if this variable is considered bindless as defined by + * ARB_bindless_texture. + */ + unsigned bindless:1; + + /** + * Non-zero if this variable is considered bound as defined by + * ARB_bindless_texture. + */ + unsigned bound:1; + /** * Emit a warning if this variable is accessed. */ @@ -846,8 +899,11 @@ public: uint8_t warn_extension_index; public: - /** Image internal format if specified explicitly, otherwise GL_NONE. */ - uint16_t image_format; + /** + * Image internal format if specified explicitly, otherwise + * PIPE_FORMAT_NONE. + */ + enum pipe_format image_format; private: /** @@ -866,7 +922,7 @@ public: * * For array types, this represents the binding point for the first element. */ - int16_t binding; + uint16_t binding; /** * Storage location of the base of this variable @@ -900,6 +956,9 @@ public: /** * Vertex stream output identifier. + * + * For packed outputs, bit 31 is set and bits [2*i+1,2*i] indicate the + * stream of the i-th component. */ unsigned stream; @@ -1065,6 +1124,8 @@ enum ir_intrinsic_id { ir_intrinsic_image_atomic_comp_swap, ir_intrinsic_image_size, ir_intrinsic_image_samples, + ir_intrinsic_image_atomic_inc_wrap, + ir_intrinsic_image_atomic_dec_wrap, ir_intrinsic_ssbo_load, ir_intrinsic_ssbo_store = MAKE_INTRINSIC_FOR_TYPE(store, ssbo), @@ -1084,6 +1145,17 @@ enum ir_intrinsic_id { ir_intrinsic_memory_barrier_buffer, ir_intrinsic_memory_barrier_image, ir_intrinsic_memory_barrier_shared, + ir_intrinsic_begin_invocation_interlock, + ir_intrinsic_end_invocation_interlock, + + ir_intrinsic_vote_all, + ir_intrinsic_vote_any, + ir_intrinsic_vote_eq, + ir_intrinsic_ballot, + ir_intrinsic_read_invocation, + ir_intrinsic_read_first_invocation, + + ir_intrinsic_helper_invocation, ir_intrinsic_shared_load, ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared), @@ -1127,7 +1199,9 @@ public: * given a list of the actual parameters and the variable context. * Returns NULL for non-built-ins. */ - ir_constant *constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context); + ir_constant *constant_expression_value(void *mem_ctx, + exec_list *actual_parameters, + struct hash_table *variable_context); /** * Get the name of the function for which this is a signature @@ -1168,7 +1242,7 @@ public: /** * Function return type. * - * \note This discards the optional precision qualifier. + * \note The precision qualifier is stored separately in return_precision. */ const struct glsl_type *return_type; @@ -1183,6 +1257,13 @@ public: /** Whether or not this function has a body (which may be empty). */ unsigned is_defined:1; + /* + * Precision qualifier for the return type. + * + * See the comment for ir_variable_data::precision for more details. + */ + unsigned return_precision:2; + /** Whether or not this function signature is a built-in. */ bool is_builtin() const; @@ -1230,7 +1311,8 @@ private: * Returns false if the expression is not constant, true otherwise, * and the value in *result if result is non-NULL. */ - bool constant_expression_evaluate_expression_list(const struct exec_list &body, + bool constant_expression_evaluate_expression_list(void *mem_ctx, + const struct exec_list &body, struct hash_table *variable_context, ir_constant **result); }; @@ -1386,7 +1468,8 @@ public: virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); + virtual ir_constant *constant_expression_value(void *mem_ctx, + struct hash_table *variable_context = NULL); virtual void accept(ir_visitor *v) { @@ -1454,6 +1537,7 @@ public: #include "ir_expression_operation.h" extern const char *const ir_expression_operation_strings[ir_last_opcode + 1]; +extern const char *const ir_expression_operation_enum_strings[ir_last_opcode + 1]; class ir_expression : public ir_rvalue { public: @@ -1491,21 +1575,14 @@ public: * If the expression cannot be constant folded, this method will return * \c NULL. */ - virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - - /** - * Determine the number of operands used by an expression - */ - static unsigned int get_num_operands(ir_expression_operation); + virtual ir_constant *constant_expression_value(void *mem_ctx, + struct hash_table *variable_context = NULL); /** - * Determine the number of operands used by an expression + * This is only here for ir_reader to used for testing purposes please use + * the precomputed num_operands field if you need the number of operands. */ - unsigned int get_num_operands() const - { - return (this->operation == ir_quadop_vector) - ? this->type->vector_elements : get_num_operands(operation); - } + static unsigned get_num_operands(ir_expression_operation); /** * Return whether the expression operates on vectors horizontally. @@ -1535,8 +1612,21 @@ public: virtual ir_variable *variable_referenced() const; + /** + * Determine the number of operands used by an expression + */ + void init_num_operands() + { + if (operation == ir_quadop_vector) { + num_operands = this->type->vector_elements; + } else { + num_operands = get_num_operands(operation); + } + } + ir_expression_operation operation; ir_rvalue *operands[4]; + uint8_t num_operands; }; @@ -1553,7 +1643,6 @@ public: { assert(callee->return_type != NULL); actual_parameters->move_nodes_to(& this->actual_parameters); - this->use_builtin = callee->is_builtin(); } ir_call(ir_function_signature *callee, @@ -1564,12 +1653,12 @@ public: { assert(callee->return_type != NULL); actual_parameters->move_nodes_to(& this->actual_parameters); - this->use_builtin = callee->is_builtin(); } virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); + virtual ir_constant *constant_expression_value(void *mem_ctx, + struct hash_table *variable_context = NULL); virtual void accept(ir_visitor *v) { @@ -1606,9 +1695,6 @@ public: /* List of ir_rvalue of paramaters passed in this call. */ exec_list actual_parameters; - /** Should this call only bind to a built-in function? */ - bool use_builtin; - /* * ARB_shader_subroutine support - * the subroutine uniform variable and array index @@ -1738,6 +1824,28 @@ public: /*@}*/ +/** + * IR instruction representing demote statements from + * GL_EXT_demote_to_helper_invocation. + */ +class ir_demote : public ir_instruction { +public: + ir_demote() + : ir_instruction(ir_type_demote) + { + } + + virtual ir_demote *clone(void *mem_ctx, struct hash_table *ht) const; + + virtual void accept(ir_visitor *v) + { + v->visit(this); + } + + virtual ir_visitor_status accept(ir_hierarchical_visitor *); +}; + + /** * Texture sampling opcodes used in ir_texture */ @@ -1766,7 +1874,7 @@ enum ir_texture_opcode { * * Texel offset (0 or an expression) * | Projection divisor - * | | Shadow comparitor + * | | Shadow comparator * | | | * v v v * (tex 0 1 ( )) @@ -1787,14 +1895,15 @@ public: ir_texture(enum ir_texture_opcode op) : ir_rvalue(ir_type_texture), op(op), sampler(NULL), coordinate(NULL), projector(NULL), - shadow_comparitor(NULL), offset(NULL) + shadow_comparator(NULL), offset(NULL) { memset(&lod_info, 0, sizeof(lod_info)); } virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); + virtual ir_constant *constant_expression_value(void *mem_ctx, + struct hash_table *variable_context = NULL); virtual void accept(ir_visitor *v) { @@ -1842,7 +1951,7 @@ public: * If there is no shadow comparison, this will be \c NULL. For the * \c ir_txf opcode, this *must* be \c NULL. */ - ir_rvalue *shadow_comparitor; + ir_rvalue *shadow_comparator; /** Texel offset. */ ir_rvalue *offset; @@ -1891,7 +2000,8 @@ public: virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); + virtual ir_constant *constant_expression_value(void *mem_ctx, + struct hash_table *variable_context = NULL); /** * Construct an ir_swizzle from the textual representation. Can fail. @@ -1908,9 +2018,9 @@ public: virtual bool equals(const ir_instruction *ir, enum ir_node_type ignore = ir_type_unset) const; - bool is_lvalue() const + bool is_lvalue(const struct _mesa_glsl_parse_state *state) const { - return val->is_lvalue() && !mask.has_duplicates; + return val->is_lvalue(state) && !mask.has_duplicates; } /** @@ -1935,13 +2045,19 @@ class ir_dereference : public ir_rvalue { public: virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0; - bool is_lvalue() const; + bool is_lvalue(const struct _mesa_glsl_parse_state *state) const; /** * Get the variable that is ultimately referenced by an r-value */ virtual ir_variable *variable_referenced() const = 0; + /** + * Get the precision. This can either come from the eventual variable that + * is dereferenced, or from a record member. + */ + virtual int precision() const = 0; + protected: ir_dereference(enum ir_node_type t) : ir_rvalue(t) @@ -1957,7 +2073,8 @@ public: virtual ir_dereference_variable *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); + virtual ir_constant *constant_expression_value(void *mem_ctx, + struct hash_table *variable_context = NULL); virtual bool equals(const ir_instruction *ir, enum ir_node_type ignore = ir_type_unset) const; @@ -1970,6 +2087,11 @@ public: return this->var; } + virtual int precision() const + { + return this->var->data.precision; + } + virtual ir_variable *whole_variable_referenced() { /* ir_dereference_variable objects always dereference the entire @@ -2004,7 +2126,8 @@ public: virtual ir_dereference_array *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); + virtual ir_constant *constant_expression_value(void *mem_ctx, + struct hash_table *variable_context = NULL); virtual bool equals(const ir_instruction *ir, enum ir_node_type ignore = ir_type_unset) const; @@ -2017,6 +2140,16 @@ public: return this->array->variable_referenced(); } + virtual int precision() const + { + ir_dereference *deref = this->array->as_dereference(); + + if (deref == NULL) + return GLSL_PRECISION_NONE; + else + return deref->precision(); + } + virtual void accept(ir_visitor *v) { v->visit(this); @@ -2041,7 +2174,8 @@ public: virtual ir_dereference_record *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); + virtual ir_constant *constant_expression_value(void *mem_ctx, + struct hash_table *variable_context = NULL); /** * Get the variable that is ultimately referenced by an r-value @@ -2051,6 +2185,13 @@ public: return this->record->variable_referenced(); } + virtual int precision() const + { + glsl_struct_field *field = record->type->fields.structure + field_idx; + + return field->precision; + } + virtual void accept(ir_visitor *v) { v->visit(this); @@ -2059,7 +2200,7 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); ir_rvalue *record; - const char *field; + int field_idx; }; @@ -2072,6 +2213,11 @@ union ir_constant_data { float f[16]; bool b[16]; double d[16]; + uint16_t f16[16]; + uint16_t u16[16]; + int16_t i16[16]; + uint64_t u64[16]; + int64_t i64[16]; }; @@ -2079,10 +2225,15 @@ class ir_constant : public ir_rvalue { public: ir_constant(const struct glsl_type *type, const ir_constant_data *data); ir_constant(bool b, unsigned vector_elements=1); + ir_constant(int16_t i16, unsigned vector_elements=1); + ir_constant(uint16_t u16, unsigned vector_elements=1); ir_constant(unsigned int u, unsigned vector_elements=1); ir_constant(int i, unsigned vector_elements=1); + ir_constant(float16_t f16, unsigned vector_elements=1); ir_constant(float f, unsigned vector_elements=1); ir_constant(double d, unsigned vector_elements=1); + ir_constant(uint64_t u64, unsigned vector_elements=1); + ir_constant(int64_t i64, unsigned vector_elements=1); /** * Construct an ir_constant from a list of ir_constant values @@ -2108,7 +2259,8 @@ public: virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); + virtual ir_constant *constant_expression_value(void *mem_ctx, + struct hash_table *variable_context = NULL); virtual void accept(ir_visitor *v) { @@ -2130,14 +2282,19 @@ public: /*@{*/ bool get_bool_component(unsigned i) const; float get_float_component(unsigned i) const; + uint16_t get_float16_component(unsigned i) const; double get_double_component(unsigned i) const; + int16_t get_int16_component(unsigned i) const; + uint16_t get_uint16_component(unsigned i) const; int get_int_component(unsigned i) const; unsigned get_uint_component(unsigned i) const; + int64_t get_int64_component(unsigned i) const; + uint64_t get_uint64_component(unsigned i) const; /*@}*/ ir_constant *get_array_element(unsigned i) const; - ir_constant *get_record_field(const char *name); + ir_constant *get_record_field(int idx); /** * Copy the values on another constant at a given offset. @@ -2199,11 +2356,8 @@ public: */ union ir_constant_data value; - /* Array elements */ - ir_constant **array_elements; - - /* Structure fields */ - exec_list components; + /* Array elements and structure fields */ + ir_constant **const_elements; private: /** @@ -2352,29 +2506,6 @@ extern void _mesa_glsl_initialize_variables(exec_list *instructions, struct _mesa_glsl_parse_state *state); -extern void -_mesa_glsl_initialize_derived_variables(struct gl_context *ctx, - gl_shader *shader); - -extern void -_mesa_glsl_initialize_builtin_functions(); - -extern ir_function_signature * -_mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state, - const char *name, exec_list *actual_parameters); - -extern ir_function * -_mesa_glsl_find_builtin_function_by_name(const char *name); - -extern gl_shader * -_mesa_glsl_get_builtin_function_shader(void); - -extern ir_function_signature * -_mesa_get_main_function_signature(glsl_symbol_table *symbols); - -extern void -_mesa_glsl_release_builtin_functions(void); - extern void reparent_ir(exec_list *list, void *mem_ctx);