From: Marek Olšák <marek.ol...@amd.com> Discussion: https://bugs.freedesktop.org/show_bug.cgi?id=83510#c8 --- src/gallium/drivers/radeonsi/si_shader.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 973bac2..e0799c9 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -2744,6 +2744,32 @@ static int si_generate_gs_copy_shader(struct si_screen *sscreen, return r; } +/** + * This emulates V_RCP_LEGACY_F32, which has the following rule for division + * by zero: 1 / 0 = 0 + * + * V_RCP_F32(x) = 1 / x + * V_RCP_LEGACY_F32(x) = (x != +-0) ? V_RCP_F32(x) : 0. + */ +static void si_llvm_emit_rcp_legacy(const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + LLVMValueRef cmp = + lp_build_cmp(&bld_base->base, + PIPE_FUNC_NOTEQUAL, + emit_data->args[0], + bld_base->base.zero); + + LLVMValueRef div = + lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_DIV, + bld_base->base.one, + emit_data->args[0]); + + emit_data->output[emit_data->chan] = + lp_build_select(&bld_base->base, cmp, div, bld_base->base.zero); +} + int si_shader_create(struct si_screen *sscreen, struct si_shader *shader) { struct si_shader_selector *sel = shader->selector; @@ -2798,6 +2824,7 @@ int si_shader_create(struct si_screen *sscreen, struct si_shader *shader) bld_base->op_actions[TGSI_OPCODE_MIN].emit = build_tgsi_intrinsic_nomem; bld_base->op_actions[TGSI_OPCODE_MIN].intr_name = "llvm.minnum.f32"; } + bld_base->op_actions[TGSI_OPCODE_RCP].emit = si_llvm_emit_rcp_legacy; si_shader_ctx.radeon_bld.load_system_value = declare_system_value; si_shader_ctx.tokens = sel->tokens; -- 2.1.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev