From 50b3fc6204a28881f625605f988cb0866ae6a6a5 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Wed, 17 Apr 2013 10:47:03 +0100 Subject: gallium: Disambiguate TGSI_OPCODE_IF. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. Reviewed-by: Roland Scheidegger Reviewed-by: Marek Olšák v2: - Incorporate Roland's feedback. - Fix r600_shader.c merge conflict. - Fix typo in radeon, spotted by Michel Dänzer. - Incorporte Christoph Bumiller's patch to handle TGSI_OPCODE_IF(float) properly in nv50/ir. --- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 8 +++++++- src/mesa/state_tracker/st_mesa_to_tgsi.c | 12 ++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'src/mesa') 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: -- cgit v1.2.3