X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fir.h;h=e266328b204e62a231eff8fda0f49c1c7680099f;hb=de796b0ef09f05ca3f8a568ed07293e28ae697b0;hp=6c5630b09657bd49771bf974c01d9d670f61e1ff;hpb=5561251b58c976a70125bb07dc1c6cc2bd2541f4;p=mesa.git diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 6c5630b0965..e266328b204 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -86,6 +86,7 @@ enum ir_node_type { ir_type_max /**< maximum ir_type enum number, for validation */ }; + /** * Base class of all IR instructions */ @@ -133,11 +134,22 @@ public: virtual class ir_return * as_return() { return NULL; } virtual class ir_if * as_if() { return NULL; } virtual class ir_swizzle * as_swizzle() { return NULL; } + virtual class ir_texture * as_texture() { return NULL; } virtual class ir_constant * as_constant() { return NULL; } virtual class ir_discard * as_discard() { return NULL; } virtual class ir_jump * as_jump() { return NULL; } /*@}*/ + /** + * IR equality method: Return true if the referenced instruction would + * return the same value as this one. + * + * This intended to be used for CSE and algebraic optimizations, on rvalues + * in particular. No support for other instruction types (assignments, + * jumps, calls, etc.) is planned. + */ + virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); + protected: ir_instruction() { @@ -282,6 +294,34 @@ enum ir_variable_mode { ir_var_mode_count /**< Number of variable modes */ }; +/** + * Enum keeping track of how a variable was declared. For error checking of + * the gl_PerVertex redeclaration rules. + */ +enum ir_var_declaration_type { + /** + * Normal declaration (for most variables, this means an explicit + * declaration. Exception: temporaries are always implicitly declared, but + * they still use ir_var_declared_normally). + * + * Note: an ir_variable that represents a named interface block uses + * ir_var_declared_normally. + */ + ir_var_declared_normally = 0, + + /** + * Variable was explicitly declared (or re-declared) in an unnamed + * interface block. + */ + ir_var_declared_in_block, + + /** + * Variable is an implicitly declared built-in that has not been explicitly + * re-declared by the shader. + */ + ir_var_declared_implicitly, +}; + /** * \brief Layout qualifiers for gl_FragDepth. * @@ -312,6 +352,22 @@ struct ir_state_slot { int swizzle; }; + +/** + * Get the string value for an interpolation qualifier + * + * \return The string that would be used in a shader to specify \c + * mode will be returned. + * + * This function is used to generate error messages of the form "shader + * uses %s interpolation qualifier", so in the case where there is no + * interpolation qualifier, it returns "no". + * + * This function should only be used on a shader input or output variable. + */ +const char *interpolation_string(unsigned interpolation); + + class ir_variable : public ir_instruction { public: ir_variable(const struct glsl_type *, const char *, ir_variable_mode); @@ -331,20 +387,6 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); - /** - * Get the string value for the interpolation qualifier - * - * \return The string that would be used in a shader to specify \c - * mode will be returned. - * - * This function is used to generate error messages of the form "shader - * uses %s interpolation qualifier", so in the case where there is no - * interpolation qualifier, it returns "no". - * - * This function should only be used on a shader input or output variable. - */ - const char *interpolation_string() const; - /** * Determine how this variable should be interpolated based on its * interpolation qualifier (if present), whether it is gl_Color or @@ -361,7 +403,7 @@ public: */ inline bool is_in_uniform_block() const { - return this->mode == ir_var_uniform && this->interface_type != NULL; + return this->data.mode == ir_var_uniform && this->interface_type != NULL; } /** @@ -392,159 +434,270 @@ public: } /** - * Declared type of the variable + * Set this->interface_type on a newly created variable. */ - const struct glsl_type *type; + void init_interface_type(const struct glsl_type *type) + { + assert(this->interface_type == NULL); + this->interface_type = type; + if (this->is_interface_instance()) { + this->max_ifc_array_access = + rzalloc_array(this, unsigned, type->length); + } + } /** - * Declared name of the variable + * Change this->interface_type on a variable that previously had a + * different, but compatible, interface_type. This is used during linking + * to set the size of arrays in interface blocks. */ - const char *name; + void change_interface_type(const struct glsl_type *type) + { + if (this->max_ifc_array_access != NULL) { + /* max_ifc_array_access has already been allocated, so make sure the + * new interface has the same number of fields as the old one. + */ + assert(this->interface_type->length == type->length); + } + this->interface_type = type; + } /** - * Highest element accessed with a constant expression array index - * - * Not used for non-array variables. + * Change this->interface_type on a variable that previously had a + * different, and incompatible, interface_type. This is used during + * compilation to handle redeclaration of the built-in gl_PerVertex + * interface block. */ - unsigned max_array_access; + void reinit_interface_type(const struct glsl_type *type) + { + if (this->max_ifc_array_access != NULL) { +#ifndef NDEBUG + /* Redeclaring gl_PerVertex is only allowed if none of the built-ins + * it defines have been accessed yet; so it's safe to throw away the + * old max_ifc_array_access pointer, since all of its values are + * zero. + */ + for (unsigned i = 0; i < this->interface_type->length; i++) + assert(this->max_ifc_array_access[i] == 0); +#endif + ralloc_free(this->max_ifc_array_access); + this->max_ifc_array_access = NULL; + } + this->interface_type = NULL; + init_interface_type(type); + } - /** - * Is the variable read-only? - * - * This is set for variables declared as \c const, shader inputs, - * and uniforms. - */ - unsigned read_only:1; - unsigned centroid:1; - unsigned invariant:1; + const glsl_type *get_interface_type() const + { + return this->interface_type; + } /** - * Has this variable been used for reading or writing? - * - * Several GLSL semantic checks require knowledge of whether or not a - * 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. + * Declared type of the variable */ - unsigned used:1; + const struct glsl_type *type; /** - * Has this variable been statically assigned? - * - * This answers whether the variable was assigned in any path of - * the shader during ast_to_hir. This doesn't answer whether it is - * still written after dead code removal, nor is it maintained in - * non-ast_to_hir.cpp (GLSL parsing) paths. + * Declared name of the variable */ - unsigned assigned:1; + const char *name; /** - * Storage class of the variable. + * For variables which satisfy the is_interface_instance() predicate, this + * points to an array of integers such that if the ith member of the + * interface block is an array, max_ifc_array_access[i] is the maximum + * array element of that member that has been accessed. If the ith member + * of the interface block is not an array, max_ifc_array_access[i] is + * unused. * - * \sa ir_variable_mode + * For variables whose type is not an interface block, this pointer is + * NULL. */ - unsigned mode:4; + unsigned *max_ifc_array_access; - /** - * Interpolation mode for shader inputs / outputs - * - * \sa ir_variable_interpolation - */ - unsigned interpolation:2; + struct ir_variable_data { - /** - * \name ARB_fragment_coord_conventions - * @{ - */ - unsigned origin_upper_left:1; - unsigned pixel_center_integer:1; - /*@}*/ + /** + * Is the variable read-only? + * + * This is set for variables declared as \c const, shader inputs, + * and uniforms. + */ + unsigned read_only:1; + unsigned centroid:1; + unsigned sample:1; + unsigned invariant:1; + + /** + * Has this variable been used for reading or writing? + * + * Several GLSL semantic checks require knowledge of whether or not a + * 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. + */ + unsigned used:1; + + /** + * Has this variable been statically assigned? + * + * This answers whether the variable was assigned in any path of + * the shader during ast_to_hir. This doesn't answer whether it is + * still written after dead code removal, nor is it maintained in + * non-ast_to_hir.cpp (GLSL parsing) paths. + */ + unsigned assigned:1; - /** - * Was the location explicitly set in the shader? - * - * If the location is explicitly set in the shader, it \b cannot be changed - * by the linker or by the API (e.g., calls to \c glBindAttribLocation have - * no effect). - */ - unsigned explicit_location:1; - unsigned explicit_index:1; + /** + * Enum indicating how the variable was declared. See + * ir_var_declaration_type. + * + * This is used to detect certain kinds of illegal variable redeclarations. + */ + unsigned how_declared:2; - /** - * Was an initial binding explicitly set in the shader? - * - * If so, constant_value contains an integer ir_constant representing the - * initial binding point. - */ - unsigned explicit_binding:1; + /** + * Storage class of the variable. + * + * \sa ir_variable_mode + */ + unsigned mode:4; - /** - * Does this variable have an initializer? - * - * This is used by the linker to cross-validiate initializers of global - * variables. - */ - unsigned has_initializer:1; + /** + * Interpolation mode for shader inputs / outputs + * + * \sa ir_variable_interpolation + */ + unsigned interpolation:2; - /** - * Is this variable a generic output or input that has not yet been matched - * up to a variable in another stage of the pipeline? - * - * This is used by the linker as scratch storage while assigning locations - * to generic inputs and outputs. - */ - unsigned is_unmatched_generic_inout:1; + /** + * \name ARB_fragment_coord_conventions + * @{ + */ + unsigned origin_upper_left:1; + unsigned pixel_center_integer:1; + /*@}*/ + + /** + * Was the location explicitly set in the shader? + * + * If the location is explicitly set in the shader, it \b cannot be changed + * by the linker or by the API (e.g., calls to \c glBindAttribLocation have + * no effect). + */ + unsigned explicit_location:1; + unsigned explicit_index:1; + + /** + * Was an initial binding explicitly set in the shader? + * + * If so, constant_value contains an integer ir_constant representing the + * initial binding point. + */ + unsigned explicit_binding:1; - /** - * If non-zero, then this variable may be packed along with other variables - * into a single varying slot, so this offset should be applied when - * accessing components. For example, an offset of 1 means that the x - * component of this variable is actually stored in component y of the - * location specified by \c location. - */ - unsigned location_frac:2; + /** + * Does this variable have an initializer? + * + * This is used by the linker to cross-validiate initializers of global + * variables. + */ + unsigned has_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? + * + * This is used by the linker as scratch storage while assigning locations + * to generic inputs and outputs. + */ + unsigned is_unmatched_generic_inout:1; + + /** + * If non-zero, then this variable may be packed along with other variables + * into a single varying slot, so this offset should be applied when + * accessing components. For example, an offset of 1 means that the x + * component of this variable is actually stored in component y of the + * location specified by \c location. + */ + unsigned location_frac:2; + + /** + * Non-zero if this variable was created by lowering a named interface + * block which was not an array. + * + * Note that this variable and \c from_named_ifc_block_array will never + * both be non-zero. + */ + unsigned from_named_ifc_block_nonarray:1; + + /** + * Non-zero if this variable was created by lowering a named interface + * block which was an array. + * + * Note that this variable and \c from_named_ifc_block_nonarray will never + * both be non-zero. + */ + unsigned from_named_ifc_block_array:1; - /** - * \brief Layout qualifier for gl_FragDepth. - * - * This is not equal to \c ir_depth_layout_none if and only if this - * variable is \c gl_FragDepth and a layout qualifier is specified. - */ - ir_depth_layout depth_layout; + /** + * \brief Layout qualifier for gl_FragDepth. + * + * This is not equal to \c ir_depth_layout_none if and only if this + * variable is \c gl_FragDepth and a layout qualifier is specified. + */ + ir_depth_layout depth_layout; + + /** + * Storage location of the base of this variable + * + * The precise meaning of this field depends on the nature of the variable. + * + * - Vertex shader input: one of the values from \c gl_vert_attrib. + * - Vertex shader output: one of the values from \c gl_varying_slot. + * - Geometry shader input: one of the values from \c gl_varying_slot. + * - Geometry shader output: one of the values from \c gl_varying_slot. + * - Fragment shader input: one of the values from \c gl_varying_slot. + * - Fragment shader output: one of the values from \c gl_frag_result. + * - Uniforms: Per-stage uniform slot number for default uniform block. + * - Uniforms: Index within the uniform block definition for UBO members. + * - Other: This field is not currently used. + * + * If the variable is a uniform, shader input, or shader output, and the + * slot has not been assigned, the value will be -1. + */ + int location; - /** - * Storage location of the base of this variable - * - * The precise meaning of this field depends on the nature of the variable. - * - * - Vertex shader input: one of the values from \c gl_vert_attrib. - * - Vertex shader output: one of the values from \c gl_varying_slot. - * - Geometry shader input: one of the values from \c gl_varying_slot. - * - Geometry shader output: one of the values from \c gl_varying_slot. - * - Fragment shader input: one of the values from \c gl_varying_slot. - * - Fragment shader output: one of the values from \c gl_frag_result. - * - Uniforms: Per-stage uniform slot number for default uniform block. - * - Uniforms: Index within the uniform block definition for UBO members. - * - Other: This field is not currently used. - * - * If the variable is a uniform, shader input, or shader output, and the - * slot has not been assigned, the value will be -1. - */ - int location; + /** + * output index for dual source blending. + */ + int index; - /** - * output index for dual source blending. - */ - int index; + /** + * Initial binding point for a sampler or UBO. + * + * For array types, this represents the binding point for the first element. + */ + int binding; - /** - * Initial binding point for a sampler or UBO. - * - * For array types, this represents the binding point for the first element. - */ - int binding; + /** + * Location an atomic counter is stored at. + */ + struct { + unsigned buffer_index; + unsigned offset; + } atomic; + + /** + * Highest element accessed with a constant expression array index + * + * Not used for non-array variables. + */ + unsigned max_array_access; + + } data; /** * Built-in state that backs this uniform @@ -582,6 +735,7 @@ public: */ ir_constant *constant_initializer; +private: /** * For variables that are in an interface block or are an instance of an * interface block, this is the \c GLSL_TYPE_INTERFACE type for that block. @@ -686,6 +840,12 @@ public: /** Whether or not this function signature is a built-in. */ bool is_builtin() const; + /** + * Whether or not this function is an intrinsic to be implemented + * by the driver. + */ + bool is_intrinsic; + /** Whether or not a built-in is available for this shader. */ bool is_builtin_available(const _mesa_glsl_parse_state *state) const; @@ -753,14 +913,6 @@ public: this->signatures.push_tail(sig); } - /** - * Get an iterator for the set of function signatures - */ - exec_list_iterator iterator() - { - return signatures.iterator(); - } - /** * Find a signature that matches a set of actual parameters, taking implicit * conversions into account. Also flags whether the match was exact. @@ -858,44 +1010,8 @@ public: return this; } - /** - * Get an iterator for the instructions of the loop body - */ - exec_list_iterator iterator() - { - return body_instructions.iterator(); - } - /** List of ir_instruction that make up the body of the loop. */ exec_list body_instructions; - - /** - * \name Loop counter and controls - * - * Represents a loop like a FORTRAN \c do-loop. - * - * \note - * If \c from and \c to are the same value, the loop will execute once. - */ - /*@{*/ - ir_rvalue *from; /** Value of the loop counter on the first - * iteration of the loop. - */ - ir_rvalue *to; /** Value of the loop counter on the last - * iteration of the loop. - */ - ir_rvalue *increment; - ir_variable *counter; - - /** - * Comparison operation in the loop terminator. - * - * If any of the loop control fields are non-\c NULL, this field must be - * one of \c ir_binop_less, \c ir_binop_greater, \c ir_binop_lequal, - * \c ir_binop_gequal, \c ir_binop_equal, or \c ir_binop_nequal. - */ - int cmp; - /*@}*/ }; @@ -1091,9 +1207,25 @@ enum ir_expression_operation { ir_binop_add, ir_binop_sub, - ir_binop_mul, + ir_binop_mul, /**< Floating-point or low 32-bit integer multiply. */ + ir_binop_imul_high, /**< Calculates the high 32-bits of a 64-bit multiply. */ ir_binop_div, + /** + * Returns the carry resulting from the addition of the two arguments. + */ + /*@{*/ + ir_binop_carry, + /*@}*/ + + /** + * Returns the borrow resulting from the subtraction of the second argument + * from the first argument. + */ + /*@{*/ + ir_binop_borrow, + /*@}*/ + /** * Takes one of two combinations of arguments: * @@ -1281,6 +1413,8 @@ public: return this; } + virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); + virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const; /** @@ -1370,14 +1504,6 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); - /** - * Get an iterator for the set of acutal parameters - */ - exec_list_iterator iterator() - { - return actual_parameters.iterator(); - } - /** * Get the name of the function being called. */ @@ -1559,7 +1685,9 @@ enum ir_texture_opcode { ir_txf, /**< Texel fetch with explicit LOD */ ir_txf_ms, /**< Multisample texture fetch */ ir_txs, /**< Texture size */ - ir_lod /**< Texture lod query */ + ir_lod, /**< Texture lod query */ + ir_tg4, /**< Texture gather */ + ir_query_levels /**< Texture levels query */ }; @@ -1584,6 +1712,8 @@ enum ir_texture_opcode { * ) * (txs ) * (lod ) + * (tg4 ) + * (query_levels ) */ class ir_texture : public ir_rvalue { public: @@ -1604,8 +1734,15 @@ public: v->visit(this); } + virtual ir_texture *as_texture() + { + return this; + } + virtual ir_visitor_status accept(ir_hierarchical_visitor *); + virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); + /** * Return a string representing the ir_texture_opcode. */ @@ -1651,6 +1788,7 @@ public: ir_rvalue *lod; /**< Floating point LOD */ ir_rvalue *bias; /**< Floating point LOD bias */ ir_rvalue *sample_index; /**< MSAA sample index */ + ir_rvalue *component; /**< Gather component selector */ struct { ir_rvalue *dPdx; /**< Partial derivative of coordinate wrt X */ ir_rvalue *dPdy; /**< Partial derivative of coordinate wrt Y */ @@ -1709,6 +1847,8 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); + virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); + bool is_lvalue() const { return val->is_lvalue() && !mask.has_duplicates; @@ -1773,6 +1913,8 @@ public: return this; } + virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); + /** * Get the variable that is ultimately referenced by an r-value */ @@ -1831,6 +1973,8 @@ public: return this; } + virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); + /** * Get the variable that is ultimately referenced by an r-value */ @@ -1965,6 +2109,8 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); + virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); + /** * Get a particular component of a constant as a specific type * @@ -2016,6 +2162,12 @@ public: */ bool has_value(const ir_constant *) const; + /** + * Return true if this ir_constant represents the given value. + * + * For vectors, this checks that each component is the given value. + */ + virtual bool is_value(float f, int i) const; virtual bool is_zero() const; virtual bool is_one() const; virtual bool is_negative_one() const; @@ -2152,6 +2304,9 @@ extern ir_function_signature * _mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state, const char *name, exec_list *actual_parameters); +extern gl_shader * +_mesa_glsl_get_builtin_function_shader(void); + extern void _mesa_glsl_release_functions(void); @@ -2172,12 +2327,15 @@ ir_has_call(ir_instruction *ir); extern void do_set_program_inouts(exec_list *instructions, struct gl_program *prog, - GLenum shader_type); + gl_shader_stage shader_stage); extern char * prototype_string(const glsl_type *return_type, const char *name, exec_list *parameters); +const char * +mode_string(const ir_variable *var); + extern "C" { #endif /* __cplusplus */