diff options
Diffstat (limited to 'src/gallium/drivers/nouveau/nouveau_buffer.c')
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_buffer.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index 17052b2..7e0906f 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -380,6 +380,7 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe, struct pipe_transfer **ptransfer) { struct nouveau_context *nv = nouveau_context(pipe); + struct nouveau_screen *screen = nv->screen; struct nv04_resource *buf = nv04_resource(resource); struct nouveau_transfer *tx = MALLOC_STRUCT(nouveau_transfer); uint8_t *map; @@ -427,14 +428,19 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe, buf->data = NULL; } nouveau_transfer_staging(nv, tx, false); + pipe_mutex_lock(screen->push_mutex); nouveau_transfer_read(nv, tx); + pipe_mutex_unlock(screen->push_mutex); } else { /* The buffer is currently idle. Create a staging area for writes, * and make sure that the cached data is up-to-date. */ if (usage & PIPE_TRANSFER_WRITE) nouveau_transfer_staging(nv, tx, true); - if (!buf->data) + if (!buf->data) { + pipe_mutex_lock(screen->push_mutex); nouveau_buffer_cache(nv, buf); + pipe_mutex_unlock(screen->push_mutex); + } } } return buf->data ? (buf->data + box->x) : tx->map; @@ -479,7 +485,9 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe, if (unlikely(usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE)) { /* Discarding was not possible, must sync because * subsequent transfers might use UNSYNCHRONIZED. */ + pipe_mutex_lock(screen->push_mutex); nouveau_buffer_sync(nv, buf, usage & PIPE_TRANSFER_READ_WRITE); + pipe_mutex_unlock(screen->push_mutex); } else if (usage & PIPE_TRANSFER_DISCARD_RANGE) { /* The whole range is being discarded, so it doesn't matter what was @@ -488,10 +496,13 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe, map = tx->map; } else if (nouveau_buffer_busy(buf, PIPE_TRANSFER_READ)) { - if (usage & PIPE_TRANSFER_DONTBLOCK) + if (usage & PIPE_TRANSFER_DONTBLOCK) { map = NULL; - else + } else { + pipe_mutex_lock(screen->push_mutex); nouveau_buffer_sync(nv, buf, usage & PIPE_TRANSFER_READ_WRITE); + pipe_mutex_unlock(screen->push_mutex); + } } else { /* It is expected that the returned buffer be a representation of the * data in question, so we must copy it over from the buffer. */ @@ -515,9 +526,13 @@ nouveau_buffer_transfer_flush_region(struct pipe_context *pipe, { struct nouveau_transfer *tx = nouveau_transfer(transfer); struct nv04_resource *buf = nv04_resource(transfer->resource); + struct nouveau_screen *screen = nouveau_context(pipe)->screen; - if (tx->map) + if (tx->map) { + pipe_mutex_lock(screen->push_mutex); nouveau_transfer_write(nouveau_context(pipe), tx, box->x, box->width); + pipe_mutex_unlock(screen->push_mutex); + } util_range_add(&buf->valid_buffer_range, tx->base.box.x + box->x, @@ -537,11 +552,15 @@ nouveau_buffer_transfer_unmap(struct pipe_context *pipe, struct nouveau_context *nv = nouveau_context(pipe); struct nouveau_transfer *tx = nouveau_transfer(transfer); struct nv04_resource *buf = nv04_resource(transfer->resource); + struct nouveau_screen *screen = nouveau_context(pipe)->screen; if (tx->base.usage & PIPE_TRANSFER_WRITE) { if (!(tx->base.usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) { - if (tx->map) + if (tx->map) { + pipe_mutex_lock(screen->push_mutex); nouveau_transfer_write(nv, tx, 0, tx->base.box.width); + pipe_mutex_unlock(screen->push_mutex); + } util_range_add(&buf->valid_buffer_range, tx->base.box.x, tx->base.box.x + tx->base.box.width); |