gallivm/llvmpipe: replace 'int stride' with 'int row_stride[MAX_LEVELS]'
authorBrian Paul <brianp@vmware.com>
Thu, 11 Mar 2010 21:46:06 +0000 (14:46 -0700)
committerBrian Paul <brianp@vmware.com>
Thu, 11 Mar 2010 21:49:01 +0000 (14:49 -0700)
The stride depends on the mipmap level.  Rename to row_stride to
distinguish from img_stride for 3D textures.

Fixes incorrect texel addressing in small mipmap levels.

src/gallium/auxiliary/gallivm/lp_bld_sample.h
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_tex_sample_llvm.c

index 9e88ea54d70909c35c9ddc1a106746014ab23068..7f08bfaac1f8de6d7b5de62bb411027744a3f384 100644 (file)
@@ -113,9 +113,9 @@ struct lp_sampler_dynamic_state
                   unsigned unit);
 
    LLVMValueRef
-   (*stride)( struct lp_sampler_dynamic_state *state,
-              LLVMBuilderRef builder,
-              unsigned unit);
+   (*row_stride)( struct lp_sampler_dynamic_state *state,
+                  LLVMBuilderRef builder,
+                  unsigned unit);
 
    LLVMValueRef
    (*data_ptr)( struct lp_sampler_dynamic_state *state,
index 9358ad38601fde5b24d6f52c8312f63dda952795..2fc22fb1fd547b1c84e335cc40fc9b0acd256c2c 100644 (file)
@@ -138,6 +138,34 @@ lp_build_get_const_mipmap_level(struct lp_build_sample_context *bld,
 }
 
 
+/**
+ * Dereference stride_array[mipmap_level] array to get a stride.
+ * Return stride as a vector.
+ */
+static LLVMValueRef
+lp_build_get_level_stride_vec(struct lp_build_sample_context *bld,
+                              LLVMValueRef stride_array, LLVMValueRef level)
+{
+   LLVMValueRef indexes[2], stride;
+   indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+   indexes[1] = level;
+   stride = LLVMBuildGEP(bld->builder, stride_array, indexes, 2, "");
+   stride = LLVMBuildLoad(bld->builder, stride, "");
+   stride = lp_build_broadcast_scalar(&bld->int_coord_bld, stride);
+   return stride;
+}
+
+
+/** Dereference stride_array[0] array to get a stride (as vector). */
+static LLVMValueRef
+lp_build_get_const_level_stride_vec(struct lp_build_sample_context *bld,
+                                    LLVMValueRef stride_array, int level)
+{
+   LLVMValueRef lvl = LLVMConstInt(LLVMInt32Type(), level, 0);
+   return lp_build_get_level_stride_vec(bld, stride_array, lvl);
+}
+
+
 static int
 texture_dims(enum pipe_texture_target tex)
 {
@@ -1190,7 +1218,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
                         LLVMValueRef width_vec,
                         LLVMValueRef height_vec,
                         LLVMValueRef depth_vec,
-                        LLVMValueRef row_stride_vec,
+                        LLVMValueRef row_stride_array,
                         LLVMValueRef img_stride_vec,
                         LLVMValueRef data_array,
                         LLVMValueRef *colors_out)
@@ -1248,7 +1276,8 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
    width0_vec = lp_build_minify(bld, width_vec, ilevel0_vec);
    if (dims >= 2) {
       height0_vec = lp_build_minify(bld, height_vec, ilevel0_vec);
-      row_stride0_vec = lp_build_minify(bld, row_stride_vec, ilevel0_vec);
+      row_stride0_vec = lp_build_get_level_stride_vec(bld, row_stride_array,
+                                                      ilevel0);
       if (dims == 3) {
          depth0_vec = lp_build_minify(bld, depth_vec, ilevel0_vec);
       }
@@ -1258,7 +1287,8 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
       width1_vec = lp_build_minify(bld, width_vec, ilevel1_vec);
       if (dims >= 2) {
          height1_vec = lp_build_minify(bld, height_vec, ilevel1_vec);
-         row_stride1_vec = lp_build_minify(bld, row_stride_vec, ilevel1_vec);
+         row_stride1_vec = lp_build_get_level_stride_vec(bld, row_stride_array,
+                                                         ilevel1);
          if (dims == 3) {
             depth1_vec = lp_build_minify(bld, depth_vec, ilevel1_vec);
          }
@@ -1380,7 +1410,7 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
                               LLVMValueRef t,
                               LLVMValueRef width,
                               LLVMValueRef height,
-                              LLVMValueRef stride,
+                              LLVMValueRef stride_array,
                               LLVMValueRef data_array,
                               LLVMValueRef *texel)
 {
@@ -1397,6 +1427,7 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
    LLVMValueRef neighbors_hi[2][2];
    LLVMValueRef packed, packed_lo, packed_hi;
    LLVMValueRef unswizzled[4];
+   LLVMValueRef stride;
 
    lp_build_context_init(&i32, builder, lp_type_int_vec(32));
    lp_build_context_init(&h16, builder, lp_type_ufixed(16));
@@ -1504,6 +1535,8 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
       t_fpart_hi = LLVMBuildShuffleVector(builder, t_fpart, h16.undef, shuffle_hi, "");
    }
 
+   stride = lp_build_get_const_level_stride_vec(bld, stride_array, 0);
+
    /*
     * Fetch the pixels as 4 x 32bit (rgba order might differ):
     *
@@ -1628,7 +1661,7 @@ lp_build_sample_soa(LLVMBuilderRef builder,
    LLVMValueRef width, width_vec;
    LLVMValueRef height, height_vec;
    LLVMValueRef depth, depth_vec;
-   LLVMValueRef stride, stride_vec;
+   LLVMValueRef stride_array;
    LLVMValueRef data_array;
    LLVMValueRef s;
    LLVMValueRef t;
@@ -1664,7 +1697,7 @@ lp_build_sample_soa(LLVMBuilderRef builder,
    width = dynamic_state->width(dynamic_state, builder, unit);
    height = dynamic_state->height(dynamic_state, builder, unit);
    depth = dynamic_state->depth(dynamic_state, builder, unit);
-   stride = dynamic_state->stride(dynamic_state, builder, unit);
+   stride_array = dynamic_state->row_stride(dynamic_state, builder, unit);
    data_array = dynamic_state->data_ptr(dynamic_state, builder, unit);
    /* Note that data_array is an array[level] of pointers to texture images */
 
@@ -1675,7 +1708,6 @@ lp_build_sample_soa(LLVMBuilderRef builder,
    width_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, width);
    height_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, height);
    depth_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, depth);
-   stride_vec = lp_build_broadcast_scalar(&bld.uint_coord_bld, stride);
 
    if (lp_format_is_rgba8(bld.format_desc) &&
        static_state->min_img_filter == PIPE_TEX_FILTER_LINEAR &&
@@ -1685,13 +1717,13 @@ lp_build_sample_soa(LLVMBuilderRef builder,
        is_simple_wrap_mode(static_state->wrap_t)) {
       /* special case */
       lp_build_sample_2d_linear_aos(&bld, s, t, width_vec, height_vec,
-                                    stride_vec, data_array, texel);
+                                    stride_array, data_array, texel);
    }
    else {
       lp_build_sample_general(&bld, unit, s, t, r,
                               width, height, depth,
                               width_vec, height_vec, depth_vec,
-                              stride_vec, NULL, data_array,
+                              stride_array, NULL, data_array,
                               texel);
    }
 
index 08c8f93794d219e4ec3428046819759bf066f655..5887613120d83a0596b25d1518df5ceb63854bb5 100644 (file)
@@ -57,7 +57,8 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
       elem_types[LP_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
       elem_types[LP_JIT_TEXTURE_DEPTH] = LLVMInt32Type();
       elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
-      elem_types[LP_JIT_TEXTURE_STRIDE] = LLVMInt32Type();
+      elem_types[LP_JIT_TEXTURE_ROW_STRIDE] =
+         LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_2D_LEVELS);
       elem_types[LP_JIT_TEXTURE_DATA] =
          LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
                        LP_MAX_TEXTURE_2D_LEVELS);
@@ -76,9 +77,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, last_level,
                              screen->target, texture_type,
                              LP_JIT_TEXTURE_LAST_LEVEL);
-      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, stride,
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride,
                              screen->target, texture_type,
-                             LP_JIT_TEXTURE_STRIDE);
+                             LP_JIT_TEXTURE_ROW_STRIDE);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
                              screen->target, texture_type,
                              LP_JIT_TEXTURE_DATA);
index 5cc7a12c03bd96ec8cb05153cc71f2e28654558c..13167ae3bf4edbc4e05a260242238a52d7c45c97 100644 (file)
@@ -51,7 +51,7 @@ struct lp_jit_texture
    uint32_t height;
    uint32_t depth;
    uint32_t last_level;
-   uint32_t stride;
+   uint32_t row_stride[LP_MAX_TEXTURE_2D_LEVELS];
    const void *data[LP_MAX_TEXTURE_2D_LEVELS];
 };
 
@@ -61,7 +61,7 @@ enum {
    LP_JIT_TEXTURE_HEIGHT,
    LP_JIT_TEXTURE_DEPTH,
    LP_JIT_TEXTURE_LAST_LEVEL,
-   LP_JIT_TEXTURE_STRIDE,
+   LP_JIT_TEXTURE_ROW_STRIDE,
    LP_JIT_TEXTURE_DATA
 };
 
index d6d37c4809011299a22c73c970cb0e8e40c109ae..c870f89d01d4d78ff836c564281ecf9639b9c03c 100644 (file)
@@ -471,13 +471,13 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
          jit_tex->height = tex->height0;
          jit_tex->depth = tex->depth0;
          jit_tex->last_level = tex->last_level;
-         jit_tex->stride = lp_tex->stride[0];
          if (!lp_tex->dt) {
             /* regular texture - setup array of mipmap level pointers */
             int j;
             for (j = 0; j <= tex->last_level; j++) {
                jit_tex->data[j] =
                   (ubyte *) lp_tex->data + lp_tex->level_offset[j];
+               jit_tex->row_stride[j] = lp_tex->stride[j];
             }
          }
          else {
@@ -490,6 +490,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
             struct sw_winsys *winsys = screen->winsys;
             jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
                                                       PIPE_BUFFER_USAGE_CPU_READ);
+            jit_tex->row_stride[0] = lp_tex->stride[0];
             assert(jit_tex->data[0]);
          }
 
index 5a3cf37d6d8eafb45c6c734d6658edb836e40a6c..662508af61a32e97e4f0564e973b622915413fbb 100644 (file)
@@ -147,7 +147,7 @@ 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(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE)
-LP_LLVM_TEXTURE_MEMBER(stride,     LP_JIT_TEXTURE_STRIDE, TRUE)
+LP_LLVM_TEXTURE_MEMBER(row_stride, LP_JIT_TEXTURE_ROW_STRIDE, FALSE)
 LP_LLVM_TEXTURE_MEMBER(data_ptr,   LP_JIT_TEXTURE_DATA, FALSE)
 
 
@@ -204,7 +204,7 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
    sampler->dynamic_state.base.height = lp_llvm_texture_height;
    sampler->dynamic_state.base.depth = lp_llvm_texture_depth;
    sampler->dynamic_state.base.last_level = lp_llvm_texture_last_level;
-   sampler->dynamic_state.base.stride = lp_llvm_texture_stride;
+   sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride;
    sampler->dynamic_state.base.data_ptr = lp_llvm_texture_data_ptr;
    sampler->dynamic_state.static_state = static_state;
    sampler->dynamic_state.context_ptr = context_ptr;