summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau/nouveau_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nouveau/nouveau_buffer.c')
-rw-r--r--src/gallium/drivers/nouveau/nouveau_buffer.c33
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);