radeonsi: move handling of DBG_NO_OPT_VARIANT into si_shader_selector_key
[mesa.git] / src / gallium / drivers / llvmpipe / lp_bld_interp.c
index 490a69179fa506e444fd6f133004cea1536892bf..79325683c61efe858212f2fb9def50320ec0766d 100644 (file)
@@ -1,7 +1,7 @@
 /**************************************************************************
  * 
  * Copyright 2009 VMware, Inc.
- * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007-2008 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -19,7 +19,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -307,10 +307,8 @@ attribs_update_simple(struct lp_build_interp_soa_context *bld,
                /*
                 * a = a0 + (x * dadx + y * dady)
                 */
-               dadx = LLVMBuildFMul(builder, dadx, pixoffx, "");
-               dady = LLVMBuildFMul(builder, dady, pixoffy, "");
-               a = LLVMBuildFAdd(builder, a, dadx, "");
-               a = LLVMBuildFAdd(builder, a, dady, "");
+               a = lp_build_fmuladd(builder, dadx, pixoffx, a);
+               a = lp_build_fmuladd(builder, dady, pixoffy, a);
 
                if (interp == LP_INTERP_PERSPECTIVE) {
                   if (oow == NULL) {
@@ -340,10 +338,18 @@ attribs_update_simple(struct lp_build_interp_soa_context *bld,
                break;
             }
 
-            if ((attrib == 0) && (chan == 2)){
+            if ((attrib == 0) && (chan == 2) && !bld->depth_clamp){
                /* FIXME: Depth values can exceed 1.0, due to the fact that
                 * setup interpolation coefficients refer to (0,0) which causes
-                * precision loss. So we must clamp to 1.0 here to avoid artifacts
+                * precision loss. So we must clamp to 1.0 here to avoid artifacts.
+                * Note though values outside [0,1] are perfectly valid with
+                * depth clip disabled.
+                * XXX: If depth clip is disabled but we force depth clamp
+                * we may get values larger than 1.0 in the fs (but not in
+                * depth test). Not sure if that's an issue...
+                * Also, on a similar note, it is not obvious if the depth values
+                * appearing in fs (with depth clip disabled) should be clamped
+                * to [0,1], clamped to near/far or not be clamped at all...
                 */
                a = lp_build_min(coeff_bld, a, coeff_bld->one);
             }
@@ -437,13 +443,10 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
        */
       if (interp != LP_INTERP_CONSTANT &&
           interp != LP_INTERP_FACING) {
-         LLVMValueRef axaos, ayaos;
-         axaos = LLVMBuildFMul(builder, lp_build_broadcast_scalar(setup_bld, bld->x),
-                               dadxaos, "");
-         ayaos = LLVMBuildFMul(builder, lp_build_broadcast_scalar(setup_bld, bld->y),
-                               dadyaos, "");
-         a0aos = LLVMBuildFAdd(builder, a0aos, ayaos, "");
-         a0aos = LLVMBuildFAdd(builder, a0aos, axaos, "");
+         LLVMValueRef x = lp_build_broadcast_scalar(setup_bld, bld->x);
+         LLVMValueRef y = lp_build_broadcast_scalar(setup_bld, bld->y);
+         a0aos = lp_build_fmuladd(builder, x, dadxaos, a0aos);
+         a0aos = lp_build_fmuladd(builder, y, dadyaos, a0aos);
       }
 
       /*
@@ -638,10 +641,18 @@ attribs_update(struct lp_build_interp_soa_context *bld,
                }
 #endif
 
-               if (attrib == 0 && chan == 2) {
+               if (attrib == 0 && chan == 2 && !bld->depth_clamp) {
                   /* FIXME: Depth values can exceed 1.0, due to the fact that
                    * setup interpolation coefficients refer to (0,0) which causes
-                   * precision loss. So we must clamp to 1.0 here to avoid artifacts
+                   * precision loss. So we must clamp to 1.0 here to avoid artifacts.
+                   * Note though values outside [0,1] are perfectly valid with
+                   * depth clip disabled..
+                   * XXX: If depth clip is disabled but we force depth clamp
+                   * we may get values larger than 1.0 in the fs (but not in
+                   * depth test). Not sure if that's an issue...
+                   * Also, on a similar note, it is not obvious if the depth values
+                   * appearing in fs (with depth clip disabled) should be clamped
+                   * to [0,1], clamped to near/far or not be clamped at all...
                    */
                   a = lp_build_min(coeff_bld, a, coeff_bld->one);
                }
@@ -682,6 +693,7 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
                          unsigned num_inputs,
                          const struct lp_shader_input *inputs,
                          boolean pixel_center_integer,
+                         boolean depth_clamp,
                          LLVMBuilderRef builder,
                          struct lp_type type,
                          LLVMValueRef a0_ptr,
@@ -743,10 +755,16 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
    } else {
       bld->pos_offset = 0.5;
    }
+   bld->depth_clamp = depth_clamp;
 
    pos_init(bld, x0, y0);
 
-   if (coeff_type.length > 4) {
+   /*
+    * Simple method (single step interpolation) may be slower if vector length
+    * is just 4, but the results are different (generally less accurate) with
+    * the other method, so always use more accurate version.
+    */
+   if (1) {
       bld->simple_interp = TRUE;
       {
          /* XXX this should use a global static table */