gallivm: Only apply min/max_lod when necessary.
authorJosé Fonseca <jfonseca@vmware.com>
Wed, 6 Oct 2010 13:53:19 +0000 (14:53 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Wed, 6 Oct 2010 17:50:57 +0000 (18:50 +0100)
src/gallium/auxiliary/gallivm/lp_bld_sample.c
src/gallium/auxiliary/gallivm/lp_bld_sample.h
src/gallium/drivers/llvmpipe/lp_state_fs.c

index 2227a062d0880a14bc42ee2b7a49dfc6fe5101bf..c1c98bf85960019b881b961154dc40d05388ced4 100644 (file)
@@ -126,21 +126,32 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
    state->wrap_r            = sampler->wrap_r;
    state->min_img_filter    = sampler->min_img_filter;
    state->mag_img_filter    = sampler->mag_img_filter;
-   if (view->last_level) {
+
+   if (view->last_level && sampler->max_lod > 0.0f) {
       state->min_mip_filter = sampler->min_mip_filter;
    } else {
       state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
    }
 
-   if (sampler->lod_bias != 0.0) {
-      state->lod_bias_non_zero = 1;
-   }
+   if (state->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) {
+      if (sampler->lod_bias != 0.0f) {
+         state->lod_bias_non_zero = 1;
+      }
 
-   /* If min_lod == max_lod we can greatly simplify mipmap selection.
-    * This is a case that occurs during automatic mipmap generation.
-    */
-   if (sampler->min_lod == sampler->max_lod) {
-      state->min_max_lod_equal = 1;
+      /* If min_lod == max_lod we can greatly simplify mipmap selection.
+       * This is a case that occurs during automatic mipmap generation.
+       */
+      if (sampler->min_lod == sampler->max_lod) {
+         state->min_max_lod_equal = 1;
+      } else {
+         if (sampler->min_lod > 0.0f) {
+            state->apply_min_lod = 1;
+         }
+
+         if (sampler->max_lod < (float)view->last_level) {
+            state->apply_max_lod = 1;
+         }
+      }
    }
 
    state->compare_mode      = sampler->compare_mode;
@@ -181,21 +192,19 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
                       LLVMValueRef depth)
 
 {
-   LLVMValueRef min_lod =
-      bld->dynamic_state->min_lod(bld->dynamic_state, bld->builder, unit);
-
    if (bld->static_state->min_max_lod_equal) {
       /* User is forcing sampling from a particular mipmap level.
        * This is hit during mipmap generation.
        */
+      LLVMValueRef min_lod =
+         bld->dynamic_state->min_lod(bld->dynamic_state, bld->builder, unit);
+
       return min_lod;
    }
    else {
       struct lp_build_context *float_bld = &bld->float_bld;
       LLVMValueRef sampler_lod_bias =
          bld->dynamic_state->lod_bias(bld->dynamic_state, bld->builder, unit);
-      LLVMValueRef max_lod =
-         bld->dynamic_state->max_lod(bld->dynamic_state, bld->builder, unit);
       LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
       LLVMValueRef lod;
 
@@ -265,8 +274,20 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
       if (bld->static_state->lod_bias_non_zero)
          lod = LLVMBuildFAdd(bld->builder, lod, sampler_lod_bias, "sampler_lod_bias");
 
+
       /* clamp lod */
-      lod = lp_build_clamp(float_bld, lod, min_lod, max_lod);
+      if (bld->static_state->apply_max_lod) {
+         LLVMValueRef max_lod =
+            bld->dynamic_state->max_lod(bld->dynamic_state, bld->builder, unit);
+
+         lod = lp_build_min(float_bld, lod, max_lod);
+      }
+      if (bld->static_state->apply_min_lod) {
+         LLVMValueRef min_lod =
+            bld->dynamic_state->min_lod(bld->dynamic_state, bld->builder, unit);
+
+         lod = lp_build_max(float_bld, lod, min_lod);
+      }
 
       return lod;
    }
index bb1c8c8dcee4f56b1ac0bc01d4346fa5a93bf8ff..bb83ede9314cc441685af262ebfc04d61dbd7770 100644 (file)
@@ -84,6 +84,8 @@ struct lp_sampler_static_state
    unsigned normalized_coords:1;
    unsigned min_max_lod_equal:1;  /**< min_lod == max_lod ? */
    unsigned lod_bias_non_zero:1;
+   unsigned apply_min_lod:1;  /**< min_lod > 0 ? */
+   unsigned apply_max_lod:1;  /**< max_lod < last_level ? */
 };
 
 
index e50768445ff3ecfbdb017be4429f5dd54847f432..3ce8be5a0a99b50676abd70bacf8e508aa1eba35 100644 (file)
@@ -812,6 +812,10 @@ dump_fs_variant_key(const struct lp_fragment_shader_variant_key *key)
       if (key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE)
          debug_printf("  .compare_func = %s\n", util_dump_func(key->sampler[i].compare_func, TRUE));
       debug_printf("  .normalized_coords = %u\n", key->sampler[i].normalized_coords);
+      debug_printf("  .min_max_lod_equal = %u\n", key->sampler[i].min_max_lod_equal);
+      debug_printf("  .lod_bias_non_zero = %u\n", key->sampler[i].lod_bias_non_zero);
+      debug_printf("  .apply_min_lod = %u\n", key->sampler[i].apply_min_lod);
+      debug_printf("  .apply_max_lod = %u\n", key->sampler[i].apply_max_lod);
    }
 }