glsl: Use conditional-select in mix().
authorMatt Turner <mattst88@gmail.com>
Fri, 6 Sep 2013 19:36:48 +0000 (12:36 -0700)
committerMatt Turner <mattst88@gmail.com>
Mon, 9 Sep 2013 22:01:08 +0000 (15:01 -0700)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/builtin_functions.cpp

index 662fc1eda5edc2ed1e46f15c3ef4e1ac907d6c2a..0139b6ff01f70ac978496e954a12403f4e585cbf 100644 (file)
@@ -2262,14 +2262,14 @@ builtin_builder::_mix_sel(const glsl_type *val_type, const glsl_type *blend_type
    ir_variable *a = in_var(blend_type, "a");
    MAKE_SIG(val_type, v130, 3, x, y, a);
 
-   if (blend_type->vector_elements == 1) {
-      body.emit(assign(x, y, a));
-   } else {
-      for (int i = 0; i < blend_type->vector_elements; i++) {
-         body.emit(assign(x, swizzle(y, i, 1), swizzle(a, i, 1), 1 << i));
-      }
-   }
-   body.emit(ret(x));
+   /* csel matches the ternary operator in that a selector of true choses the
+    * first argument. This differs from mix(x, y, false) which choses the
+    * second argument (to remain consistent with the interpolating version of
+    * mix() which takes a blend factor from 0.0 to 1.0 where 0.0 is only x.
+    *
+    * To handle the behavior mismatch, reverse the x and y arguments.
+    */
+   body.emit(ret(csel(a, y, x)));
 
    return sig;
 }