From a052a9c27777fc2cc92ed7ac3cd820e828abf2f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 8 May 2020 22:16:42 -0400 Subject: [PATCH] glsl: handle int16 and uint16 types and add instructions for mediump v2: add more changes to ir_validate.cpp Reviewed-by: Alyssa Rosenzweig Reviewed-by: Rob Clark Part-of: --- 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 +++++++++------- .../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; itype->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()");