X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fir.cpp;h=fe5601a16c7c0dc0f48be31b84443903be83320d;hb=c4fab711ed5bbdb6b8421a1b980215032fc795b8;hp=ae67d6bddec9854e110af62ef41b717544c69529;hpb=7a4754d7d961b06652cc940c37c4f87a9111dc2a;p=mesa.git diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index ae67d6bddec..fe5601a16c7 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -23,10 +23,10 @@ #include #include "main/core.h" /* for MAX2 */ #include "ir.h" -#include "ir_visitor.h" #include "glsl_types.h" -ir_rvalue::ir_rvalue() +ir_rvalue::ir_rvalue(enum ir_node_type t) + : ir_instruction(t) { this->type = glsl_type::error_type; } @@ -46,11 +46,6 @@ bool ir_rvalue::is_negative_one() const return false; } -bool ir_rvalue::is_basis() const -{ - return false; -} - /** * Modify the swizzle make to move one component to another * @@ -153,8 +148,8 @@ ir_assignment::whole_variable_written() ir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_rvalue *condition, unsigned write_mask) + : ir_instruction(ir_type_assignment) { - this->ir_type = ir_type_assignment; this->condition = condition; this->rhs = rhs; this->lhs = lhs; @@ -173,8 +168,8 @@ ir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs, ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_rvalue *condition) + : ir_instruction(ir_type_assignment) { - this->ir_type = ir_type_assignment; this->condition = condition; this->rhs = rhs; @@ -198,8 +193,8 @@ ir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs, ir_expression::ir_expression(int op, const struct glsl_type *type, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2, ir_rvalue *op3) + : ir_rvalue(ir_type_expression) { - this->ir_type = ir_type_expression; this->type = type; this->operation = ir_expression_operation(op); this->operands[0] = op0; @@ -215,9 +210,8 @@ ir_expression::ir_expression(int op, const struct glsl_type *type, } ir_expression::ir_expression(int op, ir_rvalue *op0) + : ir_rvalue(ir_type_expression) { - this->ir_type = ir_type_expression; - this->operation = ir_expression_operation(op); this->operands[0] = op0; this->operands[1] = NULL; @@ -249,8 +243,14 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_sin_reduced: case ir_unop_cos_reduced: case ir_unop_dFdx: + case ir_unop_dFdx_coarse: + case ir_unop_dFdx_fine: case ir_unop_dFdy: + case ir_unop_dFdy_coarse: + case ir_unop_dFdy_fine: case ir_unop_bitfield_reverse: + case ir_unop_interpolate_at_centroid: + case ir_unop_saturate: this->type = op0->type; break; @@ -324,9 +324,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) } ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) + : ir_rvalue(ir_type_expression) { - this->ir_type = ir_type_expression; - this->operation = ir_expression_operation(op); this->operands[0] = op0; this->operands[1] = op1; @@ -398,10 +397,15 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) this->type = glsl_type::uint_type; break; + case ir_binop_imul_high: + case ir_binop_carry: + case ir_binop_borrow: case ir_binop_lshift: case ir_binop_rshift: case ir_binop_bfm: case ir_binop_ldexp: + case ir_binop_interpolate_at_offset: + case ir_binop_interpolate_at_sample: this->type = op0->type; break; @@ -417,9 +421,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2) + : ir_rvalue(ir_type_expression) { - this->ir_type = ir_type_expression; - this->operation = ir_expression_operation(op); this->operands[0] = op0; this->operands[1] = op1; @@ -506,7 +509,11 @@ static const char *const operator_strs[] = { "sin_reduced", "cos_reduced", "dFdx", + "dFdxCoarse", + "dFdxFine", "dFdy", + "dFdyCoarse", + "dFdyFine", "packSnorm2x16", "packSnorm4x8", "packUnorm2x16", @@ -523,11 +530,16 @@ static const char *const operator_strs[] = { "bit_count", "find_msb", "find_lsb", + "sat", "noise", + "interpolate_at_centroid", "+", "-", "*", + "imul_high", "/", + "carry", + "borrow", "%", "<", ">", @@ -554,6 +566,8 @@ static const char *const operator_strs[] = { "ubo_load", "ldexp", "vector_extract", + "interpolate_at_offset", + "interpolate_at_sample", "fma", "lrp", "csel", @@ -604,25 +618,25 @@ ir_expression::get_operator(const char *str) } ir_constant::ir_constant() + : ir_rvalue(ir_type_constant) { - this->ir_type = ir_type_constant; } ir_constant::ir_constant(const struct glsl_type *type, const ir_constant_data *data) + : ir_rvalue(ir_type_constant) { assert((type->base_type >= GLSL_TYPE_UINT) && (type->base_type <= GLSL_TYPE_BOOL)); - this->ir_type = ir_type_constant; this->type = type; memcpy(& this->value, data, sizeof(this->value)); } ir_constant::ir_constant(float f, unsigned vector_elements) + : ir_rvalue(ir_type_constant) { assert(vector_elements <= 4); - this->ir_type = ir_type_constant; this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, vector_elements, 1); for (unsigned i = 0; i < vector_elements; i++) { this->value.f[i] = f; @@ -633,9 +647,9 @@ ir_constant::ir_constant(float f, unsigned vector_elements) } ir_constant::ir_constant(unsigned int u, unsigned vector_elements) + : ir_rvalue(ir_type_constant) { assert(vector_elements <= 4); - this->ir_type = ir_type_constant; this->type = glsl_type::get_instance(GLSL_TYPE_UINT, vector_elements, 1); for (unsigned i = 0; i < vector_elements; i++) { this->value.u[i] = u; @@ -646,9 +660,9 @@ ir_constant::ir_constant(unsigned int u, unsigned vector_elements) } ir_constant::ir_constant(int integer, unsigned vector_elements) + : ir_rvalue(ir_type_constant) { assert(vector_elements <= 4); - this->ir_type = ir_type_constant; this->type = glsl_type::get_instance(GLSL_TYPE_INT, vector_elements, 1); for (unsigned i = 0; i < vector_elements; i++) { this->value.i[i] = integer; @@ -659,9 +673,9 @@ ir_constant::ir_constant(int integer, unsigned vector_elements) } ir_constant::ir_constant(bool b, unsigned vector_elements) + : ir_rvalue(ir_type_constant) { assert(vector_elements <= 4); - this->ir_type = ir_type_constant; this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, vector_elements, 1); for (unsigned i = 0; i < vector_elements; i++) { this->value.b[i] = b; @@ -672,8 +686,8 @@ ir_constant::ir_constant(bool b, unsigned vector_elements) } ir_constant::ir_constant(const ir_constant *c, unsigned i) + : ir_rvalue(ir_type_constant) { - this->ir_type = ir_type_constant; this->type = c->type->get_base_type(); switch (this->type->base_type) { @@ -686,8 +700,8 @@ ir_constant::ir_constant(const ir_constant *c, unsigned i) } ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) + : ir_rvalue(ir_type_constant) { - this->ir_type = ir_type_constant; this->type = type; assert(type->is_scalar() || type->is_vector() || type->is_matrix() @@ -696,8 +710,7 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) if (type->is_array()) { this->array_elements = ralloc_array(this, ir_constant *, type->length); unsigned i = 0; - foreach_list(node, value_list) { - ir_constant *value = (ir_constant *) node; + foreach_in_list(ir_constant, value, value_list) { assert(value->as_constant() != NULL); this->array_elements[i++] = value; @@ -998,9 +1011,7 @@ ir_constant::copy_offset(ir_constant *src, int offset) case GLSL_TYPE_STRUCT: { assert (src->type == this->type); this->components.make_empty(); - foreach_list(node, &src->components) { - ir_constant *const orig = (ir_constant *) node; - + foreach_in_list(ir_constant, orig, &src->components) { this->components.push_tail(orig->clone(this, NULL)); } break; @@ -1116,27 +1127,31 @@ ir_constant::has_value(const ir_constant *c) const } bool -ir_constant::is_zero() const +ir_constant::is_value(float f, int i) const { if (!this->type->is_scalar() && !this->type->is_vector()) return false; + /* Only accept boolean values for 0/1. */ + if (int(bool(i)) != i && this->type->is_boolean()) + return false; + for (unsigned c = 0; c < this->type->vector_elements; c++) { switch (this->type->base_type) { case GLSL_TYPE_FLOAT: - if (this->value.f[c] != 0.0) + if (this->value.f[c] != f) return false; break; case GLSL_TYPE_INT: - if (this->value.i[c] != 0) + if (this->value.i[c] != i) return false; break; case GLSL_TYPE_UINT: - if (this->value.u[c] != 0) + if (this->value.u[c] != unsigned(i)) return false; break; case GLSL_TYPE_BOOL: - if (this->value.b[c] != false) + if (this->value.b[c] != bool(i)) return false; break; default: @@ -1153,137 +1168,43 @@ ir_constant::is_zero() const } bool -ir_constant::is_one() const +ir_constant::is_zero() const { - if (!this->type->is_scalar() && !this->type->is_vector()) - return false; - - for (unsigned c = 0; c < this->type->vector_elements; c++) { - switch (this->type->base_type) { - case GLSL_TYPE_FLOAT: - if (this->value.f[c] != 1.0) - return false; - break; - case GLSL_TYPE_INT: - if (this->value.i[c] != 1) - return false; - break; - case GLSL_TYPE_UINT: - if (this->value.u[c] != 1) - return false; - break; - case GLSL_TYPE_BOOL: - if (this->value.b[c] != true) - return false; - break; - default: - /* The only other base types are structures, arrays, and samplers. - * Samplers cannot be constants, and the others should have been - * filtered out above. - */ - assert(!"Should not get here."); - return false; - } - } + return is_value(0.0, 0); +} - return true; +bool +ir_constant::is_one() const +{ + return is_value(1.0, 1); } bool ir_constant::is_negative_one() const { - if (!this->type->is_scalar() && !this->type->is_vector()) - return false; - - if (this->type->is_boolean()) - return false; - - for (unsigned c = 0; c < this->type->vector_elements; c++) { - switch (this->type->base_type) { - case GLSL_TYPE_FLOAT: - if (this->value.f[c] != -1.0) - return false; - break; - case GLSL_TYPE_INT: - if (this->value.i[c] != -1) - return false; - break; - case GLSL_TYPE_UINT: - if (int(this->value.u[c]) != -1) - return false; - break; - default: - /* The only other base types are structures, arrays, samplers, and - * booleans. Samplers cannot be constants, and the others should - * have been filtered out above. - */ - assert(!"Should not get here."); - return false; - } - } - - return true; + return is_value(-1.0, -1); } bool -ir_constant::is_basis() const +ir_constant::is_uint16_constant() const { - if (!this->type->is_scalar() && !this->type->is_vector()) + if (!type->is_integer()) return false; - if (this->type->is_boolean()) - return false; - - unsigned ones = 0; - for (unsigned c = 0; c < this->type->vector_elements; c++) { - switch (this->type->base_type) { - case GLSL_TYPE_FLOAT: - if (this->value.f[c] == 1.0) - ones++; - else if (this->value.f[c] != 0.0) - return false; - break; - case GLSL_TYPE_INT: - if (this->value.i[c] == 1) - ones++; - else if (this->value.i[c] != 0) - return false; - break; - case GLSL_TYPE_UINT: - if (int(this->value.u[c]) == 1) - ones++; - else if (int(this->value.u[c]) != 0) - return false; - break; - default: - /* The only other base types are structures, arrays, samplers, and - * booleans. Samplers cannot be constants, and the others should - * have been filtered out above. - */ - assert(!"Should not get here."); - return false; - } - } - - return ones == 1; + return value.u[0] < (1 << 16); } ir_loop::ir_loop() + : ir_instruction(ir_type_loop) { - this->ir_type = ir_type_loop; - this->cmp = ir_unop_neg; - this->from = NULL; - this->to = NULL; - this->increment = NULL; - this->counter = NULL; } ir_dereference_variable::ir_dereference_variable(ir_variable *var) + : ir_dereference(ir_type_dereference_variable) { assert(var != NULL); - this->ir_type = ir_type_dereference_variable; this->var = var; this->type = var->type; } @@ -1291,8 +1212,8 @@ ir_dereference_variable::ir_dereference_variable(ir_variable *var) ir_dereference_array::ir_dereference_array(ir_rvalue *value, ir_rvalue *array_index) + : ir_dereference(ir_type_dereference_array) { - this->ir_type = ir_type_dereference_array; this->array_index = array_index; this->set_array(value); } @@ -1300,10 +1221,10 @@ ir_dereference_array::ir_dereference_array(ir_rvalue *value, ir_dereference_array::ir_dereference_array(ir_variable *var, ir_rvalue *array_index) + : ir_dereference(ir_type_dereference_array) { void *ctx = ralloc_parent(var); - this->ir_type = ir_type_dereference_array; this->array_index = array_index; this->set_array(new(ctx) ir_dereference_variable(var)); } @@ -1330,10 +1251,10 @@ ir_dereference_array::set_array(ir_rvalue *value) ir_dereference_record::ir_dereference_record(ir_rvalue *value, const char *field) + : ir_dereference(ir_type_dereference_record) { assert(value != NULL); - this->ir_type = ir_type_dereference_record; this->record = value; this->field = ralloc_strdup(this, field); this->type = this->record->type->field_type(field); @@ -1342,10 +1263,10 @@ ir_dereference_record::ir_dereference_record(ir_rvalue *value, ir_dereference_record::ir_dereference_record(ir_variable *var, const char *field) + : ir_dereference(ir_type_dereference_record) { void *ctx = ralloc_parent(var); - this->ir_type = ir_type_dereference_record; this->record = new(ctx) ir_dereference_variable(var); this->field = ralloc_strdup(this, field); this->type = this->record->type->field_type(field); @@ -1358,23 +1279,23 @@ ir_dereference::is_lvalue() const /* Every l-value derference chain eventually ends in a variable. */ - if ((var == NULL) || var->read_only) + if ((var == NULL) || var->data.read_only) return false; - /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec: + /* From section 4.1.7 of the GLSL 4.40 spec: * - * "Samplers cannot be treated as l-values; hence cannot be used - * as out or inout function parameters, nor can they be - * assigned into." + * "Opaque variables cannot be treated as l-values; hence cannot + * be used as out or inout function parameters, nor can they be + * assigned into." */ - if (this->type->contains_sampler()) + if (this->type->contains_opaque()) return false; return true; } -static const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod", "tg4", "query_levels" }; +static const char * const tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod", "tg4", "query_levels" }; const char *ir_texture::opcode_string() { @@ -1462,24 +1383,22 @@ ir_swizzle::init_mask(const unsigned *comp, unsigned count) ir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z, unsigned w, unsigned count) - : val(val) + : ir_rvalue(ir_type_swizzle), val(val) { const unsigned components[4] = { x, y, z, w }; - this->ir_type = ir_type_swizzle; this->init_mask(components, count); } ir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp, unsigned count) - : val(val) + : ir_rvalue(ir_type_swizzle), val(val) { - this->ir_type = ir_type_swizzle; this->init_mask(comp, count); } ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask) + : ir_rvalue(ir_type_swizzle) { - this->ir_type = ir_type_swizzle; this->val = val; this->mask = mask; this->type = glsl_type::get_instance(val->type->base_type, @@ -1576,35 +1495,81 @@ ir_swizzle::variable_referenced() const } +bool ir_variable::temporaries_allocate_names = false; + +const char ir_variable::tmp_name[] = "compiler_temp"; + ir_variable::ir_variable(const struct glsl_type *type, const char *name, ir_variable_mode mode) - : max_array_access(0), read_only(false), centroid(false), invariant(false), - mode(mode), interpolation(INTERP_QUALIFIER_NONE) + : ir_instruction(ir_type_variable) { - this->ir_type = ir_type_variable; this->type = type; - this->name = ralloc_strdup(this, name); - this->explicit_location = false; - this->has_initializer = false; - this->location = -1; - this->location_frac = 0; - this->warn_extension = NULL; + + if (mode == ir_var_temporary && !ir_variable::temporaries_allocate_names) + name = NULL; + + /* The ir_variable clone method may call this constructor with name set to + * tmp_name. + */ + assert(name != NULL + || mode == ir_var_temporary + || mode == ir_var_function_in + || mode == ir_var_function_out + || mode == ir_var_function_inout); + assert(name != ir_variable::tmp_name + || mode == ir_var_temporary); + if (mode == ir_var_temporary + && (name == NULL || name == ir_variable::tmp_name)) { + this->name = ir_variable::tmp_name; + } else { + this->name = ralloc_strdup(this, name); + } + + this->u.max_ifc_array_access = NULL; + + this->data.explicit_location = false; + this->data.has_initializer = false; + this->data.location = -1; + this->data.location_frac = 0; + this->data.binding = 0; + this->data.warn_extension_index = 0; this->constant_value = NULL; this->constant_initializer = NULL; - this->origin_upper_left = false; - this->pixel_center_integer = false; - this->depth_layout = ir_depth_layout_none; - this->used = false; - - if (type && type->base_type == GLSL_TYPE_SAMPLER) - this->read_only = true; + this->data.origin_upper_left = false; + this->data.pixel_center_integer = false; + this->data.depth_layout = ir_depth_layout_none; + this->data.used = false; + this->data.read_only = false; + this->data.centroid = false; + this->data.sample = false; + this->data.invariant = false; + this->data.how_declared = ir_var_declared_normally; + this->data.mode = mode; + this->data.interpolation = INTERP_QUALIFIER_NONE; + this->data.max_array_access = 0; + this->data.atomic.offset = 0; + this->data.image_read_only = false; + this->data.image_write_only = false; + this->data.image_coherent = false; + this->data.image_volatile = false; + this->data.image_restrict = false; + + if (type != NULL) { + if (type->base_type == GLSL_TYPE_SAMPLER) + this->data.read_only = true; + + if (type->is_interface()) + this->init_interface_type(type); + else if (type->is_array() && type->fields.array->is_interface()) + this->init_interface_type(type->fields.array); + } } const char * -ir_variable::interpolation_string() const +interpolation_string(unsigned interpolation) { - switch (this->interpolation) { + switch (interpolation) { case INTERP_QUALIFIER_NONE: return "no"; case INTERP_QUALIFIER_SMOOTH: return "smooth"; case INTERP_QUALIFIER_FLAT: return "flat"; @@ -1619,9 +1584,9 @@ ir_variable::interpolation_string() const glsl_interp_qualifier ir_variable::determine_interpolation_mode(bool flat_shade) { - if (this->interpolation != INTERP_QUALIFIER_NONE) - return (glsl_interp_qualifier) this->interpolation; - int location = this->location; + if (this->data.interpolation != INTERP_QUALIFIER_NONE) + return (glsl_interp_qualifier) this->data.interpolation; + int location = this->data.location; bool is_gl_Color = location == VARYING_SLOT_COL0 || location == VARYING_SLOT_COL1; if (flat_shade && is_gl_Color) @@ -1630,13 +1595,39 @@ ir_variable::determine_interpolation_mode(bool flat_shade) return INTERP_QUALIFIER_SMOOTH; } +const char *const ir_variable::warn_extension_table[] = { + "", + "GL_ARB_shader_stencil_export", + "GL_AMD_shader_stencil_export", +}; + +void +ir_variable::enable_extension_warning(const char *extension) +{ + for (unsigned i = 0; i < Elements(warn_extension_table); i++) { + if (strcmp(warn_extension_table[i], extension) == 0) { + this->data.warn_extension_index = i; + return; + } + } + + assert(!"Should not get here."); + this->data.warn_extension_index = 0; +} + +const char * +ir_variable::get_extension_warning() const +{ + return this->data.warn_extension_index == 0 + ? NULL : warn_extension_table[this->data.warn_extension_index]; +} ir_function_signature::ir_function_signature(const glsl_type *return_type, builtin_available_predicate b) - : return_type(return_type), is_defined(false), builtin_avail(b), - _function(NULL) + : ir_instruction(ir_type_function_signature), + return_type(return_type), is_defined(false), is_intrinsic(false), + builtin_avail(b), _function(NULL) { - this->ir_type = ir_type_function_signature; this->origin = NULL; } @@ -1683,25 +1674,25 @@ modes_match(unsigned a, unsigned b) const char * ir_function_signature::qualifiers_match(exec_list *params) { - exec_list_iterator iter_a = parameters.iterator(); - exec_list_iterator iter_b = params->iterator(); - /* check that the qualifiers match. */ - while (iter_a.has_next()) { - ir_variable *a = (ir_variable *)iter_a.get(); - ir_variable *b = (ir_variable *)iter_b.get(); - - if (a->read_only != b->read_only || - !modes_match(a->mode, b->mode) || - a->interpolation != b->interpolation || - a->centroid != b->centroid) { + foreach_two_lists(a_node, &this->parameters, b_node, params) { + ir_variable *a = (ir_variable *) a_node; + ir_variable *b = (ir_variable *) b_node; + + if (a->data.read_only != b->data.read_only || + !modes_match(a->data.mode, b->data.mode) || + a->data.interpolation != b->data.interpolation || + a->data.centroid != b->data.centroid || + a->data.sample != b->data.sample || + a->data.image_read_only != b->data.image_read_only || + a->data.image_write_only != b->data.image_write_only || + a->data.image_coherent != b->data.image_coherent || + a->data.image_volatile != b->data.image_volatile || + a->data.image_restrict != b->data.image_restrict) { /* parameter a's qualifiers don't match */ return a->name; } - - iter_a.next(); - iter_b.next(); } return NULL; } @@ -1714,19 +1705,13 @@ ir_function_signature::replace_parameters(exec_list *new_params) * parameter information comes from the function prototype, it may either * specify incorrect parameter names or not have names at all. */ - foreach_iter(exec_list_iterator, iter, parameters) { - assert(((ir_instruction *) iter.get())->as_variable() != NULL); - - iter.remove(); - } - new_params->move_nodes_to(¶meters); } ir_function::ir_function(const char *name) + : ir_instruction(ir_type_function) { - this->ir_type = ir_type_function; this->name = ralloc_strdup(this, name); } @@ -1734,8 +1719,7 @@ ir_function::ir_function(const char *name) bool ir_function::has_user_signature() { - foreach_list(n, &this->signatures) { - ir_function_signature *const sig = (ir_function_signature *) n; + foreach_in_list(ir_function_signature, sig, &this->signatures) { if (!sig->is_builtin()) return true; } @@ -1746,7 +1730,7 @@ ir_function::has_user_signature() ir_rvalue * ir_rvalue::error_value(void *mem_ctx) { - ir_rvalue *v = new(mem_ctx) ir_rvalue; + ir_rvalue *v = new(mem_ctx) ir_rvalue(ir_type_unset); v->type = glsl_type::error_type; return v; @@ -1756,8 +1740,8 @@ ir_rvalue::error_value(void *mem_ctx) void visit_exec_list(exec_list *list, ir_visitor *visitor) { - foreach_iter(exec_list_iterator, iter, *list) { - ((ir_instruction *)iter.get())->accept(visitor); + foreach_in_list_safe(ir_instruction, node, list) { + node->accept(visitor); } } @@ -1778,8 +1762,7 @@ steal_memory(ir_instruction *ir, void *new_ctx) */ if (constant != NULL) { if (constant->type->is_record()) { - foreach_iter(exec_list_iterator, iter, constant->components) { - ir_constant *field = (ir_constant *)iter.get(); + foreach_in_list(ir_constant, field, &constant->components) { steal_memory(field, ir); } } else if (constant->type->is_array()) { @@ -1796,8 +1779,8 @@ steal_memory(ir_instruction *ir, void *new_ctx) void reparent_ir(exec_list *list, void *mem_ctx) { - foreach_list(node, list) { - visit_tree((ir_instruction *) node, steal_memory, mem_ctx); + foreach_in_list(ir_instruction, node, list) { + visit_tree(node, steal_memory, mem_ctx); } } @@ -1877,3 +1860,46 @@ vertices_per_prim(GLenum prim) return 3; } } + +/** + * Generate a string describing the mode of a variable + */ +const char * +mode_string(const ir_variable *var) +{ + switch (var->data.mode) { + case ir_var_auto: + return (var->data.read_only) ? "global constant" : "global variable"; + + case ir_var_uniform: + return "uniform"; + + case ir_var_shader_in: + return "shader input"; + + case ir_var_shader_out: + return "shader output"; + + case ir_var_function_in: + case ir_var_const_in: + return "function input"; + + case ir_var_function_out: + return "function output"; + + case ir_var_function_inout: + return "function inout"; + + case ir_var_system_value: + return "shader input"; + + case ir_var_temporary: + return "compiler temporary"; + + case ir_var_mode_count: + break; + } + + assert(!"Should not get here."); + return "invalid variable"; +}