Am 14.04.2013 10:12, schrieb jfons...@vmware.com: > From: José Fonseca <jfons...@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 <srol...@vmware.com> _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev