#include <stdlib.h>
#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
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.
*/
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;
*/
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 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?
*/
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 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;
*/
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
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_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_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),
* 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;
* 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)
{
* 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.
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
*/
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)
{
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_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)
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;
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
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;
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);
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
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);
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];
+ uint16_t f16[16];
+ uint16_t u16[16];
+ int16_t i16[16];
uint64_t u64[16];
int64_t i64[16];
};
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);
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)
{
/*@{*/
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;
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(struct gl_context *ctx,
- gl_shader *shader);
-
extern void
reparent_ir(exec_list *list, void *mem_ctx);
extern void _mesa_print_ir(FILE *f, struct exec_list *instructions,
struct _mesa_glsl_parse_state *state);
+extern void
+ir_print_type(FILE *f, const struct glsl_type *t);
+
extern void
fprint_ir(FILE *f, const void *instruction);