X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fcompiler%2Fglsl%2Fir.cpp;h=1d1a56ae9a53714132d0cda4224ff86d1f72d9f2;hb=ed4020fabe7c5b9d5f152ece64a2b4bb9b73c2bc;hp=d69ab131199aa8d584f93958a5e41cb6d1473260;hpb=945c6887ab43a98a6e042841b2fb547aaef250e2;p=mesa.git diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp index d69ab131199..1d1a56ae9a5 100644 --- a/src/compiler/glsl/ir.cpp +++ b/src/compiler/glsl/ir.cpp @@ -21,9 +21,10 @@ * DEALINGS IN THE SOFTWARE. */ #include -#include "main/core.h" /* for MAX2 */ #include "ir.h" #include "compiler/glsl_types.h" +#include "glsl_parser_extras.h" + ir_rvalue::ir_rvalue(enum ir_node_type t) : ir_instruction(t) @@ -201,11 +202,16 @@ ir_expression::ir_expression(int op, const struct glsl_type *type, this->operands[1] = op1; this->operands[2] = op2; this->operands[3] = op3; + init_num_operands(); + #ifndef NDEBUG - int num_operands = get_num_operands(this->operation); - for (int i = num_operands; i < 4; i++) { + for (unsigned i = num_operands; i < 4; i++) { assert(this->operands[i] == NULL); } + + for (unsigned i = 0; i < num_operands; i++) { + assert(this->operands[i] != NULL); + } #endif } @@ -219,6 +225,9 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) this->operands[3] = NULL; assert(op <= ir_last_unop); + init_num_operands(); + assert(num_operands == 1); + assert(this->operands[0]); switch (this->operation) { case ir_unop_bit_not: @@ -261,6 +270,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_find_msb: case ir_unop_find_lsb: case ir_unop_subroutine_to_int: + case ir_unop_i642i: + case ir_unop_u642i: this->type = glsl_type::get_instance(GLSL_TYPE_INT, op0->type->vector_elements, 1); break; @@ -271,6 +282,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_d2f: case ir_unop_bitcast_i2f: case ir_unop_bitcast_u2f: + case ir_unop_i642f: + case ir_unop_u642f: this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, op0->type->vector_elements, 1); break; @@ -278,6 +291,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_f2b: case ir_unop_i2b: case ir_unop_d2b: + case ir_unop_i642b: this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, op0->type->vector_elements, 1); break; @@ -285,6 +299,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_f2d: case ir_unop_i2d: case ir_unop_u2d: + case ir_unop_i642d: + case ir_unop_u642d: this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, op0->type->vector_elements, 1); break; @@ -293,18 +309,43 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) case ir_unop_f2u: case ir_unop_d2u: case ir_unop_bitcast_f2u: + case ir_unop_i642u: + case ir_unop_u642u: this->type = glsl_type::get_instance(GLSL_TYPE_UINT, op0->type->vector_elements, 1); break; + case ir_unop_i2i64: + case ir_unop_u2i64: + case ir_unop_b2i64: + case ir_unop_f2i64: + case ir_unop_d2i64: + case ir_unop_u642i64: + this->type = glsl_type::get_instance(GLSL_TYPE_INT64, + op0->type->vector_elements, 1); + break; + + case ir_unop_i2u64: + case ir_unop_u2u64: + case ir_unop_f2u64: + case ir_unop_d2u64: + case ir_unop_i642u64: + this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, + op0->type->vector_elements, 1); + break; case ir_unop_noise: this->type = glsl_type::float_type; break; case ir_unop_unpack_double_2x32: + case ir_unop_unpack_uint_2x32: this->type = glsl_type::uvec2_type; break; + case ir_unop_unpack_int_2x32: + this->type = glsl_type::ivec2_type; + break; + case ir_unop_pack_snorm_2x16: case ir_unop_pack_snorm_4x8: case ir_unop_pack_unorm_2x16: @@ -317,6 +358,14 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) this->type = glsl_type::double_type; break; + case ir_unop_pack_int_2x32: + this->type = glsl_type::int64_t_type; + break; + + case ir_unop_pack_uint_2x32: + this->type = glsl_type::uint64_t_type; + break; + case ir_unop_unpack_snorm_2x16: case ir_unop_unpack_unorm_2x16: case ir_unop_unpack_half_2x16: @@ -328,6 +377,16 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) this->type = glsl_type::vec4_type; break; + case ir_unop_unpack_sampler_2x32: + case ir_unop_unpack_image_2x32: + this->type = glsl_type::uvec2_type; + break; + + case ir_unop_pack_sampler_2x32: + case ir_unop_pack_image_2x32: + this->type = op0->type; + break; + case ir_unop_frexp_sig: this->type = op0->type; break; @@ -341,6 +400,21 @@ ir_expression::ir_expression(int op, ir_rvalue *op0) this->type = glsl_type::int_type; break; + case ir_unop_bitcast_i642d: + case ir_unop_bitcast_u642d: + this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, + op0->type->vector_elements, 1); + break; + + case ir_unop_bitcast_d2i64: + this->type = glsl_type::get_instance(GLSL_TYPE_INT64, + op0->type->vector_elements, 1); + break; + case ir_unop_bitcast_d2u64: + this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, + op0->type->vector_elements, 1); + break; + default: assert(!"not reached: missing automatic type setup for ir_expression"); this->type = op0->type; @@ -358,6 +432,11 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) this->operands[3] = NULL; assert(op > ir_last_unop); + init_num_operands(); + assert(num_operands == 2); + for (unsigned i = 0; i < num_operands; i++) { + assert(this->operands[i] != NULL); + } switch (this->operation) { case ir_binop_all_equal: @@ -407,10 +486,8 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1) case ir_binop_equal: case ir_binop_nequal: - case ir_binop_lequal: case ir_binop_gequal: case ir_binop_less: - case ir_binop_greater: assert(op0->type == op1->type); this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, op0->type->vector_elements, 1); @@ -452,6 +529,11 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, this->operands[3] = NULL; assert(op > ir_last_binop && op <= ir_last_triop); + init_num_operands(); + assert(num_operands == 3); + for (unsigned i = 0; i < num_operands; i++) { + assert(this->operands[i] != NULL); + } switch (this->operation) { case ir_triop_fma: @@ -471,7 +553,11 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, } } -unsigned int +/** + * 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 ir_expression::get_num_operands(ir_expression_operation op) { assert(op <= ir_last_opcode); @@ -488,134 +574,10 @@ ir_expression::get_num_operands(ir_expression_operation op) if (op <= ir_last_quadop) return 4; - assert(false); - return 0; + unreachable("Could not calculate number of operands"); } -static const char *const operator_strs[] = { - "~", - "!", - "neg", - "abs", - "sign", - "rcp", - "rsq", - "sqrt", - "exp", - "log", - "exp2", - "log2", - "f2i", - "f2u", - "i2f", - "f2b", - "b2f", - "i2b", - "b2i", - "u2f", - "i2u", - "u2i", - "d2f", - "f2d", - "d2i", - "i2d", - "d2u", - "u2d", - "d2b", - "bitcast_i2f", - "bitcast_f2i", - "bitcast_u2f", - "bitcast_f2u", - "trunc", - "ceil", - "floor", - "fract", - "round_even", - "sin", - "cos", - "dFdx", - "dFdxCoarse", - "dFdxFine", - "dFdy", - "dFdyCoarse", - "dFdyFine", - "packSnorm2x16", - "packSnorm4x8", - "packUnorm2x16", - "packUnorm4x8", - "packHalf2x16", - "unpackSnorm2x16", - "unpackSnorm4x8", - "unpackUnorm2x16", - "unpackUnorm4x8", - "unpackHalf2x16", - "bitfield_reverse", - "bit_count", - "find_msb", - "find_lsb", - "sat", - "packDouble2x32", - "unpackDouble2x32", - "frexp_sig", - "frexp_exp", - "noise", - "subroutine_to_int", - "interpolate_at_centroid", - "get_buffer_size", - "ssbo_unsized_array_length", - "+", - "-", - "*", - "imul_high", - "/", - "carry", - "borrow", - "%", - "<", - ">", - "<=", - ">=", - "==", - "!=", - "all_equal", - "any_nequal", - "<<", - ">>", - "&", - "^", - "|", - "&&", - "^^", - "||", - "dot", - "min", - "max", - "pow", - "ubo_load", - "ldexp", - "vector_extract", - "interpolate_at_offset", - "interpolate_at_sample", - "fma", - "lrp", - "csel", - "bitfield_extract", - "vector_insert", - "bitfield_insert", - "vector", -}; - -const char *ir_expression::operator_string(ir_expression_operation op) -{ - assert((unsigned int) op < ARRAY_SIZE(operator_strs)); - assert(ARRAY_SIZE(operator_strs) == (ir_quadop_vector + 1)); - return operator_strs[op]; -} - -const char *ir_expression::operator_string() -{ - return operator_string(this->operation); -} +#include "ir_expression_operation_strings.h" const char* depth_layout_string(ir_depth_layout layout) @@ -636,9 +598,8 @@ depth_layout_string(ir_depth_layout layout) ir_expression_operation ir_expression::get_operator(const char *str) { - const int operator_count = sizeof(operator_strs) / sizeof(operator_strs[0]); - for (int op = 0; op < operator_count; op++) { - if (strcmp(str, operator_strs[op]) == 0) + for (int op = 0; op <= int(ir_last_opcode); op++) { + if (strcmp(str, ir_expression_operation_strings[op]) == 0) return (ir_expression_operation) op; } return (ir_expression_operation) -1; @@ -663,14 +624,17 @@ ir_expression::variable_referenced() const ir_constant::ir_constant() : ir_rvalue(ir_type_constant) { + this->const_elements = NULL; } ir_constant::ir_constant(const struct glsl_type *type, const ir_constant_data *data) : ir_rvalue(ir_type_constant) { + this->const_elements = NULL; + assert((type->base_type >= GLSL_TYPE_UINT) - && (type->base_type <= GLSL_TYPE_BOOL)); + && (type->base_type <= GLSL_TYPE_IMAGE)); this->type = type; memcpy(& this->value, data, sizeof(this->value)); @@ -728,6 +692,32 @@ ir_constant::ir_constant(int integer, unsigned vector_elements) } } +ir_constant::ir_constant(uint64_t u64, unsigned vector_elements) + : ir_rvalue(ir_type_constant) +{ + assert(vector_elements <= 4); + this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, vector_elements, 1); + for (unsigned i = 0; i < vector_elements; i++) { + this->value.u64[i] = u64; + } + for (unsigned i = vector_elements; i < 16; i++) { + this->value.u64[i] = 0; + } +} + +ir_constant::ir_constant(int64_t int64, unsigned vector_elements) + : ir_rvalue(ir_type_constant) +{ + assert(vector_elements <= 4); + this->type = glsl_type::get_instance(GLSL_TYPE_INT64, vector_elements, 1); + for (unsigned i = 0; i < vector_elements; i++) { + this->value.i64[i] = int64; + } + for (unsigned i = vector_elements; i < 16; i++) { + this->value.i64[i] = 0; + } +} + ir_constant::ir_constant(bool b, unsigned vector_elements) : ir_rvalue(ir_type_constant) { @@ -744,6 +734,7 @@ 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->const_elements = NULL; this->type = c->type->get_base_type(); switch (this->type->base_type) { @@ -759,33 +750,25 @@ 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->const_elements = NULL; this->type = type; assert(type->is_scalar() || type->is_vector() || type->is_matrix() || type->is_record() || type->is_array()); - if (type->is_array()) { - this->array_elements = ralloc_array(this, ir_constant *, type->length); - unsigned i = 0; - foreach_in_list(ir_constant, value, value_list) { - assert(value->as_constant() != NULL); - - this->array_elements[i++] = value; - } - return; - } - /* If the constant is a record, the types of each of the entries in * value_list must be a 1-for-1 match with the structure components. Each * entry must also be a constant. Just move the nodes from the value_list * to the list in the ir_constant. */ - /* FINISHME: Should there be some type checking and / or assertions here? */ - /* FINISHME: Should the new constant take ownership of the nodes from - * FINISHME: value_list, or should it make copies? - */ - if (type->is_record()) { - value_list->move_nodes_to(& this->components); + if (type->is_array() || type->is_record()) { + this->const_elements = ralloc_array(this, ir_constant *, type->length); + unsigned i = 0; + foreach_in_list(ir_constant, value, value_list) { + assert(value->as_constant() != NULL); + + this->const_elements[i++] = value; + } return; } @@ -793,7 +776,7 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) this->value.u[i] = 0; } - ir_constant *value = (ir_constant *) (value_list->head); + ir_constant *value = (ir_constant *) (value_list->get_head_raw()); /* Constructors with exactly one scalar argument are special for vectors * and matrices. For vectors, the scalar value is replicated to fill all @@ -803,10 +786,9 @@ 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 || - type->base_type == GLSL_TYPE_DOUBLE); + assert(type->is_float() || type->is_double()); for (unsigned i = 0; i < type->matrix_columns; i++) { - if (type->base_type == GLSL_TYPE_FLOAT) + if (type->is_float()) this->value.f[i * type->vector_elements + i] = value->value.f[0]; else @@ -829,10 +811,19 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) for (unsigned i = 0; i < type->components(); i++) this->value.d[i] = value->value.d[0]; break; + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: + for (unsigned i = 0; i < type->components(); i++) + this->value.u64[i] = value->value.u64[0]; + break; case GLSL_TYPE_BOOL: for (unsigned i = 0; i < type->components(); i++) this->value.b[i] = value->value.b[0]; break; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + this->value.u64[0] = value->value.u64[0]; + break; default: assert(!"Should not get here."); break; @@ -891,6 +882,12 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list) case GLSL_TYPE_DOUBLE: this->value.d[i] = value->get_double_component(j); break; + case GLSL_TYPE_UINT64: + this->value.u64[i] = value->get_uint64_component(j); + break; + case GLSL_TYPE_INT64: + this->value.i64[i] = value->get_int64_component(j); + break; default: /* FINISHME: What to do? Exceptions are not the answer. */ @@ -919,16 +916,18 @@ ir_constant::zero(void *mem_ctx, const glsl_type *type) memset(&c->value, 0, sizeof(c->value)); if (type->is_array()) { - c->array_elements = ralloc_array(c, ir_constant *, type->length); + c->const_elements = ralloc_array(c, ir_constant *, type->length); for (unsigned i = 0; i < type->length; i++) - c->array_elements[i] = ir_constant::zero(c, type->fields.array); + c->const_elements[i] = ir_constant::zero(c, type->fields.array); } if (type->is_record()) { + c->const_elements = ralloc_array(c, ir_constant *, type->length); + for (unsigned i = 0; i < type->length; i++) { - ir_constant *comp = ir_constant::zero(mem_ctx, type->fields.structure[i].type); - c->components.push_tail(comp); + c->const_elements[i] = + ir_constant::zero(mem_ctx, type->fields.structure[i].type); } } @@ -944,6 +943,10 @@ ir_constant::get_bool_component(unsigned i) const 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; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: return this->value.u64[i] != 0; + case GLSL_TYPE_INT64: return this->value.i64[i] != 0; default: assert(!"Should not get here."); break; } @@ -962,6 +965,10 @@ ir_constant::get_float_component(unsigned i) const 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]; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: return (float) this->value.u64[i]; + case GLSL_TYPE_INT64: return (float) this->value.i64[i]; default: assert(!"Should not get here."); break; } @@ -980,6 +987,10 @@ ir_constant::get_double_component(unsigned i) const 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]; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: return (double) this->value.u64[i]; + case GLSL_TYPE_INT64: return (double) this->value.i64[i]; default: assert(!"Should not get here."); break; } @@ -998,6 +1009,10 @@ ir_constant::get_int_component(unsigned i) const 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]; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: return (int) this->value.u64[i]; + case GLSL_TYPE_INT64: return (int) this->value.i64[i]; default: assert(!"Should not get here."); break; } @@ -1016,6 +1031,54 @@ ir_constant::get_uint_component(unsigned i) const 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]; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: return (unsigned) this->value.u64[i]; + case GLSL_TYPE_INT64: return (unsigned) this->value.i64[i]; + default: assert(!"Should not get here."); break; + } + + /* Must return something to make the compiler happy. This is clearly an + * error case. + */ + return 0; +} + +int64_t +ir_constant::get_int64_component(unsigned i) const +{ + switch (this->type->base_type) { + case GLSL_TYPE_UINT: return this->value.u[i]; + case GLSL_TYPE_INT: return this->value.i[i]; + case GLSL_TYPE_FLOAT: return (int64_t) this->value.f[i]; + case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; + case GLSL_TYPE_DOUBLE: return (int64_t) this->value.d[i]; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: return (int64_t) this->value.u64[i]; + case GLSL_TYPE_INT64: return this->value.i64[i]; + default: assert(!"Should not get here."); break; + } + + /* Must return something to make the compiler happy. This is clearly an + * error case. + */ + return 0; +} + +uint64_t +ir_constant::get_uint64_component(unsigned i) const +{ + switch (this->type->base_type) { + case GLSL_TYPE_UINT: return this->value.u[i]; + case GLSL_TYPE_INT: return this->value.i[i]; + case GLSL_TYPE_FLOAT: return (uint64_t) this->value.f[i]; + case GLSL_TYPE_BOOL: return this->value.b[i] ? 1 : 0; + case GLSL_TYPE_DOUBLE: return (uint64_t) this->value.d[i]; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: return this->value.u64[i]; + case GLSL_TYPE_INT64: return (uint64_t) this->value.i64[i]; default: assert(!"Should not get here."); break; } @@ -1045,32 +1108,16 @@ ir_constant::get_array_element(unsigned i) const else if (i >= this->type->length) i = this->type->length - 1; - return array_elements[i]; + return const_elements[i]; } ir_constant * -ir_constant::get_record_field(const char *name) +ir_constant::get_record_field(int idx) { - int idx = this->type->field_index(name); + assert(this->type->is_record()); + assert(idx >= 0 && (unsigned) idx < this->type->length); - if (idx < 0) - return NULL; - - if (this->components.is_empty()) - return NULL; - - exec_node *node = this->components.head; - for (int i = 0; i < idx; i++) { - node = node->next; - - /* If the end of the list is encountered before the element matching the - * requested field is found, return NULL. - */ - if (node->is_tail_sentinel()) - return NULL; - } - - return (ir_constant *) node; + return const_elements[idx]; } void @@ -1081,6 +1128,10 @@ ir_constant::copy_offset(ir_constant *src, int offset) case GLSL_TYPE_INT: case GLSL_TYPE_FLOAT: case GLSL_TYPE_DOUBLE: + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: + case GLSL_TYPE_INT64: case GLSL_TYPE_BOOL: { unsigned int size = src->type->components(); assert (size <= this->type->components() - offset); @@ -1101,6 +1152,14 @@ ir_constant::copy_offset(ir_constant *src, int offset) case GLSL_TYPE_DOUBLE: value.d[i+offset] = src->get_double_component(i); break; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: + value.u64[i+offset] = src->get_uint64_component(i); + break; + case GLSL_TYPE_INT64: + value.i64[i+offset] = src->get_int64_component(i); + break; default: // Shut up the compiler break; } @@ -1108,19 +1167,11 @@ ir_constant::copy_offset(ir_constant *src, int offset) break; } - case GLSL_TYPE_STRUCT: { - assert (src->type == this->type); - this->components.make_empty(); - foreach_in_list(ir_constant, orig, &src->components) { - this->components.push_tail(orig->clone(this, NULL)); - } - break; - } - + case GLSL_TYPE_STRUCT: case GLSL_TYPE_ARRAY: { assert (src->type == this->type); for (unsigned i = 0; i < this->type->length; i++) { - this->array_elements[i] = src->array_elements[i]->clone(this, NULL); + this->const_elements[i] = src->const_elements[i]->clone(this, NULL); } break; } @@ -1160,6 +1211,14 @@ ir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask) case GLSL_TYPE_DOUBLE: value.d[i+offset] = src->get_double_component(id++); break; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: + value.u64[i+offset] = src->get_uint64_component(id++); + break; + case GLSL_TYPE_INT64: + value.i64[i+offset] = src->get_int64_component(id++); + break; default: assert(!"Should not get here."); return; @@ -1174,31 +1233,11 @@ ir_constant::has_value(const ir_constant *c) const if (this->type != c->type) return false; - if (this->type->is_array()) { + if (this->type->is_array() || this->type->is_record()) { for (unsigned i = 0; i < this->type->length; i++) { - if (!this->array_elements[i]->has_value(c->array_elements[i])) - return false; - } - return true; - } - - if (this->type->base_type == GLSL_TYPE_STRUCT) { - const exec_node *a_node = this->components.head; - const exec_node *b_node = c->components.head; - - while (!a_node->is_tail_sentinel()) { - assert(!b_node->is_tail_sentinel()); - - const ir_constant *const a_field = (ir_constant *) a_node; - const ir_constant *const b_field = (ir_constant *) b_node; - - if (!a_field->has_value(b_field)) + if (!this->const_elements[i]->has_value(c->const_elements[i])) return false; - - a_node = a_node->next; - b_node = b_node->next; } - return true; } @@ -1224,6 +1263,16 @@ ir_constant::has_value(const ir_constant *c) const if (this->value.d[i] != c->value.d[i]) return false; break; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: + if (this->value.u64[i] != c->value.u64[i]) + return false; + break; + case GLSL_TYPE_INT64: + if (this->value.i64[i] != c->value.i64[i]) + return false; + break; default: assert(!"Should not get here."); return false; @@ -1265,6 +1314,16 @@ ir_constant::is_value(float f, int i) const if (this->value.d[c] != double(f)) return false; break; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_UINT64: + if (this->value.u64[c] != uint64_t(i)) + return false; + break; + case GLSL_TYPE_INT64: + if (this->value.i64[c] != i) + return false; + break; default: /* The only other base types are structures, arrays, and samplers. * Samplers cannot be constants, and the others should have been @@ -1367,8 +1426,8 @@ ir_dereference_record::ir_dereference_record(ir_rvalue *value, assert(value != NULL); this->record = value; - this->field = ralloc_strdup(this, field); this->type = this->record->type->field_type(field); + this->field_idx = this->record->type->field_index(field); } @@ -1379,12 +1438,12 @@ ir_dereference_record::ir_dereference_record(ir_variable *var, void *ctx = ralloc_parent(var); this->record = new(ctx) ir_dereference_variable(var); - this->field = ralloc_strdup(this, field); this->type = this->record->type->field_type(field); + this->field_idx = this->record->type->field_index(field); } bool -ir_dereference::is_lvalue() const +ir_dereference::is_lvalue(const struct _mesa_glsl_parse_state *state) const { ir_variable *var = this->variable_referenced(); @@ -1393,6 +1452,20 @@ ir_dereference::is_lvalue() const if ((var == NULL) || var->data.read_only) return false; + /* From section 4.1.7 of the ARB_bindless_texture spec: + * + * "Samplers can be used as l-values, so can be assigned into and used as + * "out" and "inout" function parameters." + * + * From section 4.1.X of the ARB_bindless_texture spec: + * + * "Images can be used as l-values, so can be assigned into and used as + * "out" and "inout" function parameters." + */ + if ((!state || state->has_bindless()) && + (this->type->contains_sampler() || this->type->contains_image())) + return true; + /* From section 4.1.7 of the GLSL 4.40 spec: * * "Opaque variables cannot be treated as l-values; hence cannot @@ -1439,10 +1512,10 @@ ir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type) assert(type->base_type == GLSL_TYPE_INT); } else if (this->op == ir_lod) { assert(type->vector_elements == 2); - assert(type->base_type == GLSL_TYPE_FLOAT); + assert(type->is_float()); } else if (this->op == ir_samples_identical) { assert(type == glsl_type::bool_type); - assert(sampler->type->base_type == GLSL_TYPE_SAMPLER); + assert(sampler->type->is_sampler()); assert(sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS); } else { assert(sampler->type->sampled_type == (int) type->base_type); @@ -1512,10 +1585,8 @@ ir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp, } ir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask) - : ir_rvalue(ir_type_swizzle) + : ir_rvalue(ir_type_swizzle), val(val), mask(mask) { - this->val = val; - this->mask = mask; this->type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1); } @@ -1636,6 +1707,10 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name, if (mode == ir_var_temporary && (name == NULL || name == ir_variable::tmp_name)) { this->name = ir_variable::tmp_name; + } else if (name == NULL || + strlen(name) < ARRAY_SIZE(this->name_storage)) { + strcpy(this->name_storage, name ? name : ""); + this->name = this->name_storage; } else { this->name = ralloc_strdup(this, name); } @@ -1662,21 +1737,21 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name, 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.interpolation = INTERP_MODE_NONE; + this->data.max_array_access = -1; this->data.offset = 0; this->data.precision = GLSL_PRECISION_NONE; - 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; + this->data.memory_read_only = false; + this->data.memory_write_only = false; + this->data.memory_coherent = false; + this->data.memory_volatile = false; + this->data.memory_restrict = false; this->data.from_ssbo_unsized_array = false; + this->data.fb_fetch_output = false; + this->data.bindless = false; + this->data.bound = 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->without_array()->is_interface()) @@ -1689,10 +1764,10 @@ const char * interpolation_string(unsigned interpolation) { switch (interpolation) { - case INTERP_QUALIFIER_NONE: return "no"; - case INTERP_QUALIFIER_SMOOTH: return "smooth"; - case INTERP_QUALIFIER_FLAT: return "flat"; - case INTERP_QUALIFIER_NOPERSPECTIVE: return "noperspective"; + case INTERP_MODE_NONE: return "no"; + case INTERP_MODE_SMOOTH: return "smooth"; + case INTERP_MODE_FLAT: return "flat"; + case INTERP_MODE_NOPERSPECTIVE: return "noperspective"; } assert(!"Should not get here."); @@ -1729,8 +1804,8 @@ ir_variable::get_extension_warning() const ir_function_signature::ir_function_signature(const glsl_type *return_type, builtin_available_predicate b) : ir_instruction(ir_type_function_signature), - return_type(return_type), is_defined(false), is_intrinsic(false), - builtin_avail(b), _function(NULL) + return_type(return_type), is_defined(false), + intrinsic_id(ir_intrinsic_invalid), builtin_avail(b), _function(NULL) { this->origin = NULL; } @@ -1789,11 +1864,11 @@ ir_function_signature::qualifiers_match(exec_list *params) a->data.centroid != b->data.centroid || a->data.sample != b->data.sample || a->data.patch != b->data.patch || - 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) { + a->data.memory_read_only != b->data.memory_read_only || + a->data.memory_write_only != b->data.memory_write_only || + a->data.memory_coherent != b->data.memory_coherent || + a->data.memory_volatile != b->data.memory_volatile || + a->data.memory_restrict != b->data.memory_restrict) { /* parameter a's qualifiers don't match */ return a->name; @@ -1870,15 +1945,10 @@ steal_memory(ir_instruction *ir, void *new_ctx) /* The components of aggregate constants are not visited by the normal * visitor, so steal their values by hand. */ - if (constant != NULL) { - if (constant->type->is_record()) { - foreach_in_list(ir_constant, field, &constant->components) { - steal_memory(field, ir); - } - } else if (constant->type->is_array()) { - for (unsigned int i = 0; i < constant->type->length; i++) { - steal_memory(constant->array_elements[i], ir); - } + if (constant != NULL && + (constant->type->is_array() || constant->type->is_record())) { + for (unsigned int i = 0; i < constant->type->length; i++) { + steal_memory(constant->const_elements[i], ir); } }