Mesa (master): glsl: handle int16 and uint16 types and add instructions for mediump

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 2 20:25:45 UTC 2020


Module: Mesa
Branch: master
Commit: a052a9c27777fc2cc92ed7ac3cd820e828abf2f0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a052a9c27777fc2cc92ed7ac3cd820e828abf2f0

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Fri May  8 22:16:42 2020 -0400

glsl: handle int16 and uint16 types and add instructions for mediump

v2: add more changes to ir_validate.cpp

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Reviewed-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5002>

---

 src/compiler/glsl/glsl_to_nir.cpp              |  34 +++++
 src/compiler/glsl/ir.cpp                       | 165 +++++++++++++++++++++++++
 src/compiler/glsl/ir.h                         |   6 +
 src/compiler/glsl/ir_constant_expression.cpp   |  69 +++++++++--
 src/compiler/glsl/ir_expression_operation.py   |   5 +
 src/compiler/glsl/ir_print_visitor.cpp         |   2 +
 src/compiler/glsl/ir_validate.cpp              | 147 ++++++++++++----------
 src/compiler/glsl/opt_constant_propagation.cpp |   6 +
 src/compiler/glsl/opt_minmax.cpp               |  26 ++++
 src/compiler/glsl_types.h                      |  50 ++++++++
 src/mesa/program/ir_to_mesa.cpp                |   4 +
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp     |   4 +
 12 files changed, 445 insertions(+), 73 deletions(-)

diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp
index c9e0607271e..a6b9f44277f 100644
--- a/src/compiler/glsl/glsl_to_nir.cpp
+++ b/src/compiler/glsl/glsl_to_nir.cpp
@@ -305,6 +305,14 @@ nir_visitor::constant_copy(ir_constant *ir, void *mem_ctx)
 
       break;
 
+   case GLSL_TYPE_UINT16:
+      /* Only float base types can be matrices. */
+      assert(cols == 1);
+
+      for (unsigned r = 0; r < rows; r++)
+         ret->values[r].u16 = ir->value.u16[r];
+      break;
+
    case GLSL_TYPE_INT:
       /* Only float base types can be matrices. */
       assert(cols == 1);
@@ -314,6 +322,14 @@ nir_visitor::constant_copy(ir_constant *ir, void *mem_ctx)
 
       break;
 
+   case GLSL_TYPE_INT16:
+      /* Only float base types can be matrices. */
+      assert(cols == 1);
+
+      for (unsigned r = 0; r < rows; r++)
+         ret->values[r].i16 = ir->value.i16[r];
+      break;
+
    case GLSL_TYPE_FLOAT:
    case GLSL_TYPE_FLOAT16:
    case GLSL_TYPE_DOUBLE:
@@ -1911,6 +1927,8 @@ nir_visitor::visit(ir_expression *ir)
    case ir_unop_f2f16:
    case ir_unop_f162b:
    case ir_unop_b2f16:
+   case ir_unop_i2i:
+   case ir_unop_u2u:
    case ir_unop_d2i:
    case ir_unop_d2u:
    case ir_unop_d2b:
@@ -1954,6 +1972,16 @@ nir_visitor::visit(ir_expression *ir)
       break;
    }
 
+   case ir_unop_i2imp: {
+      result = nir_build_alu(&b, nir_op_i2imp, srcs[0], NULL, NULL, NULL);
+      break;
+   }
+
+   case ir_unop_u2ump: {
+      result = nir_build_alu(&b, nir_op_u2ump, srcs[0], NULL, NULL, NULL);
+      break;
+   }
+
    case ir_unop_bitcast_i2f:
    case ir_unop_bitcast_f2i:
    case ir_unop_bitcast_u2f:
@@ -2390,6 +2418,12 @@ nir_visitor::visit(ir_texture *ir)
    case GLSL_TYPE_FLOAT16:
       instr->dest_type = nir_type_float16;
       break;
+   case GLSL_TYPE_INT16:
+      instr->dest_type = nir_type_int16;
+      break;
+   case GLSL_TYPE_UINT16:
+      instr->dest_type = nir_type_uint16;
+      break;
    case GLSL_TYPE_INT:
       instr->dest_type = nir_type_int;
       break;
diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp
index 66660c73c75..607cb3e78ef 100644
--- a/src/compiler/glsl/ir.cpp
+++ b/src/compiler/glsl/ir.cpp
@@ -299,6 +299,38 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
 					   op0->type->vector_elements, 1);
       break;
 
+   case ir_unop_i2imp:
+      this->type = glsl_type::get_instance(GLSL_TYPE_INT16,
+					   op0->type->vector_elements, 1);
+      break;
+
+   case ir_unop_i2i:
+      if (op0->type->base_type == GLSL_TYPE_INT) {
+         this->type = glsl_type::get_instance(GLSL_TYPE_INT16,
+                                              op0->type->vector_elements, 1);
+      } else {
+         assert(op0->type->base_type == GLSL_TYPE_INT16);
+         this->type = glsl_type::get_instance(GLSL_TYPE_INT,
+                                              op0->type->vector_elements, 1);
+      }
+      break;
+
+   case ir_unop_u2u:
+      if (op0->type->base_type == GLSL_TYPE_UINT) {
+         this->type = glsl_type::get_instance(GLSL_TYPE_UINT16,
+                                              op0->type->vector_elements, 1);
+      } else {
+         assert(op0->type->base_type == GLSL_TYPE_UINT16);
+         this->type = glsl_type::get_instance(GLSL_TYPE_UINT,
+                                              op0->type->vector_elements, 1);
+      }
+      break;
+
+   case ir_unop_u2ump:
+      this->type = glsl_type::get_instance(GLSL_TYPE_UINT16,
+					   op0->type->vector_elements, 1);
+      break;
+
    case ir_unop_f2b:
    case ir_unop_i2b:
    case ir_unop_d2b:
@@ -728,6 +760,32 @@ ir_constant::ir_constant(double d, unsigned vector_elements)
    }
 }
 
+ir_constant::ir_constant(int16_t i16, unsigned vector_elements)
+   : ir_rvalue(ir_type_constant)
+{
+   assert(vector_elements <= 4);
+   this->type = glsl_type::get_instance(GLSL_TYPE_INT16, vector_elements, 1);
+   for (unsigned i = 0; i < vector_elements; i++) {
+      this->value.i16[i] = i16;
+   }
+   for (unsigned i = vector_elements; i < 16; i++) {
+      this->value.i16[i] = 0;
+   }
+}
+
+ir_constant::ir_constant(uint16_t u16, unsigned vector_elements)
+   : ir_rvalue(ir_type_constant)
+{
+   assert(vector_elements <= 4);
+   this->type = glsl_type::get_instance(GLSL_TYPE_UINT16, vector_elements, 1);
+   for (unsigned i = 0; i < vector_elements; i++) {
+      this->value.u16[i] = u16;
+   }
+   for (unsigned i = vector_elements; i < 16; i++) {
+      this->value.u16[i] = 0;
+   }
+}
+
 ir_constant::ir_constant(unsigned int u, unsigned vector_elements)
    : ir_rvalue(ir_type_constant)
 {
@@ -800,6 +858,8 @@ ir_constant::ir_constant(const ir_constant *c, unsigned i)
    this->type = c->type->get_base_type();
 
    switch (this->type->base_type) {
+   case GLSL_TYPE_UINT16:  this->value.u16[0] = c->value.u16[i]; break;
+   case GLSL_TYPE_INT16:  this->value.i16[0] = c->value.i16[i]; break;
    case GLSL_TYPE_UINT:  this->value.u[0] = c->value.u[i]; break;
    case GLSL_TYPE_INT:   this->value.i[0] = c->value.i[i]; break;
    case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break;
@@ -870,6 +930,11 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
       } else {
 	 /* Vector or scalar - fill all components */
 	 switch (type->base_type) {
+         case GLSL_TYPE_UINT16:
+	 case GLSL_TYPE_INT16:
+	    for (unsigned i = 0; i < type->components(); i++)
+	       this->value.u16[i] = value->value.u16[0];
+	    break;
 	 case GLSL_TYPE_UINT:
 	 case GLSL_TYPE_INT:
 	    for (unsigned i = 0; i < type->components(); i++)
@@ -943,6 +1008,12 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
 
       for (unsigned j = 0; j < value->type->components(); j++) {
 	 switch (type->base_type) {
+         case GLSL_TYPE_UINT16:
+	    this->value.u16[i] = value->get_uint16_component(j);
+	    break;
+	 case GLSL_TYPE_INT16:
+	    this->value.i16[i] = value->get_int16_component(j);
+	    break;
 	 case GLSL_TYPE_UINT:
 	    this->value.u[i] = value->get_uint_component(j);
 	    break;
@@ -1017,6 +1088,8 @@ bool
 ir_constant::get_bool_component(unsigned i) const
 {
    switch (this->type->base_type) {
+   case GLSL_TYPE_UINT16:return this->value.u16[i] != 0;
+   case GLSL_TYPE_INT16: return this->value.i16[i] != 0;
    case GLSL_TYPE_UINT:  return this->value.u[i] != 0;
    case GLSL_TYPE_INT:   return this->value.i[i] != 0;
    case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
@@ -1040,6 +1113,8 @@ float
 ir_constant::get_float_component(unsigned i) const
 {
    switch (this->type->base_type) {
+   case GLSL_TYPE_UINT16:return (float) this->value.u16[i];
+   case GLSL_TYPE_INT16: return (float) this->value.i16[i];
    case GLSL_TYPE_UINT:  return (float) this->value.u[i];
    case GLSL_TYPE_INT:   return (float) this->value.i[i];
    case GLSL_TYPE_FLOAT: return this->value.f[i];
@@ -1072,6 +1147,8 @@ double
 ir_constant::get_double_component(unsigned i) const
 {
    switch (this->type->base_type) {
+   case GLSL_TYPE_UINT16:return (double) this->value.u16[i];
+   case GLSL_TYPE_INT16: return (double) this->value.i16[i];
    case GLSL_TYPE_UINT:  return (double) this->value.u[i];
    case GLSL_TYPE_INT:   return (double) this->value.i[i];
    case GLSL_TYPE_FLOAT: return (double) this->value.f[i];
@@ -1091,10 +1168,62 @@ ir_constant::get_double_component(unsigned i) const
    return 0.0;
 }
 
+int16_t
+ir_constant::get_int16_component(unsigned i) const
+{
+   switch (this->type->base_type) {
+   case GLSL_TYPE_UINT16:return this->value.u16[i];
+   case GLSL_TYPE_INT16: return this->value.i16[i];
+   case GLSL_TYPE_UINT:  return this->value.u[i];
+   case GLSL_TYPE_INT:   return this->value.i[i];
+   case GLSL_TYPE_FLOAT: return (int16_t) this->value.f[i];
+   case GLSL_TYPE_FLOAT16: return (int16_t) _mesa_half_to_float(this->value.f16[i]);
+   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
+   case GLSL_TYPE_DOUBLE: return (int16_t) this->value.d[i];
+   case GLSL_TYPE_SAMPLER:
+   case GLSL_TYPE_IMAGE:
+   case GLSL_TYPE_UINT64: return (int16_t) this->value.u64[i];
+   case GLSL_TYPE_INT64:  return (int16_t) 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;
+}
+
+uint16_t
+ir_constant::get_uint16_component(unsigned i) const
+{
+   switch (this->type->base_type) {
+   case GLSL_TYPE_UINT16:return this->value.u16[i];
+   case GLSL_TYPE_INT16: return this->value.i16[i];
+   case GLSL_TYPE_UINT:  return this->value.u[i];
+   case GLSL_TYPE_INT:   return this->value.i[i];
+   case GLSL_TYPE_FLOAT: return (uint16_t) this->value.f[i];
+   case GLSL_TYPE_FLOAT16: return (uint16_t) _mesa_half_to_float(this->value.f16[i]);
+   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
+   case GLSL_TYPE_DOUBLE: return (uint16_t) this->value.d[i];
+   case GLSL_TYPE_SAMPLER:
+   case GLSL_TYPE_IMAGE:
+   case GLSL_TYPE_UINT64: return (uint16_t) this->value.u64[i];
+   case GLSL_TYPE_INT64:  return (uint16_t) 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;
+}
+
 int
 ir_constant::get_int_component(unsigned i) const
 {
    switch (this->type->base_type) {
+   case GLSL_TYPE_UINT16:return this->value.u16[i];
+   case GLSL_TYPE_INT16: return this->value.i16[i];
    case GLSL_TYPE_UINT:  return this->value.u[i];
    case GLSL_TYPE_INT:   return this->value.i[i];
    case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
@@ -1118,6 +1247,8 @@ unsigned
 ir_constant::get_uint_component(unsigned i) const
 {
    switch (this->type->base_type) {
+   case GLSL_TYPE_UINT16:return this->value.u16[i];
+   case GLSL_TYPE_INT16: return this->value.i16[i];
    case GLSL_TYPE_UINT:  return this->value.u[i];
    case GLSL_TYPE_INT:   return this->value.i[i];
    case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
@@ -1141,6 +1272,8 @@ int64_t
 ir_constant::get_int64_component(unsigned i) const
 {
    switch (this->type->base_type) {
+   case GLSL_TYPE_UINT16:return this->value.u16[i];
+   case GLSL_TYPE_INT16: return this->value.i16[i];
    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];
@@ -1164,6 +1297,8 @@ uint64_t
 ir_constant::get_uint64_component(unsigned i) const
 {
    switch (this->type->base_type) {
+   case GLSL_TYPE_UINT16:return this->value.u16[i];
+   case GLSL_TYPE_INT16: return this->value.i16[i];
    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];
@@ -1219,6 +1354,8 @@ void
 ir_constant::copy_offset(ir_constant *src, int offset)
 {
    switch (this->type->base_type) {
+   case GLSL_TYPE_UINT16:
+   case GLSL_TYPE_INT16:
    case GLSL_TYPE_UINT:
    case GLSL_TYPE_INT:
    case GLSL_TYPE_FLOAT:
@@ -1233,6 +1370,12 @@ ir_constant::copy_offset(ir_constant *src, int offset)
       assert (size <= this->type->components() - offset);
       for (unsigned int i=0; i<size; i++) {
 	 switch (this->type->base_type) {
+         case GLSL_TYPE_UINT16:
+	    value.u16[i+offset] = src->get_uint16_component(i);
+	    break;
+	 case GLSL_TYPE_INT16:
+	    value.i16[i+offset] = src->get_int16_component(i);
+	    break;
 	 case GLSL_TYPE_UINT:
 	    value.u[i+offset] = src->get_uint_component(i);
 	    break;
@@ -1295,6 +1438,12 @@ ir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask)
    for (int i=0; i<4; i++) {
       if (mask & (1 << i)) {
 	 switch (this->type->base_type) {
+         case GLSL_TYPE_UINT16:
+	    value.u16[i+offset] = src->get_uint16_component(id++);
+	    break;
+	 case GLSL_TYPE_INT16:
+	    value.i16[i+offset] = src->get_int16_component(id++);
+	    break;
 	 case GLSL_TYPE_UINT:
 	    value.u[i+offset] = src->get_uint_component(id++);
 	    break;
@@ -1345,6 +1494,14 @@ ir_constant::has_value(const ir_constant *c) const
 
    for (unsigned i = 0; i < this->type->components(); i++) {
       switch (this->type->base_type) {
+      case GLSL_TYPE_UINT16:
+	 if (this->value.u16[i] != c->value.u16[i])
+	    return false;
+	 break;
+      case GLSL_TYPE_INT16:
+	 if (this->value.i16[i] != c->value.i16[i])
+	    return false;
+	 break;
       case GLSL_TYPE_UINT:
 	 if (this->value.u[i] != c->value.u[i])
 	    return false;
@@ -1410,6 +1567,14 @@ ir_constant::is_value(float f, int i) const
          if (_mesa_half_to_float(this->value.f16[c]) != f)
             return false;
          break;
+      case GLSL_TYPE_INT16:
+	 if (this->value.i16[c] != int16_t(i))
+	    return false;
+	 break;
+      case GLSL_TYPE_UINT16:
+	 if (this->value.u16[c] != uint16_t(i))
+	    return false;
+	 break;
       case GLSL_TYPE_INT:
 	 if (this->value.i[c] != i)
 	    return false;
diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h
index c6edffea34a..90bcc72bcf2 100644
--- a/src/compiler/glsl/ir.h
+++ b/src/compiler/glsl/ir.h
@@ -2214,6 +2214,8 @@ union ir_constant_data {
       bool b[16];
       double d[16];
       uint16_t f16[16];
+      int16_t u16[16];
+      int16_t i16[16];
       uint64_t u64[16];
       int64_t i64[16];
 };
@@ -2223,6 +2225,8 @@ class ir_constant : public ir_rvalue {
 public:
    ir_constant(const struct glsl_type *type, const ir_constant_data *data);
    ir_constant(bool b, unsigned vector_elements=1);
+   ir_constant(int16_t i16, unsigned vector_elements=1);
+   ir_constant(uint16_t u16, unsigned vector_elements=1);
    ir_constant(unsigned int u, unsigned vector_elements=1);
    ir_constant(int i, unsigned vector_elements=1);
    ir_constant(float16_t f16, unsigned vector_elements=1);
@@ -2280,6 +2284,8 @@ public:
    float get_float_component(unsigned i) const;
    uint16_t get_float16_component(unsigned i) const;
    double get_double_component(unsigned i) const;
+   int16_t get_int16_component(unsigned i) const;
+   uint16_t get_uint16_component(unsigned i) const;
    int get_int_component(unsigned i) const;
    unsigned get_uint_component(unsigned i) const;
    int64_t get_int64_component(unsigned i) const;
diff --git a/src/compiler/glsl/ir_constant_expression.cpp b/src/compiler/glsl/ir_constant_expression.cpp
index f4974210843..636196886b3 100644
--- a/src/compiler/glsl/ir_constant_expression.cpp
+++ b/src/compiler/glsl/ir_constant_expression.cpp
@@ -693,19 +693,55 @@ ir_expression::constant_expression_value(void *mem_ctx,
    }
 
    for (unsigned operand = 0; operand < this->num_operands; operand++) {
-      if (op[operand]->type->base_type == GLSL_TYPE_FLOAT16) {
+      switch (op[operand]->type->base_type) {
+      case GLSL_TYPE_FLOAT16: {
          const struct glsl_type *float_type =
-            glsl_type::get_instance(GLSL_TYPE_FLOAT,
-                                    op[operand]->type->vector_elements,
-                                    op[operand]->type->matrix_columns,
-                                    op[operand]->type->explicit_stride,
-                                    op[operand]->type->interface_row_major);
+               glsl_type::get_instance(GLSL_TYPE_FLOAT,
+                                       op[operand]->type->vector_elements,
+                                       op[operand]->type->matrix_columns,
+                                       op[operand]->type->explicit_stride,
+                                       op[operand]->type->interface_row_major);
 
          ir_constant_data f;
          for (unsigned i = 0; i < ARRAY_SIZE(f.f); i++)
             f.f[i] = _mesa_half_to_float(op[operand]->value.f16[i]);
 
          op[operand] = new(mem_ctx) ir_constant(float_type, &f);
+         break;
+      }
+      case GLSL_TYPE_INT16: {
+         const struct glsl_type *int_type =
+            glsl_type::get_instance(GLSL_TYPE_INT,
+                                    op[operand]->type->vector_elements,
+                                    op[operand]->type->matrix_columns,
+                                    op[operand]->type->explicit_stride,
+                                    op[operand]->type->interface_row_major);
+
+         ir_constant_data d;
+         for (unsigned i = 0; i < ARRAY_SIZE(d.i); i++)
+            d.i[i] = op[operand]->value.i16[i];
+
+         op[operand] = new(mem_ctx) ir_constant(int_type, &d);
+         break;
+      }
+      case GLSL_TYPE_UINT16: {
+         const struct glsl_type *uint_type =
+            glsl_type::get_instance(GLSL_TYPE_UINT,
+                                    op[operand]->type->vector_elements,
+                                    op[operand]->type->matrix_columns,
+                                    op[operand]->type->explicit_stride,
+                                    op[operand]->type->interface_row_major);
+
+         ir_constant_data d;
+         for (unsigned i = 0; i < ARRAY_SIZE(d.u); i++)
+            d.u[i] = op[operand]->value.u16[i];
+
+         op[operand] = new(mem_ctx) ir_constant(uint_type, &d);
+         break;
+      }
+      default:
+         /* nothing to do */
+         break;
       }
    }
 
@@ -757,16 +793,31 @@ ir_expression::constant_expression_value(void *mem_ctx,
 
 #include "ir_expression_operation_constant.h"
 
-   if (this->type->base_type == GLSL_TYPE_FLOAT16) {
+   switch (type->base_type) {
+   case GLSL_TYPE_FLOAT16: {
       ir_constant_data f;
       for (unsigned i = 0; i < ARRAY_SIZE(f.f16); i++)
          f.f16[i] = _mesa_float_to_half(data.f[i]);
 
       return new(mem_ctx) ir_constant(this->type, &f);
    }
+   case GLSL_TYPE_INT16: {
+      ir_constant_data d;
+      for (unsigned i = 0; i < ARRAY_SIZE(d.i16); i++)
+         d.i16[i] = data.i[i];
 
+      return new(mem_ctx) ir_constant(this->type, &d);
+   }
+   case GLSL_TYPE_UINT16: {
+      ir_constant_data d;
+      for (unsigned i = 0; i < ARRAY_SIZE(d.u16); i++)
+         d.u16[i] = data.u[i];
 
-   return new(mem_ctx) ir_constant(this->type, &data);
+      return new(mem_ctx) ir_constant(this->type, &d);
+   }
+   default:
+      return new(mem_ctx) ir_constant(this->type, &data);
+   }
 }
 
 
@@ -796,6 +847,8 @@ ir_swizzle::constant_expression_value(void *mem_ctx,
 
       for (unsigned i = 0; i < this->mask.num_components; i++) {
          switch (v->type->base_type) {
+         case GLSL_TYPE_UINT16:
+         case GLSL_TYPE_INT16: data.u16[i] = v->value.u16[swiz_idx[i]]; break;
          case GLSL_TYPE_UINT:
          case GLSL_TYPE_INT:   data.u[i] = v->value.u[swiz_idx[i]]; break;
          case GLSL_TYPE_FLOAT: data.f[i] = v->value.f[swiz_idx[i]]; break;
diff --git a/src/compiler/glsl/ir_expression_operation.py b/src/compiler/glsl/ir_expression_operation.py
index 8481e2ce640..d2c4d41024f 100644
--- a/src/compiler/glsl/ir_expression_operation.py
+++ b/src/compiler/glsl/ir_expression_operation.py
@@ -461,6 +461,11 @@ ir_expression_operation = [
    operation("f2f16", 1, source_types=(float_type,), dest_type=float_type, c_expression="{src0}"),
    operation("f2fmp", 1, source_types=(float_type,), dest_type=float_type, c_expression="{src0}"),
    operation("f162f", 1, source_types=(float_type,), dest_type=float_type, c_expression="{src0}"),
+   # int16<->int32 conversion.
+   operation("i2i", 1, source_types=(int_type,), dest_type=int_type, c_expression="{src0}"),
+   operation("i2imp", 1, source_types=(int_type,), dest_type=int_type, c_expression="{src0}"),
+   operation("u2u", 1, source_types=(uint_type,), dest_type=uint_type, c_expression="{src0}"),
+   operation("u2ump", 1, source_types=(uint_type,), dest_type=uint_type, c_expression="{src0}"),
    # Double-to-integer conversion.
    operation("d2i", 1, source_types=(double_type,), dest_type=int_type, c_expression="{src0}"),
    # Integer-to-double conversion.
diff --git a/src/compiler/glsl/ir_print_visitor.cpp b/src/compiler/glsl/ir_print_visitor.cpp
index 7533a52ee81..dc057c5a263 100644
--- a/src/compiler/glsl/ir_print_visitor.cpp
+++ b/src/compiler/glsl/ir_print_visitor.cpp
@@ -495,6 +495,8 @@ void ir_print_visitor::visit(ir_constant *ir)
 	 if (i != 0)
 	    fprintf(f, " ");
 	 switch (ir->type->base_type) {
+         case GLSL_TYPE_UINT16:fprintf(f, "%u", ir->value.u16[i]); break;
+	 case GLSL_TYPE_INT16: fprintf(f, "%d", ir->value.i16[i]); break;
 	 case GLSL_TYPE_UINT:  fprintf(f, "%u", ir->value.u[i]); break;
 	 case GLSL_TYPE_INT:   fprintf(f, "%d", ir->value.i[i]); break;
 	 case GLSL_TYPE_FLOAT:
diff --git a/src/compiler/glsl/ir_validate.cpp b/src/compiler/glsl/ir_validate.cpp
index e370bc21b24..cba7d8c6f08 100644
--- a/src/compiler/glsl/ir_validate.cpp
+++ b/src/compiler/glsl/ir_validate.cpp
@@ -126,7 +126,7 @@ ir_validate::visit_enter(class ir_dereference_array *ir)
       abort();
    }
 
-   if (!ir->array_index->type->is_integer_32()) {
+   if (!ir->array_index->type->is_integer_16_32()) {
       printf("ir_dereference_array @ %p does not have integer index: %s\n",
              (void *) ir, ir->array_index->type->name);
       abort();
@@ -259,9 +259,8 @@ ir_validate::visit_leave(ir_expression *ir)
 
    case ir_unop_abs:
    case ir_unop_sign:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT ||
-             ir->operands[0]->type->is_float_16_32_64() ||
-             ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
+      assert(ir->operands[0]->type->is_int_16_32_64() ||
+             ir->operands[0]->type->is_float_16_32_64());
       assert(ir->type == ir->operands[0]->type);
       break;
 
@@ -282,19 +281,19 @@ ir_validate::visit_leave(ir_expression *ir)
       break;
 
    case ir_unop_f2i:
-      assert(ir->operands[0]->type->is_float());
-      assert(ir->type->base_type == GLSL_TYPE_INT);
+      assert(ir->operands[0]->type->is_float_16_32());
+      assert(ir->type->is_int_16_32());
       break;
    case ir_unop_f2u:
-      assert(ir->operands[0]->type->is_float());
-      assert(ir->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->operands[0]->type->is_float_16_32());
+      assert(ir->type->is_uint_16_32());
       break;
    case ir_unop_i2f:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
-      assert(ir->type->is_float());
+      assert(ir->operands[0]->type->is_int_16_32());
+      assert(ir->type->is_float_16_32());
       break;
    case ir_unop_f2b:
-      assert(ir->operands[0]->type->is_float());
+      assert(ir->operands[0]->type->is_float_16_32());
       assert(ir->type->is_boolean());
       break;
    case ir_unop_f162b:
@@ -304,47 +303,47 @@ ir_validate::visit_leave(ir_expression *ir)
       break;
    case ir_unop_b2f:
       assert(ir->operands[0]->type->is_boolean());
-      assert(ir->type->is_float());
+      assert(ir->type->is_float_16_32());
       break;
    case ir_unop_b2f16:
       assert(ir->operands[0]->type->is_boolean());
       assert(ir->type->base_type == GLSL_TYPE_FLOAT16);
       break;
    case ir_unop_i2b:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
+      assert(ir->operands[0]->type->is_int_16_32());
       assert(ir->type->is_boolean());
       break;
    case ir_unop_b2i:
       assert(ir->operands[0]->type->is_boolean());
-      assert(ir->type->base_type == GLSL_TYPE_INT);
+      assert(ir->type->is_int_16_32());
       break;
    case ir_unop_u2f:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
-      assert(ir->type->is_float());
+      assert(ir->operands[0]->type->is_uint_16_32());
+      assert(ir->type->is_float_16_32());
       break;
    case ir_unop_i2u:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
-      assert(ir->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->operands[0]->type->is_int_16_32());
+      assert(ir->type->is_uint_16_32());
       break;
    case ir_unop_u2i:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
-      assert(ir->type->base_type == GLSL_TYPE_INT);
+      assert(ir->operands[0]->type->is_uint_16_32());
+      assert(ir->type->is_int_16_32());
       break;
    case ir_unop_bitcast_i2f:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
-      assert(ir->type->is_float());
+      assert(ir->operands[0]->type->is_int_16_32());
+      assert(ir->type->is_float_16_32());
       break;
    case ir_unop_bitcast_f2i:
-      assert(ir->operands[0]->type->is_float());
-      assert(ir->type->base_type == GLSL_TYPE_INT);
+      assert(ir->operands[0]->type->is_float_16_32());
+      assert(ir->type->is_int_16_32());
       break;
    case ir_unop_bitcast_u2f:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
-      assert(ir->type->is_float());
+      assert(ir->operands[0]->type->is_uint_16_32());
+      assert(ir->type->is_float_16_32());
       break;
    case ir_unop_bitcast_f2u:
-      assert(ir->operands[0]->type->is_float());
-      assert(ir->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->operands[0]->type->is_float_16_32());
+      assert(ir->type->is_uint_16_32());
       break;
 
    case ir_unop_bitcast_u642d:
@@ -365,19 +364,19 @@ ir_validate::visit_leave(ir_expression *ir)
       break;
    case ir_unop_i642i:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
-      assert(ir->type->base_type == GLSL_TYPE_INT);
+      assert(ir->type->is_int_16_32());
       break;
    case ir_unop_u642i:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
-      assert(ir->type->base_type == GLSL_TYPE_INT);
+      assert(ir->type->is_int_16_32());
       break;
    case ir_unop_i642u:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
-      assert(ir->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->type->is_uint_16_32());
       break;
    case ir_unop_u642u:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT64);
-      assert(ir->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->type->is_uint_16_32());
       break;
    case ir_unop_i642b:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT64);
@@ -400,11 +399,11 @@ ir_validate::visit_leave(ir_expression *ir)
       assert(ir->type->is_double());
       break;
    case ir_unop_i2i64:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
+      assert(ir->operands[0]->type->is_int_16_32());
       assert(ir->type->base_type == GLSL_TYPE_INT64);
       break;
    case ir_unop_u2i64:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->operands[0]->type->is_uint_16_32());
       assert(ir->type->base_type == GLSL_TYPE_INT64);
       break;
    case ir_unop_b2i64:
@@ -420,11 +419,11 @@ ir_validate::visit_leave(ir_expression *ir)
       assert(ir->type->base_type == GLSL_TYPE_INT64);
       break;
    case ir_unop_i2u64:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
+      assert(ir->operands[0]->type->is_int_16_32());
       assert(ir->type->base_type == GLSL_TYPE_UINT64);
       break;
    case ir_unop_u2u64:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->operands[0]->type->is_uint_16_32());
       assert(ir->type->base_type == GLSL_TYPE_UINT64);
       break;
    case ir_unop_f2u64:
@@ -541,20 +540,20 @@ ir_validate::visit_leave(ir_expression *ir)
 
    case ir_unop_bitfield_reverse:
       assert(ir->operands[0]->type == ir->type);
-      assert(ir->type->is_integer_32());
+      assert(ir->type->is_integer_16_32());
       break;
 
    case ir_unop_bit_count:
    case ir_unop_find_msb:
    case ir_unop_find_lsb:
       assert(ir->operands[0]->type->vector_elements == ir->type->vector_elements);
-      assert(ir->operands[0]->type->is_integer_32());
-      assert(ir->type->base_type == GLSL_TYPE_INT);
+      assert(ir->operands[0]->type->is_integer_16_32());
+      assert(ir->type->is_int_16_32());
       break;
 
    case ir_unop_clz:
       assert(ir->operands[0]->type == ir->type);
-      assert(ir->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->type->is_uint_16_32());
       break;
 
    case ir_unop_interpolate_at_centroid:
@@ -590,20 +589,38 @@ ir_validate::visit_leave(ir_expression *ir)
       assert(ir->operands[0]->type->is_float());
       assert(ir->type->base_type == GLSL_TYPE_FLOAT16);
       break;
+   case ir_unop_i2i:
+      assert(ir->operands[0]->type->is_int_16_32());
+      assert(ir->type->is_int_16_32());
+      assert(ir->type->base_type != ir->operands[0]->type->base_type);
+      break;
+   case ir_unop_u2u:
+      assert(ir->operands[0]->type->is_uint_16_32());
+      assert(ir->type->is_uint_16_32());
+      assert(ir->type->base_type != ir->operands[0]->type->base_type);
+      break;
+   case ir_unop_i2imp:
+      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
+      assert(ir->type->base_type == GLSL_TYPE_INT16);
+      break;
+   case ir_unop_u2ump:
+      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->type->base_type == GLSL_TYPE_UINT16);
+      break;
    case ir_unop_d2i:
       assert(ir->operands[0]->type->is_double());
-      assert(ir->type->base_type == GLSL_TYPE_INT);
+      assert(ir->type->is_int_16_32());
       break;
    case ir_unop_i2d:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
+      assert(ir->operands[0]->type->is_int_16_32());
       assert(ir->type->is_double());
       break;
    case ir_unop_d2u:
       assert(ir->operands[0]->type->is_double());
-      assert(ir->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->type->is_uint_16_32());
       break;
    case ir_unop_u2d:
-      assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
+      assert(ir->operands[0]->type->is_uint_16_32());
       assert(ir->type->is_double());
       break;
    case ir_unop_d2b:
@@ -617,7 +634,7 @@ ir_validate::visit_leave(ir_expression *ir)
       break;
    case ir_unop_frexp_exp:
       assert(ir->operands[0]->type->is_float_16_32_64());
-      assert(ir->type->base_type == GLSL_TYPE_INT);
+      assert(ir->type->is_int_16_32());
       break;
    case ir_unop_subroutine_to_int:
       assert(ir->operands[0]->type->base_type == GLSL_TYPE_SUBROUTINE);
@@ -643,10 +660,10 @@ ir_validate::visit_leave(ir_expression *ir)
       if (ir->operation == ir_binop_mul &&
           (ir->type->base_type == GLSL_TYPE_UINT64 ||
            ir->type->base_type == GLSL_TYPE_INT64) &&
-          (ir->operands[0]->type->base_type == GLSL_TYPE_INT ||
-           ir->operands[1]->type->base_type == GLSL_TYPE_INT ||
-           ir->operands[0]->type->base_type == GLSL_TYPE_UINT ||
-           ir->operands[1]->type->base_type == GLSL_TYPE_UINT)) {
+          (ir->operands[0]->type->is_int_16_32()||
+           ir->operands[1]->type->is_int_16_32()||
+           ir->operands[0]->type->is_uint_16_32() ||
+           ir->operands[1]->type->is_uint_16_32())) {
          assert(ir->operands[0]->type == ir->operands[1]->type);
          break;
       }
@@ -664,11 +681,10 @@ ir_validate::visit_leave(ir_expression *ir)
 
    case ir_binop_abs_sub:
       assert(ir->operands[0]->type == ir->operands[1]->type);
-      assert(ir->operands[0]->type->is_integer_32_64());
+      assert(ir->operands[0]->type->is_integer_16_32_64());
       assert(ir->operands[0]->type->vector_elements ==
              ir->type->vector_elements);
-      assert(ir->type->base_type == GLSL_TYPE_UINT ||
-             ir->type->base_type == GLSL_TYPE_UINT64);
+      assert(ir->type->is_uint_16_32_64());
       break;
 
    case ir_binop_add_sat:
@@ -677,7 +693,7 @@ ir_validate::visit_leave(ir_expression *ir)
    case ir_binop_avg_round:
       assert(ir->type == ir->operands[0]->type);
       assert(ir->type == ir->operands[1]->type);
-      assert(ir->type->is_integer_32_64());
+      assert(ir->type->is_integer_16_32_64());
       break;
 
    case ir_binop_mul_32x16:
@@ -722,8 +738,8 @@ ir_validate::visit_leave(ir_expression *ir)
 
    case ir_binop_lshift:
    case ir_binop_rshift:
-      assert(ir->operands[0]->type->is_integer_32_64() &&
-             ir->operands[1]->type->is_integer_32());
+      assert(ir->operands[0]->type->is_integer_16_32_64() &&
+             ir->operands[1]->type->is_integer_16_32());
       if (ir->operands[0]->type->is_scalar()) {
           assert(ir->operands[1]->type->is_scalar());
       }
@@ -740,7 +756,7 @@ ir_validate::visit_leave(ir_expression *ir)
    case ir_binop_bit_or:
        assert(ir->operands[0]->type->base_type ==
               ir->operands[1]->type->base_type);
-       assert(ir->type->is_integer_32_64());
+       assert(ir->type->is_integer_16_32_64());
        if (ir->operands[0]->type->is_vector() &&
            ir->operands[1]->type->is_vector()) {
            assert(ir->operands[0]->type->vector_elements ==
@@ -774,7 +790,7 @@ ir_validate::visit_leave(ir_expression *ir)
    case ir_binop_ldexp:
       assert(ir->operands[0]->type == ir->type);
       assert(ir->operands[0]->type->is_float_16_32_64());
-      assert(ir->operands[1]->type->base_type == GLSL_TYPE_INT);
+      assert(ir->operands[1]->type->is_int_16_32());
       assert(ir->operands[0]->type->components() ==
              ir->operands[1]->type->components());
       break;
@@ -782,20 +798,21 @@ ir_validate::visit_leave(ir_expression *ir)
    case ir_binop_vector_extract:
       assert(ir->operands[0]->type->is_vector());
       assert(ir->operands[1]->type->is_scalar()
-             && ir->operands[1]->type->is_integer_32());
+             && ir->operands[1]->type->is_integer_16_32());
       break;
 
    case ir_binop_interpolate_at_offset:
       assert(ir->operands[0]->type == ir->type);
-      assert(ir->operands[0]->type->is_float());
+      assert(ir->operands[0]->type->is_float_16_32());
       assert(ir->operands[1]->type->components() == 2);
-      assert(ir->operands[1]->type->is_float());
+      assert(ir->operands[1]->type->is_float_16_32());
       break;
 
    case ir_binop_interpolate_at_sample:
       assert(ir->operands[0]->type == ir->type);
-      assert(ir->operands[0]->type->is_float());
-      assert(ir->operands[1]->type == glsl_type::int_type);
+      assert(ir->operands[0]->type->is_float_16_32());
+      assert(ir->operands[1]->type == glsl_type::int_type ||
+             ir->operands[1]->type == glsl_type::int16_t_type);
       break;
 
    case ir_binop_atan2:
@@ -828,7 +845,7 @@ ir_validate::visit_leave(ir_expression *ir)
       break;
 
    case ir_triop_bitfield_extract:
-      assert(ir->type->is_integer_32());
+      assert(ir->type->is_integer_16_32());
       assert(ir->operands[0]->type == ir->type);
       assert(ir->operands[1]->type == ir->type);
       assert(ir->operands[2]->type == ir->type);
@@ -839,12 +856,12 @@ ir_validate::visit_leave(ir_expression *ir)
       assert(ir->operands[1]->type->is_scalar());
       assert(ir->operands[0]->type->base_type == ir->operands[1]->type->base_type);
       assert(ir->operands[2]->type->is_scalar()
-             && ir->operands[2]->type->is_integer_32());
+             && ir->operands[2]->type->is_integer_16_32());
       assert(ir->type == ir->operands[0]->type);
       break;
 
    case ir_quadop_bitfield_insert:
-      assert(ir->type->is_integer_32());
+      assert(ir->type->is_integer_16_32());
       assert(ir->operands[0]->type == ir->type);
       assert(ir->operands[1]->type == ir->type);
       assert(ir->operands[2]->type == ir->type);
diff --git a/src/compiler/glsl/opt_constant_propagation.cpp b/src/compiler/glsl/opt_constant_propagation.cpp
index 674208348b8..1e598b70df4 100644
--- a/src/compiler/glsl/opt_constant_propagation.cpp
+++ b/src/compiler/glsl/opt_constant_propagation.cpp
@@ -220,6 +220,12 @@ ir_constant_propagation_visitor::constant_propagation(ir_rvalue **rvalue) {
       case GLSL_TYPE_UINT:
 	 data.u[i] = found->constant->value.u[rhs_channel];
 	 break;
+      case GLSL_TYPE_INT16:
+	 data.i16[i] = found->constant->value.i16[rhs_channel];
+	 break;
+      case GLSL_TYPE_UINT16:
+	 data.u16[i] = found->constant->value.u16[rhs_channel];
+	 break;
       case GLSL_TYPE_BOOL:
 	 data.b[i] = found->constant->value.b[rhs_channel];
 	 break;
diff --git a/src/compiler/glsl/opt_minmax.cpp b/src/compiler/glsl/opt_minmax.cpp
index 36fe0a9f05b..9f20ff87f22 100644
--- a/src/compiler/glsl/opt_minmax.cpp
+++ b/src/compiler/glsl/opt_minmax.cpp
@@ -110,6 +110,22 @@ compare_components(ir_constant *a, ir_constant *b)
         i < components;
         c0 += a_inc, c1 += b_inc, ++i) {
       switch (a->type->base_type) {
+      case GLSL_TYPE_UINT16:
+         if (a->value.u16[c0] < b->value.u16[c1])
+            foundless = true;
+         else if (a->value.u16[c0] > b->value.u16[c1])
+            foundgreater = true;
+         else
+            foundequal = true;
+         break;
+      case GLSL_TYPE_INT16:
+         if (a->value.i16[c0] < b->value.i16[c1])
+            foundless = true;
+         else if (a->value.i16[c0] > b->value.i16[c1])
+            foundgreater = true;
+         else
+            foundequal = true;
+         break;
       case GLSL_TYPE_UINT:
          if (a->value.u[c0] < b->value.u[c1])
             foundless = true;
@@ -183,6 +199,16 @@ combine_constant(bool ismin, ir_constant *a, ir_constant *b)
    ir_constant *c = a->clone(mem_ctx, NULL);
    for (unsigned i = 0; i < c->type->components(); i++) {
       switch (c->type->base_type) {
+      case GLSL_TYPE_UINT16:
+         if ((ismin && b->value.u16[i] < c->value.u16[i]) ||
+             (!ismin && b->value.u16[i] > c->value.u16[i]))
+            c->value.u16[i] = b->value.u16[i];
+         break;
+      case GLSL_TYPE_INT16:
+         if ((ismin && b->value.i16[i] < c->value.i16[i]) ||
+             (!ismin && b->value.i16[i] > c->value.i16[i]))
+            c->value.i16[i] = b->value.i16[i];
+         break;
       case GLSL_TYPE_UINT:
          if ((ismin && b->value.u[i] < c->value.u[i]) ||
              (!ismin && b->value.u[i] > c->value.u[i]))
diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h
index aa1a4cec324..4654ad7cf57 100644
--- a/src/compiler/glsl_types.h
+++ b/src/compiler/glsl_types.h
@@ -721,6 +721,14 @@ public:
       return glsl_base_type_is_integer(base_type);
    }
 
+   /**
+    * Query whether or not a type is a 16-bit integer.
+    */
+   bool is_integer_16() const
+   {
+      return base_type == GLSL_TYPE_UINT16 || base_type == GLSL_TYPE_INT16;
+   }
+
    /**
     * Query whether or not a type is an 32-bit integer.
     */
@@ -745,6 +753,22 @@ public:
       return is_integer_32() || is_integer_64();
    }
 
+   /**
+    * Query whether or not a type is a 16-bit or 32-bit integer
+    */
+   bool is_integer_16_32() const
+   {
+      return is_integer_16() || is_integer_32() || is_integer_64();
+   }
+
+   /**
+    * Query whether or not a type is a 16-bit, 32-bit or 64-bit integer
+    */
+   bool is_integer_16_32_64() const
+   {
+      return is_integer_16() || is_integer_32() || is_integer_64();
+   }
+
    /**
     * Query whether or not type is an integral type, or for struct and array
     * types, contains an integral type.
@@ -787,6 +811,32 @@ public:
       return base_type == GLSL_TYPE_FLOAT16 || is_float() || is_double();
    }
 
+   bool is_int_16_32_64() const
+   {
+      return base_type == GLSL_TYPE_INT16 ||
+             base_type == GLSL_TYPE_INT ||
+             base_type == GLSL_TYPE_INT64;
+   }
+
+   bool is_uint_16_32_64() const
+   {
+      return base_type == GLSL_TYPE_UINT16 ||
+             base_type == GLSL_TYPE_UINT ||
+             base_type == GLSL_TYPE_UINT64;
+   }
+
+   bool is_int_16_32() const
+   {
+      return base_type == GLSL_TYPE_INT ||
+             base_type == GLSL_TYPE_INT16;
+   }
+
+   bool is_uint_16_32() const
+   {
+      return base_type == GLSL_TYPE_UINT ||
+             base_type == GLSL_TYPE_UINT16;
+   }
+
    /**
     * Query whether or not a type is a double type
     */
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 3b8472384ca..3ee8490ddc0 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1343,6 +1343,10 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
    case ir_unop_f2fmp:
    case ir_unop_f162b:
    case ir_unop_b2f16:
+   case ir_unop_i2i:
+   case ir_unop_i2imp:
+   case ir_unop_u2u:
+   case ir_unop_u2ump:
       assert(!"not supported");
       break;
 
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 390e91deebd..f2f1de316fc 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -2394,6 +2394,10 @@ glsl_to_tgsi_visitor::visit_expression(ir_expression* ir, st_src_reg *op)
    case ir_unop_f2fmp:
    case ir_unop_f162b:
    case ir_unop_b2f16:
+   case ir_unop_i2i:
+   case ir_unop_i2imp:
+   case ir_unop_u2u:
+   case ir_unop_u2ump:
       /* This operation is not supported, or should have already been handled.
        */
       assert(!"Invalid ir opcode in glsl_to_tgsi_visitor::visit()");



More information about the mesa-commit mailing list