nv50: race free state tracking

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Acked-by: M Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
This commit is contained in:
Karol Herbst 2022-05-15 19:20:40 +02:00 committed by Marge Bot
parent df0a4d02f2
commit a5c5b172fd
10 changed files with 42 additions and 5 deletions

View file

@ -567,10 +567,11 @@ nv50_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
struct nv50_program *cp = nv50->compprog;
bool ret;
simple_mtx_lock(&nv50->screen->state_lock);
ret = !nv50_state_validate_cp(nv50, ~0);
if (ret) {
NOUVEAU_ERR("Failed to launch grid !\n");
return;
goto out;
}
nv50_compute_upload_input(nv50, info->input);
@ -622,4 +623,8 @@ nv50_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
nv50->compute_invocations += info->block[0] * info->block[1] * info->block[2] *
grid[0] * grid[1] * grid[2];
out:
PUSH_KICK(push);
simple_mtx_unlock(&nv50->screen->state_lock);
}

View file

@ -180,11 +180,13 @@ nv50_destroy(struct pipe_context *pipe)
{
struct nv50_context *nv50 = nv50_context(pipe);
simple_mtx_lock(&nv50->screen->state_lock);
if (nv50->screen->cur_ctx == nv50) {
nv50->screen->cur_ctx = NULL;
/* Save off the state in case another context gets created */
nv50->screen->save_state = nv50->state;
}
simple_mtx_unlock(&nv50->screen->state_lock);
if (nv50->base.pipe.stream_uploader)
u_upload_destroy(nv50->base.pipe.stream_uploader);
@ -347,6 +349,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
pipe->get_sample_position = nv50_context_get_sample_position;
pipe->emit_string_marker = nv50_emit_string_marker;
simple_mtx_lock(&screen->state_lock);
if (!screen->cur_ctx) {
/* Restore the last context's state here, normally handled during
* context switch
@ -354,6 +357,8 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
nv50->state = screen->save_state;
screen->cur_ctx = nv50;
}
simple_mtx_unlock(&screen->state_lock);
nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx);
nv50->base.kick_notify = nv50_default_kick_notify;
nv50->base.pushbuf->rsvd_kick = 5;

View file

@ -486,6 +486,7 @@ nv50_program_upload_code(struct nv50_context *nv50, struct nv50_program *prog)
return false;
}
simple_mtx_assert_locked(&nv50->screen->state_lock);
ret = nouveau_heap_alloc(heap, size, prog, &prog->mem);
if (ret) {
/* Out of space: evict everything to compactify the code segment, hoping
@ -545,8 +546,11 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
const struct pipe_shader_state pipe = p->pipe;
const ubyte type = p->type;
if (p->mem)
if (p->mem) {
if (nv50)
simple_mtx_assert_locked(&nv50->screen->state_lock);
nouveau_heap_free(&p->mem);
}
FREE(p->code);

View file

@ -652,6 +652,7 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
nouveau_object_del(&screen->sync);
nouveau_screen_fini(&screen->base);
simple_mtx_destroy(&screen->state_lock);
FREE(screen);
}
@ -1013,6 +1014,7 @@ nv50_screen_create(struct nouveau_device *dev)
pscreen = &screen->base.base;
pscreen->destroy = nv50_screen_destroy;
simple_mtx_init(&screen->state_lock, mtx_plain);
ret = nouveau_screen_init(&screen->base, dev);
if (ret) {
NOUVEAU_ERR("nouveau_screen_init failed: %d\n", ret);

View file

@ -62,6 +62,7 @@ struct nv50_screen {
struct nv50_context *cur_ctx;
struct nv50_graph_state save_state;
simple_mtx_t state_lock;
int num_occlusion_queries_active;

View file

@ -128,6 +128,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
if (prog->mem)
return true;
simple_mtx_assert_locked(&nv50->screen->state_lock);
return nv50_program_upload_code(nv50, prog);
}

View file

@ -774,9 +774,12 @@ nv50_sp_state_create(struct pipe_context *pipe,
static void
nv50_sp_state_delete(struct pipe_context *pipe, void *hwcso)
{
struct nv50_context *nv50 = nv50_context(pipe);
struct nv50_program *prog = (struct nv50_program *)hwcso;
nv50_program_destroy(nv50_context(pipe), prog);
simple_mtx_lock(&nv50->screen->state_lock);
nv50_program_destroy(nv50, prog);
simple_mtx_unlock(&nv50->screen->state_lock);
if (prog->pipe.type == PIPE_SHADER_IR_TGSI)
FREE((void *)prog->pipe.tokens);

View file

@ -450,6 +450,7 @@ nv50_switch_pipe_context(struct nv50_context *ctx_to)
{
struct nv50_context *ctx_from = ctx_to->screen->cur_ctx;
simple_mtx_assert_locked(&ctx_to->screen->state_lock);
if (ctx_from)
ctx_to->state = ctx_from->state;
else
@ -536,6 +537,8 @@ nv50_state_validate(struct nv50_context *nv50, uint32_t mask,
int ret;
unsigned i;
simple_mtx_assert_locked(&nv50->screen->state_lock);
if (nv50->screen->cur_ctx != nv50)
nv50_switch_pipe_context(nv50);

View file

@ -534,9 +534,11 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, const struct pipe_scisso
unsigned i, j, k;
uint32_t mode = 0;
simple_mtx_lock(&nv50->screen->state_lock);
/* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
if (!nv50_state_validate_3d(nv50, NV50_NEW_3D_FRAMEBUFFER))
return;
goto out;
if (scissor_state) {
uint32_t minx = scissor_state->minx;
@ -544,7 +546,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, const struct pipe_scisso
uint32_t miny = scissor_state->miny;
uint32_t maxy = MIN2(fb->height, scissor_state->maxy);
if (maxx <= minx || maxy <= miny)
return;
goto out;
BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
PUSH_DATA (push, minx | (maxx - minx) << 16);
@ -622,6 +624,10 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, const struct pipe_scisso
PUSH_DATA (push, fb->width << 16);
PUSH_DATA (push, fb->height << 16);
}
out:
PUSH_KICK(push);
simple_mtx_unlock(&nv50->screen->state_lock);
}
static void
@ -1773,6 +1779,7 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
info->src.box.height != -info->dst.box.height))
eng3d = true;
simple_mtx_lock(&nv50->screen->state_lock);
if (nv50->screen->num_occlusion_queries_active) {
BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
PUSH_DATA (push, 0);
@ -1787,6 +1794,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);
}
PUSH_KICK(push);
simple_mtx_unlock(&nv50->screen->state_lock);
}
static void

View file

@ -811,6 +811,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
if (unlikely(nv50->num_so_targets && !nv50->gmtyprog))
nv50->state.prim_size = nv50_pipe_prim_to_prim_size[info->mode];
simple_mtx_lock(&nv50->screen->state_lock);
nv50_state_validate_3d(nv50, ~0);
nv50->base.kick_notify = nv50_draw_vbo_kick_notify;
@ -920,6 +921,9 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
}
cleanup:
PUSH_KICK(push);
simple_mtx_unlock(&nv50->screen->state_lock);
nv50->base.kick_notify = nv50_default_kick_notify;
nv50_release_user_vbufs(nv50);