[Mesa-dev] [PATCH 19/47] glsl: Add a lowering pass for 64-bit float abs()

Elie Tournier tournier.elie at gmail.com
Wed Aug 23 11:07:49 UTC 2017


Squashed with:
glsl/lower_64bit: fix return type conversion (airlied)

Only do conversion for the 64-bit types, add a path
to do result merging without conversion.

Signed-off-by: Elie Tournier <elie.tournier at collabora.com>
---
 src/compiler/Makefile.sources                      |  2 +-
 src/compiler/glsl/ir_optimization.h                |  8 +-
 .../glsl/{lower_int64.cpp => lower_64bit.cpp}      | 87 ++++++++++++++++++----
 src/mesa/state_tracker/st_extensions.c             |  3 +-
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp         |  9 +++
 5 files changed, 92 insertions(+), 17 deletions(-)
 rename src/compiler/glsl/{lower_int64.cpp => lower_64bit.cpp} (81%)

diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
index 24fa7716de..699133234c 100644
--- a/src/compiler/Makefile.sources
+++ b/src/compiler/Makefile.sources
@@ -92,7 +92,7 @@ LIBGLSL_FILES = \
 	glsl/lower_distance.cpp \
 	glsl/lower_if_to_cond_assign.cpp \
 	glsl/lower_instructions.cpp \
-	glsl/lower_int64.cpp \
+	glsl/lower_64bit.cpp \
 	glsl/lower_jumps.cpp \
 	glsl/lower_mat_op_to_vec.cpp \
 	glsl/lower_noise.cpp \
diff --git a/src/compiler/glsl/ir_optimization.h b/src/compiler/glsl/ir_optimization.h
index 573ddb4a8d..6cc0909a80 100644
--- a/src/compiler/glsl/ir_optimization.h
+++ b/src/compiler/glsl/ir_optimization.h
@@ -55,11 +55,14 @@
 #define DIV_TO_MUL_RCP            (FDIV_TO_MUL_RCP | DDIV_TO_MUL_RCP)
 #define SQRT_TO_ABS_SQRT          0x200000
 
-/* Opertaions for lower_64bit_integer_instructions() */
+/* Operations for lower_64bit_integer_instructions()
+ * and lower_64bit_double_instructions()
+ */
 #define MUL64                     (1U << 0)
 #define SIGN64                    (1U << 1)
 #define DIV64                     (1U << 2)
 #define MOD64                     (1U << 3)
+#define ABS64                     (1U << 4)
 
 /**
  * \see class lower_packing_builtins_visitor
@@ -177,4 +180,7 @@ compare_index_block(exec_list *instructions, ir_variable *index,
 bool lower_64bit_integer_instructions(exec_list *instructions,
                                       unsigned what_to_lower);
 
+bool lower_64bit_double_instructions(exec_list *instructions,
+                                      unsigned what_to_lower);
+
 #endif /* GLSL_IR_OPTIMIZATION_H */
diff --git a/src/compiler/glsl/lower_int64.cpp b/src/compiler/glsl/lower_64bit.cpp
similarity index 81%
rename from src/compiler/glsl/lower_int64.cpp
rename to src/compiler/glsl/lower_64bit.cpp
index 2d4fdbb1a5..4887e5538c 100644
--- a/src/compiler/glsl/lower_int64.cpp
+++ b/src/compiler/glsl/lower_64bit.cpp
@@ -22,7 +22,7 @@
  */
 
 /**
- * \file lower_int64.cpp
+ * \file lower_64bit.cpp
  *
  * Lower 64-bit operations to 32-bit operations.  Each 64-bit value is lowered
  * to a uvec2.  For each operation that can be lowered, there is a function
@@ -56,6 +56,9 @@ void expand_source(ir_factory &, ir_rvalue *val, ir_variable **expanded_src);
 ir_dereference_variable *compact_destination(ir_factory &,
                                              const glsl_type *type,
                                              ir_variable *result[4]);
+ir_dereference_variable *merge_destination(ir_factory &,
+                                           const glsl_type *type,
+                                           ir_variable *result[4]);
 
 ir_rvalue *lower_op_to_function_call(ir_instruction *base_ir,
                                      ir_expression *ir,
@@ -132,7 +135,7 @@ private:
 #define lowering(x) (this->lower & x)
 
 bool
-lower_64bit_integer_instructions(exec_list *instructions,
+lower_64bit_instructions(exec_list *instructions,
                                  unsigned what_to_lower)
 {
    if (instructions->is_empty())
@@ -163,6 +166,19 @@ lower_64bit_integer_instructions(exec_list *instructions,
    return v.progress;
 }
 
+bool
+lower_64bit_integer_instructions(exec_list *instructions,
+                                 unsigned what_to_lower)
+{
+   return lower_64bit_instructions(instructions, what_to_lower);
+}
+
+bool
+lower_64bit_double_instructions(exec_list *instructions,
+                                 unsigned what_to_lower)
+{
+   return lower_64bit_instructions(instructions, what_to_lower);
+}
 
 /**
  * Expand individual 64-bit values to uvec2 values
@@ -200,18 +216,21 @@ lower_64bit::expand_source(ir_factory &body,
                            ir_rvalue *val,
                            ir_variable **expanded_src)
 {
-   assert(val->type->is_integer_64());
+   assert(val->type->is_integer_64() || val->type->is_double());
 
    ir_variable *const temp = body.make_temp(val->type, "tmp");
 
    body.emit(assign(temp, val));
 
    const ir_expression_operation unpack_opcode =
-      val->type->base_type == GLSL_TYPE_UINT64
-      ? ir_unop_unpack_uint_2x32 : ir_unop_unpack_int_2x32;
+      val->type->base_type == GLSL_TYPE_DOUBLE
+      ? ir_unop_unpack_double_2x32 :
+      (val->type->base_type == GLSL_TYPE_UINT64
+      ? ir_unop_unpack_uint_2x32 : ir_unop_unpack_int_2x32);
 
    const glsl_type *const type =
-      val->type->base_type == GLSL_TYPE_UINT64
+      (val->type->base_type == GLSL_TYPE_UINT64 ||
+      val->type->base_type == GLSL_TYPE_DOUBLE)
       ? glsl_type::uvec2_type : glsl_type::ivec2_type;
 
    unsigned i;
@@ -235,8 +254,10 @@ lower_64bit::compact_destination(ir_factory &body,
                                  ir_variable *result[4])
 {
    const ir_expression_operation pack_opcode =
-      type->base_type == GLSL_TYPE_UINT64
-      ? ir_unop_pack_uint_2x32 : ir_unop_pack_int_2x32;
+      type->base_type == GLSL_TYPE_DOUBLE
+      ? ir_unop_pack_double_2x32 :
+      (type->base_type == GLSL_TYPE_UINT64
+      ? ir_unop_pack_uint_2x32 : ir_unop_pack_int_2x32);
 
    ir_variable *const compacted_result =
       body.make_temp(type, "compacted_64bit_result");
@@ -251,6 +272,24 @@ lower_64bit::compact_destination(ir_factory &body,
    return new(mem_ctx) ir_dereference_variable(compacted_result);
 }
 
+ir_dereference_variable *
+lower_64bit::merge_destination(ir_factory &body,
+                               const glsl_type *type,
+                               ir_variable *result[4])
+{
+   ir_variable *const merged_result =
+      body.make_temp(type, "merged_result");
+
+   for (unsigned i = 0; i < type->vector_elements; i++) {
+      body.emit(assign(merged_result,
+                       result[i],
+                       1U << i));
+   }
+
+   void *const mem_ctx = ralloc_parent(merged_result);
+   return new(mem_ctx) ir_dereference_variable(merged_result);
+}
+
 ir_rvalue *
 lower_64bit::lower_op_to_function_call(ir_instruction *base_ir,
                                        ir_expression *ir,
@@ -262,9 +301,16 @@ lower_64bit::lower_op_to_function_call(ir_instruction *base_ir,
    void *const mem_ctx = ralloc_parent(ir);
    exec_list instructions;
    unsigned source_components = 0;
-   const glsl_type *const result_type =
-      ir->type->base_type == GLSL_TYPE_UINT64
-      ? glsl_type::uvec2_type : glsl_type::ivec2_type;
+   const glsl_type *result_type;
+
+   if (ir->type->is_64bit()) {
+      if (ir->type->base_type == GLSL_TYPE_UINT64 ||
+          ir->type->base_type == GLSL_TYPE_DOUBLE)
+         result_type = glsl_type::uvec2_type;
+      else
+         result_type = glsl_type::ivec2_type;
+   } else
+      result_type = ir->type->get_scalar_type();
 
    ir_factory body(&instructions, mem_ctx);
 
@@ -293,7 +339,11 @@ lower_64bit::lower_op_to_function_call(ir_instruction *base_ir,
       body.emit(c);
    }
 
-   ir_rvalue *const rv = compact_destination(body, ir->type, dst);
+   ir_rvalue *rv;
+   if (ir->type->is_64bit())
+      rv = compact_destination(body, ir->type, dst);
+   else
+      rv = merge_destination(body, ir->type, dst);
 
    /* Move all of the nodes from instructions between base_ir and the
     * instruction before it.
@@ -317,8 +367,9 @@ lower_64bit_visitor::handle_op(ir_expression *ir,
                                const char *function_name,
                                function_generator generator)
 {
-   for (unsigned i = 0; i < ir->num_operands; i++)
-      if (!ir->operands[i]->type->is_integer_64())
+   for (unsigned i = 0; i < ir->get_num_operands(); i++)
+      if (!ir->operands[i]->type->is_integer_64() &&
+          !ir->operands[i]->type->is_double())
          return ir;
 
    /* Get a handle to the correct ir_function_signature for the core
@@ -353,6 +404,14 @@ lower_64bit_visitor::handle_rvalue(ir_rvalue **rvalue)
    assert(ir != NULL);
 
    switch (ir->operation) {
+
+   case ir_unop_abs:
+      if (lowering(ABS64)) {
+         if (ir->type->base_type == GLSL_TYPE_DOUBLE)
+            *rvalue = handle_op(ir, "__builtin_fabs64", generate_ir::fabs64);
+      }
+      break;
+
    case ir_unop_sign:
       if (lowering(SIGN64)) {
          *rvalue = handle_op(ir, "__builtin_sign64", generate_ir::sign64);
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index e37814412a..903ea827f7 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -1186,7 +1186,8 @@ void st_init_extensions(struct pipe_screen *screen,
    }
 #endif
 
-   if (screen->get_param(screen, PIPE_CAP_DOUBLES)) {
+   if (screen->get_param(screen, PIPE_CAP_DOUBLES) ||
+       consts->GLSLVersion >= 130) {
       extensions->ARB_gpu_shader_fp64 = GL_TRUE;
       extensions->ARB_vertex_attrib_64bit = GL_TRUE;
    }
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index d12434101f..991eae4917 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -7053,6 +7053,15 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
       if (!pscreen->get_param(pscreen, PIPE_CAP_INT64_DIVMOD))
          lower_64bit_integer_instructions(ir, DIV64 | MOD64);
 
+      /* Enable double lowering if the hardware doesn't support doubles.
+       * The lowering requires GLSL >= 130.
+       */
+      if (!pscreen->get_param(pscreen, PIPE_CAP_DOUBLES) &&
+            ctx->Const.GLSLVersion >= 130) {
+         unsigned lower_inst = ABS64;
+         lower_64bit_double_instructions(ir, lower_inst);
+      }
+
       if (ctx->Extensions.ARB_shading_language_packing) {
          unsigned lower_inst = LOWER_PACK_SNORM_2x16 |
                                LOWER_UNPACK_SNORM_2x16 |
-- 
2.14.1



More information about the mesa-dev mailing list