summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau/nv50
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nouveau/nv50')
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_compute.c4
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_context.c11
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_context.h5
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_miptree.c7
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_query.c14
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_query_hw.c25
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c8
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_surface.c43
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_transfer.c6
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_vbo.c5
10 files changed, 114 insertions, 14 deletions
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_compute.c b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
index d781f6f..3c174e4 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_compute.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
@@ -249,9 +249,11 @@ nv50_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
struct nv50_program *cp = nv50->compprog;
bool ret;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
ret = !nv50_state_validate_cp(nv50, ~0);
if (ret) {
NOUVEAU_ERR("Failed to launch grid !\n");
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
}
@@ -284,6 +286,8 @@ nv50_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
BEGIN_NV04(push, SUBC_CP(NV50_GRAPH_SERIALIZE), 1);
PUSH_DATA (push, 0);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
+
/* bind a compute shader clobbers fragment shader state */
nv50->dirty_3d |= NV50_NEW_3D_FRAGPROG;
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c
index fc852d7..84b5e3f 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c
@@ -37,7 +37,9 @@ nv50_flush(struct pipe_context *pipe,
if (fence)
nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
+ pipe_mutex_lock(screen->push_mutex);
PUSH_KICK(screen->pushbuf);
+ pipe_mutex_unlock(screen->push_mutex);
nouveau_context_update_frame_stats(nouveau_context(pipe));
}
@@ -47,10 +49,12 @@ nv50_texture_barrier(struct pipe_context *pipe)
{
struct nouveau_pushbuf *push = nv50_context(pipe)->base.pushbuf;
+ pipe_mutex_lock(nouveau_context(pipe)->screen->push_mutex);
BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
PUSH_DATA (push, 0);
BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1);
PUSH_DATA (push, 0x20);
+ pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex);
}
static void
@@ -107,6 +111,7 @@ nv50_emit_string_marker(struct pipe_context *pipe, const char *str, int len)
data_words = string_words;
else
data_words = string_words + !!(len & 3);
+ pipe_mutex_lock(nouveau_context(pipe)->screen->push_mutex);
BEGIN_NI04(push, SUBC_3D(NV04_GRAPH_NOP), data_words);
if (string_words)
PUSH_DATAp(push, str, string_words);
@@ -115,6 +120,7 @@ nv50_emit_string_marker(struct pipe_context *pipe, const char *str, int len)
memcpy(&data, &str[string_words * 4], len & 3);
PUSH_DATA (push, data);
}
+ pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex);
}
void
@@ -291,6 +297,8 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
return NULL;
pipe = &nv50->base.pipe;
+ pipe_mutex_lock(screen->base.push_mutex);
+
if (!nv50_blitctx_create(nv50))
goto out_err;
@@ -384,9 +392,12 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
util_dynarray_init(&nv50->global_residents);
+ pipe_mutex_unlock(screen->base.push_mutex);
+
return pipe;
out_err:
+ pipe_mutex_unlock(screen->base.push_mutex);
if (nv50->bufctx_3d)
nouveau_bufctx_del(&nv50->bufctx_3d);
if (nv50->bufctx_cp)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h
index cca44f5..4c8a4e5 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h
@@ -222,6 +222,11 @@ void nv50_default_kick_notify(struct nouveau_pushbuf *);
/* nv50_draw.c */
extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *);
+/* nv50_query.c */
+void nv50_render_condition(struct pipe_context *pipe,
+ struct pipe_query *pq,
+ boolean condition, uint mode);
+
/* nv50_shader_state.c */
void nv50_vertprog_validate(struct nv50_context *);
void nv50_gmtyprog_validate(struct nv50_context *);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
index f2e304f..7f281f9 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
@@ -163,10 +163,13 @@ nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
{
struct nv50_miptree *mt = nv50_miptree(pt);
- if (mt->base.fence && mt->base.fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
+ if (mt->base.fence && mt->base.fence->state < NOUVEAU_FENCE_STATE_FLUSHED) {
+ pipe_mutex_lock(nouveau_screen(pscreen)->push_mutex);
nouveau_fence_work(mt->base.fence, nouveau_fence_unref_bo, mt->base.bo);
- else
+ pipe_mutex_unlock(nouveau_screen(pscreen)->push_mutex);
+ } else {
nouveau_bo_ref(NULL, &mt->base.bo);
+ }
nouveau_fence_ref(NULL, &mt->base.fence);
nouveau_fence_ref(NULL, &mt->base.fence_wr);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query.c b/src/gallium/drivers/nouveau/nv50/nv50_query.c
index 9a1397a..c90e20e 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query.c
@@ -70,7 +70,7 @@ nv50_get_query_result(struct pipe_context *pipe, struct pipe_query *pq,
return q->funcs->get_query_result(nv50_context(pipe), q, wait, result);
}
-static void
+void
nv50_render_condition(struct pipe_context *pipe,
struct pipe_query *pq,
boolean condition, uint mode)
@@ -145,6 +145,16 @@ nv50_render_condition(struct pipe_context *pipe,
}
static void
+nv50_render_condition_locked(struct pipe_context *pipe,
+ struct pipe_query *pq,
+ boolean condition, uint mode)
+{
+ pipe_mutex_lock(nouveau_context(pipe)->screen->push_mutex);
+ nv50_render_condition(pipe, pq, condition, mode);
+ pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex);
+}
+
+static void
nv50_set_active_query_state(struct pipe_context *pipe, boolean enable)
{
}
@@ -160,7 +170,7 @@ nv50_init_query_functions(struct nv50_context *nv50)
pipe->end_query = nv50_end_query;
pipe->get_query_result = nv50_get_query_result;
pipe->set_active_query_state = nv50_set_active_query_state;
- pipe->render_condition = nv50_render_condition;
+ pipe->render_condition = nv50_render_condition_locked;
nv50->cond_condmode = NV50_3D_COND_MODE_ALWAYS;
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
index 727b509..d2ad72e 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
@@ -56,9 +56,12 @@ nv50_hw_query_allocate(struct nv50_context *nv50, struct nv50_query *q,
if (hq->mm) {
if (hq->state == NV50_HW_QUERY_STATE_READY)
nouveau_mm_free(hq->mm);
- else
+ else {
+ pipe_mutex_lock(screen->base.push_mutex);
nouveau_fence_work(screen->base.fence.current,
nouveau_mm_free_work, hq->mm);
+ pipe_mutex_unlock(screen->base.push_mutex);
+ }
}
}
if (size) {
@@ -129,6 +132,7 @@ nv50_hw_begin_query(struct nv50_context *nv50, struct nv50_query *q)
{
struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_hw_query *hq = nv50_hw_query(q);
+ bool ret = true;
if (hq->funcs && hq->funcs->begin_query)
return hq->funcs->begin_query(nv50, hq);
@@ -154,6 +158,7 @@ nv50_hw_begin_query(struct nv50_context *nv50, struct nv50_query *q)
if (!hq->is64bit)
hq->data[0] = hq->sequence++; /* the previously used one */
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
switch (q->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
@@ -193,10 +198,13 @@ nv50_hw_begin_query(struct nv50_context *nv50, struct nv50_query *q)
break;
default:
assert(0);
- return false;
+ ret = false;
+ break;
}
- hq->state = NV50_HW_QUERY_STATE_ACTIVE;
- return true;
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
+ if (ret)
+ hq->state = NV50_HW_QUERY_STATE_ACTIVE;
+ return ret;
}
static void
@@ -212,6 +220,7 @@ nv50_hw_end_query(struct nv50_context *nv50, struct nv50_query *q)
hq->state = NV50_HW_QUERY_STATE_ENDED;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
switch (q->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
@@ -264,6 +273,7 @@ nv50_hw_end_query(struct nv50_context *nv50, struct nv50_query *q)
assert(0);
break;
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
if (hq->is64bit)
nouveau_fence_ref(nv50->screen->base.fence.current, &hq->fence);
}
@@ -286,16 +296,21 @@ nv50_hw_get_query_result(struct nv50_context *nv50, struct nv50_query *q,
nv50_hw_query_update(q);
if (hq->state != NV50_HW_QUERY_STATE_READY) {
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
if (!wait) {
/* for broken apps that spin on GL_QUERY_RESULT_AVAILABLE */
if (hq->state != NV50_HW_QUERY_STATE_FLUSHED) {
hq->state = NV50_HW_QUERY_STATE_FLUSHED;
PUSH_KICK(nv50->base.pushbuf);
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return false;
}
- if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nv50->screen->base.client))
+ if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nv50->screen->base.client)) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return false;
+ }
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
}
hq->state = NV50_HW_QUERY_STATE_READY;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
index bcfba9f..31445eb 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
@@ -176,6 +176,7 @@ nv50_hw_sm_begin_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
return false;
}
+ pipe_mutex_lock(screen->base.push_mutex);
assert(cfg->num_counters <= 4);
PUSH_SPACE(push, 4 * 4);
@@ -208,6 +209,7 @@ nv50_hw_sm_begin_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
BEGIN_NV04(push, NV50_CP(MP_PM_SET(c)), 1);
PUSH_DATA (push, 0);
}
+ pipe_mutex_unlock(screen->base.push_mutex);
return true;
}
@@ -237,6 +239,7 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
screen->pm.prog = prog;
}
+ pipe_mutex_lock(screen->base.push_mutex);
/* disable all counting */
PUSH_SPACE(push, 8);
for (c = 0; c < 4; c++) {
@@ -260,6 +263,7 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
PUSH_SPACE(push, 2);
BEGIN_NV04(push, SUBC_CP(NV50_GRAPH_SERIALIZE), 1);
PUSH_DATA (push, 0);
+ pipe_mutex_unlock(screen->base.push_mutex);
pipe->bind_compute_state(pipe, screen->pm.prog);
input[0] = hq->bo->offset + hq->base_offset;
@@ -276,6 +280,7 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
nouveau_bufctx_reset(nv50->bufctx_cp, NV50_BIND_CP_QUERY);
+ pipe_mutex_lock(screen->base.push_mutex);
/* re-active other counters */
PUSH_SPACE(push, 8);
mask = 0;
@@ -302,6 +307,7 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
| cfg->ctr[i].unit | cfg->ctr[i].mode);
}
}
+ pipe_mutex_unlock(screen->base.push_mutex);
}
static inline bool
@@ -343,7 +349,9 @@ nv50_hw_sm_get_query_result(struct nv50_context *nv50, struct nv50_hw_query *hq,
cfg = nv50_hw_sm_query_get_cfg(nv50, hq);
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
ret = nv50_hw_sm_query_read_data(count, nv50, wait, hq, cfg, mp_count);
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
if (!ret)
return false;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index a6c0bbc..c0f77dc 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -204,10 +204,13 @@ nv50_resource_copy_region(struct pipe_context *pipe,
bool m2mf;
unsigned dst_layer = dstz, src_layer = src_box->z;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
nouveau_copy_buffer(&nv50->base,
nv04_resource(dst), dstx,
nv04_resource(src), src_box->x, src_box->width);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
}
@@ -247,6 +250,7 @@ nv50_resource_copy_region(struct pipe_context *pipe,
else
srect.base += src_mt->layer_stride;
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
}
@@ -270,6 +274,7 @@ nv50_resource_copy_region(struct pipe_context *pipe,
break;
}
nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
}
static void
@@ -289,14 +294,18 @@ nv50_clear_render_target(struct pipe_context *pipe,
assert(dst->texture->target != PIPE_BUFFER);
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
PUSH_DATAf(push, color->f[0]);
PUSH_DATAf(push, color->f[1]);
PUSH_DATAf(push, color->f[2]);
PUSH_DATAf(push, color->f[3]);
- if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0))
+ if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0)) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
+ }
PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
@@ -358,6 +367,8 @@ nv50_clear_render_target(struct pipe_context *pipe,
PUSH_DATA (push, nv50->cond_condmode);
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
+
nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR;
}
@@ -382,6 +393,8 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
assert(dst->texture->target != PIPE_BUFFER);
assert(nouveau_bo_memtype(bo)); /* ZETA cannot be linear */
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
if (clear_flags & PIPE_CLEAR_DEPTH) {
BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
PUSH_DATAf(push, depth);
@@ -394,8 +407,10 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
mode |= NV50_3D_CLEAR_BUFFERS_S;
}
- if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0))
+ if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0)) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
+ }
PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
@@ -446,6 +461,8 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
PUSH_DATA (push, nv50->cond_condmode);
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
+
nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR;
}
@@ -534,9 +551,12 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
unsigned i, j, k;
uint32_t mode = 0;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
/* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
- if (!nv50_state_validate_3d(nv50, NV50_NEW_3D_FRAMEBUFFER))
+ if (!nv50_state_validate_3d(nv50, NV50_NEW_3D_FRAMEBUFFER)) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
+ }
/* We have to clear ALL of the layers, not up to the min number of layers
* of any attachment. */
@@ -602,6 +622,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
/* restore the array mode */
BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
PUSH_DATA (push, nv50->rt_array_mode);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
}
static void
@@ -729,14 +750,18 @@ nv50_clear_buffer(struct pipe_context *pipe,
assert(size % data_size == 0);
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
if (offset & 0xff) {
unsigned fixup_size = MIN2(size, align(offset, 0x100) - offset);
assert(fixup_size % data_size == 0);
nv50_clear_buffer_push(pipe, res, offset, fixup_size, data, data_size);
offset += fixup_size;
size -= fixup_size;
- if (!size)
+ if (!size) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
+ }
}
elements = size / data_size;
@@ -752,8 +777,10 @@ nv50_clear_buffer(struct pipe_context *pipe,
PUSH_DATAf(push, color.f[2]);
PUSH_DATAf(push, color.f[3]);
- if (nouveau_pushbuf_space(push, 32, 1, 0))
+ if (nouveau_pushbuf_space(push, 32, 1, 0)) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
+ }
PUSH_REFN(push, buf->bo, buf->domain | NOUVEAU_BO_WR);
@@ -808,6 +835,8 @@ nv50_clear_buffer(struct pipe_context *pipe,
data, data_size);
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
+
nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR;
}
@@ -1724,6 +1753,8 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
info->src.box.height != -info->dst.box.height))
eng3d = true;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
if (nv50->screen->num_occlusion_queries_active) {
BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
PUSH_DATA (push, 0);
@@ -1738,6 +1769,8 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
PUSH_DATA (push, 1);
}
+
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
}
static void
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
index 8209f1f..c751ade 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
@@ -304,6 +304,7 @@ nv50_miptree_transfer_map(struct pipe_context *pctx,
unsigned base = tx->rect[0].base;
unsigned z = tx->rect[0].z;
unsigned i;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
for (i = 0; i < box->depth; ++i) {
nv50_m2mf_transfer_rect(nv50, &tx->rect[1], &tx->rect[0],
tx->nblocksx, tx->nblocksy);
@@ -313,6 +314,9 @@ nv50_miptree_transfer_map(struct pipe_context *pctx,
tx->rect[0].base += mt->layer_stride;
tx->rect[1].base += size;
}
+ /* Kick these reads out so we don't have to reacquire a lock below */
+ PUSH_KICK(nv50->base.pushbuf);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
tx->rect[0].z = z;
tx->rect[0].base = base;
tx->rect[1].base = 0;
@@ -349,6 +353,7 @@ nv50_miptree_transfer_unmap(struct pipe_context *pctx,
unsigned i;
if (tx->base.usage & PIPE_TRANSFER_WRITE) {
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
for (i = 0; i < tx->base.box.depth; ++i) {
nv50_m2mf_transfer_rect(nv50, &tx->rect[0], &tx->rect[1],
tx->nblocksx, tx->nblocksy);
@@ -362,6 +367,7 @@ nv50_miptree_transfer_unmap(struct pipe_context *pctx,
/* Allow the copies above to finish executing before freeing the source */
nouveau_fence_work(nv50->screen->base.fence.current,
nouveau_fence_unref_bo, tx->rect[1].bo);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
} else {
nouveau_bo_ref(NULL, &tx->rect[1].bo);
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index a11cdf8..f73329c 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
@@ -767,6 +767,8 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
bool tex_dirty = false;
int s;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
/* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
nv50->vb_elt_first = info->min_index + info->index_bias;
nv50->vb_elt_limit = info->max_index - info->min_index;
@@ -827,6 +829,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv50_push_vbo(nv50, info);
push->kick_notify = nv50_default_kick_notify;
nouveau_pushbuf_bufctx(push, NULL);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
}
@@ -886,4 +889,6 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv50_release_user_vbufs(nv50);
nouveau_pushbuf_bufctx(push, NULL);
+
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
}