From 43b85af56efbe6eb06f4e62d23e9f6f583c5ec2e Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sun, 25 Apr 2010 16:59:09 +0100 Subject: 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 153491378a..470132d49f 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 e516cee378..1b38820b5a 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 4934055bc6..1432782cef 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 e1aed7fdb5..29bdfe36ae 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, -- cgit v1.2.3