From: Nicolai Hähnle <nicolai.haeh...@amd.com> --- src/gallium/auxiliary/gallivm/lp_bld_tgsi.c | 18 +++++++++++++++++- src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.h | 5 +++++ src/gallium/auxiliary/tgsi/tgsi_exec.h | 9 +++++++++ 3 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c index 66f752989ab..b33976bb647 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c @@ -257,25 +257,31 @@ lp_build_tgsi_inst_llvm( break; } /* Check if the opcode has been implemented */ if (!action->emit) { return FALSE; } 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; emit_data.info = info; /* Emit the instructions */ if (info->output_mode == TGSI_OUTPUT_COMPONENTWISE && bld_base->soa) { TGSI_FOR_EACH_DST0_ENABLED_CHANNEL(inst, chan_index) { int src_index = get_src_chan_idx(inst->Instruction.Opcode, chan_index); /* ignore channels 1/3 in double dst */ @@ -302,25 +308,35 @@ lp_build_tgsi_inst_llvm( } action->emit(action, bld_base, &emit_data); /* Replicate the output values */ if (info->output_mode == TGSI_OUTPUT_REPLICATE && bld_base->soa) { val = emit_data.output[0]; memset(emit_data.output, 0, sizeof(emit_data.output)); 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; } LLVMValueRef lp_build_emit_fetch_src( struct lp_build_tgsi_context *bld_base, const struct tgsi_full_src_register *reg, enum tgsi_opcode_type stype, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.h index 463d44eb450..c92517fee28 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.h @@ -75,20 +75,25 @@ struct lp_build_emit_data { * This is used to specify the src channel to read from for doubles. */ unsigned src_chan; /** The lp_build_tgsi_action::emit 'executes' the opcode and writes the * results to this array. */ 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; const struct tgsi_opcode_info * info; }; struct lp_build_tgsi_action { /** diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 9d7e65f2c51..f656133400d 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -51,20 +51,29 @@ extern "C" { #define TGSI_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ ((INST)->Dst[0].Register.WriteMask & (1 << (CHAN))) #define TGSI_IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\ if (TGSI_IS_DST0_CHANNEL_ENABLED( INST, CHAN )) #define TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\ 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. */ union tgsi_exec_channel { float f[TGSI_QUAD_SIZE]; int i[TGSI_QUAD_SIZE]; unsigned u[TGSI_QUAD_SIZE]; }; -- 2.11.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev