summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c1
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c1
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c1
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c17
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c22
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.c3
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h1
-rw-r--r--src/gallium/docs/source/tgsi.rst21
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp5
-rw-r--r--src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp2
-rw-r--r--src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp2
-rw-r--r--src/gallium/drivers/r600/r600_shader.c23
-rw-r--r--src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c41
-rw-r--r--src/gallium/include/pipe/p_shader_tokens.h2
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp8
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c12
17 files changed, 137 insertions, 27 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
index c71c1f111bd..e1c362be4a8 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 98bce0eb269..223184d554a 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 3c79abf7d52..b00aa094d38 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:
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 239530de729..73965360e7b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -1732,6 +1732,7 @@ 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_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 365665fa6f7..77b75b1e0bf 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 8579d8a57eb..05f749ed6c1 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;
+ IFETCH( &r[0], 0, TGSI_CHAN_X );
+ /* 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 716b16b7f9f..aee2d3081b2 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 },
@@ -297,6 +297,7 @@ tgsi_opcode_infer_src_type( uint opcode )
case TGSI_OPCODE_TXF:
case TGSI_OPCODE_SAMPLE_I:
case TGSI_OPCODE_SAMPLE_I_MS:
+ case TGSI_OPCODE_UIF:
return TGSI_TYPE_UNSIGNED;
case TGSI_OPCODE_MOD:
case TGSI_OPCODE_I2F:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
index b8519c64a2b..a6bcbb0f322 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 0002626c715..b7180f85df4 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.
+
+
+.. 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 68976914240..d8abccd15af 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;
@@ -385,6 +386,7 @@ static nv50_ir::TexTarget translateTexture(uint tex)
nv50_ir::DataType Instruction::inferSrcType() const
{
switch (getOpcode()) {
+ case TGSI_OPCODE_UIF:
case TGSI_OPCODE_AND:
case TGSI_OPCODE_OR:
case TGSI_OPCODE_XOR:
@@ -2430,6 +2432,7 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
mkOp1(op, TYPE_U32, NULL, src0)->fixed = 1;
break;
case TGSI_OPCODE_IF:
+ case TGSI_OPCODE_UIF:
{
BasicBlock *ifBB = new BasicBlock(func);
@@ -2437,7 +2440,7 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
condBBs.push(bb);
joinBBs.push(bb);
- mkFlow(OP_BRA, NULL, CC_NOT_P, fetchSrc(0, 0));
+ mkFlow(OP_BRA, NULL, CC_NOT_P, fetchSrc(0, 0))->setType(srcTy);
setPosition(ifBB, true);
}
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp
index 20f76f81ded..03086e379c0 100644
--- a/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp
+++ b/src/gallium/drivers/nv50/codegen/nv50_ir_lowering_nv50.cpp
@@ -1011,7 +1011,7 @@ NV50LoweringPreSSA::checkPredicate(Instruction *insn)
return;
cdst = bld.getSSA(1, FILE_FLAGS);
- bld.mkCmp(OP_SET, CC_NEU, TYPE_U32, cdst, bld.loadImm(NULL, 0), pred);
+ bld.mkCmp(OP_SET, CC_NEU, insn->dType, cdst, bld.loadImm(NULL, 0), pred);
insn->setPredicate(insn->cc, cdst);
}
diff --git a/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp
index 4d1d37281bc..7676185f03f 100644
--- a/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp
+++ b/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp
@@ -1490,7 +1490,7 @@ NVC0LoweringPass::checkPredicate(Instruction *insn)
// CAUTION: don't use pdst->getInsn, the definition might not be unique,
// delay turning PSET(FSET(x,y),0) into PSET(x,y) to a later pass
- bld.mkCmp(OP_SET, CC_NEU, TYPE_U32, pdst, bld.mkImm(0), pred);
+ bld.mkCmp(OP_SET, CC_NEU, insn->dType, pdst, bld.mkImm(0), pred);
insn->setPredicate(insn->cc, pdst);
}
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 7185c8e78f0..5ac8c095183 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -5728,7 +5728,7 @@ static void break_loop_on_flag(struct r600_shader_ctx *ctx, unsigned fc_sp)
}
#endif
-static int tgsi_if(struct r600_shader_ctx *ctx)
+static int emit_if(struct r600_shader_ctx *ctx, int opcode)
{
int alu_type = CF_OP_ALU_PUSH_BEFORE;
@@ -5742,7 +5742,7 @@ static int tgsi_if(struct r600_shader_ctx *ctx)
alu_type = CF_OP_ALU;
}
- emit_logic_pred(ctx, ALU_OP2_PRED_SETNE_INT, alu_type);
+ emit_logic_pred(ctx, opcode, alu_type);
r600_bytecode_add_cfinst(ctx->bc, CF_OP_JUMP);
@@ -5752,6 +5752,16 @@ static int tgsi_if(struct r600_shader_ctx *ctx)
return 0;
}
+static int tgsi_if(struct r600_shader_ctx *ctx)
+{
+ return emit_if(ctx, ALU_OP2_PRED_SETNE);
+}
+
+static int tgsi_uif(struct r600_shader_ctx *ctx)
+{
+ return emit_if(ctx, ALU_OP2_PRED_SETNE_INT);
+}
+
static int tgsi_else(struct r600_shader_ctx *ctx)
{
r600_bytecode_add_cfinst(ctx->bc, CF_OP_ELSE);
@@ -6003,8 +6013,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},
@@ -6197,8 +6206,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},
@@ -6391,8 +6399,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 314c9634fa7..0629b89a8e5 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_UIF].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 6fcd151aecc..50de2d370a1 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 589c9128712..f2eb3e7d912 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 5471a9a86f2..27d8beae1e9 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: