From: Elie Tournier <tournier.e...@gmail.com>

[airlied: handle vector cases]
Signed-off-by: Elie Tournier <elie.tourn...@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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to