Signed-off-by: Karol Herbst <kher...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev