Mesa (master): i915g: postpone mipmap/face offset calculation

Jakob Bornecrantz wallbraker at kemper.freedesktop.org
Thu Dec 2 00:36:27 UTC 2010


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

Author: Daniel Vetter <daniel.vetter at ffwll.ch>
Date:   Sat Nov 20 10:00:38 2010 +0100

i915g: postpone mipmap/face offset calculation

libdrm-intel can refuse to tile buffers for various reasons. For
potentially tiled buffers the stride is therefore only known after
the iws->buffer_create_tiled call. Unconditionally rounding up to whatever
tiling requires wastes space, so rework the code to not use tex->stride
in the layout code.

Luckily only the mimap/face offset calculation uses it which can easily
be solved by storing an (x, y) coordinate pair. Furthermore this will
be usefull later for properly supporting rendering into the different
levels of tiled mipmap textures.

v2: switch to nblocks(x|y): More in line with gallium and better
suited for rendering into mipmap textures.

Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
Reviewed-by: Jakob Bornecrantz <wallbraker at gmail.com>
Signed-off-by: Jakob Bornecrantz <wallbraker at gmail.com>

---

 src/gallium/drivers/i915/i915_resource.h         |   10 +++++-
 src/gallium/drivers/i915/i915_resource_texture.c |   42 +++++++++++++---------
 src/gallium/drivers/i915/i915_surface.c          |   18 +++++-----
 3 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/src/gallium/drivers/i915/i915_resource.h b/src/gallium/drivers/i915/i915_resource.h
index 753bd26..578c6bd 100644
--- a/src/gallium/drivers/i915/i915_resource.h
+++ b/src/gallium/drivers/i915/i915_resource.h
@@ -49,6 +49,10 @@ struct i915_buffer {
 #define I915_MAX_TEXTURE_3D_LEVELS  8  /* max 128x128x128 */
 
 
+struct offset_pair {
+	unsigned short nblocksx;
+	unsigned short nblocksy;
+};
 
 struct i915_texture {
    struct u_resource b;
@@ -63,14 +67,18 @@ struct i915_texture {
 
    /* Explicitly store the offset of each image for each cube face or
     * depth value.
+    *
+    * Array [depth] off offsets.
     */
-   unsigned *image_offset[I915_MAX_TEXTURE_2D_LEVELS];   /**< array [depth] of offsets */
+   struct offset_pair *image_offset[I915_MAX_TEXTURE_2D_LEVELS];
 
    /* The data is held here:
     */
    struct i915_winsys_buffer *buffer;
 };
 
+unsigned i915_texture_offset(struct i915_texture *tex,
+	                     unsigned level, unsigned face);
 void i915_init_screen_resource_functions(struct i915_screen *is);
 void i915_init_resource_functions(struct i915_context *i915);
 
diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c
index ae34477..6ff6ac7 100644
--- a/src/gallium/drivers/i915/i915_resource_texture.c
+++ b/src/gallium/drivers/i915/i915_resource_texture.c
@@ -120,25 +120,37 @@ i915_texture_set_level_info(struct i915_texture *tex,
    assert(!tex->image_offset[level]);
 
    tex->nr_images[level] = nr_images;
-   tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
-   tex->image_offset[level][0] = 0;
+   tex->image_offset[level] = MALLOC(nr_images * sizeof(struct offset_pair));
+   tex->image_offset[level][0].nblocksx = 0;
+   tex->image_offset[level][0].nblocksy = 0;
+}
+
+inline unsigned i915_texture_offset(struct i915_texture *tex,
+			            unsigned level, unsigned face)
+{
+	unsigned x, y;
+	x = tex->image_offset[level][face].nblocksx
+               * util_format_get_blocksize(tex->b.b.format);
+	y = tex->image_offset[level][face].nblocksy;
+
+	return y * tex->stride + x;
 }
 
 static void
 i915_texture_set_image_offset(struct i915_texture *tex,
                               unsigned level, unsigned img,
-                              unsigned x, unsigned y)
+                              unsigned nblocksx, unsigned nblocksy)
 {
    /* for the first image and level make sure offset is zero */
-   assert(!(img == 0 && level == 0) || (x == 0 && y == 0));
+   assert(!(img == 0 && level == 0) || (nblocksx == 0 && nblocksy == 0));
    assert(img < tex->nr_images[level]);
 
-   tex->image_offset[level][img] = y * tex->stride + x * util_format_get_blocksize(tex->b.b.format);
+   tex->image_offset[level][img].nblocksx = nblocksx;
+   tex->image_offset[level][img].nblocksy = nblocksy;
 
 #if DEBUG_TEXTURES
-   debug_printf("%s: %p level %u, img %u (%u, %u) %p\n", __FUNCTION__,
-                tex, level, img, x, y,
-                (void*)(uintptr_t)tex->image_offset[level][img]);
+   debug_printf("%s: %p level %u, img %u (%u, %u)\n", __FUNCTION__,
+                tex, level, img, x, y);
 #endif
 }
 
@@ -686,7 +698,6 @@ i915_texture_get_transfer(struct pipe_context *context,
    return transfer;
 }
 
-
 static void *
 i915_texture_transfer_map(struct pipe_context *pipe,
 			  struct pipe_transfer *transfer)
@@ -701,11 +712,11 @@ i915_texture_transfer_map(struct pipe_context *pipe,
    char *map;
 
    if (resource->target == PIPE_TEXTURE_CUBE) {
-      offset = tex->image_offset[sr.level][sr.face];
+      offset = i915_texture_offset(tex, sr.level, sr.face);
    } else if (resource->target == PIPE_TEXTURE_3D) {
-      offset = tex->image_offset[sr.level][box->z];
+      offset = i915_texture_offset(tex, sr.level, box->z);
    } else {
-      offset = tex->image_offset[sr.level][0];
+      offset = i915_texture_offset(tex, sr.level, 0);
       assert(sr.face == 0);
       assert(box->z == 0);
    }
@@ -754,7 +765,6 @@ i915_texture_create(struct pipe_screen *screen,
    struct i915_screen *is = i915_screen(screen);
    struct i915_winsys *iws = is->iws;
    struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
-   size_t tex_size;
    unsigned buf_usage = 0;
 
    if (!tex)
@@ -773,8 +783,6 @@ i915_texture_create(struct pipe_screen *screen,
          goto fail;
    }
 
-   tex_size = tex->stride * tex->total_nblocksy;
-
    /* for scanouts and cursors, cursors arn't scanouts */
 
    /* XXX: use a custom flag for cursors, don't rely on magically
@@ -790,8 +798,8 @@ i915_texture_create(struct pipe_screen *screen,
    if (!tex->buffer)
       goto fail;
 
-   I915_DBG(DBG_TEXTURE, "%s: %p size %u, stride %u, blocks (%u, %u)\n", __func__,
-            tex, (unsigned int)tex_size, tex->stride,
+   I915_DBG(DBG_TEXTURE, "%s: %p stride %u, blocks (%u, %u)\n", __func__,
+            tex, tex->stride,
             tex->stride / util_format_get_blocksize(tex->b.b.format),
             tex->total_nblocksy);
 
diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c
index f40876e..3a7d9ec 100644
--- a/src/gallium/drivers/i915/i915_surface.c
+++ b/src/gallium/drivers/i915/i915_surface.c
@@ -56,24 +56,24 @@ i915_surface_copy(struct pipe_context *pipe,
    unsigned dst_offset, src_offset;  /* in bytes */
 
    if (dst->target == PIPE_TEXTURE_CUBE) {
-      dst_offset = dst_tex->image_offset[subdst.level][subdst.face];
+      dst_offset = i915_texture_offset(dst_tex, subdst.level, subdst.face);
    }
    else if (dst->target == PIPE_TEXTURE_3D) {
-      dst_offset = dst_tex->image_offset[subdst.level][dstz];
+      dst_offset = i915_texture_offset(dst_tex, subdst.level, dstz);
    }
    else {
-      dst_offset = dst_tex->image_offset[subdst.level][0];
+      dst_offset = i915_texture_offset(dst_tex, subdst.level, 0);
       assert(subdst.face == 0);
       assert(dstz == 0);
    }
    if (src->target == PIPE_TEXTURE_CUBE) {
-      src_offset = src_tex->image_offset[subsrc.level][subsrc.face];
+      src_offset = i915_texture_offset(src_tex, subsrc.level, subsrc.face);
    }
    else if (src->target == PIPE_TEXTURE_3D) {
-      src_offset = src_tex->image_offset[subsrc.level][srcz];
+      src_offset = i915_texture_offset(src_tex, subsrc.level, srcz);
    }
    else {
-      src_offset = src_tex->image_offset[subsrc.level][0];
+      src_offset = i915_texture_offset(src_tex, subsrc.level, 0);
       assert(subsrc.face == 0);
       assert(srcz == 0);
    }
@@ -173,13 +173,13 @@ i915_get_tex_surface(struct pipe_screen *screen,
    unsigned offset;  /* in bytes */
 
    if (pt->target == PIPE_TEXTURE_CUBE) {
-      offset = tex->image_offset[level][face];
+      offset = i915_texture_offset(tex, level, face);
    }
    else if (pt->target == PIPE_TEXTURE_3D) {
-      offset = tex->image_offset[level][zslice];
+      offset = i915_texture_offset(tex, level, zslice);
    }
    else {
-      offset = tex->image_offset[level][0];
+      offset = i915_texture_offset(tex, level, 0);
       assert(face == 0);
       assert(zslice == 0);
    }




More information about the mesa-commit mailing list