Mesa (master): llvmpipe: Take the sampler view' s first_level into account when sampling.

Marek Olšák mareko at kemper.freedesktop.org
Thu Apr 7 19:51:11 PDT 2011


Module: Mesa
Branch: master
Commit: 08070cead0bb79d4441d8c5b900d1571bb63c670
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=08070cead0bb79d4441d8c5b900d1571bb63c670

Author: Fabian Bieler <der.fabe at gmx.net>
Date:   Thu Mar 31 12:32:52 2011 +0200

llvmpipe: Take the sampler view's first_level into account when sampling.

---

 src/gallium/auxiliary/draw/draw_context.c         |    4 +-
 src/gallium/auxiliary/draw/draw_context.h         |    2 +-
 src/gallium/auxiliary/draw/draw_llvm.c            |    9 +++-
 src/gallium/auxiliary/draw/draw_llvm.h            |    4 +-
 src/gallium/auxiliary/draw/draw_llvm_sample.c     |    2 +
 src/gallium/auxiliary/gallivm/lp_bld_sample.c     |   54 +++++++++++++--------
 src/gallium/auxiliary/gallivm/lp_bld_sample.h     |    6 ++
 src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c |    7 ++-
 src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c |    7 ++-
 src/gallium/drivers/llvmpipe/lp_jit.c             |    4 ++
 src/gallium/drivers/llvmpipe/lp_jit.h             |    2 +
 src/gallium/drivers/llvmpipe/lp_setup.c           |    4 +-
 src/gallium/drivers/llvmpipe/lp_state_sampler.c   |    4 +-
 src/gallium/drivers/llvmpipe/lp_tex_sample.c      |    2 +
 14 files changed, 78 insertions(+), 33 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 95d9671..d99f94e 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -751,7 +751,7 @@ void
 draw_set_mapped_texture(struct draw_context *draw,
                         unsigned sampler_idx,
                         uint32_t width, uint32_t height, uint32_t depth,
-                        uint32_t last_level,
+                        uint32_t first_level, uint32_t last_level,
                         uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS],
                         uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS],
                         const void *data[PIPE_MAX_TEXTURE_LEVELS])
@@ -760,7 +760,7 @@ draw_set_mapped_texture(struct draw_context *draw,
    if(draw->llvm)
       draw_llvm_set_mapped_texture(draw,
                                 sampler_idx,
-                                width, height, depth, last_level,
+                                width, height, depth, first_level, last_level,
                                 row_stride, img_stride, data);
 #endif
 }
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index a0b217e..7db75b7 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -123,7 +123,7 @@ void
 draw_set_mapped_texture(struct draw_context *draw,
                         unsigned sampler_idx,
                         uint32_t width, uint32_t height, uint32_t depth,
-                        uint32_t last_level,
+                        uint32_t first_level, uint32_t last_level,
                         uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS],
                         uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS],
                         const void *data[PIPE_MAX_TEXTURE_LEVELS]);
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 27c5f3b..a1b8fc3 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -106,6 +106,7 @@ create_jit_texture_type(struct gallivm_state *gallivm)
    elem_types[DRAW_JIT_TEXTURE_WIDTH]  =
    elem_types[DRAW_JIT_TEXTURE_HEIGHT] =
    elem_types[DRAW_JIT_TEXTURE_DEPTH] =
+   elem_types[DRAW_JIT_TEXTURE_FIRST_LEVEL] =
    elem_types[DRAW_JIT_TEXTURE_LAST_LEVEL] = int32_type;
    elem_types[DRAW_JIT_TEXTURE_ROW_STRIDE] =
    elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] =
@@ -136,6 +137,9 @@ create_jit_texture_type(struct gallivm_state *gallivm)
    LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, depth,
                           target, texture_type,
                           DRAW_JIT_TEXTURE_DEPTH);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, first_level,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_FIRST_LEVEL);
    LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, last_level,
                           target, texture_type,
                           DRAW_JIT_TEXTURE_LAST_LEVEL);
@@ -1595,7 +1599,7 @@ void
 draw_llvm_set_mapped_texture(struct draw_context *draw,
                              unsigned sampler_idx,
                              uint32_t width, uint32_t height, uint32_t depth,
-                             uint32_t last_level,
+                             uint32_t first_level, uint32_t last_level,
                              uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS],
                              uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS],
                              const void *data[PIPE_MAX_TEXTURE_LEVELS])
@@ -1611,9 +1615,10 @@ draw_llvm_set_mapped_texture(struct draw_context *draw,
    jit_tex->width = width;
    jit_tex->height = height;
    jit_tex->depth = depth;
+   jit_tex->first_level = first_level;
    jit_tex->last_level = last_level;
 
-   for (j = 0; j <= last_level; j++) {
+   for (j = first_level; j <= last_level; j++) {
       jit_tex->data[j] = data[j];
       jit_tex->row_stride[j] = row_stride[j];
       jit_tex->img_stride[j] = img_stride[j];
diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h
index 873a272..375b7b8 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.h
+++ b/src/gallium/auxiliary/draw/draw_llvm.h
@@ -50,6 +50,7 @@ struct draw_jit_texture
    uint32_t width;
    uint32_t height;
    uint32_t depth;
+   uint32_t first_level;
    uint32_t last_level;
    uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
    uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
@@ -64,6 +65,7 @@ enum {
    DRAW_JIT_TEXTURE_WIDTH = 0,
    DRAW_JIT_TEXTURE_HEIGHT,
    DRAW_JIT_TEXTURE_DEPTH,
+   DRAW_JIT_TEXTURE_FIRST_LEVEL,
    DRAW_JIT_TEXTURE_LAST_LEVEL,
    DRAW_JIT_TEXTURE_ROW_STRIDE,
    DRAW_JIT_TEXTURE_IMG_STRIDE,
@@ -296,7 +298,7 @@ void
 draw_llvm_set_mapped_texture(struct draw_context *draw,
                              unsigned sampler_idx,
                              uint32_t width, uint32_t height, uint32_t depth,
-                             uint32_t last_level,
+                             uint32_t first_level, uint32_t last_level,
                              uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS],
                              uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS],
                              const void *data[PIPE_MAX_TEXTURE_LEVELS]);
diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c
index 574c7cc..8af3461 100644
--- a/src/gallium/auxiliary/draw/draw_llvm_sample.c
+++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c
@@ -144,6 +144,7 @@ draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
 DRAW_LLVM_TEXTURE_MEMBER(width,      DRAW_JIT_TEXTURE_WIDTH, TRUE)
 DRAW_LLVM_TEXTURE_MEMBER(height,     DRAW_JIT_TEXTURE_HEIGHT, TRUE)
 DRAW_LLVM_TEXTURE_MEMBER(depth,      DRAW_JIT_TEXTURE_DEPTH, TRUE)
+DRAW_LLVM_TEXTURE_MEMBER(first_level,DRAW_JIT_TEXTURE_FIRST_LEVEL, TRUE)
 DRAW_LLVM_TEXTURE_MEMBER(last_level, DRAW_JIT_TEXTURE_LAST_LEVEL, TRUE)
 DRAW_LLVM_TEXTURE_MEMBER(row_stride, DRAW_JIT_TEXTURE_ROW_STRIDE, FALSE)
 DRAW_LLVM_TEXTURE_MEMBER(img_stride, DRAW_JIT_TEXTURE_IMG_STRIDE, FALSE)
@@ -209,6 +210,7 @@ draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
    sampler->dynamic_state.base.width = draw_llvm_texture_width;
    sampler->dynamic_state.base.height = draw_llvm_texture_height;
    sampler->dynamic_state.base.depth = draw_llvm_texture_depth;
+   sampler->dynamic_state.base.first_level = draw_llvm_texture_first_level;
    sampler->dynamic_state.base.last_level = draw_llvm_texture_last_level;
    sampler->dynamic_state.base.row_stride = draw_llvm_texture_row_stride;
    sampler->dynamic_state.base.img_stride = draw_llvm_texture_img_stride;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index 8ad3459..4636371 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -51,6 +51,10 @@
  */
 #define BRILINEAR_FACTOR 2
 
+static LLVMValueRef
+lp_build_minify(struct lp_build_context *bld,
+                LLVMValueRef base_size,
+                LLVMValueRef level);
 
 /**
  * Does the given texture wrap mode allow sampling the texture border color?
@@ -184,9 +188,11 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
  */
 static LLVMValueRef
 lp_build_rho(struct lp_build_sample_context *bld,
+             unsigned unit,
              const LLVMValueRef ddx[4],
              const LLVMValueRef ddy[4])
 {
+   struct lp_build_context *int_size_bld = &bld->int_size_bld;
    struct lp_build_context *float_size_bld = &bld->float_size_bld;
    struct lp_build_context *float_bld = &bld->float_bld;
    const unsigned dims = bld->dims;
@@ -198,8 +204,9 @@ lp_build_rho(struct lp_build_sample_context *bld,
    LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
    LLVMValueRef rho_x, rho_y;
    LLVMValueRef rho_vec;
-   LLVMValueRef float_size;
+   LLVMValueRef int_size, float_size;
    LLVMValueRef rho;
+   LLVMValueRef first_level, first_level_vec;
 
    dsdx = ddx[0];
    dsdy = ddy[0];
@@ -235,7 +242,11 @@ lp_build_rho(struct lp_build_sample_context *bld,
 
    rho_vec = lp_build_max(float_size_bld, rho_x, rho_y);
 
-   float_size = lp_build_int_to_float(float_size_bld, bld->int_size);
+   first_level = bld->dynamic_state->first_level(bld->dynamic_state,
+                                                 bld->gallivm, unit);
+   first_level_vec = lp_build_broadcast_scalar(&bld->int_size_bld, first_level);
+   int_size = lp_build_minify(int_size_bld, bld->int_size, first_level_vec);
+   float_size = lp_build_int_to_float(float_size_bld, int_size);
 
    rho_vec = lp_build_mul(float_size_bld, rho_vec, float_size);
 
@@ -442,7 +453,7 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
       else {
          LLVMValueRef rho;
 
-         rho = lp_build_rho(bld, ddx, ddy);
+         rho = lp_build_rho(bld, unit, ddx, ddy);
 
          /*
           * Compute lod = log2(rho)
@@ -542,18 +553,18 @@ lp_build_nearest_mip_level(struct lp_build_sample_context *bld,
                            LLVMValueRef *level_out)
 {
    struct lp_build_context *int_bld = &bld->int_bld;
-   LLVMValueRef last_level, level;
-
-   LLVMValueRef zero = lp_build_const_int32(bld->gallivm, 0);
+   LLVMValueRef first_level, last_level, level;
 
+   first_level = bld->dynamic_state->first_level(bld->dynamic_state,
+                                                 bld->gallivm, unit);
    last_level = bld->dynamic_state->last_level(bld->dynamic_state,
                                                bld->gallivm, unit);
 
    /* convert float lod to integer */
-   level = lod_ipart;
+   level = lp_build_add(int_bld, lod_ipart, first_level);
 
    /* clamp level to legal range of levels */
-   *level_out = lp_build_clamp(int_bld, level, zero, last_level);
+   *level_out = lp_build_clamp(int_bld, level, first_level, last_level);
 }
 
 
@@ -573,39 +584,42 @@ lp_build_linear_mip_levels(struct lp_build_sample_context *bld,
    LLVMBuilderRef builder = bld->gallivm->builder;
    struct lp_build_context *int_bld = &bld->int_bld;
    struct lp_build_context *float_bld = &bld->float_bld;
-   LLVMValueRef last_level;
+   LLVMValueRef first_level, last_level;
    LLVMValueRef clamp_min;
    LLVMValueRef clamp_max;
 
-   *level0_out = lod_ipart;
-   *level1_out = lp_build_add(int_bld, lod_ipart, int_bld->one);
+   first_level = bld->dynamic_state->first_level(bld->dynamic_state,
+                                                 bld->gallivm, unit);
+
+   *level0_out = lp_build_add(int_bld, lod_ipart, first_level);
+   *level1_out = lp_build_add(int_bld, *level0_out, int_bld->one);
 
    last_level = bld->dynamic_state->last_level(bld->dynamic_state,
                                                bld->gallivm, unit);
 
    /*
-    * 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
+    * Clamp both *level0_out and *level1_out to [first_level, last_level], with
+    * the minimum number of comparisons, and zeroing lod_fpart in the extreme
     * ends in the process.
     */
 
-   /* lod_ipart < 0 */
+   /* *level0_out < first_level */
    clamp_min = LLVMBuildICmp(builder, LLVMIntSLT,
-                             lod_ipart, int_bld->zero,
-                             "clamp_lod_to_zero");
+                             *level0_out, first_level,
+                             "clamp_lod_to_first");
 
    *level0_out = LLVMBuildSelect(builder, clamp_min,
-                                 int_bld->zero, *level0_out, "");
+                                 first_level, *level0_out, "");
 
    *level1_out = LLVMBuildSelect(builder, clamp_min,
-                                 int_bld->zero, *level1_out, "");
+                                 first_level, *level1_out, "");
 
    *lod_fpart_inout = LLVMBuildSelect(builder, clamp_min,
                                       float_bld->zero, *lod_fpart_inout, "");
 
-   /* lod_ipart >= last_level */
+   /* *level0_out >= last_level */
    clamp_max = LLVMBuildICmp(builder, LLVMIntSGE,
-                             lod_ipart, last_level,
+                             *level0_out, last_level,
                              "clamp_lod_to_last");
 
    *level0_out = LLVMBuildSelect(builder, clamp_max,
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
index 8c9d5df..a71e656 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -120,6 +120,12 @@ struct lp_sampler_dynamic_state
              struct gallivm_state *gallivm,
              unsigned unit);
 
+   /** Obtain the first mipmap level (base level) (returns int32) */
+   LLVMValueRef
+   (*first_level)( const struct lp_sampler_dynamic_state *state,
+                   struct gallivm_state *gallivm,
+                   unsigned unit);
+
    /** Obtain the number of mipmap levels minus one (returns int32) */
    LLVMValueRef
    (*last_level)( const struct lp_sampler_dynamic_state *state,
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
index e61cf95..4f16015 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
@@ -939,6 +939,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
    LLVMValueRef unswizzled[4];
    LLVMValueRef face_ddx[4], face_ddy[4];
    struct lp_build_context h16_bld;
+   LLVMValueRef first_level;
    LLVMValueRef i32t_zero = lp_build_const_int32(bld->gallivm, 0);
 
    /* we only support the common/simple wrap modes at this time */
@@ -1008,7 +1009,9 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
          lp_build_nearest_mip_level(bld, unit, lod_ipart, &ilevel0);
       }
       else {
-         ilevel0 = i32t_zero;
+         first_level = bld->dynamic_state->first_level(bld->dynamic_state,
+                                                       bld->gallivm, unit);
+         ilevel0 = first_level;
       }
       break;
    case PIPE_TEX_MIPFILTER_NEAREST:
@@ -1065,7 +1068,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
          lp_build_sample_mipmap(bld, 
                                 mag_filter, PIPE_TEX_MIPFILTER_NONE,
                                 s, t, r,
-                                i32t_zero, NULL, NULL,
+                                ilevel0, NULL, NULL,
                                 packed_lo, packed_hi);
       }
       lp_build_endif(&if_ctx);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 9961ba0..4ea7b4b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -943,6 +943,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
    LLVMValueRef ilevel0, ilevel1 = NULL;
    LLVMValueRef face_ddx[4], face_ddy[4];
    LLVMValueRef texels[4];
+   LLVMValueRef first_level;
    LLVMValueRef i32t_zero = lp_build_const_int32(bld->gallivm, 0);
    unsigned chan;
 
@@ -1009,7 +1010,9 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
          lp_build_nearest_mip_level(bld, unit, lod_ipart, &ilevel0);
       }
       else {
-         ilevel0 = i32t_zero;
+         first_level = bld->dynamic_state->first_level(bld->dynamic_state,
+                                                       bld->gallivm, unit);
+         ilevel0 = first_level;
       }
       break;
    case PIPE_TEX_MIPFILTER_NEAREST:
@@ -1068,7 +1071,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
          lp_build_sample_mipmap(bld, unit,
                                 mag_filter, PIPE_TEX_MIPFILTER_NONE,
                                 s, t, r,
-                                i32t_zero, NULL, NULL,
+                                ilevel0, NULL, NULL,
                                 texels);
       }
       lp_build_endif(&if_ctx);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 482a902..268f0fa 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -54,6 +54,7 @@ lp_jit_create_types(struct llvmpipe_context *lp)
       elem_types[LP_JIT_TEXTURE_WIDTH]  =
       elem_types[LP_JIT_TEXTURE_HEIGHT] =
       elem_types[LP_JIT_TEXTURE_DEPTH] =
+      elem_types[LP_JIT_TEXTURE_FIRST_LEVEL] =
       elem_types[LP_JIT_TEXTURE_LAST_LEVEL] =  LLVMInt32TypeInContext(lc);
       elem_types[LP_JIT_TEXTURE_ROW_STRIDE] =
       elem_types[LP_JIT_TEXTURE_IMG_STRIDE] =
@@ -81,6 +82,9 @@ lp_jit_create_types(struct llvmpipe_context *lp)
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, depth,
                              gallivm->target, texture_type,
                              LP_JIT_TEXTURE_DEPTH);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, first_level,
+                             gallivm->target, texture_type,
+                             LP_JIT_TEXTURE_FIRST_LEVEL);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, last_level,
                              gallivm->target, texture_type,
                              LP_JIT_TEXTURE_LAST_LEVEL);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index a6763dc..04e8dd5 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -50,6 +50,7 @@ struct lp_jit_texture
    uint32_t width;
    uint32_t height;
    uint32_t depth;
+   uint32_t first_level;
    uint32_t last_level;
    uint32_t row_stride[LP_MAX_TEXTURE_LEVELS];
    uint32_t img_stride[LP_MAX_TEXTURE_LEVELS];
@@ -66,6 +67,7 @@ enum {
    LP_JIT_TEXTURE_WIDTH = 0,
    LP_JIT_TEXTURE_HEIGHT,
    LP_JIT_TEXTURE_DEPTH,
+   LP_JIT_TEXTURE_FIRST_LEVEL,
    LP_JIT_TEXTURE_LAST_LEVEL,
    LP_JIT_TEXTURE_ROW_STRIDE,
    LP_JIT_TEXTURE_IMG_STRIDE,
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 3813e0e..c82ab82 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -653,6 +653,7 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
          jit_tex->width = tex->width0;
          jit_tex->height = tex->height0;
          jit_tex->depth = tex->depth0;
+         jit_tex->first_level = view->u.tex.first_level;
          jit_tex->last_level = tex->last_level;
 
          /* We're referencing the texture's internal data, so save a
@@ -663,7 +664,7 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
          if (!lp_tex->dt) {
             /* regular texture - setup array of mipmap level pointers */
             int j;
-            for (j = 0; j <= tex->last_level; j++) {
+            for (j = view->u.tex.first_level; j <= tex->last_level; j++) {
                jit_tex->data[j] =
                   llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ,
                                                  LP_TEX_LAYOUT_LINEAR);
@@ -677,6 +678,7 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
                   jit_tex->width = TILE_SIZE/8;
                   jit_tex->height = TILE_SIZE/8;
                   jit_tex->depth = 1;
+                  jit_tex->first_level = 0;
                   jit_tex->last_level = 0;
                   jit_tex->row_stride[j] = 0;
                   jit_tex->img_stride[j] = 0;
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index 1dd8661..df9fb89 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -269,7 +269,7 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
          if (!lp_tex->dt) {
             /* regular texture - setup array of mipmap level pointers */
             int j;
-            for (j = 0; j <= tex->last_level; j++) {
+            for (j = view->u.tex.first_level; j <= tex->last_level; j++) {
                data[j] =
                   llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ,
                                                  LP_TEX_LAYOUT_LINEAR);
@@ -293,7 +293,7 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
          draw_set_mapped_texture(lp->draw,
                                  i,
                                  tex->width0, tex->height0, tex->depth0,
-                                 tex->last_level,
+                                 view->u.tex.first_level, tex->last_level,
                                  row_stride, img_stride, data);
       }
    }
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
index ed42829..ccc1396 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
@@ -149,6 +149,7 @@ lp_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
 LP_LLVM_TEXTURE_MEMBER(width,      LP_JIT_TEXTURE_WIDTH, TRUE)
 LP_LLVM_TEXTURE_MEMBER(height,     LP_JIT_TEXTURE_HEIGHT, TRUE)
 LP_LLVM_TEXTURE_MEMBER(depth,      LP_JIT_TEXTURE_DEPTH, TRUE)
+LP_LLVM_TEXTURE_MEMBER(first_level, LP_JIT_TEXTURE_FIRST_LEVEL, TRUE)
 LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE)
 LP_LLVM_TEXTURE_MEMBER(row_stride, LP_JIT_TEXTURE_ROW_STRIDE, FALSE)
 LP_LLVM_TEXTURE_MEMBER(img_stride, LP_JIT_TEXTURE_IMG_STRIDE, FALSE)
@@ -219,6 +220,7 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
    sampler->dynamic_state.base.width = lp_llvm_texture_width;
    sampler->dynamic_state.base.height = lp_llvm_texture_height;
    sampler->dynamic_state.base.depth = lp_llvm_texture_depth;
+   sampler->dynamic_state.base.first_level = lp_llvm_texture_first_level;
    sampler->dynamic_state.base.last_level = lp_llvm_texture_last_level;
    sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride;
    sampler->dynamic_state.base.img_stride = lp_llvm_texture_img_stride;



More information about the mesa-commit mailing list