llvmpipe: Take the sampler view's first_level into account when sampling.
authorFabian Bieler <der.fabe@gmx.net>
Thu, 31 Mar 2011 10:32:52 +0000 (12:32 +0200)
committerMarek Olšák <maraeo@gmail.com>
Fri, 8 Apr 2011 02:47:04 +0000 (04:47 +0200)
14 files changed:
src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_context.h
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_llvm.h
src/gallium/auxiliary/draw/draw_llvm_sample.c
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
src/gallium/drivers/llvmpipe/lp_jit.c
src/gallium/drivers/llvmpipe/lp_jit.h
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_state_sampler.c
src/gallium/drivers/llvmpipe/lp_tex_sample.c

index 95d96719873972590a21392b13bde2733e8ae018..d99f94edc43a590059333e431bac94d9b32793a5 100644 (file)
@@ -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
 }
index a0b217e4d33b4c05a5d6a81e4c5cbfb741673d54..7db75b71b43879d33b67269a9eead68c7eb42b5e 100644 (file)
@@ -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]);
index 27c5f3bff5ac45fcc07ac6fc2640451ea531cc2c..a1b8fc38880e2fb42b93648e841f97770a8c557d 100644 (file)
@@ -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];
index 873a272e98b35959cf502dc908b0049f21d20268..375b7b8b571f25537e5de2251250a0b314de6633 100644 (file)
@@ -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]);
index 574c7cc452f9d9d4c443ca9996d8a05ec45cd578..8af34617353dfe1ee69fe04da1ae620ec1a3374e 100644 (file)
@@ -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;
index 8ad34598a92d94d25fa6975f051dd57d78c61393..4636371a0f5713884d4b019b04dccd43caded23a 100644 (file)
  */
 #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,
index 8c9d5df4e43aa9281002977747378a0bfe487f05..a71e656fe0e95d3924f7de9d9b741af1717188b2 100644 (file)
@@ -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,
index e61cf9541ea9cb50fd8c28f1939606c912ab3296..4f16015996846d974b08643aa65523f682c54c6c 100644 (file)
@@ -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);
index 9961ba08f3a1d83b53a1f314589020ff3251a958..4ea7b4bd8a26e8ffc308fb5023ac0cc614aff800 100644 (file)
@@ -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);
index 482a902dd23116e7c13c34b36fbbb66b952c6621..268f0fa034b78abcf0671295a483726820910b0c 100644 (file)
@@ -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);
index a6763dce17abf5bcf155096360d1529f5d5267b8..04e8dd5267b4c92debcfea0c41be92ac0e1948c4 100644 (file)
@@ -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,
index 3813e0ed972fcf530ff15510d5789b6ebb289bfe..c82ab821c7eb81008170e30fa89f6f6d634e4d45 100644 (file)
@@ -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;
index 1dd866195d336e4d6956e854ed1f3e79b38af8a5..df9fb89cc8ec38eb983ae9b5f60172d5c580fce7 100644 (file)
@@ -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);
       }
    }
index ed4282937f88859aea7ffe416395e1c6a67a86ee..ccc139603ee043e14b0d22e878924b0cac0db4cd 100644 (file)
@@ -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;