Mesa (master): llvmpipe: Don't use texture transfer internally.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Sat Mar 13 16:14:34 UTC 2010


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

Author: José Fonseca <jfonseca at vmware.com>
Date:   Sat Mar 13 16:04:06 2010 +0000

llvmpipe: Don't use texture transfer internally.

Now that transfers are context objects their sideeffects must happen in
order when used by the state tracker, but that synchronization must be
bypassed when used inside the driver, or it would cause infinite
recursion.

---

 src/gallium/drivers/llvmpipe/lp_rast.c    |   14 ++-
 src/gallium/drivers/llvmpipe/lp_scene.c   |   70 +++++---------
 src/gallium/drivers/llvmpipe/lp_scene.h   |    2 -
 src/gallium/drivers/llvmpipe/lp_texture.c |  158 +++++++++++++++++-----------
 src/gallium/drivers/llvmpipe/lp_texture.h |   22 ++++
 5 files changed, 150 insertions(+), 116 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index dd9a8e8..81ea11a 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -62,18 +62,20 @@ lp_rast_begin( struct lp_rasterizer *rast,
    rast->state.write_color = write_color;
    
    for (i = 0; i < rast->state.nr_cbufs; i++) {
+      struct pipe_surface *cbuf = scene->fb.cbufs[i];
       rast->cbuf[i].map = scene->cbuf_map[i];
-      rast->cbuf[i].format = scene->cbuf_transfer[i]->texture->format;
-      rast->cbuf[i].width = scene->cbuf_transfer[i]->width;
-      rast->cbuf[i].height = scene->cbuf_transfer[i]->height;
-      rast->cbuf[i].stride = scene->cbuf_transfer[i]->stride;
+      rast->cbuf[i].format = cbuf->texture->format;
+      rast->cbuf[i].width = cbuf->width;
+      rast->cbuf[i].height = cbuf->height;
+      rast->cbuf[i].stride = llvmpipe_texture_stride(cbuf->texture, cbuf->level);
    }
 
    if (write_zstencil) {
+      struct pipe_surface *zsbuf = scene->fb.zsbuf;
       rast->zsbuf.map = scene->zsbuf_map;
-      rast->zsbuf.stride = scene->zsbuf_transfer->stride;
+      rast->zsbuf.stride = llvmpipe_texture_stride(zsbuf->texture, zsbuf->level);
       rast->zsbuf.blocksize = 
-         util_format_get_blocksize(scene->zsbuf_transfer->texture->format);
+         util_format_get_blocksize(zsbuf->texture->format);
    }
 
    lp_scene_bin_iter_begin( scene );
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
index 505cb21..681ce67 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene.c
@@ -397,7 +397,6 @@ end:
 static boolean
 lp_scene_map_buffers( struct lp_scene *scene )
 {
-   struct pipe_context *pipe = scene->pipe;
    struct pipe_surface *cbuf, *zsbuf;
    int i;
 
@@ -409,20 +408,10 @@ lp_scene_map_buffers( struct lp_scene *scene )
    for (i = 0; i < scene->fb.nr_cbufs; i++) {
       cbuf = scene->fb.cbufs[i];
       if (cbuf) {
-	 scene->cbuf_transfer[i] = pipe->get_tex_transfer(pipe,
-                                                          cbuf->texture,
-                                                          cbuf->face,
-                                                          cbuf->level,
-                                                          cbuf->zslice,
-                                                          PIPE_TRANSFER_READ_WRITE,
-                                                          0, 0,
-                                                          cbuf->width, 
-                                                          cbuf->height);
-	 if (!scene->cbuf_transfer[i])
-	    goto fail;
-
-	 scene->cbuf_map[i] = pipe->transfer_map(pipe, 
-                                                 scene->cbuf_transfer[i]);
+	 scene->cbuf_map[i] = llvmpipe_texture_map(cbuf->texture,
+	                                           cbuf->face,
+                                                   cbuf->level,
+                                                   cbuf->zslice);
 	 if (!scene->cbuf_map[i])
 	    goto fail;
       }
@@ -432,20 +421,10 @@ lp_scene_map_buffers( struct lp_scene *scene )
     */
    zsbuf = scene->fb.zsbuf;
    if (zsbuf) {
-      scene->zsbuf_transfer = pipe->get_tex_transfer(pipe,
-                                                       zsbuf->texture,
-                                                       zsbuf->face,
-                                                       zsbuf->level,
-                                                       zsbuf->zslice,
-                                                       PIPE_TRANSFER_READ_WRITE,
-                                                       0, 0,
-                                                       zsbuf->width,
-                                                       zsbuf->height);
-      if (!scene->zsbuf_transfer)
-         goto fail;
-
-      scene->zsbuf_map = pipe->transfer_map(pipe, 
-                                              scene->zsbuf_transfer);
+      scene->zsbuf_map = llvmpipe_texture_map(zsbuf->texture,
+                                              zsbuf->face,
+                                              zsbuf->level,
+                                              zsbuf->zslice);
       if (!scene->zsbuf_map)
 	 goto fail;
    }
@@ -469,28 +448,27 @@ fail:
 static void
 lp_scene_unmap_buffers( struct lp_scene *scene )
 {
-   struct pipe_context *pipe = scene->pipe;
    unsigned i;
 
    for (i = 0; i < scene->fb.nr_cbufs; i++) {
-      if (scene->cbuf_map[i]) 
-	 pipe->transfer_unmap(pipe, scene->cbuf_transfer[i]);
-
-      if (scene->cbuf_transfer[i])
-	 pipe->tex_transfer_destroy(pipe, scene->cbuf_transfer[i]);
-
-      scene->cbuf_transfer[i] = NULL;
-      scene->cbuf_map[i] = NULL;
+      if (scene->cbuf_map[i]) {
+         struct pipe_surface *cbuf = scene->fb.cbufs[i];
+         llvmpipe_texture_unmap(cbuf->texture,
+                                cbuf->face,
+                                cbuf->level,
+                                cbuf->zslice);
+         scene->cbuf_map[i] = NULL;
+      }
    }
 
-   if (scene->zsbuf_map) 
-      pipe->transfer_unmap(pipe, scene->zsbuf_transfer);
-
-   if (scene->zsbuf_transfer)
-      pipe->tex_transfer_destroy(pipe, scene->zsbuf_transfer);
-
-   scene->zsbuf_transfer = NULL;
-   scene->zsbuf_map = NULL;
+   if (scene->zsbuf_map) {
+      struct pipe_surface *zsbuf = scene->fb.zsbuf;
+      llvmpipe_texture_unmap(zsbuf->texture,
+                             zsbuf->face,
+                             zsbuf->level,
+                             zsbuf->zslice);
+      scene->zsbuf_map = NULL;
+   }
 
    util_unreference_framebuffer_state( &scene->fb );
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h
index 739ac22..b602b1e 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.h
+++ b/src/gallium/drivers/llvmpipe/lp_scene.h
@@ -114,8 +114,6 @@ struct texture_ref {
  */
 struct lp_scene {
    struct pipe_context *pipe;
-   struct pipe_transfer *cbuf_transfer[PIPE_MAX_COLOR_BUFS];
-   struct pipe_transfer *zsbuf_transfer;
 
    /* Scene's buffers are mapped at the time the scene is enqueued:
     */
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index f2c6dbd..f3f0cd7 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -40,6 +40,7 @@
 
 #include "lp_context.h"
 #include "lp_screen.h"
+#include "lp_flush.h"
 #include "lp_texture.h"
 #include "lp_tile_size.h"
 #include "state_tracker/sw_winsys.h"
@@ -163,6 +164,92 @@ llvmpipe_texture_destroy(struct pipe_texture *pt)
 }
 
 
+/**
+ * Map a texture. Without any synchronization.
+ */
+void *
+llvmpipe_texture_map(struct pipe_texture *texture,
+                     unsigned face,
+                     unsigned level,
+                     unsigned zslice)
+{
+   struct llvmpipe_texture *lpt = llvmpipe_texture(texture);
+   uint8_t *map;
+
+   if (lpt->dt) {
+      /* display target */
+      struct llvmpipe_screen *screen = llvmpipe_screen(texture->screen);
+      struct sw_winsys *winsys = screen->winsys;
+      const unsigned usage = PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+
+      assert(face == 0);
+      assert(level == 0);
+      assert(zslice == 0);
+
+      /* FIXME: keep map count? */
+      map = winsys->displaytarget_map(winsys, lpt->dt, usage);
+   }
+   else {
+      /* regular texture */
+      unsigned offset;
+      unsigned stride;
+
+      map = lpt->data;
+
+      assert(level < LP_MAX_TEXTURE_2D_LEVELS);
+
+      offset = lpt->level_offset[level];
+      stride = lpt->stride[level];
+
+      /* XXX shouldn't that rather be
+         tex_height = align(u_minify(texture->height0, level), 2)
+         to account for alignment done in llvmpipe_texture_layout ?
+      */
+      if (texture->target == PIPE_TEXTURE_CUBE) {
+         unsigned tex_height = u_minify(texture->height0, level);
+         offset += face *  util_format_get_nblocksy(texture->format, tex_height) * stride;
+      }
+      else if (texture->target == PIPE_TEXTURE_3D) {
+         unsigned tex_height = u_minify(texture->height0, level);
+         offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * stride;
+      }
+      else {
+         assert(face == 0);
+         assert(zslice == 0);
+      }
+
+      map += offset;
+   }
+
+   return map;
+}
+
+
+/**
+ * Unmap a texture. Without any synchronization.
+ */
+void
+llvmpipe_texture_unmap(struct pipe_texture *texture,
+                       unsigned face,
+                       unsigned level,
+                       unsigned zslice)
+{
+   struct llvmpipe_texture *lpt = llvmpipe_texture(texture);
+
+   if (lpt->dt) {
+      /* display target */
+      struct llvmpipe_screen *lp_screen = llvmpipe_screen(texture->screen);
+      struct sw_winsys *winsys = lp_screen->winsys;
+
+      assert(face == 0);
+      assert(level == 0);
+      assert(zslice == 0);
+
+      winsys->displaytarget_unmap(winsys, lpt->dt);
+   }
+}
+
+
 static struct pipe_surface *
 llvmpipe_get_tex_surface(struct pipe_screen *screen,
                          struct pipe_texture *pt,
@@ -181,7 +268,6 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
       ps->format = pt->format;
       ps->width = u_minify(pt->width0, level);
       ps->height = u_minify(pt->height0, level);
-      ps->offset = lpt->level_offset[level];
       ps->usage = usage;
 
       /* Because we are llvmpipe, anything that the state tracker
@@ -207,23 +293,6 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
       ps->face = face;
       ps->level = level;
       ps->zslice = zslice;
-
-      /* XXX shouldn't that rather be
-         tex_height = align(ps->height, 2);
-         to account for alignment done in llvmpipe_texture_layout ?
-      */
-      if (pt->target == PIPE_TEXTURE_CUBE) {
-         unsigned tex_height = ps->height;
-         ps->offset += face * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
-      }
-      else if (pt->target == PIPE_TEXTURE_3D) {
-         unsigned tex_height = ps->height;
-         ps->offset += zslice * util_format_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
-      }
-      else {
-         assert(face == 0);
-         assert(zslice == 0);
-      }
    }
    return ps;
 }
@@ -269,24 +338,6 @@ llvmpipe_get_tex_transfer(struct pipe_context *pipe,
       pt->level = level;
       pt->zslice = zslice;
 
-      lpt->offset = lptex->level_offset[level];
-
-      /* XXX shouldn't that rather be
-         tex_height = align(u_minify(texture->height0, level), 2)
-         to account for alignment done in llvmpipe_texture_layout ?
-      */
-      if (texture->target == PIPE_TEXTURE_CUBE) {
-         unsigned tex_height = u_minify(texture->height0, level);
-         lpt->offset += face *  util_format_get_nblocksy(texture->format, tex_height) * pt->stride;
-      }
-      else if (texture->target == PIPE_TEXTURE_3D) {
-         unsigned tex_height = u_minify(texture->height0, level);
-         lpt->offset += zslice * util_format_get_nblocksy(texture->format, tex_height) * pt->stride;
-      }
-      else {
-         assert(face == 0);
-         assert(zslice == 0);
-      }
       return pt;
    }
    return NULL;
@@ -312,7 +363,7 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
                        struct pipe_transfer *transfer )
 {
    struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
-   ubyte *map, *xfer_map;
+   ubyte *map;
    struct llvmpipe_texture *lpt;
    enum pipe_format format;
 
@@ -320,34 +371,24 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
    lpt = llvmpipe_texture(transfer->texture);
    format = lpt->base.format;
 
-   if (lpt->dt) {
-      /* display target */
-      struct sw_winsys *winsys = screen->winsys;
 
-      map = winsys->displaytarget_map(winsys, lpt->dt,
-                                      pipe_transfer_buffer_flags(transfer));
-      if (map == NULL)
-         return NULL;
-   }
-   else {
-      /* regular texture */
-      map = lpt->data;
-   }
+   map = llvmpipe_texture_map(transfer->texture,
+                              transfer->face, transfer->level, transfer->zslice);
 
    /* May want to different things here depending on read/write nature
     * of the map:
     */
-   if (transfer->texture && (transfer->usage & PIPE_TRANSFER_WRITE)) {
+   if (transfer->usage & PIPE_TRANSFER_WRITE) {
       /* Do something to notify sharing contexts of a texture change.
        */
       screen->timestamp++;
    }
    
-   xfer_map = map + llvmpipe_transfer(transfer)->offset +
+   map +=
       transfer->y / util_format_get_blockheight(format) * transfer->stride +
       transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
-   /*printf("map = %p  xfer map = %p\n", map, xfer_map);*/
-   return xfer_map;
+
+   return map;
 }
 
 
@@ -355,17 +396,10 @@ static void
 llvmpipe_transfer_unmap(struct pipe_context *pipe,
                         struct pipe_transfer *transfer)
 {
-   struct llvmpipe_screen *lp_screen = llvmpipe_screen(pipe->screen);
-   struct llvmpipe_texture *lpt;
-
    assert(transfer->texture);
-   lpt = llvmpipe_texture(transfer->texture);
 
-   if (lpt->dt) {
-      /* display target */
-      struct sw_winsys *winsys = lp_screen->winsys;
-      winsys->displaytarget_unmap(winsys, lpt->dt);
-   }
+   llvmpipe_texture_unmap(transfer->texture,
+                          transfer->face, transfer->level, transfer->zslice);
 }
 
 
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
index 94b667a..2350c26 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.h
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -95,6 +95,28 @@ llvmpipe_transfer(struct pipe_transfer *pt)
 }
 
 
+static INLINE unsigned
+llvmpipe_texture_stride(struct pipe_texture *texture,
+                        unsigned level)
+{
+   struct llvmpipe_texture *lpt = llvmpipe_texture(texture);
+   assert(level < LP_MAX_TEXTURE_2D_LEVELS);
+   return lpt->stride[level];
+}
+
+
+void *
+llvmpipe_texture_map(struct pipe_texture *texture,
+                     unsigned face,
+                     unsigned level,
+                     unsigned zslice);
+
+void
+llvmpipe_texture_unmap(struct pipe_texture *texture,
+                       unsigned face,
+                       unsigned level,
+                       unsigned zslice);
+
 extern void
 llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen);
 




More information about the mesa-commit mailing list