diff options
Diffstat (limited to 'src/gallium/drivers/nouveau/nouveau_buffer.c')
-rw-r--r-- | src/gallium/drivers/nouveau/nouveau_buffer.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index 17052b2..b164953 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -80,6 +80,8 @@ release_allocation(struct nouveau_mm_allocation **mm, inline void nouveau_buffer_release_gpu_storage(struct nv04_resource *buf) { + if (buf->fence) + pipe_mutex_lock(buf->fence->screen->push_mutex); if (buf->fence && buf->fence->state < NOUVEAU_FENCE_STATE_FLUSHED) { nouveau_fence_work(buf->fence, nouveau_fence_unref_bo, buf->bo); buf->bo = NULL; @@ -89,6 +91,8 @@ nouveau_buffer_release_gpu_storage(struct nv04_resource *buf) if (buf->mm) release_allocation(&buf->mm, buf->fence); + if (buf->fence) + pipe_mutex_unlock(buf->fence->screen->push_mutex); if (buf->domain == NOUVEAU_BO_VRAM) NOUVEAU_DRV_STAT_RES(buf, buf_obj_current_bytes_vid, -(uint64_t)buf->base.width0); @@ -380,6 +384,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 +432,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 +489,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 +500,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 +530,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 +556,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); |