summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/softpipe/sp_texture.c
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2010-04-25 17:03:48 +0100
committerJosé Fonseca <jfonseca@vmware.com>2010-04-25 23:41:48 +0100
commit53e94bd4adb218c5974c522389c3bcf40f3fa7e8 (patch)
treebc8061898c4f8b0852645124a0c2a6cccdf16880 /src/gallium/drivers/softpipe/sp_texture.c
parent43b85af56efbe6eb06f4e62d23e9f6f583c5ec2e (diff)
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.
Diffstat (limited to 'src/gallium/drivers/softpipe/sp_texture.c')
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 167b6b1161..3533c4fd4f 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -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;