llvmpipe: Don't use texture transfer internally.
authorJosé Fonseca <jfonseca@vmware.com>
Sat, 13 Mar 2010 16:04:06 +0000 (16:04 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 13 Mar 2010 16:04:06 +0000 (16:04 +0000)
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
src/gallium/drivers/llvmpipe/lp_scene.c
src/gallium/drivers/llvmpipe/lp_scene.h
src/gallium/drivers/llvmpipe/lp_texture.c
src/gallium/drivers/llvmpipe/lp_texture.h

index dd9a8e8856f20dea6cf6770b08cb90dc46ae4e9a..81ea11a16b6ea6a2a26d69d7ee095679471d34e2 100644 (file)
@@ -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 );
index 505cb21503a34d6874e58f629ca3917463094e38..681ce674d49e1d8ff16d639a9918e9e3e8038b35 100644 (file)
@@ -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 );
 }
index 739ac2290891611d56422759908c12558c725b5f..b602b1e8a05c31569d8c25ddeca0bd8391adcce8 100644 (file)
@@ -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:
     */
index f2c6dbd088ab60488a37a1e0fa76cf4a92b64ec5..f3f0cd7b4726bf6df48d29245819e9887d5fe57a 100644 (file)
@@ -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);
 }
 
 
index 94b667abf31fd51aacaebad643f9a5372caceeec..2350c26e4fccd06bfd442cbffe32eb4dda641a0b 100644 (file)
@@ -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);