[Mesa-dev] [PATCH 43/50] glsl: Add a lowering pass for 64-bit float floor()
Dave Airlie
airlied at gmail.com
Tue Mar 13 04:25:08 UTC 2018
From: Elie Tournier <tournier.elie at gmail.com>
[airlied: handle vector cases]
Signed-off-by: Elie Tournier <elie.tournier at collabora.com>
---
src/compiler/glsl/ir_optimization.h | 1 +
src/compiler/glsl/lower_instructions.cpp | 34 ++++++++++++++++++++++++++++++--
2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/src/compiler/glsl/ir_optimization.h b/src/compiler/glsl/ir_optimization.h
index f9b688a..ba0c101 100644
--- a/src/compiler/glsl/ir_optimization.h
+++ b/src/compiler/glsl/ir_optimization.h
@@ -55,6 +55,7 @@
#define DIV_TO_MUL_RCP (FDIV_TO_MUL_RCP | DDIV_TO_MUL_RCP)
#define SQRT_TO_ABS_SQRT 0x200000
#define DMIN_DMAX_TO_LESS 0x400000
+#define DOPS_TO_DTRUNC 0x800000
/* Opertaions for lower_64bit_integer_instructions() */
#define MUL64 (1U << 0)
diff --git a/src/compiler/glsl/lower_instructions.cpp b/src/compiler/glsl/lower_instructions.cpp
index 144bc41..03246e6 100644
--- a/src/compiler/glsl/lower_instructions.cpp
+++ b/src/compiler/glsl/lower_instructions.cpp
@@ -44,6 +44,7 @@
* - SAT_TO_CLAMP
* - DOPS_TO_DFRAC
* - DMIN_DMAX_TO_LESS
+ * - DOPS_TO_DTRUNC
*
* SUB_TO_ADD_NEG:
* ---------------
@@ -178,6 +179,7 @@ private:
void sqrt_to_abs_sqrt(ir_expression *ir);
void dmin_to_less(ir_expression *ir);
void dmax_to_less(ir_expression *ir);
+ void dfloor_to_dtrunc(ir_expression *ir);
ir_expression *_carry(operand a, operand b);
};
@@ -1714,6 +1716,29 @@ lower_instructions_visitor::dmax_to_less(ir_expression *ir)
this->progress = true;
}
+void
+lower_instructions_visitor::dfloor_to_dtrunc(ir_expression *ir)
+{
+ /*
+ * For x >= 0, floor(x) = trunc(x)
+ * For x < 0,
+ * - if x is integer, floor(x) = x
+ * - otherwise, floor(x) = trunc(x) - 1
+ */
+ const unsigned vec_elem = ir->type->vector_elements;
+ ir_rvalue *src = ir->operands[0]->clone(ir, NULL);
+ ir_rvalue *tr = trunc(src);
+
+ ir->operation = ir_triop_csel;
+ ir->init_num_operands();
+ ir->operands[0] = logic_or(gequal(src, new(ir) ir_constant(0.0, vec_elem)),
+ equal(src, tr));
+ ir->operands[1] = tr;
+ ir->operands[2] = add(tr, new(ir) ir_constant(-1.0, vec_elem));
+
+ this->progress = true;
+}
+
ir_visitor_status
lower_instructions_visitor::visit_leave(ir_expression *ir)
{
@@ -1802,8 +1827,13 @@ lower_instructions_visitor::visit_leave(ir_expression *ir)
break;
case ir_unop_floor:
- if (lowering(DOPS_TO_DFRAC) && ir->type->is_double())
- dfloor_to_dfrac(ir);
+ if (ir->type->is_double()) {
+ if (lowering(DOPS_TO_DFRAC)) {
+ dfloor_to_dfrac(ir);
+ } else if (lowering(DOPS_TO_DTRUNC)) {
+ dfloor_to_dtrunc(ir);
+ }
+ }
break;
case ir_unop_round_even:
--
2.9.5
More information about the mesa-dev
mailing list