Hi all

Short and simple patch series attached.

Some drivers can treat one shot resources differently then resources
that are expected to be used several times. Add a usage flag to allow
the state tracker to mark such resources.

The motivation behind this is to identify the glBitmap cache textures
so that the i915g driver can make them not tiled and upload the texture
data with pwrites, which is faster then mapping them via the GTT which is
needed when they tiled.

Comments please?

Cheers Jakob.
From fd9f00bcdab78d8cf4db7c4eb15a522a34587aed Mon Sep 17 00:00:00 2001
From: Jakob Bornecrantz <wallbra...@gmail.com>
Date: Fri, 25 Feb 2011 21:34:26 +0100
Subject: [PATCH 1/3] gallium: Add usage for resources that have a short life cycle

Some drivers can treat one shot resources differently then resources
that are expected to be used several times. Add a usage flag to allow
the state tracker to mark such resources.
---
 src/gallium/include/pipe/p_defines.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 81da4b8..83bb4a3 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -335,6 +335,7 @@ enum pipe_transfer_usage {
 #define PIPE_USAGE_IMMUTABLE      3 /* no change after first upload */
 #define PIPE_USAGE_STREAM         4 /* upload, draw, upload, draw */
 #define PIPE_USAGE_STAGING        5 /* supports data transfers from the GPU to the CPU */
+#define PIPE_USAGE_ONCE           6 /* upload, draw, free */
 
 
 /* These are intended to be used in calls to is_format_supported, but
-- 
1.7.1

From f50f8827fa66e931680cf72d9bc498df0d551e82 Mon Sep 17 00:00:00 2001
From: Jakob Bornecrantz <wallbra...@gmail.com>
Date: Fri, 25 Feb 2011 21:36:49 +0100
Subject: [PATCH 2/3] st/mesa: Route texture usage from bitmap down into the driver

Use the new USAGE_ONCE flag to tell the driver its a once shot resource.
---
 src/mesa/state_tracker/st_atom_pixeltransfer.c |    3 ++-
 src/mesa/state_tracker/st_cb_bitmap.c          |   14 +++++++++-----
 src/mesa/state_tracker/st_cb_drawpixels.c      |    3 ++-
 src/mesa/state_tracker/st_cb_texture.c         |    6 ++++--
 src/mesa/state_tracker/st_gen_mipmap.c         |    3 ++-
 src/mesa/state_tracker/st_texture.c            |    5 +++--
 src/mesa/state_tracker/st_texture.h            |    3 ++-
 7 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c
index 739a2ea..f925b77 100644
--- a/src/mesa/state_tracker/st_atom_pixeltransfer.c
+++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c
@@ -99,7 +99,8 @@ create_color_map_texture(struct gl_context *ctx)
 
    /* create texture for color map/table */
    pt = st_texture_create(st, PIPE_TEXTURE_2D, format, 0,
-                          texSize, texSize, 1, 1, PIPE_BIND_SAMPLER_VIEW);
+                          texSize, texSize, 1, 1,
+                          PIPE_BIND_SAMPLER_VIEW, PIPE_USAGE_DEFAULT);
    return pt;
 }
 
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 149f1ca..3cdf44d 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -276,9 +276,11 @@ make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height,
    /**
     * Create texture to hold bitmap pattern.
     */
-   pt = st_texture_create(st, st->internal_target, st->bitmap.tex_format,
-                          0, width, height, 1, 1,
-                          PIPE_BIND_SAMPLER_VIEW);
+   pt = st_texture_create(st, st->internal_target,
+                          st->bitmap.tex_format, 0,
+                          width, height, 1, 1,
+                          PIPE_BIND_SAMPLER_VIEW,
+                          PIPE_USAGE_ONCE);
    if (!pt) {
       _mesa_unmap_pbo_source(ctx, unpack);
       return NULL;
@@ -562,9 +564,11 @@ reset_cache(struct st_context *st)
    /* allocate a new texture */
    cache->texture = st_texture_create(st, PIPE_TEXTURE_2D,
                                       st->bitmap.tex_format, 0,
-                                      BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
+                                      BITMAP_CACHE_WIDTH,
+                                      BITMAP_CACHE_HEIGHT,
                                       1, 1,
-				      PIPE_BIND_SAMPLER_VIEW);
+                                      PIPE_BIND_SAMPLER_VIEW,
+                                      PIPE_USAGE_ONCE);
 }
 
 
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index c2b4e18..5905b3a 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -344,7 +344,8 @@ alloc_texture(struct st_context *st, GLsizei width, GLsizei height,
    struct pipe_resource *pt;
 
    pt = st_texture_create(st, st->internal_target, texFormat, 0,
-                          width, height, 1, 1, PIPE_BIND_SAMPLER_VIEW);
+                          width, height, 1, 1,
+                          PIPE_BIND_SAMPLER_VIEW, PIPE_USAGE_ONCE);
 
    return pt;
 }
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 3f98ffd..1c04b3f 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -398,7 +398,8 @@ guess_and_alloc_texture(struct st_context *st,
                                  ptHeight,
                                  ptDepth,
                                  ptLayers,
-                                 bindings);
+                                 bindings,
+                                 PIPE_USAGE_DEFAULT);
 
    DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));
 
@@ -1819,7 +1820,8 @@ st_finalize_texture(struct gl_context *ctx,
                                     ptHeight,
                                     ptDepth,
                                     ptLayers,
-                                    bindings);
+                                    bindings,
+                                    PIPE_USAGE_DEFAULT);
 
       if (!stObj->pt) {
          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c
index a12a32e..d6a4b0a 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -387,7 +387,8 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
                                     oldTex->height0,
                                     oldTex->depth0,
                                     oldTex->array_size,
-                                    oldTex->bind);
+                                    oldTex->bind,
+                                    PIPE_USAGE_DEFAULT);
 
       /* This will copy the old texture's base image into the new texture
        * which we just allocated.
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index 1e0a832..46a299e 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -60,7 +60,8 @@ st_texture_create(struct st_context *st,
 		  GLuint height0,
 		  GLuint depth0,
                   GLuint layers,
-                  GLuint bind )
+                  GLuint bind,
+                  GLuint usage)
 {
    struct pipe_resource pt, *newtex;
    struct pipe_screen *screen = st->pipe->screen;
@@ -88,7 +89,7 @@ st_texture_create(struct st_context *st,
    pt.height0 = height0;
    pt.depth0 = depth0;
    pt.array_size = (target == PIPE_TEXTURE_CUBE ? 6 : layers);
-   pt.usage = PIPE_USAGE_DEFAULT;
+   pt.usage = usage;
    pt.bind = bind;
    pt.flags = 0;
 
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index d50c3c9..63e02cf 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -172,7 +172,8 @@ st_texture_create(struct st_context *st,
                   GLuint height0,
                   GLuint depth0,
                   GLuint layers,
-                  GLuint tex_usage );
+                  GLuint bind,
+                  GLuint usage);
 
 
 extern void
-- 
1.7.1

From 2c753fde42643eeaa79f64d6ebaac985040efa2a Mon Sep 17 00:00:00 2001
From: Jakob Bornecrantz <wallbra...@gmail.com>
Date: Fri, 25 Feb 2011 21:48:46 +0100
Subject: [PATCH 3/3] i915g: Don't use tiling and upload via buffer write for usage once textures

---
 src/gallium/drivers/i915/i915_resource_texture.c |   65 +++++++++++++++++++++-
 1 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c
index aad5235..400a72a 100644
--- a/src/gallium/drivers/i915/i915_resource_texture.c
+++ b/src/gallium/drivers/i915/i915_resource_texture.c
@@ -726,7 +726,10 @@ i915_texture_get_transfer(struct pipe_context *pipe,
    transfer->usage = usage;
    transfer->box = *box;
    transfer->stride = tex->stride;
-   /* FIXME: layer_stride */
+
+   /* Need to zero these */
+   transfer->layer_stride = 0;
+   transfer->data = NULL;
 
    return transfer;
 }
@@ -754,6 +757,27 @@ i915_texture_transfer_map(struct pipe_context *pipe,
    if (resource->target != PIPE_TEXTURE_3D &&
        resource->target != PIPE_TEXTURE_CUBE)
       assert(box->z == 0);
+
+   if (resource->target == PIPE_TEXTURE_2D &&
+       resource->usage == PIPE_USAGE_ONCE &&
+       transfer->usage == PIPE_TRANSFER_WRITE) {
+      size_t size;
+
+      /* We can do the upload in a single write call */
+      if (!resource->last_level &&
+          transfer->box.width == resource->width0) {
+         assert(!transfer->box.x);
+         transfer->stride = tex->stride;
+      } else {
+         transfer->stride = util_format_get_stride(format, transfer->box.width);
+      }
+
+      size = util_format_get_2d_size(format, transfer->stride,
+                                     transfer->box.height);
+      transfer->data = MALLOC(size);
+      return transfer->data;
+   }
+
    offset = i915_texture_offset(tex, transfer->level, box->z);
 
    map = iws->buffer_map(iws, tex->buffer,
@@ -772,7 +796,42 @@ i915_texture_transfer_unmap(struct pipe_context *pipe,
 {
    struct i915_texture *tex = i915_texture(transfer->resource);
    struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws;
-   iws->buffer_unmap(iws, tex->buffer);
+   enum pipe_format format = tex->b.b.format;
+   size_t offset;
+   size_t size;
+
+   if (!transfer->data) {
+      iws->buffer_unmap(iws, tex->buffer);
+      return;
+   }
+
+   offset = i915_texture_offset(tex, transfer->level, transfer->box.z);
+
+   if (!tex->b.b.last_level &&
+       tex->b.b.width0 == transfer->box.width) {
+      unsigned nby = util_format_get_nblocksy(format, transfer->box.y);
+      assert(!offset); 
+      assert(!transfer->box.x);
+      assert(tex->stride == transfer->stride);
+
+      offset += tex->stride * nby;
+      size = util_format_get_2d_size(format, transfer->stride,
+                                     transfer->box.height);
+      iws->buffer_write(iws, tex->buffer, offset, size, transfer->data);
+
+   } else {
+      unsigned nby = util_format_get_nblocksy(format, transfer->box.y);
+      int i;
+      offset += util_format_get_stride(format, transfer->box.x);
+      size = transfer->stride;
+
+      for (i = 0; i < nby; i++) {
+         iws->buffer_write(iws, tex->buffer, offset, size, transfer->data);
+         offset += tex->stride;
+      }
+   }
+   FREE(transfer->data);
+   transfer->data = NULL;
 }
 
 
@@ -811,6 +870,8 @@ i915_texture_create(struct pipe_screen *screen,
    tex->b.b.screen = screen;
 
    tex->tiling = i915_texture_tiling(is, tex);
+   if (template->usage == PIPE_USAGE_ONCE)
+      tex->tiling = I915_TILE_NONE;
 
    if (is->is_i945) {
       if (!i945_texture_layout(tex))
-- 
1.7.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to