diff options
author | Roland Scheidegger <[email protected]> | 2016-01-29 02:49:22 +0100 |
---|---|---|
committer | Roland Scheidegger <[email protected]> | 2016-02-02 05:58:19 +0100 |
commit | 5171ec9ca92ce489e32c227ae3b4b6df621bbf40 (patch) | |
tree | 7474f33031da46893c0eade1564a7c6cc034551f /src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c | |
parent | dc16086e3b616f767ab31c86505502c4df7739ac (diff) |
gallivm: add PK2H/UP2H support
Add support for these opcodes, the conversion functions were already
there albeit need some new packing stuff.
Just like the tgsi version, piglit won't like it for all the same
reasons, so it's disabled (UP2H passes piglit arb_shader_language_packing
tests, albeit since PK2H won't due those rounding differences I don't
know if that one works or not as the piglit test is rather difficult to
deal with).
Diffstat (limited to 'src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c')
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c index 6f75bec5005..f6b42eead1e 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c @@ -45,8 +45,10 @@ #include "lp_bld_arit.h" #include "lp_bld_bitarit.h" #include "lp_bld_const.h" +#include "lp_bld_conv.h" #include "lp_bld_gather.h" #include "lp_bld_logic.h" +#include "lp_bld_pack.h" #include "tgsi/tgsi_exec.h" @@ -530,6 +532,75 @@ static struct lp_build_tgsi_action log_action = { log_emit /* emit */ }; +/* TGSI_OPCODE_PK2H */ + +static void +pk2h_fetch_args( + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + /* src0.x */ + emit_data->args[0] = lp_build_emit_fetch(bld_base, emit_data->inst, + 0, TGSI_CHAN_X); + /* src0.y */ + emit_data->args[1] = lp_build_emit_fetch(bld_base, emit_data->inst, + 0, TGSI_CHAN_Y); +} + +static void +pk2h_emit(const struct lp_build_tgsi_action *action, + struct lp_build_tgsi_context *bld_base, + struct lp_build_emit_data *emit_data) +{ + struct gallivm_state *gallivm = bld_base->base.gallivm; + struct lp_type f16i_t; + LLVMValueRef lo, hi, res; + + f16i_t = lp_type_uint_vec(16, bld_base->base.type.length * 32); + lo = lp_build_float_to_half(gallivm, emit_data->args[0]); + hi = lp_build_float_to_half(gallivm, emit_data->args[1]); + /* maybe some interleave doubling vector width would be useful... */ + lo = lp_build_pad_vector(gallivm, lo, bld_base->base.type.length * 2); + hi = lp_build_pad_vector(gallivm, hi, bld_base->base.type.length * 2); + res = lp_build_interleave2(gallivm, f16i_t, lo, hi, 0); + + emit_data->output[emit_data->chan] = res; +} + +static struct lp_build_tgsi_action pk2h_action = { + pk2h_fetch_args, /* fetch_args */ + pk2h_emit /* emit */ +}; + +/* TGSI_OPCODE_UP2H */ + +static void +up2h_emit(const struct lp_build_tgsi_action *action, + struct lp_build_tgsi_context *bld_base, + struct lp_build_emit_data *emit_data) +{ + struct gallivm_state *gallivm = bld_base->base.gallivm; + LLVMBuilderRef builder = gallivm->builder; + LLVMContextRef context = gallivm->context; + LLVMValueRef lo, hi, res[2], arg; + unsigned nr = bld_base->base.type.length; + LLVMTypeRef i16t = LLVMVectorType(LLVMInt16TypeInContext(context), nr * 2); + + arg = LLVMBuildBitCast(builder, emit_data->args[0], i16t, ""); + lo = lp_build_uninterleave1(gallivm, nr * 2, arg, 0); + hi = lp_build_uninterleave1(gallivm, nr * 2, arg, 1); + res[0] = lp_build_half_to_float(gallivm, lo); + res[1] = lp_build_half_to_float(gallivm, hi); + + emit_data->output[0] = emit_data->output[2] = res[0]; + emit_data->output[1] = emit_data->output[3] = res[1]; +} + +static struct lp_build_tgsi_action up2h_action = { + scalar_unary_fetch_args, /* fetch_args */ + up2h_emit /* emit */ +}; + /* TGSI_OPCODE_LRP */ static void @@ -1032,10 +1103,12 @@ lp_set_default_actions(struct lp_build_tgsi_context * bld_base) bld_base->op_actions[TGSI_OPCODE_EXP] = exp_action; bld_base->op_actions[TGSI_OPCODE_LIT] = lit_action; bld_base->op_actions[TGSI_OPCODE_LOG] = log_action; + bld_base->op_actions[TGSI_OPCODE_PK2H] = pk2h_action; bld_base->op_actions[TGSI_OPCODE_RSQ] = rsq_action; bld_base->op_actions[TGSI_OPCODE_SQRT] = sqrt_action; bld_base->op_actions[TGSI_OPCODE_POW] = pow_action; bld_base->op_actions[TGSI_OPCODE_SCS] = scs_action; + bld_base->op_actions[TGSI_OPCODE_UP2H] = up2h_action; bld_base->op_actions[TGSI_OPCODE_XPD] = xpd_action; bld_base->op_actions[TGSI_OPCODE_BREAKC].fetch_args = scalar_unary_fetch_args; |