mesa: set up gl_vert_result and gl_frag_attrib values for gl_ClipDistance.
[mesa.git] / src / glsl / ir.cpp
index cc508e2a424d352a38e37e659f6f4d38e3f0e7a7..d6594cd9a3e65063b4a72754aa8781d2100d3c7c 100644 (file)
@@ -272,6 +272,7 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
 
    case ir_unop_f2i:
    case ir_unop_b2i:
+   case ir_unop_u2i:
       this->type = glsl_type::get_instance(GLSL_TYPE_INT,
                                           op0->type->vector_elements, 1);
       break;
@@ -289,6 +290,11 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
                                           op0->type->vector_elements, 1);
       break;
 
+   case ir_unop_i2u:
+      this->type = glsl_type::get_instance(GLSL_TYPE_UINT,
+                                          op0->type->vector_elements, 1);
+      break;
+
    case ir_unop_noise:
       this->type = glsl_type::float_type;
       break;
@@ -419,6 +425,8 @@ static const char *const operator_strs[] = {
    "i2b",
    "b2i",
    "u2f",
+   "i2u",
+   "u2i",
    "any",
    "trunc",
    "ceil",
@@ -1087,23 +1095,8 @@ ir_dereference_record::ir_dereference_record(ir_variable *var,
       ? this->record->type->field_type(field) : glsl_type::error_type;
 }
 
-bool type_contains_sampler(const glsl_type *type)
-{
-   if (type->is_array()) {
-      return type_contains_sampler(type->fields.array);
-   } else if (type->is_record()) {
-      for (unsigned int i = 0; i < type->length; i++) {
-        if (type_contains_sampler(type->fields.structure[i].type))
-           return true;
-      }
-      return false;
-   } else {
-      return type->is_sampler();
-   }
-}
-
 bool
-ir_dereference::is_lvalue()
+ir_dereference::is_lvalue() const
 {
    ir_variable *var = this->variable_referenced();
 
@@ -1112,23 +1105,20 @@ ir_dereference::is_lvalue()
    if ((var == NULL) || var->read_only)
       return false;
 
-   if (this->type->is_array() && !var->array_lvalue)
-      return false;
-
    /* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
     *
     *    "Samplers cannot be treated as l-values; hence cannot be used
     *     as out or inout function parameters, nor can they be
     *     assigned into."
     */
-   if (type_contains_sampler(this->type))
+   if (this->type->contains_sampler())
       return false;
 
    return true;
 }
 
 
-const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf" };
+const char *tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txs" };
 
 const char *ir_texture::opcode_string()
 {
@@ -1150,21 +1140,21 @@ ir_texture::get_opcode(const char *str)
 
 
 void
-ir_texture::set_sampler(ir_dereference *sampler)
+ir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type)
 {
    assert(sampler != NULL);
+   assert(type != NULL);
    this->sampler = sampler;
+   this->type = type;
 
-   switch (sampler->type->sampler_type) {
-   case GLSL_TYPE_FLOAT:
-      this->type = glsl_type::vec4_type;
-      break;
-   case GLSL_TYPE_INT:
-      this->type = glsl_type::ivec4_type;
-      break;
-   case GLSL_TYPE_UINT:
-      this->type = glsl_type::uvec4_type;
-      break;
+   if (this->op == ir_txs) {
+      assert(type->base_type == GLSL_TYPE_INT);
+   } else {
+      assert(sampler->type->sampler_type == (int) type->base_type);
+      if (sampler->type->sampler_shadow)
+        assert(type->vector_elements == 4 || type->vector_elements == 1);
+      else
+        assert(type->vector_elements == 4);
    }
 }
 
@@ -1321,7 +1311,7 @@ ir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
 #undef I
 
 ir_variable *
-ir_swizzle::variable_referenced()
+ir_swizzle::variable_referenced() const
 {
    return this->val->variable_referenced();
 }
@@ -1330,7 +1320,7 @@ ir_swizzle::variable_referenced()
 ir_variable::ir_variable(const struct glsl_type *type, const char *name,
                         ir_variable_mode mode)
    : max_array_access(0), read_only(false), centroid(false), invariant(false),
-     mode(mode), interpolation(ir_var_smooth), array_lvalue(false)
+     mode(mode), interpolation(ir_var_smooth)
 {
    this->ir_type = ir_type_variable;
    this->type = type;
@@ -1379,6 +1369,21 @@ ir_function_signature::ir_function_signature(const glsl_type *return_type)
 }
 
 
+static bool
+modes_match(unsigned a, unsigned b)
+{
+   if (a == b)
+      return true;
+
+   /* Accept "in" vs. "const in" */
+   if ((a == ir_var_const_in && b == ir_var_in) ||
+       (b == ir_var_const_in && a == ir_var_in))
+      return true;
+
+   return false;
+}
+
+
 const char *
 ir_function_signature::qualifiers_match(exec_list *params)
 {
@@ -1391,7 +1396,7 @@ ir_function_signature::qualifiers_match(exec_list *params)
       ir_variable *b = (ir_variable *)iter_b.get();
 
       if (a->read_only != b->read_only ||
-         a->mode != b->mode ||
+         !modes_match(a->mode, b->mode) ||
          a->interpolation != b->interpolation ||
          a->centroid != b->centroid) {