X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fir.h;h=06198e4f3f619a2f29cabc6623f1ebb4c9281aa3;hb=cd6a31cd4a9ea6deef4778c2eaef2d47240c3a6e;hp=b6cd1bae31cacf390d47451118b9a8d211ad8622;hpb=e340854115f2562109c91fa908ffe6628432f989;p=mesa.git diff --git a/src/glsl/ir.h b/src/glsl/ir.h index b6cd1bae31c..06198e4f3f6 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -41,7 +41,31 @@ extern "C" { #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #endif +/** + * \defgroup IR Intermediate representation nodes + * + * @{ + */ + +/** + * Class tags + * + * Each concrete class derived from \c ir_instruction has a value in this + * enumerant. The value for the type is stored in \c ir_instruction::ir_type + * by the constructor. While using type tags is not very C++, it is extremely + * convenient. For example, during debugging you can simply inspect + * \c ir_instruction::ir_type to find out the actual type of the object. + * + * In addition, it is possible to use a switch-statement based on \c + * \c ir_instruction::ir_type to select different behavior for different object + * types. For functions that have only slight differences for several object + * types, this allows writing very straightforward, readable code. + */ enum ir_node_type { + /** + * Zero is unused so that the IR validator can detect cases where + * \c ir_instruction::ir_type has not been initialized. + */ ir_type_unset, ir_type_variable, ir_type_assignment, @@ -60,7 +84,7 @@ enum ir_node_type { ir_type_return, ir_type_swizzle, ir_type_texture, - ir_type_max, /**< maximum ir_type enum number, for validation */ + ir_type_max /**< maximum ir_type enum number, for validation */ }; /** @@ -76,7 +100,8 @@ public: virtual void accept(ir_visitor *) = 0; virtual ir_visitor_status accept(ir_hierarchical_visitor *) = 0; - virtual ir_instruction *clone(struct hash_table *ht) const = 0; + virtual ir_instruction *clone(void *mem_ctx, + struct hash_table *ht) const = 0; /** * \name IR instruction downcast functions @@ -106,15 +131,16 @@ protected: ir_instruction() { ir_type = ir_type_unset; + type = NULL; } }; class ir_rvalue : public ir_instruction { public: - class ir_constant *constant_expression_value(); + virtual ir_rvalue *clone(void *mem_ctx, struct hash_table *) const = 0; - virtual ir_rvalue *clone(struct hash_table *) const = 0; + virtual ir_constant *constant_expression_value() = 0; virtual ir_rvalue * as_rvalue() { @@ -150,19 +176,20 @@ public: } protected: - ir_rvalue() - { - /* empty */ - } + ir_rvalue(); }; +/** + * Variable storage classes + */ enum ir_variable_mode { - ir_var_auto = 0, - ir_var_uniform, + ir_var_auto = 0, /**< Function local variables and globals. */ + ir_var_uniform, /**< Variable declared as a uniform. */ ir_var_in, ir_var_out, - ir_var_inout + ir_var_inout, + ir_var_temporary /**< Temporary variable generated during compilation. */ }; enum ir_variable_interpolation { @@ -174,9 +201,9 @@ enum ir_variable_interpolation { class ir_variable : public ir_instruction { public: - ir_variable(const struct glsl_type *, const char *); + ir_variable(const struct glsl_type *, const char *, ir_variable_mode); - virtual ir_variable *clone(struct hash_table *ht) const; + virtual ir_variable *clone(void *mem_ctx, struct hash_table *ht) const; virtual ir_variable *as_variable() { @@ -194,10 +221,10 @@ public: /** * Get the string value for the interpolation qualifier * - * \return - * If none of \c shader_in or \c shader_out is set, an empty string will - * be returned. Otherwise the string that would be used in a shader to - * specify \c mode will be returned. + * \return The string that would be used in a shader to specify \c + * mode will be returned. + * + * This function should only be used on a shader input or output variable. */ const char *interpolation_string() const; @@ -209,6 +236,9 @@ public: */ unsigned component_slots() const; + /** + * Delcared name of the variable + */ const char *name; /** @@ -218,17 +248,28 @@ public: */ unsigned max_array_access; + /** + * 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; - /** If the variable is initialized outside of the scope of the shader */ - unsigned shader_in:1; + /** - * If the variable value is later used outside of the scope of the shader. + * Storage class of the variable. + * + * \sa ir_variable_mode */ - unsigned shader_out:1; - unsigned mode:3; + + /** + * Interpolation mode for shader inputs / outputs + * + * \sa ir_variable_interpolation + */ unsigned interpolation:2; /** @@ -239,6 +280,23 @@ public: */ unsigned array_lvalue: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; + /** * Storage location of the base of this variable * @@ -280,7 +338,8 @@ class ir_function_signature : public ir_instruction { public: ir_function_signature(const glsl_type *return_type); - virtual ir_function_signature *clone(struct hash_table *ht) const; + virtual ir_function_signature *clone(void *mem_ctx, + struct hash_table *ht) const; virtual void accept(ir_visitor *v) { @@ -344,7 +403,7 @@ public: unsigned is_defined:1; /** Whether or not this function signature is a built-in. */ - unsigned is_built_in:1; + unsigned is_builtin:1; /** Body of instructions in the function. */ struct exec_list body; @@ -366,7 +425,7 @@ class ir_function : public ir_instruction { public: ir_function(const char *name); - virtual ir_function *clone(struct hash_table *ht) const; + virtual ir_function *clone(void *mem_ctx, struct hash_table *ht) const; virtual ir_function *as_function() { @@ -411,7 +470,9 @@ public: */ const char *name; -private: + /** Whether or not this function has a signature that isn't a built-in. */ + bool has_user_signature(); + /** * List of ir_function_signature for each overloaded function with this name. */ @@ -436,7 +497,7 @@ public: ir_type = ir_type_if; } - virtual ir_if *clone(struct hash_table *ht) const; + virtual ir_if *clone(void *mem_ctx, struct hash_table *ht) const; virtual ir_if *as_if() { @@ -463,12 +524,9 @@ public: */ class ir_loop : public ir_instruction { public: - ir_loop() : from(NULL), to(NULL), increment(NULL), counter(NULL) - { - ir_type = ir_type_loop; - } + ir_loop(); - virtual ir_loop *clone(struct hash_table *ht) const; + virtual ir_loop *clone(void *mem_ctx, struct hash_table *ht) const; virtual void accept(ir_visitor *v) { @@ -495,21 +553,51 @@ public: /** * \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; - ir_rvalue *to; + 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; /*@}*/ }; -class ir_assignment : public ir_rvalue { +class ir_assignment : public ir_instruction { public: ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition); - virtual ir_assignment *clone(struct hash_table *ht) const; + /** + * Construct an assignment with an explicit write mask + * + * \note + * Since a write mask is supplied, the LHS must already be a bare + * \c ir_dereference. The cannot be any swizzles in the LHS. + */ + ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_rvalue *condition, + unsigned write_mask); + + virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const; + + virtual ir_constant *constant_expression_value(); virtual void accept(ir_visitor *v) { @@ -523,10 +611,32 @@ public: return this; } + /** + * Get a whole variable written by an assignment + * + * If the LHS of the assignment writes a whole variable, the variable is + * returned. Otherwise \c NULL is returned. Examples of whole-variable + * assignment are: + * + * - Assigning to a scalar + * - Assigning to all components of a vector + * - Whole array (or matrix) assignment + * - Whole structure assignment + */ + ir_variable *whole_variable_written(); + + /** + * Set the LHS of an assignment + */ + void set_lhs(ir_rvalue *lhs); + /** * Left-hand side of the assignment. + * + * This should be treated as read only. If you need to set the LHS of an + * assignment, use \c ir_assignment::set_lhs. */ - ir_rvalue *lhs; + ir_dereference *lhs; /** * Value being assigned @@ -537,6 +647,24 @@ public: * Optional condition for the assignment. */ ir_rvalue *condition; + + + /** + * Component mask written + * + * For non-vector types in the LHS, this field will be zero. For vector + * types, a bit will be set for each component that is written. Note that + * for \c vec2 and \c vec3 types only the lower bits will ever be set. + * + * A partially-set write mask means that each enabled channel gets + * the value from a consecutive channel of the rhs. For example, + * to write just .xyw of gl_FrontColor with color: + * + * (assign (constant bool (1)) (xyw) + * (var_ref gl_FragColor) + * (swiz xyw (var_ref color))) + */ + unsigned write_mask:4; }; /* Update ir_expression::num_operands() and operator_strs when @@ -551,8 +679,8 @@ enum ir_expression_operation { ir_unop_rcp, ir_unop_rsq, ir_unop_sqrt, - ir_unop_exp, - ir_unop_log, + ir_unop_exp, /**< Log base e on gentype */ + ir_unop_log, /**< Natural log on gentype */ ir_unop_exp2, ir_unop_log2, ir_unop_f2i, /**< Float-to-integer conversion. */ @@ -562,6 +690,7 @@ enum ir_expression_operation { ir_unop_i2b, /**< int-to-boolean conversion */ ir_unop_b2i, /**< Boolean-to-int conversion */ ir_unop_u2f, /**< Unsigned-to-float conversion. */ + ir_unop_any, /** * \name Unary floating-point rounding operations. @@ -571,6 +700,7 @@ enum ir_expression_operation { ir_unop_ceil, ir_unop_floor, ir_unop_fract, + ir_unop_round_even, /*@}*/ /** @@ -589,6 +719,8 @@ enum ir_expression_operation { ir_unop_dFdy, /*@}*/ + ir_unop_noise, + ir_binop_add, ir_binop_sub, ir_binop_mul, @@ -605,7 +737,8 @@ enum ir_expression_operation { ir_binop_mod, /** - * \name Binary comparison operators + * \name Binary comparison operators which return a boolean vector. + * The type of both operands must be equal. */ /*@{*/ ir_binop_less, @@ -614,6 +747,16 @@ enum ir_expression_operation { ir_binop_gequal, ir_binop_equal, ir_binop_nequal, + /** + * Returns single boolean for whether all components of operands[0] + * equal the components of operands[1]. + */ + ir_binop_all_equal, + /** + * Returns single boolean for whether any component of operands[0] + * is not equal to the corresponding component of operands[1]. + */ + ir_binop_any_nequal, /*@}*/ /** @@ -649,9 +792,24 @@ public: return this; } - virtual ir_expression *clone(struct hash_table *ht) const; + virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const; + + /** + * Attempt to constant-fold the expression + * + * If the expression cannot be constant folded, this method will return + * \c NULL. + */ + virtual ir_constant *constant_expression_value(); + /** + * Determine the number of operands used by an expression + */ static unsigned int get_num_operands(ir_expression_operation); + + /** + * Determine the number of operands used by an expression + */ unsigned int get_num_operands() const { return get_num_operands(operation); @@ -662,6 +820,12 @@ public: */ const char *operator_string(); + /** + * Return a string representing this expression's operator. + */ + static const char *operator_string(ir_expression_operation); + + /** * Do a reverse-lookup to translate the given string into an operator. */ @@ -693,7 +857,9 @@ public: actual_parameters->move_nodes_to(& this->actual_parameters); } - virtual ir_call *clone(struct hash_table *ht) const; + virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const; + + virtual ir_constant *constant_expression_value(); virtual ir_call *as_call() { @@ -730,6 +896,9 @@ public: return callee->function_name(); } + /** + * Get the function signature bound to this function call + */ ir_function_signature *get_callee() { return callee; @@ -788,7 +957,7 @@ public: this->ir_type = ir_type_return; } - virtual ir_return *clone(struct hash_table *) const; + virtual ir_return *clone(void *mem_ctx, struct hash_table *) const; virtual ir_return *as_return() { @@ -833,7 +1002,7 @@ public: this->loop = loop; } - virtual ir_loop_jump *clone(struct hash_table *) const; + virtual ir_loop_jump *clone(void *mem_ctx, struct hash_table *) const; virtual void accept(ir_visitor *v) { @@ -872,10 +1041,11 @@ public: ir_discard(ir_rvalue *cond) { + this->ir_type = ir_type_discard; this->condition = cond; } - virtual ir_discard *clone(struct hash_table *ht) const; + virtual ir_discard *clone(void *mem_ctx, struct hash_table *ht) const; virtual void accept(ir_visitor *v) { @@ -893,11 +1063,11 @@ public: * Texture sampling opcodes used in ir_texture */ enum ir_texture_opcode { - ir_tex, /* Regular texture look-up */ - ir_txb, /* Texture look-up with LOD bias */ - ir_txl, /* Texture look-up with explicit LOD */ - ir_txd, /* Texture look-up with partial derivatvies */ - ir_txf /* Texel fetch with explicit LOD */ + ir_tex, /**< Regular texture look-up */ + ir_txb, /**< Texture look-up with LOD bias */ + ir_txl, /**< Texture look-up with explicit LOD */ + ir_txd, /**< Texture look-up with partial derivatvies */ + ir_txf /**< Texel fetch with explicit LOD */ }; @@ -927,7 +1097,9 @@ public: this->ir_type = ir_type_texture; } - virtual ir_texture *clone(struct hash_table *) const; + virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const; + + virtual ir_constant *constant_expression_value(); virtual void accept(ir_visitor *v) { @@ -1017,7 +1189,9 @@ public: ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask); - virtual ir_swizzle *clone(struct hash_table *) const; + virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const; + + virtual ir_constant *constant_expression_value(); virtual ir_swizzle *as_swizzle() { @@ -1061,7 +1235,7 @@ private: class ir_dereference : public ir_rvalue { public: - virtual ir_dereference *clone(struct hash_table *) const = 0; + virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0; virtual ir_dereference *as_dereference() { @@ -1081,7 +1255,10 @@ class ir_dereference_variable : public ir_dereference { public: ir_dereference_variable(ir_variable *var); - virtual ir_dereference_variable *clone(struct hash_table *) const; + virtual ir_dereference_variable *clone(void *mem_ctx, + struct hash_table *) const; + + virtual ir_constant *constant_expression_value(); virtual ir_dereference_variable *as_dereference_variable() { @@ -1127,7 +1304,10 @@ public: ir_dereference_array(ir_variable *var, ir_rvalue *array_index); - virtual ir_dereference_array *clone(struct hash_table *) const; + virtual ir_dereference_array *clone(void *mem_ctx, + struct hash_table *) const; + + virtual ir_constant *constant_expression_value(); virtual ir_dereference_array *as_dereference_array() { @@ -1163,7 +1343,10 @@ public: ir_dereference_record(ir_variable *var, const char *field); - virtual ir_dereference_record *clone(struct hash_table *) const; + virtual ir_dereference_record *clone(void *mem_ctx, + struct hash_table *) const; + + virtual ir_constant *constant_expression_value(); /** * Get the variable that is ultimately referenced by an r-value @@ -1221,7 +1404,14 @@ public: */ ir_constant(const ir_constant *c, unsigned i); - virtual ir_constant *clone(struct hash_table *) const; + /** + * Return a new ir_constant of the specified type containing all zeros. + */ + static ir_constant *zero(void *mem_ctx, const glsl_type *type); + + virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const; + + virtual ir_constant *constant_expression_value(); virtual ir_constant *as_constant() { @@ -1249,6 +1439,8 @@ public: unsigned get_uint_component(unsigned i) const; /*@}*/ + ir_constant *get_array_element(unsigned i) const; + ir_constant *get_record_field(const char *name); /** @@ -1265,6 +1457,10 @@ public: */ union ir_constant_data value; + /* Array elements */ + ir_constant **array_elements; + + /* Structure fields */ exec_list components; private: @@ -1274,9 +1470,17 @@ private: ir_constant(void); }; +/*@}*/ + +/** + * Apply a visitor to each IR node in a list + */ void visit_exec_list(exec_list *list, ir_visitor *visitor); +/** + * Validate invariants on each IR node in a list + */ void validate_ir_tree(exec_list *instructions); /** @@ -1286,7 +1490,7 @@ void validate_ir_tree(exec_list *instructions); * \param out List to hold the cloned instructions */ void -clone_ir_list(exec_list *out, const exec_list *in); +clone_ir_list(void *mem_ctx, exec_list *out, const exec_list *in); extern void _mesa_glsl_initialize_variables(exec_list *instructions, @@ -1296,4 +1500,22 @@ extern void _mesa_glsl_initialize_functions(exec_list *instructions, struct _mesa_glsl_parse_state *state); +extern void +_mesa_glsl_release_functions(void); + +extern void +reparent_ir(exec_list *list, void *mem_ctx); + +struct glsl_symbol_table; + +extern void +import_prototypes(const exec_list *source, exec_list *dest, + struct glsl_symbol_table *symbols, void *mem_ctx); + +extern bool +ir_has_call(ir_instruction *ir); + +extern void +do_set_program_inouts(exec_list *instructions, struct gl_program *prog); + #endif /* IR_H */