diff options
author | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2017-09-16 12:50:42 +0200 |
---|---|---|
committer | Nicolai Hähnle <nicolai.haehnle@amd.com> | 2017-09-16 13:18:42 +0200 |
commit | ad393c676176bde1972457c25f670cc50d3f60cd (patch) | |
tree | b5eaa0e867e6a8b33115f95188064c4fdf33a412 | |
parent | d686c347e5e73eaf26b825cbd9970de814f8d9dd (diff) |
gallivm: add support for TGSI instructions with two outputs
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi.c | 18 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.h | 5 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_exec.h | 9 |
3 files changed, 31 insertions, 1 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c index 66f752989a..b33976bb64 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c @@ -264,11 +264,17 @@ lp_build_tgsi_inst_llvm( memset(&emit_data, 0, sizeof(emit_data)); - assert(info->num_dst <= 1); + assert(info->num_dst <= 2); if (info->num_dst) { TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) { emit_data.output[chan_index] = bld_base->base.undef; } + + if (info->num_dst >= 2) { + TGSI_FOR_EACH_DST1_ENABLED_CHANNEL( inst, chan_index ) { + emit_data.output1[chan_index] = bld_base->base.undef; + } + } } emit_data.inst = inst; @@ -309,11 +315,21 @@ lp_build_tgsi_inst_llvm( TGSI_FOR_EACH_DST0_ENABLED_CHANNEL(inst, chan_index) { emit_data.output[chan_index] = val; } + + if (info->num_dst >= 2) { + val = emit_data.output1[0]; + memset(emit_data.output1, 0, sizeof(emit_data.output1)); + TGSI_FOR_EACH_DST1_ENABLED_CHANNEL(inst, chan_index) { + emit_data.output1[chan_index] = val; + } + } } } if (info->num_dst > 0 && info->opcode != TGSI_OPCODE_STORE) { bld_base->emit_store(bld_base, inst, info, 0, emit_data.output); + if (info->num_dst >= 2) + bld_base->emit_store(bld_base, inst, info, 1, emit_data.output1); } return TRUE; } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.h index 463d44eb45..c92517fee2 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.h @@ -82,6 +82,11 @@ struct lp_build_emit_data { LLVMValueRef output[4]; /** + * Secondary output for instruction that have a second destination register. + */ + LLVMValueRef output1[4]; + + /** * The current instruction that is being 'executed'. */ const struct tgsi_full_instruction * inst; diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 9d7e65f2c5..f656133400 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -58,6 +58,15 @@ extern "C" { TGSI_FOR_EACH_CHANNEL( CHAN )\ TGSI_IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN ) +#define TGSI_IS_DST1_CHANNEL_ENABLED( INST, CHAN )\ + ((INST)->Dst[1].Register.WriteMask & (1 << (CHAN))) + +#define TGSI_IF_IS_DST1_CHANNEL_ENABLED( INST, CHAN )\ + if (TGSI_IS_DST1_CHANNEL_ENABLED( INST, CHAN )) + +#define TGSI_FOR_EACH_DST1_ENABLED_CHANNEL( INST, CHAN )\ + TGSI_FOR_EACH_CHANNEL( CHAN )\ + TGSI_IF_IS_DST1_CHANNEL_ENABLED( INST, CHAN ) /** * Registers may be treated as float, signed int or unsigned int. |