summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/glsl/glsl_to_nir.cpp34
-rw-r--r--src/compiler/glsl/ir.cpp165
-rw-r--r--src/compiler/glsl/ir.h6
-rw-r--r--src/compiler/glsl/ir_constant_expression.cpp69
-rw-r--r--src/compiler/glsl/ir_expression_operation.py5
-rw-r--r--src/compiler/glsl/ir_print_visitor.cpp2
-rw-r--r--src/compiler/glsl/ir_validate.cpp147
-rw-r--r--src/compiler/glsl/opt_constant_propagation.cpp6
-rw-r--r--src/compiler/glsl/opt_minmax.cpp26
-rw-r--r--src/compiler/glsl_types.h50
-rw-r--r--src/mesa/program/ir_to_mesa.cpp4
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp4
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
@@ -722,6 +722,14 @@ public:
}
/**
+ * 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.
*/
bool is_integer_32() const
@@ -746,6 +754,22 @@ public:
}
/**
+ * 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()");