glsl: handle int16 and uint16 types and add instructions for mediump
authorMarek Olšák <marek.olsak@amd.com>
Sat, 9 May 2020 02:16:42 +0000 (22:16 -0400)
committerMarge Bot <eric+marge@anholt.net>
Tue, 2 Jun 2020 20:01:18 +0000 (20:01 +0000)
v2: add more changes to ir_validate.cpp

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

12 files changed:
src/compiler/glsl/glsl_to_nir.cpp
src/compiler/glsl/ir.cpp
src/compiler/glsl/ir.h
src/compiler/glsl/ir_constant_expression.cpp
src/compiler/glsl/ir_expression_operation.py
src/compiler/glsl/ir_print_visitor.cpp
src/compiler/glsl/ir_validate.cpp
src/compiler/glsl/opt_constant_propagation.cpp
src/compiler/glsl/opt_minmax.cpp
src/compiler/glsl_types.h
src/mesa/program/ir_to_mesa.cpp
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index c9e0607271e2eeb9ec5864cc3543ab37baaa1ecf..a6b9f44277f88e3e86ef69cb8cd046623652c2b7 100644 (file)
@@ -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;
index 66660c73c75b1f5e0c16f2ba1be2b6d511eacafc..607cb3e78ef27dfccd03c94618cb5e7b727a4c33 100644 (file)
@@ -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;
index c6edffea34a33c0cd77c1cc8aade8433b27b57fc..90bcc72bcf25d009e293160c0b83233299f2299b 100644 (file)
@@ -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;
index f49742108437f4bef6faf26e51e28ec63207a4d0..636196886b3bd9d05c2d2b85d3ee1972c13ebe27 100644 (file)
@@ -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;
index 8481e2ce640a765c1324a571c8c3f74d9dbf6601..d2c4d41024fd6f5a4489ec4ce8c77f6daaf56087 100644 (file)
@@ -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.
index 7533a52ee818f510f9363cbfd0e91839c0bd9be1..dc057c5a263a8affa55919a4c9c98e66221f306f 100644 (file)
@@ -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:
index e370bc21b24ad93177fc6b600897b19dd252f098..cba7d8c6f087a5e6a9da68f2a9cd967ca44f9d37 100644 (file)
@@ -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);
index 674208348b87aa59bda660a9e6178bc237cc9bde..1e598b70df44ea76644cfd0a47034d5b9c3de134 100644 (file)
@@ -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;
index 36fe0a9f05b61e854d6e2e1f38478418b7d2d7e7..9f20ff87f22bfc7d3053fd88e39019161d118b1f 100644 (file)
@@ -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]))
index aa1a4cec324b842213b57532827075aa5cf49650..4654ad7cf573371c719c185b6b016d1142bf8fa9 100644 (file)
@@ -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
     */
index 3b8472384ca9fcddeee4d3b5f7206ff079231cc8..3ee8490ddc0b8d052a6c9b985903d74f8a52842f 100644 (file)
@@ -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;
 
index 390e91deebd49a1635b6cfc6edcc32d51d898121..f2f1de316fca838698bd99a2149685b8192fb4d1 100644 (file)
@@ -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()");