gallivm: Clamp mipmap level and zero mip weight simultaneously.
authorJosé Fonseca <jfonseca@vmware.com>
Fri, 8 Oct 2010 13:05:50 +0000 (14:05 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Fri, 8 Oct 2010 13:06:38 +0000 (14:06 +0100)
src/gallium/auxiliary/gallivm/lp_bld_sample.c
src/gallium/auxiliary/gallivm/lp_bld_sample.h
src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c

index d6b50fbe5ff213a6767f322733c4428cfeef4edc..cf6da2c27839892b7863c5b6c2068d4b9607dfe1 100644 (file)
@@ -409,27 +409,60 @@ void
 lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
                            unsigned unit,
                            LLVMValueRef lod_ipart,
+                           LLVMValueRef *lod_fpart_inout,
                            LLVMValueRef *level0_out,
                            LLVMValueRef *level1_out)
 {
+   LLVMBuilderRef builder = bld->builder;
    struct lp_build_context *int_bld = &bld->int_bld;
-   LLVMValueRef last_level, level;
+   struct lp_build_context *float_bld = &bld->float_bld;
+   LLVMValueRef last_level;
+   LLVMValueRef clamp_min;
+   LLVMValueRef clamp_max;
+
+   *level0_out = lod_ipart;
+   *level1_out = lp_build_add(int_bld, lod_ipart, int_bld->one);
 
    last_level = bld->dynamic_state->last_level(bld->dynamic_state,
                                                bld->builder, unit);
 
-   /* convert float lod to integer */
-   level = lod_ipart;
+   /*
+    * Clamp both lod_ipart and lod_ipart + 1 to [0, last_level], with the
+    * minimum number of comparisons, and zeroing lod_fpart in the extreme
+    * ends in the process.
+    */
+
+   /* lod_ipart < 0 */
+   clamp_min = LLVMBuildICmp(builder, LLVMIntSLT,
+                             lod_ipart, int_bld->zero,
+                             "clamp_lod_to_zero");
+
+   *level0_out = LLVMBuildSelect(builder, clamp_min,
+                                 int_bld->zero, *level0_out, "");
+
+   *level1_out = LLVMBuildSelect(builder, clamp_min,
+                                 int_bld->zero, *level1_out, "");
+
+   *lod_fpart_inout = LLVMBuildSelect(builder, clamp_min,
+                                      float_bld->zero, *lod_fpart_inout, "");
+
+   /* lod_ipart >= last_level */
+   clamp_max = LLVMBuildICmp(builder, LLVMIntSGE,
+                             lod_ipart, last_level,
+                             "clamp_lod_to_last");
+
+   *level0_out = LLVMBuildSelect(builder, clamp_max,
+                                 int_bld->zero, *level0_out, "");
+
+   *level1_out = LLVMBuildSelect(builder, clamp_max,
+                                 int_bld->zero, *level1_out, "");
+
+   *lod_fpart_inout = LLVMBuildSelect(builder, clamp_max,
+                                      float_bld->zero, *lod_fpart_inout, "");
 
-   /* compute level 0 and clamp to legal range of levels */
-   *level0_out = lp_build_clamp(int_bld, level,
-                                int_bld->zero,
-                                last_level);
-   /* compute level 1 and clamp to legal range of levels */
-   level = lp_build_add(int_bld, level, int_bld->one);
-   *level1_out = lp_build_clamp(int_bld, level,
-                                int_bld->zero,
-                                last_level);
+   lp_build_name(*level0_out, "sampler%u_miplevel0", unit);
+   lp_build_name(*level1_out, "sampler%u_miplevel1", unit);
+   lp_build_name(*lod_fpart_inout, "sampler%u_mipweight", unit);
 }
 
 
index 76f428d4be19f6dbefcefb3e64a883bc92311631..e5d7f10778f2904e5b1ea15dfbb0b2e9a29f0df5 100644 (file)
@@ -309,6 +309,7 @@ void
 lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
                            unsigned unit,
                            LLVMValueRef lod_ipart,
+                           LLVMValueRef *lod_fpart_inout,
                            LLVMValueRef *level0_out,
                            LLVMValueRef *level1_out);
 
index 511090ed14d3854ba6bc46d8c6c016b441b84fc8..293237c5b1e496e9c359d427e9a5587666a65574 100644 (file)
@@ -1004,7 +1004,9 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
    case PIPE_TEX_MIPFILTER_LINEAR:
       assert(lod_ipart);
       assert(lod_fpart);
-      lp_build_linear_mip_levels(bld, unit, lod_ipart, &ilevel0, &ilevel1);
+      lp_build_linear_mip_levels(bld, unit,
+                                 lod_ipart, &lod_fpart,
+                                 &ilevel0, &ilevel1);
       break;
    }
 
index 4adce4e8b3263643b78f0011b822beebaaf5bceb..886df7c29c0f5bd2c282990e43221c791030ed61 100644 (file)
@@ -997,7 +997,9 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
    case PIPE_TEX_MIPFILTER_LINEAR:
       assert(lod_ipart);
       assert(lod_fpart);
-      lp_build_linear_mip_levels(bld, unit, lod_ipart, &ilevel0, &ilevel1);
+      lp_build_linear_mip_levels(bld, unit,
+                                 lod_ipart, &lod_fpart,
+                                 &ilevel0, &ilevel1);
       break;
    }