* DEALINGS IN THE SOFTWARE.
*/
-#pragma once
#ifndef IR_H
#define IR_H
#include <stdlib.h>
#include "util/ralloc.h"
+#include "util/format/u_format.h"
#include "compiler/glsl_types.h"
#include "list.h"
#include "ir_visitor.h"
#include "ir_hierarchical_visitor.h"
-#include "main/mtypes.h"
#ifdef __cplusplus
ir_type_loop_jump,
ir_type_return,
ir_type_discard,
+ ir_type_demote,
ir_type_emit_vertex,
ir_type_end_primitive,
ir_type_barrier,
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;
}
* \sa ir_variable::state_slots
*/
struct ir_state_slot {
- int tokens[5];
+ gl_state_index16 tokens[STATE_LENGTH];
int swizzle;
};
*
* 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.
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.
*/
this->interface_type = type;
if (this->is_interface_instance()) {
this->u.max_ifc_array_access =
- rzalloc_array(this, unsigned, type->length);
+ ralloc_array(this, int, type->length);
+ for (unsigned i = 0; i < type->length; i++) {
+ this->u.max_ifc_array_access[i] = -1;
+ }
}
}
* zero.
*/
for (unsigned i = 0; i < this->interface_type->length; i++)
- assert(this->u.max_ifc_array_access[i] == 0);
+ assert(this->u.max_ifc_array_access[i] == -1);
#endif
ralloc_free(this->u.max_ifc_array_access);
this->u.max_ifc_array_access = NULL;
return this->interface_type;
}
+ enum glsl_interface_packing get_interface_type_packing() const
+ {
+ return this->interface_type->get_interface_packing();
+ }
/**
* Get the max_ifc_array_access pointer
*
* A "set" function is not needed because the array is dynmically allocated
* as necessary.
*/
- inline unsigned *get_max_ifc_array_access()
+ inline int *get_max_ifc_array_access()
{
assert(this->data._num_state_slots == 0);
return this->u.max_ifc_array_access;
return this->u.state_slots;
}
+ inline bool is_interpolation_flat() const
+ {
+ return this->data.interpolation == INTERP_MODE_FLAT ||
+ this->type->contains_integer() ||
+ this->type->contains_double();
+ }
+
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;
}
/**
*/
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 {
/**
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;
* 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;
/**
* Interpolation mode for shader inputs / outputs
*
- * \sa ir_variable_interpolation
+ * \sa glsl_interp_mode
*/
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?
*
*/
unsigned explicit_binding:1;
+ /**
+ * Was an initial component explicitly set in the shader?
+ */
+ unsigned explicit_component:1;
+
/**
* Does this variable have an initializer?
*
*/
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?
*
*/
unsigned is_xfb_only:1;
+ /**
+ * Was a transform feedback buffer set in the shader?
+ */
+ unsigned explicit_xfb_buffer:1;
+
+ /**
+ * Was a transform feedback offset set in the shader?
+ */
+ unsigned explicit_xfb_offset:1;
+
+ /**
+ * Was a transform feedback stride set in the shader?
+ */
+ unsigned explicit_xfb_stride: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
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
*/
unsigned from_ssbo_unsized_array:1; /**< unsized array buffer variable. */
+ unsigned implicit_sized_array:1;
+
+ /**
+ * Whether this is a fragment shader output implicitly initialized with
+ * the previous contents of the specified render target at the
+ * framebuffer location corresponding to this shader invocation.
+ */
+ 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.
*/
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:
/**
*
* 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
/**
* 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;
/**
- * Atomic or block member offset.
+ * Atomic, transform feedback or block member offset.
*/
unsigned offset;
/**
* Highest element accessed with a constant expression array index
*
- * Not used for non-array variables.
+ * Not used for non-array variables. -1 is never accessed.
+ */
+ int max_array_access;
+
+ /**
+ * Transform feedback buffer.
+ */
+ unsigned xfb_buffer;
+
+ /**
+ * Transform feedback stride.
*/
- unsigned max_array_access;
+ unsigned xfb_stride;
/**
* Allow (only) ir_variable direct access private members.
* For variables whose type is not an interface block, this pointer is
* NULL.
*/
- unsigned *max_ifc_array_access;
+ int *max_ifc_array_access;
/**
* Built-in state that backs this uniform
*/
typedef bool (*builtin_available_predicate)(const _mesa_glsl_parse_state *);
+#define MAKE_INTRINSIC_FOR_TYPE(op, t) \
+ ir_intrinsic_generic_ ## op - ir_intrinsic_generic_load + ir_intrinsic_ ## t ## _ ## load
+
+#define MAP_INTRINSIC_TO_TYPE(i, t) \
+ ir_intrinsic_id(int(i) - int(ir_intrinsic_generic_load) + int(ir_intrinsic_ ## t ## _ ## load))
+
+enum ir_intrinsic_id {
+ ir_intrinsic_invalid = 0,
+
+ /**
+ * \name Generic intrinsics
+ *
+ * Each of these intrinsics has a specific version for shared variables and
+ * SSBOs.
+ */
+ /*@{*/
+ ir_intrinsic_generic_load,
+ ir_intrinsic_generic_store,
+ ir_intrinsic_generic_atomic_add,
+ ir_intrinsic_generic_atomic_and,
+ ir_intrinsic_generic_atomic_or,
+ ir_intrinsic_generic_atomic_xor,
+ ir_intrinsic_generic_atomic_min,
+ ir_intrinsic_generic_atomic_max,
+ ir_intrinsic_generic_atomic_exchange,
+ ir_intrinsic_generic_atomic_comp_swap,
+ /*@}*/
+
+ ir_intrinsic_atomic_counter_read,
+ ir_intrinsic_atomic_counter_increment,
+ ir_intrinsic_atomic_counter_predecrement,
+ ir_intrinsic_atomic_counter_add,
+ ir_intrinsic_atomic_counter_and,
+ ir_intrinsic_atomic_counter_or,
+ ir_intrinsic_atomic_counter_xor,
+ ir_intrinsic_atomic_counter_min,
+ ir_intrinsic_atomic_counter_max,
+ ir_intrinsic_atomic_counter_exchange,
+ ir_intrinsic_atomic_counter_comp_swap,
+
+ ir_intrinsic_image_load,
+ ir_intrinsic_image_store,
+ ir_intrinsic_image_atomic_add,
+ ir_intrinsic_image_atomic_and,
+ ir_intrinsic_image_atomic_or,
+ ir_intrinsic_image_atomic_xor,
+ ir_intrinsic_image_atomic_min,
+ ir_intrinsic_image_atomic_max,
+ ir_intrinsic_image_atomic_exchange,
+ 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),
+ ir_intrinsic_ssbo_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, ssbo),
+ ir_intrinsic_ssbo_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, ssbo),
+ ir_intrinsic_ssbo_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, ssbo),
+ ir_intrinsic_ssbo_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, ssbo),
+ ir_intrinsic_ssbo_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, ssbo),
+ ir_intrinsic_ssbo_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, ssbo),
+ ir_intrinsic_ssbo_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, ssbo),
+ ir_intrinsic_ssbo_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, ssbo),
+
+ ir_intrinsic_memory_barrier,
+ ir_intrinsic_shader_clock,
+ ir_intrinsic_group_memory_barrier,
+ ir_intrinsic_memory_barrier_atomic_counter,
+ 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),
+ ir_intrinsic_shared_atomic_add = MAKE_INTRINSIC_FOR_TYPE(atomic_add, shared),
+ ir_intrinsic_shared_atomic_and = MAKE_INTRINSIC_FOR_TYPE(atomic_and, shared),
+ ir_intrinsic_shared_atomic_or = MAKE_INTRINSIC_FOR_TYPE(atomic_or, shared),
+ ir_intrinsic_shared_atomic_xor = MAKE_INTRINSIC_FOR_TYPE(atomic_xor, shared),
+ ir_intrinsic_shared_atomic_min = MAKE_INTRINSIC_FOR_TYPE(atomic_min, shared),
+ ir_intrinsic_shared_atomic_max = MAKE_INTRINSIC_FOR_TYPE(atomic_max, shared),
+ ir_intrinsic_shared_atomic_exchange = MAKE_INTRINSIC_FOR_TYPE(atomic_exchange, shared),
+ ir_intrinsic_shared_atomic_comp_swap = MAKE_INTRINSIC_FOR_TYPE(atomic_comp_swap, shared),
+};
+
/*@{*/
/**
* The representation of a function instance; may be the full definition or
* 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
/**
* 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;
/** 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;
* Whether or not this function is an intrinsic to be implemented
* by the driver.
*/
- bool is_intrinsic;
+ inline bool is_intrinsic() const
+ {
+ return intrinsic_id != ir_intrinsic_invalid;
+ }
+
+ /** Indentifier for this intrinsic. */
+ enum ir_intrinsic_id intrinsic_id;
/** Whether or not a built-in is available for this shader. */
bool is_builtin_available(const _mesa_glsl_parse_state *state) const;
* 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);
};
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)
{
unsigned write_mask:4;
};
-/* Update ir_expression::get_num_operands() and operator_strs when
- * updating this list.
- */
-enum ir_expression_operation {
- ir_unop_bit_not,
- ir_unop_logic_not,
- ir_unop_neg,
- ir_unop_abs,
- ir_unop_sign,
- ir_unop_rcp,
- ir_unop_rsq,
- ir_unop_sqrt,
- 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. */
- ir_unop_f2u, /**< Float-to-unsigned conversion. */
- ir_unop_i2f, /**< Integer-to-float conversion. */
- ir_unop_f2b, /**< Float-to-boolean conversion */
- ir_unop_b2f, /**< Boolean-to-float conversion */
- ir_unop_i2b, /**< int-to-boolean conversion */
- ir_unop_b2i, /**< Boolean-to-int conversion */
- ir_unop_u2f, /**< Unsigned-to-float conversion. */
- ir_unop_i2u, /**< Integer-to-unsigned conversion. */
- ir_unop_u2i, /**< Unsigned-to-integer conversion. */
- ir_unop_d2f, /**< Double-to-float conversion. */
- ir_unop_f2d, /**< Float-to-double conversion. */
- ir_unop_d2i, /**< Double-to-integer conversion. */
- ir_unop_i2d, /**< Integer-to-double conversion. */
- ir_unop_d2u, /**< Double-to-unsigned conversion. */
- ir_unop_u2d, /**< Unsigned-to-double conversion. */
- ir_unop_d2b, /**< Double-to-boolean conversion. */
- ir_unop_bitcast_i2f, /**< Bit-identical int-to-float "conversion" */
- ir_unop_bitcast_f2i, /**< Bit-identical float-to-int "conversion" */
- ir_unop_bitcast_u2f, /**< Bit-identical uint-to-float "conversion" */
- ir_unop_bitcast_f2u, /**< Bit-identical float-to-uint "conversion" */
-
- /**
- * \name Unary floating-point rounding operations.
- */
- /*@{*/
- ir_unop_trunc,
- ir_unop_ceil,
- ir_unop_floor,
- ir_unop_fract,
- ir_unop_round_even,
- /*@}*/
-
- /**
- * \name Trigonometric operations.
- */
- /*@{*/
- ir_unop_sin,
- ir_unop_cos,
- /*@}*/
-
- /**
- * \name Partial derivatives.
- */
- /*@{*/
- ir_unop_dFdx,
- ir_unop_dFdx_coarse,
- ir_unop_dFdx_fine,
- ir_unop_dFdy,
- ir_unop_dFdy_coarse,
- ir_unop_dFdy_fine,
- /*@}*/
-
- /**
- * \name Floating point pack and unpack operations.
- */
- /*@{*/
- ir_unop_pack_snorm_2x16,
- ir_unop_pack_snorm_4x8,
- ir_unop_pack_unorm_2x16,
- ir_unop_pack_unorm_4x8,
- ir_unop_pack_half_2x16,
- ir_unop_unpack_snorm_2x16,
- ir_unop_unpack_snorm_4x8,
- ir_unop_unpack_unorm_2x16,
- ir_unop_unpack_unorm_4x8,
- ir_unop_unpack_half_2x16,
- /*@}*/
-
- /**
- * \name Bit operations, part of ARB_gpu_shader5.
- */
- /*@{*/
- ir_unop_bitfield_reverse,
- ir_unop_bit_count,
- ir_unop_find_msb,
- ir_unop_find_lsb,
- /*@}*/
+#include "ir_expression_operation.h"
- ir_unop_saturate,
-
- /**
- * \name Double packing, part of ARB_gpu_shader_fp64.
- */
- /*@{*/
- ir_unop_pack_double_2x32,
- ir_unop_unpack_double_2x32,
- /*@}*/
-
- ir_unop_frexp_sig,
- ir_unop_frexp_exp,
-
- ir_unop_noise,
-
- ir_unop_subroutine_to_int,
- /**
- * Interpolate fs input at centroid
- *
- * operand0 is the fs input.
- */
- ir_unop_interpolate_at_centroid,
-
- /**
- * Ask the driver for the total size of a buffer block.
- *
- * operand0 is the ir_constant buffer block index in the linked shader.
- */
- ir_unop_get_buffer_size,
-
- /**
- * Calculate length of an unsized array inside a buffer block.
- * This opcode is going to be replaced in a lowering pass inside
- * the linker.
- *
- * operand0 is the unsized array's ir_value for the calculation
- * of its length.
- */
- ir_unop_ssbo_unsized_array_length,
-
- /**
- * A sentinel marking the last of the unary operations.
- */
- ir_last_unop = ir_unop_ssbo_unsized_array_length,
-
- ir_binop_add,
- ir_binop_sub,
- 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:
- *
- * - mod(vecN, vecN)
- * - mod(vecN, float)
- *
- * Does not take integer types.
- */
- ir_binop_mod,
-
- /**
- * \name Binary comparison operators which return a boolean vector.
- * The type of both operands must be equal.
- */
- /*@{*/
- ir_binop_less,
- ir_binop_greater,
- ir_binop_lequal,
- 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,
- /*@}*/
-
- /**
- * \name Bit-wise binary operations.
- */
- /*@{*/
- ir_binop_lshift,
- ir_binop_rshift,
- ir_binop_bit_and,
- ir_binop_bit_xor,
- ir_binop_bit_or,
- /*@}*/
-
- ir_binop_logic_and,
- ir_binop_logic_xor,
- ir_binop_logic_or,
-
- ir_binop_dot,
- ir_binop_min,
- ir_binop_max,
-
- ir_binop_pow,
-
- /**
- * Load a value the size of a given GLSL type from a uniform block.
- *
- * operand0 is the ir_constant uniform block index in the linked shader.
- * operand1 is a byte offset within the uniform block.
- */
- ir_binop_ubo_load,
-
- /**
- * \name Multiplies a number by two to a power, part of ARB_gpu_shader5.
- */
- /*@{*/
- ir_binop_ldexp,
- /*@}*/
-
- /**
- * Extract a scalar from a vector
- *
- * operand0 is the vector
- * operand1 is the index of the field to read from operand0
- */
- ir_binop_vector_extract,
-
- /**
- * Interpolate fs input at offset
- *
- * operand0 is the fs input
- * operand1 is the offset from the pixel center
- */
- ir_binop_interpolate_at_offset,
-
- /**
- * Interpolate fs input at sample position
- *
- * operand0 is the fs input
- * operand1 is the sample ID
- */
- ir_binop_interpolate_at_sample,
-
- /**
- * A sentinel marking the last of the binary operations.
- */
- ir_last_binop = ir_binop_interpolate_at_sample,
-
- /**
- * \name Fused floating-point multiply-add, part of ARB_gpu_shader5.
- */
- /*@{*/
- ir_triop_fma,
- /*@}*/
-
- ir_triop_lrp,
-
- /**
- * \name Conditional Select
- *
- * A vector conditional select instruction (like ?:, but operating per-
- * component on vectors).
- *
- * \see lower_instructions_visitor::ldexp_to_arith
- */
- /*@{*/
- ir_triop_csel,
- /*@}*/
-
- ir_triop_bitfield_extract,
-
- /**
- * Generate a value with one field of a vector changed
- *
- * operand0 is the vector
- * operand1 is the value to write into the vector result
- * operand2 is the index in operand0 to be modified
- */
- ir_triop_vector_insert,
-
- /**
- * A sentinel marking the last of the ternary operations.
- */
- ir_last_triop = ir_triop_vector_insert,
-
- ir_quadop_bitfield_insert,
-
- ir_quadop_vector,
-
- /**
- * A sentinel marking the last of the ternary operations.
- */
- ir_last_quadop = ir_quadop_vector,
-
- /**
- * A sentinel marking the last of all operations.
- */
- ir_last_opcode = ir_quadop_vector
-};
+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:
* 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);
+ virtual ir_constant *constant_expression_value(void *mem_ctx,
+ struct hash_table *variable_context = NULL);
/**
- * 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
+ * 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.
operation == ir_quadop_vector;
}
- /**
- * Return a string representing this expression's operator.
- */
- 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.
*/
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;
};
{
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,
{
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)
{
/* 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
/*@}*/
+/**
+ * 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
*/
*
* Texel offset (0 or an expression)
* | Projection divisor
- * | | Shadow comparitor
+ * | | Shadow comparator
* | | |
* v v v
* (tex <type> <sampler> <coordinate> 0 1 ( ))
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)
{
* 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;
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.
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;
}
/**
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_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;
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;
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
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
ir_rvalue *record;
- const char *field;
+ int field_idx;
};
float f[16];
bool b[16];
double d[16];
+ uint64_t u64[16];
+ int64_t i64[16];
};
ir_constant(int i, 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
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)
{
double get_double_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.
*/
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:
/**
_mesa_glsl_initialize_variables(exec_list *instructions,
struct _mesa_glsl_parse_state *state);
-extern void
-_mesa_glsl_initialize_derived_variables(gl_shader *shader);
-
-extern void
-_mesa_glsl_initialize_functions(_mesa_glsl_parse_state *state);
-
-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(gl_shader *sh);
-
-extern void
-_mesa_glsl_release_functions(void);
-
-extern void
-_mesa_glsl_release_builtin_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,
gl_shader_stage shader_stage);
extern void
fprint_ir(FILE *f, const void *instruction);
+extern const struct gl_builtin_uniform_desc *
+_mesa_glsl_get_builtin_uniform_desc(const char *name);
+
#ifdef __cplusplus
} /* extern "C" */
#endif