>From the GLSL 1.30 specification, section 4.1.10 ("Implicit Conversions"):
    "There are no implicit conversions between signed and unsigned integers."

However, convert_component() was assuming that conversions between int and uint 
were implicit.
---
 src/glsl/ast_function.cpp           |   16 ++++++++++++----
 src/glsl/ir.cpp                     |    8 ++++++++
 src/glsl/ir.h                       |    2 ++
 src/glsl/ir_constant_expression.cpp |    8 ++++++++
 src/glsl/ir_validate.cpp            |    8 ++++++++
 5 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index e5cb873..cc3f032 100644
--- a/src/glsl/ast_function.cpp
+++ b/src/glsl/ast_function.cpp
@@ -267,17 +267,25 @@ convert_component(ir_rvalue *src, const glsl_type 
*desired_type)
    assert(a <= GLSL_TYPE_BOOL);
    assert(b <= GLSL_TYPE_BOOL);
 
-   if ((a == b) || (src->type->is_integer() && desired_type->is_integer()))
+   if (a == b)
       return src;
 
    switch (a) {
    case GLSL_TYPE_UINT:
    case GLSL_TYPE_INT:
-      if (b == GLSL_TYPE_FLOAT)
+      switch(b) {
+      case GLSL_TYPE_UINT:
+        result = new(ctx) ir_expression(ir_unop_u2i, desired_type, src, NULL);
+        break;
+         case GLSL_TYPE_INT:
+        result = new(ctx) ir_expression(ir_unop_i2u, desired_type, src, NULL);
+        break;
+      case GLSL_TYPE_FLOAT:
         result = new(ctx) ir_expression(ir_unop_f2i, desired_type, src, NULL);
-      else {
-        assert(b == GLSL_TYPE_BOOL);
+        break;
+      case GLSL_TYPE_BOOL:
         result = new(ctx) ir_expression(ir_unop_b2i, desired_type, src, NULL);
+        break;
       }
       break;
    case GLSL_TYPE_FLOAT:
diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp
index a3623b3..85c54ba 100644
--- a/src/glsl/ir.cpp
+++ b/src/glsl/ir.cpp
@@ -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;
@@ -288,6 +289,11 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
       this->type = glsl_type::get_instance(GLSL_TYPE_BOOL,
                                           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;
@@ -419,6 +425,8 @@ static const char *const operator_strs[] = {
    "i2b",
    "b2i",
    "u2f",
+   "i2u",
+   "u2i",
    "any",
    "trunc",
    "ceil",
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index a419843..a9de530 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -789,6 +789,8 @@ enum ir_expression_operation {
    ir_unop_i2b,      /**< int-to-boolean conversion */
    ir_unop_b2i,      /**< Boolean-to-int conversion */
    ir_unop_u2f,      /**< Unsigned-to-float conversion. */
+   ir_unop_i2u,      /**< Integer-to-unsigned conversion. */
+   ir_unop_u2i,      /**< Unsigned-to-integer conversion. */
    ir_unop_any,
 
    /**
diff --git a/src/glsl/ir_constant_expression.cpp 
b/src/glsl/ir_constant_expression.cpp
index 2a30848..341c2e6 100644
--- a/src/glsl/ir_constant_expression.cpp
+++ b/src/glsl/ir_constant_expression.cpp
@@ -166,6 +166,14 @@ ir_expression::constant_expression_value()
         data.b[c] = op[0]->value.u[c] ? true : false;
       }
       break;
+   case ir_unop_u2i:
+      assert(op[0]->type->base_type == GLSL_TYPE_UINT);
+      /* Conversion from uint to int is a no-op. */
+      break;
+   case ir_unop_i2u:
+      assert(op[0]->type->base_type == GLSL_TYPE_INT);
+      /* Type conversion from int to uint is a no-op. */
+      break;
 
    case ir_unop_any:
       assert(op[0]->type->is_boolean());
diff --git a/src/glsl/ir_validate.cpp b/src/glsl/ir_validate.cpp
index ec79d05..f3fceb2 100644
--- a/src/glsl/ir_validate.cpp
+++ b/src/glsl/ir_validate.cpp
@@ -280,6 +280,14 @@ ir_validate::visit_leave(ir_expression *ir)
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
       assert(ir->type->base_type == GLSL_TYPE_FLOAT);
       break;
+   case ir_unop_i2u:
+      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
+      assert(ir->type->base_type == GLSL_TYPE_UINT);
+      break;
+   case ir_unop_u2i:
+      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->type->base_type == GLSL_TYPE_INT);
+      break;
 
    case ir_unop_any:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL);
-- 
1.7.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to