Mesa (master): llvmpipe/gallivm: checkpoint: array of pointers to mipmap levels

Brian Paul brianp at kemper.freedesktop.org
Mon Mar 8 15:27:30 PST 2010


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

Author: Brian Paul <brianp at vmware.com>
Date:   Mon Mar  8 15:19:13 2010 -0700

llvmpipe/gallivm: checkpoint: array of pointers to mipmap levels

Change the texture data_ptr from just a single image pointer to an
array of image pointers, indexed by mipmap level.
We'll use this for mipmap filtering.
For now, the mipmap level is hard-coded to zero.

---

 src/gallium/auxiliary/gallivm/lp_bld_sample.c     |    3 +-
 src/gallium/auxiliary/gallivm/lp_bld_sample.h     |    3 +-
 src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c |   69 ++++++++++++++-------
 src/gallium/drivers/llvmpipe/lp_jit.c             |    4 +-
 src/gallium/drivers/llvmpipe/lp_jit.h             |    3 +-
 src/gallium/drivers/llvmpipe/lp_setup.c           |   16 +++--
 src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c |   27 +++++---
 7 files changed, 81 insertions(+), 44 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index 29cadcc..311c9f1 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -162,8 +162,7 @@ lp_build_sample_offset(struct lp_build_context *bld,
                        const struct util_format_description *format_desc,
                        LLVMValueRef x,
                        LLVMValueRef y,
-                       LLVMValueRef y_stride,
-                       LLVMValueRef data_ptr)
+                       LLVMValueRef y_stride)
 {
    LLVMValueRef x_stride;
    LLVMValueRef offset;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
index 5ba0925..68db91d 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -148,8 +148,7 @@ lp_build_sample_offset(struct lp_build_context *bld,
                        const struct util_format_description *format_desc,
                        LLVMValueRef x,
                        LLVMValueRef y,
-                       LLVMValueRef y_stride,
-                       LLVMValueRef data_ptr);
+                       LLVMValueRef y_stride);
 
 
 void
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 9058f76..1dca29c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -124,13 +124,14 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
                           LLVMValueRef x,
                           LLVMValueRef y,
                           LLVMValueRef y_stride,
-                          LLVMValueRef data_ptr,
+                          LLVMValueRef data_array,
                           LLVMValueRef *texel)
 {
    struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
    LLVMValueRef offset;
    LLVMValueRef packed;
    LLVMValueRef use_border = NULL;
+   LLVMValueRef data_ptr;
 
    /* use_border = x < 0 || x >= width || y < 0 || y >= height */
    if (wrap_mode_uses_border_color(bld->static_state->wrap_s)) {
@@ -153,6 +154,16 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
       }
    }
 
+   /* XXX always use mipmap level 0 for now */
+   {
+      const int level = 0;
+      LLVMValueRef indexes[2];
+      indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+      indexes[1] = LLVMConstInt(LLVMInt32Type(), level, 0);
+      data_ptr = LLVMBuildGEP(bld->builder, data_array, indexes, 2, "");
+      data_ptr = LLVMBuildLoad(bld->builder, data_ptr, "");
+   }
+
    /*
     * Note: if we find an app which frequently samples the texture border
     * we might want to implement a true conditional here to avoid sampling
@@ -171,8 +182,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
    /* convert x,y coords to linear offset from start of texture, in bytes */
    offset = lp_build_sample_offset(&bld->uint_coord_bld,
                                    bld->format_desc,
-                                   x, y, y_stride,
-                                   data_ptr);
+                                   x, y, y_stride);
 
    assert(bld->format_desc->block.width == 1);
    assert(bld->format_desc->block.height == 1);
@@ -210,19 +220,31 @@ lp_build_sample_packed(struct lp_build_sample_context *bld,
                        LLVMValueRef x,
                        LLVMValueRef y,
                        LLVMValueRef y_stride,
-                       LLVMValueRef data_ptr)
+                       LLVMValueRef data_array)
 {
    LLVMValueRef offset;
+   LLVMValueRef data_ptr;
 
    offset = lp_build_sample_offset(&bld->uint_coord_bld,
                                    bld->format_desc,
-                                   x, y, y_stride,
-                                   data_ptr);
+                                   x, y, y_stride);
 
    assert(bld->format_desc->block.width == 1);
    assert(bld->format_desc->block.height == 1);
    assert(bld->format_desc->block.bits <= bld->texel_type.width);
 
+   /* XXX always use mipmap level 0 for now */
+   {
+      const int level = 0;
+      LLVMValueRef indexes[2];
+      /* get data_ptr[level] */
+      indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+      indexes[1] = LLVMConstInt(LLVMInt32Type(), level, 0);
+      data_ptr = LLVMBuildGEP(bld->builder, data_array, indexes, 2, "");
+      /* load texture base address */
+      data_ptr = LLVMBuildLoad(bld->builder, data_ptr, "");
+   }
+
    return lp_build_gather(bld->builder,
                           bld->texel_type.length,
                           bld->format_desc->block.bits,
@@ -720,7 +742,7 @@ lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld,
                                LLVMValueRef width,
                                LLVMValueRef height,
                                LLVMValueRef stride,
-                               LLVMValueRef data_ptr,
+                               LLVMValueRef data_array,
                                LLVMValueRef *texel)
 {
    LLVMValueRef x, y;
@@ -735,7 +757,7 @@ lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld,
    lp_build_name(x, "tex.x.wrapped");
    lp_build_name(y, "tex.y.wrapped");
 
-   lp_build_sample_texel_soa(bld, width, height, x, y, stride, data_ptr, texel);
+   lp_build_sample_texel_soa(bld, width, height, x, y, stride, data_array, texel);
 }
 
 
@@ -749,7 +771,7 @@ lp_build_sample_2d_linear_soa(struct lp_build_sample_context *bld,
                               LLVMValueRef width,
                               LLVMValueRef height,
                               LLVMValueRef stride,
-                              LLVMValueRef data_ptr,
+                              LLVMValueRef data_array,
                               LLVMValueRef *texel)
 {
    LLVMValueRef s_fpart;
@@ -764,10 +786,10 @@ lp_build_sample_2d_linear_soa(struct lp_build_sample_context *bld,
    lp_build_sample_wrap_linear(bld, t, height, bld->static_state->pot_height,
                                bld->static_state->wrap_t, &y0, &y1, &t_fpart);
 
-   lp_build_sample_texel_soa(bld, width, height, x0, y0, stride, data_ptr, neighbors[0][0]);
-   lp_build_sample_texel_soa(bld, width, height, x1, y0, stride, data_ptr, neighbors[0][1]);
-   lp_build_sample_texel_soa(bld, width, height, x0, y1, stride, data_ptr, neighbors[1][0]);
-   lp_build_sample_texel_soa(bld, width, height, x1, y1, stride, data_ptr, neighbors[1][1]);
+   lp_build_sample_texel_soa(bld, width, height, x0, y0, stride, data_array, neighbors[0][0]);
+   lp_build_sample_texel_soa(bld, width, height, x1, y0, stride, data_array, neighbors[0][1]);
+   lp_build_sample_texel_soa(bld, width, height, x0, y1, stride, data_array, neighbors[1][0]);
+   lp_build_sample_texel_soa(bld, width, height, x1, y1, stride, data_array, neighbors[1][1]);
 
    /* TODO: Don't interpolate missing channels */
    for(chan = 0; chan < 4; ++chan) {
@@ -818,7 +840,7 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
                               LLVMValueRef width,
                               LLVMValueRef height,
                               LLVMValueRef stride,
-                              LLVMValueRef data_ptr,
+                              LLVMValueRef data_array,
                               LLVMValueRef *texel)
 {
    LLVMBuilderRef builder = bld->builder;
@@ -958,10 +980,10 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
     * The higher 8 bits of the resulting elements will be zero.
     */
 
-   neighbors[0][0] = lp_build_sample_packed(bld, x0, y0, stride, data_ptr);
-   neighbors[0][1] = lp_build_sample_packed(bld, x1, y0, stride, data_ptr);
-   neighbors[1][0] = lp_build_sample_packed(bld, x0, y1, stride, data_ptr);
-   neighbors[1][1] = lp_build_sample_packed(bld, x1, y1, stride, data_ptr);
+   neighbors[0][0] = lp_build_sample_packed(bld, x0, y0, stride, data_array);
+   neighbors[0][1] = lp_build_sample_packed(bld, x1, y0, stride, data_array);
+   neighbors[1][0] = lp_build_sample_packed(bld, x0, y1, stride, data_array);
+   neighbors[1][1] = lp_build_sample_packed(bld, x1, y1, stride, data_array);
 
    neighbors[0][0] = LLVMBuildBitCast(builder, neighbors[0][0], u8n_vec_type, "");
    neighbors[0][1] = LLVMBuildBitCast(builder, neighbors[0][1], u8n_vec_type, "");
@@ -1248,7 +1270,7 @@ lp_build_sample_soa(LLVMBuilderRef builder,
    LLVMValueRef width;
    LLVMValueRef height;
    LLVMValueRef stride;
-   LLVMValueRef data_ptr;
+   LLVMValueRef data_array;
    LLVMValueRef s;
    LLVMValueRef t;
    LLVMValueRef r;
@@ -1276,7 +1298,8 @@ lp_build_sample_soa(LLVMBuilderRef builder,
    width = dynamic_state->width(dynamic_state, builder, unit);
    height = dynamic_state->height(dynamic_state, builder, unit);
    stride = dynamic_state->stride(dynamic_state, builder, unit);
-   data_ptr = dynamic_state->data_ptr(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 */
 
    s = coords[0];
    t = coords[1];
@@ -1292,17 +1315,17 @@ lp_build_sample_soa(LLVMBuilderRef builder,
    switch (static_state->min_img_filter) {
    case PIPE_TEX_FILTER_NEAREST:
       lp_build_sample_2d_nearest_soa(&bld, s, t, width, height,
-                                     stride, data_ptr, texel);
+                                     stride, data_array, texel);
       break;
    case PIPE_TEX_FILTER_LINEAR:
       if(lp_format_is_rgba8(bld.format_desc) &&
          is_simple_wrap_mode(static_state->wrap_s) &&
          is_simple_wrap_mode(static_state->wrap_t))
          lp_build_sample_2d_linear_aos(&bld, s, t, width, height,
-                                       stride, data_ptr, texel);
+                                       stride, data_array, texel);
       else
          lp_build_sample_2d_linear_soa(&bld, s, t, width, height,
-                                       stride, data_ptr, texel);
+                                       stride, data_array, texel);
       break;
    default:
       assert(0);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index bacff50..08c8f93 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -58,7 +58,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
       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_DATA]   = LLVMPointerType(LLVMInt8Type(), 0);
+      elem_types[LP_JIT_TEXTURE_DATA] =
+         LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
+                       LP_MAX_TEXTURE_2D_LEVELS);
 
       texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
 
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 0ebb282..5cc7a12 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -39,6 +39,7 @@
 #include "gallivm/lp_bld_struct.h"
 
 #include "pipe/p_state.h"
+#include "lp_texture.h"
 
 
 struct llvmpipe_screen;
@@ -51,7 +52,7 @@ struct lp_jit_texture
    uint32_t depth;
    uint32_t last_level;
    uint32_t stride;
-   const void *data;
+   const void *data[LP_MAX_TEXTURE_2D_LEVELS];
 };
 
 
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index b0713c3..cc7c18c 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -472,19 +472,25 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
          jit_tex->depth = tex->depth0;
          jit_tex->last_level = tex->last_level;
          jit_tex->stride = lp_tex->stride[0];
-         if(!lp_tex->dt) {
-            jit_tex->data = lp_tex->data;
+         if (!lp_tex->dt) {
+            /* regular texture - setup array of mipmap level pointers */
+            int j;
+            for (j = 0; j < LP_MAX_TEXTURE_2D_LEVELS; j++) {
+               jit_tex->data[j] =
+                  (ubyte *) lp_tex->data + lp_tex->level_offset[j];
+            }
          }
          else {
+            /* display target texture/surface */
             /*
              * XXX: Where should this be unmapped?
              */
 
             struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
             struct llvmpipe_winsys *winsys = screen->winsys;
-            jit_tex->data = winsys->displaytarget_map(winsys, lp_tex->dt,
-                                                      PIPE_BUFFER_USAGE_CPU_READ);
-            assert(jit_tex->data);
+            jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
+                                                 PIPE_BUFFER_USAGE_CPU_READ);
+            assert(jit_tex->data[0]);
          }
 
          /* the scene references this texture */
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
index fde2d65..5a3cf37 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
@@ -80,6 +80,9 @@ struct lp_llvm_sampler_soa
 
 /**
  * Fetch the specified member of the lp_jit_texture structure.
+ * \param emit_load  if TRUE, emit the LLVM load instruction to actually
+ *                   fetch the field's value.  Otherwise, just emit the
+ *                   GEP code to address the field.
  *
  * @sa http://llvm.org/docs/GetElementPtr.html
  */
@@ -88,7 +91,8 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
                        LLVMBuilderRef builder,
                        unsigned unit,
                        unsigned member_index,
-                       const char *member_name)
+                       const char *member_name,
+                       boolean emit_load)
 {
    struct llvmpipe_sampler_dynamic_state *state =
       (struct llvmpipe_sampler_dynamic_state *)base;
@@ -109,7 +113,10 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
 
    ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), "");
 
-   res = LLVMBuildLoad(builder, ptr, "");
+   if (emit_load)
+      res = LLVMBuildLoad(builder, ptr, "");
+   else
+      res = ptr;
 
    lp_build_name(res, "context.texture%u.%s", unit, member_name);
 
@@ -126,22 +133,22 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
  * sampler code generator a reusable module without dependencies to
  * llvmpipe internals.
  */
-#define LP_LLVM_TEXTURE_MEMBER(_name, _index) \
+#define LP_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load)  \
    static LLVMValueRef \
    lp_llvm_texture_##_name( struct lp_sampler_dynamic_state *base, \
                             LLVMBuilderRef builder, \
                             unsigned unit) \
    { \
-      return lp_llvm_texture_member(base, builder, unit, _index, #_name ); \
+      return lp_llvm_texture_member(base, builder, unit, _index, #_name, _emit_load ); \
    }
 
 
-LP_LLVM_TEXTURE_MEMBER(width,      LP_JIT_TEXTURE_WIDTH)
-LP_LLVM_TEXTURE_MEMBER(height,     LP_JIT_TEXTURE_HEIGHT)
-LP_LLVM_TEXTURE_MEMBER(depth,      LP_JIT_TEXTURE_DEPTH)
-LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL)
-LP_LLVM_TEXTURE_MEMBER(stride,     LP_JIT_TEXTURE_STRIDE)
-LP_LLVM_TEXTURE_MEMBER(data_ptr,   LP_JIT_TEXTURE_DATA)
+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(data_ptr,   LP_JIT_TEXTURE_DATA, FALSE)
 
 
 static void



More information about the mesa-commit mailing list