X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Fir.cpp;h=54656f89933feda6745eee3f6f7701790cf60619;hb=a398168f7238b42c2fbecf940e09fc5ebef71f62;hp=720fcdcd883eddd5d0b61f76482805dd9fcf17ff;hpb=5f7e778fa1b1e969a1b15e3650dec49b0026ed08;p=mesa.git diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index 720fcdcd883..54656f89933 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,14 +243,21 @@ 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; case ir_unop_f2i: case ir_unop_b2i: case ir_unop_u2i: + case ir_unop_d2i: case ir_unop_bitcast_f2i: case ir_unop_bit_count: case ir_unop_find_msb: @@ -268,6 +269,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_b2f: case ir_unop_i2f: case ir_unop_u2f: + case ir_unop_d2f: case ir_unop_bitcast_i2f: case ir_unop_bitcast_u2f: this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, @@ -276,12 +278,21 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_f2b: case ir_unop_i2b: + case ir_unop_d2b: this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, op0->type->vector_elements, 1); break; + case ir_unop_f2d: + case ir_unop_i2d: + case ir_unop_u2d: + this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, + op0->type->vector_elements, 1); + break; + case ir_unop_i2u: case ir_unop_f2u: + case ir_unop_d2u: case ir_unop_bitcast_f2u: this->type = glsl_type::get_instance(GLSL_TYPE_UINT, op0->type->vector_elements, 1); @@ -293,6 +304,10 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) this->type = glsl_type::float_type; break; + case ir_unop_unpack_double_2x32: + this->type = glsl_type::uvec2_type; + break; + case ir_unop_any: this->type = glsl_type::bool_type; break; @@ -305,6 +320,10 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) this->type = glsl_type::uint_type; break; + case ir_unop_pack_double_2x32: + this->type = glsl_type::double_type; + break; + case ir_unop_unpack_snorm_2x16: case ir_unop_unpack_unorm_2x16: case ir_unop_unpack_half_2x16: @@ -316,6 +335,14 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) this->type = glsl_type::vec4_type; break; + case ir_unop_frexp_sig: + this->type = op0->type; + break; + case ir_unop_frexp_exp: + this->type = glsl_type::get_instance(GLSL_TYPE_INT, + op0->type->vector_elements, 1); + break; + default: assert(!"not reached: missing automatic type setup for ir_expression"); this->type = op0->type; @@ -324,9 +351,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; @@ -391,7 +417,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) break; case ir_binop_dot: - this->type = glsl_type::float_type; + this->type = op0->type->get_base_type(); break; case ir_binop_pack_half_2x16_split: @@ -405,6 +431,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) 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; @@ -420,9 +448,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; @@ -494,6 +521,13 @@ static const char *const operator_strs[] = { "u2f", "i2u", "u2i", + "d2f", + "f2d", + "d2i", + "i2d", + "d2u", + "u2d", + "d2b", "bitcast_i2f", "bitcast_f2i", "bitcast_u2f", @@ -509,7 +543,11 @@ static const char *const operator_strs[] = { "sin_reduced", "cos_reduced", "dFdx", + "dFdxCoarse", + "dFdxFine", "dFdy", + "dFdyCoarse", + "dFdyFine", "packSnorm2x16", "packSnorm4x8", "packUnorm2x16", @@ -526,7 +564,13 @@ static const char *const operator_strs[] = { "bit_count", "find_msb", "find_lsb", + "sat", + "packDouble2x32", + "unpackDouble2x32", + "frexp_sig", + "frexp_exp", "noise", + "interpolate_at_centroid", "+", "-", "*", @@ -560,6 +604,8 @@ static const char *const operator_strs[] = { "ubo_load", "ldexp", "vector_extract", + "interpolate_at_offset", + "interpolate_at_sample", "fma", "lrp", "csel", @@ -572,8 +618,8 @@ static const char *const operator_strs[] = { const char *ir_expression::operator_string(ir_expression_operation op) { - assert((unsigned int) op < Elements(operator_strs)); - assert(Elements(operator_strs) == (ir_quadop_vector + 1)); + assert((unsigned int) op < ARRAY_SIZE(operator_strs)); + assert(ARRAY_SIZE(operator_strs) == (ir_quadop_vector + 1)); return operator_strs[op]; } @@ -610,25 +656,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; @@ -638,10 +684,23 @@ ir_constant::ir_constant(float f, unsigned vector_elements) } } +ir_constant::ir_constant(double d, unsigned vector_elements) + : ir_rvalue(ir_type_constant) +{ + assert(vector_elements <= 4); + this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, vector_elements, 1); + for (unsigned i = 0; i < vector_elements; i++) { + this->value.d[i] = d; + } + for (unsigned i = vector_elements; i < 16; i++) { + this->value.d[i] = 0.0; + } +} + 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; @@ -652,9 +711,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; @@ -665,9 +724,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; @@ -678,8 +737,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) { @@ -687,13 +746,14 @@ ir_constant::ir_constant(const ir_constant *c, unsigned i) case GLSL_TYPE_INT: this->value.i[0] = c->value.i[i]; break; case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break; case GLSL_TYPE_BOOL: this->value.b[0] = c->value.b[i]; break; + case GLSL_TYPE_DOUBLE: this->value.d[0] = c->value.d[i]; break; default: assert(!"Should not get here."); break; } } 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() @@ -702,8 +762,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; @@ -739,9 +798,16 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) if (value->type->is_scalar() && value->next->is_tail_sentinel()) { if (type->is_matrix()) { /* Matrix - fill diagonal (rest is already set to 0) */ - assert(type->base_type == GLSL_TYPE_FLOAT); - for (unsigned i = 0; i < type->matrix_columns; i++) - this->value.f[i * type->vector_elements + i] = value->value.f[0]; + assert(type->base_type == GLSL_TYPE_FLOAT || + type->base_type == GLSL_TYPE_DOUBLE); + for (unsigned i = 0; i < type->matrix_columns; i++) { + if (type->base_type == GLSL_TYPE_FLOAT) + this->value.f[i * type->vector_elements + i] = + value->value.f[0]; + else + this->value.d[i * type->vector_elements + i] = + value->value.d[0]; + } } else { /* Vector or scalar - fill all components */ switch (type->base_type) { @@ -754,6 +820,10 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) for (unsigned i = 0; i < type->components(); i++) this->value.f[i] = value->value.f[0]; break; + case GLSL_TYPE_DOUBLE: + for (unsigned i = 0; i < type->components(); i++) + this->value.d[i] = value->value.d[0]; + break; case GLSL_TYPE_BOOL: for (unsigned i = 0; i < type->components(); i++) this->value.b[i] = value->value.b[0]; @@ -812,6 +882,9 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) case GLSL_TYPE_BOOL: this->value.b[i] = value->get_bool_component(j); break; + case GLSL_TYPE_DOUBLE: + this->value.d[i] = value->get_double_component(j); + break; default: /* FINISHME: What to do? Exceptions are not the answer. */ @@ -862,6 +935,7 @@ ir_constant::get_bool_component(unsigned i) const case GLSL_TYPE_INT: return this->value.i[i] != 0; case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0; case GLSL_TYPE_BOOL: return this->value.b[i]; + case GLSL_TYPE_DOUBLE: return this->value.d[i] != 0.0; default: assert(!"Should not get here."); break; } @@ -879,6 +953,25 @@ ir_constant::get_float_component(unsigned i) const case GLSL_TYPE_INT: return (float) this->value.i[i]; case GLSL_TYPE_FLOAT: return this->value.f[i]; case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0f : 0.0f; + case GLSL_TYPE_DOUBLE: return (float) this->value.d[i]; + default: assert(!"Should not get here."); break; + } + + /* Must return something to make the compiler happy. This is clearly an + * error case. + */ + return 0.0; +} + +double +ir_constant::get_double_component(unsigned i) const +{ + switch (this->type->base_type) { + case GLSL_TYPE_UINT: return (double) this->value.u[i]; + case GLSL_TYPE_INT: return (double) this->value.i[i]; + case GLSL_TYPE_FLOAT: return (double) this->value.f[i]; + case GLSL_TYPE_BOOL: return this->value.b[i] ? 1.0 : 0.0; + case GLSL_TYPE_DOUBLE: return this->value.d[i]; default: assert(!"Should not get here."); break; } @@ -896,6 +989,7 @@ ir_constant::get_int_component(unsigned i) const case GLSL_TYPE_INT: return this->value.i[i]; case GLSL_TYPE_FLOAT: return (int) this->value.f[i]; case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; + case GLSL_TYPE_DOUBLE: return (int) this->value.d[i]; default: assert(!"Should not get here."); break; } @@ -913,6 +1007,7 @@ ir_constant::get_uint_component(unsigned i) const case GLSL_TYPE_INT: return this->value.i[i]; case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i]; case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; + case GLSL_TYPE_DOUBLE: return (unsigned) this->value.d[i]; default: assert(!"Should not get here."); break; } @@ -977,6 +1072,7 @@ ir_constant::copy_offset(ir_constant *src, int offset) case GLSL_TYPE_UINT: case GLSL_TYPE_INT: case GLSL_TYPE_FLOAT: + case GLSL_TYPE_DOUBLE: case GLSL_TYPE_BOOL: { unsigned int size = src->type->components(); assert (size <= this->type->components() - offset); @@ -994,6 +1090,9 @@ ir_constant::copy_offset(ir_constant *src, int offset) case GLSL_TYPE_BOOL: value.b[i+offset] = src->get_bool_component(i); break; + case GLSL_TYPE_DOUBLE: + value.d[i+offset] = src->get_double_component(i); + break; default: // Shut up the compiler break; } @@ -1004,9 +1103,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; @@ -1052,6 +1149,9 @@ ir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask) case GLSL_TYPE_BOOL: value.b[i+offset] = src->get_bool_component(id++); break; + case GLSL_TYPE_DOUBLE: + value.d[i+offset] = src->get_double_component(id++); + break; default: assert(!"Should not get here."); return; @@ -1112,6 +1212,10 @@ ir_constant::has_value(const ir_constant *c) const if (this->value.b[i] != c->value.b[i]) return false; break; + case GLSL_TYPE_DOUBLE: + if (this->value.d[i] != c->value.d[i]) + return false; + break; default: assert(!"Should not get here."); return false; @@ -1149,6 +1253,10 @@ ir_constant::is_value(float f, int i) const if (this->value.b[c] != bool(i)) return false; break; + case GLSL_TYPE_DOUBLE: + if (this->value.d[c] != double(f)) + return false; + break; default: /* The only other base types are structures, arrays, and samplers. * Samplers cannot be constants, and the others should have been @@ -1181,59 +1289,25 @@ ir_constant::is_negative_one() const } 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; } 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; } @@ -1241,8 +1315,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); } @@ -1250,10 +1324,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)); } @@ -1280,10 +1354,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); @@ -1292,10 +1366,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); @@ -1311,20 +1385,20 @@ ir_dereference::is_lvalue() const 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() { @@ -1412,24 +1486,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, @@ -1526,18 +1598,44 @@ 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_ifc_array_access(NULL) + : ir_instruction(ir_type_variable) { - this->ir_type = ir_type_variable; this->type = type; - this->name = ralloc_strdup(this, name); + + 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->warn_extension = NULL; + this->data.binding = 0; + this->data.warn_extension_index = 0; this->constant_value = NULL; this->constant_initializer = NULL; this->data.origin_upper_left = false; @@ -1552,8 +1650,12 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name, this->data.mode = mode; this->data.interpolation = INTERP_QUALIFIER_NONE; this->data.max_array_access = 0; - this->data.atomic.buffer_index = 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) @@ -1596,13 +1698,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 < ARRAY_SIZE(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), is_intrinsic(false), + : 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; } @@ -1649,26 +1777,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(); + 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.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; } @@ -1686,8 +1813,8 @@ ir_function_signature::replace_parameters(exec_list *new_params) ir_function::ir_function(const char *name) + : ir_instruction(ir_type_function) { - this->ir_type = ir_type_function; this->name = ralloc_strdup(this, name); } @@ -1695,8 +1822,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; } @@ -1707,7 +1833,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; @@ -1717,8 +1843,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); } } @@ -1739,8 +1865,7 @@ steal_memory(ir_instruction *ir, void *new_ctx) */ if (constant != NULL) { if (constant->type->is_record()) { - foreach_list(n, &constant->components) { - ir_constant *field = (ir_constant *) n; + foreach_in_list(ir_constant, field, &constant->components) { steal_memory(field, ir); } } else if (constant->type->is_array()) { @@ -1757,8 +1882,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); } }