summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Cain <[email protected]>2011-08-20 13:56:06 -0500
committerBryan Cain <[email protected]>2011-08-20 14:00:41 -0500
commitf3dce133f0422c42ca61f07f488237107efc30e6 (patch)
tree3ec8411a08b3ec98de5a829264d9fb1d739af8ad
parenta43f68810a347f3e952a0bc401be6edb91e1baea (diff)
glsl_to_tgsi: implement ir_binop_any_nequal using DP4 w/saturate or DP4 w/SLT
Implement the any() part of the operation the same way regular ir_unop_any is implemented. This is a port of commit e7bf096e8b04 to glsl_to_tgsi, with added integer support.
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index f7d79e9f50c..b238c267c81 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1475,8 +1475,29 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
glsl_type::vec4_type);
assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT);
emit(ir, TGSI_OPCODE_SNE, st_dst_reg(temp), op[0], op[1]);
- emit_dp(ir, result_dst, temp, temp, 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, temp, temp, 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
+ * 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 {
+ emit(ir, TGSI_OPCODE_SNE, result_dst, result_src, st_src_reg_for_float(0.0));
+ }
} else {
emit(ir, TGSI_OPCODE_SNE, result_dst, op[0], op[1]);
}