From: Roland Scheidegger Date: Mon, 12 Aug 2013 23:16:42 +0000 (+0200) Subject: gallivm: implement new float comparison instructions returning integer masks X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6991f86945b3444d60c9f1990975f2d5094cf79b;p=mesa.git gallivm: implement new float comparison instructions returning integer masks FSEQ/FSGE/FSLT/FSNE work just the same as SEQ/SGE/SLT/SNE except skip the select. And just for consistency use the same appropriate ordered/unordered comparisons for the old opcodes as well. Reviewed-by: Zack Rusin --- diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c index f46166101da..86c3249575d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c @@ -1094,6 +1094,70 @@ f2u_emit_cpu( emit_data->args[0]); } +/* TGSI_OPCODE_FSET Helper (CPU Only) */ +static void +fset_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data, + unsigned pipe_func) +{ + LLVMValueRef cond; + + if (pipe_func != PIPE_FUNC_NOTEQUAL) { + cond = lp_build_cmp_ordered(&bld_base->base, pipe_func, + emit_data->args[0], emit_data->args[1]); + } + else { + cond = lp_build_cmp(&bld_base->base, pipe_func, + emit_data->args[0], emit_data->args[1]); + + } + emit_data->output[emit_data->chan] = cond; +} + + +/* TGSI_OPCODE_FSEQ (CPU Only) */ +static void +fseq_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + fset_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_EQUAL); +} + +/* TGSI_OPCODE_ISGE (CPU Only) */ +static void +fsge_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + fset_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_GEQUAL); +} + +/* TGSI_OPCODE_ISLT (CPU Only) */ +static void +fslt_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + fset_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_LESS); +} + +/* TGSI_OPCODE_USNE (CPU Only) */ + +static void +fsne_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + fset_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_NOTEQUAL); +} + /* TGSI_OPCODE_FLR (CPU Only) */ static void @@ -1396,8 +1460,17 @@ set_emit_cpu( struct lp_build_emit_data * emit_data, unsigned pipe_func) { - LLVMValueRef cond = lp_build_cmp(&bld_base->base, pipe_func, - emit_data->args[0], emit_data->args[1]); + LLVMValueRef cond; + + if (pipe_func != PIPE_FUNC_NOTEQUAL) { + cond = lp_build_cmp_ordered(&bld_base->base, pipe_func, + emit_data->args[0], emit_data->args[1]); + } + else { + cond = lp_build_cmp(&bld_base->base, pipe_func, + emit_data->args[0], emit_data->args[1]); + + } emit_data->output[emit_data->chan] = lp_build_select(&bld_base->base, cond, bld_base->base.one, @@ -1716,6 +1789,10 @@ lp_set_default_actions_cpu( bld_base->op_actions[TGSI_OPCODE_F2I].emit = f2i_emit_cpu; bld_base->op_actions[TGSI_OPCODE_F2U].emit = f2u_emit_cpu; bld_base->op_actions[TGSI_OPCODE_FLR].emit = flr_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_FSEQ].emit = fseq_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_FSGE].emit = fsge_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_FSLT].emit = fslt_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_FSNE].emit = fsne_emit_cpu; bld_base->op_actions[TGSI_OPCODE_I2F].emit = i2f_emit_cpu; bld_base->op_actions[TGSI_OPCODE_IABS].emit = iabs_emit_cpu;