Signed-off-by: Elie Tournier <elie.tourn...@collabora.com> --- src/compiler/glsl/ir_optimization.h | 1 + src/compiler/glsl/lower_instructions.cpp | 34 ++++++++++++++++++++++++++++-- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 2 +- 3 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/src/compiler/glsl/ir_optimization.h b/src/compiler/glsl/ir_optimization.h index a2ebc16e93..f004380670 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 MIN_MAX_TO_LESS 0x400000 +#define DOPS_TO_DTRUNC 0x800000 /* Operations for lower_64bit_integer_instructions() * and lower_64bit_double_instructions() diff --git a/src/compiler/glsl/lower_instructions.cpp b/src/compiler/glsl/lower_instructions.cpp index c6c3a627d3..50c35124fb 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 * - MIN_MAX_TO_LESS + * - DOPS_TO_DTRUNC * * SUB_TO_ADD_NEG: * --------------- @@ -178,6 +179,7 @@ private: void sqrt_to_abs_sqrt(ir_expression *ir); void min_to_less(ir_expression *ir); void max_to_less(ir_expression *ir); + void dfloor_to_dtrunc(ir_expression *ir); ir_expression *_carry(operand a, operand b); }; @@ -1660,6 +1662,29 @@ lower_instructions_visitor::max_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 + */ + + 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, 1)), + equal(src, tr)); + ir->operands[1] = tr; + ir->operands[2] = add(tr, new(ir) ir_constant(-1.0, 1)); + + this->progress = true; +} + ir_visitor_status lower_instructions_visitor::visit_leave(ir_expression *ir) { @@ -1748,8 +1773,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) && ir->type->is_scalar()) { + dfloor_to_dtrunc(ir); + } + } break; case ir_unop_round_even: diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index ef3a15932a..4fbf2c0a99 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -7058,7 +7058,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) */ if (!pscreen->get_param(pscreen, PIPE_CAP_DOUBLES) && ctx->Const.GLSLVersion >= 130) { - lower_instructions(ir, MIN_MAX_TO_LESS); + lower_instructions(ir, MIN_MAX_TO_LESS | DOPS_TO_DTRUNC); unsigned lower_inst = ABS64 | NEG64 | SIGN64 | -- 2.14.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev