OSDN Git Service

Merge remote-tracking branch 'mesa/18.3' into oreo-x86
[android-x86/external-mesa.git] / src / compiler / glsl / ir.cpp
index c223ec6..f5aa1be 100644 (file)
@@ -21,7 +21,6 @@
  * 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"
@@ -487,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);
@@ -759,7 +756,12 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
    assert(type->is_scalar() || type->is_vector() || type->is_matrix()
          || type->is_record() || type->is_array());
 
-   if (type->is_array()) {
+   /* 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.
+    */
+   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) {
@@ -770,20 +772,6 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
       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);
-      return;
-   }
-
    for (unsigned i = 0; i < 16; i++) {
       this->value.u[i] = 0;
    }
@@ -832,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.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;
@@ -931,9 +923,11 @@ ir_constant::zero(void *mem_ctx, const glsl_type *type)
    }
 
    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);
       }
    }
 
@@ -949,6 +943,8 @@ 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;
@@ -969,6 +965,8 @@ 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;
@@ -989,6 +987,8 @@ 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;
@@ -1009,6 +1009,8 @@ 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;
@@ -1029,6 +1031,8 @@ 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;
@@ -1049,6 +1053,8 @@ ir_constant::get_int64_component(unsigned i) const
    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;
@@ -1069,6 +1075,8 @@ ir_constant::get_uint64_component(unsigned i) const
    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;
@@ -1106,24 +1114,10 @@ ir_constant::get_array_element(unsigned i) const
 ir_constant *
 ir_constant::get_record_field(int idx)
 {
-   if (idx < 0)
-      return NULL;
-
-   if (this->components.is_empty())
-      return NULL;
-
-   exec_node *node = this->components.get_head_raw();
-   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
@@ -1134,6 +1128,8 @@ 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: {
@@ -1156,7 +1152,9 @@ 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_UINT64:
+        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:
@@ -1169,15 +1167,7 @@ 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++) {
@@ -1221,7 +1211,9 @@ 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_UINT64:
+        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:
@@ -1241,7 +1233,7 @@ 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->const_elements[i]->has_value(c->const_elements[i]))
            return false;
@@ -1249,26 +1241,6 @@ ir_constant::has_value(const ir_constant *c) const
       return true;
    }
 
-   if (this->type->is_record()) {
-      const exec_node *a_node = this->components.get_head_raw();
-      const exec_node *b_node = c->components.get_head_raw();
-
-      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))
-           return false;
-
-        a_node = a_node->next;
-        b_node = b_node->next;
-      }
-
-      return true;
-   }
-
    for (unsigned i = 0; i < this->type->components(); i++) {
       switch (this->type->base_type) {
       case GLSL_TYPE_UINT:
@@ -1291,6 +1263,8 @@ 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;
@@ -1340,6 +1314,8 @@ 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;
@@ -1758,6 +1734,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *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;
@@ -1969,15 +1946,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->const_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);
       }
    }