Mesa (master): llvmpipe: get 3D texture image stride from an array rather than computing it

Brian Paul brianp at kemper.freedesktop.org
Mon Apr 19 23:08:49 UTC 2010


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

Author: Brian Paul <brianp at vmware.com>
Date:   Mon Apr 19 17:05:05 2010 -0600

llvmpipe: get 3D texture image stride from an array rather than computing it

This fixes broken 3D texture indexing when the height of the 3D texture
was less than 64 (the tile size).  It's simpler to pass this as an array
(as we do with the row stride) than to compute it on the fly.

---

 src/gallium/drivers/llvmpipe/lp_jit.c             |    7 ++++++-
 src/gallium/drivers/llvmpipe/lp_jit.h             |    5 ++++-
 src/gallium/drivers/llvmpipe/lp_setup.c           |    6 ++++--
 src/gallium/drivers/llvmpipe/lp_surface.c         |    4 ++--
 src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c |    2 ++
 src/gallium/drivers/llvmpipe/lp_texture.c         |   21 ++++++++++++---------
 src/gallium/drivers/llvmpipe/lp_texture.h         |    6 ++++--
 7 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 7e8a117..8690941 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -51,7 +51,7 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
 
    /* struct lp_jit_texture */
    {
-      LLVMTypeRef elem_types[6];
+      LLVMTypeRef elem_types[LP_JIT_TEXTURE_NUM_FIELDS];
 
       elem_types[LP_JIT_TEXTURE_WIDTH]  = LLVMInt32Type();
       elem_types[LP_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
@@ -59,6 +59,8 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
       elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
       elem_types[LP_JIT_TEXTURE_ROW_STRIDE] =
          LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_LEVELS);
+      elem_types[LP_JIT_TEXTURE_IMG_STRIDE] =
+         LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_LEVELS);
       elem_types[LP_JIT_TEXTURE_DATA] =
          LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
                        LP_MAX_TEXTURE_LEVELS);
@@ -80,6 +82,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride,
                              screen->target, texture_type,
                              LP_JIT_TEXTURE_ROW_STRIDE);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, img_stride,
+                             screen->target, texture_type,
+                             LP_JIT_TEXTURE_IMG_STRIDE);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
                              screen->target, texture_type,
                              LP_JIT_TEXTURE_DATA);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 3790a71..5d0268c 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -52,6 +52,7 @@ struct lp_jit_texture
    uint32_t depth;
    uint32_t last_level;
    uint32_t row_stride[LP_MAX_TEXTURE_LEVELS];
+   uint32_t img_stride[LP_MAX_TEXTURE_LEVELS];
    const void *data[LP_MAX_TEXTURE_LEVELS];
 };
 
@@ -62,7 +63,9 @@ enum {
    LP_JIT_TEXTURE_DEPTH,
    LP_JIT_TEXTURE_LAST_LEVEL,
    LP_JIT_TEXTURE_ROW_STRIDE,
-   LP_JIT_TEXTURE_DATA
+   LP_JIT_TEXTURE_IMG_STRIDE,
+   LP_JIT_TEXTURE_DATA,
+   LP_JIT_TEXTURE_NUM_FIELDS  /* number of fields above */
 };
 
 
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 065b4b6..1bd5f57 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -534,7 +534,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
                   llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ,
                                                  LP_TEX_LAYOUT_LINEAR);
 #endif
-               jit_tex->row_stride[j] = lp_tex->stride[j];
+               jit_tex->row_stride[j] = lp_tex->row_stride[j];
+               jit_tex->img_stride[j] = lp_tex->img_stride[j];
             }
          }
          else {
@@ -547,7 +548,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
             struct sw_winsys *winsys = screen->winsys;
             jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
 							 PIPE_TRANSFER_READ);
-            jit_tex->row_stride[0] = lp_tex->stride[0];
+            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]);
          }
       }
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index 4fee40f..155b7fc 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -135,10 +135,10 @@ lp_surface_copy(struct pipe_context *pipe,
                                               LP_TEX_LAYOUT_LINEAR);
 
       util_copy_rect(dst_linear_ptr, format,
-                     dst_tex->stride[dst->level],
+                     dst_tex->row_stride[dst->level],
                      dstx, dsty,
                      width, height,
-                     src_linear_ptr, src_tex->stride[src->level],
+                     src_linear_ptr, src_tex->row_stride[src->level],
                      srcx, srcy);
    }
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
index 4715cfe..74b7393 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
@@ -148,6 +148,7 @@ 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(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)
 
 
@@ -205,6 +206,7 @@ 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.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;
    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;
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 002669a..45739e9 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -120,9 +120,11 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
        */
       nblocksx = util_format_get_nblocksx(pt->format, align(width, TILE_SIZE));
 
-      lpr->stride[level] =
+      lpr->row_stride[level] =
          align(nblocksx * util_format_get_blocksize(pt->format), 16);
 
+      lpr->img_stride[level] = lpr->row_stride[level] * align(height, TILE_SIZE);
+
       lpr->tiles_per_row[level] = width_t;
       lpr->tiles_per_image[level] = width_t * height_t;
       lpr->num_slices_faces[level] = num_slices;
@@ -155,6 +157,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
    lpr->tiles_per_row[0] = width_t;
    lpr->tiles_per_image[0] = width_t * height_t;
    lpr->num_slices_faces[0] = 1;
+   lpr->img_stride[0] = 0;
 
    lpr->layout[0] = alloc_layout_array(1, width, height);
 
@@ -163,7 +166,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
                                           lpr->base.format,
                                           width, height,
                                           16,
-                                          &lpr->stride[0] );
+                                          &lpr->row_stride[0] );
 
    return lpr->dt != NULL;
 }
@@ -409,7 +412,7 @@ llvmpipe_resource_from_handle(struct pipe_screen *screen,
    lpr->dt = winsys->displaytarget_from_handle(winsys,
                                                template,
                                                whandle,
-                                               &lpr->stride[0]);
+                                               &lpr->row_stride[0]);
    if (!lpr->dt)
       goto fail;
 
@@ -496,7 +499,7 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
       pipe_resource_reference(&pt->resource, resource);
       pt->box = *box;
       pt->sr = sr;
-      pt->stride = lprex->stride[sr.level];
+      pt->stride = lprex->row_stride[sr.level];
       pt->usage = usage;
 
       return pt;
@@ -684,7 +687,7 @@ tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level,
       const enum pipe_format format = lpr->base.format;
       const unsigned nblocksy =
          util_format_get_nblocksy(format, align(height, TILE_SIZE));
-      const unsigned buffer_size = nblocksy * lpr->stride[level];
+      const unsigned buffer_size = nblocksy * lpr->row_stride[level];
       return buffer_size;
    }
 }
@@ -954,14 +957,14 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
                                      x * TILE_SIZE, y * TILE_SIZE,
                                      TILE_SIZE, TILE_SIZE,
                                      lpr->base.format,
-                                     lpr->stride[level]);
+                                     lpr->row_stride[level]);
                }
                else {
                   lp_tiled_to_linear(other_data, target_data,
                                      x * TILE_SIZE, y * TILE_SIZE,
                                      TILE_SIZE, TILE_SIZE,
                                      lpr->base.format,
-                                     lpr->stride[level]);
+                                     lpr->row_stride[level]);
                }
             }
 
@@ -1045,7 +1048,7 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
    if (convert) {
       lp_tiled_to_linear(tiled_img->data, linear_img->data,
                          x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
-                         lpr->stride[level]);
+                         lpr->row_stride[level]);
    }
 
    if (new_layout != cur_layout)
@@ -1094,7 +1097,7 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
    if (convert) {
       lp_linear_to_tiled(linear_img->data, tiled_img->data,
                          x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
-                         lpr->stride[level]);
+                         lpr->row_stride[level]);
    }
 
    if (new_layout != cur_layout)
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
index 57f3e0f..5862f97 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.h
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -92,7 +92,9 @@ struct llvmpipe_resource
    struct pipe_resource base;
 
    /** Row stride in bytes */
-   unsigned stride[LP_MAX_TEXTURE_LEVELS];
+   unsigned row_stride[LP_MAX_TEXTURE_LEVELS];
+   /** Image stride (for cube maps or 3D textures) in bytes */
+   unsigned img_stride[LP_MAX_TEXTURE_LEVELS];
    unsigned tiles_per_row[LP_MAX_TEXTURE_LEVELS];
    unsigned tiles_per_image[LP_MAX_TEXTURE_LEVELS];
    /** Number of 3D slices or cube faces per level */
@@ -164,7 +166,7 @@ llvmpipe_resource_stride(struct pipe_resource *resource,
 {
    struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
    assert(level < LP_MAX_TEXTURE_2D_LEVELS);
-   return lpr->stride[level];
+   return lpr->row_stride[level];
 }
 
 




More information about the mesa-commit mailing list