[Mesa-dev] [PATCH 6/7] nouveau: make fence API independent from nouveau_screen
Karol Herbst
kherbst at redhat.com
Wed Dec 5 21:04:56 UTC 2018
Signed-off-by: Karol Herbst <kherbst at redhat.com>
---
src/gallium/drivers/nouveau/nouveau_buffer.c | 37 +++----
src/gallium/drivers/nouveau/nouveau_buffer.h | 2 +-
src/gallium/drivers/nouveau/nouveau_fence.c | 96 +++++++++----------
src/gallium/drivers/nouveau/nouveau_fence.h | 38 ++++++--
src/gallium/drivers/nouveau/nouveau_screen.c | 6 +-
src/gallium/drivers/nouveau/nouveau_screen.h | 12 +--
.../drivers/nouveau/nv30/nv30_context.c | 4 +-
.../drivers/nouveau/nv30/nv30_miptree.c | 2 +-
.../drivers/nouveau/nv30/nv30_screen.c | 17 ++--
src/gallium/drivers/nouveau/nv30/nv30_vbo.c | 2 +-
.../drivers/nouveau/nv50/nv50_compute.c | 2 +-
.../drivers/nouveau/nv50/nv50_context.c | 4 +-
.../drivers/nouveau/nv50/nv50_miptree.c | 2 +-
.../drivers/nouveau/nv50/nv50_query_hw.c | 2 +-
.../drivers/nouveau/nv50/nv50_screen.c | 22 ++---
.../drivers/nouveau/nv50/nv50_transfer.c | 2 +-
src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 4 +-
.../drivers/nouveau/nvc0/nvc0_context.c | 4 +-
.../drivers/nouveau/nvc0/nvc0_query_hw.c | 6 +-
.../drivers/nouveau/nvc0/nvc0_screen.c | 25 +++--
.../drivers/nouveau/nvc0/nvc0_transfer.c | 6 +-
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c | 2 +-
22 files changed, 157 insertions(+), 140 deletions(-)
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index 97305d993ff..03f214dae4c 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -69,24 +69,25 @@ nouveau_buffer_allocate(struct nouveau_screen *screen,
static inline void
release_allocation(struct nouveau_mm_allocation **mm,
- struct nouveau_fence *fence)
+ struct nouveau_fence *fence,
+ struct nouveau_pushbuf *push)
{
- nouveau_fence_work(fence, nouveau_mm_free_work, *mm);
+ nouveau_fence_work(fence, push, nouveau_mm_free_work, *mm);
(*mm) = NULL;
}
inline void
-nouveau_buffer_release_gpu_storage(struct nv04_resource *buf)
+nouveau_buffer_release_gpu_storage(struct nouveau_pushbuf *push, struct nv04_resource *buf)
{
if (buf->fence && buf->fence->state < NOUVEAU_FENCE_STATE_FLUSHED) {
- nouveau_fence_work(buf->fence, nouveau_fence_unref_bo, buf->bo);
+ nouveau_fence_work(buf->fence, push, nouveau_fence_unref_bo, buf->bo);
buf->bo = NULL;
} else {
nouveau_bo_ref(NULL, &buf->bo);
}
if (buf->mm)
- release_allocation(&buf->mm, buf->fence);
+ release_allocation(&buf->mm, buf->fence, push);
if (buf->domain == NOUVEAU_BO_VRAM)
NOUVEAU_DRV_STAT_RES(buf, buf_obj_current_bytes_vid, -(uint64_t)buf->base.width0);
@@ -97,10 +98,10 @@ nouveau_buffer_release_gpu_storage(struct nv04_resource *buf)
}
static inline bool
-nouveau_buffer_reallocate(struct nouveau_screen *screen,
+nouveau_buffer_reallocate(struct nouveau_screen *screen, struct nouveau_pushbuf *push,
struct nv04_resource *buf, unsigned domain)
{
- nouveau_buffer_release_gpu_storage(buf);
+ nouveau_buffer_release_gpu_storage(push, buf);
nouveau_fence_ref(NULL, &buf->fence);
nouveau_fence_ref(NULL, &buf->fence_wr);
@@ -116,7 +117,7 @@ nouveau_buffer_destroy(struct pipe_screen *pscreen,
{
struct nv04_resource *res = nv04_resource(presource);
- nouveau_buffer_release_gpu_storage(res);
+ nouveau_buffer_release_gpu_storage(nouveau_screen(pscreen)->pushbuf, res);
if (res->data && !(res->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY))
align_free(res->data);
@@ -231,14 +232,14 @@ nouveau_buffer_sync(struct nouveau_context *nv,
return true;
NOUVEAU_DRV_STAT_RES(buf, buf_non_kernel_fence_sync_count,
!nouveau_fence_signalled(buf->fence_wr));
- if (!nouveau_fence_wait(buf->fence_wr, &nv->debug))
+ if (!nouveau_fence_wait(buf->fence_wr, nv->pushbuf, &nv->debug))
return false;
} else {
if (!buf->fence)
return true;
NOUVEAU_DRV_STAT_RES(buf, buf_non_kernel_fence_sync_count,
!nouveau_fence_signalled(buf->fence));
- if (!nouveau_fence_wait(buf->fence, &nv->debug))
+ if (!nouveau_fence_wait(buf->fence, nv->pushbuf, &nv->debug))
return false;
nouveau_fence_ref(NULL, &buf->fence);
@@ -285,10 +286,10 @@ nouveau_buffer_transfer_del(struct nouveau_context *nv,
{
if (tx->map) {
if (likely(tx->bo)) {
- nouveau_fence_work(nv->screen->fence.current,
+ nouveau_fence_work(nv->screen->fence.current, nv->pushbuf,
nouveau_fence_unref_bo, tx->bo);
if (tx->mm)
- release_allocation(&tx->mm, nv->screen->fence.current);
+ release_allocation(&tx->mm, nv->screen->fence.current, nv->pushbuf);
} else {
align_free(tx->map -
(tx->base.box.x & NOUVEAU_MIN_BUFFER_MAP_ALIGN_MASK));
@@ -442,7 +443,7 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
if (nouveau_buffer_should_discard(buf, usage)) {
int ref = buf->base.reference.count - 1;
- nouveau_buffer_reallocate(nv->screen, buf, buf->domain);
+ nouveau_buffer_reallocate(nv->screen, nv->pushbuf, buf, buf->domain);
if (ref > 0) /* any references inside context possible ? */
nv->invalidate_resource_storage(nv, &buf->base, ref);
}
@@ -785,9 +786,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(screen->fence.current, nv->pushbuf, nouveau_fence_unref_bo, bo);
if (mm)
- release_allocation(&mm, screen->fence.current);
+ release_allocation(&mm, screen->fence.current, nv->pushbuf);
} else
if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) {
struct nouveau_transfer tx;
@@ -824,7 +825,7 @@ nouveau_user_buffer_upload(struct nouveau_context *nv,
assert(buf->status & NOUVEAU_BUFFER_STATUS_USER_MEMORY);
buf->base.width0 = base + size;
- if (!nouveau_buffer_reallocate(screen, buf, NOUVEAU_BO_GART))
+ if (!nouveau_buffer_reallocate(screen, nv->pushbuf, buf, NOUVEAU_BO_GART))
return false;
ret = nouveau_bo_map(buf->bo, 0, nv->client);
@@ -862,7 +863,7 @@ nouveau_buffer_invalidate(struct pipe_context *pipe,
if (buf->mm && !nouveau_buffer_busy(buf, PIPE_TRANSFER_WRITE)) {
util_range_set_empty(&buf->valid_buffer_range);
} else {
- nouveau_buffer_reallocate(nv->screen, buf, buf->domain);
+ nouveau_buffer_reallocate(nv->screen, nv->pushbuf, buf, buf->domain);
if (ref > 0) /* any references inside context possible ? */
nv->invalidate_resource_storage(nv, &buf->base, ref);
}
@@ -897,7 +898,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->screen->fence.current, nv->pushbuf, nouveau_scratch_unref_bos,
nv->scratch.runout))
return;
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h b/src/gallium/drivers/nouveau/nouveau_buffer.h
index 3a33fae9ce2..836778892ba 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.h
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.h
@@ -53,7 +53,7 @@ struct nv04_resource {
};
void
-nouveau_buffer_release_gpu_storage(struct nv04_resource *);
+nouveau_buffer_release_gpu_storage(struct nouveau_pushbuf *push, struct nv04_resource *);
void
nouveau_copy_buffer(struct nouveau_context *,
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c
index d14c59b2dd1..97a7223f950 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.c
+++ b/src/gallium/drivers/nouveau/nouveau_fence.c
@@ -30,13 +30,13 @@
#endif
bool
-nouveau_fence_new(struct nouveau_screen *screen, struct nouveau_fence **fence)
+nouveau_fence_new(struct nouveau_fence_list *list, struct nouveau_fence **fence)
{
*fence = CALLOC_STRUCT(nouveau_fence);
if (!*fence)
return false;
- (*fence)->screen = screen;
+ (*fence)->list = list;
(*fence)->ref = 1;
LIST_INITHEAD(&(*fence)->work);
@@ -56,9 +56,9 @@ nouveau_fence_trigger_work(struct nouveau_fence *fence)
}
void
-nouveau_fence_emit(struct nouveau_fence *fence)
+nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_pushbuf *push)
{
- struct nouveau_screen *screen = fence->screen;
+ struct nouveau_fence_list *list = fence->list;
assert(fence->state == NOUVEAU_FENCE_STATE_AVAILABLE);
@@ -67,14 +67,14 @@ nouveau_fence_emit(struct nouveau_fence *fence)
++fence->ref;
- if (screen->fence.tail)
- screen->fence.tail->next = fence;
+ if (list->tail)
+ list->tail->next = fence;
else
- screen->fence.head = fence;
+ list->head = fence;
- screen->fence.tail = fence;
+ list->tail = fence;
- screen->fence.emit(&screen->base, &fence->sequence);
+ list->emit(list, push, &fence->sequence);
assert(fence->state == NOUVEAU_FENCE_STATE_EMITTING);
fence->state = NOUVEAU_FENCE_STATE_EMITTED;
@@ -84,19 +84,19 @@ void
nouveau_fence_del(struct nouveau_fence *fence)
{
struct nouveau_fence *it;
- struct nouveau_screen *screen = fence->screen;
+ struct nouveau_fence_list *list = fence->list;
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 == list->head) {
+ list->head = fence->next;
+ if (!list->head)
+ list->tail = NULL;
} else {
- for (it = screen->fence.head; it && it->next != fence; it = it->next);
+ for (it = list->head; it && it->next != fence; it = it->next);
it->next = fence->next;
- if (screen->fence.tail == fence)
- screen->fence.tail = it;
+ if (list->tail == fence)
+ list->tail = it;
}
}
@@ -109,17 +109,17 @@ nouveau_fence_del(struct nouveau_fence *fence)
}
void
-nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
+nouveau_fence_update(struct nouveau_fence_list *list, bool flushed)
{
struct nouveau_fence *fence;
struct nouveau_fence *next = NULL;
- u32 sequence = screen->fence.update(&screen->base);
+ u32 sequence = list->update(list);
- if (screen->fence.sequence_ack == sequence)
+ if (list->sequence_ack == sequence)
return;
- screen->fence.sequence_ack = sequence;
+ list->sequence_ack = sequence;
- for (fence = screen->fence.head; fence; fence = next) {
+ for (fence = list->head; fence; fence = next) {
next = fence->next;
sequence = fence->sequence;
@@ -128,12 +128,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 == list->sequence_ack)
break;
}
- screen->fence.head = next;
+ list->head = next;
if (!next)
- screen->fence.tail = NULL;
+ list->tail = NULL;
if (flushed) {
for (fence = next; fence; fence = fence->next)
@@ -147,57 +147,52 @@ nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
bool
nouveau_fence_signalled(struct nouveau_fence *fence)
{
- struct nouveau_screen *screen = fence->screen;
-
if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED)
return true;
if (fence->state >= NOUVEAU_FENCE_STATE_EMITTED)
- nouveau_fence_update(screen, false);
+ nouveau_fence_update(fence->list, false);
return fence->state == NOUVEAU_FENCE_STATE_SIGNALLED;
}
static bool
-nouveau_fence_kick(struct nouveau_fence *fence)
+nouveau_fence_kick(struct nouveau_fence *fence, struct nouveau_pushbuf *push)
{
- struct nouveau_screen *screen = fence->screen;
-
/* 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(screen->pushbuf, 8);
+ PUSH_SPACE(push, 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, push);
}
if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
- if (nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel))
+ if (nouveau_pushbuf_kick(push, push->channel))
return false;
- if (fence == screen->fence.current)
- nouveau_fence_next(screen);
+ if (fence == fence->list->current)
+ nouveau_fence_next(fence->list, push);
- nouveau_fence_update(screen, false);
+ nouveau_fence_update(fence->list, false);
return true;
}
bool
-nouveau_fence_wait(struct nouveau_fence *fence, struct pipe_debug_callback *debug)
+nouveau_fence_wait(struct nouveau_fence *fence, struct nouveau_pushbuf *push, struct pipe_debug_callback *debug)
{
- struct nouveau_screen *screen = fence->screen;
uint32_t spins = 0;
int64_t start = 0;
if (debug && debug->debug_message)
start = os_time_get_nano();
- if (!nouveau_fence_kick(fence))
+ if (!nouveau_fence_kick(fence, push))
return false;
do {
@@ -209,36 +204,36 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct pipe_debug_callback *debu
return true;
}
if (!spins)
- NOUVEAU_DRV_STAT(screen, any_non_kernel_fence_sync_count, 1);
+ NOUVEAU_DRV_STAT(fence->list->screen, any_non_kernel_fence_sync_count, 1);
spins++;
#ifdef PIPE_OS_UNIX
if (!(spins % 8)) /* donate a few cycles */
sched_yield();
#endif
- nouveau_fence_update(screen, false);
+ nouveau_fence_update(fence->list, false);
} while (spins < NOUVEAU_FENCE_MAX_SPINS);
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;
}
void
-nouveau_fence_next(struct nouveau_screen *screen)
+nouveau_fence_next(struct nouveau_fence_list *list, struct nouveau_pushbuf *push)
{
- if (screen->fence.current->state < NOUVEAU_FENCE_STATE_EMITTING) {
- if (screen->fence.current->ref > 1)
- nouveau_fence_emit(screen->fence.current);
+ if (list->current->state < NOUVEAU_FENCE_STATE_EMITTING) {
+ if (list->current->ref > 1)
+ nouveau_fence_emit(list->current, push);
else
return;
}
- nouveau_fence_ref(NULL, &screen->fence.current);
+ nouveau_fence_ref(NULL, &list->current);
- nouveau_fence_new(screen, &screen->fence.current);
+ nouveau_fence_new(list, &list->current);
}
void
@@ -251,6 +246,7 @@ nouveau_fence_unref_bo(void *data)
bool
nouveau_fence_work(struct nouveau_fence *fence,
+ struct nouveau_pushbuf *push,
void (*func)(void *), void *data)
{
struct nouveau_fence_work *work;
@@ -268,6 +264,6 @@ nouveau_fence_work(struct nouveau_fence *fence,
LIST_ADD(&work->list, &fence->work);
p_atomic_inc(&fence->work_count);
if (fence->work_count > 64)
- nouveau_fence_kick(fence);
+ nouveau_fence_kick(fence, push);
return true;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h
index e14572bce8f..d4c5f03b66f 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.h
+++ b/src/gallium/drivers/nouveau/nouveau_fence.h
@@ -13,6 +13,10 @@
struct pipe_debug_callback;
+struct nouveau_fence_list;
+struct nouveau_pushbuf;
+struct nouveau_screen;
+
struct nouveau_fence_work {
struct list_head list;
void (*func)(void *);
@@ -21,7 +25,7 @@ struct nouveau_fence_work {
struct nouveau_fence {
struct nouveau_fence *next;
- struct nouveau_screen *screen;
+ struct nouveau_fence_list *list;
int state;
int ref;
uint32_t sequence;
@@ -29,18 +33,38 @@ struct nouveau_fence {
struct list_head work;
};
-void nouveau_fence_emit(struct nouveau_fence *);
+struct nouveau_fence_list {
+ struct nouveau_fence *head;
+ struct nouveau_fence *tail;
+ struct nouveau_fence *current;
+
+ struct nouveau_screen *screen;
+ void *data;
+
+ uint32_t sequence;
+ uint32_t sequence_ack;
+ void (*emit)(struct nouveau_fence_list *, struct nouveau_pushbuf *, uint32_t *sequence);
+ uint32_t (*update)(struct nouveau_fence_list *);
+};
+
+void nouveau_fence_emit(struct nouveau_fence *, struct nouveau_pushbuf *);
void nouveau_fence_del(struct nouveau_fence *);
-bool nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence **);
-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 *);
-bool nouveau_fence_wait(struct nouveau_fence *, struct pipe_debug_callback *);
+bool nouveau_fence_new(struct nouveau_fence_list *list, struct nouveau_fence **);
+bool nouveau_fence_work(struct nouveau_fence *, struct nouveau_pushbuf *, void (*)(void *), void *);
+void nouveau_fence_update(struct nouveau_fence_list *, bool flushed);
+void nouveau_fence_next(struct nouveau_fence_list *, struct nouveau_pushbuf *);
+bool nouveau_fence_wait(struct nouveau_fence *, struct nouveau_pushbuf *push, struct pipe_debug_callback *);
bool nouveau_fence_signalled(struct nouveau_fence *);
void nouveau_fence_unref_bo(void *data); /* generic unref bo callback */
+static inline void
+nouveau_fence_list_init(struct nouveau_fence_list *list,
+ struct nouveau_screen *screen)
+{
+ list->screen = screen;
+}
static inline void
nouveau_fence_ref(struct nouveau_fence *fence, struct nouveau_fence **ref)
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 07cdb370c13..ee874a1fce7 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -80,10 +80,12 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *pfence,
uint64_t timeout)
{
+ struct nouveau_pushbuf *push = ctx ? nouveau_context(ctx)->pushbuf : nouveau_screen(screen)->pushbuf;
+
if (!timeout)
return nouveau_fence_signalled(nouveau_fence(pfence));
- return nouveau_fence_wait(nouveau_fence(pfence), NULL);
+ return nouveau_fence_wait(nouveau_fence(pfence), push, NULL);
}
@@ -224,6 +226,8 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
if (ret)
return ret;
+ nouveau_fence_list_init(&screen->fence, screen);
+
/* getting CPU time first appears to be more accurate */
screen->cpu_gpu_time_delta = os_time_get();
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index 9273d52c1de..7f16ee3f269 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -9,6 +9,8 @@
# define NOUVEAU_ENABLE_DRIVER_STATISTICS
#endif
+#include "nouveau_fence.h"
+
typedef uint32_t u32;
typedef uint16_t u16;
@@ -38,15 +40,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_context.c b/src/gallium/drivers/nouveau/nv30/nv30_context.c
index 18eb2c41618..3fd5e2b28c0 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_context.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_context.c
@@ -45,8 +45,8 @@ nv30_context_kick_notify(struct nouveau_pushbuf *push)
nv30 = container_of(push->user_priv, nv30, bufctx);
screen = &nv30->screen->base;
- nouveau_fence_next(screen);
- nouveau_fence_update(screen, true);
+ nouveau_fence_next(&screen->fence, push);
+ nouveau_fence_update(&screen->fence, true);
if (push->bufctx) {
struct nouveau_bufref *bref;
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
index 4f991776323..1518d8f433f 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
@@ -343,7 +343,7 @@ nv30_miptree_transfer_unmap(struct pipe_context *pipe,
nv30_transfer_rect(nv30, NEAREST, &tx->tmp, &tx->img);
/* Allow the copies above to finish executing before freeing the source */
- nouveau_fence_work(nv30->screen->base.fence.current,
+ nouveau_fence_work(nv30->screen->base.fence.current, nv30->base.pushbuf,
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 d7563f4a60e..41169be7108 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -442,12 +442,9 @@ nv30_screen_is_format_supported(struct pipe_screen *pscreen,
}
static void
-nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence)
+nv30_screen_fence_emit(struct nouveau_fence_list *fence, struct nouveau_pushbuf *push, uint32_t *sequence)
{
- struct nv30_screen *screen = nv30_screen(pscreen);
- struct nouveau_pushbuf *push = screen->base.pushbuf;
-
- *sequence = ++screen->base.fence.sequence;
+ *sequence = ++fence->sequence;
assert(PUSH_AVAIL(push) + push->rsvd_kick >= 3);
PUSH_DATA (push, NV30_3D_FENCE_OFFSET |
@@ -457,9 +454,9 @@ nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence)
}
static uint32_t
-nv30_screen_fence_update(struct pipe_screen *pscreen)
+nv30_screen_fence_update(struct nouveau_fence_list *list)
{
- struct nv30_screen *screen = nv30_screen(pscreen);
+ struct nv30_screen *screen = list->data;
struct nv04_notify *fence = screen->fence->data;
return *(uint32_t *)((char *)screen->notify->map + fence->offset);
}
@@ -479,7 +476,7 @@ nv30_screen_destroy(struct pipe_screen *pscreen)
* _current_ one, and remove both.
*/
nouveau_fence_ref(screen->base.fence.current, ¤t);
- nouveau_fence_wait(current, NULL);
+ nouveau_fence_wait(current, screen->base.pushbuf, NULL);
nouveau_fence_ref(NULL, ¤t);
nouveau_fence_ref(NULL, &screen->base.fence.current);
}
@@ -592,6 +589,8 @@ nv30_screen_create(struct nouveau_device *dev)
if (ret)
FAIL_SCREEN_INIT("nv30_screen_init failed: %d\n", ret);
+ screen->base.fence.data = screen;
+
screen->base.vidmem_bindings |= PIPE_BIND_VERTEX_BUFFER;
screen->base.sysmem_bindings |= PIPE_BIND_VERTEX_BUFFER;
if (oclass == NV40_3D_CLASS) {
@@ -788,6 +787,6 @@ nv30_screen_create(struct nouveau_device *dev)
nouveau_pushbuf_kick(push, push->channel);
- nouveau_fence_new(&screen->base, &screen->base.fence.current);
+ nouveau_fence_new(&screen->base.fence, &screen->base.fence.current);
return &screen->base;
}
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
index bb0a8a0b1d5..5c92af0cfb3 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
@@ -173,7 +173,7 @@ nv30_release_user_vbufs(struct nv30_context *nv30)
int i = ffs(vbo_user) - 1;
vbo_user &= ~(1 << i);
- nouveau_buffer_release_gpu_storage(nv04_resource(nv30->vtxbuf[i].buffer.resource));
+ nouveau_buffer_release_gpu_storage(nv30->base.pushbuf, nv04_resource(nv30->vtxbuf[i].buffer.resource));
}
nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VTXTMP);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_compute.c b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
index aac60bba54d..440d7b48fff 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_compute.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
@@ -219,7 +219,7 @@ nv50_compute_upload_input(struct nv50_context *nv50, const uint32_t *input)
BEGIN_NV04(push, NV50_CP(USER_PARAM(0)), size / 4);
nouveau_pushbuf_data(push, bo, offset, size);
- nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, mm);
+ nouveau_fence_work(screen->base.fence.current, push, 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 398560c0fca..e54a06d39ec 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c
@@ -120,8 +120,8 @@ nv50_default_kick_notify(struct nouveau_pushbuf *push)
struct nv50_screen *screen = push->user_priv;
if (screen) {
- nouveau_fence_next(&screen->base);
- nouveau_fence_update(&screen->base, true);
+ nouveau_fence_next(&screen->base.fence, push);
+ nouveau_fence_update(&screen->base.fence, true);
if (screen->cur_ctx)
screen->cur_ctx->state.flushed = true;
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
index f2e304fde62..04f9d8416fa 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
@@ -164,7 +164,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);
+ nouveau_fence_work(mt->base.fence, nouveau_screen(pscreen)->pushbuf, nouveau_fence_unref_bo, mt->base.bo);
else
nouveau_bo_ref(NULL, &mt->base.bo);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
index 5be7a4eea1c..c12f9da701d 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
@@ -57,7 +57,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(screen->base.fence.current, nv50->base.pushbuf,
nouveau_mm_free_work, hq->mm);
}
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index 0fc7002d640..0373620fe53 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -503,7 +503,7 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
* _current_ one, and remove both.
*/
nouveau_fence_ref(screen->base.fence.current, ¤t);
- nouveau_fence_wait(current, NULL);
+ nouveau_fence_wait(current, screen->base.pushbuf, NULL);
nouveau_fence_ref(NULL, ¤t);
nouveau_fence_ref(NULL, &screen->base.fence.current);
}
@@ -543,18 +543,17 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
}
static void
-nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
+nv50_screen_fence_emit(struct nouveau_fence_list *fence, struct nouveau_pushbuf *push, u32 *sequence)
{
- struct nv50_screen *screen = nv50_screen(pscreen);
- struct nouveau_pushbuf *push = screen->base.pushbuf;
+ struct nouveau_bo *bo = fence->data;
/* we need to do it after possible flush in MARK_RING */
- *sequence = ++screen->base.fence.sequence;
+ *sequence = ++fence->sequence;
assert(PUSH_AVAIL(push) + push->rsvd_kick >= 5);
PUSH_DATA (push, NV50_FIFO_PKHDR(NV50_3D(QUERY_ADDRESS_HIGH), 4));
- PUSH_DATAh(push, screen->fence.bo->offset);
- PUSH_DATA (push, screen->fence.bo->offset);
+ PUSH_DATAh(push, bo->offset);
+ PUSH_DATA (push, bo->offset);
PUSH_DATA (push, *sequence);
PUSH_DATA (push, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
NV50_3D_QUERY_GET_UNK4 |
@@ -565,9 +564,10 @@ nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
}
static u32
-nv50_screen_fence_update(struct pipe_screen *pscreen)
+nv50_screen_fence_update(struct nouveau_fence_list *fence)
{
- uint32_t *map = nv50_screen(pscreen)->fence.bo->map;
+ struct nouveau_bo *bo = fence->data;
+ uint32_t *map = bo->map;
return map[0];
}
@@ -933,8 +933,8 @@ nv50_screen_create(struct nouveau_device *dev)
NOUVEAU_ERR("Failed to allocate fence bo: %d\n", ret);
goto fail;
}
-
nouveau_bo_map(screen->fence.bo, 0, NULL);
+ screen->base.fence.data = screen->fence.bo;
screen->base.fence.emit = nv50_screen_fence_emit;
screen->base.fence.update = nv50_screen_fence_update;
@@ -1076,7 +1076,7 @@ nv50_screen_create(struct nouveau_device *dev)
goto fail;
}
- nouveau_fence_new(&screen->base, &screen->base.fence.current);
+ nouveau_fence_new(&screen->base.fence, &screen->base.fence.current);
return &screen->base;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
index d08095a0f6f..863e67d47ea 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
@@ -360,7 +360,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->screen->base.fence.current, nv50->base.pushbuf,
nouveau_fence_unref_bo, tx->rect[1].bo);
} else {
nouveau_bo_ref(NULL, &tx->rect[1].bo);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index ed041121a26..260b55e9b01 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,
* pushbuf submit, but it's probably not a big performance difference.
*/
if (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr))
- nouveau_fence_wait(buf->fence_wr, &nv50->base.debug);
+ nouveau_fence_wait(buf->fence_wr, push, &nv50->base.debug);
while (instance_count--) {
BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
@@ -757,7 +757,7 @@ nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan)
{
struct nv50_screen *screen = chan->user_priv;
- nouveau_fence_update(&screen->base, true);
+ nouveau_fence_update(&screen->base.fence, true);
nv50_bufctx_fence(screen->cur_ctx->bufctx_3d, true);
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
index 962e9ddef04..471078c56b4 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
@@ -225,8 +225,8 @@ nvc0_default_kick_notify(struct nouveau_pushbuf *push)
struct nvc0_screen *screen = push->user_priv;
if (screen) {
- nouveau_fence_next(&screen->base);
- nouveau_fence_update(&screen->base, true);
+ nouveau_fence_next(&screen->base.fence, push);
+ nouveau_fence_update(&screen->base.fence, true);
if (screen->cur_ctx)
screen->cur_ctx->state.flushed = true;
NOUVEAU_DRV_STAT(&screen->base, pushbuf_count, 1);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
index 00d12d19c35..40cc552a29b 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
@@ -49,7 +49,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(screen->base.fence.current, nvc0->base.pushbuf,
nouveau_mm_free_work, hq->mm);
}
}
@@ -405,7 +405,7 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0,
* of the following logic more complicated.
*/
if (hq->is64bit && hq->fence->state < NOUVEAU_FENCE_STATE_EMITTED)
- nouveau_fence_emit(hq->fence);
+ nouveau_fence_emit(hq->fence, push);
/* We either need to compute a 32- or 64-bit difference between 2 values,
* and then store the result as either a 32- or 64-bit value. As such let's
@@ -627,7 +627,7 @@ nvc0_hw_query_fifo_wait(struct nvc0_context *nvc0, struct nvc0_query *q)
/* ensure the query's fence has been emitted */
if (hq->is64bit && hq->fence->state < NOUVEAU_FENCE_STATE_EMITTED)
- nouveau_fence_emit(hq->fence);
+ nouveau_fence_emit(hq->fence, push);
PUSH_SPACE(push, 5);
PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 6fb95e89712..26642c2629d 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -603,7 +603,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
* _current_ one, and remove both.
*/
nouveau_fence_ref(screen->base.fence.current, ¤t);
- nouveau_fence_wait(current, NULL);
+ nouveau_fence_wait(current, screen->base.pushbuf, NULL);
nouveau_fence_ref(NULL, ¤t);
nouveau_fence_ref(NULL, &screen->base.fence.current);
}
@@ -728,28 +728,27 @@ 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 nouveau_fence_list *list, struct nouveau_pushbuf *push, u32 *sequence)
{
- struct nvc0_screen *screen = nvc0_screen(pscreen);
- struct nouveau_pushbuf *push = screen->base.pushbuf;
+ struct nouveau_bo *bo = list->data;
/* we need to do it after possible flush in MARK_RING */
- *sequence = ++screen->base.fence.sequence;
+ *sequence = ++list->sequence;
assert(PUSH_AVAIL(push) + push->rsvd_kick >= 5);
PUSH_DATA (push, NVC0_FIFO_PKHDR_SQ(NVC0_3D(QUERY_ADDRESS_HIGH), 4));
- PUSH_DATAh(push, screen->fence.bo->offset);
- PUSH_DATA (push, screen->fence.bo->offset);
+ PUSH_DATAh(push, bo->offset);
+ PUSH_DATA (push, bo->offset);
PUSH_DATA (push, *sequence);
PUSH_DATA (push, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT |
(0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT));
}
-static u32
-nvc0_screen_fence_update(struct pipe_screen *pscreen)
+static uint32_t
+nvc0_screen_fence_update(struct nouveau_fence_list *list)
{
- struct nvc0_screen *screen = nvc0_screen(pscreen);
- uint32_t *map = screen->fence.bo->map;
+ struct nouveau_bo *bo = list->data;
+ uint32_t *map = bo->map;
return map[0];
}
@@ -973,10 +972,10 @@ nvc0_screen_create(struct nouveau_device *dev)
if (ret)
FAIL_SCREEN_INIT("Error allocating fence BO: %d\n", ret);
nouveau_bo_map(screen->fence.bo, 0, NULL);
+ screen->base.fence.data = screen->fence.bo;
screen->base.fence.emit = nvc0_screen_fence_emit;
screen->base.fence.update = nvc0_screen_fence_update;
-
ret = nouveau_object_new(chan, (dev->chipset < 0xe0) ? 0x1f906e : 0x906e,
NVIF_CLASS_SW_GF100, NULL, 0, &screen->nvsw);
if (ret)
@@ -1390,7 +1389,7 @@ nvc0_screen_create(struct nouveau_device *dev)
screen->default_tsc = CALLOC_STRUCT(nv50_tsc_entry);
screen->default_tsc->tsc[0] = G80_TSC_0_SRGB_CONVERSION;
- nouveau_fence_new(&screen->base, &screen->base.fence.current);
+ nouveau_fence_new(&screen->base.fence, &screen->base.fence.current);
return &screen->base;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
index 853ce12b13c..440d00dcc94 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
@@ -362,8 +362,8 @@ nvc0_mt_sync(struct nvc0_context *nvc0, struct nv50_miptree *mt, unsigned usage)
return !nouveau_bo_wait(mt->base.bo, access, nvc0->base.client);
}
if (usage & PIPE_TRANSFER_WRITE)
- return !mt->base.fence || nouveau_fence_wait(mt->base.fence, &nvc0->base.debug);
- return !mt->base.fence_wr || nouveau_fence_wait(mt->base.fence_wr, &nvc0->base.debug);
+ return !mt->base.fence || nouveau_fence_wait(mt->base.fence, nvc0->base.pushbuf, &nvc0->base.debug);
+ return !mt->base.fence_wr || nouveau_fence_wait(mt->base.fence_wr, nvc0->base.pushbuf, &nvc0->base.debug);
}
void *
@@ -518,7 +518,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->base.fence.current,
+ nouveau_fence_work(nvc0->screen->base.fence.current, nvc0->base.pushbuf,
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_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
index 66de6d9e2fa..31bb910c551 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
@@ -554,7 +554,7 @@ nvc0_draw_vbo_kick_notify(struct nouveau_pushbuf *push)
{
struct nvc0_screen *screen = push->user_priv;
- nouveau_fence_update(&screen->base, true);
+ nouveau_fence_update(&screen->base.fence, true);
NOUVEAU_DRV_STAT(&screen->base, pushbuf_count, 1);
}
--
2.19.2
More information about the mesa-dev
mailing list