summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2010-04-25 16:59:09 +0100
committerJosé Fonseca <[email protected]>2010-04-25 23:41:48 +0100
commit43b85af56efbe6eb06f4e62d23e9f6f583c5ec2e (patch)
treee5d96cc5349ba5efbae081771f000d6c9f6ef5d3
parent8352983e2ab9523345f2b2b3db62db19f01fab62 (diff)
llvmpipe: Cleanup/improve llvmpipe_flush_resource usage.
Recognize PIPE_TRANSFER_UNSYNCHRONIZED and PIPE_TRANSFER_DONTBLOCK.
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.c11
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.h19
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.c20
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c34
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 153491378ae..470132d49fa 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 e516cee3789..1b38820b5a4 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 4934055bc6f..1432782cefa 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 e1aed7fdb5b..29bdfe36ae6 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,