Mesa (master): gallivm,draw,llvmpipe: use base ptr + mip offsets instead of mip pointers

Roland Scheidegger sroland at kemper.freedesktop.org
Mon Nov 12 20:03:36 UTC 2012


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

Author: Roland Scheidegger <sroland at vmware.com>
Date:   Mon Nov 12 20:35:04 2012 +0100

gallivm,draw,llvmpipe: use base ptr + mip offsets instead of mip pointers

This might have a slight overhead but handling mip offsets more like
the width (and image) strides should make some things easier (mip level
being just part of the offset calculation) later.

Reviewed-by: Brian Paul <brianp at vmware.com>
Reviewed-by: José Fonseca <jfonseca at vmware.com>

---

 src/gallium/auxiliary/draw/draw_context.c         |    8 ++-
 src/gallium/auxiliary/draw/draw_context.h         |    3 +-
 src/gallium/auxiliary/draw/draw_llvm.c            |   19 +++++---
 src/gallium/auxiliary/draw/draw_llvm.h            |    9 ++-
 src/gallium/auxiliary/draw/draw_llvm_sample.c     |    6 ++-
 src/gallium/auxiliary/gallivm/lp_bld_sample.c     |    7 ++-
 src/gallium/auxiliary/gallivm/lp_bld_sample.h     |   13 ++++-
 src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c |    8 ++-
 src/gallium/drivers/i915/i915_state.c             |   12 ++--
 src/gallium/drivers/llvmpipe/lp_jit.c             |   14 +++--
 src/gallium/drivers/llvmpipe/lp_jit.h             |    6 ++-
 src/gallium/drivers/llvmpipe/lp_setup.c           |   53 +++++++++++++++------
 src/gallium/drivers/llvmpipe/lp_state_sampler.c   |   30 +++++++++---
 src/gallium/drivers/llvmpipe/lp_tex_sample.c      |    6 ++-
 14 files changed, 131 insertions(+), 63 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index 91dd2e1..6980631 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -802,17 +802,19 @@ draw_set_mapped_texture(struct draw_context *draw,
                         unsigned sampler_idx,
                         uint32_t width, uint32_t height, uint32_t depth,
                         uint32_t first_level, uint32_t last_level,
+                        const void *base_ptr,
                         uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS],
                         uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS],
-                        const void *data[PIPE_MAX_TEXTURE_LEVELS])
+                        uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS])
 {
    if (shader_stage == PIPE_SHADER_VERTEX) {
 #ifdef HAVE_LLVM
       if (draw->llvm)
          draw_llvm_set_mapped_texture(draw,
                                       sampler_idx,
-                                      width, height, depth, first_level, last_level,
-                                      row_stride, img_stride, data);
+                                      width, height, depth, first_level,
+                                      last_level, base_ptr,
+                                      row_stride, img_stride, mip_offsets);
 #endif
    }
 }
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 3063323..a4937b6 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -154,9 +154,10 @@ draw_set_mapped_texture(struct draw_context *draw,
                         unsigned sampler_idx,
                         uint32_t width, uint32_t height, uint32_t depth,
                         uint32_t first_level, uint32_t last_level,
+                        const void *base,
                         uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS],
                         uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS],
-                        const void *data[PIPE_MAX_TEXTURE_LEVELS]);
+                        uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]);
 
 
 /*
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index ebfe437..6f0e1de 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -79,12 +79,12 @@ create_jit_texture_type(struct gallivm_state *gallivm, const char *struct_name)
    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_BASE] =
+      LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0);
    elem_types[DRAW_JIT_TEXTURE_ROW_STRIDE] =
    elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] =
+   elem_types[DRAW_JIT_TEXTURE_MIP_OFFSETS] =
       LLVMArrayType(int32_type, PIPE_MAX_TEXTURE_LEVELS);
-   elem_types[DRAW_JIT_TEXTURE_DATA] =
-      LLVMArrayType(LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0),
-                    PIPE_MAX_TEXTURE_LEVELS);
    elem_types[DRAW_JIT_TEXTURE_MIN_LOD] =
    elem_types[DRAW_JIT_TEXTURE_MAX_LOD] =
    elem_types[DRAW_JIT_TEXTURE_LOD_BIAS] = LLVMFloatTypeInContext(gallivm->context);
@@ -118,15 +118,18 @@ create_jit_texture_type(struct gallivm_state *gallivm, const char *struct_name)
    LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, last_level,
                           target, texture_type,
                           DRAW_JIT_TEXTURE_LAST_LEVEL);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, base,
+                          target, texture_type,
+                          DRAW_JIT_TEXTURE_BASE);
    LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, row_stride,
                           target, texture_type,
                           DRAW_JIT_TEXTURE_ROW_STRIDE);
    LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, img_stride,
                           target, texture_type,
                           DRAW_JIT_TEXTURE_IMG_STRIDE);
-   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, data,
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, mip_offsets,
                           target, texture_type,
-                          DRAW_JIT_TEXTURE_DATA);
+                          DRAW_JIT_TEXTURE_MIP_OFFSETS);
    LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, min_lod,
                           target, texture_type,
                           DRAW_JIT_TEXTURE_MIN_LOD);
@@ -1364,9 +1367,10 @@ draw_llvm_set_mapped_texture(struct draw_context *draw,
                              unsigned sampler_idx,
                              uint32_t width, uint32_t height, uint32_t depth,
                              uint32_t first_level, uint32_t last_level,
+                             const void *base_ptr,
                              uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS],
                              uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS],
-                             const void *data[PIPE_MAX_TEXTURE_LEVELS])
+                             uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS])
 {
    unsigned j;
    struct draw_jit_texture *jit_tex;
@@ -1380,9 +1384,10 @@ draw_llvm_set_mapped_texture(struct draw_context *draw,
    jit_tex->depth = depth;
    jit_tex->first_level = first_level;
    jit_tex->last_level = last_level;
+   jit_tex->base = base_ptr;
 
    for (j = first_level; j <= last_level; j++) {
-      jit_tex->data[j] = data[j];
+      jit_tex->mip_offsets[j] = mip_offsets[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 9a291a4..d7a630e 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.h
+++ b/src/gallium/auxiliary/draw/draw_llvm.h
@@ -47,9 +47,10 @@ struct draw_jit_texture
    uint32_t depth;
    uint32_t first_level;
    uint32_t last_level;
+   const void *base;
    uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
    uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
-   const void *data[PIPE_MAX_TEXTURE_LEVELS];
+   uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS];
    float min_lod;
    float max_lod;
    float lod_bias;
@@ -62,9 +63,10 @@ enum {
    DRAW_JIT_TEXTURE_DEPTH,
    DRAW_JIT_TEXTURE_FIRST_LEVEL,
    DRAW_JIT_TEXTURE_LAST_LEVEL,
+   DRAW_JIT_TEXTURE_BASE,
    DRAW_JIT_TEXTURE_ROW_STRIDE,
    DRAW_JIT_TEXTURE_IMG_STRIDE,
-   DRAW_JIT_TEXTURE_DATA,
+   DRAW_JIT_TEXTURE_MIP_OFFSETS,
    DRAW_JIT_TEXTURE_MIN_LOD,
    DRAW_JIT_TEXTURE_MAX_LOD,
    DRAW_JIT_TEXTURE_LOD_BIAS,
@@ -293,8 +295,9 @@ draw_llvm_set_mapped_texture(struct draw_context *draw,
                              unsigned sampler_idx,
                              uint32_t width, uint32_t height, uint32_t depth,
                              uint32_t first_level, uint32_t last_level,
+                             const void *base_ptr,
                              uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS],
                              uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS],
-                             const void *data[PIPE_MAX_TEXTURE_LEVELS]);
+                             uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]);
 
 #endif
diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c
index 5331716..0892d16 100644
--- a/src/gallium/auxiliary/draw/draw_llvm_sample.c
+++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c
@@ -146,9 +146,10 @@ 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(base_ptr,   DRAW_JIT_TEXTURE_BASE, 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)
-DRAW_LLVM_TEXTURE_MEMBER(data_ptr,   DRAW_JIT_TEXTURE_DATA, FALSE)
+DRAW_LLVM_TEXTURE_MEMBER(mip_offsets, DRAW_JIT_TEXTURE_MIP_OFFSETS, FALSE)
 DRAW_LLVM_TEXTURE_MEMBER(min_lod,    DRAW_JIT_TEXTURE_MIN_LOD, TRUE)
 DRAW_LLVM_TEXTURE_MEMBER(max_lod,    DRAW_JIT_TEXTURE_MAX_LOD, TRUE)
 DRAW_LLVM_TEXTURE_MEMBER(lod_bias,   DRAW_JIT_TEXTURE_LOD_BIAS, TRUE)
@@ -238,7 +239,8 @@ draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
    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;
-   sampler->dynamic_state.base.data_ptr = draw_llvm_texture_data_ptr;
+   sampler->dynamic_state.base.base_ptr = draw_llvm_texture_base_ptr;
+   sampler->dynamic_state.base.mip_offsets = draw_llvm_texture_mip_offsets;
    sampler->dynamic_state.base.min_lod = draw_llvm_texture_min_lod;
    sampler->dynamic_state.base.max_lod = draw_llvm_texture_max_lod;
    sampler->dynamic_state.base.lod_bias = draw_llvm_texture_lod_bias;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index 63cf610..0727fd2 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -733,12 +733,13 @@ lp_build_get_mipmap_level(struct lp_build_sample_context *bld,
                           LLVMValueRef level)
 {
    LLVMBuilderRef builder = bld->gallivm->builder;
-   LLVMValueRef indexes[2], data_ptr;
+   LLVMValueRef indexes[2], data_ptr, mip_offset;
 
    indexes[0] = lp_build_const_int32(bld->gallivm, 0);
    indexes[1] = level;
-   data_ptr = LLVMBuildGEP(builder, bld->data_array, indexes, 2, "");
-   data_ptr = LLVMBuildLoad(builder, data_ptr, "");
+   mip_offset = LLVMBuildGEP(builder, bld->mip_offsets, indexes, 2, "");
+   mip_offset = LLVMBuildLoad(builder, mip_offset, "");
+   data_ptr = LLVMBuildGEP(builder, bld->base_ptr, &mip_offset, 1, "");
    return data_ptr;
 }
 
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
index 0f3d8ae..d8a068d 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -157,12 +157,18 @@ struct lp_sampler_dynamic_state
                   struct gallivm_state *gallivm,
                   unsigned unit);
 
-   /** Obtain pointer to array of pointers to mimpap levels */
+   /** Obtain pointer to base of texture */
    LLVMValueRef
-   (*data_ptr)( const struct lp_sampler_dynamic_state *state,
+   (*base_ptr)( const struct lp_sampler_dynamic_state *state,
                 struct gallivm_state *gallivm,
                 unsigned unit);
 
+   /** Obtain pointer to array of mipmap offsets */
+   LLVMValueRef
+   (*mip_offsets)( const struct lp_sampler_dynamic_state *state,
+                   struct gallivm_state *gallivm,
+                   unsigned unit);
+
    /** Obtain texture min lod (returns float) */
    LLVMValueRef
    (*min_lod)(const struct lp_sampler_dynamic_state *state,
@@ -246,7 +252,8 @@ struct lp_build_sample_context
    /* Common dynamic state values */
    LLVMValueRef row_stride_array;
    LLVMValueRef img_stride_array;
-   LLVMValueRef data_array;
+   LLVMValueRef base_ptr;
+   LLVMValueRef mip_offsets;
 
    /** Integer vector with texture width, height, depth */
    LLVMValueRef int_size;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index aaef797..00a5b18 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -1298,8 +1298,9 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
    tex_depth = dynamic_state->depth(dynamic_state, gallivm, unit);
    bld.row_stride_array = dynamic_state->row_stride(dynamic_state, gallivm, unit);
    bld.img_stride_array = dynamic_state->img_stride(dynamic_state, gallivm, unit);
-   bld.data_array = dynamic_state->data_ptr(dynamic_state, gallivm, unit);
-   /* Note that data_array is an array[level] of pointers to texture images */
+   bld.base_ptr = dynamic_state->base_ptr(dynamic_state, gallivm, unit);
+   bld.mip_offsets = dynamic_state->mip_offsets(dynamic_state, gallivm, unit);
+   /* Note that mip_offsets is an array[level] of offsets to texture images */
 
    s = coords[0];
    t = coords[1];
@@ -1439,7 +1440,8 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
             bld4.dims = bld.dims;
             bld4.row_stride_array = bld.row_stride_array;
             bld4.img_stride_array = bld.img_stride_array;
-            bld4.data_array = bld.data_array;
+            bld4.base_ptr = bld.base_ptr;
+            bld4.mip_offsets = bld.mip_offsets;
             bld4.int_size = bld.int_size;
 
             bld4.vector_width = lp_type_width(type4);
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 7fa648f..37ad1ed 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -360,7 +360,7 @@ i915_prepare_vertex_sampling(struct i915_context *i915)
    unsigned i,j;
    uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
    uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
-   const void* data[PIPE_MAX_TEXTURE_LEVELS];
+   uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS];
    unsigned num = i915->num_vertex_sampler_views;
    struct pipe_sampler_view **views = i915->vertex_sampler_views;
 
@@ -381,16 +381,15 @@ i915_prepare_vertex_sampling(struct i915_context *i915)
           */
          pipe_resource_reference(&i915->mapped_vs_tex[i], tex);
 
-	 i915->mapped_vs_tex_buffer[i] = i915_tex->buffer;
+         i915->mapped_vs_tex_buffer[i] = i915_tex->buffer;
          addr = iws->buffer_map(iws,
                                 i915_tex->buffer,
                                 FALSE /* read only */);
 
          /* Setup array of mipmap level pointers */
-	 /* FIXME: handle 3D textures? */
+         /* FIXME: handle 3D textures? */
          for (j = view->u.tex.first_level; j <= tex->last_level; j++) {
-            unsigned offset = i915_texture_offset(i915_tex, j , 0 /* FIXME depth */);
-            data[j] = addr + offset;
+            mip_offsets[j] = i915_texture_offset(i915_tex, j , 0 /* FIXME depth */);
             row_stride[j] = i915_tex->stride;
             img_stride[j] = 0; /* FIXME */;
          }
@@ -400,7 +399,8 @@ i915_prepare_vertex_sampling(struct i915_context *i915)
                                  i,
                                  tex->width0, tex->height0, tex->depth0,
                                  view->u.tex.first_level, tex->last_level,
-                                 row_stride, img_stride, data);
+                                 addr,
+                                 row_stride, img_stride, mip_offsets);
       } else
          i915->mapped_vs_tex[i] = NULL;
    }
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 7a85eab..20c53cb 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -55,13 +55,12 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp)
       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_LAST_LEVEL] = LLVMInt32TypeInContext(lc);
+      elem_types[LP_JIT_TEXTURE_BASE] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
       elem_types[LP_JIT_TEXTURE_ROW_STRIDE] =
       elem_types[LP_JIT_TEXTURE_IMG_STRIDE] =
+      elem_types[LP_JIT_TEXTURE_MIP_OFFSETS] =
          LLVMArrayType(LLVMInt32TypeInContext(lc), LP_MAX_TEXTURE_LEVELS);
-      elem_types[LP_JIT_TEXTURE_DATA] =
-         LLVMArrayType(LLVMPointerType(LLVMInt8TypeInContext(lc), 0),
-                       LP_MAX_TEXTURE_LEVELS);
       elem_types[LP_JIT_TEXTURE_MIN_LOD] =
       elem_types[LP_JIT_TEXTURE_MAX_LOD] =
       elem_types[LP_JIT_TEXTURE_LOD_BIAS] = LLVMFloatTypeInContext(lc);
@@ -91,15 +90,18 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp)
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, last_level,
                              gallivm->target, texture_type,
                              LP_JIT_TEXTURE_LAST_LEVEL);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, base,
+                             gallivm->target, texture_type,
+                             LP_JIT_TEXTURE_BASE);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride,
                              gallivm->target, texture_type,
                              LP_JIT_TEXTURE_ROW_STRIDE);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, img_stride,
                              gallivm->target, texture_type,
                              LP_JIT_TEXTURE_IMG_STRIDE);
-      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, mip_offsets,
                              gallivm->target, texture_type,
-                             LP_JIT_TEXTURE_DATA);
+                             LP_JIT_TEXTURE_MIP_OFFSETS);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, min_lod,
                              gallivm->target, texture_type,
                              LP_JIT_TEXTURE_MIN_LOD);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 584d2c8..94a2bb5 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -53,9 +53,10 @@ struct lp_jit_texture
    uint32_t depth;
    uint32_t first_level;
    uint32_t last_level;
+   const void *base;
    uint32_t row_stride[LP_MAX_TEXTURE_LEVELS];
    uint32_t img_stride[LP_MAX_TEXTURE_LEVELS];
-   const void *data[LP_MAX_TEXTURE_LEVELS];
+   uint32_t mip_offsets[LP_MAX_TEXTURE_LEVELS];
    /* sampler state, actually */
    float min_lod;
    float max_lod;
@@ -70,9 +71,10 @@ enum {
    LP_JIT_TEXTURE_DEPTH,
    LP_JIT_TEXTURE_FIRST_LEVEL,
    LP_JIT_TEXTURE_LAST_LEVEL,
+   LP_JIT_TEXTURE_BASE,
    LP_JIT_TEXTURE_ROW_STRIDE,
    LP_JIT_TEXTURE_IMG_STRIDE,
-   LP_JIT_TEXTURE_DATA,
+   LP_JIT_TEXTURE_MIP_OFFSETS,
    LP_JIT_TEXTURE_MIN_LOD,
    LP_JIT_TEXTURE_MAX_LOD,
    LP_JIT_TEXTURE_LOD_BIAS,
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index e5c84bb..60144c3 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -663,24 +663,46 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
          pipe_resource_reference(&setup->fs.current_tex[i], tex);
 
          if (!lp_tex->dt) {
-            /* regular texture - setup array of mipmap level pointers */
+            /* regular texture - setup array of mipmap level offsets */
+            void *mip_ptr;
             int j;
+            /*
+             * XXX this is messed up we don't want to accidentally trigger
+             * tiled->linear conversion for levels we don't need.
+             * So ask for first_level data (which will allocate all levels)
+             * then if successful get base ptr.
+             */
+            mip_ptr = llvmpipe_get_texture_image_all(lp_tex, view->u.tex.first_level,
+                                                     LP_TEX_USAGE_READ,
+                                                     LP_TEX_LAYOUT_LINEAR);
+            if ((LP_PERF & PERF_TEX_MEM) || !mip_ptr) {
+               /* out of memory - use dummy tile memory */
+               jit_tex->base = lp_dummy_tile;
+               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;
+            }
+            else {
+               jit_tex->base = lp_tex->linear_img.data;
+            }
             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);
+               mip_ptr = llvmpipe_get_texture_image_all(lp_tex, j,
+                                                        LP_TEX_USAGE_READ,
+                                                        LP_TEX_LAYOUT_LINEAR);
+               jit_tex->mip_offsets[j] = (uint8_t *)mip_ptr - (uint8_t *)jit_tex->base;
+               /*
+                * could get mip offset directly but need call above to
+                * invoke tiled->linear conversion.
+                */
+               assert(lp_tex->linear_mip_offsets[j] == jit_tex->mip_offsets[j]);
                jit_tex->row_stride[j] = lp_tex->row_stride[j];
                jit_tex->img_stride[j] = lp_tex->img_stride[j];
 
-               if ((LP_PERF & PERF_TEX_MEM) ||
-		   !jit_tex->data[j]) {
+               if (jit_tex->base == lp_dummy_tile) {
                   /* out of memory - use dummy tile memory */
-                  jit_tex->data[j] = lp_dummy_tile;
-                  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->mip_offsets[j] = 0;
                   jit_tex->row_stride[j] = 0;
                   jit_tex->img_stride[j] = 0;
                }
@@ -693,11 +715,12 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
              */
             struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
             struct sw_winsys *winsys = screen->winsys;
-            jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
-							 PIPE_TRANSFER_READ);
+            jit_tex->base = winsys->displaytarget_map(winsys, lp_tex->dt,
+                                                         PIPE_TRANSFER_READ);
             jit_tex->row_stride[0] = lp_tex->row_stride[0];
             jit_tex->img_stride[0] = lp_tex->img_stride[0];
-            assert(jit_tex->data[0]);
+            jit_tex->mip_offsets[0] = 0;
+            assert(jit_tex->base);
          }
       }
    }
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index 0be900e..58fac3f 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -255,7 +255,8 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
    unsigned i;
    uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
    uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
-   const void *data[PIPE_MAX_TEXTURE_LEVELS];
+   uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS];
+   const void *addr;
 
    assert(num <= PIPE_MAX_SAMPLERS);
    if (!num)
@@ -275,11 +276,24 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
 
          if (!lp_tex->dt) {
             /* regular texture - setup array of mipmap level pointers */
+            /* XXX this may fail due to OOM ? */
             int j;
+            void *mip_ptr;
+            /* must trigger allocation first before we can get base ptr */
+            mip_ptr = llvmpipe_get_texture_image_all(lp_tex, view->u.tex.first_level,
+                                                     LP_TEX_USAGE_READ,
+                                                     LP_TEX_LAYOUT_LINEAR);
+            addr = lp_tex->linear_img.data;
             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);
+               mip_ptr = llvmpipe_get_texture_image_all(lp_tex, j,
+                                                        LP_TEX_USAGE_READ,
+                                                        LP_TEX_LAYOUT_LINEAR);
+               mip_offsets[j] = (uint8_t *)mip_ptr - (uint8_t *)addr;
+               /*
+                * could get mip offset directly but need call above to
+                * invoke tiled->linear conversion.
+                */
+               assert(lp_tex->linear_mip_offsets[j] == mip_offsets[j]);
                row_stride[j] = lp_tex->row_stride[j];
                img_stride[j] = lp_tex->img_stride[j];
             }
@@ -291,18 +305,20 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
              */
             struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
             struct sw_winsys *winsys = screen->winsys;
-            data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
+            addr = winsys->displaytarget_map(winsys, lp_tex->dt,
                                                 PIPE_TRANSFER_READ);
             row_stride[0] = lp_tex->row_stride[0];
             img_stride[0] = lp_tex->img_stride[0];
-            assert(data[0]);
+            mip_offsets[0] = 0;
+            assert(addr);
          }
          draw_set_mapped_texture(lp->draw,
                                  PIPE_SHADER_VERTEX,
                                  i,
                                  tex->width0, tex->height0, tex->depth0,
                                  view->u.tex.first_level, tex->last_level,
-                                 row_stride, img_stride, data);
+                                 addr,
+                                 row_stride, img_stride, mip_offsets);
       }
    }
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
index 9151e42..1c5c009 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
@@ -151,9 +151,10 @@ 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(base_ptr,   LP_JIT_TEXTURE_BASE, 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)
-LP_LLVM_TEXTURE_MEMBER(data_ptr,   LP_JIT_TEXTURE_DATA, FALSE)
+LP_LLVM_TEXTURE_MEMBER(mip_offsets, LP_JIT_TEXTURE_MIP_OFFSETS, FALSE)
 LP_LLVM_TEXTURE_MEMBER(min_lod,    LP_JIT_TEXTURE_MIN_LOD, TRUE)
 LP_LLVM_TEXTURE_MEMBER(max_lod,    LP_JIT_TEXTURE_MAX_LOD, TRUE)
 LP_LLVM_TEXTURE_MEMBER(lod_bias,   LP_JIT_TEXTURE_LOD_BIAS, TRUE)
@@ -246,9 +247,10 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
    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.base_ptr = lp_llvm_texture_base_ptr;
    sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride;
    sampler->dynamic_state.base.img_stride = lp_llvm_texture_img_stride;
-   sampler->dynamic_state.base.data_ptr = lp_llvm_texture_data_ptr;
+   sampler->dynamic_state.base.mip_offsets = lp_llvm_texture_mip_offsets;
    sampler->dynamic_state.base.min_lod = lp_llvm_texture_min_lod;
    sampler->dynamic_state.base.max_lod = lp_llvm_texture_max_lod;
    sampler->dynamic_state.base.lod_bias = lp_llvm_texture_lod_bias;




More information about the mesa-commit mailing list