glsl: don't create conversion opcodes for array types
authorMarek Olšák <marek.olsak@amd.com>
Thu, 23 Jul 2020 22:41:28 +0000 (18:41 -0400)
committerMarge Bot <eric+marge@anholt.net>
Wed, 5 Aug 2020 22:04:47 +0000 (22:04 +0000)
Instead, convert all elements one by one.
This fixes piglit shaders@glsl-bug-110796.

Reviewed-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6073>

src/compiler/glsl/lower_precision.cpp

index 97a91f8c440fcf4ec1c15a5117908748133c6ccb..f602c78878fa666441f52b3e47735a9beae6a2dd 100644 (file)
@@ -690,7 +690,7 @@ convert_precision(bool up, ir_rvalue *ir)
    unsigned op;
 
    if (up) {
    unsigned op;
 
    if (up) {
-      switch (ir->type->without_array()->base_type) {
+      switch (ir->type->base_type) {
       case GLSL_TYPE_FLOAT16:
          op = ir_unop_f162f;
          break;
       case GLSL_TYPE_FLOAT16:
          op = ir_unop_f162f;
          break;
@@ -705,7 +705,7 @@ convert_precision(bool up, ir_rvalue *ir)
          return NULL;
       }
    } else {
          return NULL;
       }
    } else {
-      switch (ir->type->without_array()->base_type) {
+      switch (ir->type->base_type) {
       case GLSL_TYPE_FLOAT:
          op = ir_unop_f2fmp;
          break;
       case GLSL_TYPE_FLOAT:
          op = ir_unop_f2fmp;
          break;
@@ -1255,10 +1255,20 @@ void lower_variables_visitor::handle_rvalue(ir_rvalue **rvalue)
       if (var &&
           _mesa_set_search(lower_vars, var) &&
           deref->type->without_array()->is_32bit()) {
       if (var &&
           _mesa_set_search(lower_vars, var) &&
           deref->type->without_array()->is_32bit()) {
+         void *mem_ctx = ralloc_parent(ir);
+
+         /* Create a 32-bit temporary variable. */
+         ir_variable *new_var =
+            new(mem_ctx) ir_variable(deref->type, "lowerp", ir_var_temporary);
+         base_ir->insert_before(new_var);
+
+         /* Fix types in dereferences. */
          fix_types_in_deref_chain(deref);
 
          fix_types_in_deref_chain(deref);
 
-         /* Then convert the type up. Optimizations should eliminate this. */
-         *rvalue = convert_precision(true, deref);
+         /* Convert to 32 bits for the rvalue. */
+         convert_split_assignment(new(mem_ctx) ir_dereference_variable(new_var),
+                                  deref, true);
+         *rvalue = new(mem_ctx) ir_dereference_variable(new_var);
       }
    }
 }
       }
    }
 }