[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