gallivm: Fetch the lod from the dynamic state when min_lod == max_lod.
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_sample.c
index 19e380a8dceec6d1ae147b45c4997026018717d9..d9fbc0f3057da84602db778700d07d3058e7c5c1 100644 (file)
@@ -104,7 +104,6 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
     */
    if (sampler->min_lod == sampler->max_lod) {
       state->min_max_lod_equal = 1;
-      state->min_max_lod = sampler->min_lod;
    }
 
    state->compare_mode      = sampler->compare_mode;
@@ -145,18 +144,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.
        */
-      return LLVMConstReal(LLVMFloatType(), bld->static_state->min_max_lod);
+      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 min_lod =
-         bld->dynamic_state->min_lod(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);
@@ -655,11 +655,21 @@ lp_build_sample_partial_offset(struct lp_build_context *bld,
        * Pixel blocks have power of two dimensions. LLVM should convert the
        * rem/div to bit arithmetic.
        * TODO: Verify this.
+       * It does indeed BUT it does transform it to scalar (and back) when doing so
+       * (using roughly extract, shift/and, mov, unpack) (llvm 2.7).
+       * The generated code looks seriously unfunny and is quite expensive.
        */
-
+#if 0
       LLVMValueRef block_width = lp_build_const_int_vec(bld->type, block_length);
       subcoord = LLVMBuildURem(bld->builder, coord, block_width, "");
       coord    = LLVMBuildUDiv(bld->builder, coord, block_width, "");
+#else
+      unsigned logbase2 = util_unsigned_logbase2(block_length);
+      LLVMValueRef block_shift = lp_build_const_int_vec(bld->type, logbase2);
+      LLVMValueRef block_mask = lp_build_const_int_vec(bld->type, block_length - 1);
+      subcoord = LLVMBuildAnd(bld->builder, coord, block_mask, "");
+      coord = LLVMBuildLShr(bld->builder, coord, block_shift, "");
+#endif
    }
 
    offset = lp_build_mul(bld, coord, stride);