From 579ccae73d29211c9f5c01ba527e1743ea39c94e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Feb 2012 16:32:59 +0000 Subject: [PATCH] gallivm: add major integer opcodes to the tgsi action handler This adds support for all the opcodes needed for native integer support with GLSL 1.20 enabled, and some of the ones for GLSL1.30 support. I've split them between non-cpu and cpu along the same lines Tom's code did for the other ones I think, but I'm open to review on which ones should go where. With instance ids fixed I get no regressions on my box here with LLVM 2.8, will test with later LLVMs as well. Signed-off-by: Dave Airlie --- .../auxiliary/gallivm/lp_bld_tgsi_action.c | 383 +++++++++++++++++- 1 file changed, 382 insertions(+), 1 deletion(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c index 65c2a6b6be8..7f011563264 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c @@ -43,6 +43,7 @@ #include "lp_bld_tgsi.h" #include "lp_bld_arit.h" +#include "lp_bld_bitarit.h" #include "lp_bld_const.h" #include "lp_bld_gather.h" #include "lp_bld_logic.h" @@ -683,6 +684,43 @@ sub_emit( emit_data->args[1], ""); } +/* TGSI_OPCODE_U2F */ +static void +u2f_emit( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = LLVMBuildUIToFP(bld_base->base.gallivm->builder, + emit_data->args[0], + bld_base->uint_bld.vec_type, ""); +} + +static void +umad_emit( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + LLVMValueRef tmp; + tmp = lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_UMUL, + emit_data->args[0], + emit_data->args[1]); + emit_data->output[emit_data->chan] = lp_build_emit_llvm_binary(bld_base, + TGSI_OPCODE_UADD, tmp, emit_data->args[2]); +} + +/* TGSI_OPCODE_UMUL */ +static void +umul_emit( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_mul(&bld_base->uint_bld, + emit_data->args[0], emit_data->args[1]); +} + /* TGSI_OPCODE_XPD */ static void @@ -776,6 +814,11 @@ lp_set_default_actions(struct lp_build_tgsi_context * bld_base) bld_base->op_actions[TGSI_OPCODE_SFL].emit = sfl_emit; bld_base->op_actions[TGSI_OPCODE_STR].emit = str_emit; bld_base->op_actions[TGSI_OPCODE_SUB].emit = sub_emit; + + bld_base->op_actions[TGSI_OPCODE_UARL].emit = mov_emit; + bld_base->op_actions[TGSI_OPCODE_U2F].emit = u2f_emit; + bld_base->op_actions[TGSI_OPCODE_UMAD].emit = umad_emit; + bld_base->op_actions[TGSI_OPCODE_UMUL].emit = umul_emit; } /* CPU Only default actions */ @@ -807,6 +850,17 @@ add_emit_cpu( emit_data->args[0], emit_data->args[1]); } +/* TGSI_OPCODE_AND (CPU Only) */ +static void +and_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_and(&bld_base->uint_bld, + emit_data->args[0], emit_data->args[1]); +} + /* TGSI_OPCODE_ARL (CPU Only) */ static void arl_emit_cpu( @@ -919,6 +973,17 @@ exp_emit_cpu( emit_data->output[TGSI_CHAN_W] = bld_base->base.one; } +/* TGSI_OPCODE_F2I (CPU Only) */ +static void +f2i_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_itrunc(&bld_base->base, + emit_data->args[0]); +} + /* TGSI_OPCODE_FLR (CPU Only) */ static void @@ -931,6 +996,111 @@ flr_emit_cpu( emit_data->args[0]); } +/* TGSI_OPCODE_I2F (CPU Only) */ +static void +i2f_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_int_to_float(&bld_base->base, + emit_data->args[0]); +} + +/* TGSI_OPCODE_IDIV (CPU Only) */ +static void +idiv_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_div(&bld_base->int_bld, + emit_data->args[0], emit_data->args[1]); +} + +/* TGSI_OPCODE_INEG (CPU Only) */ +static void +ineg_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_sub(&bld_base->int_bld, + bld_base->int_bld.zero, + emit_data->args[0]); +} + +/* TGSI_OPCODE_ISET Helper (CPU Only) */ +static void +iset_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 nz = lp_build_const_vec(bld_base->base.gallivm, + bld_base->int_bld.type, ~0U); + LLVMValueRef cond = lp_build_cmp(&bld_base->int_bld, pipe_func, + emit_data->args[0], emit_data->args[1]); + emit_data->output[emit_data->chan] = lp_build_select(&bld_base->int_bld, + cond, + nz, + bld_base->int_bld.zero); +} + +/* TGSI_OPCODE_IMAX (CPU Only) */ +static void +imax_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_max(&bld_base->int_bld, + emit_data->args[0], emit_data->args[1]); +} + +/* TGSI_OPCODE_IMIN (CPU Only) */ +static void +imin_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_min(&bld_base->int_bld, + emit_data->args[0], emit_data->args[1]); +} + +/* TGSI_OPCODE_ISGE (CPU Only) */ +static void +isge_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + iset_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_GEQUAL); +} + +/* TGSI_OPCODE_ISHR (CPU Only) */ +static void +ishr_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_shr(&bld_base->int_bld, + emit_data->args[0], emit_data->args[1]); +} + +/* TGSI_OPCODE_ISLT (CPU Only) */ +static void +islt_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + iset_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_LESS); +} + /* TGSI_OPCODE_LG2 (CPU Only) */ static void lg2_emit_cpu( @@ -991,6 +1161,39 @@ min_emit_cpu( emit_data->args[0], emit_data->args[1]); } +/* TGSI_OPCODE_MOD (CPU Only) */ +static void +mod_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_mod(&bld_base->int_bld, + emit_data->args[0], emit_data->args[1]); +} + +/* TGSI_OPCODE_NOT */ +static void +not_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_not(&bld_base->base, + emit_data->args[0]); +} + +/* TGSI_OPCODE_OR (CPU Only) */ +static void +or_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_or(&bld_base->uint_bld, + emit_data->args[0], emit_data->args[1]); +} + /* TGSI_OPCODE_POW (CPU Only) */ static void pow_emit_cpu( @@ -1089,6 +1292,17 @@ sgt_emit_cpu( set_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_GREATER); } +/* TGSI_OPCODE_SHL (CPU Only) */ +static void +shl_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_shl(&bld_base->uint_bld, + emit_data->args[0], emit_data->args[1]); +} + /* TGSI_OPCODE_SIN (CPU Only) */ static void sin_emit_cpu( @@ -1111,7 +1325,6 @@ sle_emit_cpu( } /* TGSI_OPCODE_SLT (CPU Only) */ - static void slt_emit_cpu( const struct lp_build_tgsi_action * action, @@ -1169,6 +1382,144 @@ trunc_emit_cpu( emit_data->args[0]); } +/* TGSI_OPCODE_UADD (CPU Only) */ +static void +uadd_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_add(&bld_base->uint_bld, + emit_data->args[0], emit_data->args[1]); +} + +/* TGSI_OPCODE_UDIV (CPU Only) */ +static void +udiv_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_div(&bld_base->uint_bld, + emit_data->args[0], emit_data->args[1]); +} + +/* TGSI_OPCODE_UMAX (CPU Only) */ +static void +umax_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_max(&bld_base->uint_bld, + emit_data->args[0], emit_data->args[1]); +} + +/* TGSI_OPCODE_UMIN (CPU Only) */ +static void +umin_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_min(&bld_base->uint_bld, + emit_data->args[0], emit_data->args[1]); +} + +/* TGSI_OPCODE_UMOD (CPU Only) */ +static void +umod_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_mod(&bld_base->uint_bld, + emit_data->args[0], emit_data->args[1]); +} + +/* TGSI_OPCODE_USET Helper (CPU Only) */ +static void +uset_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 nz = lp_build_const_vec(bld_base->base.gallivm, + bld_base->uint_bld.type, ~0U); + LLVMValueRef cond = lp_build_cmp(&bld_base->uint_bld, pipe_func, + emit_data->args[0], emit_data->args[1]); + emit_data->output[emit_data->chan] = lp_build_select(&bld_base->uint_bld, + cond, + nz, + bld_base->uint_bld.zero); +} + + +/* TGSI_OPCODE_USEQ (CPU Only) */ +static void +useq_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + uset_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_EQUAL); +} + +/* TGSI_OPCODE_ISGE (CPU Only) */ +static void +usge_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + uset_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_GEQUAL); +} + +/* TGSI_OPCODE_USHR (CPU Only) */ +static void +ushr_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_shr(&bld_base->uint_bld, + emit_data->args[0], emit_data->args[1]); +} + +/* TGSI_OPCODE_ISLT (CPU Only) */ +static void +uslt_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + uset_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_LESS); +} + +/* TGSI_OPCODE_USNE (CPU Only) */ + +static void +usne_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + uset_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_NOTEQUAL); +} + +/* TGSI_OPCODE_XOR */ +static void +xor_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_xor(&bld_base->uint_bld, + emit_data->args[0], + emit_data->args[1]); +} + void lp_set_default_actions_cpu( struct lp_build_tgsi_context * bld_base) @@ -1176,6 +1527,7 @@ lp_set_default_actions_cpu( lp_set_default_actions(bld_base); bld_base->op_actions[TGSI_OPCODE_ABS].emit = abs_emit_cpu; bld_base->op_actions[TGSI_OPCODE_ADD].emit = add_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_AND].emit = and_emit_cpu; bld_base->op_actions[TGSI_OPCODE_ARL].emit = arl_emit_cpu; bld_base->op_actions[TGSI_OPCODE_ARR].emit = arr_emit_cpu; bld_base->op_actions[TGSI_OPCODE_CEIL].emit = ceil_emit_cpu; @@ -1185,11 +1537,25 @@ lp_set_default_actions_cpu( bld_base->op_actions[TGSI_OPCODE_DIV].emit = div_emit_cpu; bld_base->op_actions[TGSI_OPCODE_EX2].emit = ex2_emit_cpu; bld_base->op_actions[TGSI_OPCODE_EXP].emit = exp_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_F2I].emit = f2i_emit_cpu; bld_base->op_actions[TGSI_OPCODE_FLR].emit = flr_emit_cpu; + + bld_base->op_actions[TGSI_OPCODE_I2F].emit = i2f_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_IDIV].emit = idiv_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_INEG].emit = ineg_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_IMAX].emit = imax_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_IMIN].emit = imin_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_ISGE].emit = isge_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_ISHR].emit = ishr_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_ISLT].emit = islt_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_LG2].emit = lg2_emit_cpu; bld_base->op_actions[TGSI_OPCODE_LOG].emit = log_emit_cpu; bld_base->op_actions[TGSI_OPCODE_MAX].emit = max_emit_cpu; bld_base->op_actions[TGSI_OPCODE_MIN].emit = min_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_MOD].emit = mod_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_NOT].emit = not_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_OR].emit = or_emit_cpu; bld_base->op_actions[TGSI_OPCODE_POW].emit = pow_emit_cpu; bld_base->op_actions[TGSI_OPCODE_RCP].emit = rcp_emit_cpu; bld_base->op_actions[TGSI_OPCODE_ROUND].emit = round_emit_cpu; @@ -1197,6 +1563,7 @@ lp_set_default_actions_cpu( bld_base->op_actions[TGSI_OPCODE_SGE].emit = sge_emit_cpu; bld_base->op_actions[TGSI_OPCODE_SGT].emit = sgt_emit_cpu; bld_base->op_actions[TGSI_OPCODE_SIN].emit = sin_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_SHL].emit = shl_emit_cpu; bld_base->op_actions[TGSI_OPCODE_SLE].emit = sle_emit_cpu; bld_base->op_actions[TGSI_OPCODE_SLT].emit = slt_emit_cpu; bld_base->op_actions[TGSI_OPCODE_SNE].emit = sne_emit_cpu; @@ -1205,4 +1572,18 @@ lp_set_default_actions_cpu( bld_base->op_actions[TGSI_OPCODE_TRUNC].emit = trunc_emit_cpu; bld_base->rsq_action.emit = recip_sqrt_emit_cpu; + + bld_base->op_actions[TGSI_OPCODE_UADD].emit = uadd_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_UDIV].emit = udiv_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_UMAX].emit = umax_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_UMIN].emit = umin_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_UMOD].emit = umod_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_USEQ].emit = useq_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_USGE].emit = usge_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_USHR].emit = ushr_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_USLT].emit = uslt_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_USNE].emit = usne_emit_cpu; + + bld_base->op_actions[TGSI_OPCODE_XOR].emit = xor_emit_cpu; + } -- 2.30.2