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, ¤t); + nouveau_fence_ref(fence_list->current, ¤t); nouveau_fence_wait(current, NULL); nouveau_fence_ref(NULL, ¤t); - 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 0ec79fb8c43..fd87f19a6c7 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 38a105c54f2..11a5975ba76 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -624,7 +624,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 e12519ceb3a..056166b04de 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -715,7 +715,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;