mesa/nouveau-multithreading-fixes.patch

6152 lines
247 KiB
Diff
Raw Normal View History

From 03891efe6d84ccedfab025173b587bc59b487026 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Fri, 7 May 2021 14:48:42 +0200
Subject: [PATCH 01/17] nouveau/buffer: simplify uses of nouveau_fence_work
nouveau_fence_work already checks the state, so we can just call it
directly.
Strictly speaking, this isn't functional equivalent, but practically it
doesn't matter when we get the callback called.
Main reason for doing this is, that this makes locking way easier as we
can simply lock within nouveau_fence_* functions and callers don't have to
take locks themselves.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: M Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nouveau_buffer.c | 8 ++------
src/gallium/drivers/nouveau/nv50/nv50_miptree.c | 6 +-----
2 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index 284525086d0..78f8a9cb5d8 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -91,12 +91,8 @@ nouveau_buffer_release_gpu_storage(struct nv04_resource *buf)
{
assert(!(buf->status & NOUVEAU_BUFFER_STATUS_USER_PTR));
- if (buf->fence && buf->fence->state < NOUVEAU_FENCE_STATE_FLUSHED) {
- nouveau_fence_work(buf->fence, nouveau_fence_unref_bo, buf->bo);
- buf->bo = NULL;
- } else {
- nouveau_bo_ref(NULL, &buf->bo);
- }
+ nouveau_fence_work(buf->fence, nouveau_fence_unref_bo, buf->bo);
+ buf->bo = NULL;
if (buf->mm)
release_allocation(&buf->mm, buf->fence);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
index 8f45d9e659f..4554dbf02d4 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
@@ -163,11 +163,7 @@ 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)
- nouveau_fence_work(mt->base.fence, nouveau_fence_unref_bo, mt->base.bo);
- else
- nouveau_bo_ref(NULL, &mt->base.bo);
-
+ nouveau_fence_work(mt->base.fence, nouveau_fence_unref_bo, mt->base.bo);
nouveau_fence_ref(NULL, &mt->base.fence);
nouveau_fence_ref(NULL, &mt->base.fence_wr);
--
2.37.3
From 7d1872d683a62000dd5e878f14bb3e31c1a49a05 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Fri, 7 May 2021 15:01:18 +0200
Subject: [PATCH 02/17] nouveau/fence: rework nouveau_fence_emit so we can call
it on emitted fences
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nouveau_fence.c | 10 ++++------
src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c | 4 ++--
2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c
index 117bce3b5c8..a0789739fa3 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.c
+++ b/src/gallium/drivers/nouveau/nouveau_fence.c
@@ -60,7 +60,9 @@ nouveau_fence_emit(struct nouveau_fence *fence)
{
struct nouveau_screen *screen = fence->screen;
- assert(fence->state == NOUVEAU_FENCE_STATE_AVAILABLE);
+ assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
+ if (fence->state >= NOUVEAU_FENCE_STATE_EMITTED)
+ return;
/* set this now, so that if fence.emit triggers a flush we don't recurse */
fence->state = NOUVEAU_FENCE_STATE_EMITTING;
@@ -190,11 +192,7 @@ nouveau_fence_kick(struct nouveau_fence *fence)
if (fence->state < NOUVEAU_FENCE_STATE_EMITTED) {
PUSH_SPACE(screen->pushbuf, 8);
- /* The space allocation might trigger a flush, which could emit the
- * current fence. So check again.
- */
- if (fence->state < NOUVEAU_FENCE_STATE_EMITTED)
- nouveau_fence_emit(fence);
+ nouveau_fence_emit(fence);
}
if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
index d2c011fc1da..e1738508798 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
@@ -420,7 +420,7 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0,
/* If the fence guarding this query has not been emitted, that makes a lot
* of the following logic more complicated.
*/
- if (hq->is64bit && hq->fence->state < NOUVEAU_FENCE_STATE_EMITTED)
+ if (hq->is64bit)
nouveau_fence_emit(hq->fence);
/* We either need to compute a 32- or 64-bit difference between 2 values,
@@ -642,7 +642,7 @@ nvc0_hw_query_fifo_wait(struct nvc0_context *nvc0, struct nvc0_query *q)
unsigned offset = hq->offset;
/* ensure the query's fence has been emitted */
- if (hq->is64bit && hq->fence->state < NOUVEAU_FENCE_STATE_EMITTED)
+ if (hq->is64bit)
nouveau_fence_emit(hq->fence);
PUSH_SPACE(push, 5);
--
2.37.3
From 05bfbdba563e3436100d7bf1cb7e360f7c7632b4 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Thu, 10 Jun 2021 16:16:24 +0200
Subject: [PATCH 03/17] nouveau: move nouveau_context initialization to common
code
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nouveau_context.h | 2 +-
src/gallium/drivers/nouveau/nouveau_screen.c | 6 +++++-
src/gallium/drivers/nouveau/nv30/nv30_context.c | 14 +++-----------
src/gallium/drivers/nouveau/nv50/nv50_context.c | 5 +----
src/gallium/drivers/nouveau/nvc0/nvc0_context.c | 6 +-----
5 files changed, 11 insertions(+), 22 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h
index 3d4af8d765c..e7941b45ec5 100644
--- a/src/gallium/drivers/nouveau/nouveau_context.h
+++ b/src/gallium/drivers/nouveau/nouveau_context.h
@@ -66,7 +66,7 @@ void
nouveau_context_init_vdec(struct nouveau_context *);
void
-nouveau_context_init(struct nouveau_context *);
+nouveau_context_init(struct nouveau_context *, struct nouveau_screen *);
void
nouveau_scratch_runout_release(struct nouveau_context *);
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 7312a5b1f98..ac69b9d3968 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -393,7 +393,11 @@ nouveau_set_debug_callback(struct pipe_context *pipe,
}
void
-nouveau_context_init(struct nouveau_context *context)
+nouveau_context_init(struct nouveau_context *context, struct nouveau_screen *screen)
{
context->pipe.set_debug_callback = nouveau_set_debug_callback;
+
+ context->screen = screen;
+ context->client = screen->client;
+ context->pushbuf = screen->pushbuf;
}
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_context.c b/src/gallium/drivers/nouveau/nv30/nv30_context.c
index 83c3c6fd82d..4ce28864b8d 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_context.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_context.c
@@ -191,7 +191,6 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
{
struct nv30_screen *screen = nv30_screen(pscreen);
struct nv30_context *nv30 = CALLOC_STRUCT(nv30_context);
- struct nouveau_pushbuf *push;
struct pipe_context *pipe;
int ret;
@@ -199,7 +198,6 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
return NULL;
nv30->screen = screen;
- nv30->base.screen = &screen->base;
nv30->base.copy_data = nv30_transfer_copy_data;
pipe = &nv30->base.pipe;
@@ -208,6 +206,9 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
pipe->destroy = nv30_context_destroy;
pipe->flush = nv30_context_flush;
+ nouveau_context_init(&nv30->base, &screen->base);
+ nv30->base.pushbuf->kick_notify = nv30_context_kick_notify;
+
nv30->base.pipe.stream_uploader = u_upload_create_default(&nv30->base.pipe);
if (!nv30->base.pipe.stream_uploader) {
nv30_context_destroy(pipe);
@@ -215,14 +216,6 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
}
nv30->base.pipe.const_uploader = nv30->base.pipe.stream_uploader;
- /*XXX: *cough* per-context client */
- nv30->base.client = screen->base.client;
-
- /*XXX: *cough* per-context pushbufs */
- push = screen->base.pushbuf;
- nv30->base.pushbuf = push;
- push->kick_notify = nv30_context_kick_notify;
-
nv30->base.invalidate_resource_storage = nv30_invalidate_resource_storage;
ret = nouveau_bufctx_new(nv30->base.client, 64, &nv30->bufctx);
@@ -244,7 +237,6 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
if (debug_get_bool_option("NV30_SWTNL", false))
nv30->draw_flags |= NV30_NEW_SWTNL;
- nouveau_context_init(&nv30->base);
nv30->sample_mask = 0xffff;
nv30_vbo_init(pipe);
nv30_query_init(pipe);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c
index c6ba3d4df9c..6b7b6889d38 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c
@@ -313,8 +313,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
if (!nv50_blitctx_create(nv50))
goto out_err;
- nv50->base.pushbuf = screen->base.pushbuf;
- nv50->base.client = screen->base.client;
+ nouveau_context_init(&nv50->base, &screen->base);
ret = nouveau_bufctx_new(nv50->base.client, 2, &nv50->bufctx);
if (!ret)
@@ -326,7 +325,6 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
if (ret)
goto out_err;
- nv50->base.screen = &screen->base;
nv50->base.copy_data = nv50_m2mf_copy_linear;
nv50->base.push_data = nv50_sifc_linear_u8;
nv50->base.push_cb = nv50_cb_push;
@@ -361,7 +359,6 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
}
nv50->base.pushbuf->kick_notify = nv50_default_kick_notify;
- nouveau_context_init(&nv50->base);
nv50_init_query_functions(nv50);
nv50_init_surface_functions(nv50);
nv50_init_state_functions(nv50);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
index 546c92361c2..c21c5e130b8 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
@@ -425,8 +425,7 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
if (!nvc0_blitctx_create(nvc0))
goto out_err;
- nvc0->base.pushbuf = screen->base.pushbuf;
- nvc0->base.client = screen->base.client;
+ nouveau_context_init(&nvc0->base, &screen->base);
ret = nouveau_bufctx_new(nvc0->base.client, 2, &nvc0->bufctx);
if (!ret)
@@ -439,8 +438,6 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
goto out_err;
nvc0->screen = screen;
- nvc0->base.screen = &screen->base;
-
pipe->screen = pscreen;
pipe->priv = priv;
pipe->stream_uploader = u_upload_create_default(pipe);
@@ -464,7 +461,6 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
pipe->emit_string_marker = nvc0_emit_string_marker;
pipe->get_device_reset_status = nvc0_get_device_reset_status;
- nouveau_context_init(&nvc0->base);
nvc0_init_query_functions(nvc0);
nvc0_init_surface_functions(nvc0);
nvc0_init_state_functions(nvc0);
--
2.37.3
From bc4f80ef83e333b203ba37bff63474091dc6b6de Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Fri, 25 Jun 2021 22:44:26 +0200
Subject: [PATCH 04/17] nouveau: wrap nouveau_bo_map
This makes it easier to insert locking code around libdrm.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: M Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nouveau_buffer.c | 22 +++++++++----------
src/gallium/drivers/nouveau/nouveau_video.c | 6 ++---
.../drivers/nouveau/nouveau_vp3_video.c | 4 +++-
src/gallium/drivers/nouveau/nouveau_winsys.h | 7 ++++++
.../drivers/nouveau/nv30/nv30_miptree.c | 2 +-
.../drivers/nouveau/nv30/nv30_screen.c | 2 +-
.../drivers/nouveau/nv30/nv30_transfer.c | 4 ++--
.../drivers/nouveau/nv50/nv50_compute.c | 2 +-
.../drivers/nouveau/nv50/nv50_query_hw.c | 2 +-
.../drivers/nouveau/nv50/nv50_screen.c | 2 +-
.../drivers/nouveau/nv50/nv50_transfer.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv84_video.c | 11 +++++-----
src/gallium/drivers/nouveau/nv50/nv98_video.c | 2 +-
.../drivers/nouveau/nv50/nv98_video_bsp.c | 3 ++-
.../drivers/nouveau/nv50/nv98_video_vp.c | 3 ++-
.../drivers/nouveau/nvc0/nvc0_query_hw.c | 2 +-
.../drivers/nouveau/nvc0/nvc0_screen.c | 2 +-
.../drivers/nouveau/nvc0/nvc0_transfer.c | 4 ++--
src/gallium/drivers/nouveau/nvc0/nvc0_video.c | 2 +-
.../drivers/nouveau/nvc0/nvc0_video_bsp.c | 8 ++++---
.../drivers/nouveau/nvc0/nvc0_video_vp.c | 3 ++-
.../drivers/nouveau/nvc0/nve4_compute.c | 2 +-
22 files changed, 56 insertions(+), 41 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index 78f8a9cb5d8..e566541a579 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -168,7 +168,7 @@ nouveau_transfer_staging(struct nouveau_context *nv,
nouveau_mm_allocate(nv->screen->mm_GART, size, &tx->bo, &tx->offset);
if (tx->bo) {
tx->offset += adj;
- if (!nouveau_bo_map(tx->bo, 0, NULL))
+ if (!BO_MAP(nv->screen, tx->bo, 0, NULL))
tx->map = (uint8_t *)tx->bo->map + tx->offset;
}
}
@@ -471,9 +471,9 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
* wait on the whole slab and instead use the logic below to return a
* reasonable buffer for that case.
*/
- ret = nouveau_bo_map(buf->bo,
- buf->mm ? 0 : nouveau_screen_transfer_flags(usage),
- nv->client);
+ ret = BO_MAP(nv->screen, buf->bo,
+ buf->mm ? 0 : nouveau_screen_transfer_flags(usage),
+ nv->client);
if (ret) {
FREE(tx);
return NULL;
@@ -639,10 +639,10 @@ nouveau_resource_map_offset(struct nouveau_context *nv,
unsigned rw;
rw = (flags & NOUVEAU_BO_WR) ? PIPE_MAP_WRITE : PIPE_MAP_READ;
nouveau_buffer_sync(nv, res, rw);
- if (nouveau_bo_map(res->bo, 0, NULL))
+ if (BO_MAP(nv->screen, res->bo, 0, NULL))
return NULL;
} else {
- if (nouveau_bo_map(res->bo, flags, nv->client))
+ if (BO_MAP(nv->screen, res->bo, flags, nv->client))
return NULL;
}
return (uint8_t *)res->bo->map + res->offset + offset;
@@ -798,7 +798,7 @@ nouveau_buffer_data_fetch(struct nouveau_context *nv, struct nv04_resource *buf,
{
if (!nouveau_buffer_malloc(buf))
return false;
- if (nouveau_bo_map(bo, NOUVEAU_BO_RD, nv->client))
+ if (BO_MAP(nv->screen, bo, NOUVEAU_BO_RD, nv->client))
return false;
memcpy(buf->data, (uint8_t *)bo->map + offset, size);
return true;
@@ -823,7 +823,7 @@ nouveau_buffer_migrate(struct nouveau_context *nv,
if (new_domain == NOUVEAU_BO_GART && old_domain == 0) {
if (!nouveau_buffer_allocate(screen, buf, new_domain))
return false;
- ret = nouveau_bo_map(buf->bo, 0, nv->client);
+ ret = BO_MAP(nv->screen, buf->bo, 0, nv->client);
if (ret)
return ret;
memcpy((uint8_t *)buf->bo->map + buf->offset, buf->data, size);
@@ -893,7 +893,7 @@ nouveau_user_buffer_upload(struct nouveau_context *nv,
if (!nouveau_buffer_reallocate(screen, buf, NOUVEAU_BO_GART))
return false;
- ret = nouveau_bo_map(buf->bo, 0, nv->client);
+ ret = BO_MAP(nv->screen, buf->bo, 0, nv->client);
if (ret)
return false;
memcpy((uint8_t *)buf->bo->map + buf->offset + base, buf->data + base, size);
@@ -989,7 +989,7 @@ nouveau_scratch_runout(struct nouveau_context *nv, unsigned size)
ret = nouveau_scratch_bo_alloc(nv, &nv->scratch.runout->bo[n], size);
if (!ret) {
- ret = nouveau_bo_map(nv->scratch.runout->bo[n], 0, NULL);
+ ret = BO_MAP(nv->screen, nv->scratch.runout->bo[n], 0, NULL);
if (ret)
nouveau_bo_ref(NULL, &nv->scratch.runout->bo[--nv->scratch.runout->nr]);
}
@@ -1027,7 +1027,7 @@ nouveau_scratch_next(struct nouveau_context *nv, unsigned size)
nv->scratch.offset = 0;
nv->scratch.end = nv->scratch.bo_size;
- ret = nouveau_bo_map(bo, NOUVEAU_BO_WR, nv->client);
+ ret = BO_MAP(nv->screen, bo, NOUVEAU_BO_WR, nv->client);
if (!ret)
nv->scratch.map = bo->map;
return !ret;
diff --git a/src/gallium/drivers/nouveau/nouveau_video.c b/src/gallium/drivers/nouveau/nouveau_video.c
index 5c94686625f..787129b376e 100644
--- a/src/gallium/drivers/nouveau/nouveau_video.c
+++ b/src/gallium/drivers/nouveau/nouveau_video.c
@@ -37,12 +37,12 @@ nouveau_vpe_init(struct nouveau_decoder *dec) {
int ret;
if (dec->cmds)
return 0;
- ret = nouveau_bo_map(dec->cmd_bo, NOUVEAU_BO_RDWR, dec->client);
+ ret = BO_MAP(dec->screen, dec->cmd_bo, NOUVEAU_BO_RDWR, dec->client);
if (ret) {
debug_printf("Mapping cmd bo: %s\n", strerror(-ret));
return ret;
}
- ret = nouveau_bo_map(dec->data_bo, NOUVEAU_BO_RDWR, dec->client);
+ ret = BO_MAP(dec->screen, dec->data_bo, NOUVEAU_BO_RDWR, dec->client);
if (ret) {
debug_printf("Mapping data bo: %s\n", strerror(-ret));
return ret;
@@ -582,7 +582,7 @@ nouveau_create_decoder(struct pipe_context *context,
0, 4096, NULL, &dec->fence_bo);
if (ret)
goto fail;
- nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR, NULL);
+ BO_MAP(screen, dec->fence_bo, NOUVEAU_BO_RDWR, NULL);
dec->fence_map = dec->fence_bo->map;
dec->fence_map[0] = 0;
#endif
diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.c b/src/gallium/drivers/nouveau/nouveau_vp3_video.c
index 3b59fd0a513..b3d93a69195 100644
--- a/src/gallium/drivers/nouveau/nouveau_vp3_video.c
+++ b/src/gallium/drivers/nouveau/nouveau_vp3_video.c
@@ -27,6 +27,7 @@
#include <nvif/class.h>
+#include "nouveau_winsys.h"
#include "nouveau_screen.h"
#include "nouveau_context.h"
#include "nouveau_vp3_video.h"
@@ -284,13 +285,14 @@ nouveau_vp3_load_firmware(struct nouveau_vp3_decoder *dec,
char path[PATH_MAX];
ssize_t r;
uint32_t *end, endval;
+ struct nouveau_screen *screen = nouveau_screen(dec->base.context->screen);
if (chipset >= 0xa3 && chipset != 0xaa && chipset != 0xac)
vp4_getpath(profile, path);
else
vp3_getpath(profile, path);
- if (nouveau_bo_map(dec->fw_bo, NOUVEAU_BO_WR, dec->client))
+ if (BO_MAP(screen, dec->fw_bo, NOUVEAU_BO_WR, dec->client))
return 1;
fd = open(path, O_RDONLY | O_CLOEXEC);
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index 94116cccfae..a5fbf7fb8a3 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -9,6 +9,8 @@
#include "drm-uapi/drm.h"
#include <nouveau.h>
+#include "nouveau_screen.h"
+
#ifndef NV04_PFIFO_MAX_PACKET_LEN
#define NV04_PFIFO_MAX_PACKET_LEN 2047
#endif
@@ -66,6 +68,11 @@ PUSH_KICK(struct nouveau_pushbuf *push)
nouveau_pushbuf_kick(push, push->channel);
}
+static inline int
+BO_MAP(struct nouveau_screen *screen, struct nouveau_bo *bo, uint32_t access, struct nouveau_client *client)
+{
+ return nouveau_bo_map(bo, access, client);
+}
#define NOUVEAU_RESOURCE_FLAG_LINEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 0)
#define NOUVEAU_RESOURCE_FLAG_DRV_PRIV (PIPE_RESOURCE_FLAG_DRV_PRIV << 1)
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
index 5d1f16b28c9..ebbe3746717 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
@@ -359,7 +359,7 @@ nv30_miptree_transfer_map(struct pipe_context *pipe, struct pipe_resource *pt,
if (usage & PIPE_MAP_WRITE)
access |= NOUVEAU_BO_WR;
- ret = nouveau_bo_map(tx->tmp.bo, access, nv30->base.client);
+ ret = BO_MAP(nv30->base.screen, tx->tmp.bo, access, nv30->base.client);
if (ret) {
pipe_resource_reference(&tx->base.resource, NULL);
FREE(tx);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
index 615dd23bbd5..b0a08a207d5 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -732,7 +732,7 @@ nv30_screen_create(struct nouveau_device *dev)
ret = nouveau_bo_wrap(screen->base.device, fifo->notify, &screen->notify);
if (ret == 0)
- ret = nouveau_bo_map(screen->notify, 0, screen->base.client);
+ ret = BO_MAP(&screen->base, screen->notify, 0, screen->base.client);
if (ret)
FAIL_SCREEN_INIT("error mapping notifier memory: %d\n", ret);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
index a79fd1f4545..1a5151acb89 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
@@ -635,8 +635,8 @@ nv30_transfer_rect_cpu(XFER_ARGS)
char *srcmap, *dstmap;
int x, y;
- nouveau_bo_map(src->bo, NOUVEAU_BO_RD, nv30->base.client);
- nouveau_bo_map(dst->bo, NOUVEAU_BO_WR, nv30->base.client);
+ BO_MAP(nv30->base.screen, src->bo, NOUVEAU_BO_RD, nv30->base.client);
+ BO_MAP(nv30->base.screen, dst->bo, NOUVEAU_BO_WR, nv30->base.client);
srcmap = src->bo->map + src->offset;
dstmap = dst->bo->map + dst->offset;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_compute.c b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
index 2e728f51662..d75aa0a9cd3 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_compute.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
@@ -540,7 +540,7 @@ nv50_compute_upload_input(struct nv50_context *nv50, const uint32_t *input)
mm = nouveau_mm_allocate(screen->base.mm_GART, size, &bo, &offset);
assert(mm);
- nouveau_bo_map(bo, 0, nv50->base.client);
+ BO_MAP(&screen->base, bo, 0, nv50->base.client);
memcpy(bo->map + offset, input, size);
nouveau_bufctx_refn(nv50->bufctx, 0, bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
index ff7f521df68..4d959426148 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
@@ -63,7 +63,7 @@ nv50_hw_query_allocate(struct nv50_context *nv50, struct nv50_query *q,
return false;
hq->offset = hq->base_offset;
- ret = nouveau_bo_map(hq->bo, 0, nv50->base.client);
+ ret = BO_MAP(&screen->base, hq->bo, 0, nv50->base.client);
if (ret) {
nv50_hw_query_allocate(nv50, q, 0);
return false;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index e54f0919390..eaa2e84e6ad 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -1070,7 +1070,7 @@ nv50_screen_create(struct nouveau_device *dev)
goto fail;
}
- nouveau_bo_map(screen->fence.bo, 0, NULL);
+ BO_MAP(&screen->base, screen->fence.bo, 0, NULL);
screen->fence.map = screen->fence.bo->map;
screen->base.fence.emit = nv50_screen_fence_emit;
screen->base.fence.update = nv50_screen_fence_update;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
index 3ebd5e46809..d84a6763a46 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
@@ -453,7 +453,7 @@ nv50_miptree_transfer_map(struct pipe_context *pctx,
if (usage & PIPE_MAP_WRITE)
flags |= NOUVEAU_BO_WR;
- ret = nouveau_bo_map(tx->rect[1].bo, flags, nv50->base.client);
+ ret = BO_MAP(nv50->base.screen, tx->rect[1].bo, flags, nv50->base.client);
if (ret) {
nouveau_bo_ref(NULL, &tx->rect[1].bo);
FREE(tx);
diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video.c b/src/gallium/drivers/nouveau/nv50/nv84_video.c
index 01ca0479b47..7e6aa8fffb3 100644
--- a/src/gallium/drivers/nouveau/nv50/nv84_video.c
+++ b/src/gallium/drivers/nouveau/nv50/nv84_video.c
@@ -69,6 +69,7 @@ nv84_load_firmwares(struct nouveau_device *dev, struct nv84_decoder *dec,
{
int ret, size1, size2 = 0;
struct nouveau_bo *fw;
+ struct nouveau_screen *screen = nouveau_screen(dec->base.context->screen);
size1 = filesize(fw1);
if (fw2)
@@ -81,7 +82,7 @@ nv84_load_firmwares(struct nouveau_device *dev, struct nv84_decoder *dec,
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, dec->vp_fw2_offset + size2, NULL, &fw);
if (ret)
return NULL;
- ret = nouveau_bo_map(fw, NOUVEAU_BO_WR, dec->client);
+ ret = BO_MAP(screen, fw, NOUVEAU_BO_WR, dec->client);
if (ret)
goto error;
@@ -406,14 +407,14 @@ nv84_create_decoder(struct pipe_context *context,
NULL, &dec->bitstream);
if (ret)
goto fail;
- ret = nouveau_bo_map(dec->bitstream, NOUVEAU_BO_WR, dec->client);
+ ret = BO_MAP(screen, dec->bitstream, NOUVEAU_BO_WR, dec->client);
if (ret)
goto fail;
ret = nouveau_bo_new(screen->device, NOUVEAU_BO_GART,
0, 0x2000, NULL, &dec->vp_params);
if (ret)
goto fail;
- ret = nouveau_bo_map(dec->vp_params, NOUVEAU_BO_WR, dec->client);
+ ret = BO_MAP(screen, dec->vp_params, NOUVEAU_BO_WR, dec->client);
if (ret)
goto fail;
}
@@ -425,7 +426,7 @@ nv84_create_decoder(struct pipe_context *context,
NULL, &dec->mpeg12_bo);
if (ret)
goto fail;
- ret = nouveau_bo_map(dec->mpeg12_bo, NOUVEAU_BO_WR, dec->client);
+ ret = BO_MAP(screen, dec->mpeg12_bo, NOUVEAU_BO_WR, dec->client);
if (ret)
goto fail;
}
@@ -434,7 +435,7 @@ nv84_create_decoder(struct pipe_context *context,
0, 0x1000, NULL, &dec->fence);
if (ret)
goto fail;
- ret = nouveau_bo_map(dec->fence, NOUVEAU_BO_WR, dec->client);
+ ret = BO_MAP(screen, dec->fence, NOUVEAU_BO_WR, dec->client);
if (ret)
goto fail;
*(uint32_t *)dec->fence->map = 0;
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video.c b/src/gallium/drivers/nouveau/nv50/nv98_video.c
index efa73294065..bc56aff2665 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video.c
@@ -269,7 +269,7 @@ nv98_create_decoder(struct pipe_context *context,
if (ret)
goto fail;
- nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR, screen->client);
+ BO_MAP(screen, dec->fence_bo, NOUVEAU_BO_RDWR, screen->client);
dec->fence_map = dec->fence_bo->map;
dec->fence_map[0] = dec->fence_map[4] = dec->fence_map[8] = 0;
dec->comm = (struct comm *)(dec->fence_map + (COMM_OFFSET/sizeof(*dec->fence_map)));
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
index f77258de850..4c3a6172233 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
@@ -39,6 +39,7 @@ nv98_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
unsigned *vp_caps, unsigned *is_ref,
struct nouveau_vp3_video_buffer *refs[16])
{
+ struct nouveau_screen *screen = nouveau_screen(dec->base.context->screen);
struct nouveau_pushbuf *push = dec->pushbuf[0];
enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);
uint32_t bsp_addr, comm_addr, inter_addr;
@@ -95,7 +96,7 @@ nv98_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
bo_refs[1].bo = dec->inter_bo[comm_seq & 1] = inter_bo = tmp_bo;
}
- ret = nouveau_bo_map(bsp_bo, NOUVEAU_BO_WR, dec->client);
+ ret = BO_MAP(screen, bsp_bo, NOUVEAU_BO_WR, dec->client);
if (ret) {
debug_printf("map failed: %i %s\n", ret, strerror(-ret));
return -1;
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
index f1cdf168ed4..68dc3546d8e 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
@@ -44,7 +44,8 @@ static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32
if ((comm->pvp_stage & 0xff) != 0xff) {
unsigned *map;
- int ret = nouveau_bo_map(inter_bo, NOUVEAU_BO_RD|NOUVEAU_BO_NOBLOCK, dec->client);
+ int ret = BO_MAP(nouveau_screen(dec->base.context->screen), inter_bo,
+ NOUVEAU_BO_RD|NOUVEAU_BO_NOBLOCK, dec->client);
assert(ret >= 0);
map = inter_bo->map;
for (i = 0; i < comm->byte_ofs + slice_size; i += 0x10) {
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
index e1738508798..7daf65bb39b 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
@@ -55,7 +55,7 @@ nvc0_hw_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q,
return false;
hq->offset = hq->base_offset;
- ret = nouveau_bo_map(hq->bo, 0, nvc0->base.client);
+ ret = BO_MAP(&screen->base, hq->bo, 0, nvc0->base.client);
if (ret) {
nvc0_hw_query_allocate(nvc0, q, 0);
return false;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index a04969809c4..59a1d614f86 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -1123,7 +1123,7 @@ nvc0_screen_create(struct nouveau_device *dev)
ret = nouveau_bo_new(dev, flags, 0, 4096, NULL, &screen->fence.bo);
if (ret)
FAIL_SCREEN_INIT("Error allocating fence BO: %d\n", ret);
- nouveau_bo_map(screen->fence.bo, 0, NULL);
+ BO_MAP(&screen->base, screen->fence.bo, 0, NULL);
screen->fence.map = screen->fence.bo->map;
screen->base.fence.emit = nvc0_screen_fence_emit;
screen->base.fence.update = nvc0_screen_fence_update;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
index cb345914510..7ede77333ec 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
@@ -388,7 +388,7 @@ nvc0_miptree_transfer_map(struct pipe_context *pctx,
if (nvc0_mt_transfer_can_map_directly(mt)) {
ret = !nvc0_mt_sync(nvc0, mt, usage);
if (!ret)
- ret = nouveau_bo_map(mt->base.bo, 0, NULL);
+ ret = BO_MAP(nvc0->base.screen, mt->base.bo, 0, NULL);
if (ret &&
(usage & PIPE_MAP_DIRECTLY))
return NULL;
@@ -480,7 +480,7 @@ nvc0_miptree_transfer_map(struct pipe_context *pctx,
if (usage & PIPE_MAP_WRITE)
flags |= NOUVEAU_BO_WR;
- ret = nouveau_bo_map(tx->rect[1].bo, flags, nvc0->base.client);
+ ret = BO_MAP(nvc0->base.screen, tx->rect[1].bo, flags, nvc0->base.client);
if (ret) {
pipe_resource_reference(&tx->base.resource, NULL);
nouveau_bo_ref(NULL, &tx->rect[1].bo);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
index 77895cdd6fa..60a90174b2c 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
@@ -293,7 +293,7 @@ nvc0_create_decoder(struct pipe_context *context,
if (ret)
goto fail;
- nouveau_bo_map(dec->fence_bo, NOUVEAU_BO_RDWR, screen->client);
+ BO_MAP(screen, dec->fence_bo, NOUVEAU_BO_RDWR, screen->client);
dec->fence_map = dec->fence_bo->map;
dec->fence_map[0] = dec->fence_map[4] = dec->fence_map[8] = 0;
dec->comm = (struct comm *)(dec->fence_map + (COMM_OFFSET/sizeof(*dec->fence_map)));
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
index ee54596e071..50e67bd81b7 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
@@ -34,10 +34,11 @@ static void dump_comm_bsp(struct comm *comm)
unsigned
nvc0_decoder_bsp_begin(struct nouveau_vp3_decoder *dec, unsigned comm_seq)
{
+ struct nouveau_screen *screen = nouveau_screen(dec->base.context->screen);
struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];
unsigned ret = 0;
- ret = nouveau_bo_map(bsp_bo, NOUVEAU_BO_WR, dec->client);
+ ret = BO_MAP(screen, bsp_bo, NOUVEAU_BO_WR, dec->client);
if (ret) {
debug_printf("map failed: %i %s\n", ret, strerror(-ret));
return -1;
@@ -53,6 +54,7 @@ nvc0_decoder_bsp_next(struct nouveau_vp3_decoder *dec,
unsigned comm_seq, unsigned num_buffers,
const void *const *data, const unsigned *num_bytes)
{
+ struct nouveau_screen *screen = nouveau_screen(dec->base.context->screen);
struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];
struct nouveau_bo *inter_bo = dec->inter_bo[comm_seq & 1];
uint32_t bsp_size = 0;
@@ -82,7 +84,7 @@ nvc0_decoder_bsp_next(struct nouveau_vp3_decoder *dec,
return -1;
}
- ret = nouveau_bo_map(tmp_bo, NOUVEAU_BO_WR, dec->client);
+ ret = BO_MAP(screen, tmp_bo, NOUVEAU_BO_WR, dec->client);
if (ret) {
debug_printf("map failed: %i %s\n", ret, strerror(-ret));
return -1;
@@ -114,7 +116,7 @@ nvc0_decoder_bsp_next(struct nouveau_vp3_decoder *dec,
return -1;
}
- ret = nouveau_bo_map(tmp_bo, NOUVEAU_BO_WR, dec->client);
+ ret = BO_MAP(screen, tmp_bo, NOUVEAU_BO_WR, dec->client);
if (ret) {
debug_printf("map failed: %i %s\n", ret, strerror(-ret));
return -1;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
index 3de4ec14867..8ec09df01c6 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
@@ -44,7 +44,8 @@ static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32
if ((comm->pvp_stage & 0xff) != 0xff) {
unsigned *map;
- int ret = nouveau_bo_map(inter_bo, NOUVEAU_BO_RD|NOUVEAU_BO_NOBLOCK, dec->client);
+ int ret = BO_MAP(nouveau_screen(dec->base.context->screen), inter_bo,
+ NOUVEAU_BO_RD|NOUVEAU_BO_NOBLOCK, dec->client);
assert(ret >= 0);
map = inter_bo->map;
for (i = 0; i < comm->byte_ofs + slice_size; i += 0x10) {
diff --git a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
index 03a88b87797..3944dfe23c7 100644
--- a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
+++ b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
@@ -1031,7 +1031,7 @@ nve4_compute_trap_info(struct nvc0_context *nvc0)
volatile struct nve4_mp_trap_info *info;
uint8_t *map;
- ret = nouveau_bo_map(bo, NOUVEAU_BO_RDWR, nvc0->base.client);
+ ret = BO_MAP(&screen->base, bo, NOUVEAU_BO_RDWR, nvc0->base.client);
if (ret)
return;
map = (uint8_t *)bo->map;
--
2.37.3
From 2095734444387603ef8a6e8d90eef94594b1f07a Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Fri, 25 Jun 2021 22:46:10 +0200
Subject: [PATCH 05/17] nouveau: wrap nouveau_bo_wait
This makes it easier to insert locking code around libdrm.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: M Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nouveau_buffer.c | 2 +-
src/gallium/drivers/nouveau/nouveau_winsys.h | 6 ++++++
src/gallium/drivers/nouveau/nv50/nv50_query_hw.c | 7 ++++---
src/gallium/drivers/nouveau/nv50/nv50_query_hw.h | 2 +-
src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv50_shader_state.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv84_video.c | 3 ++-
src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c | 3 ++-
src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c | 4 ++--
src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c | 2 +-
12 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index e566541a579..cfaf42d7086 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -191,7 +191,7 @@ nouveau_transfer_read(struct nouveau_context *nv, struct nouveau_transfer *tx)
nv->copy_data(nv, tx->bo, tx->offset, NOUVEAU_BO_GART,
buf->bo, buf->offset + base, buf->domain, size);
- if (nouveau_bo_wait(tx->bo, NOUVEAU_BO_RD, nv->client))
+ if (BO_WAIT(nv->screen, tx->bo, NOUVEAU_BO_RD, nv->client))
return false;
if (buf->data)
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index a5fbf7fb8a3..a18bd85ad9f 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -74,6 +74,12 @@ BO_MAP(struct nouveau_screen *screen, struct nouveau_bo *bo, uint32_t access, st
return nouveau_bo_map(bo, access, client);
}
+static inline int
+BO_WAIT(struct nouveau_screen *screen, struct nouveau_bo *bo, uint32_t access, struct nouveau_client *client)
+{
+ return nouveau_bo_wait(bo, access, client);
+}
+
#define NOUVEAU_RESOURCE_FLAG_LINEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 0)
#define NOUVEAU_RESOURCE_FLAG_DRV_PRIV (PIPE_RESOURCE_FLAG_DRV_PRIV << 1)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
index 4d959426148..5e079cf3307 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
@@ -294,7 +294,7 @@ nv50_hw_get_query_result(struct nv50_context *nv50, struct nv50_query *q,
}
return false;
}
- if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nv50->base.client))
+ if (BO_WAIT(&nv50->screen->base, hq->bo, NOUVEAU_BO_RD, nv50->base.client))
return false;
}
hq->state = NV50_HW_QUERY_STATE_READY;
@@ -447,14 +447,15 @@ nv50_hw_get_driver_query_info(struct nv50_screen *screen, unsigned id,
}
void
-nv50_hw_query_pushbuf_submit(struct nouveau_pushbuf *push, uint16_t method,
+nv50_hw_query_pushbuf_submit(struct nv50_context *nv50, uint16_t method,
struct nv50_query *q, unsigned result_offset)
{
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_hw_query *hq = nv50_hw_query(q);
nv50_hw_query_update(q);
if (hq->state != NV50_HW_QUERY_STATE_READY)
- nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, push->client);
+ BO_WAIT(&nv50->screen->base, hq->bo, NOUVEAU_BO_RD, push->client);
hq->state = NV50_HW_QUERY_STATE_READY;
BEGIN_NV04(push, SUBC_3D(method), 1);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.h b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.h
index 4a351510f72..ad2f7ec0f73 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.h
@@ -52,7 +52,7 @@ nv50_hw_get_driver_query_info(struct nv50_screen *, unsigned,
bool
nv50_hw_query_allocate(struct nv50_context *, struct nv50_query *, int);
void
-nv50_hw_query_pushbuf_submit(struct nouveau_pushbuf *, uint16_t,
+nv50_hw_query_pushbuf_submit(struct nv50_context *, uint16_t,
struct nv50_query *, unsigned);
void
nv84_hw_query_fifo_wait(struct nouveau_pushbuf *, struct nv50_query *);
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 de3d8fd950e..a6c92bbbd1e 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
@@ -321,7 +321,7 @@ nv50_hw_sm_query_read_data(uint32_t count[32][4],
if (hq->data[b + 4] != hq->sequence) {
if (!wait)
return false;
- if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nv50->base.client))
+ if (BO_WAIT(&nv50->screen->base, hq->bo, NOUVEAU_BO_RD, nv50->base.client))
return false;
}
count[p][c] = hq->data[b + hsq->ctr[c]];
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
index 5a3b911bfe1..3d17953ed37 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
@@ -717,7 +717,7 @@ nv50_stream_output_validate(struct nv50_context *nv50)
PUSH_DATA(push, targ->pipe.buffer_size);
if (!targ->clean) {
assert(targ->pq);
- nv50_hw_query_pushbuf_submit(push, NVA0_3D_STRMOUT_OFFSET(i),
+ nv50_hw_query_pushbuf_submit(nv50, NVA0_3D_STRMOUT_OFFSET(i),
nv50_query(targ->pq), 0x4);
} else {
BEGIN_NV04(push, NVA0_3D(STRMOUT_OFFSET(i)), 1);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index 600434f767d..2d1879ed72f 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
@@ -737,7 +737,7 @@ nva0_draw_stream_output(struct nv50_context *nv50,
PUSH_DATA (push, 0);
BEGIN_NV04(push, NVA0_3D(DRAW_TFB_STRIDE), 1);
PUSH_DATA (push, so->stride);
- nv50_hw_query_pushbuf_submit(push, NVA0_3D_DRAW_TFB_BYTES,
+ nv50_hw_query_pushbuf_submit(nv50, NVA0_3D_DRAW_TFB_BYTES,
nv50_query(so->pq), 0x4);
BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
PUSH_DATA (push, 0);
diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video.c b/src/gallium/drivers/nouveau/nv50/nv84_video.c
index 7e6aa8fffb3..c5e04bb7dfb 100644
--- a/src/gallium/drivers/nouveau/nv50/nv84_video.c
+++ b/src/gallium/drivers/nouveau/nv50/nv84_video.c
@@ -184,11 +184,12 @@ nv84_decoder_begin_frame_mpeg12(struct pipe_video_codec *decoder,
struct pipe_video_buffer *target,
struct pipe_picture_desc *picture)
{
+ struct nouveau_screen *screen = nouveau_screen(decoder->context->screen);
struct nv84_decoder *dec = (struct nv84_decoder *)decoder;
struct pipe_mpeg12_picture_desc *desc = (struct pipe_mpeg12_picture_desc *)picture;
int i;
- nouveau_bo_wait(dec->mpeg12_bo, NOUVEAU_BO_RDWR, dec->client);
+ BO_WAIT(screen, dec->mpeg12_bo, NOUVEAU_BO_RDWR, dec->client);
dec->mpeg12_mb_info = dec->mpeg12_bo->map + 0x100;
dec->mpeg12_data = dec->mpeg12_bo->map + 0x100 +
align(0x20 * mb(dec->base.width) * mb(dec->base.height), 0x100);
diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c b/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c
index 38eca1771c5..4bd96105bbb 100644
--- a/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c
@@ -89,6 +89,7 @@ nv84_decoder_bsp(struct nv84_decoder *dec,
const unsigned *num_bytes,
struct nv84_video_buffer *dest)
{
+ struct nouveau_screen *screen = nouveau_screen(dec->base.context->screen);
struct iparm params;
uint32_t more_params[0x44 / 4] = {0};
unsigned total_bytes = 0;
@@ -103,7 +104,7 @@ nv84_decoder_bsp(struct nv84_decoder *dec,
{ dec->fence, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },
};
- nouveau_bo_wait(dec->fence, NOUVEAU_BO_RDWR, dec->client);
+ BO_WAIT(screen, dec->fence, NOUVEAU_BO_RDWR, dec->client);
STATIC_ASSERT(sizeof(struct iparm) == 0x530);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
index 7daf65bb39b..d5e0fd6d1c1 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
@@ -330,7 +330,7 @@ nvc0_hw_get_query_result(struct nvc0_context *nvc0, struct nvc0_query *q,
}
return false;
}
- if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nvc0->base.client))
+ if (BO_WAIT(&nvc0->screen->base, hq->bo, NOUVEAU_BO_RD, nvc0->base.client))
return false;
NOUVEAU_DRV_STAT(&nvc0->screen->base, query_sync_count, 1);
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c
index 4cc564217db..4146ad1bc76 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c
@@ -2636,7 +2636,7 @@ nvc0_hw_sm_query_read_data(uint32_t count[32][8],
if (hq->data[b + 8] != hq->sequence) {
if (!wait)
return false;
- if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nvc0->base.client))
+ if (BO_WAIT(&nvc0->screen->base, hq->bo, NOUVEAU_BO_RD, nvc0->base.client))
return false;
}
count[p][c] = hq->data[b + hsq->ctr[c]] * (1 << c);
@@ -2664,7 +2664,7 @@ nve4_hw_sm_query_read_data(uint32_t count[32][8],
if (hq->data[b + 20 + d] != hq->sequence) {
if (!wait)
return false;
- if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nvc0->base.client))
+ if (BO_WAIT(&nvc0->screen->base, hq->bo, NOUVEAU_BO_RD, nvc0->base.client))
return false;
}
if (hsq->ctr[c] & ~0x3)
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
index 7ede77333ec..1e57d889289 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
@@ -362,7 +362,7 @@ nvc0_mt_sync(struct nvc0_context *nvc0, struct nv50_miptree *mt, unsigned usage)
if (!mt->base.mm) {
uint32_t access = (usage & PIPE_MAP_WRITE) ?
NOUVEAU_BO_WR : NOUVEAU_BO_RD;
- return !nouveau_bo_wait(mt->base.bo, access, nvc0->base.client);
+ return !BO_WAIT(&nvc0->screen->base, mt->base.bo, access, nvc0->base.client);
}
if (usage & PIPE_MAP_WRITE)
return !mt->base.fence || nouveau_fence_wait(mt->base.fence, &nvc0->base.debug);
--
2.37.3
From 1f01cae796e8183407cae3444546fcafe38511f9 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Sat, 26 Jun 2021 10:24:45 +0200
Subject: [PATCH 06/17] nouveau: wrap all nouveau_pushbuf_space calls
This makes it easier to insert locking code around libdrm.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: M Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nouveau_video.c | 4 ++--
src/gallium/drivers/nouveau/nouveau_winsys.h | 8 +++++++-
src/gallium/drivers/nouveau/nv30/nv30_clear.c | 4 ++--
src/gallium/drivers/nouveau/nv30/nv30_transfer.c | 10 +++++-----
src/gallium/drivers/nouveau/nv50/nv50_compute.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv50_surface.c | 6 +++---
src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv98_video.c | 6 +++---
src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv98_video_vp.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_compute.c | 4 ++--
src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c | 4 ++--
src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c | 4 ++--
src/gallium/drivers/nouveau/nvc0/nvc0_video.c | 6 +++---
src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nve4_compute.c | 6 +++---
20 files changed, 43 insertions(+), 37 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_video.c b/src/gallium/drivers/nouveau/nouveau_video.c
index 787129b376e..db594416348 100644
--- a/src/gallium/drivers/nouveau/nouveau_video.c
+++ b/src/gallium/drivers/nouveau/nouveau_video.c
@@ -73,7 +73,7 @@ nouveau_vpe_fini(struct nouveau_decoder *dec) {
if (!dec->cmds)
return;
- nouveau_pushbuf_space(push, 16, 2, 0);
+ PUSH_SPACE_EX(push, 16, 2, 0);
nouveau_bufctx_reset(dec->bufctx, NV31_VIDEO_BIND_CMD);
#define BCTX_ARGS dec->bufctx, NV31_VIDEO_BIND_CMD, NOUVEAU_BO_RD
@@ -588,7 +588,7 @@ nouveau_create_decoder(struct pipe_context *context,
#endif
nouveau_pushbuf_bufctx(dec->push, dec->bufctx);
- nouveau_pushbuf_space(push, 32, 4, 0);
+ PUSH_SPACE_EX(push, 32, 4, 0);
BEGIN_NV04(push, SUBC_MPEG(NV01_SUBCHAN_OBJECT), 1);
PUSH_DATA (push, dec->mpeg->handle);
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index a18bd85ad9f..a8f24b27f0d 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -24,13 +24,19 @@ PUSH_AVAIL(struct nouveau_pushbuf *push)
return push->end - push->cur;
}
+static inline bool
+PUSH_SPACE_EX(struct nouveau_pushbuf *push, uint32_t size, uint32_t relocs, uint32_t pushes)
+{
+ return nouveau_pushbuf_space(push, size, relocs, pushes) == 0;
+}
+
static inline bool
PUSH_SPACE(struct nouveau_pushbuf *push, uint32_t size)
{
/* Provide a buffer so that fences always have room to be emitted */
size += 8;
if (PUSH_AVAIL(push) < size)
- return nouveau_pushbuf_space(push, size, 0, 0) == 0;
+ return PUSH_SPACE_EX(push, size, 0, 0);
return true;
}
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_clear.c b/src/gallium/drivers/nouveau/nv30/nv30_clear.c
index 1d5727a413d..9798639b88c 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_clear.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_clear.c
@@ -148,7 +148,7 @@ nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,
refn.bo = mt->base.bo;
refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
- if (nouveau_pushbuf_space(push, 32, 1, 0) ||
+ if (!PUSH_SPACE_EX(push, 32, 1, 0) ||
nouveau_pushbuf_refn (push, &refn, 1))
return;
@@ -214,7 +214,7 @@ nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps,
refn.bo = mt->base.bo;
refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
- if (nouveau_pushbuf_space(push, 32, 1, 0) ||
+ if (!PUSH_SPACE_EX(push, 32, 1, 0) ||
nouveau_pushbuf_refn (push, &refn, 1))
return;
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
index 1a5151acb89..aaee998cfb5 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
@@ -155,7 +155,7 @@ nv30_transfer_rect_blit(XFER_ARGS)
u32 texfmt, texswz;
u32 format, stride;
- if (nouveau_pushbuf_space(push, 512, 8, 0) ||
+ if (!PUSH_SPACE_EX(push, 512, 8, 0) ||
nouveau_pushbuf_refn (push, refs, ARRAY_SIZE(refs)))
return;
@@ -431,7 +431,7 @@ nv30_transfer_rect_sifm(XFER_ARGS)
si_arg |= NV03_SIFM_FORMAT_FILTER_BILINEAR;
}
- if (nouveau_pushbuf_space(push, 64, 6, 0) ||
+ if (!PUSH_SPACE_EX(push, 64, 6, 0) ||
nouveau_pushbuf_refn (push, refs, 2))
return;
@@ -516,7 +516,7 @@ nv30_transfer_rect_m2mf(XFER_ARGS)
while (h) {
unsigned lines = (h > 2047) ? 2047 : h;
- if (nouveau_pushbuf_space(push, 32, 2, 0) ||
+ if (!PUSH_SPACE_EX(push, 32, 2, 0) ||
nouveau_pushbuf_refn (push, refs, 2))
return;
@@ -708,7 +708,7 @@ nv30_transfer_copy_data(struct nouveau_context *nv,
lines = (pages > 2047) ? 2047 : pages;
pages -= lines;
- if (nouveau_pushbuf_space(push, 32, 2, 0) ||
+ if (!PUSH_SPACE_EX(push, 32, 2, 0) ||
nouveau_pushbuf_refn (push, refs, 2))
return;
@@ -732,7 +732,7 @@ nv30_transfer_copy_data(struct nouveau_context *nv,
}
if (size) {
- if (nouveau_pushbuf_space(push, 32, 2, 0) ||
+ if (!PUSH_SPACE_EX(push, 32, 2, 0) ||
nouveau_pushbuf_refn (push, refs, 2))
return;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_compute.c b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
index d75aa0a9cd3..1fdd5a41e61 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_compute.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
@@ -547,7 +547,7 @@ nv50_compute_upload_input(struct nv50_context *nv50, const uint32_t *input)
nouveau_pushbuf_bufctx(push, nv50->bufctx);
nouveau_pushbuf_validate(push);
- nouveau_pushbuf_space(push, 0, 0, 1);
+ PUSH_SPACE_EX(push, 0, 0, 1);
BEGIN_NV04(push, NV50_CP(USER_PARAM(1)), size / 4);
nouveau_pushbuf_data(push, bo, offset, size);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index f6c8642220a..f457ac46258 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -295,7 +295,7 @@ nv50_clear_render_target(struct pipe_context *pipe,
PUSH_DATAf(push, color->f[2]);
PUSH_DATAf(push, color->f[3]);
- if (nouveau_pushbuf_space(push, 64 + sf->depth, 1, 0))
+ if (!PUSH_SPACE_EX(push, 64 + sf->depth, 1, 0))
return;
PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
@@ -394,7 +394,7 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
mode |= NV50_3D_CLEAR_BUFFERS_S;
}
- if (nouveau_pushbuf_space(push, 64 + sf->depth, 1, 0))
+ if (!PUSH_SPACE_EX(push, 64 + sf->depth, 1, 0))
return;
PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
@@ -771,7 +771,7 @@ nv50_clear_buffer(struct pipe_context *pipe,
PUSH_DATA (push, color.ui[2]);
PUSH_DATA (push, color.ui[3]);
- if (nouveau_pushbuf_space(push, 64, 1, 0))
+ if (!PUSH_SPACE_EX(push, 64, 1, 0))
return;
PUSH_REFN(push, buf->bo, buf->domain | NOUVEAU_BO_WR);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index 2d1879ed72f..830c13beeda 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
@@ -631,7 +631,7 @@ nv50_draw_elements(struct nv50_context *nv50, bool shorten,
BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
PUSH_DATA (push, prim);
- nouveau_pushbuf_space(push, 16, 0, 1);
+ PUSH_SPACE_EX(push, 16, 0, 1);
PUSH_REFN(push, buf->bo, NOUVEAU_BO_RD | buf->domain);
switch (index_size) {
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video.c b/src/gallium/drivers/nouveau/nv50/nv98_video.c
index bc56aff2665..1a5685c0a3f 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video.c
@@ -275,7 +275,7 @@ nv98_create_decoder(struct pipe_context *context,
dec->comm = (struct comm *)(dec->fence_map + (COMM_OFFSET/sizeof(*dec->fence_map)));
/* So lets test if the fence is working? */
- nouveau_pushbuf_space(push[0], 16, 1, 0);
+ PUSH_SPACE_EX(push[0], 16, 1, 0);
PUSH_REFN (push[0], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NV04(push[0], SUBC_BSP(0x240), 3);
PUSH_DATAh(push[0], dec->fence_bo->offset);
@@ -286,7 +286,7 @@ nv98_create_decoder(struct pipe_context *context,
PUSH_DATA (push[0], 0);
PUSH_KICK (push[0]);
- nouveau_pushbuf_space(push[1], 16, 1, 0);
+ PUSH_SPACE_EX(push[1], 16, 1, 0);
PUSH_REFN (push[1], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NV04(push[1], SUBC_VP(0x240), 3);
PUSH_DATAh(push[1], (dec->fence_bo->offset + 0x10));
@@ -297,7 +297,7 @@ nv98_create_decoder(struct pipe_context *context,
PUSH_DATA (push[1], 0);
PUSH_KICK (push[1]);
- nouveau_pushbuf_space(push[2], 16, 1, 0);
+ PUSH_SPACE_EX(push[2], 16, 1, 0);
PUSH_REFN (push[2], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NV04(push[2], SUBC_PPP(0x240), 3);
PUSH_DATAh(push[2], (dec->fence_bo->offset + 0x20));
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
index 4c3a6172233..7a87ad70064 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
@@ -108,7 +108,7 @@ nv98_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
nouveau_vp3_vp_caps(dec, desc, target, comm_seq, vp_caps, is_ref, refs);
- nouveau_pushbuf_space(push, 32, num_refs, 0);
+ PUSH_SPACE_EX(push, 32, num_refs, 0);
nouveau_pushbuf_refn(push, bo_refs, num_refs);
bsp_addr = bsp_bo->offset >> 8;
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c
index 3fce65ba55b..a207291a07f 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c
@@ -94,7 +94,7 @@ nv98_decoder_ppp(struct nouveau_vp3_decoder *dec, union pipe_desc desc, struct n
struct nouveau_pushbuf *push = dec->pushbuf[2];
unsigned ppp_caps = 0x10;
- nouveau_pushbuf_space(push, 32, 4, 0);
+ PUSH_SPACE_EX(push, 32, 4, 0);
switch (codec) {
case PIPE_VIDEO_FORMAT_MPEG12: {
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
index 68dc3546d8e..96ed9a6cb1a 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
@@ -112,7 +112,7 @@ nv98_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
if (!is_ref && (dec->refs[target->valid_ref].decoded_top && dec->refs[target->valid_ref].decoded_bottom))
nv98_decoder_kick_ref(dec, target);
- nouveau_pushbuf_space(push, 32 + codec_extra, num_refs, 0);
+ PUSH_SPACE_EX(push, 32 + codec_extra, num_refs, 0);
nouveau_pushbuf_refn(push, bo_refs, num_refs);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
index 62ff39172fc..f61f9cd424f 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
@@ -464,7 +464,7 @@ nvc0_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
PUSH_DATA (push, (info->block[1] << 16) | info->block[0]);
PUSH_DATA (push, info->block[2]);
- nouveau_pushbuf_space(push, 32, 2, 1);
+ PUSH_SPACE_EX(push, 32, 2, 1);
PUSH_REFN(push, screen->text, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD);
if (unlikely(info->indirect)) {
@@ -511,7 +511,7 @@ nvc0_compute_update_indirect_invocations(struct nvc0_context *nvc0,
struct nv04_resource *res = nv04_resource(info->indirect);
uint32_t offset = res->offset + info->indirect_offset;
- nouveau_pushbuf_space(push, 16, 0, 8);
+ PUSH_SPACE_EX(push, 16, 0, 8);
PUSH_REFN(push, res->bo, NOUVEAU_BO_RD | res->domain);
BEGIN_1IC0(push, NVC0_3D(MACRO_COMPUTE_COUNTER), 7);
PUSH_DATA(push, 6);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
index d5e0fd6d1c1..c2f8344a3d6 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
@@ -129,7 +129,7 @@ nvc0_hw_query_write_compute_invocations(struct nvc0_context *nvc0,
{
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
- nouveau_pushbuf_space(push, 16, 0, 8);
+ PUSH_SPACE_EX(push, 16, 0, 8);
PUSH_REFN(push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
BEGIN_1IC0(push, NVC0_3D(MACRO_COMPUTE_COUNTER_TO_QUERY), 4);
PUSH_DATA (push, nvc0->compute_invocations);
@@ -435,7 +435,7 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0,
if ((flags & PIPE_QUERY_WAIT) && hq->state != NVC0_HW_QUERY_STATE_READY)
nvc0_hw_query_fifo_wait(nvc0, q);
- nouveau_pushbuf_space(push, 32, 2, 3);
+ PUSH_SPACE_EX(push, 32, 2, 3);
PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
PUSH_REFN (push, buf->bo, buf->domain | NOUVEAU_BO_WR);
BEGIN_1IC0(push, NVC0_3D(MACRO_QUERY_BUFFER_WRITE), 9);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c
index a8203b5c6ce..0bd8a752f15 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c
@@ -364,7 +364,7 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
if (!targ->clean)
nvc0_hw_query_fifo_wait(nvc0, nvc0_query(targ->pq));
- nouveau_pushbuf_space(push, 0, 0, 1);
+ PUSH_SPACE_EX(push, 0, 0, 1);
BEGIN_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 5);
PUSH_DATA (push, 1);
PUSH_DATAh(push, buf->address + targ->pipe.buffer_offset);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
index b9118cb099e..fe51ed3ee15 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
@@ -788,7 +788,7 @@ nvc0_draw_stream_output(struct nvc0_context *nvc0,
}
while (num_instances--) {
- nouveau_pushbuf_space(push, 16, 0, 1);
+ PUSH_SPACE_EX(push, 16, 0, 1);
BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1);
PUSH_DATA (push, mode);
BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_BASE), 1);
@@ -869,7 +869,7 @@ nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info,
pushes = draws;
}
- nouveau_pushbuf_space(push, 16, 0, pushes + !!buf_count);
+ PUSH_SPACE_EX(push, 16, 0, pushes + !!buf_count);
PUSH_REFN(push, buf->bo, NOUVEAU_BO_RD | buf->domain);
if (buf_count)
PUSH_REFN(push, buf_count->bo, NOUVEAU_BO_RD | buf_count->domain);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
index 60a90174b2c..3df13e26557 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
@@ -299,7 +299,7 @@ nvc0_create_decoder(struct pipe_context *context,
dec->comm = (struct comm *)(dec->fence_map + (COMM_OFFSET/sizeof(*dec->fence_map)));
/* So lets test if the fence is working? */
- nouveau_pushbuf_space(push[0], 16, 1, 0);
+ PUSH_SPACE_EX(push[0], 16, 1, 0);
PUSH_REFN (push[0], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NVC0(push[0], SUBC_BSP(0x240), 3);
PUSH_DATAh(push[0], dec->fence_bo->offset);
@@ -310,7 +310,7 @@ nvc0_create_decoder(struct pipe_context *context,
PUSH_DATA (push[0], 0);
PUSH_KICK (push[0]);
- nouveau_pushbuf_space(push[1], 16, 1, 0);
+ PUSH_SPACE_EX(push[1], 16, 1, 0);
PUSH_REFN (push[1], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NVC0(push[1], SUBC_VP(0x240), 3);
PUSH_DATAh(push[1], (dec->fence_bo->offset + 0x10));
@@ -321,7 +321,7 @@ nvc0_create_decoder(struct pipe_context *context,
PUSH_DATA (push[1], 0);
PUSH_KICK (push[1]);
- nouveau_pushbuf_space(push[2], 16, 1, 0);
+ PUSH_SPACE_EX(push[2], 16, 1, 0);
PUSH_REFN (push[2], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NVC0(push[2], SUBC_PPP(0x240), 3);
PUSH_DATAh(push[2], (dec->fence_bo->offset + 0x20));
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
index 50e67bd81b7..96eb1015374 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
@@ -162,7 +162,7 @@ nvc0_decoder_bsp_end(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
nouveau_vp3_vp_caps(dec, desc, target, comm_seq, vp_caps, is_ref, refs);
- nouveau_pushbuf_space(push, 32, num_refs, 0);
+ PUSH_SPACE_EX(push, 32, num_refs, 0);
nouveau_pushbuf_refn(push, bo_refs, num_refs);
bsp_addr = bsp_bo->offset >> 8;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c
index 4f058628e31..d36d172f2d0 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c
@@ -94,7 +94,7 @@ nvc0_decoder_ppp(struct nouveau_vp3_decoder *dec, union pipe_desc desc, struct n
struct nouveau_pushbuf *push = dec->pushbuf[2];
unsigned ppp_caps = 0x10;
- nouveau_pushbuf_space(push, 32, 4, 0);
+ PUSH_SPACE_EX(push, 32, 4, 0);
switch (codec) {
case PIPE_VIDEO_FORMAT_MPEG12: {
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
index 8ec09df01c6..6975783a73c 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
@@ -112,7 +112,7 @@ nvc0_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
if (!is_ref && (dec->refs[target->valid_ref].decoded_top && dec->refs[target->valid_ref].decoded_bottom))
nvc0_decoder_kick_ref(dec, target);
- nouveau_pushbuf_space(push, 32 + codec_extra, num_refs, 0);
+ PUSH_SPACE_EX(push, 32 + codec_extra, num_refs, 0);
nouveau_pushbuf_refn(push, bo_refs, num_refs);
diff --git a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
index 3944dfe23c7..f07bc208377 100644
--- a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
+++ b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
@@ -545,7 +545,7 @@ nve4_compute_upload_input(struct nvc0_context *nvc0,
struct nv04_resource *res = nv04_resource(info->indirect);
uint32_t offset = res->offset + info->indirect_offset;
- nouveau_pushbuf_space(push, 32, 0, 1);
+ PUSH_SPACE_EX(push, 32, 0, 1);
PUSH_REFN(push, res->bo, NOUVEAU_BO_RD | res->domain);
BEGIN_1IC0(push, NVE4_CP(UPLOAD_EXEC), 1 + 8);
@@ -829,7 +829,7 @@ nve4_upload_indirect_desc(struct nouveau_pushbuf *push,
PUSH_DATA (push, length);
PUSH_DATA (push, 1);
- nouveau_pushbuf_space(push, 32, 0, 1);
+ PUSH_SPACE_EX(push, 32, 0, 1);
PUSH_REFN(push, res->bo, NOUVEAU_BO_RD | res->domain);
BEGIN_1IC0(push, NVE4_CP(UPLOAD_EXEC), 1 + (length / 4));
@@ -923,7 +923,7 @@ nve4_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
}
/* upload descriptor and flush */
- nouveau_pushbuf_space(push, 32, 1, 0);
+ PUSH_SPACE_EX(push, 32, 1, 0);
PUSH_REFN(push, screen->text, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD);
BEGIN_NVC0(push, NVE4_CP(LAUNCH_DESC_ADDRESS), 1);
PUSH_DATA (push, desc_gpuaddr >> 8);
--
2.37.3
From 72d3fd4243ad851989e3e961565a7fc91d93625f Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Tue, 29 Jun 2021 00:37:39 +0200
Subject: [PATCH 07/17] nouveau: wrap nouveau_pushbuf_validate
This makes it easier to insert locking code around libdrm.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: M Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nouveau_video.c | 2 +-
src/gallium/drivers/nouveau/nouveau_winsys.h | 6 ++++++
.../drivers/nouveau/nv30/nv30_state_validate.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv50_compute.c | 2 +-
.../drivers/nouveau/nv50/nv50_state_validate.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv50_surface.c | 6 +++---
src/gallium/drivers/nouveau/nv50/nv50_transfer.c | 8 ++++----
.../drivers/nouveau/nvc0/nvc0_state_validate.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_surface.c | 10 +++++-----
src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c | 12 ++++++------
.../drivers/nouveau/nvc0/nvc0_vbo_translate.c | 4 ++--
11 files changed, 31 insertions(+), 25 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_video.c b/src/gallium/drivers/nouveau/nouveau_video.c
index db594416348..9637f39c8e2 100644
--- a/src/gallium/drivers/nouveau/nouveau_video.c
+++ b/src/gallium/drivers/nouveau/nouveau_video.c
@@ -88,7 +88,7 @@ nouveau_vpe_fini(struct nouveau_decoder *dec) {
#undef BCTX_ARGS
- if (unlikely(nouveau_pushbuf_validate(dec->push)))
+ if (unlikely(PUSH_VAL(dec->push)))
return;
BEGIN_NV04(push, NV31_MPEG(EXEC), 1);
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index a8f24b27f0d..cefd83a68e5 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -74,6 +74,12 @@ PUSH_KICK(struct nouveau_pushbuf *push)
nouveau_pushbuf_kick(push, push->channel);
}
+static inline int
+PUSH_VAL(struct nouveau_pushbuf *push)
+{
+ return nouveau_pushbuf_validate(push);
+}
+
static inline int
BO_MAP(struct nouveau_screen *screen, struct nouveau_bo *bo, uint32_t access, struct nouveau_client *client)
{
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c b/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
index 26c77595c2a..248c399dd89 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
@@ -499,7 +499,7 @@ nv30_state_validate(struct nv30_context *nv30, uint32_t mask, bool hwtnl)
}
nouveau_pushbuf_bufctx(push, bctx);
- if (nouveau_pushbuf_validate(push)) {
+ if (PUSH_VAL(push)) {
nouveau_pushbuf_bufctx(push, NULL);
return false;
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_compute.c b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
index 1fdd5a41e61..cf406089eae 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_compute.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
@@ -545,7 +545,7 @@ nv50_compute_upload_input(struct nv50_context *nv50, const uint32_t *input)
nouveau_bufctx_refn(nv50->bufctx, 0, bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
nouveau_pushbuf_bufctx(push, nv50->bufctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
PUSH_SPACE_EX(push, 0, 0, 1);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
index d465cf633cf..02cf0b72e7e 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
@@ -559,7 +559,7 @@ nv50_state_validate(struct nv50_context *nv50, uint32_t mask,
nv50_bufctx_fence(bufctx, false);
}
nouveau_pushbuf_bufctx(nv50->base.pushbuf, bufctx);
- ret = nouveau_pushbuf_validate(nv50->base.pushbuf);
+ ret = PUSH_VAL(nv50->base.pushbuf);
return !ret;
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index f457ac46258..84c9bac414d 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -257,7 +257,7 @@ nv50_resource_copy_region(struct pipe_context *pipe,
BCTX_REFN(nv50->bufctx, 2D, nv04_resource(src), RD);
BCTX_REFN(nv50->bufctx, 2D, nv04_resource(dst), WR);
nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx);
- nouveau_pushbuf_validate(nv50->base.pushbuf);
+ PUSH_VAL(nv50->base.pushbuf);
for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
ret = nv50_2d_texture_do_copy(nv50->base.pushbuf,
@@ -653,7 +653,7 @@ nv50_clear_buffer_push(struct pipe_context *pipe,
nouveau_bufctx_refn(nv50->bufctx, 0, buf->bo, buf->domain | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, nv50->bufctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
offset &= ~0xff;
@@ -1639,7 +1639,7 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
BCTX_REFN(nv50->bufctx, 2D, &dst->base, WR);
BCTX_REFN(nv50->bufctx, 2D, &src->base, RD);
nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx);
- if (nouveau_pushbuf_validate(nv50->base.pushbuf))
+ if (PUSH_VAL(nv50->base.pushbuf))
return;
for (i = 0; i < info->dst.box.depth; ++i) {
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
index d84a6763a46..143d920552f 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
@@ -67,7 +67,7 @@ nv50_2d_transfer_rect(struct nv50_context *nv50,
nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, bctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
uint32_t format;
switch (cpp) {
@@ -197,7 +197,7 @@ nv50_m2mf_transfer_rect(struct nv50_context *nv50,
nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, bctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
if (nouveau_bo_memtype(src->bo)) {
BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 6);
@@ -284,7 +284,7 @@ nv50_sifc_linear_u8(struct nouveau_context *nv,
nouveau_bufctx_refn(nv50->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, nv50->bufctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
offset &= ~0xff;
@@ -337,7 +337,7 @@ nv50_m2mf_copy_linear(struct nouveau_context *nv,
nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, bctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 1);
PUSH_DATA (push, 1);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
index ab9a4717727..39c518efdef 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
@@ -985,7 +985,7 @@ nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask,
}
nouveau_pushbuf_bufctx(nvc0->base.pushbuf, bufctx);
- ret = nouveau_pushbuf_validate(nvc0->base.pushbuf);
+ ret = PUSH_VAL(nvc0->base.pushbuf);
return !ret;
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
index a1c568b0e8f..24e2a2963d4 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
@@ -267,7 +267,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD);
BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR);
nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx);
- nouveau_pushbuf_validate(nvc0->base.pushbuf);
+ PUSH_VAL(nvc0->base.pushbuf);
for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
ret = nvc0_2d_texture_do_copy(nvc0->base.pushbuf,
@@ -379,7 +379,7 @@ nvc0_clear_buffer_push_nvc0(struct pipe_context *pipe,
nouveau_bufctx_refn(nvc0->bufctx, 0, buf->bo, buf->domain | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, nvc0->bufctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
unsigned count = (size + 3) / 4;
unsigned data_words = data_size / 4;
@@ -428,7 +428,7 @@ nvc0_clear_buffer_push_nve4(struct pipe_context *pipe,
nouveau_bufctx_refn(nvc0->bufctx, 0, buf->bo, buf->domain | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, nvc0->bufctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
unsigned count = (size + 3) / 4;
unsigned data_words = data_size / 4;
@@ -1327,7 +1327,7 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
NOUVEAU_BO_GART | NOUVEAU_BO_RD, vtxbuf_bo);
BCTX_REFN_bo(nvc0->bufctx_3d, 3D_TEXT,
NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD, screen->text);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(0)), 4);
PUSH_DATA (push, NVC0_3D_VERTEX_ARRAY_FETCH_ENABLE | stride <<
@@ -1549,7 +1549,7 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
BCTX_REFN(nvc0->bufctx, 2D, &dst->base, WR);
BCTX_REFN(nvc0->bufctx, 2D, &src->base, RD);
nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx);
- if (nouveau_pushbuf_validate(nvc0->base.pushbuf))
+ if (PUSH_VAL(nvc0->base.pushbuf))
return;
for (i = 0; i < info->dst.box.depth; ++i) {
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
index 1e57d889289..1da61c0370a 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
@@ -32,7 +32,7 @@ nvc0_m2mf_transfer_rect(struct nvc0_context *nvc0,
nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, bctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
if (nouveau_bo_memtype(src->bo)) {
BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_IN), 5);
@@ -138,7 +138,7 @@ nve4_m2mf_transfer_rect(struct nvc0_context *nvc0,
nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
nouveau_pushbuf_bufctx(push, bctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
exec = NVE4_COPY_EXEC_SWIZZLE_ENABLE | NVE4_COPY_EXEC_2D_ENABLE | NVE4_COPY_EXEC_FLUSH | NVE4_COPY_EXEC_COPY_MODE_NON_PIPELINED;
@@ -207,7 +207,7 @@ nvc0_m2mf_push_linear(struct nouveau_context *nv,
nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, nvc0->bufctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
while (count) {
unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
@@ -249,7 +249,7 @@ nve4_p2mf_push_linear(struct nouveau_context *nv,
nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, nvc0->bufctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
while (count) {
unsigned nr = MIN2(count, (NV04_PFIFO_MAX_PACKET_LEN - 1));
@@ -289,7 +289,7 @@ nvc0_m2mf_copy_linear(struct nouveau_context *nv,
nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, bctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
while (size) {
unsigned bytes = MIN2(size, 1 << 17);
@@ -327,7 +327,7 @@ nve4_m2mf_copy_linear(struct nouveau_context *nv,
nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
nouveau_pushbuf_bufctx(push, bctx);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
BEGIN_NVC0(push, NVE4_COPY(SRC_ADDRESS_HIGH), 4);
PUSH_DATAh(push, src->offset + srcoff);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c
index 30dae5a1265..c7ae3fb3f9b 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c
@@ -239,7 +239,7 @@ nvc0_push_setup_vertex_array(struct nvc0_context *nvc0, const unsigned count)
BCTX_REFN_bo(nvc0->bufctx_3d, 3D_VTX_TMP, NOUVEAU_BO_GART | NOUVEAU_BO_RD,
bo);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
return dest;
}
@@ -731,7 +731,7 @@ nvc0_push_upload_vertex_ids(struct push_context *ctx,
BCTX_REFN_bo(nvc0->bufctx_3d, 3D_VTX_TMP, NOUVEAU_BO_GART | NOUVEAU_BO_RD,
bo);
- nouveau_pushbuf_validate(push);
+ PUSH_VAL(push);
if (info->index_size) {
if (!draw->index_bias) {
--
2.37.3
From 6dd4957222774264a06720e869e0c7a3e1063697 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Fri, 13 May 2022 17:36:14 +0200
Subject: [PATCH 08/17] nouveau: wrap nouveau_pushbuf_refn
This makes it easier to insert locking code around libdrm.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: M Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nouveau_winsys.h | 13 +++++++++++++
src/gallium/drivers/nouveau/nv30/nv30_clear.c | 10 ++--------
src/gallium/drivers/nouveau/nv30/nv30_transfer.c | 10 +++++-----
src/gallium/drivers/nouveau/nv30/nv30_winsys.h | 7 -------
src/gallium/drivers/nouveau/nv50/nv50_query.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv50_query_hw.c | 4 ++--
src/gallium/drivers/nouveau/nv50/nv50_surface.c | 6 +++---
src/gallium/drivers/nouveau/nv50/nv50_transfer.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv50_winsys.h | 8 --------
src/gallium/drivers/nouveau/nv50/nv84_video.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv84_video_vp.c | 6 +++---
src/gallium/drivers/nouveau/nv50/nv98_video.c | 6 +++---
src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv98_video_vp.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_compute.c | 6 +++---
src/gallium/drivers/nouveau/nvc0/nvc0_query.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c | 12 ++++++------
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 6 +++---
src/gallium/drivers/nouveau/nvc0/nvc0_surface.c | 6 +++---
src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c | 4 ++--
src/gallium/drivers/nouveau/nvc0/nvc0_video.c | 6 +++---
src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_winsys.h | 8 --------
src/gallium/drivers/nouveau/nvc0/nve4_compute.c | 6 +++---
30 files changed, 67 insertions(+), 83 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index cefd83a68e5..3d83d572615 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -68,6 +68,19 @@ PUSH_DATAf(struct nouveau_pushbuf *push, float f)
PUSH_DATA(push, u.i);
}
+static inline int
+PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_pushbuf_refn *refs, int nr)
+{
+ return nouveau_pushbuf_refn(push, refs, nr);
+}
+
+static inline int
+PUSH_REF1(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags)
+{
+ struct nouveau_pushbuf_refn ref = { bo, flags };
+ return PUSH_REFN(push, &ref, 1);
+}
+
static inline void
PUSH_KICK(struct nouveau_pushbuf *push)
{
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_clear.c b/src/gallium/drivers/nouveau/nv30/nv30_clear.c
index 9798639b88c..2b8ea9700cf 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_clear.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_clear.c
@@ -129,7 +129,6 @@ nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,
struct nv30_miptree *mt = nv30_miptree(ps->texture);
struct nouveau_pushbuf *push = nv30->base.pushbuf;
struct nouveau_object *eng3d = nv30->screen->eng3d;
- struct nouveau_pushbuf_refn refn;
uint32_t rt_format;
rt_format = nv30_format(pipe->screen, ps->format)->hw;
@@ -146,10 +145,8 @@ nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,
rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
}
- refn.bo = mt->base.bo;
- refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
if (!PUSH_SPACE_EX(push, 32, 1, 0) ||
- nouveau_pushbuf_refn (push, &refn, 1))
+ PUSH_REF1(push, mt->base.bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR))
return;
BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
@@ -190,7 +187,6 @@ nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps,
struct nv30_miptree *mt = nv30_miptree(ps->texture);
struct nouveau_pushbuf *push = nv30->base.pushbuf;
struct nouveau_object *eng3d = nv30->screen->eng3d;
- struct nouveau_pushbuf_refn refn;
uint32_t rt_format, mode = 0;
rt_format = nv30_format(pipe->screen, ps->format)->hw;
@@ -212,10 +208,8 @@ nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps,
if (buffers & PIPE_CLEAR_STENCIL)
mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;
- refn.bo = mt->base.bo;
- refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
if (!PUSH_SPACE_EX(push, 32, 1, 0) ||
- nouveau_pushbuf_refn (push, &refn, 1))
+ PUSH_REF1(push, mt->base.bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR))
return;
BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
index aaee998cfb5..c78b896a729 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
@@ -156,7 +156,7 @@ nv30_transfer_rect_blit(XFER_ARGS)
u32 format, stride;
if (!PUSH_SPACE_EX(push, 512, 8, 0) ||
- nouveau_pushbuf_refn (push, refs, ARRAY_SIZE(refs)))
+ PUSH_REFN(push, refs, ARRAY_SIZE(refs)))
return;
/* various switches depending on cpp of the transfer */
@@ -432,7 +432,7 @@ nv30_transfer_rect_sifm(XFER_ARGS)
}
if (!PUSH_SPACE_EX(push, 64, 6, 0) ||
- nouveau_pushbuf_refn (push, refs, 2))
+ PUSH_REFN(push, refs, 2))
return;
if (dst->pitch) {
@@ -517,7 +517,7 @@ nv30_transfer_rect_m2mf(XFER_ARGS)
unsigned lines = (h > 2047) ? 2047 : h;
if (!PUSH_SPACE_EX(push, 32, 2, 0) ||
- nouveau_pushbuf_refn (push, refs, 2))
+ PUSH_REFN(push, refs, 2))
return;
BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8);
@@ -709,7 +709,7 @@ nv30_transfer_copy_data(struct nouveau_context *nv,
pages -= lines;
if (!PUSH_SPACE_EX(push, 32, 2, 0) ||
- nouveau_pushbuf_refn (push, refs, 2))
+ PUSH_REFN(push, refs, 2))
return;
BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8);
@@ -733,7 +733,7 @@ nv30_transfer_copy_data(struct nouveau_context *nv,
if (size) {
if (!PUSH_SPACE_EX(push, 32, 2, 0) ||
- nouveau_pushbuf_refn (push, refs, 2))
+ PUSH_REFN(push, refs, 2))
return;
BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_winsys.h b/src/gallium/drivers/nouveau/nv30/nv30_winsys.h
index 2324b517c44..25897ea9f6b 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_winsys.h
+++ b/src/gallium/drivers/nouveau/nv30/nv30_winsys.h
@@ -39,13 +39,6 @@ PUSH_RESET(struct nouveau_pushbuf *push, int bin)
nouveau_bufctx_reset(bufctx(push), bin);
}
-static inline void
-PUSH_REFN(struct nouveau_pushbuf *push, int bin,
- struct nouveau_bo *bo, uint32_t access)
-{
- nouveau_bufctx_refn(bufctx(push), bin, bo, access);
-}
-
static inline void
PUSH_MTHDl(struct nouveau_pushbuf *push, int subc, int mthd, int bin,
struct nouveau_bo *bo, uint32_t offset, uint32_t access)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query.c b/src/gallium/drivers/nouveau/nv50/nv50_query.c
index 08820b33672..4d012a14047 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query.c
@@ -132,7 +132,7 @@ nv50_render_condition(struct pipe_context *pipe,
PUSH_DATA (push, 0);
}
- PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+ PUSH_REF1 (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
BEGIN_NV04(push, NV50_3D(COND_ADDRESS_HIGH), 3);
PUSH_DATAh(push, hq->bo->offset + hq->offset);
PUSH_DATA (push, hq->bo->offset + hq->offset);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
index 5e079cf3307..7508470e982 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
@@ -82,7 +82,7 @@ nv50_hw_query_get(struct nouveau_pushbuf *push, struct nv50_query *q,
offset += hq->offset;
PUSH_SPACE(push, 5);
- PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
+ PUSH_REF1 (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
BEGIN_NV04(push, NV50_3D(QUERY_ADDRESS_HIGH), 4);
PUSH_DATAh(push, hq->bo->offset + offset);
PUSH_DATA (push, hq->bo->offset + offset);
@@ -471,7 +471,7 @@ nv84_hw_query_fifo_wait(struct nouveau_pushbuf *push, struct nv50_query *q)
assert(!hq->is64bit);
PUSH_SPACE(push, 5);
- PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+ PUSH_REF1 (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
BEGIN_NV04(push, SUBC_3D(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4);
PUSH_DATAh(push, hq->bo->offset + offset);
PUSH_DATA (push, hq->bo->offset + offset);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index 84c9bac414d..72f185b224e 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -298,7 +298,7 @@ nv50_clear_render_target(struct pipe_context *pipe,
if (!PUSH_SPACE_EX(push, 64 + sf->depth, 1, 0))
return;
- PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
+ PUSH_REF1(push, bo, mt->base.domain | NOUVEAU_BO_WR);
BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
PUSH_DATA (push, ( width << 16) | dstx);
@@ -397,7 +397,7 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
if (!PUSH_SPACE_EX(push, 64 + sf->depth, 1, 0))
return;
- PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
+ PUSH_REF1(push, bo, mt->base.domain | NOUVEAU_BO_WR);
BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
PUSH_DATA (push, ( width << 16) | dstx);
@@ -774,7 +774,7 @@ nv50_clear_buffer(struct pipe_context *pipe,
if (!PUSH_SPACE_EX(push, 64, 1, 0))
return;
- PUSH_REFN(push, buf->bo, buf->domain | NOUVEAU_BO_WR);
+ PUSH_REF1(push, buf->bo, buf->domain | NOUVEAU_BO_WR);
BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
PUSH_DATA (push, width << 16);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
index 143d920552f..6438510d028 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
@@ -511,7 +511,7 @@ nv50_cb_bo_push(struct nouveau_context *nv,
unsigned nr = MIN2(words, NV04_PFIFO_MAX_PACKET_LEN);
PUSH_SPACE(push, nr + 3);
- PUSH_REFN (push, bo, NOUVEAU_BO_WR | domain);
+ PUSH_REF1 (push, bo, NOUVEAU_BO_WR | domain);
BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
PUSH_DATA (push, (offset << 6) | bufid);
BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index 830c13beeda..100c71b8c2d 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
@@ -632,7 +632,7 @@ nv50_draw_elements(struct nv50_context *nv50, bool shorten,
PUSH_DATA (push, prim);
PUSH_SPACE_EX(push, 16, 0, 1);
- PUSH_REFN(push, buf->bo, NOUVEAU_BO_RD | buf->domain);
+ PUSH_REF1(push, buf->bo, NOUVEAU_BO_RD | buf->domain);
switch (index_size) {
case 4:
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_winsys.h b/src/gallium/drivers/nouveau/nv50/nv50_winsys.h
index 7056258d1bf..cda05cedee9 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_winsys.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_winsys.h
@@ -39,14 +39,6 @@ nv50_add_bufctx_resident(struct nouveau_bufctx *bufctx, int bin,
#define BCTX_REFN(bctx, bin, res, acc) \
nv50_add_bufctx_resident(bctx, NV50_BIND_##bin, res, NOUVEAU_BO_##acc)
-static inline void
-PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags)
-{
- struct nouveau_pushbuf_refn ref = { bo, flags };
- nouveau_pushbuf_refn(push, &ref, 1);
-}
-
-
#define SUBC_3D(m) 3, (m)
#define NV50_3D(n) SUBC_3D(NV50_3D_##n)
#define NV84_3D(n) SUBC_3D(NV84_3D_##n)
diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video.c b/src/gallium/drivers/nouveau/nv50/nv84_video.c
index c5e04bb7dfb..41f74a66770 100644
--- a/src/gallium/drivers/nouveau/nv50/nv84_video.c
+++ b/src/gallium/drivers/nouveau/nv50/nv84_video.c
@@ -496,7 +496,7 @@ nv84_create_decoder(struct pipe_context *context,
context->clear_render_target(context, &surf.base, &color, 0, 0, 1024, 1, false);
PUSH_SPACE(nv50->base.pushbuf, 5);
- PUSH_REFN(nv50->base.pushbuf, dec->fence, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+ PUSH_REF1(nv50->base.pushbuf, dec->fence, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
/* The clear_render_target is done via 3D engine, so use it to write to a
* sempahore to indicate that it's done.
*/
diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c b/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c
index 4bd96105bbb..f988d0af212 100644
--- a/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv84_video_bsp.c
@@ -201,7 +201,7 @@ nv84_decoder_bsp(struct nv84_decoder *dec,
memcpy(dec->bitstream->map + 0x600, more_params, sizeof(more_params));
PUSH_SPACE(push, 5 + 21 + 3 + 2 + 4 + 2);
- nouveau_pushbuf_refn(push, bo_refs, ARRAY_SIZE(bo_refs));
+ PUSH_REFN(push, bo_refs, ARRAY_SIZE(bo_refs));
/* Wait for the fence = 1 */
BEGIN_NV04(push, SUBC_BSP(0x10), 4);
diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video_vp.c b/src/gallium/drivers/nouveau/nv50/nv84_video_vp.c
index 811e0c60f83..a5d4d18fb82 100644
--- a/src/gallium/drivers/nouveau/nv50/nv84_video_vp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv84_video_vp.c
@@ -141,13 +141,13 @@ nv84_decoder_vp_h264(struct nv84_decoder *dec,
{ bo1, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },
{ bo2, NOUVEAU_BO_RDWR | NOUVEAU_BO_VRAM },
};
- nouveau_pushbuf_refn(push, bo_refs, ARRAY_SIZE(bo_refs));
+ PUSH_REFN(push, bo_refs, ARRAY_SIZE(bo_refs));
}
memcpy(dec->vp_params->map, &param1, sizeof(param1));
memcpy(dec->vp_params->map + 0x400, &param2, sizeof(param2));
- nouveau_pushbuf_refn(push, bo_refs, num_refs);
+ PUSH_REFN(push, bo_refs, num_refs);
/* Wait for BSP to have completed */
BEGIN_NV04(push, SUBC_VP(0x10), 4);
@@ -522,7 +522,7 @@ nv84_decoder_vp_mpeg12(struct nv84_decoder *dec,
PUSH_SPACE(push, 10 + 3 + 2);
- nouveau_pushbuf_refn(push, bo_refs, num_refs);
+ PUSH_REFN(push, bo_refs, num_refs);
BEGIN_NV04(push, SUBC_VP(0x400), 9);
PUSH_DATA (push, 0x543210); /* each nibble possibly a dma index */
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video.c b/src/gallium/drivers/nouveau/nv50/nv98_video.c
index 1a5685c0a3f..07cb05550b1 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video.c
@@ -276,7 +276,7 @@ nv98_create_decoder(struct pipe_context *context,
/* So lets test if the fence is working? */
PUSH_SPACE_EX(push[0], 16, 1, 0);
- PUSH_REFN (push[0], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
+ PUSH_REF1 (push[0], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NV04(push[0], SUBC_BSP(0x240), 3);
PUSH_DATAh(push[0], dec->fence_bo->offset);
PUSH_DATA (push[0], dec->fence_bo->offset);
@@ -287,7 +287,7 @@ nv98_create_decoder(struct pipe_context *context,
PUSH_KICK (push[0]);
PUSH_SPACE_EX(push[1], 16, 1, 0);
- PUSH_REFN (push[1], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
+ PUSH_REF1 (push[1], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NV04(push[1], SUBC_VP(0x240), 3);
PUSH_DATAh(push[1], (dec->fence_bo->offset + 0x10));
PUSH_DATA (push[1], (dec->fence_bo->offset + 0x10));
@@ -298,7 +298,7 @@ nv98_create_decoder(struct pipe_context *context,
PUSH_KICK (push[1]);
PUSH_SPACE_EX(push[2], 16, 1, 0);
- PUSH_REFN (push[2], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
+ PUSH_REF1 (push[2], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NV04(push[2], SUBC_PPP(0x240), 3);
PUSH_DATAh(push[2], (dec->fence_bo->offset + 0x20));
PUSH_DATA (push[2], (dec->fence_bo->offset + 0x20));
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
index 7a87ad70064..2e8bf3b8af6 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_bsp.c
@@ -109,7 +109,7 @@ nv98_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
nouveau_vp3_vp_caps(dec, desc, target, comm_seq, vp_caps, is_ref, refs);
PUSH_SPACE_EX(push, 32, num_refs, 0);
- nouveau_pushbuf_refn(push, bo_refs, num_refs);
+ PUSH_REFN(push, bo_refs, num_refs);
bsp_addr = bsp_bo->offset >> 8;
inter_addr = inter_bo->offset >> 8;
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c
index a207291a07f..bbca2f99105 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_ppp.c
@@ -47,7 +47,7 @@ nv98_decoder_setup_ppp(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video
bo_refs[i].bo = mt->base.bo;
}
- nouveau_pushbuf_refn(push, bo_refs, num_refs);
+ PUSH_REFN(push, bo_refs, num_refs);
nouveau_vp3_ycbcr_offsets(dec, &y2, &cbcr, &cbcr2);
BEGIN_NV04(push, SUBC_PPP(0x700), 10);
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
index 96ed9a6cb1a..33f6f758a41 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video_vp.c
@@ -114,7 +114,7 @@ nv98_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
PUSH_SPACE_EX(push, 32 + codec_extra, num_refs, 0);
- nouveau_pushbuf_refn(push, bo_refs, num_refs);
+ PUSH_REFN(push, bo_refs, num_refs);
bsp_addr = bsp_bo->offset >> 8;
#if NOUVEAU_VP3_DEBUG_FENCE
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
index f61f9cd424f..24ee9bfff6c 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
@@ -465,14 +465,14 @@ nvc0_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
PUSH_DATA (push, info->block[2]);
PUSH_SPACE_EX(push, 32, 2, 1);
- PUSH_REFN(push, screen->text, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD);
+ PUSH_REF1(push, screen->text, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD);
if (unlikely(info->indirect)) {
struct nv04_resource *res = nv04_resource(info->indirect);
uint32_t offset = res->offset + info->indirect_offset;
unsigned macro = NVC0_CP_MACRO_LAUNCH_GRID_INDIRECT;
- PUSH_REFN(push, res->bo, NOUVEAU_BO_RD | res->domain);
+ PUSH_REF1(push, res->bo, NOUVEAU_BO_RD | res->domain);
PUSH_DATA(push, NVC0_FIFO_PKHDR_1I(1, macro, 3));
nouveau_pushbuf_data(push, res->bo, offset,
NVC0_IB_ENTRY_1_NO_PREFETCH | 3 * 4);
@@ -512,7 +512,7 @@ nvc0_compute_update_indirect_invocations(struct nvc0_context *nvc0,
uint32_t offset = res->offset + info->indirect_offset;
PUSH_SPACE_EX(push, 16, 0, 8);
- PUSH_REFN(push, res->bo, NOUVEAU_BO_RD | res->domain);
+ PUSH_REF1(push, res->bo, NOUVEAU_BO_RD | res->domain);
BEGIN_1IC0(push, NVC0_3D(MACRO_COMPUTE_COUNTER), 7);
PUSH_DATA(push, 6);
PUSH_DATA(push, info->block[0]);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c
index 0deb667a02e..085f9712d35 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c
@@ -153,7 +153,7 @@ nvc0_render_condition(struct pipe_context *pipe,
nvc0_hw_query_fifo_wait(nvc0, q);
PUSH_SPACE(push, 10);
- PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+ PUSH_REF1 (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
BEGIN_NVC0(push, NVC0_3D(COND_ADDRESS_HIGH), 3);
PUSH_DATAh(push, hq->bo->offset + hq->offset);
PUSH_DATA (push, hq->bo->offset + hq->offset);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
index c2f8344a3d6..a18fdf2e5ac 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
@@ -74,7 +74,7 @@ nvc0_hw_query_get(struct nouveau_pushbuf *push, struct nvc0_query *q,
offset += hq->offset;
PUSH_SPACE(push, 5);
- PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
+ PUSH_REF1 (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
BEGIN_NVC0(push, NVC0_3D(QUERY_ADDRESS_HIGH), 4);
PUSH_DATAh(push, hq->bo->offset + offset);
PUSH_DATA (push, hq->bo->offset + offset);
@@ -130,7 +130,7 @@ nvc0_hw_query_write_compute_invocations(struct nvc0_context *nvc0,
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
PUSH_SPACE_EX(push, 16, 0, 8);
- PUSH_REFN(push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
+ PUSH_REF1(push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
BEGIN_1IC0(push, NVC0_3D(MACRO_COMPUTE_COUNTER_TO_QUERY), 4);
PUSH_DATA (push, nvc0->compute_invocations);
PUSH_DATAh(push, nvc0->compute_invocations);
@@ -436,8 +436,8 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0,
nvc0_hw_query_fifo_wait(nvc0, q);
PUSH_SPACE_EX(push, 32, 2, 3);
- PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
- PUSH_REFN (push, buf->bo, buf->domain | NOUVEAU_BO_WR);
+ PUSH_REF1 (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+ PUSH_REF1 (push, buf->bo, buf->domain | NOUVEAU_BO_WR);
BEGIN_1IC0(push, NVC0_3D(MACRO_QUERY_BUFFER_WRITE), 9);
switch (q->type) {
case PIPE_QUERY_OCCLUSION_PREDICATE:
@@ -629,7 +629,7 @@ nvc0_hw_query_pushbuf_submit(struct nouveau_pushbuf *push,
{
struct nvc0_hw_query *hq = nvc0_hw_query(q);
- PUSH_REFN(push, hq->bo, NOUVEAU_BO_RD | NOUVEAU_BO_GART);
+ PUSH_REF1(push, hq->bo, NOUVEAU_BO_RD | NOUVEAU_BO_GART);
nouveau_pushbuf_data(push, hq->bo, hq->offset + result_offset, 4 |
NVC0_IB_ENTRY_1_NO_PREFETCH);
}
@@ -646,7 +646,7 @@ nvc0_hw_query_fifo_wait(struct nvc0_context *nvc0, struct nvc0_query *q)
nouveau_fence_emit(hq->fence);
PUSH_SPACE(push, 5);
- PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+ PUSH_REF1 (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
BEGIN_NVC0(push, SUBC_3D(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4);
if (hq->is64bit) {
PUSH_DATAh(push, nvc0->screen->fence.bo->offset);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 59a1d614f86..fa9fc82ff5a 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -935,7 +935,7 @@ nvc0_screen_resize_tls_area(struct nvc0_screen *screen,
* segment, as it may have commands that will reference it.
*/
if (screen->tls)
- PUSH_REFN(screen->base.pushbuf, screen->tls,
+ PUSH_REF1(screen->base.pushbuf, screen->tls,
NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RDWR);
nouveau_bo_ref(NULL, &screen->tls);
screen->tls = bo;
@@ -958,7 +958,7 @@ nvc0_screen_resize_text_area(struct nvc0_screen *screen, uint64_t size)
* segment, as it may have commands that will reference it.
*/
if (screen->text)
- PUSH_REFN(push, screen->text,
+ PUSH_REF1(push, screen->text,
NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD);
nouveau_bo_ref(NULL, &screen->text);
screen->text = bo;
@@ -1321,7 +1321,7 @@ nvc0_screen_create(struct nouveau_device *dev)
if (ret)
FAIL_SCREEN_INIT("Error allocating uniform BO: %d\n", ret);
- PUSH_REFN (push, screen->uniform_bo, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_WR);
+ PUSH_REF1 (push, screen->uniform_bo, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_WR);
/* return { 0.0, 0.0, 0.0, 0.0 } for out-of-bounds vtxbuf access */
BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
index 24e2a2963d4..5f95c709dec 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
@@ -301,7 +301,7 @@ nvc0_clear_render_target(struct pipe_context *pipe,
if (!PUSH_SPACE(push, 32 + sf->depth))
return;
- PUSH_REFN (push, res->bo, res->domain | NOUVEAU_BO_WR);
+ PUSH_REF1 (push, res->bo, res->domain | NOUVEAU_BO_WR);
BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);
PUSH_DATAf(push, color->f[0]);
@@ -571,7 +571,7 @@ nvc0_clear_buffer(struct pipe_context *pipe,
if (!PUSH_SPACE(push, 40))
return;
- PUSH_REFN (push, buf->bo, buf->domain | NOUVEAU_BO_WR);
+ PUSH_REF1 (push, buf->bo, buf->domain | NOUVEAU_BO_WR);
BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);
PUSH_DATA (push, color.ui[0]);
@@ -639,7 +639,7 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
if (!PUSH_SPACE(push, 32 + sf->depth))
return;
- PUSH_REFN (push, mt->base.bo, mt->base.domain | NOUVEAU_BO_WR);
+ PUSH_REF1 (push, mt->base.bo, mt->base.domain | NOUVEAU_BO_WR);
if (clear_flags & PIPE_CLEAR_DEPTH) {
BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
index 1da61c0370a..c5aab3075df 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
@@ -598,7 +598,7 @@ nvc0_cb_bo_push(struct nouveau_context *nv,
unsigned nr = MIN2(words, NV04_PFIFO_MAX_PACKET_LEN - 1);
PUSH_SPACE(push, nr + 2);
- PUSH_REFN (push, bo, NOUVEAU_BO_WR | domain);
+ PUSH_REF1 (push, bo, NOUVEAU_BO_WR | domain);
BEGIN_1IC0(push, NVC0_3D(CB_POS), nr + 1);
PUSH_DATA (push, offset);
PUSH_DATAp(push, data, nr);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
index fe51ed3ee15..b9ca992ffcb 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
@@ -870,9 +870,9 @@ nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info,
}
PUSH_SPACE_EX(push, 16, 0, pushes + !!buf_count);
- PUSH_REFN(push, buf->bo, NOUVEAU_BO_RD | buf->domain);
+ PUSH_REF1(push, buf->bo, NOUVEAU_BO_RD | buf->domain);
if (buf_count)
- PUSH_REFN(push, buf_count->bo, NOUVEAU_BO_RD | buf_count->domain);
+ PUSH_REF1(push, buf_count->bo, NOUVEAU_BO_RD | buf_count->domain);
PUSH_DATA(push,
NVC0_FIFO_PKHDR_1I(0, macro, 3 + !!buf_count + draws * size));
PUSH_DATA(push, nvc0_prim_gl(info->mode));
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
index 3df13e26557..3ffc4204b81 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
@@ -300,7 +300,7 @@ nvc0_create_decoder(struct pipe_context *context,
/* So lets test if the fence is working? */
PUSH_SPACE_EX(push[0], 16, 1, 0);
- PUSH_REFN (push[0], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
+ PUSH_REF1 (push[0], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NVC0(push[0], SUBC_BSP(0x240), 3);
PUSH_DATAh(push[0], dec->fence_bo->offset);
PUSH_DATA (push[0], dec->fence_bo->offset);
@@ -311,7 +311,7 @@ nvc0_create_decoder(struct pipe_context *context,
PUSH_KICK (push[0]);
PUSH_SPACE_EX(push[1], 16, 1, 0);
- PUSH_REFN (push[1], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
+ PUSH_REF1 (push[1], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NVC0(push[1], SUBC_VP(0x240), 3);
PUSH_DATAh(push[1], (dec->fence_bo->offset + 0x10));
PUSH_DATA (push[1], (dec->fence_bo->offset + 0x10));
@@ -322,7 +322,7 @@ nvc0_create_decoder(struct pipe_context *context,
PUSH_KICK (push[1]);
PUSH_SPACE_EX(push[2], 16, 1, 0);
- PUSH_REFN (push[2], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
+ PUSH_REF1 (push[2], dec->fence_bo, NOUVEAU_BO_GART|NOUVEAU_BO_RDWR);
BEGIN_NVC0(push[2], SUBC_PPP(0x240), 3);
PUSH_DATAh(push[2], (dec->fence_bo->offset + 0x20));
PUSH_DATA (push[2], (dec->fence_bo->offset + 0x20));
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
index 96eb1015374..df0b5286b33 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_bsp.c
@@ -163,7 +163,7 @@ nvc0_decoder_bsp_end(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
nouveau_vp3_vp_caps(dec, desc, target, comm_seq, vp_caps, is_ref, refs);
PUSH_SPACE_EX(push, 32, num_refs, 0);
- nouveau_pushbuf_refn(push, bo_refs, num_refs);
+ PUSH_REFN(push, bo_refs, num_refs);
bsp_addr = bsp_bo->offset >> 8;
inter_addr = inter_bo->offset >> 8;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c
index d36d172f2d0..6e633237023 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_ppp.c
@@ -47,7 +47,7 @@ nvc0_decoder_setup_ppp(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video
bo_refs[i].bo = mt->base.bo;
}
- nouveau_pushbuf_refn(push, bo_refs, num_refs);
+ PUSH_REFN(push, bo_refs, num_refs);
nouveau_vp3_ycbcr_offsets(dec, &y2, &cbcr, &cbcr2);
BEGIN_NVC0(push, SUBC_PPP(0x700), 10);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
index 6975783a73c..98dc1c937fc 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video_vp.c
@@ -114,7 +114,7 @@ nvc0_decoder_vp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
PUSH_SPACE_EX(push, 32 + codec_extra, num_refs, 0);
- nouveau_pushbuf_refn(push, bo_refs, num_refs);
+ PUSH_REFN(push, bo_refs, num_refs);
bsp_addr = bsp_bo->offset >> 8;
#if NOUVEAU_VP3_DEBUG_FENCE
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_winsys.h b/src/gallium/drivers/nouveau/nvc0/nvc0_winsys.h
index 81110493231..c9f4cf57162 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_winsys.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_winsys.h
@@ -38,14 +38,6 @@ nvc0_add_resident(struct nouveau_bufctx *bufctx, int bin,
#define BCTX_REFN(bctx, bin, res, acc) \
nvc0_add_resident(bctx, NVC0_BIND_##bin, res, NOUVEAU_BO_##acc)
-static inline void
-PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags)
-{
- struct nouveau_pushbuf_refn ref = { bo, flags };
- nouveau_pushbuf_refn(push, &ref, 1);
-}
-
-
#define SUBC_3D(m) 0, (m)
#define NVC0_3D(n) SUBC_3D(NVC0_3D_##n)
#define NVE4_3D(n) SUBC_3D(NVE4_3D_##n)
diff --git a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
index f07bc208377..dccbce91ef7 100644
--- a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
+++ b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
@@ -546,7 +546,7 @@ nve4_compute_upload_input(struct nvc0_context *nvc0,
uint32_t offset = res->offset + info->indirect_offset;
PUSH_SPACE_EX(push, 32, 0, 1);
- PUSH_REFN(push, res->bo, NOUVEAU_BO_RD | res->domain);
+ PUSH_REF1(push, res->bo, NOUVEAU_BO_RD | res->domain);
BEGIN_1IC0(push, NVE4_CP(UPLOAD_EXEC), 1 + 8);
PUSH_DATA (push, NVE4_COMPUTE_UPLOAD_EXEC_LINEAR | (0x20 << 1));
@@ -830,7 +830,7 @@ nve4_upload_indirect_desc(struct nouveau_pushbuf *push,
PUSH_DATA (push, 1);
PUSH_SPACE_EX(push, 32, 0, 1);
- PUSH_REFN(push, res->bo, NOUVEAU_BO_RD | res->domain);
+ PUSH_REF1(push, res->bo, NOUVEAU_BO_RD | res->domain);
BEGIN_1IC0(push, NVE4_CP(UPLOAD_EXEC), 1 + (length / 4));
PUSH_DATA (push, NVE4_COMPUTE_UPLOAD_EXEC_LINEAR | (0x08 << 1));
@@ -924,7 +924,7 @@ nve4_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
/* upload descriptor and flush */
PUSH_SPACE_EX(push, 32, 1, 0);
- PUSH_REFN(push, screen->text, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD);
+ PUSH_REF1(push, screen->text, NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD);
BEGIN_NVC0(push, NVE4_CP(LAUNCH_DESC_ADDRESS), 1);
PUSH_DATA (push, desc_gpuaddr >> 8);
BEGIN_NVC0(push, NVE4_CP(LAUNCH), 1);
--
2.37.3
From 4728a5ce42d98cd0cdc5d1d535ae73074a62a32b Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Wed, 30 Jun 2021 10:01:29 +0200
Subject: [PATCH 09/17] nouveau: use PUSH_KICK instead of nouveau_pushbuf_kick
This makes it easier to insert locking code around libdrm.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: M Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nv30/nv30_screen.c | 3 +--
src/gallium/drivers/nouveau/nv50/nv50_context.c | 2 +-
src/gallium/drivers/nouveau/nvc0/nvc0_context.c | 2 +-
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
index b0a08a207d5..4b92db1e20b 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -859,8 +859,7 @@ nv30_screen_create(struct nouveau_device *dev)
PUSH_DATA (push, screen->ntfy->handle);
BEGIN_NV04(push, NV05_SIFM(COLOR_CONVERSION), 1);
PUSH_DATA (push, NV05_SIFM_COLOR_CONVERSION_TRUNCATE);
-
- nouveau_pushbuf_kick(push, push->channel);
+ PUSH_KICK (push);
nouveau_fence_new(&screen->base, &screen->base.fence.current);
return &screen->base;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c
index 6b7b6889d38..58629873554 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c
@@ -194,7 +194,7 @@ nv50_destroy(struct pipe_context *pipe)
u_upload_destroy(nv50->base.pipe.stream_uploader);
nouveau_pushbuf_bufctx(nv50->base.pushbuf, NULL);
- nouveau_pushbuf_kick(nv50->base.pushbuf, nv50->base.pushbuf->channel);
+ PUSH_KICK(nv50->base.pushbuf);
nv50_context_unreference_resources(nv50);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
index c21c5e130b8..ea54c67e4c9 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
@@ -257,7 +257,7 @@ nvc0_destroy(struct pipe_context *pipe)
* Other contexts will always set their bufctx again on action calls.
*/
nouveau_pushbuf_bufctx(nvc0->base.pushbuf, NULL);
- nouveau_pushbuf_kick(nvc0->base.pushbuf, nvc0->base.pushbuf->channel);
+ PUSH_KICK(nvc0->base.pushbuf);
nvc0_context_unreference_resources(nvc0);
nvc0_blitctx_destroy(nvc0);
--
2.37.3
From 3e0c8701fce67a9225db83be8cd53682acc04be0 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Tue, 9 Feb 2021 20:32:15 +0100
Subject: [PATCH 10/17] nouveau/fence: make the fence struct part of the fence
API
This makes it easier to implement proper locking of the fence struct as we
can redesign some of the functions to take the list object instead of
fence objects.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: M Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nouveau_fence.c | 68 ++++++++++---------
src/gallium/drivers/nouveau/nouveau_fence.h | 12 +++-
src/gallium/drivers/nouveau/nouveau_screen.h | 12 +---
.../drivers/nouveau/nv30/nv30_screen.c | 2 +-
.../drivers/nouveau/nv50/nv50_screen.c | 2 +-
.../drivers/nouveau/nvc0/nvc0_screen.c | 2 +-
6 files changed, 54 insertions(+), 44 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c
index a0789739fa3..e3ea148b17d 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.c
+++ b/src/gallium/drivers/nouveau/nouveau_fence.c
@@ -59,6 +59,7 @@ void
nouveau_fence_emit(struct nouveau_fence *fence)
{
struct nouveau_screen *screen = fence->screen;
+ struct nouveau_fence_list *fence_list = &screen->fence;
assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
if (fence->state >= NOUVEAU_FENCE_STATE_EMITTED)
@@ -69,14 +70,14 @@ nouveau_fence_emit(struct nouveau_fence *fence)
++fence->ref;
- if (screen->fence.tail)
- screen->fence.tail->next = fence;
+ if (fence_list->tail)
+ fence_list->tail->next = fence;
else
- screen->fence.head = fence;
+ fence_list->head = fence;
- screen->fence.tail = fence;
+ fence_list->tail = fence;
- screen->fence.emit(&screen->base, &fence->sequence);
+ fence_list->emit(&screen->base, &fence->sequence);
assert(fence->state == NOUVEAU_FENCE_STATE_EMITTING);
fence->state = NOUVEAU_FENCE_STATE_EMITTED;
@@ -86,19 +87,19 @@ void
nouveau_fence_del(struct nouveau_fence *fence)
{
struct nouveau_fence *it;
- struct nouveau_screen *screen = fence->screen;
+ struct nouveau_fence_list *fence_list = &fence->screen->fence;
if (fence->state == NOUVEAU_FENCE_STATE_EMITTED ||
fence->state == NOUVEAU_FENCE_STATE_FLUSHED) {
- if (fence == screen->fence.head) {
- screen->fence.head = fence->next;
- if (!screen->fence.head)
- screen->fence.tail = NULL;
+ if (fence == fence_list->head) {
+ fence_list->head = fence->next;
+ if (!fence_list->head)
+ fence_list->tail = NULL;
} else {
- for (it = screen->fence.head; it && it->next != fence; it = it->next);
+ for (it = fence_list->head; it && it->next != fence; it = it->next);
it->next = fence->next;
- if (screen->fence.tail == fence)
- screen->fence.tail = it;
+ if (fence_list->tail == fence)
+ fence_list->tail = it;
}
}
@@ -111,18 +112,18 @@ nouveau_fence_del(struct nouveau_fence *fence)
}
void
-nouveau_fence_cleanup(struct nouveau_screen *screen)
+nouveau_fence_cleanup(struct nouveau_fence_list *fence_list)
{
- if (screen->fence.current) {
+ if (fence_list->current) {
struct nouveau_fence *current = NULL;
/* nouveau_fence_wait will create a new current fence, so wait on the
* _current_ one, and remove both.
*/
- nouveau_fence_ref(screen->fence.current, &current);
+ nouveau_fence_ref(fence_list->current, &current);
nouveau_fence_wait(current, NULL);
nouveau_fence_ref(NULL, &current);
- nouveau_fence_ref(NULL, &screen->fence.current);
+ nouveau_fence_ref(NULL, &fence_list->current);
}
}
@@ -131,7 +132,8 @@ nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
{
struct nouveau_fence *fence;
struct nouveau_fence *next = NULL;
- u32 sequence = screen->fence.update(&screen->base);
+ struct nouveau_fence_list *fence_list = &screen->fence;
+ u32 sequence = fence_list->update(&screen->base);
/* If running under drm-shim, let all fences be signalled so things run to
* completion (avoids a hang at the end of shader-db).
@@ -139,11 +141,11 @@ nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
if (unlikely(screen->disable_fences))
sequence = screen->fence.sequence;
- if (screen->fence.sequence_ack == sequence)
+ if (fence_list->sequence_ack == sequence)
return;
- screen->fence.sequence_ack = sequence;
+ fence_list->sequence_ack = sequence;
- for (fence = screen->fence.head; fence; fence = next) {
+ for (fence = fence_list->head; fence; fence = next) {
next = fence->next;
sequence = fence->sequence;
@@ -152,12 +154,12 @@ nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
nouveau_fence_trigger_work(fence);
nouveau_fence_ref(NULL, &fence);
- if (sequence == screen->fence.sequence_ack)
+ if (sequence == fence_list->sequence_ack)
break;
}
- screen->fence.head = next;
+ fence_list->head = next;
if (!next)
- screen->fence.tail = NULL;
+ fence_list->tail = NULL;
if (flushed) {
for (fence = next; fence; fence = fence->next)
@@ -186,6 +188,7 @@ static bool
nouveau_fence_kick(struct nouveau_fence *fence)
{
struct nouveau_screen *screen = fence->screen;
+ struct nouveau_fence_list *fence_list = &screen->fence;
/* wtf, someone is waiting on a fence in flush_notify handler? */
assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
@@ -199,7 +202,7 @@ nouveau_fence_kick(struct nouveau_fence *fence)
if (nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel))
return false;
- if (fence == screen->fence.current)
+ if (fence == fence_list->current)
nouveau_fence_next(screen);
nouveau_fence_update(screen, false);
@@ -211,6 +214,7 @@ bool
nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debug)
{
struct nouveau_screen *screen = fence->screen;
+ struct nouveau_fence_list *fence_list = &screen->fence;
uint32_t spins = 0;
int64_t start = 0;
@@ -241,7 +245,7 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debu
debug_printf("Wait on fence %u (ack = %u, next = %u) timed out !\n",
fence->sequence,
- screen->fence.sequence_ack, screen->fence.sequence);
+ fence_list->sequence_ack, fence_list->sequence);
return false;
}
@@ -249,16 +253,18 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debu
void
nouveau_fence_next(struct nouveau_screen *screen)
{
- if (screen->fence.current->state < NOUVEAU_FENCE_STATE_EMITTING) {
- if (screen->fence.current->ref > 1)
- nouveau_fence_emit(screen->fence.current);
+ struct nouveau_fence_list *fence_list = &screen->fence;
+
+ if (fence_list->current->state < NOUVEAU_FENCE_STATE_EMITTING) {
+ if (fence_list->current->ref > 1)
+ nouveau_fence_emit(fence_list->current);
else
return;
}
- nouveau_fence_ref(NULL, &screen->fence.current);
+ nouveau_fence_ref(NULL, &fence_list->current);
- nouveau_fence_new(screen, &screen->fence.current);
+ nouveau_fence_new(screen, &fence_list->current);
}
void
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h
index 129939f0167..a9b21624543 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.h
+++ b/src/gallium/drivers/nouveau/nouveau_fence.h
@@ -29,11 +29,21 @@ struct nouveau_fence {
struct list_head work;
};
+struct nouveau_fence_list {
+ struct nouveau_fence *head;
+ struct nouveau_fence *tail;
+ struct nouveau_fence *current;
+ uint32_t sequence;
+ uint32_t sequence_ack;
+ void (*emit)(struct pipe_screen *, uint32_t *sequence);
+ uint32_t (*update)(struct pipe_screen *);
+};
+
void nouveau_fence_emit(struct nouveau_fence *);
void nouveau_fence_del(struct nouveau_fence *);
bool nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence **);
-void nouveau_fence_cleanup(struct nouveau_screen *);
+void nouveau_fence_cleanup(struct nouveau_fence_list *);
bool nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *);
void nouveau_fence_update(struct nouveau_screen *, bool flushed);
void nouveau_fence_next(struct nouveau_screen *);
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index 470e1336785..100e9b207b2 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -6,6 +6,8 @@
#include "util/u_atomic.h"
#include "util/u_memory.h"
+#include "nouveau_fence.h"
+
#ifndef NDEBUG
# define NOUVEAU_ENABLE_DRIVER_STATISTICS
#endif
@@ -44,15 +46,7 @@ struct nouveau_screen {
uint16_t class_3d;
- struct {
- struct nouveau_fence *head;
- struct nouveau_fence *tail;
- struct nouveau_fence *current;
- u32 sequence;
- u32 sequence_ack;
- void (*emit)(struct pipe_screen *, u32 *sequence);
- u32 (*update)(struct pipe_screen *);
- } fence;
+ struct nouveau_fence_list fence;
struct nouveau_mman *mm_VRAM;
struct nouveau_mman *mm_GART;
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
index 4b92db1e20b..3c0cb06d19d 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -549,7 +549,7 @@ nv30_screen_destroy(struct pipe_screen *pscreen)
if (!nouveau_drm_screen_unref(&screen->base))
return;
- nouveau_fence_cleanup(&screen->base);
+ nouveau_fence_cleanup(&screen->base.fence);
nouveau_bo_ref(NULL, &screen->notify);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index eaa2e84e6ad..1a5f7e3da5a 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -622,7 +622,7 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
if (!nouveau_drm_screen_unref(&screen->base))
return;
- nouveau_fence_cleanup(&screen->base);
+ nouveau_fence_cleanup(&screen->base.fence);
if (screen->base.pushbuf)
screen->base.pushbuf->user_priv = NULL;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index fa9fc82ff5a..2a0fef63bca 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -714,7 +714,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
if (!nouveau_drm_screen_unref(&screen->base))
return;
- nouveau_fence_cleanup(&screen->base);
+ nouveau_fence_cleanup(&screen->base.fence);
if (screen->base.pushbuf)
screen->base.pushbuf->user_priv = NULL;
--
2.37.3
From 890bfefbe5f05f034eb7255de2d196346403f543 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Fri, 7 May 2021 18:16:12 +0200
Subject: [PATCH 11/17] nv50: remove nouveau_fence_signalled prior
nouveau_fence_wait
nouveau_fence_wait handles signalled fences just as well.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: M Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index 100c71b8c2d..8c73423ab49 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
@@ -624,7 +624,7 @@ nv50_draw_elements(struct nv50_context *nv50, bool shorten,
* the not-yet-written data. Ideally this wait would only happen on
* pushbuf submit, but it's probably not a big performance difference.
*/
- if (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr))
+ if (buf->fence_wr)
nouveau_fence_wait(buf->fence_wr, &nv50->base.debug);
while (instance_count--) {
--
2.37.3
From 22a5047c67b2b9c019512678e1bf0e17bb33f488 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Sat, 3 Jul 2021 10:01:52 +0200
Subject: [PATCH 12/17] nv50: remove nv50_bufctx_fence call in vbo_kick_notify
No idea why it is there. nvc0 doesn't do anything like it and it doesn't
regress any tests. Also removing is easier than handling the fence locking
inside the kick notify handler.
Signed-off-by: Karol Herbst <kherbst@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10752>
---
src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index 8c73423ab49..b8ea652a727 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
@@ -752,8 +752,6 @@ nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan)
struct nv50_screen *screen = chan->user_priv;
nouveau_fence_update(&screen->base, true);
-
- nv50_bufctx_fence(screen->cur_ctx->bufctx_3d, true);
}
void
--
2.37.3
From d69d4dc5dd51f7c566905d20cdb1605244daaa34 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Wed, 9 Jun 2021 21:48:17 +0200
Subject: [PATCH 13/17] nouveau/fence: per context fence
This doesn't add a fence list per pipe context, it simply makes us track
the current fence per context so we can safely modify the fence object
per thread.
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>
---
src/gallium/drivers/nouveau/nouveau_buffer.c | 21 ++++++------
src/gallium/drivers/nouveau/nouveau_context.h | 1 +
src/gallium/drivers/nouveau/nouveau_fence.c | 34 +++++++++----------
src/gallium/drivers/nouveau/nouveau_fence.h | 8 ++---
.../drivers/nouveau/nv30/nv30_context.c | 10 +++---
.../drivers/nouveau/nv30/nv30_miptree.c | 2 +-
.../drivers/nouveau/nv30/nv30_screen.c | 3 --
.../nouveau/nv30/nv30_state_validate.c | 5 ++-
.../drivers/nouveau/nv50/nv50_compute.c | 4 +--
.../drivers/nouveau/nv50/nv50_context.c | 18 +++++-----
.../drivers/nouveau/nv50/nv50_context.h | 20 ++++++++++-
.../drivers/nouveau/nv50/nv50_query_hw.c | 4 +--
.../drivers/nouveau/nv50/nv50_screen.c | 4 ---
.../drivers/nouveau/nv50/nv50_screen.h | 26 --------------
.../nouveau/nv50/nv50_state_validate.c | 4 +--
.../drivers/nouveau/nv50/nv50_surface.c | 6 ++--
.../drivers/nouveau/nv50/nv50_transfer.c | 2 +-
.../drivers/nouveau/nvc0/nvc0_context.c | 16 +++++----
.../drivers/nouveau/nvc0/nvc0_context.h | 23 +++++++++++++
.../drivers/nouveau/nvc0/nvc0_query_hw.c | 8 ++---
.../drivers/nouveau/nvc0/nvc0_screen.c | 4 ---
.../drivers/nouveau/nvc0/nvc0_screen.h | 26 --------------
.../nouveau/nvc0/nvc0_state_validate.c | 2 +-
.../drivers/nouveau/nvc0/nvc0_surface.c | 12 +++----
.../drivers/nouveau/nvc0/nvc0_transfer.c | 2 +-
25 files changed, 124 insertions(+), 141 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index cfaf42d7086..c1f5e60b905 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -229,8 +229,8 @@ nouveau_transfer_write(struct nouveau_context *nv, struct nouveau_transfer *tx,
else
nv->push_data(nv, buf->bo, buf->offset + base, buf->domain, size, data);
- nouveau_fence_ref(nv->screen->fence.current, &buf->fence);
- nouveau_fence_ref(nv->screen->fence.current, &buf->fence_wr);
+ nouveau_fence_ref(nv->fence, &buf->fence);
+ nouveau_fence_ref(nv->fence, &buf->fence_wr);
}
/* Does a CPU wait for the buffer's backing data to become reliably accessible
@@ -299,10 +299,9 @@ nouveau_buffer_transfer_del(struct nouveau_context *nv,
{
if (tx->map) {
if (likely(tx->bo)) {
- nouveau_fence_work(nv->screen->fence.current,
- nouveau_fence_unref_bo, tx->bo);
+ nouveau_fence_work(nv->fence, nouveau_fence_unref_bo, tx->bo);
if (tx->mm)
- release_allocation(&tx->mm, nv->screen->fence.current);
+ release_allocation(&tx->mm, nv->fence);
} else {
align_free(tx->map -
(tx->base.box.x & NOUVEAU_MIN_BUFFER_MAP_ALIGN_MASK));
@@ -597,11 +596,11 @@ nouveau_copy_buffer(struct nouveau_context *nv,
src->bo, src->offset + srcx, src->domain, size);
dst->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
- nouveau_fence_ref(nv->screen->fence.current, &dst->fence);
- nouveau_fence_ref(nv->screen->fence.current, &dst->fence_wr);
+ nouveau_fence_ref(nv->fence, &dst->fence);
+ nouveau_fence_ref(nv->fence, &dst->fence_wr);
src->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
- nouveau_fence_ref(nv->screen->fence.current, &src->fence);
+ nouveau_fence_ref(nv->fence, &src->fence);
} else {
struct pipe_box src_box;
src_box.x = srcx;
@@ -849,9 +848,9 @@ nouveau_buffer_migrate(struct nouveau_context *nv,
nv->copy_data(nv, buf->bo, buf->offset, new_domain,
bo, offset, old_domain, buf->base.width0);
- nouveau_fence_work(screen->fence.current, nouveau_fence_unref_bo, bo);
+ nouveau_fence_work(nv->fence, nouveau_fence_unref_bo, bo);
if (mm)
- release_allocation(&mm, screen->fence.current);
+ release_allocation(&mm, nv->fence);
} else
if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) {
struct nouveau_transfer tx;
@@ -960,7 +959,7 @@ nouveau_scratch_runout_release(struct nouveau_context *nv)
if (!nv->scratch.runout)
return;
- if (!nouveau_fence_work(nv->screen->fence.current, nouveau_scratch_unref_bos,
+ if (!nouveau_fence_work(nv->fence, nouveau_scratch_unref_bos,
nv->scratch.runout))
return;
diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h
index e7941b45ec5..e6cd7657913 100644
--- a/src/gallium/drivers/nouveau/nouveau_context.h
+++ b/src/gallium/drivers/nouveau/nouveau_context.h
@@ -15,6 +15,7 @@ struct nouveau_context {
struct nouveau_client *client;
struct nouveau_pushbuf *pushbuf;
+ struct nouveau_fence *fence;
struct util_debug_callback debug;
bool vbo_dirty;
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c
index e3ea148b17d..96b324d89cf 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.c
+++ b/src/gallium/drivers/nouveau/nouveau_fence.c
@@ -21,6 +21,7 @@
*/
#include "nouveau_screen.h"
+#include "nouveau_context.h"
#include "nouveau_winsys.h"
#include "nouveau_fence.h"
#include "util/os_time.h"
@@ -30,13 +31,14 @@
#endif
bool
-nouveau_fence_new(struct nouveau_screen *screen, struct nouveau_fence **fence)
+nouveau_fence_new(struct nouveau_context *nv, struct nouveau_fence **fence)
{
*fence = CALLOC_STRUCT(nouveau_fence);
if (!*fence)
return false;
- (*fence)->screen = screen;
+ (*fence)->screen = nv->screen;
+ (*fence)->context = nv;
(*fence)->ref = 1;
list_inithead(&(*fence)->work);
@@ -112,18 +114,18 @@ nouveau_fence_del(struct nouveau_fence *fence)
}
void
-nouveau_fence_cleanup(struct nouveau_fence_list *fence_list)
+nouveau_fence_cleanup(struct nouveau_context *nv)
{
- if (fence_list->current) {
+ if (nv->fence) {
struct nouveau_fence *current = NULL;
/* nouveau_fence_wait will create a new current fence, so wait on the
* _current_ one, and remove both.
*/
- nouveau_fence_ref(fence_list->current, &current);
+ nouveau_fence_ref(nv->fence, &current);
nouveau_fence_wait(current, NULL);
nouveau_fence_ref(NULL, &current);
- nouveau_fence_ref(NULL, &fence_list->current);
+ nouveau_fence_ref(NULL, &nv->fence);
}
}
@@ -188,7 +190,7 @@ static bool
nouveau_fence_kick(struct nouveau_fence *fence)
{
struct nouveau_screen *screen = fence->screen;
- struct nouveau_fence_list *fence_list = &screen->fence;
+ bool current = !fence->sequence;
/* wtf, someone is waiting on a fence in flush_notify handler? */
assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
@@ -202,8 +204,8 @@ nouveau_fence_kick(struct nouveau_fence *fence)
if (nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel))
return false;
- if (fence == fence_list->current)
- nouveau_fence_next(screen);
+ if (current)
+ nouveau_fence_next(fence->context);
nouveau_fence_update(screen, false);
@@ -251,20 +253,18 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debu
}
void
-nouveau_fence_next(struct nouveau_screen *screen)
+nouveau_fence_next(struct nouveau_context *nv)
{
- struct nouveau_fence_list *fence_list = &screen->fence;
-
- if (fence_list->current->state < NOUVEAU_FENCE_STATE_EMITTING) {
- if (fence_list->current->ref > 1)
- nouveau_fence_emit(fence_list->current);
+ if (nv->fence->state < NOUVEAU_FENCE_STATE_EMITTING) {
+ if (nv->fence->ref > 1)
+ nouveau_fence_emit(nv->fence);
else
return;
}
- nouveau_fence_ref(NULL, &fence_list->current);
+ nouveau_fence_ref(NULL, &nv->fence);
- nouveau_fence_new(screen, &fence_list->current);
+ nouveau_fence_new(nv, &nv->fence);
}
void
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h
index a9b21624543..2ea996521b1 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.h
+++ b/src/gallium/drivers/nouveau/nouveau_fence.h
@@ -22,6 +22,7 @@ struct nouveau_fence_work {
struct nouveau_fence {
struct nouveau_fence *next;
struct nouveau_screen *screen;
+ struct nouveau_context *context;
int state;
int ref;
uint32_t sequence;
@@ -32,7 +33,6 @@ struct nouveau_fence {
struct nouveau_fence_list {
struct nouveau_fence *head;
struct nouveau_fence *tail;
- struct nouveau_fence *current;
uint32_t sequence;
uint32_t sequence_ack;
void (*emit)(struct pipe_screen *, uint32_t *sequence);
@@ -42,11 +42,11 @@ struct nouveau_fence_list {
void nouveau_fence_emit(struct nouveau_fence *);
void nouveau_fence_del(struct nouveau_fence *);
-bool nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence **);
-void nouveau_fence_cleanup(struct nouveau_fence_list *);
+bool nouveau_fence_new(struct nouveau_context *, struct nouveau_fence **);
+void nouveau_fence_cleanup(struct nouveau_context *);
bool nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *);
void nouveau_fence_update(struct nouveau_screen *, bool flushed);
-void nouveau_fence_next(struct nouveau_screen *);
+void nouveau_fence_next(struct nouveau_context *);
bool nouveau_fence_wait(struct nouveau_fence *, struct util_debug_callback *);
bool nouveau_fence_signalled(struct nouveau_fence *);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_context.c b/src/gallium/drivers/nouveau/nv30/nv30_context.c
index 4ce28864b8d..3f25855d045 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_context.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_context.c
@@ -45,7 +45,7 @@ nv30_context_kick_notify(struct nouveau_pushbuf *push)
nv30 = container_of(push->user_priv, struct nv30_context, bufctx);
screen = &nv30->screen->base;
- nouveau_fence_next(screen);
+ nouveau_fence_next(&nv30->base);
nouveau_fence_update(screen, true);
if (push->bufctx) {
@@ -53,13 +53,13 @@ nv30_context_kick_notify(struct nouveau_pushbuf *push)
LIST_FOR_EACH_ENTRY(bref, &push->bufctx->current, thead) {
struct nv04_resource *res = bref->priv;
if (res && res->mm) {
- nouveau_fence_ref(screen->fence.current, &res->fence);
+ nouveau_fence_ref(nv30->base.fence, &res->fence);
if (bref->flags & NOUVEAU_BO_RD)
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
if (bref->flags & NOUVEAU_BO_WR) {
- nouveau_fence_ref(screen->fence.current, &res->fence_wr);
+ nouveau_fence_ref(nv30->base.fence, &res->fence_wr);
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
NOUVEAU_BUFFER_STATUS_DIRTY;
}
@@ -76,7 +76,7 @@ nv30_context_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence,
struct nouveau_pushbuf *push = nv30->base.pushbuf;
if (fence)
- nouveau_fence_ref(nv30->screen->base.fence.current,
+ nouveau_fence_ref(nv30->base.fence,
(struct nouveau_fence **)fence);
PUSH_KICK(push);
@@ -176,6 +176,7 @@ nv30_context_destroy(struct pipe_context *pipe)
if (nv30->screen->cur_ctx == nv30)
nv30->screen->cur_ctx = NULL;
+ nouveau_fence_cleanup(&nv30->base);
nouveau_context_destroy(&nv30->base);
}
@@ -257,6 +258,7 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
}
nouveau_context_init_vdec(&nv30->base);
+ nouveau_fence_new(&nv30->base, &nv30->base.fence);
return pipe;
}
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
index ebbe3746717..992a5d41d57 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
@@ -393,7 +393,7 @@ nv30_miptree_transfer_unmap(struct pipe_context *pipe,
}
/* Allow the copies above to finish executing before freeing the source */
- nouveau_fence_work(nv30->screen->base.fence.current,
+ nouveau_fence_work(nv30->base.fence,
nouveau_fence_unref_bo, tx->tmp.bo);
} else {
nouveau_bo_ref(NULL, &tx->tmp.bo);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
index 3c0cb06d19d..0ffd726102a 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -549,8 +549,6 @@ nv30_screen_destroy(struct pipe_screen *pscreen)
if (!nouveau_drm_screen_unref(&screen->base))
return;
- nouveau_fence_cleanup(&screen->base.fence);
-
nouveau_bo_ref(NULL, &screen->notify);
nouveau_heap_destroy(&screen->query_heap);
@@ -861,6 +859,5 @@ nv30_screen_create(struct nouveau_device *dev)
PUSH_DATA (push, NV05_SIFM_COLOR_CONVERSION_TRUNCATE);
PUSH_KICK (push);
- nouveau_fence_new(&screen->base, &screen->base.fence.current);
return &screen->base;
}
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c b/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
index 248c399dd89..66f19f5906f 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
@@ -463,7 +463,6 @@ nv30_state_context_switch(struct nv30_context *nv30)
bool
nv30_state_validate(struct nv30_context *nv30, uint32_t mask, bool hwtnl)
{
- struct nouveau_screen *screen = &nv30->screen->base;
struct nouveau_pushbuf *push = nv30->base.pushbuf;
struct nouveau_bufctx *bctx = nv30->bufctx;
struct nouveau_bufref *bref;
@@ -523,13 +522,13 @@ nv30_state_validate(struct nv30_context *nv30, uint32_t mask, bool hwtnl)
LIST_FOR_EACH_ENTRY(bref, &bctx->current, thead) {
struct nv04_resource *res = bref->priv;
if (res && res->mm) {
- nouveau_fence_ref(screen->fence.current, &res->fence);
+ nouveau_fence_ref(nv30->base.fence, &res->fence);
if (bref->flags & NOUVEAU_BO_RD)
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
if (bref->flags & NOUVEAU_BO_WR) {
- nouveau_fence_ref(screen->fence.current, &res->fence_wr);
+ nouveau_fence_ref(nv30->base.fence, &res->fence_wr);
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
}
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_compute.c b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
index cf406089eae..af22fd8fd81 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_compute.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
@@ -518,7 +518,7 @@ nv50_state_validate_cp(struct nv50_context *nv50, uint32_t mask)
nv50->bufctx_cp);
if (unlikely(nv50->state.flushed))
- nv50_bufctx_fence(nv50->bufctx_cp, true);
+ nv50_bufctx_fence(nv50, nv50->bufctx_cp, true);
return ret;
}
@@ -552,7 +552,7 @@ nv50_compute_upload_input(struct nv50_context *nv50, const uint32_t *input)
BEGIN_NV04(push, NV50_CP(USER_PARAM(1)), size / 4);
nouveau_pushbuf_data(push, bo, offset, size);
- nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, mm);
+ nouveau_fence_work(nv50->base.fence, nouveau_mm_free_work, mm);
nouveau_bo_ref(NULL, &bo);
nouveau_bufctx_reset(nv50->bufctx, 0);
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c
index 58629873554..9fd5f08be4c 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c
@@ -34,10 +34,9 @@ nv50_flush(struct pipe_context *pipe,
unsigned flags)
{
struct nouveau_context *context = nouveau_context(pipe);
- struct nouveau_screen *screen = context->screen;
if (fence)
- nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
+ nouveau_fence_ref(context->fence, (struct nouveau_fence **)fence);
PUSH_KICK(context->pushbuf);
@@ -136,12 +135,12 @@ void
nv50_default_kick_notify(struct nouveau_pushbuf *push)
{
struct nv50_screen *screen = push->user_priv;
+ struct nv50_context *context = screen->cur_ctx;
- if (screen) {
- nouveau_fence_next(&screen->base);
+ if (context) {
+ nouveau_fence_next(&context->base);
nouveau_fence_update(&screen->base, true);
- if (screen->cur_ctx)
- screen->cur_ctx->state.flushed = true;
+ context->state.flushed = true;
}
}
@@ -200,6 +199,7 @@ nv50_destroy(struct pipe_context *pipe)
FREE(nv50->blit);
+ nouveau_fence_cleanup(&nv50->base);
nouveau_context_destroy(&nv50->base);
}
@@ -414,6 +414,8 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
// zero entry if it's not otherwise set.
nv50->dirty_3d |= NV50_NEW_3D_SAMPLERS;
+ nouveau_fence_new(&nv50->base, &nv50->base.fence);
+
return pipe;
out_err:
@@ -431,7 +433,7 @@ out_err:
}
void
-nv50_bufctx_fence(struct nouveau_bufctx *bufctx, bool on_flush)
+nv50_bufctx_fence(struct nv50_context *nv50, struct nouveau_bufctx *bufctx, bool on_flush)
{
struct nouveau_list *list = on_flush ? &bufctx->current : &bufctx->pending;
struct nouveau_list *it;
@@ -440,7 +442,7 @@ nv50_bufctx_fence(struct nouveau_bufctx *bufctx, bool on_flush)
struct nouveau_bufref *ref = (struct nouveau_bufref *)it;
struct nv04_resource *res = ref->priv;
if (res)
- nv50_resource_validate(res, (unsigned)ref->priv_data);
+ nv50_resource_validate(nv50, res, (unsigned)ref->priv_data);
}
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h
index ed89d54afe4..dd3333a9dd2 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h
@@ -254,10 +254,28 @@ nv50_context_shader_stage(unsigned pipe)
}
}
+static inline void
+nv50_resource_validate(struct nv50_context *context, struct nv04_resource *res, uint32_t flags)
+{
+ if (likely(res->bo)) {
+ if (flags & NOUVEAU_BO_WR)
+ res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
+ NOUVEAU_BUFFER_STATUS_DIRTY;
+ if (flags & NOUVEAU_BO_RD)
+ res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
+
+ if (res->mm) {
+ nouveau_fence_ref(context->base.fence, &res->fence);
+ if (flags & NOUVEAU_BO_WR)
+ nouveau_fence_ref(context->base.fence, &res->fence_wr);
+ }
+ }
+}
+
/* nv50_context.c */
struct pipe_context *nv50_create(struct pipe_screen *, void *, unsigned flags);
-void nv50_bufctx_fence(struct nouveau_bufctx *, bool on_flush);
+void nv50_bufctx_fence(struct nv50_context *, struct nouveau_bufctx *, bool on_flush);
void nv50_default_kick_notify(struct nouveau_pushbuf *);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
index 7508470e982..ba132245249 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
@@ -52,7 +52,7 @@ nv50_hw_query_allocate(struct nv50_context *nv50, struct nv50_query *q,
if (hq->state == NV50_HW_QUERY_STATE_READY)
nouveau_mm_free(hq->mm);
else
- nouveau_fence_work(screen->base.fence.current,
+ nouveau_fence_work(nv50->base.fence,
nouveau_mm_free_work, hq->mm);
}
}
@@ -265,7 +265,7 @@ nv50_hw_end_query(struct nv50_context *nv50, struct nv50_query *q)
break;
}
if (hq->is64bit)
- nouveau_fence_ref(nv50->screen->base.fence.current, &hq->fence);
+ nouveau_fence_ref(nv50->base.fence, &hq->fence);
}
static bool
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index 1a5f7e3da5a..96607b2ef6a 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -622,8 +622,6 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
if (!nouveau_drm_screen_unref(&screen->base))
return;
- nouveau_fence_cleanup(&screen->base.fence);
-
if (screen->base.pushbuf)
screen->base.pushbuf->user_priv = NULL;
@@ -1213,8 +1211,6 @@ nv50_screen_create(struct nouveau_device *dev)
goto fail;
}
- nouveau_fence_new(&screen->base, &screen->base.fence.current);
-
return &screen->base;
fail:
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.h b/src/gallium/drivers/nouveau/nv50/nv50_screen.h
index 6584b625328..a374ba46c6f 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.h
@@ -133,32 +133,6 @@ int nv50_screen_tsc_alloc(struct nv50_screen *, void *);
int nv50_screen_compute_setup(struct nv50_screen *, struct nouveau_pushbuf *);
-static inline void
-nv50_resource_fence(struct nv04_resource *res, uint32_t flags)
-{
- struct nv50_screen *screen = nv50_screen(res->base.screen);
-
- if (res->mm) {
- nouveau_fence_ref(screen->base.fence.current, &res->fence);
- if (flags & NOUVEAU_BO_WR)
- nouveau_fence_ref(screen->base.fence.current, &res->fence_wr);
- }
-}
-
-static inline void
-nv50_resource_validate(struct nv04_resource *res, uint32_t flags)
-{
- if (likely(res->bo)) {
- if (flags & NOUVEAU_BO_WR)
- res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
- NOUVEAU_BUFFER_STATUS_DIRTY;
- if (flags & NOUVEAU_BO_RD)
- res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
-
- nv50_resource_fence(res, flags);
- }
-}
-
struct nv50_format {
uint32_t rt;
struct {
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
index 02cf0b72e7e..eec85cf6676 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
@@ -556,7 +556,7 @@ nv50_state_validate(struct nv50_context *nv50, uint32_t mask,
PUSH_DATA (nv50->base.pushbuf, 0);
}
- nv50_bufctx_fence(bufctx, false);
+ nv50_bufctx_fence(nv50, bufctx, false);
}
nouveau_pushbuf_bufctx(nv50->base.pushbuf, bufctx);
ret = PUSH_VAL(nv50->base.pushbuf);
@@ -575,7 +575,7 @@ nv50_state_validate_3d(struct nv50_context *nv50, uint32_t mask)
if (unlikely(nv50->state.flushed)) {
nv50->state.flushed = false;
- nv50_bufctx_fence(nv50->bufctx_3d, true);
+ nv50_bufctx_fence(nv50, nv50->bufctx_3d, true);
}
return ret;
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index 72f185b224e..6f28c97cc73 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -692,7 +692,7 @@ nv50_clear_buffer_push(struct pipe_context *pipe,
count -= nr;
}
- nv50_resource_validate(buf, NOUVEAU_BO_WR);
+ nv50_resource_validate(nv50, buf, NOUVEAU_BO_WR);
nouveau_bufctx_reset(nv50->bufctx, 0);
}
@@ -815,7 +815,7 @@ nv50_clear_buffer(struct pipe_context *pipe,
BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
PUSH_DATA (push, nv50->cond_condmode);
- nv50_resource_validate(buf, NOUVEAU_BO_WR);
+ nv50_resource_validate(nv50, buf, NOUVEAU_BO_WR);
if (width * height != elements) {
offset += width * height * data_size;
@@ -1679,7 +1679,7 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
PUSH_DATA (push, srcy >> 32);
}
}
- nv50_bufctx_fence(nv50->bufctx, false);
+ nv50_bufctx_fence(nv50, nv50->bufctx, false);
nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
index 6438510d028..4c73695a28d 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
@@ -485,7 +485,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_work(nv50->base.fence,
nouveau_fence_unref_bo, tx->rect[1].bo);
} else {
nouveau_bo_ref(NULL, &tx->rect[1].bo);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
index ea54c67e4c9..adc36531b28 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
@@ -81,10 +81,9 @@ nvc0_flush(struct pipe_context *pipe,
unsigned flags)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
- struct nouveau_screen *screen = &nvc0->screen->base;
if (fence)
- nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
+ nouveau_fence_ref(nvc0->base.fence, (struct nouveau_fence **)fence);
PUSH_KICK(nvc0->base.pushbuf); /* fencing handled in kick_notify */
@@ -272,6 +271,7 @@ nvc0_destroy(struct pipe_context *pipe)
free(pos);
}
+ nouveau_fence_cleanup(&nvc0->base);
nouveau_context_destroy(&nvc0->base);
}
@@ -279,12 +279,12 @@ void
nvc0_default_kick_notify(struct nouveau_pushbuf *push)
{
struct nvc0_screen *screen = push->user_priv;
+ struct nvc0_context *nvc0 = screen->cur_ctx;
- if (screen) {
- nouveau_fence_next(&screen->base);
+ if (nvc0) {
+ nouveau_fence_next(&nvc0->base);
nouveau_fence_update(&screen->base, true);
- if (screen->cur_ctx)
- screen->cur_ctx->state.flushed = true;
+ nvc0->state.flushed = true;
NOUVEAU_DRV_STAT(&screen->base, pushbuf_count, 1);
}
}
@@ -549,6 +549,8 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
nvc0->dirty_cp |= NVC0_NEW_CP_SAMPLERS;
}
+ nouveau_fence_new(&nvc0->base, &nvc0->base.fence);
+
return pipe;
out_err:
@@ -579,7 +581,7 @@ nvc0_bufctx_fence(struct nvc0_context *nvc0, struct nouveau_bufctx *bufctx,
struct nouveau_bufref *ref = (struct nouveau_bufref *)it;
struct nv04_resource *res = ref->priv;
if (res)
- nvc0_resource_validate(res, (unsigned)ref->priv_data);
+ nvc0_resource_validate(nvc0, res, (unsigned)ref->priv_data);
NOUVEAU_DRV_STAT_IFD(count++);
}
NOUVEAU_DRV_STAT(&nvc0->screen->base, resource_validate_count, count);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
index 2d8e2f0b38a..bda081d190f 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
@@ -310,6 +310,29 @@ nvc0_shader_stage(unsigned pipe)
}
}
+static inline void
+nvc0_resource_fence(struct nvc0_context *nvc0, struct nv04_resource *res, uint32_t flags)
+{
+ if (res->mm) {
+ nouveau_fence_ref(nvc0->base.fence, &res->fence);
+ if (flags & NOUVEAU_BO_WR)
+ nouveau_fence_ref(nvc0->base.fence, &res->fence_wr);
+ }
+}
+
+static inline void
+nvc0_resource_validate(struct nvc0_context *nvc0, struct nv04_resource *res, uint32_t flags)
+{
+ if (likely(res->bo)) {
+ if (flags & NOUVEAU_BO_WR)
+ res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
+ NOUVEAU_BUFFER_STATUS_DIRTY;
+ if (flags & NOUVEAU_BO_RD)
+ res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
+
+ nvc0_resource_fence(nvc0, res, flags);
+ }
+}
/* nvc0_context.c */
struct pipe_context *nvc0_create(struct pipe_screen *, void *, unsigned flags);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
index a18fdf2e5ac..e4c36a8ee96 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
@@ -44,7 +44,7 @@ nvc0_hw_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q,
if (hq->state == NVC0_HW_QUERY_STATE_READY)
nouveau_mm_free(hq->mm);
else
- nouveau_fence_work(screen->base.fence.current,
+ nouveau_fence_work(nvc0->base.fence,
nouveau_mm_free_work, hq->mm);
}
}
@@ -301,7 +301,7 @@ nvc0_hw_end_query(struct nvc0_context *nvc0, struct nvc0_query *q)
break;
}
if (hq->is64bit)
- nouveau_fence_ref(nvc0->screen->base.fence.current, &hq->fence);
+ nouveau_fence_ref(nvc0->base.fence, &hq->fence);
}
static bool
@@ -412,7 +412,7 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0,
util_range_add(&buf->base, &buf->valid_buffer_range, offset,
offset + (result_type >= PIPE_QUERY_TYPE_I64 ? 8 : 4));
- nvc0_resource_validate(buf, NOUVEAU_BO_WR);
+ nvc0_resource_validate(nvc0, buf, NOUVEAU_BO_WR);
return;
}
@@ -511,7 +511,7 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0,
util_range_add(&buf->base, &buf->valid_buffer_range, offset,
offset + (result_type >= PIPE_QUERY_TYPE_I64 ? 8 : 4));
- nvc0_resource_validate(buf, NOUVEAU_BO_WR);
+ nvc0_resource_validate(nvc0, buf, NOUVEAU_BO_WR);
}
static const struct nvc0_query_funcs hw_query_funcs = {
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 2a0fef63bca..d61568022bd 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -714,8 +714,6 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
if (!nouveau_drm_screen_unref(&screen->base))
return;
- nouveau_fence_cleanup(&screen->base.fence);
-
if (screen->base.pushbuf)
screen->base.pushbuf->user_priv = NULL;
@@ -1572,8 +1570,6 @@ nvc0_screen_create(struct nouveau_device *dev)
if (!nvc0_blitter_create(screen))
goto fail;
- nouveau_fence_new(&screen->base, &screen->base.fence.current);
-
return &screen->base;
fail:
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
index 392980562bd..3a17bbcb3c9 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
@@ -157,32 +157,6 @@ int nvc0_screen_resize_text_area(struct nvc0_screen *, uint64_t);
// 3D Only
void nvc0_screen_bind_cb_3d(struct nvc0_screen *, bool *, int, int, int, uint64_t);
-static inline void
-nvc0_resource_fence(struct nv04_resource *res, uint32_t flags)
-{
- struct nvc0_screen *screen = nvc0_screen(res->base.screen);
-
- if (res->mm) {
- nouveau_fence_ref(screen->base.fence.current, &res->fence);
- if (flags & NOUVEAU_BO_WR)
- nouveau_fence_ref(screen->base.fence.current, &res->fence_wr);
- }
-}
-
-static inline void
-nvc0_resource_validate(struct nv04_resource *res, uint32_t flags)
-{
- if (likely(res->bo)) {
- if (flags & NOUVEAU_BO_WR)
- res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
- NOUVEAU_BUFFER_STATUS_DIRTY;
- if (flags & NOUVEAU_BO_RD)
- res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
-
- nvc0_resource_fence(res, flags);
- }
-}
-
struct nvc0_format {
uint32_t rt;
struct {
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
index 39c518efdef..41d357e5848 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
@@ -253,7 +253,7 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
PUSH_DATA(push, 0);
PUSH_DATA(push, 0);
- nvc0_resource_fence(res, NOUVEAU_BO_WR);
+ nvc0_resource_fence(nvc0, res, NOUVEAU_BO_WR);
assert(!fb->zsbuf);
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
index 5f95c709dec..81b833237f8 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
@@ -348,7 +348,7 @@ nvc0_clear_render_target(struct pipe_context *pipe,
IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 0);
/* tiled textures don't have to be fenced, they're not mapped directly */
- nvc0_resource_fence(res, NOUVEAU_BO_WR);
+ nvc0_resource_fence(nvc0, res, NOUVEAU_BO_WR);
}
if (!render_condition_enabled)
@@ -410,7 +410,7 @@ nvc0_clear_buffer_push_nvc0(struct pipe_context *pipe,
size -= nr * 4;
}
- nvc0_resource_validate(buf, NOUVEAU_BO_WR);
+ nvc0_resource_validate(nvc0, buf, NOUVEAU_BO_WR);
nouveau_bufctx_reset(nvc0->bufctx, 0);
}
@@ -457,7 +457,7 @@ nvc0_clear_buffer_push_nve4(struct pipe_context *pipe,
size -= nr * 4;
}
- nvc0_resource_validate(buf, NOUVEAU_BO_WR);
+ nvc0_resource_validate(nvc0, buf, NOUVEAU_BO_WR);
nouveau_bufctx_reset(nvc0->bufctx, 0);
}
@@ -604,7 +604,7 @@ nvc0_clear_buffer(struct pipe_context *pipe,
IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode);
- nvc0_resource_validate(buf, NOUVEAU_BO_WR);
+ nvc0_resource_validate(nvc0, buf, NOUVEAU_BO_WR);
if (width * height != elements) {
offset += width * height * data_size;
@@ -1589,8 +1589,8 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
PUSH_DATA (push, srcy >> 32);
}
}
- nvc0_resource_validate(&dst->base, NOUVEAU_BO_WR);
- nvc0_resource_validate(&src->base, NOUVEAU_BO_RD);
+ nvc0_resource_validate(nvc0, &dst->base, NOUVEAU_BO_WR);
+ nvc0_resource_validate(nvc0, &src->base, NOUVEAU_BO_RD);
nouveau_bufctx_reset(nvc0->bufctx, NVC0_BIND_2D);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
index c5aab3075df..7a2531e68e1 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
@@ -521,7 +521,7 @@ nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_transfers_wr, 1);
/* Allow the copies above to finish executing before freeing the source */
- nouveau_fence_work(nvc0->screen->base.fence.current,
+ nouveau_fence_work(nvc0->base.fence,
nouveau_fence_unref_bo, tx->rect[1].bo);
} else {
nouveau_bo_ref(NULL, &tx->rect[1].bo);
--
2.37.3
From 5a7c68d03baea7c9b55d431f1bb149f300e56ee2 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Wed, 11 May 2022 02:32:52 +0200
Subject: [PATCH 14/17] nouveau: per context client and pushbuf
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>
---
src/gallium/drivers/nouveau/nouveau_context.h | 6 +-
src/gallium/drivers/nouveau/nouveau_fence.c | 7 +-
src/gallium/drivers/nouveau/nouveau_fence.h | 2 +-
src/gallium/drivers/nouveau/nouveau_screen.c | 69 ++++++++++++++++---
src/gallium/drivers/nouveau/nouveau_screen.h | 11 +++
src/gallium/drivers/nouveau/nouveau_video.c | 4 +-
.../drivers/nouveau/nouveau_vp3_video.c | 4 +-
src/gallium/drivers/nouveau/nv30/nv30_clear.c | 1 +
.../drivers/nouveau/nv30/nv30_context.c | 24 +++----
src/gallium/drivers/nouveau/nv30/nv30_draw.c | 1 +
.../drivers/nouveau/nv30/nv30_fragprog.c | 1 +
.../drivers/nouveau/nv30/nv30_fragtex.c | 1 +
.../drivers/nouveau/nv30/nv30_miptree.c | 1 +
src/gallium/drivers/nouveau/nv30/nv30_push.c | 1 +
src/gallium/drivers/nouveau/nv30/nv30_query.c | 1 +
.../drivers/nouveau/nv30/nv30_screen.c | 8 ++-
.../drivers/nouveau/nv30/nv30_screen.h | 1 -
.../nouveau/nv30/nv30_state_validate.c | 2 +-
.../drivers/nouveau/nv30/nv30_transfer.c | 1 +
src/gallium/drivers/nouveau/nv30/nv30_vbo.c | 2 +-
.../drivers/nouveau/nv30/nv30_vertprog.c | 1 +
.../drivers/nouveau/nv30/nv30_winsys.h | 6 +-
.../drivers/nouveau/nv30/nv40_verttex.c | 1 +
.../drivers/nouveau/nv50/nv50_context.c | 22 +++---
.../drivers/nouveau/nv50/nv50_context.h | 2 +-
.../drivers/nouveau/nv50/nv50_screen.c | 11 ++-
src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 10 ++-
src/gallium/drivers/nouveau/nv50/nv84_video.c | 12 ++--
src/gallium/drivers/nouveau/nv50/nv98_video.c | 4 +-
.../drivers/nouveau/nvc0/nvc0_context.c | 24 +++----
.../drivers/nouveau/nvc0/nvc0_context.h | 2 +-
.../drivers/nouveau/nvc0/nvc0_program.c | 2 +-
.../drivers/nouveau/nvc0/nvc0_screen.c | 27 +++-----
.../drivers/nouveau/nvc0/nvc0_screen.h | 4 +-
.../nouveau/nvc0/nvc0_state_validate.c | 9 +--
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c | 12 ++--
src/gallium/drivers/nouveau/nvc0/nvc0_video.c | 4 +-
37 files changed, 183 insertions(+), 118 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_context.h b/src/gallium/drivers/nouveau/nouveau_context.h
index e6cd7657913..b4c88c18e84 100644
--- a/src/gallium/drivers/nouveau/nouveau_context.h
+++ b/src/gallium/drivers/nouveau/nouveau_context.h
@@ -16,6 +16,7 @@ struct nouveau_context {
struct nouveau_client *client;
struct nouveau_pushbuf *pushbuf;
struct nouveau_fence *fence;
+ void (*kick_notify)(struct nouveau_context *);
struct util_debug_callback debug;
bool vbo_dirty;
@@ -66,7 +67,7 @@ nouveau_context(struct pipe_context *pipe)
void
nouveau_context_init_vdec(struct nouveau_context *);
-void
+int MUST_CHECK
nouveau_context_init(struct nouveau_context *, struct nouveau_screen *);
void
@@ -100,6 +101,9 @@ nouveau_context_destroy(struct nouveau_context *ctx)
if (ctx->scratch.bo[i])
nouveau_bo_ref(NULL, &ctx->scratch.bo[i]);
+ nouveau_pushbuf_destroy(&ctx->pushbuf);
+ nouveau_client_del(&ctx->client);
+
FREE(ctx);
}
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c
index 96b324d89cf..05808ebd68e 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.c
+++ b/src/gallium/drivers/nouveau/nouveau_fence.c
@@ -79,7 +79,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
fence_list->tail = fence;
- fence_list->emit(&screen->base, &fence->sequence);
+ fence_list->emit(&fence->context->pipe, &fence->sequence);
assert(fence->state == NOUVEAU_FENCE_STATE_EMITTING);
fence->state = NOUVEAU_FENCE_STATE_EMITTED;
@@ -189,6 +189,7 @@ nouveau_fence_signalled(struct nouveau_fence *fence)
static bool
nouveau_fence_kick(struct nouveau_fence *fence)
{
+ struct nouveau_context *context = fence->context;
struct nouveau_screen *screen = fence->screen;
bool current = !fence->sequence;
@@ -196,12 +197,12 @@ nouveau_fence_kick(struct nouveau_fence *fence)
assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
if (fence->state < NOUVEAU_FENCE_STATE_EMITTED) {
- PUSH_SPACE(screen->pushbuf, 8);
+ PUSH_SPACE(context->pushbuf, 8);
nouveau_fence_emit(fence);
}
if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
- if (nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel))
+ if (nouveau_pushbuf_kick(context->pushbuf, context->pushbuf->channel))
return false;
if (current)
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h
index 2ea996521b1..49e74bfc52c 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.h
+++ b/src/gallium/drivers/nouveau/nouveau_fence.h
@@ -35,7 +35,7 @@ struct nouveau_fence_list {
struct nouveau_fence *tail;
uint32_t sequence;
uint32_t sequence_ack;
- void (*emit)(struct pipe_screen *, uint32_t *sequence);
+ void (*emit)(struct pipe_context *, uint32_t *sequence);
uint32_t (*update)(struct pipe_screen *);
};
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index ac69b9d3968..37d14bee8fd 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -187,6 +187,48 @@ reserve_vma(uintptr_t start, uint64_t reserved_size)
return reserved;
}
+static void
+nouveau_pushbuf_cb(struct nouveau_pushbuf *push)
+{
+ struct nouveau_pushbuf_priv *p = (struct nouveau_pushbuf_priv *)push->user_priv;
+
+ if (p->context)
+ p->context->kick_notify(p->context);
+ else
+ nouveau_fence_update(p->screen, true);
+
+ NOUVEAU_DRV_STAT(p->screen, pushbuf_count, 1);
+}
+
+int
+nouveau_pushbuf_create(struct nouveau_screen *screen, struct nouveau_context *context,
+ struct nouveau_client *client, struct nouveau_object *chan, int nr,
+ uint32_t size, bool immediate, struct nouveau_pushbuf **push)
+{
+ int ret;
+ ret = nouveau_pushbuf_new(client, chan, nr, size, immediate, push);
+ if (ret)
+ return ret;
+
+ struct nouveau_pushbuf_priv *p = MALLOC_STRUCT(nouveau_pushbuf_priv);
+ if (!p) {
+ nouveau_pushbuf_del(push);
+ return -ENOMEM;
+ }
+ p->screen = screen;
+ p->context = context;
+ (*push)->kick_notify = nouveau_pushbuf_cb;
+ (*push)->user_priv = p;
+ return 0;
+}
+
+void
+nouveau_pushbuf_destroy(struct nouveau_pushbuf **push)
+{
+ FREE((*push)->user_priv);
+ nouveau_pushbuf_del(push);
+}
+
int
nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
{
@@ -301,9 +343,9 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
ret = nouveau_client_new(screen->device, &screen->client);
if (ret)
goto err;
- ret = nouveau_pushbuf_new(screen->client, screen->channel,
- 4, 512 * 1024, 1,
- &screen->pushbuf);
+ ret = nouveau_pushbuf_create(screen, NULL, screen->client, screen->channel,
+ 4, 512 * 1024, 1,
+ &screen->pushbuf);
if (ret)
goto err;
@@ -368,7 +410,7 @@ nouveau_screen_fini(struct nouveau_screen *screen)
nouveau_mm_destroy(screen->mm_GART);
nouveau_mm_destroy(screen->mm_VRAM);
- nouveau_pushbuf_del(&screen->pushbuf);
+ nouveau_pushbuf_destroy(&screen->pushbuf);
nouveau_client_del(&screen->client);
nouveau_object_del(&screen->channel);
@@ -392,12 +434,23 @@ nouveau_set_debug_callback(struct pipe_context *pipe,
memset(&context->debug, 0, sizeof(context->debug));
}
-void
+int
nouveau_context_init(struct nouveau_context *context, struct nouveau_screen *screen)
{
- context->pipe.set_debug_callback = nouveau_set_debug_callback;
+ int ret;
+ context->pipe.set_debug_callback = nouveau_set_debug_callback;
context->screen = screen;
- context->client = screen->client;
- context->pushbuf = screen->pushbuf;
+
+ ret = nouveau_client_new(screen->device, &context->client);
+ if (ret)
+ return ret;
+
+ ret = nouveau_pushbuf_create(screen, context, context->client, screen->channel,
+ 4, 512 * 1024, 1,
+ &context->pushbuf);
+ if (ret)
+ return ret;
+
+ return 0;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index 100e9b207b2..eafeeb91b7e 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -110,6 +110,11 @@ struct nouveau_screen {
#endif
};
+struct nouveau_pushbuf_priv {
+ struct nouveau_screen *screen;
+ struct nouveau_context *context;
+};
+
#define NV_VRAM_DOMAIN(screen) ((screen)->vram_domain)
#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
@@ -150,4 +155,10 @@ void nouveau_screen_fini(struct nouveau_screen *);
void nouveau_screen_init_vdec(struct nouveau_screen *);
+int
+nouveau_pushbuf_create(struct nouveau_screen *, struct nouveau_context *, struct nouveau_client *,
+ struct nouveau_object *chan, int nr, uint32_t size, bool immediate,
+ struct nouveau_pushbuf **);
+void nouveau_pushbuf_destroy(struct nouveau_pushbuf **);
+
#endif
diff --git a/src/gallium/drivers/nouveau/nouveau_video.c b/src/gallium/drivers/nouveau/nouveau_video.c
index 9637f39c8e2..a5596f980a5 100644
--- a/src/gallium/drivers/nouveau/nouveau_video.c
+++ b/src/gallium/drivers/nouveau/nouveau_video.c
@@ -486,7 +486,7 @@ nouveau_decoder_destroy(struct pipe_video_codec *decoder)
if (dec->bufctx)
nouveau_bufctx_del(&dec->bufctx);
if (dec->push)
- nouveau_pushbuf_del(&dec->push);
+ nouveau_pushbuf_destroy(&dec->push);
if (dec->client)
nouveau_client_del(&dec->client);
if (dec->chan)
@@ -532,7 +532,7 @@ nouveau_create_decoder(struct pipe_context *context,
ret = nouveau_client_new(screen->device, &dec->client);
if (ret)
goto fail;
- ret = nouveau_pushbuf_new(dec->client, dec->chan, 2, 4096, 1, &dec->push);
+ ret = nouveau_pushbuf_create(screen, nouveau_context(context), dec->client, dec->chan, 2, 4096, 1, &dec->push);
if (ret)
goto fail;
ret = nouveau_bufctx_new(dec->client, NV31_VIDEO_BIND_COUNT, &dec->bufctx);
diff --git a/src/gallium/drivers/nouveau/nouveau_vp3_video.c b/src/gallium/drivers/nouveau/nouveau_vp3_video.c
index b3d93a69195..02cbe246520 100644
--- a/src/gallium/drivers/nouveau/nouveau_vp3_video.c
+++ b/src/gallium/drivers/nouveau/nouveau_vp3_video.c
@@ -214,11 +214,11 @@ nouveau_vp3_decoder_destroy(struct pipe_video_codec *decoder)
if (dec->channel[0] != dec->channel[1]) {
for (i = 0; i < 3; ++i) {
- nouveau_pushbuf_del(&dec->pushbuf[i]);
+ nouveau_pushbuf_destroy(&dec->pushbuf[i]);
nouveau_object_del(&dec->channel[i]);
}
} else {
- nouveau_pushbuf_del(dec->pushbuf);
+ nouveau_pushbuf_destroy(dec->pushbuf);
nouveau_object_del(dec->channel);
}
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_clear.c b/src/gallium/drivers/nouveau/nv30/nv30_clear.c
index 2b8ea9700cf..7122858b9d1 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_clear.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_clear.c
@@ -30,6 +30,7 @@
#include "nv_object.xml.h"
#include "nv30/nv30-40_3d.xml.h"
#include "nv30/nv30_context.h"
+#include "nv30/nv30_winsys.h"
#include "nv30/nv30_format.h"
static inline uint32_t
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_context.c b/src/gallium/drivers/nouveau/nv30/nv30_context.c
index 3f25855d045..50c5071b266 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_context.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_context.c
@@ -33,19 +33,15 @@
#include "nv30/nv30_context.h"
#include "nv30/nv30_transfer.h"
#include "nv30/nv30_state.h"
+#include "nv30/nv30_winsys.h"
static void
nv30_context_kick_notify(struct nouveau_pushbuf *push)
{
- struct nouveau_screen *screen;
- struct nv30_context *nv30;
+ struct nouveau_pushbuf_priv *p = push->user_priv;
+ struct nouveau_screen *screen = p->screen;
- if (!push->user_priv)
- return;
- nv30 = container_of(push->user_priv, struct nv30_context, bufctx);
- screen = &nv30->screen->base;
-
- nouveau_fence_next(&nv30->base);
+ nouveau_fence_next(p->context);
nouveau_fence_update(screen, true);
if (push->bufctx) {
@@ -53,13 +49,13 @@ nv30_context_kick_notify(struct nouveau_pushbuf *push)
LIST_FOR_EACH_ENTRY(bref, &push->bufctx->current, thead) {
struct nv04_resource *res = bref->priv;
if (res && res->mm) {
- nouveau_fence_ref(nv30->base.fence, &res->fence);
+ nouveau_fence_ref(p->context->fence, &res->fence);
if (bref->flags & NOUVEAU_BO_RD)
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
if (bref->flags & NOUVEAU_BO_WR) {
- nouveau_fence_ref(nv30->base.fence, &res->fence_wr);
+ nouveau_fence_ref(p->context->fence, &res->fence_wr);
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
NOUVEAU_BUFFER_STATUS_DIRTY;
}
@@ -168,9 +164,6 @@ nv30_context_destroy(struct pipe_context *pipe)
if (nv30->blit_fp)
pipe_resource_reference(&nv30->blit_fp, NULL);
- if (nv30->screen->base.pushbuf->user_priv == &nv30->bufctx)
- nv30->screen->base.pushbuf->user_priv = NULL;
-
nouveau_bufctx_del(&nv30->bufctx);
if (nv30->screen->cur_ctx == nv30)
@@ -207,7 +200,10 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
pipe->destroy = nv30_context_destroy;
pipe->flush = nv30_context_flush;
- nouveau_context_init(&nv30->base, &screen->base);
+ if (nouveau_context_init(&nv30->base, &screen->base)) {
+ nv30_context_destroy(pipe);
+ return NULL;
+ }
nv30->base.pushbuf->kick_notify = nv30_context_kick_notify;
nv30->base.pipe.stream_uploader = u_upload_create_default(&nv30->base.pipe);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_draw.c b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
index 0a08bda700d..0aafb506cb4 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_draw.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
@@ -33,6 +33,7 @@
#include "nv30/nv30-40_3d.xml.h"
#include "nv30/nv30_context.h"
#include "nv30/nv30_format.h"
+#include "nv30/nv30_winsys.h"
struct nv30_render {
struct vbuf_render base;
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
index 55857781f5f..9bc55b60a61 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
@@ -30,6 +30,7 @@
#include "nv_object.xml.h"
#include "nv30/nv30-40_3d.xml.h"
#include "nv30/nv30_context.h"
+#include "nv30/nv30_winsys.h"
#include "nv30/nvfx_shader.h"
static void
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_fragtex.c b/src/gallium/drivers/nouveau/nv30/nv30_fragtex.c
index 1a06eac4746..a46c4c4f1d9 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_fragtex.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_fragtex.c
@@ -29,6 +29,7 @@
#include "nv30/nv30-40_3d.xml.h"
#include "nv30/nv30_context.h"
#include "nv30/nv30_format.h"
+#include "nv30/nv30_winsys.h"
void
nv30_fragtex_validate(struct nv30_context *nv30)
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
index 992a5d41d57..f712134f6cc 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
@@ -33,6 +33,7 @@
#include "nv30/nv30_context.h"
#include "nv30/nv30_resource.h"
#include "nv30/nv30_transfer.h"
+#include "nv30/nv30_winsys.h"
static inline unsigned
layer_offset(struct pipe_resource *pt, unsigned level, unsigned layer)
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_push.c b/src/gallium/drivers/nouveau/nv30/nv30_push.c
index 4bd799c39f9..7b762bcb054 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_push.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_push.c
@@ -33,6 +33,7 @@
#include "nv30/nv30-40_3d.xml.h"
#include "nv30/nv30_context.h"
#include "nv30/nv30_resource.h"
+#include "nv30/nv30_winsys.h"
struct push_context {
struct nouveau_pushbuf *push;
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_query.c b/src/gallium/drivers/nouveau/nv30/nv30_query.c
index 1335cb99b12..f15184f232f 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_query.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_query.c
@@ -27,6 +27,7 @@
#include "nv30/nv30-40_3d.xml.h"
#include "nv30/nv30_screen.h"
#include "nv30/nv30_context.h"
+#include "nv30/nv30_winsys.h"
struct nv30_query_object {
struct list_head list;
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
index 0ffd726102a..4dfcd76e4f1 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -39,6 +39,7 @@
#include "nv30/nv30_context.h"
#include "nv30/nv30_resource.h"
#include "nv30/nv30_format.h"
+#include "nv30/nv30_winsys.h"
#define RANKINE_0397_CHIPSET 0x00000003
#define RANKINE_0497_CHIPSET 0x000001e0
@@ -519,10 +520,11 @@ nv30_screen_get_compiler_options(struct pipe_screen *pscreen,
}
static void
-nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence)
+nv30_screen_fence_emit(struct pipe_context *pcontext, uint32_t *sequence)
{
- struct nv30_screen *screen = nv30_screen(pscreen);
- struct nouveau_pushbuf *push = screen->base.pushbuf;
+ struct nv30_context *nv30 = nv30_context(pcontext);
+ struct nv30_screen *screen = nv30->screen;
+ struct nouveau_pushbuf *push = nv30->base.pushbuf;
*sequence = ++screen->base.fence.sequence;
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.h b/src/gallium/drivers/nouveau/nv30/nv30_screen.h
index c61a1ece54b..f0bc3683685 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.h
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.h
@@ -9,7 +9,6 @@
#include "nouveau_screen.h"
#include "nouveau_fence.h"
#include "nouveau_heap.h"
-#include "nv30/nv30_winsys.h"
#include "nv30/nv30_resource.h"
#include "compiler/nir/nir.h"
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c b/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
index 66f19f5906f..8de11ab67d0 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_state_validate.c
@@ -31,6 +31,7 @@
#include "nv30/nv30-40_3d.xml.h"
#include "nv30/nv30_context.h"
#include "nv30/nv30_format.h"
+#include "nv30/nv30_winsys.h"
static void
nv30_validate_fb(struct nv30_context *nv30)
@@ -457,7 +458,6 @@ nv30_state_context_switch(struct nv30_context *nv30)
nv30->dirty &= ~NV30_NEW_ZSA;
nv30->screen->cur_ctx = nv30;
- nv30->base.pushbuf->user_priv = &nv30->bufctx;
}
bool
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
index c78b896a729..c5f5866af6b 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_transfer.c
@@ -36,6 +36,7 @@
#include "nv30/nv30_context.h"
#include "nv30/nv30_transfer.h"
+#include "nv30/nv30_winsys.h"
/* Various helper functions to transfer different types of data in a number
* of different ways.
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
index 3e24e90c735..22e309eb773 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
@@ -34,6 +34,7 @@
#include "nv30/nv30-40_3d.xml.h"
#include "nv30/nv30_context.h"
#include "nv30/nv30_format.h"
+#include "nv30/nv30_winsys.h"
static void
nv30_emit_vtxattr(struct nv30_context *nv30, struct pipe_vertex_buffer *vb,
@@ -586,7 +587,6 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
if (nv30->vbo_push_hint != !!nv30->vbo_fifo)
nv30->dirty |= NV30_NEW_ARRAYS;
- push->user_priv = &nv30->bufctx;
if (nv30->vbo_user && !(nv30->dirty & (NV30_NEW_VERTEX | NV30_NEW_ARRAYS)))
nv30_update_user_vbufs(nv30);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c b/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c
index 3866709c138..53e64a38722 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_vertprog.c
@@ -33,6 +33,7 @@
#include "nv30/nv30_context.h"
#include "nv30/nvfx_shader.h"
#include "nv30/nv30_state.h"
+#include "nv30/nv30_winsys.h"
static void
nv30_vertprog_destroy(struct nv30_vertprog *vp)
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_winsys.h b/src/gallium/drivers/nouveau/nv30/nv30_winsys.h
index 25897ea9f6b..a72af87c9b6 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_winsys.h
+++ b/src/gallium/drivers/nouveau/nv30/nv30_winsys.h
@@ -3,7 +3,9 @@
#include <string.h>
#include "nouveau_winsys.h"
+#include "nouveau_context.h"
#include "nouveau_buffer.h"
+#include "nv30_context.h"
/*XXX: rnn */
#define NV40_3D_VTXTEX_OFFSET(i) (0x0900 + ((i) * 0x20)) // 401e80
@@ -29,8 +31,8 @@ PUSH_RELOC(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t offset,
static inline struct nouveau_bufctx *
bufctx(struct nouveau_pushbuf *push)
{
- struct nouveau_bufctx **pctx = push->user_priv;
- return *pctx;
+ struct nouveau_pushbuf_priv *p = push->user_priv;
+ return nv30_context(&p->context->pipe)->bufctx;
}
static inline void
diff --git a/src/gallium/drivers/nouveau/nv30/nv40_verttex.c b/src/gallium/drivers/nouveau/nv30/nv40_verttex.c
index 578695a22ab..04f428ea6ac 100644
--- a/src/gallium/drivers/nouveau/nv30/nv40_verttex.c
+++ b/src/gallium/drivers/nouveau/nv30/nv40_verttex.c
@@ -25,6 +25,7 @@
#include "util/u_inlines.h"
#include "nv30/nv30_context.h"
+#include "nv30/nv30_winsys.h"
void
nv40_verttex_validate(struct nv30_context *nv30)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c
index 9fd5f08be4c..bbc4131a499 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c
@@ -132,16 +132,13 @@ nv50_emit_string_marker(struct pipe_context *pipe, const char *str, int len)
}
void
-nv50_default_kick_notify(struct nouveau_pushbuf *push)
+nv50_default_kick_notify(struct nouveau_context *context)
{
- struct nv50_screen *screen = push->user_priv;
- struct nv50_context *context = screen->cur_ctx;
+ struct nv50_context *nv50 = nv50_context(&context->pipe);
- if (context) {
- nouveau_fence_next(&context->base);
- nouveau_fence_update(&screen->base, true);
- context->state.flushed = true;
- }
+ nouveau_fence_next(context);
+ nouveau_fence_update(context->screen, true);
+ nv50->state.flushed = true;
}
static void
@@ -313,7 +310,8 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
if (!nv50_blitctx_create(nv50))
goto out_err;
- nouveau_context_init(&nv50->base, &screen->base);
+ if (nouveau_context_init(&nv50->base, &screen->base))
+ goto out_err;
ret = nouveau_bufctx_new(nv50->base.client, 2, &nv50->bufctx);
if (!ret)
@@ -355,9 +353,11 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
*/
nv50->state = screen->save_state;
screen->cur_ctx = nv50;
- nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx);
}
- nv50->base.pushbuf->kick_notify = nv50_default_kick_notify;
+ nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx);
+ nv50->base.kick_notify = nv50_default_kick_notify;
+ nv50->base.pushbuf->rsvd_kick = 5;
+ PUSH_SPACE(nv50->base.pushbuf, 8);
nv50_init_query_functions(nv50);
nv50_init_surface_functions(nv50);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h
index dd3333a9dd2..5173d8d1f44 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h
@@ -277,7 +277,7 @@ struct pipe_context *nv50_create(struct pipe_screen *, void *, unsigned flags);
void nv50_bufctx_fence(struct nv50_context *, struct nouveau_bufctx *, bool on_flush);
-void nv50_default_kick_notify(struct nouveau_pushbuf *);
+void nv50_default_kick_notify(struct nouveau_context *);
/* nv50_draw.c */
extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index 96607b2ef6a..79a57e5b5fa 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -622,9 +622,6 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
if (!nouveau_drm_screen_unref(&screen->base))
return;
- if (screen->base.pushbuf)
- screen->base.pushbuf->user_priv = NULL;
-
if (screen->blitter)
nv50_blitter_destroy(screen);
if (screen->pm.prog) {
@@ -658,10 +655,11 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
}
static void
-nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
+nv50_screen_fence_emit(struct pipe_context *pcontext, u32 *sequence)
{
- struct nv50_screen *screen = nv50_screen(pscreen);
- struct nouveau_pushbuf *push = screen->base.pushbuf;
+ struct nv50_context *nv50 = nv50_context(pcontext);
+ struct nv50_screen *screen = nv50->screen;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
/* we need to do it after possible flush in MARK_RING */
*sequence = ++screen->base.fence.sequence;
@@ -1027,7 +1025,6 @@ nv50_screen_create(struct nouveau_device *dev)
screen->base.sysmem_bindings |=
PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER;
- screen->base.pushbuf->user_priv = screen;
screen->base.pushbuf->rsvd_kick = 5;
chan = screen->base.channel;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index b8ea652a727..f2aebccb235 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
@@ -747,11 +747,9 @@ nva0_draw_stream_output(struct nv50_context *nv50,
}
static void
-nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan)
+nv50_draw_vbo_kick_notify(struct nouveau_context *context)
{
- struct nv50_screen *screen = chan->user_priv;
-
- nouveau_fence_update(&screen->base, true);
+ nouveau_fence_update(context->screen, true);
}
void
@@ -815,7 +813,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
nv50_state_validate_3d(nv50, ~0);
- push->kick_notify = nv50_draw_vbo_kick_notify;
+ nv50->base.kick_notify = nv50_draw_vbo_kick_notify;
for (s = 0; s < NV50_MAX_3D_SHADER_STAGES && !nv50->cb_dirty; ++s) {
if (nv50->constbuf_coherent[s])
@@ -922,7 +920,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
}
cleanup:
- push->kick_notify = nv50_default_kick_notify;
+ nv50->base.kick_notify = nv50_default_kick_notify;
nv50_release_user_vbufs(nv50);
diff --git a/src/gallium/drivers/nouveau/nv50/nv84_video.c b/src/gallium/drivers/nouveau/nv50/nv84_video.c
index 41f74a66770..f013d57c6f2 100644
--- a/src/gallium/drivers/nouveau/nv50/nv84_video.c
+++ b/src/gallium/drivers/nouveau/nv50/nv84_video.c
@@ -249,11 +249,11 @@ nv84_decoder_destroy(struct pipe_video_codec *decoder)
nouveau_object_del(&dec->vp);
nouveau_bufctx_del(&dec->bsp_bufctx);
- nouveau_pushbuf_del(&dec->bsp_pushbuf);
+ nouveau_pushbuf_destroy(&dec->bsp_pushbuf);
nouveau_object_del(&dec->bsp_channel);
nouveau_bufctx_del(&dec->vp_bufctx);
- nouveau_pushbuf_del(&dec->vp_pushbuf);
+ nouveau_pushbuf_destroy(&dec->vp_pushbuf);
nouveau_object_del(&dec->vp_channel);
nouveau_client_del(&dec->client);
@@ -337,8 +337,8 @@ nv84_create_decoder(struct pipe_context *context,
if (ret)
goto fail;
- ret = nouveau_pushbuf_new(dec->client, dec->bsp_channel, 4,
- 32 * 1024, true, &dec->bsp_pushbuf);
+ ret = nouveau_pushbuf_create(screen, &nv50->base, dec->client, dec->bsp_channel,
+ 4, 32 * 1024, true, &dec->bsp_pushbuf);
if (ret)
goto fail;
@@ -352,8 +352,8 @@ nv84_create_decoder(struct pipe_context *context,
&nv04_data, sizeof(nv04_data), &dec->vp_channel);
if (ret)
goto fail;
- ret = nouveau_pushbuf_new(dec->client, dec->vp_channel, 4,
- 32 * 1024, true, &dec->vp_pushbuf);
+ ret = nouveau_pushbuf_create(screen, &nv50->base, dec->client, dec->vp_channel,
+ 4, 32 * 1024, true, &dec->vp_pushbuf);
if (ret)
goto fail;
diff --git a/src/gallium/drivers/nouveau/nv50/nv98_video.c b/src/gallium/drivers/nouveau/nv50/nv98_video.c
index 07cb05550b1..44e6f26daad 100644
--- a/src/gallium/drivers/nouveau/nv50/nv98_video.c
+++ b/src/gallium/drivers/nouveau/nv50/nv98_video.c
@@ -120,8 +120,8 @@ nv98_create_decoder(struct pipe_context *context,
&nv04_data, sizeof(nv04_data), &dec->channel[0]);
if (!ret)
- ret = nouveau_pushbuf_new(nv50->base.client, dec->channel[0], 4,
- 32 * 1024, true, &dec->pushbuf[0]);
+ ret = nouveau_pushbuf_create(screen, &nv50->base, nv50->base.client, dec->channel[0],
+ 4, 32 * 1024, true, &dec->pushbuf[0]);
for (i = 1; i < 3; ++i) {
dec->channel[i] = dec->channel[0];
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
index adc36531b28..1fd77b1db64 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
@@ -276,17 +276,14 @@ nvc0_destroy(struct pipe_context *pipe)
}
void
-nvc0_default_kick_notify(struct nouveau_pushbuf *push)
+nvc0_default_kick_notify(struct nouveau_context *context)
{
- struct nvc0_screen *screen = push->user_priv;
- struct nvc0_context *nvc0 = screen->cur_ctx;
+ struct nvc0_context *nvc0 = nvc0_context(&context->pipe);
- if (nvc0) {
- nouveau_fence_next(&nvc0->base);
- nouveau_fence_update(&screen->base, true);
- nvc0->state.flushed = true;
- NOUVEAU_DRV_STAT(&screen->base, pushbuf_count, 1);
- }
+ nouveau_fence_next(context);
+ nouveau_fence_update(context->screen, true);
+
+ nvc0->state.flushed = true;
}
static int
@@ -425,7 +422,10 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
if (!nvc0_blitctx_create(nvc0))
goto out_err;
- nouveau_context_init(&nvc0->base, &screen->base);
+ if (nouveau_context_init(&nvc0->base, &screen->base))
+ goto out_err;
+ nvc0->base.kick_notify = nvc0_default_kick_notify;
+ nvc0->base.pushbuf->rsvd_kick = 5;
ret = nouveau_bufctx_new(nvc0->base.client, 2, &nvc0->bufctx);
if (!ret)
@@ -496,9 +496,9 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
if (!screen->cur_ctx) {
nvc0->state = screen->save_state;
screen->cur_ctx = nvc0;
- nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx);
}
- screen->base.pushbuf->kick_notify = nvc0_default_kick_notify;
+ nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx);
+ PUSH_SPACE(nvc0->base.pushbuf, 8);
/* add permanently resident buffers to bufctxts */
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
index bda081d190f..6711e950e25 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
@@ -338,7 +338,7 @@ nvc0_resource_validate(struct nvc0_context *nvc0, struct nv04_resource *res, uin
struct pipe_context *nvc0_create(struct pipe_screen *, void *, unsigned flags);
void nvc0_bufctx_fence(struct nvc0_context *, struct nouveau_bufctx *,
bool on_flush);
-void nvc0_default_kick_notify(struct nouveau_pushbuf *);
+void nvc0_default_kick_notify(struct nouveau_context *);
const void *nvc0_get_sample_locations(unsigned);
/* nvc0_draw.c */
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
index ff89fb6b461..86dd15520a5 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
@@ -905,7 +905,7 @@ nvc0_program_upload(struct nvc0_context *nvc0, struct nvc0_program *prog)
IMMED_NVC0(nvc0->base.pushbuf, NVC0_3D(SERIALIZE), 0);
if ((screen->text->size << 1) <= (1 << 23)) {
- ret = nvc0_screen_resize_text_area(screen, screen->text->size << 1);
+ ret = nvc0_screen_resize_text_area(screen, nvc0->base.pushbuf, screen->text->size << 1);
if (ret) {
NOUVEAU_ERR("Error allocating TEXT area: %d\n", ret);
return false;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index d61568022bd..64353bcdf39 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -714,9 +714,6 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
if (!nouveau_drm_screen_unref(&screen->base))
return;
- if (screen->base.pushbuf)
- screen->base.pushbuf->user_priv = NULL;
-
if (screen->blitter)
nvc0_blitter_destroy(screen);
if (screen->pm.prog) {
@@ -858,10 +855,11 @@ nvc0_magic_3d_init(struct nouveau_pushbuf *push, uint16_t obj_class)
}
static void
-nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
+nvc0_screen_fence_emit(struct pipe_context *pcontext, u32 *sequence)
{
- struct nvc0_screen *screen = nvc0_screen(pscreen);
- struct nouveau_pushbuf *push = screen->base.pushbuf;
+ struct nvc0_context *nvc0 = nvc0_context(pcontext);
+ struct nvc0_screen *screen = nvc0->screen;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
/* we need to do it after possible flush in MARK_RING */
*sequence = ++screen->base.fence.sequence;
@@ -941,9 +939,9 @@ nvc0_screen_resize_tls_area(struct nvc0_screen *screen,
}
int
-nvc0_screen_resize_text_area(struct nvc0_screen *screen, uint64_t size)
+nvc0_screen_resize_text_area(struct nvc0_screen *screen, struct nouveau_pushbuf *push,
+ uint64_t size)
{
- struct nouveau_pushbuf *push = screen->base.pushbuf;
struct nouveau_bo *bo;
int ret;
@@ -956,7 +954,7 @@ nvc0_screen_resize_text_area(struct nvc0_screen *screen, uint64_t size)
* segment, as it may have commands that will reference it.
*/
if (screen->text)
- PUSH_REF1(push, screen->text,
+ PUSH_REF1(screen->base.pushbuf, screen->text,
NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD);
nouveau_bo_ref(NULL, &screen->text);
screen->text = bo;
@@ -985,13 +983,11 @@ nvc0_screen_resize_text_area(struct nvc0_screen *screen, uint64_t size)
}
void
-nvc0_screen_bind_cb_3d(struct nvc0_screen *screen, bool *can_serialize,
- int stage, int index, int size, uint64_t addr)
+nvc0_screen_bind_cb_3d(struct nvc0_screen *screen, struct nouveau_pushbuf *push,
+ bool *can_serialize, int stage, int index, int size, uint64_t addr)
{
assert(stage != 5);
- struct nouveau_pushbuf *push = screen->base.pushbuf;
-
if (screen->base.class_3d >= GM107_3D_CLASS) {
struct nvc0_cb_binding *binding = &screen->cb_bindings[stage][index];
@@ -1076,7 +1072,6 @@ nvc0_screen_create(struct nouveau_device *dev)
FAIL_SCREEN_INIT("Base screen init failed: %d\n", ret);
chan = screen->base.channel;
push = screen->base.pushbuf;
- push->user_priv = screen;
push->rsvd_kick = 5;
/* TODO: could this be higher on Kepler+? how does reclocking vs no
@@ -1309,7 +1304,7 @@ nvc0_screen_create(struct nouveau_device *dev)
nvc0_magic_3d_init(push, screen->eng3d->oclass);
- ret = nvc0_screen_resize_text_area(screen, 1 << 19);
+ ret = nvc0_screen_resize_text_area(screen, push, 1 << 19);
if (ret)
FAIL_SCREEN_INIT("Error allocating TEXT area: %d\n", ret);
@@ -1523,7 +1518,7 @@ nvc0_screen_create(struct nouveau_device *dev)
/* TIC and TSC entries for each unit (nve4+ only) */
/* auxiliary constants (6 user clip planes, base instance id) */
- nvc0_screen_bind_cb_3d(screen, NULL, i, 15, NVC0_CB_AUX_SIZE,
+ nvc0_screen_bind_cb_3d(screen, push, NULL, i, 15, NVC0_CB_AUX_SIZE,
screen->uniform_bo->offset + NVC0_CB_AUX_INFO(i));
if (screen->eng3d->oclass >= NVE4_3D_CLASS) {
unsigned j;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
index 3a17bbcb3c9..3af38b59503 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
@@ -152,10 +152,10 @@ int nvc0_screen_tsc_alloc(struct nvc0_screen *, void *);
int nve4_screen_compute_setup(struct nvc0_screen *, struct nouveau_pushbuf *);
int nvc0_screen_compute_setup(struct nvc0_screen *, struct nouveau_pushbuf *);
-int nvc0_screen_resize_text_area(struct nvc0_screen *, uint64_t);
+int nvc0_screen_resize_text_area(struct nvc0_screen *, struct nouveau_pushbuf *, uint64_t);
// 3D Only
-void nvc0_screen_bind_cb_3d(struct nvc0_screen *, bool *, int, int, int, uint64_t);
+void nvc0_screen_bind_cb_3d(struct nvc0_screen *, struct nouveau_pushbuf *, bool *, int, int, int, uint64_t);
struct nvc0_format {
uint32_t rt;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
index 41d357e5848..3fb69b51208 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
@@ -577,6 +577,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
unsigned s;
bool can_serialize = true;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
for (s = 0; s < 5; ++s) {
while (nvc0->constbuf_dirty[s]) {
@@ -593,7 +594,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
if (!nvc0->state.uniform_buffer_bound[s]) {
nvc0->state.uniform_buffer_bound[s] = true;
- nvc0_screen_bind_cb_3d(nvc0->screen, &can_serialize, s, i,
+ nvc0_screen_bind_cb_3d(nvc0->screen, push, &can_serialize, s, i,
NVC0_MAX_CONSTBUF_SIZE, bo->offset + base);
}
nvc0_cb_bo_push(&nvc0->base, bo, NV_VRAM_DOMAIN(&nvc0->screen->base),
@@ -604,7 +605,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
struct nv04_resource *res =
nv04_resource(nvc0->constbuf[s][i].u.buf);
if (res) {
- nvc0_screen_bind_cb_3d(nvc0->screen, &can_serialize, s, i,
+ nvc0_screen_bind_cb_3d(nvc0->screen, push, &can_serialize, s, i,
nvc0->constbuf[s][i].size,
res->address + nvc0->constbuf[s][i].offset);
@@ -616,7 +617,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
if (i == 0)
nvc0->state.uniform_buffer_bound[s] = false;
} else if (i != 0) {
- nvc0_screen_bind_cb_3d(nvc0->screen, &can_serialize, s, i, -1, 0);
+ nvc0_screen_bind_cb_3d(nvc0->screen, push, &can_serialize, s, i, -1, 0);
}
}
}
@@ -717,7 +718,7 @@ nvc0_validate_driverconst(struct nvc0_context *nvc0)
int i;
for (i = 0; i < 5; ++i)
- nvc0_screen_bind_cb_3d(screen, NULL, i, 15, NVC0_CB_AUX_SIZE,
+ nvc0_screen_bind_cb_3d(screen, nvc0->base.pushbuf, NULL, i, 15, NVC0_CB_AUX_SIZE,
screen->uniform_bo->offset + NVC0_CB_AUX_INFO(i));
nvc0->dirty_cp |= NVC0_NEW_CP_DRIVERCONST;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
index b9ca992ffcb..8f11296f812 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
@@ -557,13 +557,9 @@ nvc0_prim_gl(unsigned prim)
}
static void
-nvc0_draw_vbo_kick_notify(struct nouveau_pushbuf *push)
+nvc0_draw_vbo_kick_notify(struct nouveau_context *context)
{
- struct nvc0_screen *screen = push->user_priv;
-
- nouveau_fence_update(&screen->base, true);
-
- NOUVEAU_DRV_STAT(&screen->base, pushbuf_count, 1);
+ nouveau_fence_update(context->screen, true);
}
static void
@@ -1047,7 +1043,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
nvc0->seamless_cube_map ? NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP : 0);
}
- push->kick_notify = nvc0_draw_vbo_kick_notify;
+ nvc0->base.kick_notify = nvc0_draw_vbo_kick_notify;
for (s = 0; s < 5 && !nvc0->cb_dirty; ++s) {
if (nvc0->constbuf_coherent[s])
@@ -1131,7 +1127,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
}
cleanup:
- push->kick_notify = nvc0_default_kick_notify;
+ nvc0->base.kick_notify = nvc0_default_kick_notify;
nvc0_release_user_vbufs(nvc0);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
index 3ffc4204b81..d2aed4a7030 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_video.c
@@ -161,8 +161,8 @@ nvc0_create_decoder(struct pipe_context *context,
data, size, &dec->channel[i]);
if (!ret)
- ret = nouveau_pushbuf_new(nvc0->base.client, dec->channel[i], 4,
- 32 * 1024, true, &dec->pushbuf[i]);
+ ret = nouveau_pushbuf_create(screen, &nvc0->base, nvc0->base.client, dec->channel[i],
+ 4, 32 * 1024, true, &dec->pushbuf[i]);
if (ret)
break;
}
--
2.37.3
From 8dc30c20a41f886c28f56552c7eb6a8d04a342f9 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Wed, 30 Jun 2021 10:26:35 +0200
Subject: [PATCH 15/17] nouveau: make fencing race free
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>
---
src/gallium/drivers/nouveau/nouveau_fence.c | 145 ++++++++++++++----
src/gallium/drivers/nouveau/nouveau_fence.h | 37 +++--
src/gallium/drivers/nouveau/nouveau_screen.c | 4 +-
src/gallium/drivers/nouveau/nouveau_winsys.h | 33 +++-
.../drivers/nouveau/nv30/nv30_context.c | 8 +-
.../drivers/nouveau/nv50/nv50_context.c | 4 +-
src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 2 +-
.../drivers/nouveau/nvc0/nvc0_context.c | 4 +-
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c | 2 +-
9 files changed, 179 insertions(+), 60 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c
index 05808ebd68e..4ac3fa4f7b6 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.c
+++ b/src/gallium/drivers/nouveau/nouveau_fence.c
@@ -30,6 +30,9 @@
#include <sched.h>
#endif
+static bool
+_nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debug);
+
bool
nouveau_fence_new(struct nouveau_context *nv, struct nouveau_fence **fence)
{
@@ -48,6 +51,8 @@ nouveau_fence_new(struct nouveau_context *nv, struct nouveau_fence **fence)
static void
nouveau_fence_trigger_work(struct nouveau_fence *fence)
{
+ simple_mtx_assert_locked(&fence->screen->fence.lock);
+
struct nouveau_fence_work *work, *tmp;
LIST_FOR_EACH_ENTRY_SAFE(work, tmp, &fence->work, list) {
@@ -57,12 +62,14 @@ nouveau_fence_trigger_work(struct nouveau_fence *fence)
}
}
-void
-nouveau_fence_emit(struct nouveau_fence *fence)
+static void
+_nouveau_fence_emit(struct nouveau_fence *fence)
{
struct nouveau_screen *screen = fence->screen;
struct nouveau_fence_list *fence_list = &screen->fence;
+ simple_mtx_assert_locked(&fence_list->lock);
+
assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
if (fence->state >= NOUVEAU_FENCE_STATE_EMITTED)
return;
@@ -70,7 +77,7 @@ nouveau_fence_emit(struct nouveau_fence *fence)
/* set this now, so that if fence.emit triggers a flush we don't recurse */
fence->state = NOUVEAU_FENCE_STATE_EMITTING;
- ++fence->ref;
+ p_atomic_inc(&fence->ref);
if (fence_list->tail)
fence_list->tail->next = fence;
@@ -85,12 +92,14 @@ nouveau_fence_emit(struct nouveau_fence *fence)
fence->state = NOUVEAU_FENCE_STATE_EMITTED;
}
-void
+static void
nouveau_fence_del(struct nouveau_fence *fence)
{
struct nouveau_fence *it;
struct nouveau_fence_list *fence_list = &fence->screen->fence;
+ simple_mtx_assert_locked(&fence_list->lock);
+
if (fence->state == NOUVEAU_FENCE_STATE_EMITTED ||
fence->state == NOUVEAU_FENCE_STATE_FLUSHED) {
if (fence == fence_list->head) {
@@ -117,26 +126,31 @@ void
nouveau_fence_cleanup(struct nouveau_context *nv)
{
if (nv->fence) {
+ struct nouveau_fence_list *fence_list = &nv->screen->fence;
struct nouveau_fence *current = NULL;
/* nouveau_fence_wait will create a new current fence, so wait on the
* _current_ one, and remove both.
*/
- nouveau_fence_ref(nv->fence, &current);
- nouveau_fence_wait(current, NULL);
- nouveau_fence_ref(NULL, &current);
- nouveau_fence_ref(NULL, &nv->fence);
+ simple_mtx_lock(&fence_list->lock);
+ _nouveau_fence_ref(nv->fence, &current);
+ _nouveau_fence_wait(current, NULL);
+ _nouveau_fence_ref(NULL, &current);
+ _nouveau_fence_ref(NULL, &nv->fence);
+ simple_mtx_unlock(&fence_list->lock);
}
}
void
-nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
+_nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
{
struct nouveau_fence *fence;
struct nouveau_fence *next = NULL;
struct nouveau_fence_list *fence_list = &screen->fence;
u32 sequence = fence_list->update(&screen->base);
+ simple_mtx_assert_locked(&fence_list->lock);
+
/* If running under drm-shim, let all fences be signalled so things run to
* completion (avoids a hang at the end of shader-db).
*/
@@ -154,7 +168,7 @@ nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
fence->state = NOUVEAU_FENCE_STATE_SIGNALLED;
nouveau_fence_trigger_work(fence);
- nouveau_fence_ref(NULL, &fence);
+ _nouveau_fence_ref(NULL, &fence);
if (sequence == fence_list->sequence_ack)
break;
@@ -172,16 +186,18 @@ nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
#define NOUVEAU_FENCE_MAX_SPINS (1 << 31)
-bool
-nouveau_fence_signalled(struct nouveau_fence *fence)
+static bool
+_nouveau_fence_signalled(struct nouveau_fence *fence)
{
struct nouveau_screen *screen = fence->screen;
+ simple_mtx_assert_locked(&screen->fence.lock);
+
if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED)
return true;
if (fence->state >= NOUVEAU_FENCE_STATE_EMITTED)
- nouveau_fence_update(screen, false);
+ _nouveau_fence_update(screen, false);
return fence->state == NOUVEAU_FENCE_STATE_SIGNALLED;
}
@@ -191,36 +207,43 @@ nouveau_fence_kick(struct nouveau_fence *fence)
{
struct nouveau_context *context = fence->context;
struct nouveau_screen *screen = fence->screen;
+ struct nouveau_fence_list *fence_list = &screen->fence;
bool current = !fence->sequence;
+ simple_mtx_assert_locked(&fence_list->lock);
+
/* wtf, someone is waiting on a fence in flush_notify handler? */
assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
if (fence->state < NOUVEAU_FENCE_STATE_EMITTED) {
- PUSH_SPACE(context->pushbuf, 8);
- nouveau_fence_emit(fence);
+ if (PUSH_AVAIL(context->pushbuf) < 16)
+ nouveau_pushbuf_space(context->pushbuf, 16, 0, 0);
+ _nouveau_fence_emit(fence);
}
- if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
+ if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED) {
if (nouveau_pushbuf_kick(context->pushbuf, context->pushbuf->channel))
return false;
+ }
if (current)
- nouveau_fence_next(fence->context);
+ _nouveau_fence_next(fence->context);
- nouveau_fence_update(screen, false);
+ _nouveau_fence_update(screen, false);
return true;
}
-bool
-nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debug)
+static bool
+_nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debug)
{
struct nouveau_screen *screen = fence->screen;
struct nouveau_fence_list *fence_list = &screen->fence;
uint32_t spins = 0;
int64_t start = 0;
+ simple_mtx_assert_locked(&fence_list->lock);
+
if (debug && debug->debug_message)
start = os_time_get_nano();
@@ -243,7 +266,7 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debu
sched_yield();
#endif
- nouveau_fence_update(screen, false);
+ _nouveau_fence_update(screen, false);
} while (spins < NOUVEAU_FENCE_MAX_SPINS);
debug_printf("Wait on fence %u (ack = %u, next = %u) timed out !\n",
@@ -254,16 +277,20 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debu
}
void
-nouveau_fence_next(struct nouveau_context *nv)
+_nouveau_fence_next(struct nouveau_context *nv)
{
+ struct nouveau_fence_list *fence_list = &nv->screen->fence;
+
+ simple_mtx_assert_locked(&fence_list->lock);
+
if (nv->fence->state < NOUVEAU_FENCE_STATE_EMITTING) {
- if (nv->fence->ref > 1)
- nouveau_fence_emit(nv->fence);
+ if (p_atomic_read(&nv->fence->ref) > 1)
+ _nouveau_fence_emit(nv->fence);
else
return;
}
- nouveau_fence_ref(NULL, &nv->fence);
+ _nouveau_fence_ref(NULL, &nv->fence);
nouveau_fence_new(nv, &nv->fence);
}
@@ -281,6 +308,7 @@ nouveau_fence_work(struct nouveau_fence *fence,
void (*func)(void *), void *data)
{
struct nouveau_fence_work *work;
+ struct nouveau_screen *screen;
if (!fence || fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) {
func(data);
@@ -292,9 +320,72 @@ nouveau_fence_work(struct nouveau_fence *fence,
return false;
work->func = func;
work->data = data;
+
+ /* the fence might get deleted by fence_kick */
+ screen = fence->screen;
+
+ simple_mtx_lock(&screen->fence.lock);
list_add(&work->list, &fence->work);
- p_atomic_inc(&fence->work_count);
- if (fence->work_count > 64)
+ if (++fence->work_count > 64)
nouveau_fence_kick(fence);
+ simple_mtx_unlock(&screen->fence.lock);
return true;
}
+
+void
+_nouveau_fence_ref(struct nouveau_fence *fence, struct nouveau_fence **ref)
+{
+ if (fence)
+ p_atomic_inc(&fence->ref);
+
+ if (*ref) {
+ simple_mtx_assert_locked(&(*ref)->screen->fence.lock);
+ if (p_atomic_dec_zero(&(*ref)->ref))
+ nouveau_fence_del(*ref);
+ }
+
+ *ref = fence;
+}
+
+void
+nouveau_fence_ref(struct nouveau_fence *fence, struct nouveau_fence **ref)
+{
+ struct nouveau_fence_list *fence_list = NULL;
+ if (ref && *ref)
+ fence_list = &(*ref)->screen->fence;
+
+ if (fence_list)
+ simple_mtx_lock(&fence_list->lock);
+
+ _nouveau_fence_ref(fence, ref);
+
+ if (fence_list)
+ simple_mtx_unlock(&fence_list->lock);
+}
+
+bool
+nouveau_fence_wait(struct nouveau_fence *fence, struct util_debug_callback *debug)
+{
+ struct nouveau_fence_list *fence_list = &fence->screen->fence;
+ simple_mtx_lock(&fence_list->lock);
+ bool res = _nouveau_fence_wait(fence, debug);
+ simple_mtx_unlock(&fence_list->lock);
+ return res;
+}
+
+void
+nouveau_fence_emit(struct nouveau_fence *fence)
+{
+ simple_mtx_lock(&fence->screen->fence.lock);
+ _nouveau_fence_emit(fence);
+ simple_mtx_unlock(&fence->screen->fence.lock);
+}
+
+bool
+nouveau_fence_signalled(struct nouveau_fence *fence)
+{
+ simple_mtx_lock(&fence->screen->fence.lock);
+ bool ret = _nouveau_fence_signalled(fence);
+ simple_mtx_unlock(&fence->screen->fence.lock);
+ return ret;
+}
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h
index 49e74bfc52c..444598b3eb1 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.h
+++ b/src/gallium/drivers/nouveau/nouveau_fence.h
@@ -4,6 +4,7 @@
#include "util/u_inlines.h"
#include "util/list.h"
+#include "util/simple_mtx.h"
#define NOUVEAU_FENCE_STATE_AVAILABLE 0
#define NOUVEAU_FENCE_STATE_EMITTING 1
@@ -35,13 +36,29 @@ struct nouveau_fence_list {
struct nouveau_fence *tail;
uint32_t sequence;
uint32_t sequence_ack;
+ simple_mtx_t lock;
void (*emit)(struct pipe_context *, uint32_t *sequence);
uint32_t (*update)(struct pipe_screen *);
};
-void nouveau_fence_emit(struct nouveau_fence *);
-void nouveau_fence_del(struct nouveau_fence *);
+static inline void
+nouveau_fence_list_init(struct nouveau_fence_list *fence_list)
+{
+ simple_mtx_init(&fence_list->lock, mtx_plain);
+}
+
+static inline void
+nouveau_fence_list_destroy(struct nouveau_fence_list *fence_list)
+{
+ simple_mtx_destroy(&fence_list->lock);
+}
+
+/* unlocked versions, use with care */
+void _nouveau_fence_update(struct nouveau_screen *, bool flushed);
+void _nouveau_fence_next(struct nouveau_context *);
+void _nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **);
+void nouveau_fence_emit(struct nouveau_fence *);
bool nouveau_fence_new(struct nouveau_context *, struct nouveau_fence **);
void nouveau_fence_cleanup(struct nouveau_context *);
bool nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *);
@@ -49,24 +66,10 @@ void nouveau_fence_update(struct nouveau_screen *, bool flushed);
void nouveau_fence_next(struct nouveau_context *);
bool nouveau_fence_wait(struct nouveau_fence *, struct util_debug_callback *);
bool nouveau_fence_signalled(struct nouveau_fence *);
+void nouveau_fence_ref(struct nouveau_fence *, struct nouveau_fence **);
void nouveau_fence_unref_bo(void *data); /* generic unref bo callback */
-
-static inline void
-nouveau_fence_ref(struct nouveau_fence *fence, struct nouveau_fence **ref)
-{
- if (fence)
- ++fence->ref;
-
- if (*ref) {
- if (--(*ref)->ref == 0)
- nouveau_fence_del(*ref);
- }
-
- *ref = fence;
-}
-
static inline struct nouveau_fence *
nouveau_fence(struct pipe_fence_handle *fence)
{
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 37d14bee8fd..5f4b9c8cad4 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -195,7 +195,7 @@ nouveau_pushbuf_cb(struct nouveau_pushbuf *push)
if (p->context)
p->context->kick_notify(p->context);
else
- nouveau_fence_update(p->screen, true);
+ _nouveau_fence_update(p->screen, true);
NOUVEAU_DRV_STAT(p->screen, pushbuf_count, 1);
}
@@ -384,6 +384,7 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
PIPE_BIND_COMMAND_ARGS_BUFFER;
memset(&mm_config, 0, sizeof(mm_config));
+ nouveau_fence_list_init(&screen->fence);
screen->mm_GART = nouveau_mm_create(dev,
NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
@@ -420,6 +421,7 @@ nouveau_screen_fini(struct nouveau_screen *screen)
close(fd);
disk_cache_destroy(screen->disk_shader_cache);
+ nouveau_fence_list_destroy(&screen->fence);
}
static void
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index 3d83d572615..1b6652f6952 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -27,7 +27,11 @@ PUSH_AVAIL(struct nouveau_pushbuf *push)
static inline bool
PUSH_SPACE_EX(struct nouveau_pushbuf *push, uint32_t size, uint32_t relocs, uint32_t pushes)
{
- return nouveau_pushbuf_space(push, size, relocs, pushes) == 0;
+ struct nouveau_pushbuf_priv *ppush = push->user_priv;
+ simple_mtx_lock(&ppush->screen->fence.lock);
+ bool res = nouveau_pushbuf_space(push, size, relocs, pushes) == 0;
+ simple_mtx_unlock(&ppush->screen->fence.lock);
+ return res;
}
static inline bool
@@ -71,7 +75,11 @@ PUSH_DATAf(struct nouveau_pushbuf *push, float f)
static inline int
PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_pushbuf_refn *refs, int nr)
{
- return nouveau_pushbuf_refn(push, refs, nr);
+ struct nouveau_pushbuf_priv *ppush = push->user_priv;
+ simple_mtx_lock(&ppush->screen->fence.lock);
+ int ret = nouveau_pushbuf_refn(push, refs, nr);
+ simple_mtx_unlock(&ppush->screen->fence.lock);
+ return ret;
}
static inline int
@@ -84,25 +92,40 @@ PUSH_REF1(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags)
static inline void
PUSH_KICK(struct nouveau_pushbuf *push)
{
+ struct nouveau_pushbuf_priv *ppush = push->user_priv;
+ simple_mtx_lock(&ppush->screen->fence.lock);
nouveau_pushbuf_kick(push, push->channel);
+ simple_mtx_unlock(&ppush->screen->fence.lock);
}
static inline int
PUSH_VAL(struct nouveau_pushbuf *push)
{
- return nouveau_pushbuf_validate(push);
+ struct nouveau_pushbuf_priv *ppush = push->user_priv;
+ simple_mtx_lock(&ppush->screen->fence.lock);
+ int res = nouveau_pushbuf_validate(push);
+ simple_mtx_unlock(&ppush->screen->fence.lock);
+ return res;
}
static inline int
BO_MAP(struct nouveau_screen *screen, struct nouveau_bo *bo, uint32_t access, struct nouveau_client *client)
{
- return nouveau_bo_map(bo, access, client);
+ int res;
+ simple_mtx_lock(&screen->fence.lock);
+ res = nouveau_bo_map(bo, access, client);
+ simple_mtx_unlock(&screen->fence.lock);
+ return res;
}
static inline int
BO_WAIT(struct nouveau_screen *screen, struct nouveau_bo *bo, uint32_t access, struct nouveau_client *client)
{
- return nouveau_bo_wait(bo, access, client);
+ int res;
+ simple_mtx_lock(&screen->fence.lock);
+ res = nouveau_bo_wait(bo, access, client);
+ simple_mtx_unlock(&screen->fence.lock);
+ return res;
}
#define NOUVEAU_RESOURCE_FLAG_LINEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 0)
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_context.c b/src/gallium/drivers/nouveau/nv30/nv30_context.c
index 50c5071b266..7ce9f33a165 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_context.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_context.c
@@ -41,21 +41,21 @@ nv30_context_kick_notify(struct nouveau_pushbuf *push)
struct nouveau_pushbuf_priv *p = push->user_priv;
struct nouveau_screen *screen = p->screen;
- nouveau_fence_next(p->context);
- nouveau_fence_update(screen, true);
+ _nouveau_fence_next(p->context);
+ _nouveau_fence_update(screen, true);
if (push->bufctx) {
struct nouveau_bufref *bref;
LIST_FOR_EACH_ENTRY(bref, &push->bufctx->current, thead) {
struct nv04_resource *res = bref->priv;
if (res && res->mm) {
- nouveau_fence_ref(p->context->fence, &res->fence);
+ _nouveau_fence_ref(p->context->fence, &res->fence);
if (bref->flags & NOUVEAU_BO_RD)
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
if (bref->flags & NOUVEAU_BO_WR) {
- nouveau_fence_ref(p->context->fence, &res->fence_wr);
+ _nouveau_fence_ref(p->context->fence, &res->fence_wr);
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING |
NOUVEAU_BUFFER_STATUS_DIRTY;
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c
index bbc4131a499..977ce2e27e7 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c
@@ -136,8 +136,8 @@ nv50_default_kick_notify(struct nouveau_context *context)
{
struct nv50_context *nv50 = nv50_context(&context->pipe);
- nouveau_fence_next(context);
- nouveau_fence_update(context->screen, true);
+ _nouveau_fence_next(context);
+ _nouveau_fence_update(context->screen, true);
nv50->state.flushed = true;
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index f2aebccb235..2a49539b0cd 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
@@ -749,7 +749,7 @@ nva0_draw_stream_output(struct nv50_context *nv50,
static void
nv50_draw_vbo_kick_notify(struct nouveau_context *context)
{
- nouveau_fence_update(context->screen, true);
+ _nouveau_fence_update(context->screen, true);
}
void
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
index 1fd77b1db64..1c90ba17853 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
@@ -280,8 +280,8 @@ nvc0_default_kick_notify(struct nouveau_context *context)
{
struct nvc0_context *nvc0 = nvc0_context(&context->pipe);
- nouveau_fence_next(context);
- nouveau_fence_update(context->screen, true);
+ _nouveau_fence_next(context);
+ _nouveau_fence_update(context->screen, true);
nvc0->state.flushed = true;
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
index 8f11296f812..d55792c44e8 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
@@ -559,7 +559,7 @@ nvc0_prim_gl(unsigned prim)
static void
nvc0_draw_vbo_kick_notify(struct nouveau_context *context)
{
- nouveau_fence_update(context->screen, true);
+ _nouveau_fence_update(context->screen, true);
}
static void
--
2.37.3
From 468eb784519eee1cdfde1ff2e447c6685f844d31 Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Thu, 17 Jun 2021 18:56:24 +0200
Subject: [PATCH 16/17] nvc0: make state handling race free
I am not entirely convinced that contexts can't mess up the state of other
contexts, but with this we at least turn down the amount of races on the
CPU side.
If we hit bugs later we can always look into it then and figure out what
to fix how.
I think we might need a better solution for it in the future as state
tracking might need to become more involved, but for now this should be
good enough.
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>
---
src/gallium/drivers/nouveau/nvc0/nvc0_compute.c | 7 ++++++-
src/gallium/drivers/nouveau/nvc0/nvc0_context.c | 5 +++++
src/gallium/drivers/nouveau/nvc0/nvc0_program.c | 6 +++++-
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 3 +++
src/gallium/drivers/nouveau/nvc0/nvc0_screen.h | 1 +
.../drivers/nouveau/nvc0/nvc0_shader_state.c | 3 +++
src/gallium/drivers/nouveau/nvc0/nvc0_state.c | 3 +++
.../drivers/nouveau/nvc0/nvc0_state_validate.c | 3 +++
src/gallium/drivers/nouveau/nvc0/nvc0_surface.c | 16 ++++++++++++++--
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c | 6 ++++++
src/gallium/drivers/nouveau/nvc0/nve4_compute.c | 7 ++++++-
11 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
index 24ee9bfff6c..b2b00f4ba98 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
@@ -428,10 +428,11 @@ nvc0_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
struct nvc0_program *cp = nvc0->compprog;
int ret;
+ simple_mtx_lock(&screen->state_lock);
ret = !nvc0_state_validate_cp(nvc0, ~0);
if (ret) {
NOUVEAU_ERR("Failed to launch grid !\n");
- return;
+ goto out;
}
nvc0_compute_upload_input(nvc0, info);
@@ -502,6 +503,10 @@ nvc0_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
nvc0->images_dirty[5] |= nvc0->images_valid[5];
nvc0_update_compute_invocations_counter(nvc0, info);
+
+out:
+ PUSH_KICK(push);
+ simple_mtx_unlock(&screen->state_lock);
}
static void
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
index 1c90ba17853..f718d0d8fec 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
@@ -243,11 +243,13 @@ nvc0_destroy(struct pipe_context *pipe)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
+ simple_mtx_lock(&nvc0->screen->state_lock);
if (nvc0->screen->cur_ctx == nvc0) {
nvc0->screen->cur_ctx = NULL;
nvc0->screen->save_state = nvc0->state;
nvc0->screen->save_state.tfb = NULL;
}
+ simple_mtx_unlock(&nvc0->screen->state_lock);
if (nvc0->base.pipe.stream_uploader)
u_upload_destroy(nvc0->base.pipe.stream_uploader);
@@ -493,10 +495,13 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
/* now that there are no more opportunities for errors, set the current
* context if there isn't already one.
*/
+ simple_mtx_lock(&screen->state_lock);
if (!screen->cur_ctx) {
nvc0->state = screen->save_state;
screen->cur_ctx = nvc0;
}
+ simple_mtx_unlock(&screen->state_lock);
+
nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx);
PUSH_SPACE(nvc0->base.pushbuf, 8);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
index 86dd15520a5..36d0f7017c7 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c
@@ -884,6 +884,7 @@ nvc0_program_upload(struct nvc0_context *nvc0, struct nvc0_program *prog)
size += TU102_SHADER_HEADER_SIZE;
}
+ simple_mtx_assert_locked(&nvc0->screen->state_lock);
ret = nvc0_program_alloc_code(nvc0, prog);
if (ret) {
struct nouveau_heap *heap = screen->text_heap;
@@ -990,8 +991,11 @@ nvc0_program_destroy(struct nvc0_context *nvc0, struct nvc0_program *prog)
const struct pipe_shader_state pipe = prog->pipe;
const ubyte type = prog->type;
- if (prog->mem)
+ if (prog->mem) {
+ if (nvc0)
+ simple_mtx_assert_locked(&nvc0->screen->state_lock);
nouveau_heap_free(&prog->mem);
+ }
FREE(prog->code); /* may be 0 for hardcoded shaders */
FREE(prog->relocs);
FREE(prog->fixups);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 64353bcdf39..07bb622db08 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -741,6 +741,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
nouveau_object_del(&screen->nvsw);
nouveau_screen_fini(&screen->base);
+ simple_mtx_destroy(&screen->state_lock);
FREE(screen);
}
@@ -1067,6 +1068,8 @@ nvc0_screen_create(struct nouveau_device *dev)
pscreen = &screen->base.base;
pscreen->destroy = nvc0_screen_destroy;
+ simple_mtx_init(&screen->state_lock, mtx_plain);
+
ret = nouveau_screen_init(&screen->base, dev);
if (ret)
FAIL_SCREEN_INIT("Base screen init failed: %d\n", ret);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
index 3af38b59503..8bce90ae3af 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.h
@@ -71,6 +71,7 @@ struct nvc0_screen {
struct nvc0_context *cur_ctx;
struct nvc0_graph_state save_state;
+ simple_mtx_t state_lock;
int num_occlusion_queries_active;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c
index 0bd8a752f15..b0715c7bfff 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c
@@ -71,6 +71,7 @@ nvc0_program_sp_start_id(struct nvc0_context *nvc0, int stage,
{
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+ simple_mtx_assert_locked(&nvc0->screen->state_lock);
if (nvc0->screen->eng3d->oclass < GV100_3D_CLASS) {
BEGIN_NVC0(push, NVC0_3D(SP_START_ID(stage)), 1);
PUSH_DATA (push, prog->code_base);
@@ -338,6 +339,8 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
}
}
}
+
+ simple_mtx_assert_locked(&nvc0->screen->state_lock);
nvc0->state.tfb = tfb;
if (!(nvc0->dirty_3d & NVC0_NEW_3D_TFB_TARGETS))
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index 13c4fc6a27b..d7283b344a2 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -635,9 +635,12 @@ nvc0_sp_state_create(struct pipe_context *pipe,
static void
nvc0_sp_state_delete(struct pipe_context *pipe, void *hwcso)
{
+ struct nvc0_context *nvc0 = nvc0_context(pipe);
struct nvc0_program *prog = (struct nvc0_program *)hwcso;
+ simple_mtx_lock(&nvc0->screen->state_lock);
nvc0_program_destroy(nvc0_context(pipe), prog);
+ simple_mtx_unlock(&nvc0->screen->state_lock);
if (prog->pipe.type == PIPE_SHADER_IR_TGSI)
FREE((void *)prog->pipe.tokens);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
index 3fb69b51208..6726b94587e 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c
@@ -872,6 +872,7 @@ nvc0_switch_pipe_context(struct nvc0_context *ctx_to)
struct nvc0_context *ctx_from = ctx_to->screen->cur_ctx;
unsigned s;
+ simple_mtx_assert_locked(&ctx_to->screen->state_lock);
if (ctx_from)
ctx_to->state = ctx_from->state;
else
@@ -968,6 +969,8 @@ nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask,
int ret;
unsigned i;
+ simple_mtx_assert_locked(&nvc0->screen->state_lock);
+
if (nvc0->screen->cur_ctx != nvc0)
nvc0_switch_pipe_context(nvc0);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
index 81b833237f8..2e7de275252 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
@@ -700,9 +700,11 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers,
unsigned i, j, k;
uint32_t mode = 0;
+ simple_mtx_lock(&nvc0->screen->state_lock);
+
/* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
if (!nvc0_state_validate_3d(nvc0, NVC0_NEW_3D_FRAMEBUFFER))
- return;
+ goto out;
if (scissor_state) {
uint32_t minx = scissor_state->minx;
@@ -710,7 +712,7 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers,
uint32_t miny = scissor_state->miny;
uint32_t maxy = MIN2(fb->height, scissor_state->maxy);
if (maxx <= minx || maxy <= miny)
- return;
+ goto out;
BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
PUSH_DATA (push, minx | (maxx - minx) << 16);
@@ -781,6 +783,10 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers,
PUSH_DATA (push, fb->width << 16);
PUSH_DATA (push, fb->height << 16);
}
+
+out:
+ PUSH_KICK(push);
+ simple_mtx_unlock(&nvc0->screen->state_lock);
}
static void
@@ -789,8 +795,11 @@ gm200_evaluate_depth_buffer(struct pipe_context *pipe)
struct nvc0_context *nvc0 = nvc0_context(pipe);
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+ simple_mtx_lock(&nvc0->screen->state_lock);
nvc0_state_validate_3d(nvc0, NVC0_NEW_3D_FRAMEBUFFER);
IMMED_NVC0(push, SUBC_3D(0x11fc), 1);
+ PUSH_KICK(push);
+ simple_mtx_unlock(&nvc0->screen->state_lock);
}
@@ -1684,6 +1693,7 @@ nvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
if (info->num_window_rectangles > 0 || info->window_rectangle_include)
eng3d = true;
+ simple_mtx_lock(&nvc0->screen->state_lock);
if (nvc0->screen->num_occlusion_queries_active)
IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 0);
@@ -1694,6 +1704,8 @@ nvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
if (nvc0->screen->num_occlusion_queries_active)
IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 1);
+ PUSH_KICK(push);
+ simple_mtx_unlock(&nvc0->screen->state_lock);
NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_blit_count, 1);
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
index d55792c44e8..75c5080fa77 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
@@ -462,6 +462,7 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
if (update_vertex) {
const unsigned n = MAX2(vertex->num_elements, nvc0->state.num_vtxelts);
+ simple_mtx_assert_locked(&nvc0->screen->state_lock);
nvc0->state.constant_vbos = const_vbos;
nvc0->state.constant_elts = 0;
nvc0->state.num_vtxelts = vertex->num_elements;
@@ -1020,6 +1021,8 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
BCTX_REFN_bo(nvc0->bufctx_3d, 3D_TEXT, vram_domain | NOUVEAU_BO_RD,
screen->text);
+ simple_mtx_lock(&nvc0->screen->state_lock);
+
nvc0_state_validate_3d(nvc0, ~0);
if (nvc0->vertprog->vp.need_draw_parameters && (!indirect || indirect->count_from_stream_output)) {
@@ -1127,6 +1130,9 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
}
cleanup:
+ PUSH_KICK(push);
+ simple_mtx_unlock(&nvc0->screen->state_lock);
+
nvc0->base.kick_notify = nvc0_default_kick_notify;
nvc0_release_user_vbufs(nvc0);
diff --git a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
index dccbce91ef7..23d157fd4bf 100644
--- a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
+++ b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
@@ -867,9 +867,10 @@ nve4_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
resident->flags);
}
+ simple_mtx_lock(&screen->state_lock);
ret = !nve4_state_validate_cp(nvc0, ~0);
if (ret)
- goto out;
+ goto out_unlock;
if (nvc0->screen->compute->oclass >= GV100_COMPUTE_CLASS)
gv100_compute_setup_launch_desc(nvc0, desc, info);
@@ -934,6 +935,10 @@ nve4_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
nvc0_update_compute_invocations_counter(nvc0, info);
+out_unlock:
+ PUSH_KICK(push);
+ simple_mtx_unlock(&screen->state_lock);
+
out:
if (ret)
NOUVEAU_ERR("Failed to launch grid !\n");
--
2.37.3
From e90b5ca67ed1824e4b5825564a9ab3a90016da1f Mon Sep 17 00:00:00 2001
From: Karol Herbst <kherbst@redhat.com>
Date: Sun, 15 May 2022 19:20:40 +0200
Subject: [PATCH 17/17] 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>
---
src/gallium/drivers/nouveau/nv50/nv50_compute.c | 7 ++++++-
src/gallium/drivers/nouveau/nv50/nv50_context.c | 5 +++++
src/gallium/drivers/nouveau/nv50/nv50_program.c | 6 +++++-
src/gallium/drivers/nouveau/nv50/nv50_screen.c | 2 ++
src/gallium/drivers/nouveau/nv50/nv50_screen.h | 1 +
.../drivers/nouveau/nv50/nv50_shader_state.c | 1 +
src/gallium/drivers/nouveau/nv50/nv50_state.c | 5 ++++-
.../drivers/nouveau/nv50/nv50_state_validate.c | 3 +++
src/gallium/drivers/nouveau/nv50/nv50_surface.c | 13 +++++++++++--
src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 4 ++++
10 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_compute.c b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
index af22fd8fd81..1213effd53d 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_compute.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
@@ -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);
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c
index 977ce2e27e7..056aa0f0087 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c
@@ -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;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_program.c b/src/gallium/drivers/nouveau/nv50/nv50_program.c
index a81b176fccf..903145dca98 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_program.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_program.c
@@ -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);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index 79a57e5b5fa..eb2e71a28f8 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -650,6 +650,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);
}
@@ -1011,6 +1012,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);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.h b/src/gallium/drivers/nouveau/nv50/nv50_screen.h
index a374ba46c6f..72a6fc851fe 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.h
@@ -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;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
index 3d17953ed37..be9f25209ef 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_shader_state.c
@@ -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);
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state.c b/src/gallium/drivers/nouveau/nv50/nv50_state.c
index 3ad9e41fdbb..bb7d78712b8 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_state.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_state.c
@@ -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);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
index eec85cf6676..daba9f730c6 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_state_validate.c
@@ -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);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index 6f28c97cc73..983a67200ff 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -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
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index 2a49539b0cd..24070085634 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
@@ -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);
--
2.37.3