summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan Cain <bryancain3@gmail.com>2011-08-20 13:26:12 -0500
committerBryan Cain <bryancain3@gmail.com>2011-08-20 14:00:41 -0500
commita43f68810a347f3e952a0bc401be6edb91e1baea (patch)
tree213248c9df82d644526bdabef7c8df27fb11148b
parentc15eb5569bf76c5dc41327017b92a5d960207b97 (diff)
glsl_to_tgsi: implement ir_unop_any using DP4 w/saturate or DP4 w/SLT
This is a port of commit 92ca560d68e8 to glsl_to_tgsi, with integer support added.
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp32
1 files changed, 28 insertions, 4 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 62127afadde..f7d79e9f50c 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1482,12 +1482,36 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
}
break;
- case ir_unop_any:
+ case ir_unop_any: {
assert(ir->operands[0]->type->is_vector());
- emit_dp(ir, result_dst, op[0], op[0],
- ir->operands[0]->type->vector_elements);
- emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_float(0.0));
+
+ /* After the dot-product, the value will be an integer on the
+ * range [0,4]. Zero stays zero, and positive values become 1.0.
+ */
+ glsl_to_tgsi_instruction *const dp =
+ emit_dp(ir, result_dst, op[0], op[0],
+ ir->operands[0]->type->vector_elements);
+ if (this->prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
+ result_dst.type == GLSL_TYPE_FLOAT) {
+ /* The clamping to [0,1] can be done for free in the fragment
+ * shader with a saturate.
+ */
+ dp->saturate = true;
+ } else if (result_dst.type == GLSL_TYPE_FLOAT) {
+ /* Negating the result of the dot-product gives values on the range
+ * [-4, 0]. Zero stays zero, and negative values become 1.0. This
+ * is achieved using SLT.
+ */
+ st_src_reg slt_src = result_src;
+ slt_src.negate = ~slt_src.negate;
+ emit(ir, TGSI_OPCODE_SLT, result_dst, slt_src, st_src_reg_for_float(0.0));
+ }
+ else {
+ /* Use SNE 0 if integers are being used as boolean values. */
+ emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_int(0));
+ }
break;
+ }
case ir_binop_logic_xor:
emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);