glsl: Expand fp16 to float before constant expression evaluation
authorKristian H. Kristensen <hoegsberg@google.com>
Tue, 25 Feb 2020 21:43:39 +0000 (13:43 -0800)
committerMarge Bot <eric+marge@anholt.net>
Mon, 9 Mar 2020 16:31:08 +0000 (16:31 +0000)
This way the generated constant folding code doesn't need to
understand fp16.  All operations have to be expanded to full float for
evaulation on the CPU, so we might as well do it up front.  As far as
GLSL is concerned, fp16 isn't a separate type from float, so
everything we're supposed to support for float we need to do for fp16.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3929>

src/compiler/glsl/ir_constant_expression.cpp

index 4b80282c266e42d9b456b36ccb8647b5e8fdab47..cdb634bd328021e64a28387a459f9d7f33b0a74b 100644 (file)
@@ -692,6 +692,23 @@ ir_expression::constant_expression_value(void *mem_ctx,
          return NULL;
    }
 
+   for (unsigned operand = 0; operand < this->num_operands; operand++) {
+      if (op[operand]->type->base_type == 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);
+
+         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);
+      }
+   }
+
    if (op[1] != NULL)
       switch (this->operation) {
       case ir_binop_lshift:
@@ -740,6 +757,15 @@ ir_expression::constant_expression_value(void *mem_ctx,
 
 #include "ir_expression_operation_constant.h"
 
+   if (this->type->base_type == 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);
+   }
+
+
    return new(mem_ctx) ir_constant(this->type, &data);
 }