aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/program/ir_to_mesa.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/program/ir_to_mesa.cpp')
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp59
1 files changed, 10 insertions, 49 deletions
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index e5844c3c4..49e4a7a40 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -311,7 +311,6 @@ public:
int mul_operand);
bool try_emit_mad_for_and_not(ir_expression *ir,
int mul_operand);
- bool try_emit_sat(ir_expression *ir);
void emit_swz(ir_expression *ir);
@@ -866,50 +865,6 @@ ir_to_mesa_visitor::try_emit_mad_for_and_not(ir_expression *ir, int try_operand)
return true;
}
-bool
-ir_to_mesa_visitor::try_emit_sat(ir_expression *ir)
-{
- /* Saturates were only introduced to vertex programs in
- * NV_vertex_program3, so don't give them to drivers in the VP.
- */
- if (this->prog->Target == GL_VERTEX_PROGRAM_ARB)
- return false;
-
- ir_rvalue *sat_src = ir->as_rvalue_to_saturate();
- if (!sat_src)
- return false;
-
- sat_src->accept(this);
- src_reg src = this->result;
-
- /* If we generated an expression instruction into a temporary in
- * processing the saturate's operand, apply the saturate to that
- * instruction. Otherwise, generate a MOV to do the saturate.
- *
- * Note that we have to be careful to only do this optimization if
- * the instruction in question was what generated src->result. For
- * example, ir_dereference_array might generate a MUL instruction
- * to create the reladdr, and return us a src reg using that
- * reladdr. That MUL result is not the value we're trying to
- * saturate.
- */
- ir_expression *sat_src_expr = sat_src->as_expression();
- ir_to_mesa_instruction *new_inst;
- new_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
- if (sat_src_expr && (sat_src_expr->operation == ir_binop_mul ||
- sat_src_expr->operation == ir_binop_add ||
- sat_src_expr->operation == ir_binop_dot)) {
- new_inst->saturate = true;
- } else {
- this->result = get_temp(ir->type);
- ir_to_mesa_instruction *inst;
- inst = emit(ir, OPCODE_MOV, dst_reg(this->result), src);
- inst->saturate = true;
- }
-
- return true;
-}
-
void
ir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir,
src_reg *reg, int *num_reladdr)
@@ -1072,9 +1027,6 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
return;
}
- if (try_emit_sat(ir))
- return;
-
if (ir->operation == ir_quadop_vector) {
this->emit_swz(ir);
return;
@@ -1171,6 +1123,12 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
emit(ir, OPCODE_DDY, result_dst, op[0]);
break;
+ case ir_unop_saturate: {
+ ir_to_mesa_instruction *inst = emit(ir, OPCODE_MOV,
+ result_dst, op[0]);
+ inst->saturate = true;
+ break;
+ }
case ir_unop_noise: {
const enum prog_opcode opcode =
prog_opcode(OPCODE_NOISE1
@@ -2990,9 +2948,12 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
/* Lowering */
do_mat_op_to_vec(ir);
+ GLenum target = _mesa_shader_stage_to_program(prog->_LinkedShaders[i]->Stage);
lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2
| LOG_TO_LOG2 | INT_DIV_TO_MUL_RCP
- | ((options->EmitNoPow) ? POW_TO_EXP2 : 0)));
+ | ((options->EmitNoPow) ? POW_TO_EXP2 : 0)
+ | ((target == GL_VERTEX_PROGRAM_ARB) ? SAT_TO_CLAMP
+ : 0)));
progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;