softpipe: Make softpipe transfers in-order.

Transfer, being now a context operation, should happen in order with
all other contexts operations. If there is rendering pending on the
resource then the driver must flush and potentially wait itself
internally.

Instead of avoiding using transfers internally (as done in llvmpipe) I've
opted to simply pass PIPE_TRANSFER_UNSYNCHRONIZED in all internal
transfers, to avoid infinite recursion.
This commit is contained in:
José Fonseca
2010-04-25 17:03:48 +01:00
parent 43b85af56e
commit 53e94bd4ad
5 changed files with 109 additions and 4 deletions

View File

@@ -39,6 +39,7 @@
#include "util/u_transfer.h"
#include "sp_context.h"
#include "sp_flush.h"
#include "sp_texture.h"
#include "sp_screen.h"
@@ -301,6 +302,27 @@ softpipe_get_transfer(struct pipe_context *pipe,
assert(box->y + box->height <= u_minify(resource->height0, sr.level));
assert(box->z + box->depth <= u_minify(resource->depth0, sr.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 (!softpipe_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;
}
}
spr = CALLOC_STRUCT(softpipe_transfer);
if (spr) {
struct pipe_transfer *pt = &spr->base;