* DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
-#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)
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
}
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:
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;
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;
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;
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;
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:
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:
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;
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;
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:
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);
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:
}
}
-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);
if (op <= ir_last_quadop)
return 4;
- assert(false);
- return 0;
-}
-
-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];
+ unreachable("Could not calculate number of operands");
}
-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)
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;
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));
}
}
+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)
{
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) {
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;
}
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
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
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;
/* Use each component from each entry in the value_list to initialize one
* component of the constant being constructed.
*/
- for (unsigned i = 0; i < type->components(); /* empty */) {
+ unsigned i = 0;
+ for (;;) {
assert(value->as_constant() != NULL);
assert(!value->is_tail_sentinel());
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.
*/
break;
}
+ if (i >= type->components())
+ break; /* avoid downcasting a list sentinel */
value = (ir_constant *) value->next;
}
}
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);
}
}
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;
}
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;
}
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;
}
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;
}
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;
}
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);
-
- 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;
- }
+ assert(this->type->is_record());
+ assert(idx >= 0 && (unsigned) idx < this->type->length);
- return (ir_constant *) node;
+ return const_elements[idx];
}
void
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);
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;
}
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;
}
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;
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;
}
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;
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
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);
}
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();
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
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->sampler_type == (int) type->base_type);
+ assert(sampler->type->sampled_type == (int) type->base_type);
if (sampler->type->sampler_shadow)
assert(type->vector_elements == 4 || type->vector_elements == 1);
else
}
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);
}
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);
}
this->data.centroid = false;
this->data.sample = false;
this->data.patch = false;
+ this->data.explicit_invariant = 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.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())
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.");
return "";
}
-
-glsl_interp_qualifier
-ir_variable::determine_interpolation_mode(bool flat_shade)
-{
- 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)
- return INTERP_QUALIFIER_FLAT;
- else
- return INTERP_QUALIFIER_SMOOTH;
-}
-
const char *const ir_variable::warn_extension_table[] = {
"",
"GL_ARB_shader_stencil_export",
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;
}
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;
/* 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);
}
}