Mesa (master): llvmpipe: Cleanup/improve llvmpipe_flush_resource usage.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Sun Apr 25 22:41:54 UTC 2010


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

Author: José Fonseca <jfonseca at vmware.com>
Date:   Sun Apr 25 16:59:09 2010 +0100

llvmpipe: Cleanup/improve llvmpipe_flush_resource usage.

Recognize PIPE_TRANSFER_UNSYNCHRONIZED and PIPE_TRANSFER_DONTBLOCK.

---

 src/gallium/drivers/llvmpipe/lp_flush.c   |   11 ++++++---
 src/gallium/drivers/llvmpipe/lp_flush.h   |   19 ++++++++-------
 src/gallium/drivers/llvmpipe/lp_surface.c |   20 ++++++++--------
 src/gallium/drivers/llvmpipe/lp_texture.c |   34 +++++++++++++++++-----------
 4 files changed, 48 insertions(+), 36 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
index 1534913..470132d 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.c
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -96,6 +96,9 @@ llvmpipe_flush( struct pipe_context *pipe,
 /**
  * Flush context if necessary.
  *
+ * Returns FALSE if it would have block, but do_not_block was set, TRUE
+ * otherwise.
+ *
  * TODO: move this logic to an auxiliary library?
  */
 boolean
@@ -106,7 +109,7 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
                         unsigned flush_flags,
                         boolean read_only,
                         boolean cpu_access,
-                        boolean do_not_flush)
+                        boolean do_not_block)
 {
    unsigned referenced;
 
@@ -115,9 +118,6 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
    if ((referenced & PIPE_REFERENCED_FOR_WRITE) ||
        ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) {
 
-      if (do_not_flush)
-         return FALSE;
-
       /*
        * TODO: The semantics of these flush flags are too obtuse. They should
        * disappear and the pipe driver should just ensure that all visible
@@ -136,6 +136,9 @@ llvmpipe_flush_resource(struct pipe_context *pipe,
 
          struct pipe_fence_handle *fence = NULL;
 
+         if (do_not_block)
+            return FALSE;
+
          pipe->flush(pipe, flush_flags, &fence);
 
          if (fence) {
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.h b/src/gallium/drivers/llvmpipe/lp_flush.h
index e516cee..1b38820 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.h
+++ b/src/gallium/drivers/llvmpipe/lp_flush.h
@@ -33,17 +33,18 @@
 struct pipe_context;
 struct pipe_fence_handle;
 
-void llvmpipe_flush(struct pipe_context *pipe, unsigned flags,
-                    struct pipe_fence_handle **fence);
+void
+llvmpipe_flush(struct pipe_context *pipe, unsigned flags,
+               struct pipe_fence_handle **fence);
 
 boolean
 llvmpipe_flush_resource(struct pipe_context *pipe,
-                       struct pipe_resource *texture,
-                       unsigned face,
-                       unsigned level,
-                       unsigned flush_flags,
-                       boolean read_only,
-                       boolean cpu_access,
-                       boolean do_not_flush);
+                        struct pipe_resource *texture,
+                        unsigned face,
+                        unsigned level,
+                        unsigned flush_flags,
+                        boolean read_only,
+                        boolean cpu_access,
+                        boolean do_not_block);
 
 #endif
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index 4934055..1432782 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -60,18 +60,18 @@ lp_surface_copy(struct pipe_context *pipe,
    const enum pipe_format format = src_tex->base.format;
 
    llvmpipe_flush_resource(pipe,
-                          dst->texture, dst->face, dst->level,
-                          0, /* flush_flags */
-                          FALSE, /* read_only */
-                          FALSE, /* cpu_access */
-                          FALSE); /* do_not_flush */
+                           dst->texture, dst->face, dst->level,
+                           0, /* flush_flags */
+                           FALSE, /* read_only */
+                           FALSE, /* cpu_access */
+                           FALSE); /* do_not_block */
 
    llvmpipe_flush_resource(pipe,
-                          src->texture, src->face, src->level,
-                          0, /* flush_flags */
-                          TRUE, /* read_only */
-                          FALSE, /* cpu_access */
-                          FALSE); /* do_not_flush */
+                           src->texture, src->face, src->level,
+                           0, /* flush_flags */
+                           TRUE, /* read_only */
+                           FALSE, /* cpu_access */
+                           FALSE); /* do_not_block */
 
    /*
    printf("surface copy from %u to %u: %u,%u to %u,%u %u x %u\n",
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index e1aed7f..29bdfe3 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -492,6 +492,27 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
    assert(resource);
    assert(sr.level <= resource->last_level);
 
+   /*
+    * Transfers, like other pipe operations, must happen in order, so flush the
+    * context if necessary.
+    */
+   if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
+      boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
+      boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
+      if (!llvmpipe_flush_resource(pipe, resource,
+                                   sr.face, sr.level,
+                                   0, /* flush_flags */
+                                   read_only,
+                                   TRUE, /* cpu_access */
+                                   do_not_block)) {
+         /*
+          * It would have blocked, but state tracker requested no to.
+          */
+         assert(do_not_block);
+         return NULL;
+      }
+   }
+
    lpr = CALLOC_STRUCT(llvmpipe_transfer);
    if (lpr) {
       struct pipe_transfer *pt = &lpr->base;
@@ -562,19 +583,6 @@ llvmpipe_transfer_map( struct pipe_context *pipe,
    lpr = llvmpipe_resource(transfer->resource);
    format = lpr->base.format;
 
-   /*
-    * Transfers, like other pipe operations, must happen in order, so flush the
-    * context if necessary.
-    */
-   llvmpipe_flush_resource(pipe,
-                          transfer->resource,
-			  transfer->sr.face,
-			  transfer->sr.level,
-                          0, /* flush_flags */
-                          !(transfer->usage & PIPE_TRANSFER_WRITE), /* read_only */
-                          TRUE, /* cpu_access */
-                          FALSE); /* do_not_flush */
-
    map = llvmpipe_resource_map(transfer->resource,
 			       transfer->sr.face,
 			       transfer->sr.level,




More information about the mesa-commit mailing list