[Mesa-dev] [PATCH 2/2] gallium: Desambiguate TGSI_OPCODE_IF.
Roland Scheidegger
sroland at vmware.com
Sun Apr 14 08:24:27 PDT 2013
Am 14.04.2013 10:12, schrieb jfonseca at vmware.com:
> From: José Fonseca <jfonseca at vmware.com>
>
> TGSI_OPCODE_IF condition had two possible interpretations:
>
> - src.x != 0.0f
>
> - Mesa statetracker when PIPE_SHADER_CAP_INTEGERS was false either for
> vertex and fragment shaders
> - gallivm/llvmpipe
> - postprocess
> - vl state tracker
> - vega state tracker
> - most old drivers
> - old internal state trackers
> - many graw examples
>
> - src.x != 0U
>
> - Mesa statetracker when PIPE_SHADER_CAP_INTEGERS was true for both
> vertex and fragment shaders
> - tgsi_exec/softpipe
> - r600
> - radeonsi
> - nv50
>
> And drivers that use draw module also were a mess (because Mesa would
> emit float IFs, but draw module supports native integers so it would
> interpret IF arg as integers...)
>
> This sort of works if the source argument is limited to float +0.0f or
> +1.0f, integer 0, but would fail if source is float -0.0f, or integer in
> the float NaN range. It could also fail if source is integer 1, and
> hardware flushes denormalized numbers to zero.
>
> But with this change there are now two opcodes, IF and UIF, with clear
> meaning.
>
> Drivers that do not support native integers do not need to worry about
> UIF. However, for backwards compatibility with old state trackers and
> examples, it is advisable that native integer capable drivers also
> support the float IF opcode.
>
> I tried to implement this for r600 and radeonsi based on the surrounding
> code. I couldn't do this for nouveau, so I just shunted IF/UIF
> together, which matches the current behavior.
> ---
> src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c | 1 +
> src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c | 1 +
> src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c | 1 +
> src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 19 ++++++++-
> src/gallium/auxiliary/tgsi/tgsi_dump.c | 2 +
> src/gallium/auxiliary/tgsi/tgsi_exec.c | 22 +++++++++++
> src/gallium/auxiliary/tgsi/tgsi_info.c | 2 +-
> src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h | 1 +
> src/gallium/docs/source/tgsi.rst | 21 ++++++++--
> .../drivers/nv50/codegen/nv50_ir_from_tgsi.cpp | 6 +++
> src/gallium/drivers/r600/r600_shader.c | 21 +++++++---
> .../drivers/radeon/radeon_setup_tgsi_llvm.c | 41 ++++++++++++++++----
> src/gallium/include/pipe/p_shader_tokens.h | 2 +-
> src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 8 +++-
> src/mesa/state_tracker/st_mesa_to_tgsi.c | 12 +++++-
> 15 files changed, 137 insertions(+), 23 deletions(-)
>
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
> index c71c1f1..e1c362b 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
> @@ -868,6 +868,7 @@ lp_set_default_actions(struct lp_build_tgsi_context * bld_base)
> bld_base->op_actions[TGSI_OPCODE_COS].fetch_args = scalar_unary_fetch_args;
> bld_base->op_actions[TGSI_OPCODE_EX2].fetch_args = scalar_unary_fetch_args;
> bld_base->op_actions[TGSI_OPCODE_IF].fetch_args = scalar_unary_fetch_args;
> + bld_base->op_actions[TGSI_OPCODE_UIF].fetch_args = scalar_unary_fetch_args;
> bld_base->op_actions[TGSI_OPCODE_KIL].fetch_args = kil_fetch_args;
> bld_base->op_actions[TGSI_OPCODE_KILP].fetch_args = kilp_fetch_args;
> bld_base->op_actions[TGSI_OPCODE_RCP].fetch_args = scalar_unary_fetch_args;
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c
> index 98bce0e..223184d 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c
> @@ -837,6 +837,7 @@ lp_emit_instruction_aos(
> return FALSE;
>
> case TGSI_OPCODE_IF:
> + case TGSI_OPCODE_UIF:
> return FALSE;
>
> case TGSI_OPCODE_BGNLOOP:
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c
> index 3c79abf..b00aa09 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c
> @@ -389,6 +389,7 @@ analyse_instruction(struct analysis_context *ctx,
>
> switch (inst->Instruction.Opcode) {
> case TGSI_OPCODE_IF:
> + case TGSI_OPCODE_UIF:
> case TGSI_OPCODE_ELSE:
> case TGSI_OPCODE_ENDIF:
> case TGSI_OPCODE_BGNLOOP:
Could you also add it to tgsi_opcode_infer_src_type?
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index 239530d..362a1de 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -1732,7 +1732,8 @@ near_end_of_shader(struct lp_build_tgsi_soa_context *bld,
> opcode == TGSI_OPCODE_CAL ||
> opcode == TGSI_OPCODE_CALLNZ ||
> opcode == TGSI_OPCODE_IF ||
> - opcode == TGSI_OPCODE_BGNLOOP ||
> + opcode == TGSI_OPCODE_UIF ||
> + opcode == TGSI_OPCODE_BGNLOOP ||
> opcode == TGSI_OPCODE_SWITCH)
> return FALSE;
> }
> @@ -2395,6 +2396,21 @@ if_emit(
> }
>
> static void
> +uif_emit(
> + const struct lp_build_tgsi_action * action,
> + struct lp_build_tgsi_context * bld_base,
> + struct lp_build_emit_data * emit_data)
> +{
> + LLVMValueRef tmp;
> + struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
> + struct lp_build_context *uint_bld = &bld_base->uint_bld;
> +
> + tmp = lp_build_cmp(uint_bld, PIPE_FUNC_NOTEQUAL,
> + emit_data->args[0], uint_bld->zero);
> + lp_exec_mask_cond_push(&bld->exec_mask, tmp);
> +}
> +
> +static void
> bgnloop_emit(
> const struct lp_build_tgsi_action * action,
> struct lp_build_tgsi_context * bld_base,
> @@ -2742,6 +2758,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm,
> bld.bld_base.op_actions[TGSI_OPCODE_ENDLOOP].emit = endloop_emit;
> bld.bld_base.op_actions[TGSI_OPCODE_ENDSUB].emit = endsub_emit;
> bld.bld_base.op_actions[TGSI_OPCODE_IF].emit = if_emit;
> + bld.bld_base.op_actions[TGSI_OPCODE_UIF].emit = uif_emit;
> bld.bld_base.op_actions[TGSI_OPCODE_KIL].emit = kil_emit;
> bld.bld_base.op_actions[TGSI_OPCODE_KILP].emit = kilp_emit;
> bld.bld_base.op_actions[TGSI_OPCODE_NRM].emit = nrm_emit;
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
> index 365665f..77b75b1 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
> @@ -589,6 +589,7 @@ iter_instruction(
>
> switch (inst->Instruction.Opcode) {
> case TGSI_OPCODE_IF:
> + case TGSI_OPCODE_UIF:
> case TGSI_OPCODE_ELSE:
> case TGSI_OPCODE_BGNLOOP:
> case TGSI_OPCODE_ENDLOOP:
> @@ -600,6 +601,7 @@ iter_instruction(
>
> /* update indentation */
> if (inst->Instruction.Opcode == TGSI_OPCODE_IF ||
> + inst->Instruction.Opcode == TGSI_OPCODE_UIF ||
> inst->Instruction.Opcode == TGSI_OPCODE_ELSE ||
> inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP) {
> ctx->indentation += indent_spaces;
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> index 8579d8a..15eea1f 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
> @@ -3982,6 +3982,28 @@ exec_instruction(
> mach->CondStack[mach->CondStackTop++] = mach->CondMask;
> FETCH( &r[0], 0, TGSI_CHAN_X );
> /* update CondMask */
> + if( ! r[0].f[0] ) {
> + mach->CondMask &= ~0x1;
> + }
> + if( ! r[0].f[1] ) {
> + mach->CondMask &= ~0x2;
> + }
> + if( ! r[0].f[2] ) {
> + mach->CondMask &= ~0x4;
> + }
> + if( ! r[0].f[3] ) {
> + mach->CondMask &= ~0x8;
> + }
> + UPDATE_EXEC_MASK(mach);
> + /* Todo: If CondMask==0, jump to ELSE */
> + break;
> +
> + case TGSI_OPCODE_UIF:
> + /* push CondMask */
> + assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING);
> + mach->CondStack[mach->CondStackTop++] = mach->CondMask;
> + FETCH( &r[0], 0, TGSI_CHAN_X );
While this was there before, technically using FETCH is not entirely
correct since it will fetch a float. Now since it goes into a union
anyway this shouldn't really matter, but src modifiers would be handled
wrong. I guess though modifiers aren't really allowed with that opcode.
> + /* update CondMask */
> if( ! r[0].u[0] ) {
> mach->CondMask &= ~0x1;
> }
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
> index 716b16b..11ba0b6 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_info.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
> @@ -112,7 +112,7 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
> { 1, 2, 1, 0, 0, 0, OTHR, "TXL", TGSI_OPCODE_TXL },
> { 0, 0, 0, 0, 0, 0, NONE, "BRK", TGSI_OPCODE_BRK },
> { 0, 1, 0, 1, 0, 1, NONE, "IF", TGSI_OPCODE_IF },
> - { 1, 1, 0, 0, 0, 1, NONE, "", 75 }, /* removed */
> + { 0, 1, 0, 1, 0, 1, NONE, "UIF", TGSI_OPCODE_UIF },
> { 0, 1, 0, 0, 0, 1, NONE, "", 76 }, /* removed */
> { 0, 0, 0, 1, 1, 1, NONE, "ELSE", TGSI_OPCODE_ELSE },
> { 0, 0, 0, 0, 1, 0, NONE, "ENDIF", TGSI_OPCODE_ENDIF },
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
> index b8519c6..a6bcbb0 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
> @@ -128,6 +128,7 @@ OP12(DP2)
> OP12_TEX(TXL)
> OP00(BRK)
> OP01_LBL(IF)
> +OP01_LBL(UIF)
> OP00_LBL(ELSE)
> OP00(ENDIF)
> OP01(PUSHA)
> diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst
> index 0002626..b7180f8 100644
> --- a/src/gallium/docs/source/tgsi.rst
> +++ b/src/gallium/docs/source/tgsi.rst
> @@ -864,19 +864,32 @@ This instruction replicates its result.
> TBD
>
>
> -.. opcode:: IF - If
> +.. opcode:: IF - Float If
>
> - TBD
> + Start an IF ... ELSE .. ENDIF block. Condition evaluates to true if
> +
> + src0.x != 0.0
> +
> + where src0.x is interpreted as a floating point register.
Maybe should say something wrt evaluation of NaNs? I know we haven't
really established rules for comparisons etc. wrt NaNs but those
bools-as-float make me cry. I guess it is no different though than other
float opcodes, if we now really have a definition saying IF takes _any_
float not just a bool-as-float which was loosely implied before.
> +
> +
> +.. opcode:: UIF - Bitwise If
> +
> + Start an UIF ... ELSE .. ENDIF block. Condition evaluates to true if
> +
> + src0.x != 0
> +
> + where src0.x is interpreted as an integer register.
>
>
> .. opcode:: ELSE - Else
>
> - TBD
> + Starts an else block, after an IF or UIF statement.
>
>
> .. opcode:: ENDIF - End If
>
> - TBD
> + Ends an IF or UIF block.
>
>
> .. opcode:: PUSHA - Push Address Register On Stack
> diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
> index 6897691..054c75e 100644
> --- a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
> +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
> @@ -242,6 +242,7 @@ unsigned int Instruction::srcMask(unsigned int s) const
> case TGSI_OPCODE_SCS:
> return 0x1;
> case TGSI_OPCODE_IF:
> + case TGSI_OPCODE_UIF:
> return 0x1;
> case TGSI_OPCODE_LIT:
> return 0xb;
> @@ -2430,6 +2431,11 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
> mkOp1(op, TYPE_U32, NULL, src0)->fixed = 1;
> break;
> case TGSI_OPCODE_IF:
> + /* XXX: fall-through into UIF, but this might lead to
> + * incorrect behavior on state trackers and auxiliary
> + * modules that emit float bool IFs regardless of
> + * native integer support */
> + case TGSI_OPCODE_UIF:
> {
> BasicBlock *ifBB = new BasicBlock(func);
>
> diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
> index 44b5ce5..6e8c7a2 100644
> --- a/src/gallium/drivers/r600/r600_shader.c
> +++ b/src/gallium/drivers/r600/r600_shader.c
> @@ -5730,6 +5730,18 @@ static void break_loop_on_flag(struct r600_shader_ctx *ctx, unsigned fc_sp)
>
> static int tgsi_if(struct r600_shader_ctx *ctx)
> {
> + emit_logic_pred(ctx, ALU_OP2_PRED_SETNE);
> +
> + r600_bytecode_add_cfinst(ctx->bc, CF_OP_JUMP);
> +
> + fc_pushlevel(ctx, FC_IF);
> +
> + callstack_push(ctx, FC_PUSH_VPM);
> + return 0;
> +}
> +
> +static int tgsi_uif(struct r600_shader_ctx *ctx)
> +{
> emit_logic_pred(ctx, ALU_OP2_PRED_SETNE_INT);
>
> r600_bytecode_add_cfinst(ctx->bc, CF_OP_JUMP);
> @@ -5991,8 +6003,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = {
> {TGSI_OPCODE_TXL, 0, FETCH_OP_SAMPLE_L, tgsi_tex},
> {TGSI_OPCODE_BRK, 0, CF_OP_LOOP_BREAK, tgsi_loop_brk_cont},
> {TGSI_OPCODE_IF, 0, ALU_OP0_NOP, tgsi_if},
> - /* gap */
> - {75, 0, ALU_OP0_NOP, tgsi_unsupported},
> + {TGSI_OPCODE_UIF, 0, ALU_OP0_NOP, tgsi_uif},
> {76, 0, ALU_OP0_NOP, tgsi_unsupported},
> {TGSI_OPCODE_ELSE, 0, ALU_OP0_NOP, tgsi_else},
> {TGSI_OPCODE_ENDIF, 0, ALU_OP0_NOP, tgsi_endif},
> @@ -6185,8 +6196,7 @@ static struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] = {
> {TGSI_OPCODE_TXL, 0, FETCH_OP_SAMPLE_L, tgsi_tex},
> {TGSI_OPCODE_BRK, 0, CF_OP_LOOP_BREAK, tgsi_loop_brk_cont},
> {TGSI_OPCODE_IF, 0, ALU_OP0_NOP, tgsi_if},
> - /* gap */
> - {75, 0, ALU_OP0_NOP, tgsi_unsupported},
> + {TGSI_OPCODE_UIF, 0, ALU_OP0_NOP, tgsi_uif},
> {76, 0, ALU_OP0_NOP, tgsi_unsupported},
> {TGSI_OPCODE_ELSE, 0, ALU_OP0_NOP, tgsi_else},
> {TGSI_OPCODE_ENDIF, 0, ALU_OP0_NOP, tgsi_endif},
> @@ -6379,8 +6389,7 @@ static struct r600_shader_tgsi_instruction cm_shader_tgsi_instruction[] = {
> {TGSI_OPCODE_TXL, 0, FETCH_OP_SAMPLE_L, tgsi_tex},
> {TGSI_OPCODE_BRK, 0, CF_OP_LOOP_BREAK, tgsi_loop_brk_cont},
> {TGSI_OPCODE_IF, 0, ALU_OP0_NOP, tgsi_if},
> - /* gap */
> - {75, 0, ALU_OP0_NOP, tgsi_unsupported},
> + {TGSI_OPCODE_UIF, 0, ALU_OP0_NOP, tgsi_uif},
> {76, 0, ALU_OP0_NOP, tgsi_unsupported},
> {TGSI_OPCODE_ELSE, 0, ALU_OP0_NOP, tgsi_else},
> {TGSI_OPCODE_ENDIF, 0, ALU_OP0_NOP, tgsi_endif},
> diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
> index 314c963..dfc7cbc 100644
> --- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
> +++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
> @@ -515,20 +515,16 @@ static void endloop_emit(
> ctx->loop_depth--;
> }
>
> -static void if_emit(
> +static void if_cond_emit(
> const struct lp_build_tgsi_action * action,
> struct lp_build_tgsi_context * bld_base,
> - struct lp_build_emit_data * emit_data)
> + struct lp_build_emit_data * emit_data,
> + LLVMValueRef cond)
> {
> struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
> struct gallivm_state * gallivm = bld_base->base.gallivm;
> - LLVMValueRef cond;
> LLVMBasicBlockRef if_block, else_block, endif_block;
>
> - cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE,
> - bitcast(bld_base, TGSI_TYPE_UNSIGNED, emit_data->args[0]),
> - bld_base->int_bld.zero, "");
> -
> endif_block = LLVMAppendBasicBlockInContext(gallivm->context,
> ctx->main_fn, "ENDIF");
> if_block = LLVMInsertBasicBlockInContext(gallivm->context,
> @@ -545,6 +541,36 @@ static void if_emit(
> ctx->branch[ctx->branch_depth - 1].has_else = 0;
> }
>
> +static void if_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;
> + LLVMValueRef cond;
> +
> + cond = LLVMBuildFCmp(gallivm->builder, LLVMRealUNE,
> + emit_data->args[0],
> + bld_base->base.zero, "");
> +
> + if_cond_emit(action, bld_base, emit_data, cond);
> +}
> +
> +static void uif_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;
> + LLVMValueRef cond;
> +
> + cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE,
> + bitcast(bld_base, TGSI_TYPE_UNSIGNED, emit_data->args[0]),
> + bld_base->int_bld.zero, "");
> +
> + if_cond_emit(action, bld_base, emit_data, cond);
> +}
> +
> static void kil_emit(
> const struct lp_build_tgsi_action * action,
> struct lp_build_tgsi_context * bld_base,
> @@ -1209,6 +1235,7 @@ void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
> bld_base->op_actions[TGSI_OPCODE_IABS].intr_name = "llvm.AMDIL.abs.";
> bld_base->op_actions[TGSI_OPCODE_IDIV].emit = emit_idiv;
> bld_base->op_actions[TGSI_OPCODE_IF].emit = if_emit;
> + bld_base->op_actions[TGSI_OPCODE_IF].emit = uif_emit;
> bld_base->op_actions[TGSI_OPCODE_IMAX].emit = build_tgsi_intrinsic_nomem;
> bld_base->op_actions[TGSI_OPCODE_IMAX].intr_name = "llvm.AMDGPU.imax";
> bld_base->op_actions[TGSI_OPCODE_IMIN].emit = build_tgsi_intrinsic_nomem;
> diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
> index 6fcd151..50de2d3 100644
> --- a/src/gallium/include/pipe/p_shader_tokens.h
> +++ b/src/gallium/include/pipe/p_shader_tokens.h
> @@ -335,7 +335,7 @@ struct tgsi_property_data {
> #define TGSI_OPCODE_TXL 72
> #define TGSI_OPCODE_BRK 73
> #define TGSI_OPCODE_IF 74
> - /* gap */
> +#define TGSI_OPCODE_UIF 75
> #define TGSI_OPCODE_ELSE 77
> #define TGSI_OPCODE_ENDIF 78
> /* gap */
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index 589c912..f2eb3e7 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -2978,12 +2978,15 @@ glsl_to_tgsi_visitor::visit(ir_discard *ir)
> void
> glsl_to_tgsi_visitor::visit(ir_if *ir)
> {
> + unsigned if_opcode;
> glsl_to_tgsi_instruction *if_inst;
>
> ir->condition->accept(this);
> assert(this->result.file != PROGRAM_UNDEFINED);
>
> - if_inst = emit(ir->condition, TGSI_OPCODE_IF, undef_dst, this->result);
> + if_opcode = native_integers ? TGSI_OPCODE_UIF : TGSI_OPCODE_IF;
> +
> + if_inst = emit(ir->condition, if_opcode, undef_dst, this->result);
>
> this->instructions.push_tail(if_inst);
>
> @@ -3462,6 +3465,7 @@ glsl_to_tgsi_visitor::copy_propagate(void)
> break;
>
> case TGSI_OPCODE_IF:
> + case TGSI_OPCODE_UIF:
> ++level;
> break;
>
> @@ -3664,6 +3668,7 @@ glsl_to_tgsi_visitor::eliminate_dead_code_advanced(void)
> break;
>
> case TGSI_OPCODE_IF:
> + case TGSI_OPCODE_UIF:
> ++level;
> /* fallthrough to default case to mark the condition as read */
>
> @@ -4389,6 +4394,7 @@ compile_tgsi_instruction(struct st_translate *t,
> case TGSI_OPCODE_ELSE:
> case TGSI_OPCODE_ENDLOOP:
> case TGSI_OPCODE_IF:
> + case TGSI_OPCODE_UIF:
> assert(num_dst == 0);
> ureg_label_insn(ureg,
> inst->op,
> diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
> index 5471a9a..27d8bea 100644
> --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
> +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
> @@ -665,6 +665,7 @@ translate_opcode( unsigned op )
>
> static void
> compile_instruction(
> + struct gl_context *ctx,
> struct st_translate *t,
> const struct prog_instruction *inst,
> boolean clamp_dst_color_output)
> @@ -697,7 +698,6 @@ compile_instruction(
> case OPCODE_CAL:
> case OPCODE_ELSE:
> case OPCODE_ENDLOOP:
> - case OPCODE_IF:
> debug_assert(num_dst == 0);
> ureg_label_insn( ureg,
> translate_opcode( inst->Opcode ),
> @@ -705,6 +705,14 @@ compile_instruction(
> get_label( t, inst->BranchTarget ));
> return;
>
> + case OPCODE_IF:
> + debug_assert(num_dst == 0);
> + ureg_label_insn( ureg,
> + ctx->Const.NativeIntegers ? TGSI_OPCODE_UIF : TGSI_OPCODE_IF,
> + src, num_src,
> + get_label( t, inst->BranchTarget ));
> + return;
> +
> case OPCODE_TEX:
> case OPCODE_TXB:
> case OPCODE_TXD:
> @@ -1229,7 +1237,7 @@ st_translate_mesa_program(
> */
> for (i = 0; i < program->NumInstructions; i++) {
> set_insn_start( t, ureg_get_instruction_number( ureg ));
> - compile_instruction( t, &program->Instructions[i], clamp_color );
> + compile_instruction( ctx, t, &program->Instructions[i], clamp_color );
> }
>
> /* Fix up all emitted labels:
>
Oh and I think that really should be "Disambiguate" in the commit title.
Otherwise looks great, let's get rid of that mess.
Reviewed-by: Roland Scheidegger <sroland at vmware.com>
More information about the mesa-dev
mailing list