Skip to contentSkip to conversation

gallium/nouveau: decouple nouveau_fence implementation from screen

PATCH In review Maarten Lankhorst 3 participants 3 messages Jun 16, 2014 1 message not in the archive

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 gallium/nouveau: decouple nouveau_fence implementation from screen

---
 src/gallium/drivers/nouveau/nouveau_fence.c     | 76 ++++++++++++-------------
 src/gallium/drivers/nouveau/nouveau_fence.h     | 22 +++++--
 src/gallium/drivers/nouveau/nouveau_screen.c    |  9 +++
 src/gallium/drivers/nouveau/nouveau_screen.h    | 14 ++---
 src/gallium/drivers/nouveau/nv30/nv30_context.c |  4 +-
 src/gallium/drivers/nouveau/nv30/nv30_screen.c  | 23 +++++---
 src/gallium/drivers/nouveau/nv50/nv50_context.c |  4 +-
 src/gallium/drivers/nouveau/nv50/nv50_screen.c  | 20 +++++--
 src/gallium/drivers/nouveau/nv50/nv50_vbo.c     |  2 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_context.c |  4 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.c  | 19 +++++--
 src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c     |  2 +-
 12 files changed, 121 insertions(+), 78 deletions(-)
src/gallium/drivers/nouveau/nouveau_fence.c +38 -38
index c686710..09b3b1e 100644
@@ -31,14 +31,14 @@
 #endif
 
 boolean
-nouveau_fence_new(struct nouveau_screen *screen, struct nouveau_fence **fence,
+nouveau_fence_new(struct nouveau_fence_mgr *mgr, struct nouveau_fence **fence,
                   boolean emit)
 {
    *fence = CALLOC_STRUCT(nouveau_fence);
    if (!*fence)
       return FALSE;
 
-   (*fence)->screen = screen;
+   (*fence)->mgr = mgr;
    (*fence)->ref = 1;
    LIST_INITHEAD(&(*fence)->work);
 
@@ -83,7 +83,7 @@ nouveau_fence_work(struct nouveau_fence *fence,
 void
 nouveau_fence_emit(struct nouveau_fence *fence)
 {
-   struct nouveau_screen *screen = fence->screen;
+   struct nouveau_fence_mgr *mgr = fence->mgr;
 
    assert(fence->state == NOUVEAU_FENCE_STATE_AVAILABLE);
 
@@ -92,14 +92,14 @@ nouveau_fence_emit(struct nouveau_fence *fence)
 
    ++fence->ref;
 
-   if (screen->fence.tail)
-      screen->fence.tail->next = fence;
+   if (mgr->tail)
+      mgr->tail->next = fence;
    else
-      screen->fence.head = fence;
+      mgr->head = fence;
 
-   screen->fence.tail = fence;
+   mgr->tail = fence;
 
-   screen->fence.emit(&screen->base, &fence->sequence);
+   mgr->emit(mgr, &fence->sequence);
 
    assert(fence->state == NOUVEAU_FENCE_STATE_EMITTING);
    fence->state = NOUVEAU_FENCE_STATE_EMITTED;
@@ -109,19 +109,19 @@ void
 nouveau_fence_del(struct nouveau_fence *fence)
 {
    struct nouveau_fence *it;
-   struct nouveau_screen *screen = fence->screen;
+   struct nouveau_fence_mgr *mgr = fence->mgr;
 
    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 == mgr->head) {
+         mgr->head = fence->next;
+         if (!mgr->head)
+            mgr->tail = NULL;
       } else {
-         for (it = screen->fence.head; it && it->next != fence; it = it->next);
+         for (it = mgr->head; it && it->next != fence; it = it->next);
          it->next = fence->next;
-         if (screen->fence.tail == fence)
-            screen->fence.tail = it;
+         if (mgr->tail == fence)
+            mgr->tail = it;
       }
    }
 
@@ -134,17 +134,17 @@ nouveau_fence_del(struct nouveau_fence *fence)
 }
 
 void
-nouveau_fence_update(struct nouveau_screen *screen, boolean flushed)
+nouveau_fence_update(struct nouveau_fence_mgr *mgr, boolean flushed)
 {
    struct nouveau_fence *fence;
    struct nouveau_fence *next = NULL;
-   u32 sequence = screen->fence.update(&screen->base);
+   u32 sequence = mgr->update(mgr);
 
-   if (screen->fence.sequence_ack == sequence)
+   if (mgr->sequence_ack == sequence)
       return;
-   screen->fence.sequence_ack = sequence;
+   mgr->sequence_ack = sequence;
 
-   for (fence = screen->fence.head; fence; fence = next) {
+   for (fence = mgr->head; fence; fence = next) {
       next = fence->next;
       sequence = fence->sequence;
 
@@ -153,12 +153,12 @@ nouveau_fence_update(struct nouveau_screen *screen, boolean flushed)
       nouveau_fence_trigger_work(fence);
       nouveau_fence_ref(NULL, &fence);
 
-      if (sequence == screen->fence.sequence_ack)
+      if (sequence == mgr->sequence_ack)
          break;
    }
-   screen->fence.head = next;
+   mgr->head = next;
    if (!next)
-      screen->fence.tail = NULL;
+      mgr->tail = NULL;
 
    if (flushed) {
       for (fence = next; fence; fence = fence->next)
@@ -172,10 +172,10 @@ nouveau_fence_update(struct nouveau_screen *screen, boolean flushed)
 boolean
 nouveau_fence_signalled(struct nouveau_fence *fence)
 {
-   struct nouveau_screen *screen = fence->screen;
+   struct nouveau_fence_mgr *mgr = fence->mgr;
 
    if (fence->state >= NOUVEAU_FENCE_STATE_EMITTED)
-      nouveau_fence_update(screen, FALSE);
+      nouveau_fence_update(mgr, FALSE);
 
    return fence->state == NOUVEAU_FENCE_STATE_SIGNALLED;
 }
@@ -183,7 +183,7 @@ nouveau_fence_signalled(struct nouveau_fence *fence)
 boolean
 nouveau_fence_wait(struct nouveau_fence *fence)
 {
-   struct nouveau_screen *screen = fence->screen;
+   struct nouveau_fence_mgr *mgr = fence->mgr;
    uint32_t spins = 0;
 
    /* wtf, someone is waiting on a fence in flush_notify handler? */
@@ -193,19 +193,19 @@ nouveau_fence_wait(struct nouveau_fence *fence)
       nouveau_fence_emit(fence);
 
    if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
-      if (nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel))
+      if (mgr->flush(mgr))
          return FALSE;
 
-   if (fence == screen->fence.current)
-      nouveau_fence_next(screen);
+   if (fence == mgr->current)
+      nouveau_fence_next(mgr);
 
    do {
-      nouveau_fence_update(screen, FALSE);
+      nouveau_fence_update(mgr, FALSE);
 
       if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED)
          return TRUE;
       if (!spins)
-         NOUVEAU_DRV_STAT(screen, any_non_kernel_fence_sync_count, 1);
+         NOUVEAU_DRV_STAT(mgr->screen, any_non_kernel_fence_sync_count, 1);
       spins++;
 #ifdef PIPE_OS_UNIX
       if (!(spins % 8)) /* donate a few cycles */
@@ -215,18 +215,18 @@ nouveau_fence_wait(struct nouveau_fence *fence)
 
    debug_printf("Wait on fence %u (ack = %u, next = %u) timed out !\n",
                 fence->sequence,
-                screen->fence.sequence_ack, screen->fence.sequence);
+                mgr->sequence_ack, mgr->sequence);
 
    return FALSE;
 }
 
 void
-nouveau_fence_next(struct nouveau_screen *screen)
+nouveau_fence_next(struct nouveau_fence_mgr *mgr)
 {
-   if (screen->fence.current->state < NOUVEAU_FENCE_STATE_EMITTING)
-      nouveau_fence_emit(screen->fence.current);
+   if (mgr->current->state < NOUVEAU_FENCE_STATE_EMITTING)
+      nouveau_fence_emit(mgr->current);
 
-   nouveau_fence_ref(NULL, &screen->fence.current);
+   nouveau_fence_ref(NULL, &mgr->current);
 
-   nouveau_fence_new(screen, &screen->fence.current, FALSE);
+   nouveau_fence_new(mgr, &mgr->current, FALSE);
 }
src/gallium/drivers/nouveau/nouveau_fence.h +18 -4
index 3984a9a..cb44dd3 100644
@@ -11,6 +11,20 @@
 #define NOUVEAU_FENCE_STATE_FLUSHED   3
 #define NOUVEAU_FENCE_STATE_SIGNALLED 4
 
+struct nouveau_fence_mgr {
+	struct nouveau_fence *head;
+	struct nouveau_fence *tail;
+	struct nouveau_fence *current;
+	uint32_t sequence;
+	uint32_t sequence_ack;
+	int  (*flush)(struct nouveau_fence_mgr *);
+	void (*emit)(struct nouveau_fence_mgr *, uint32_t *sequence);
+	uint32_t (*update)(struct nouveau_fence_mgr *);
+
+	/* for driver stats */
+	struct nouveau_screen *screen;
+};
+
 struct nouveau_fence_work {
    struct list_head list;
    void (*func)(void *);
@@ -19,7 +33,7 @@ struct nouveau_fence_work {
 
 struct nouveau_fence {
    struct nouveau_fence *next;
-   struct nouveau_screen *screen;
+   struct nouveau_fence_mgr *mgr;
    int state;
    int ref;
    uint32_t sequence;
@@ -29,11 +43,11 @@ struct nouveau_fence {
 void nouveau_fence_emit(struct nouveau_fence *);
 void nouveau_fence_del(struct nouveau_fence *);
 
-boolean nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence **,
+boolean nouveau_fence_new(struct nouveau_fence_mgr *, struct nouveau_fence **,
                           boolean emit);
 boolean nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *);
-void    nouveau_fence_update(struct nouveau_screen *, boolean flushed);
-void    nouveau_fence_next(struct nouveau_screen *);
+void    nouveau_fence_update(struct nouveau_fence_mgr *, boolean flushed);
+void    nouveau_fence_next(struct nouveau_fence_mgr *);
 boolean nouveau_fence_wait(struct nouveau_fence *);
 boolean nouveau_fence_signalled(struct nouveau_fence *);
 
src/gallium/drivers/nouveau/nouveau_screen.c +9 -0
index 9d71bf7..9ea3a46 100644
@@ -223,3 +223,12 @@ nouveau_screen_fini(struct nouveau_screen *screen)
 
 	nouveau_device_del(&screen->device);
 }
+
+int nouveau_screen_fence_kick(struct nouveau_fence_mgr *mgr)
+{
+	struct nouveau_screen *screen = NULL;
+
+	screen = container_of(mgr, screen, fence);
+
+	return nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel);
+}
src/gallium/drivers/nouveau/nouveau_screen.h +5 -9
index cf06f7e..7682214 100644
@@ -4,6 +4,8 @@
 #include "pipe/p_screen.h"
 #include "util/u_memory.h"
 
+#include "nouveau_fence.h"
+
 #ifdef DEBUG
 # define NOUVEAU_ENABLE_DRIVER_STATISTICS
 #endif
@@ -34,15 +36,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_mgr fence;
 
 	struct nouveau_mman *mm_VRAM;
 	struct nouveau_mman *mm_GART;
@@ -132,4 +126,6 @@ void nouveau_screen_fini(struct nouveau_screen *);
 
 void nouveau_screen_init_vdec(struct nouveau_screen *);
 
+int nouveau_screen_fence_kick(struct nouveau_fence_mgr *);
+
 #endif
src/gallium/drivers/nouveau/nv30/nv30_context.c +2 -2
index f325c5c..35c66f1 100644
@@ -44,8 +44,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);
+   nouveau_fence_update(&screen->fence, TRUE);
 
    if (push->bufctx) {
       struct nouveau_bufref *bref;
src/gallium/drivers/nouveau/nv30/nv30_screen.c +16 -7
index fb9378c..a0518c3 100644
@@ -287,10 +287,13 @@ 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_mgr *mgr, uint32_t *sequence)
 {
-   struct nv30_screen *screen = nv30_screen(pscreen);
-   struct nouveau_pushbuf *push = screen->base.pushbuf;
+   struct nv30_screen *screen = NULL;
+   struct nouveau_pushbuf *push;
+
+   screen = container_of(mgr, screen, base.fence);
+   push = screen->base.pushbuf;
 
    *sequence = ++screen->base.fence.sequence;
 
@@ -300,10 +303,14 @@ 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_mgr *mgr)
 {
-   struct nv30_screen *screen = nv30_screen(pscreen);
-   struct nv04_notify *fence = screen->fence->data;
+   struct nv30_screen *screen = NULL;
+   struct nv04_notify *fence;
+
+   screen = container_of(mgr, screen, base.fence);
+   fence = screen->fence->data;
+
    return *(uint32_t *)((char *)screen->notify->map + fence->offset);
 }
 
@@ -404,6 +411,8 @@ nv30_screen_create(struct nouveau_device *dev)
    nv30_resource_screen_init(pscreen);
    nouveau_screen_init_vdec(&screen->base);
 
+   screen->base.fence.screen = &screen->base;
+   screen->base.fence.flush = nouveau_screen_fence_kick;
    screen->base.fence.emit = nv30_screen_fence_emit;
    screen->base.fence.update = nv30_screen_fence_update;
 
@@ -607,6 +616,6 @@ nv30_screen_create(struct nouveau_device *dev)
 
    nouveau_pushbuf_kick(push, push->channel);
 
-   nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
+   nouveau_fence_new(&screen->base.fence, &screen->base.fence.current, FALSE);
    return pscreen;
 }
src/gallium/drivers/nouveau/nv50/nv50_context.c +2 -2
index f844592..af1e436 100644
@@ -83,8 +83,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);
+      nouveau_fence_update(&screen->base.fence, TRUE);
       if (screen->cur_ctx)
          screen->cur_ctx->state.flushed = TRUE;
    }
src/gallium/drivers/nouveau/nv50/nv50_screen.c +14 -6
index 015f139..8195650 100644
@@ -348,10 +348,13 @@ 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_mgr *mgr, u32 *sequence)
 {
-   struct nv50_screen *screen = nv50_screen(pscreen);
-   struct nouveau_pushbuf *push = screen->base.pushbuf;
+   struct nv50_screen *screen = NULL;
+   struct nouveau_pushbuf *push;
+
+   screen = container_of(mgr, screen, base.fence);
+   push = screen->base.pushbuf;
 
    /* we need to do it after possible flush in MARK_RING */
    *sequence = ++screen->base.fence.sequence;
@@ -369,9 +372,12 @@ 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_mgr *mgr)
 {
-   return nv50_screen(pscreen)->fence.map[0];
+   struct nv50_screen *screen = NULL;
+
+   screen = container_of(mgr, screen, base.fence);
+   return screen->fence.map[0];
 }
 
 static void
@@ -717,6 +723,8 @@ nv50_screen_create(struct nouveau_device *dev)
 
    nouveau_bo_map(screen->fence.bo, 0, NULL);
    screen->fence.map = screen->fence.bo->map;
+   screen->base.fence.screen = &screen->base;
+   screen->base.fence.flush = nouveau_screen_fence_kick;
    screen->base.fence.emit = nv50_screen_fence_emit;
    screen->base.fence.update = nv50_screen_fence_update;
 
@@ -850,7 +858,7 @@ nv50_screen_create(struct nouveau_device *dev)
 
    nv50_screen_init_hwctx(screen);
 
-   nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
+   nouveau_fence_new(&screen->base.fence, &screen->base.fence.current, FALSE);
 
    return pscreen;
 
src/gallium/drivers/nouveau/nv50/nv50_vbo.c +1 -1
index 7c2b7ff..3fa2f05 100644
@@ -737,7 +737,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);
 }
src/gallium/drivers/nouveau/nvc0/nvc0_context.c +2 -2
index e5040c4..52f8a57 100644
@@ -147,8 +147,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);
+      nouveau_fence_update(&screen->base.fence, TRUE);
       if (screen->cur_ctx)
          screen->cur_ctx->state.flushed = TRUE;
    }
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +13 -6
index 3e6b011..2a317af 100644
@@ -490,10 +490,13 @@ 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_mgr *mgr, u32 *sequence)
 {
-   struct nvc0_screen *screen = nvc0_screen(pscreen);
-   struct nouveau_pushbuf *push = screen->base.pushbuf;
+   struct nvc0_screen *screen = NULL;
+   struct nouveau_pushbuf *push;
+
+   screen = container_of(mgr, screen, base.fence);
+   push = screen->base.pushbuf;
 
    /* we need to do it after possible flush in MARK_RING */
    *sequence = ++screen->base.fence.sequence;
@@ -507,9 +510,11 @@ nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
 }
 
 static u32
-nvc0_screen_fence_update(struct pipe_screen *pscreen)
+nvc0_screen_fence_update(struct nouveau_fence_mgr *mgr)
 {
-   struct nvc0_screen *screen = nvc0_screen(pscreen);
+   struct nvc0_screen *screen = NULL;
+
+   screen = container_of(mgr, screen, base.fence);
    return screen->fence.map[0];
 }
 
@@ -639,6 +644,8 @@ nvc0_screen_create(struct nouveau_device *dev)
       goto fail;
    nouveau_bo_map(screen->fence.bo, 0, NULL);
    screen->fence.map = screen->fence.bo->map;
+   screen->base.fence.screen = &screen->base;
+   screen->base.fence.flush = nouveau_screen_fence_kick;
    screen->base.fence.emit = nvc0_screen_fence_emit;
    screen->base.fence.update = nvc0_screen_fence_update;
 
@@ -997,7 +1004,7 @@ nvc0_screen_create(struct nouveau_device *dev)
    if (!nvc0_blitter_create(screen))
       goto fail;
 
-   nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
+   nouveau_fence_new(&screen->base.fence, &screen->base.fence.current, FALSE);
 
    return pscreen;
 
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c +1 -1
index 83d406d..6406cf5 100644
@@ -559,7 +559,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);
 }
Signature · 1 line
2.0.0

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw

PATCH 2/2 gallium/nouveau: move pushbuf and fences to context

nv30 seems to not support dma objects with offset, so simply extend the query_heap to cover the entire notifier, and use a offset in nv30_context_kick_notify.

---
 src/gallium/drivers/nouveau/nouveau_buffer.c       |  14 +-
 src/gallium/drivers/nouveau/nouveau_context.h      |   5 +
 src/gallium/drivers/nouveau/nouveau_fence.c        |  10 +
 src/gallium/drivers/nouveau/nouveau_fence.h        |   6 +-
 src/gallium/drivers/nouveau/nouveau_screen.c       |  16 --
 src/gallium/drivers/nouveau/nouveau_screen.h       |   5 -
 src/gallium/drivers/nouveau/nv30/nv30_context.c    | 104 +++++++--
 src/gallium/drivers/nouveau/nv30/nv30_context.h    |   2 +
 src/gallium/drivers/nouveau/nv30/nv30_draw.c       |   4 +-
 src/gallium/drivers/nouveau/nv30/nv30_query.c      |   6 +-
 src/gallium/drivers/nouveau/nv30/nv30_screen.c     | 160 ++++---------
 src/gallium/drivers/nouveau/nv30/nv30_screen.h     |   4 +-
 .../drivers/nouveau/nv30/nv30_state_validate.c     |   9 +-
 src/gallium/drivers/nouveau/nv50/nv50_context.c    | 128 ++++++++---
 src/gallium/drivers/nouveau/nv50/nv50_context.h    |  33 ++-
 src/gallium/drivers/nouveau/nv50/nv50_program.c    |   2 +-
 src/gallium/drivers/nouveau/nv50/nv50_query.c      |   2 +-
 src/gallium/drivers/nouveau/nv50/nv50_screen.c     |  79 +------
 src/gallium/drivers/nouveau/nv50/nv50_screen.h     |  35 +--
 .../drivers/nouveau/nv50/nv50_state_validate.c     |   8 +-
 src/gallium/drivers/nouveau/nv50/nv50_surface.c    |   6 +-
 src/gallium/drivers/nouveau/nv50/nv50_vbo.c        |   6 +-
 src/gallium/drivers/nouveau/nv50/nv84_video.c      |  16 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_compute.c    |  20 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_compute.h    |   4 +
 src/gallium/drivers/nouveau/nvc0/nvc0_context.c    | 133 ++++++++---
 src/gallium/drivers/nouveau/nvc0/nvc0_context.h    |  32 +++
 src/gallium/drivers/nouveau/nvc0/nvc0_query.c      |   4 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.c     | 253 +++++++++------------
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.h     |  35 +--
 .../drivers/nouveau/nvc0/nvc0_state_validate.c     |   6 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_surface.c    |  10 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c        |   6 +-
 src/gallium/drivers/nouveau/nvc0/nve4_compute.c    |  22 +-
 src/gallium/drivers/nouveau/nvc0/nve4_compute.h    |   3 +
 35 files changed, 625 insertions(+), 563 deletions(-)
src/gallium/drivers/nouveau/nouveau_buffer.c +7 -7
index 49ff100..8affb0e 100644
@@ -217,8 +217,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.current, &buf->fence);
+   nouveau_fence_ref(nv->fence.current, &buf->fence_wr);
 }
 
 /* Does a CPU wait for the buffer's backing data to become reliably accessible
@@ -288,7 +288,7 @@ nouveau_buffer_transfer_del(struct nouveau_context *nv,
       if (likely(tx->bo)) {
          nouveau_bo_ref(NULL, &tx->bo);
          if (tx->mm)
-            release_allocation(&tx->mm, nv->screen->fence.current);
+            release_allocation(&tx->mm, nv->fence.current);
       } else {
          align_free(tx->map -
                     (tx->base.box.x & NOUVEAU_MIN_BUFFER_MAP_ALIGN_MASK));
@@ -572,11 +572,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.current, &dst->fence);
+      nouveau_fence_ref(nv->fence.current, &dst->fence_wr);
 
       src->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
-      nouveau_fence_ref(nv->screen->fence.current, &src->fence);
+      nouveau_fence_ref(nv->fence.current, &src->fence);
    } else {
       struct pipe_box src_box;
       src_box.x = srcx;
@@ -787,7 +787,7 @@ nouveau_buffer_migrate(struct nouveau_context *nv,
 
       nouveau_bo_ref(NULL, &bo);
       if (mm)
-         release_allocation(&mm, screen->fence.current);
+         release_allocation(&mm, nv->fence.current);
    } else
    if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) {
       struct nouveau_transfer tx;
src/gallium/drivers/nouveau/nouveau_context.h +5 -0
index 14608d3..48e2a66 100644
@@ -49,6 +49,8 @@ struct nouveau_context {
       uint32_t buf_cache_count;
       uint32_t buf_cache_frame;
    } stats;
+
+   struct nouveau_fence_mgr fence;
 };
 
 static INLINE struct nouveau_context *
@@ -91,6 +93,7 @@ nouveau_context_destroy(struct nouveau_context *ctx)
       if (ctx->scratch.bo[i])
          nouveau_bo_ref(NULL, &ctx->scratch.bo[i]);
 
+   nouveau_pushbuf_del(&ctx->pushbuf);
    FREE(ctx);
 }
 
@@ -106,4 +109,6 @@ nouveau_context_update_frame_stats(struct nouveau_context *nv)
    }
 }
 
+int nouveau_context_fence_kick(struct nouveau_fence_mgr *);
+
 #endif
src/gallium/drivers/nouveau/nouveau_fence.c +10 -0
index 09b3b1e..b751971 100644
@@ -23,6 +23,7 @@
 #include "util/u_double_list.h"
 
 #include "nouveau_screen.h"
+#include "nouveau_context.h"
 #include "nouveau_winsys.h"
 #include "nouveau_fence.h"
 
@@ -30,6 +31,15 @@
 #include <sched.h>
 #endif
 
+int nouveau_context_fence_kick(struct nouveau_fence_mgr *mgr)
+{
+   struct nouveau_context *context = NULL;
+
+   context = container_of(mgr, context, fence);
+
+   return nouveau_pushbuf_kick(context->pushbuf, context->pushbuf->channel);
+}
+
 boolean
 nouveau_fence_new(struct nouveau_fence_mgr *mgr, struct nouveau_fence **fence,
                   boolean emit)
src/gallium/drivers/nouveau/nouveau_fence.h +3 -3
index cb44dd3..cdc60ed 100644
@@ -32,10 +32,10 @@ struct nouveau_fence_work {
 };
 
 struct nouveau_fence {
+   int32_t ref;
    struct nouveau_fence *next;
    struct nouveau_fence_mgr *mgr;
    int state;
-   int ref;
    uint32_t sequence;
    struct list_head work;
 };
@@ -55,10 +55,10 @@ static INLINE void
 nouveau_fence_ref(struct nouveau_fence *fence, struct nouveau_fence **ref)
 {
    if (fence)
-      ++fence->ref;
+      p_atomic_inc(&fence->ref);
 
    if (*ref) {
-      if (--(*ref)->ref == 0)
+      if (p_atomic_dec_zero(&(*ref)->ref))
          nouveau_fence_del(*ref);
    }
 
src/gallium/drivers/nouveau/nouveau_screen.c +0 -16
index 9ea3a46..f78b6e1 100644
@@ -167,11 +167,6 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
 	ret = nouveau_client_new(screen->device, &screen->client);
 	if (ret)
 		return ret;
-	ret = nouveau_pushbuf_new(screen->client, screen->channel,
-				  4, 512 * 1024, 1,
-				  &screen->pushbuf);
-	if (ret)
-		return ret;
 
         /* getting CPU time first appears to be more accurate */
         screen->cpu_gpu_time_delta = os_time_get();
@@ -216,19 +211,8 @@ 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_client_del(&screen->client);
 	nouveau_object_del(&screen->channel);
 
 	nouveau_device_del(&screen->device);
 }
-
-int nouveau_screen_fence_kick(struct nouveau_fence_mgr *mgr)
-{
-	struct nouveau_screen *screen = NULL;
-
-	screen = container_of(mgr, screen, fence);
-
-	return nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel);
-}
src/gallium/drivers/nouveau/nouveau_screen.h +0 -5
index 7682214..c1e9bc3 100644
@@ -22,7 +22,6 @@ struct nouveau_screen {
 	struct nouveau_device *device;
 	struct nouveau_object *channel;
 	struct nouveau_client *client;
-	struct nouveau_pushbuf *pushbuf;
 
 	int refcount;
 
@@ -36,8 +35,6 @@ struct nouveau_screen {
 
 	uint16_t class_3d;
 
-	struct nouveau_fence_mgr fence;
-
 	struct nouveau_mman *mm_VRAM;
 	struct nouveau_mman *mm_GART;
 
@@ -126,6 +123,4 @@ void nouveau_screen_fini(struct nouveau_screen *);
 
 void nouveau_screen_init_vdec(struct nouveau_screen *);
 
-int nouveau_screen_fence_kick(struct nouveau_fence_mgr *);
-
 #endif
src/gallium/drivers/nouveau/nv30/nv30_context.c +84 -20

180 lines not on this page · raw message

src/gallium/drivers/nouveau/nv30/nv30_context.h +2 -0
index 7b32aae..e9180a5 100644
@@ -97,6 +97,8 @@ struct nv30_context {
       unsigned dirty_samplers;
    } fragprog;
 
+   struct nouveau_heap *fence;
+
    struct pipe_framebuffer_state framebuffer;
    struct pipe_blend_color blend_colour;
    struct pipe_stencil_ref stencil_ref;
src/gallium/drivers/nouveau/nv30/nv30_draw.c +2 -2
index 3575c3d..2ee5e58 100644
@@ -119,7 +119,7 @@ nv30_render_draw_elements(struct vbuf_render *render,
 {
    struct nv30_render *r = nv30_render(render);
    struct nv30_context *nv30 = r->nv30;
-   struct nouveau_pushbuf *push = nv30->screen->base.pushbuf;
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
    unsigned i;
 
    BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
@@ -269,7 +269,7 @@ nv30_render_validate(struct nv30_context *nv30)
    struct nv30_render *r = nv30_render(nv30->draw->render);
    struct nv30_rasterizer_stateobj *rast = nv30->rast;
    struct pipe_screen *pscreen = &nv30->screen->base.base;
-   struct nouveau_pushbuf *push = nv30->screen->base.pushbuf;
+   struct nouveau_pushbuf *push = nv30->base.pushbuf;
    struct nouveau_object *eng3d = nv30->screen->eng3d;
    struct nv30_vertprog *vp = nv30->vertprog.program;
    struct vertex_info *vinfo = &r->vertex_info;
src/gallium/drivers/nouveau/nv30/nv30_query.c +5 -1
index 01b3817..6b27267 100644
@@ -39,7 +39,7 @@ struct nv30_query_object {
 static volatile void *
 nv30_ntfy(struct nv30_screen *screen, struct nv30_query_object *qo)
 {
-   struct nv04_notify *query = screen->query->data;
+   struct nv04_notify *query = screen->ntfy->data;
    struct nouveau_bo *notify = screen->notify;
    volatile void *ntfy = NULL;
 
@@ -76,6 +76,10 @@ nv30_query_object_new(struct nv30_screen *screen)
     * spin waiting for one to become free
     */
    while (nouveau_heap_alloc(screen->query_heap, 32, NULL, &qo->hw)) {
+      if (&screen->queries == screen->queries.next) {
+         FREE(qo);
+         return NULL;
+      }
       oq = LIST_FIRST_ENTRY(struct nv30_query_object, &screen->queries, list);
       nv30_query_object_del(screen, &oq);
    }
src/gallium/drivers/nouveau/nv30/nv30_screen.c +48 -112

242 lines not on this page · raw message

src/gallium/drivers/nouveau/nv30/nv30_screen.h +2 -2
index 0b3bbbb..7a8c339 100644
@@ -22,9 +22,7 @@ struct nv30_screen {
    struct nouveau_bo *notify;
 
    struct nouveau_object *ntfy;
-   struct nouveau_object *fence;
 
-   struct nouveau_object *query;
    struct nouveau_heap *query_heap;
    struct list_head queries;
 
@@ -46,4 +44,6 @@ nv30_screen(struct pipe_screen *pscreen)
    return (struct nv30_screen *)pscreen;
 }
 
+extern void nv30_screen_init_hwctx(struct nv30_screen *screen, struct nouveau_pushbuf *push);
+
 #endif
src/gallium/drivers/nouveau/nv30/nv30_state_validate.c +5 -4
index f227559..0daab1b 100644
@@ -432,8 +432,10 @@ nv30_state_context_switch(struct nv30_context *nv30)
 {
    struct nv30_context *prev = nv30->screen->cur_ctx;
 
-   if (prev)
+   if (prev) {
+      PUSH_KICK(prev->base.pushbuf);
       nv30->state = prev->state;
+   }
    nv30->dirty = NV30_NEW_ALL;
 
    if (!nv30->vertex)
@@ -458,7 +460,6 @@ nv30_state_context_switch(struct nv30_context *nv30)
 boolean
 nv30_state_validate(struct nv30_context *nv30, boolean 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;
@@ -516,13 +517,13 @@ nv30_state_validate(struct nv30_context *nv30, boolean 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.current, &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.current, &res->fence_wr);
             res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
          }
       }
src/gallium/drivers/nouveau/nv50/nv50_context.c +97 -31

199 lines not on this page · raw message

src/gallium/drivers/nouveau/nv50/nv50_context.h +32 -1
index 3b7cb18..529a6da 100644
@@ -186,6 +186,13 @@ struct nv50_context {
 
    struct nv50_blitctx *blit;
 
+   struct {
+      struct nouveau_mm_allocation *mm;
+      struct nouveau_bo *bo;
+      unsigned ofs;
+      u32 *map;
+   } fence;
+
 #ifdef NV50_WITH_DRAW_MODULE
    struct draw_context *draw;
 #endif
@@ -218,10 +225,34 @@ nv50_context_shader_stage(unsigned pipe)
    }
 }
 
+static INLINE void
+nv50_resource_fence(struct nv50_context *nv50, struct nv04_resource *res, uint32_t flags)
+{
+   if (res->mm) {
+      nouveau_fence_ref(nv50->base.fence.current, &res->fence);
+      if (flags & NOUVEAU_BO_WR)
+         nouveau_fence_ref(nv50->base.fence.current, &res->fence_wr);
+   }
+}
+
+static INLINE void
+nv50_resource_validate(struct nv50_context *nv50, 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(nv50, res, flags);
+   }
+}
+
 /* nv50_context.c */
 struct pipe_context *nv50_create(struct pipe_screen *, void *);
 
-void nv50_bufctx_fence(struct nouveau_bufctx *, boolean on_flush);
+void nv50_bufctx_fence(struct nv50_context *nv50, struct nouveau_bufctx *, boolean on_flush);
 
 void nv50_default_kick_notify(struct nouveau_pushbuf *);
 
src/gallium/drivers/nouveau/nv50/nv50_program.c +1 -1
index 4744a3c..c489a0d 100644
@@ -445,7 +445,7 @@ nv50_program_upload_code(struct nv50_context *nv50, struct nv50_program *prog)
    }
    prog->code_base = prog->mem->start;
 
-   ret = nv50_tls_realloc(nv50->screen, prog->tls_space);
+   ret = nv50_tls_realloc(nv50, prog->tls_space);
    if (ret < 0) {
       nouveau_heap_free(&prog->mem);
       return FALSE;
src/gallium/drivers/nouveau/nv50/nv50_query.c +1 -1
index 6a17139..44ac2e1 100644
@@ -68,7 +68,7 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
          if (q->ready)
             nouveau_mm_free(q->mm);
          else
-            nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work,
+            nouveau_fence_work(nv50->base.fence.current, nouveau_mm_free_work,
                                q->mm);
       }
    }
src/gallium/drivers/nouveau/nv50/nv50_screen.c +5 -74

123 lines not on this page · raw message

src/gallium/drivers/nouveau/nv50/nv50_screen.h +3 -32
index f8ce365..db69b67 100644
@@ -59,11 +59,6 @@ struct nv50_screen {
       uint32_t lock[NV50_TSC_MAX_ENTRIES / 32];
    } tsc;
 
-   struct {
-      uint32_t *map;
-      struct nouveau_bo *bo;
-   } fence;
-
    struct nouveau_object *sync;
 
    struct nouveau_object *tesla;
@@ -83,32 +78,6 @@ void nv50_blitter_destroy(struct nv50_screen *);
 int nv50_screen_tic_alloc(struct nv50_screen *, void *);
 int nv50_screen_tsc_alloc(struct nv50_screen *, void *);
 
-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;
    uint32_t tic;
@@ -150,6 +119,8 @@ nv50_screen_tsc_free(struct nv50_screen *screen, struct nv50_tsc_entry *tsc)
    }
 }
 
-extern int nv50_tls_realloc(struct nv50_screen *screen, unsigned tls_space);
+extern int nv50_tls_realloc(struct nv50_context *nv50, unsigned tls_space);
+
+extern void nv50_screen_init_hwctx(struct nv50_screen *screen, struct nouveau_pushbuf *push);
 
 #endif
src/gallium/drivers/nouveau/nv50/nv50_state_validate.c +5 -3
index 1dcb961..3c6acb3 100644
@@ -393,8 +393,10 @@ nv50_switch_pipe_context(struct nv50_context *ctx_to)
 {
    struct nv50_context *ctx_from = ctx_to->screen->cur_ctx;
 
-   if (ctx_from)
+   if (ctx_from) {
+      PUSH_KICK(ctx_from->base.pushbuf);
       ctx_to->state = ctx_from->state;
+   }
 
    ctx_to->dirty = ~0;
    ctx_to->viewports_dirty = ~0;
@@ -494,14 +496,14 @@ nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
          PUSH_DATA (nv50->base.pushbuf, 0);
       }
 
-      nv50_bufctx_fence(nv50->bufctx_3d, FALSE);
+      nv50_bufctx_fence(nv50, nv50->bufctx_3d, FALSE);
    }
    nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx_3d);
    ret = nouveau_pushbuf_validate(nv50->base.pushbuf);
 
    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;
 }
src/gallium/drivers/nouveau/nv50/nv50_surface.c +3 -3
index 6e68fb8..fd555d5 100644
@@ -601,8 +601,8 @@ nv50_clear_buffer(struct pipe_context *pipe,
       PUSH_DATA (push, 0x3c);
    }
 
-   nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence);
-   nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence_wr);
+   nouveau_fence_ref(nv50->base.fence.current, &buf->fence);
+   nouveau_fence_ref(nv50->base.fence.current, &buf->fence_wr);
 
    nv50->dirty |= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR;
 }
@@ -1405,7 +1405,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);
 
src/gallium/drivers/nouveau/nv50/nv50_vbo.c +3 -3
index 3fa2f05..9707a45 100644
@@ -735,11 +735,11 @@ nva0_draw_stream_output(struct nv50_context *nv50,
 static void
 nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan)
 {
-   struct nv50_screen *screen = chan->user_priv;
+   struct nv50_context *nv50 = chan->user_priv;
 
-   nouveau_fence_update(&screen->base.fence, TRUE);
+   nouveau_fence_update(&nv50->base.fence, TRUE);
 
-   nv50_bufctx_fence(screen->cur_ctx->bufctx_3d, TRUE);
+   nv50_bufctx_fence(nv50, nv50->bufctx_3d, TRUE);
 }
 
 void
src/gallium/drivers/nouveau/nv50/nv84_video.c +8 -8
index a39f572..d5aa43b 100644
@@ -492,17 +492,17 @@ nv84_create_decoder(struct pipe_context *context,
       surf.offset = dec->vpring->size - 0x1000;
       context->clear_render_target(context, &surf.base, &color, 0, 0, 1024, 1);
 
-      PUSH_SPACE(screen->pushbuf, 5);
-      PUSH_REFN(screen->pushbuf, dec->fence, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+      PUSH_SPACE(nv50->base.pushbuf, 5);
+      PUSH_REFN(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.
        */
-      BEGIN_NV04(screen->pushbuf, NV50_3D(QUERY_ADDRESS_HIGH), 4);
-      PUSH_DATAh(screen->pushbuf, dec->fence->offset);
-      PUSH_DATA (screen->pushbuf, dec->fence->offset);
-      PUSH_DATA (screen->pushbuf, 1);
-      PUSH_DATA (screen->pushbuf, 0xf010);
-      PUSH_KICK (screen->pushbuf);
+      BEGIN_NV04(nv50->base.pushbuf, NV50_3D(QUERY_ADDRESS_HIGH), 4);
+      PUSH_DATAh(nv50->base.pushbuf, dec->fence->offset);
+      PUSH_DATA (nv50->base.pushbuf, dec->fence->offset);
+      PUSH_DATA (nv50->base.pushbuf, 1);
+      PUSH_DATA (nv50->base.pushbuf, 0xf010);
+      PUSH_KICK (nv50->base.pushbuf);
 
       PUSH_SPACE(bsp_push, 2 + 12 + 2 + 4 + 3);
 
src/gallium/drivers/nouveau/nvc0/nvc0_compute.c +13 -7
index ad287a2..f769e67 100644
@@ -26,14 +26,12 @@
 #include "nvc0/nvc0_compute.h"
 
 int
-nvc0_screen_compute_setup(struct nvc0_screen *screen,
-                          struct nouveau_pushbuf *push)
+nvc0_screen_compute_setup(struct nvc0_screen *screen)
 {
    struct nouveau_object *chan = screen->base.channel;
    struct nouveau_device *dev = screen->base.device;
    uint32_t obj_class;
    int ret;
-   int i;
 
    switch (dev->chipset & ~0xf) {
    case 0xc0:
@@ -59,8 +57,18 @@ nvc0_screen_compute_setup(struct nvc0_screen *screen,
 
    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 1 << 12, NULL,
                         &screen->parm);
-   if (ret)
-      return ret;
+   return ret;
+}
+
+void
+nvc0_context_compute_setup(struct nvc0_context *nvc0)
+{
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+   struct nvc0_screen *screen = nvc0->screen;
+   int i;
+
+   if (!screen->parm)
+      return;
 
    BEGIN_NVC0(push, SUBC_COMPUTE(NV01_SUBCHAN_OBJECT), 1);
    PUSH_DATA (push, screen->compute->oclass);
@@ -117,8 +125,6 @@ nvc0_screen_compute_setup(struct nvc0_screen *screen,
    PUSH_DATA (push, (0 << 8) | 1);
 
    /* TODO: textures & samplers */
-
-   return 0;
 }
 
 boolean
src/gallium/drivers/nouveau/nvc0/nvc0_compute.h +4 -0
index 9a1a717..6364c3b 100644
@@ -4,6 +4,10 @@
 #include "nv50/nv50_defs.xml.h"
 #include "nvc0/nvc0_compute.xml.h"
 
+void nvc0_context_compute_setup(struct nvc0_context *nvc0);
+
+int nvc0_screen_compute_setup(struct nvc0_screen *);
+
 boolean
 nvc0_compute_validate_program(struct nvc0_context *nvc0);
 
src/gallium/drivers/nouveau/nvc0/nvc0_context.c +99 -34

202 lines not on this page · raw message

src/gallium/drivers/nouveau/nvc0/nvc0_context.h +32 -0
index 76416a0..823a181 100644
@@ -140,6 +140,13 @@ struct nvc0_context {
       struct nvc0_transform_feedback_state *tfb;
    } state;
 
+   struct {
+      struct nouveau_mm_allocation *mm;
+      struct nouveau_bo *bo;
+      u32 ofs;
+      u32 *map;
+   } fence;
+
    struct nvc0_blend_stateobj *blend;
    struct nvc0_rasterizer_stateobj *rast;
    struct nvc0_zsa_stateobj *zsa;
@@ -356,4 +363,29 @@ void nve4_launch_grid(struct pipe_context *,
 void nvc0_launch_grid(struct pipe_context *,
                       const uint *, const uint *, uint32_t, const void *);
 
+
+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.current, &res->fence);
+      if (flags & NOUVEAU_BO_WR)
+         nouveau_fence_ref(nvc0->base.fence.current, &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);
+   }
+}
+
 #endif
src/gallium/drivers/nouveau/nvc0/nvc0_query.c +2 -2
index 856f685..7438d62 100644
@@ -79,7 +79,7 @@ nvc0_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q, int size)
          if (q->state == NVC0_QUERY_STATE_READY)
             nouveau_mm_free(q->u.mm);
          else
-            nouveau_fence_work(screen->base.fence.current,
+            nouveau_fence_work(nvc0->base.fence.current,
                                nouveau_mm_free_work, q->u.mm);
       }
    }
@@ -411,7 +411,7 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
       break;
    }
    if (q->is64bit)
-      nouveau_fence_ref(nvc0->screen->base.fence.current, &q->fence);
+      nouveau_fence_ref(nvc0->base.fence.current, &q->fence);
 }
 
 static INLINE void
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +109 -144

360 lines not on this page · raw message

src/gallium/drivers/nouveau/nvc0/nvc0_screen.h +5 -30
index c58add5..95843c7 100644
@@ -59,9 +59,11 @@ struct nvc0_screen {
    } tsc;
 
    struct {
+      struct nouveau_mm_allocation *mm;
       struct nouveau_bo *bo;
-      uint32_t *map;
-   } fence;
+      u32 ofs;
+      u32 *map;
+   } notify;
 
    struct {
       struct nvc0_program *prog; /* compute state object to read MP counters */
@@ -250,37 +252,10 @@ void nvc0_screen_make_buffers_resident(struct nvc0_screen *);
 int nvc0_screen_tic_alloc(struct nvc0_screen *, void *);
 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 *);
-
 boolean nvc0_screen_resize_tls_area(struct nvc0_screen *, uint32_t lpos,
                                     uint32_t lneg, uint32_t cstack);
 
-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);
-   }
-}
+int nvc0_screen_init_hwctx(struct nvc0_context *nvc0);
 
 struct nvc0_format {
    uint32_t rt;
src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c +4 -2
index dcec910..e808082 100644
@@ -130,7 +130,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);
         }
@@ -523,8 +523,10 @@ nvc0_switch_pipe_context(struct nvc0_context *ctx_to)
    struct nvc0_context *ctx_from = ctx_to->screen->cur_ctx;
    unsigned s;
 
-   if (ctx_from)
+   if (ctx_from) {
+      PUSH_KICK(ctx_from->base.pushbuf);
       ctx_to->state = ctx_from->state;
+   }
 
    ctx_to->dirty = ~0;
 
src/gallium/drivers/nouveau/nvc0/nvc0_surface.c +5 -5
index c28ec6d..6e4f68b 100644
@@ -332,7 +332,7 @@ nvc0_clear_render_target(struct pipe_context *pipe,
       IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 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);
    }
 
    BEGIN_NIC0(push, NVC0_3D(CLEAR_BUFFERS), sf->depth);
@@ -479,8 +479,8 @@ nvc0_clear_buffer(struct pipe_context *pipe,
       IMMED_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 0x3c);
    }
 
-   nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence);
-   nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence_wr);
+   nouveau_fence_ref(nvc0->base.fence.current, &buf->fence);
+   nouveau_fence_ref(nvc0->base.fence.current, &buf->fence_wr);
    nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
 }
 
@@ -1354,8 +1354,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);
 
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c +3 -3
index 6406cf5..fbb18cf 100644
@@ -557,11 +557,11 @@ nvc0_prim_gl(unsigned prim)
 static void
 nvc0_draw_vbo_kick_notify(struct nouveau_pushbuf *push)
 {
-   struct nvc0_screen *screen = push->user_priv;
+   struct nvc0_context *nvc0 = push->user_priv;
 
-   nouveau_fence_update(&screen->base.fence, TRUE);
+   nouveau_fence_update(&nvc0->base.fence, TRUE);
 
-   NOUVEAU_DRV_STAT(&screen->base, pushbuf_count, 1);
+   NOUVEAU_DRV_STAT(&nvc0->screen->base, pushbuf_count, 1);
 }
 
 static void
src/gallium/drivers/nouveau/nvc0/nve4_compute.c +15 -7
index f243316..90848b4 100644
@@ -34,12 +34,10 @@ static void nve4_compute_dump_launch_desc(const struct nve4_cp_launch_desc *);
 
 
 int
-nve4_screen_compute_setup(struct nvc0_screen *screen,
-                          struct nouveau_pushbuf *push)
+nve4_screen_compute_setup(struct nvc0_screen *screen)
 {
    struct nouveau_device *dev = screen->base.device;
    struct nouveau_object *chan = screen->base.channel;
-   unsigned i;
    int ret;
    uint32_t obj_class;
 
@@ -65,9 +63,21 @@ nve4_screen_compute_setup(struct nvc0_screen *screen,
 
    ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, NVE4_CP_PARAM_SIZE, NULL,
                         &screen->parm);
-   if (ret)
-      return ret;
+   return ret;
+}
+
+void
+nve4_context_compute_setup(struct nvc0_context *nvc0)
+{
+   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+   struct nvc0_screen *screen = nvc0->screen;
+   uint32_t obj_class;
+   unsigned i;
 
+   if (!screen->parm)
+      return;
+
+   obj_class = screen->compute->oclass;
    BEGIN_NVC0(push, SUBC_COMPUTE(NV01_SUBCHAN_OBJECT), 1);
    PUSH_DATA (push, screen->compute->oclass);
 
@@ -176,8 +186,6 @@ nve4_screen_compute_setup(struct nvc0_screen *screen,
 
    BEGIN_NVC0(push, NVE4_COMPUTE(FLUSH), 1);
    PUSH_DATA (push, NVE4_COMPUTE_FLUSH_CB);
-
-   return 0;
 }
 
 
src/gallium/drivers/nouveau/nvc0/nve4_compute.h +3 -0
index 79862b7..a4be963 100644
@@ -5,6 +5,9 @@
 #include "nv50/nv50_defs.xml.h"
 #include "nvc0/nve4_compute.xml.h"
 
+void nve4_context_compute_setup(struct nvc0_context *nvc0);
+int nve4_screen_compute_setup(struct nvc0_screen *);
+
 /* Input space is implemented as c0[], to which we bind the screen->parm bo.
  */
 #define NVE4_CP_INPUT_USER           0x0000
Signature · 1 line
2.0.0
#3 lore raw
In reply to a message not in the archive

Not sure what you did with these patches, but the spacing is all off... makes them hard to read (for me) and also they won't apply for testing. Mind regenerating them? Perhaps you were doing a 2-way merge?

Quoted 504 lines · Maarten Lankhorst
---
 src/gallium/drivers/nouveau/nouveau_fence.c     | 76
++++++++++++-------------
 src/gallium/drivers/nouveau/nouveau_fence.h     | 22 +++++--
 src/gallium/drivers/nouveau/nouveau_screen.c    |  9 +++
 src/gallium/drivers/nouveau/nouveau_screen.h    | 14 ++---
 src/gallium/drivers/nouveau/nv30/nv30_context.c |  4 +-
 src/gallium/drivers/nouveau/nv30/nv30_screen.c  | 23 +++++---
 src/gallium/drivers/nouveau/nv50/nv50_context.c |  4 +-
 src/gallium/drivers/nouveau/nv50/nv50_screen.c  | 20 +++++--
 src/gallium/drivers/nouveau/nv50/nv50_vbo.c     |  2 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_context.c |  4 +-
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.c  | 19 +++++--
 src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c     |  2 +-
 12 files changed, 121 insertions(+), 78 deletions(-)
src/gallium/drivers/nouveau/nouveau_fence.c +16 -12
index c686710..09b3b1e 100644
@@ -31,14 +31,14 @@
 #endif
  boolean
-nouveau_fence_new(struct nouveau_screen *screen, struct nouveau_fence
 **fence,
+nouveau_fence_new(struct nouveau_fence_mgr *mgr, struct nouveau_fence
 **fence,
                   boolean emit)
 {
    *fence = CALLOC_STRUCT(nouveau_fence);
    if (!*fence)
       return FALSE;
 -   (*fence)->screen = screen;
+   (*fence)->mgr = mgr;
    (*fence)->ref = 1;
    LIST_INITHEAD(&(*fence)->work);
 @@ -83,7 +83,7 @@ nouveau_fence_work(struct nouveau_fence *fence,
 void
 nouveau_fence_emit(struct nouveau_fence *fence)
 {
-   struct nouveau_screen *screen = fence->screen;
+   struct nouveau_fence_mgr *mgr = fence->mgr;
     assert(fence->state == NOUVEAU_FENCE_STATE_AVAILABLE);
 @@ -92,14 +92,14 @@ nouveau_fence_emit(struct nouveau_fence *fence)
     ++fence->ref;
 -   if (screen->fence.tail)
-      screen->fence.tail->next = fence;
+   if (mgr->tail)
+      mgr->tail->next = fence;
    else
-      screen->fence.head = fence;
+      mgr->head = fence;
 -   screen->fence.tail = fence;
+   mgr->tail = fence;
 -   screen->fence.emit(&screen->base, &fence->sequence);
+   mgr->emit(mgr, &fence->sequence);
     assert(fence->state == NOUVEAU_FENCE_STATE_EMITTING);
    fence->state = NOUVEAU_FENCE_STATE_EMITTED;
@@ -109,19 +109,19 @@ void
 nouveau_fence_del(struct nouveau_fence *fence)
 {
    struct nouveau_fence *it;
-   struct nouveau_screen *screen = fence->screen;
+   struct nouveau_fence_mgr *mgr = fence->mgr;
     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 == mgr->head) {
+         mgr->head = fence->next;
+         if (!mgr->head)
+            mgr->tail = NULL;
       } else {
-         for (it = screen->fence.head; it && it->next != fence; it =
 it->next);
+         for (it = mgr->head; it && it->next != fence; it = it->next);
          it->next = fence->next;
-         if (screen->fence.tail == fence)
-            screen->fence.tail = it;
+         if (mgr->tail == fence)
+            mgr->tail = it;
       }
    }
 @@ -134,17 +134,17 @@ nouveau_fence_del(struct nouveau_fence *fence)

}
void

src/gallium/drivers/nouveau/nouveau_fence.c +5 -3
-nouveau_fence_update(struct nouveau_screen *screen, boolean flushed)
+nouveau_fence_update(struct nouveau_fence_mgr *mgr, boolean flushed)
 {
    struct nouveau_fence *fence;
    struct nouveau_fence *next = NULL;
-   u32 sequence = screen->fence.update(&screen->base);
+   u32 sequence = mgr->update(mgr);
 -   if (screen->fence.sequence_ack == sequence)
+   if (mgr->sequence_ack == sequence)
       return;
-   screen->fence.sequence_ack = sequence;
+   mgr->sequence_ack = sequence;
 -   for (fence = screen->fence.head; fence; fence = next) {
+   for (fence = mgr->head; fence; fence = next) {
       next = fence->next;
       sequence = fence->sequence;
 @@ -153,12 +153,12 @@ nouveau_fence_update(struct nouveau_screen *screen,

boolean flushed)

       nouveau_fence_trigger_work(fence);
       nouveau_fence_ref(NULL, &fence);

- if (sequence == screen->fence.sequence_ack)

src/gallium/drivers/nouveau/nouveau_fence.c +17 -13
+      if (sequence == mgr->sequence_ack)
          break;
    }
-   screen->fence.head = next;
+   mgr->head = next;
    if (!next)
-      screen->fence.tail = NULL;
+      mgr->tail = NULL;
     if (flushed) {
       for (fence = next; fence; fence = fence->next)
@@ -172,10 +172,10 @@ nouveau_fence_update(struct nouveau_screen *screen,
 boolean flushed)
 boolean
 nouveau_fence_signalled(struct nouveau_fence *fence)
 {
-   struct nouveau_screen *screen = fence->screen;
+   struct nouveau_fence_mgr *mgr = fence->mgr;
     if (fence->state >= NOUVEAU_FENCE_STATE_EMITTED)
-      nouveau_fence_update(screen, FALSE);
+      nouveau_fence_update(mgr, FALSE);
     return fence->state == NOUVEAU_FENCE_STATE_SIGNALLED;
 }
@@ -183,7 +183,7 @@ nouveau_fence_signalled(struct nouveau_fence *fence)
 boolean
 nouveau_fence_wait(struct nouveau_fence *fence)
 {
-   struct nouveau_screen *screen = fence->screen;
+   struct nouveau_fence_mgr *mgr = fence->mgr;
    uint32_t spins = 0;
     /* wtf, someone is waiting on a fence in flush_notify handler? */
@@ -193,19 +193,19 @@ nouveau_fence_wait(struct nouveau_fence *fence)
       nouveau_fence_emit(fence);
     if (fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
-      if (nouveau_pushbuf_kick(screen->pushbuf, screen->pushbuf->channel))
+      if (mgr->flush(mgr))
          return FALSE;
 -   if (fence == screen->fence.current)
-      nouveau_fence_next(screen);
+   if (fence == mgr->current)
+      nouveau_fence_next(mgr);
     do {
-      nouveau_fence_update(screen, FALSE);
+      nouveau_fence_update(mgr, FALSE);
        if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED)
          return TRUE;
       if (!spins)
-         NOUVEAU_DRV_STAT(screen, any_non_kernel_fence_sync_count, 1);
+         NOUVEAU_DRV_STAT(mgr->screen, any_non_kernel_fence_sync_count, 1);
       spins++;
 #ifdef PIPE_OS_UNIX
       if (!(spins % 8)) /* donate a few cycles */
@@ -215,18 +215,18 @@ nouveau_fence_wait(struct nouveau_fence *fence)
     debug_printf("Wait on fence %u (ack = %u, next = %u) timed out !\n",
                 fence->sequence,
-                screen->fence.sequence_ack, screen->fence.sequence);
+                mgr->sequence_ack, mgr->sequence);
     return FALSE;
 }
  void
-nouveau_fence_next(struct nouveau_screen *screen)
+nouveau_fence_next(struct nouveau_fence_mgr *mgr)
 {
-   if (screen->fence.current->state < NOUVEAU_FENCE_STATE_EMITTING)
-      nouveau_fence_emit(screen->fence.current);
+   if (mgr->current->state < NOUVEAU_FENCE_STATE_EMITTING)
+      nouveau_fence_emit(mgr->current);
 -   nouveau_fence_ref(NULL, &screen->fence.current);
+   nouveau_fence_ref(NULL, &mgr->current);
 -   nouveau_fence_new(screen, &screen->fence.current, FALSE);
+   nouveau_fence_new(mgr, &mgr->current, FALSE);
 }
src/gallium/drivers/nouveau/nouveau_fence.h +17 -3
index 3984a9a..cb44dd3 100644
@@ -11,6 +11,20 @@
 #define NOUVEAU_FENCE_STATE_FLUSHED   3
 #define NOUVEAU_FENCE_STATE_SIGNALLED 4
 +struct nouveau_fence_mgr {
+       struct nouveau_fence *head;
+       struct nouveau_fence *tail;
+       struct nouveau_fence *current;
+       uint32_t sequence;
+       uint32_t sequence_ack;
+       int  (*flush)(struct nouveau_fence_mgr *);
+       void (*emit)(struct nouveau_fence_mgr *, uint32_t *sequence);
+       uint32_t (*update)(struct nouveau_fence_mgr *);
+
+       /* for driver stats */
+       struct nouveau_screen *screen;
+};
+
 struct nouveau_fence_work {
    struct list_head list;
    void (*func)(void *);
@@ -19,7 +33,7 @@ struct nouveau_fence_work {
  struct nouveau_fence {
    struct nouveau_fence *next;
-   struct nouveau_screen *screen;
+   struct nouveau_fence_mgr *mgr;
    int state;
    int ref;
    uint32_t sequence;
@@ -29,11 +43,11 @@ struct nouveau_fence {
 void nouveau_fence_emit(struct nouveau_fence *);
 void nouveau_fence_del(struct nouveau_fence *);
 -boolean nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence
 **,
+boolean nouveau_fence_new(struct nouveau_fence_mgr *, struct nouveau_fence
 **,
                           boolean emit);
 boolean nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void
 *);
-void    nouveau_fence_update(struct nouveau_screen *, boolean flushed);
-void    nouveau_fence_next(struct nouveau_screen *);
+void    nouveau_fence_update(struct nouveau_fence_mgr *, boolean flushed);
+void    nouveau_fence_next(struct nouveau_fence_mgr *);
 boolean nouveau_fence_wait(struct nouveau_fence *);
 boolean nouveau_fence_signalled(struct nouveau_fence *);
 diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c

b/src/gallium/drivers/nouveau/nouveau_screen.c
index 9d71bf7..9ea3a46 100644

src/gallium/drivers/nouveau/nouveau_screen.c +9 -0
@@ -223,3 +223,12 @@ nouveau_screen_fini(struct nouveau_screen *screen)
        nouveau_device_del(&screen->device);
 }
+
+int nouveau_screen_fence_kick(struct nouveau_fence_mgr *mgr)
+{
+       struct nouveau_screen *screen = NULL;
+
+       screen = container_of(mgr, screen, fence);
+
+       return nouveau_pushbuf_kick(screen->pushbuf,
 screen->pushbuf->channel);
+}
src/gallium/drivers/nouveau/nouveau_screen.h +3 -8
index cf06f7e..7682214 100644
@@ -4,6 +4,8 @@
 #include "pipe/p_screen.h"
 #include "util/u_memory.h"
 +#include "nouveau_fence.h"
+
 #ifdef DEBUG
 # define NOUVEAU_ENABLE_DRIVER_STATISTICS
 #endif
@@ -34,15 +36,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_mgr fence;
        struct nouveau_mman *mm_VRAM;
        struct nouveau_mman *mm_GART;
@@ -132,4 +126,6 @@ void nouveau_screen_fini(struct nouveau_screen *);
  void nouveau_screen_init_vdec(struct nouveau_screen *);
 +int nouveau_screen_fence_kick(struct nouveau_fence_mgr *);
+
 #endif
src/gallium/drivers/nouveau/nv30/nv30_context.c +2 -1
index f325c5c..35c66f1 100644
@@ -44,8 +44,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);
+   nouveau_fence_update(&screen->fence, TRUE);
     if (push->bufctx) {
       struct nouveau_bufref *bref;
src/gallium/drivers/nouveau/nv30/nv30_screen.c +6 -3
index fb9378c..a0518c3 100644
@@ -287,10 +287,13 @@ 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_mgr *mgr, uint32_t *sequence)
 {
-   struct nv30_screen *screen = nv30_screen(pscreen);
-   struct nouveau_pushbuf *push = screen->base.pushbuf;
+   struct nv30_screen *screen = NULL;
+   struct nouveau_pushbuf *push;
+
+   screen = container_of(mgr, screen, base.fence);
+   push = screen->base.pushbuf;
     *sequence = ++screen->base.fence.sequence;
 @@ -300,10 +303,14 @@ nv30_screen_fence_emit(struct pipe_screen *pscreen,
 uint32_t *sequence)

}
static uint32_t

src/gallium/drivers/nouveau/nv30/nv30_screen.c +9 -3
-nv30_screen_fence_update(struct pipe_screen *pscreen)
+nv30_screen_fence_update(struct nouveau_fence_mgr *mgr)
 {
-   struct nv30_screen *screen = nv30_screen(pscreen);
-   struct nv04_notify *fence = screen->fence->data;
+   struct nv30_screen *screen = NULL;
+   struct nv04_notify *fence;
+
+   screen = container_of(mgr, screen, base.fence);
+   fence = screen->fence->data;
+
    return *(uint32_t *)((char *)screen->notify->map + fence->offset);
 }
 @@ -404,6 +411,8 @@ nv30_screen_create(struct nouveau_device *dev)
    nv30_resource_screen_init(pscreen);
    nouveau_screen_init_vdec(&screen->base);
 +   screen->base.fence.screen = &screen->base;
+   screen->base.fence.flush = nouveau_screen_fence_kick;
    screen->base.fence.emit = nv30_screen_fence_emit;
    screen->base.fence.update = nv30_screen_fence_update;
 @@ -607,6 +616,6 @@ nv30_screen_create(struct nouveau_device *dev)
     nouveau_pushbuf_kick(push, push->channel);
 -   nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
+   nouveau_fence_new(&screen->base.fence, &screen->base.fence.current,
FALSE);
    return pscreen;

}

src/gallium/drivers/nouveau/nv50/nv50_context.c +2 -2
index f844592..af1e436 100644
@@ -83,8 +83,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);
+      nouveau_fence_update(&screen->base.fence, TRUE);
       if (screen->cur_ctx)
          screen->cur_ctx->state.flushed = TRUE;
    }
src/gallium/drivers/nouveau/nv50/nv50_screen.c +13 -5
index 015f139..8195650 100644
@@ -348,10 +348,13 @@ 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_mgr *mgr, u32 *sequence)
 {
-   struct nv50_screen *screen = nv50_screen(pscreen);
-   struct nouveau_pushbuf *push = screen->base.pushbuf;
+   struct nv50_screen *screen = NULL;
+   struct nouveau_pushbuf *push;
+
+   screen = container_of(mgr, screen, base.fence);
+   push = screen->base.pushbuf;
     /* we need to do it after possible flush in MARK_RING */
    *sequence = ++screen->base.fence.sequence;
@@ -369,9 +372,12 @@ 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_mgr *mgr)
 {
-   return nv50_screen(pscreen)->fence.map[0];
+   struct nv50_screen *screen = NULL;
+
+   screen = container_of(mgr, screen, base.fence);
+   return screen->fence.map[0];
 }
  static void
@@ -717,6 +723,8 @@ nv50_screen_create(struct nouveau_device *dev)
     nouveau_bo_map(screen->fence.bo, 0, NULL);
    screen->fence.map = screen->fence.bo->map;
+   screen->base.fence.screen = &screen->base;
+   screen->base.fence.flush = nouveau_screen_fence_kick;
    screen->base.fence.emit = nv50_screen_fence_emit;
    screen->base.fence.update = nv50_screen_fence_update;
 @@ -850,7 +858,7 @@ nv50_screen_create(struct nouveau_device *dev)
     nv50_screen_init_hwctx(screen);

- nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
+ nouveau_fence_new(&screen->base.fence, &screen->base.fence.current,

FALSE);
     return pscreen;

diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c index 7c2b7ff..3fa2f05 100644

src/gallium/drivers/nouveau/nv50/nv50_vbo.c +1 -0
@@ -737,7 +737,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);
 }
src/gallium/drivers/nouveau/nvc0/nvc0_context.c +2 -2
index e5040c4..52f8a57 100644
@@ -147,8 +147,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);
+      nouveau_fence_update(&screen->base.fence, TRUE);
       if (screen->cur_ctx)
          screen->cur_ctx->state.flushed = TRUE;
    }
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +10 -5
index 3e6b011..2a317af 100644
@@ -490,10 +490,13 @@ 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_mgr *mgr, u32 *sequence)
 {
-   struct nvc0_screen *screen = nvc0_screen(pscreen);
-   struct nouveau_pushbuf *push = screen->base.pushbuf;
+   struct nvc0_screen *screen = NULL;
+   struct nouveau_pushbuf *push;
+
+   screen = container_of(mgr, screen, base.fence);
+   push = screen->base.pushbuf;
     /* we need to do it after possible flush in MARK_RING */
    *sequence = ++screen->base.fence.sequence;
@@ -507,9 +510,11 @@ nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32
 *sequence)
 }
  static u32
-nvc0_screen_fence_update(struct pipe_screen *pscreen)
+nvc0_screen_fence_update(struct nouveau_fence_mgr *mgr)
 {
-   struct nvc0_screen *screen = nvc0_screen(pscreen);
+   struct nvc0_screen *screen = NULL;
+
+   screen = container_of(mgr, screen, base.fence);
    return screen->fence.map[0];
 }
 @@ -639,6 +644,8 @@ nvc0_screen_create(struct nouveau_device *dev)
       goto fail;
    nouveau_bo_map(screen->fence.bo, 0, NULL);
    screen->fence.map = screen->fence.bo->map;
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +3 -0
+   screen->base.fence.screen = &screen->base;
+   screen->base.fence.flush = nouveau_screen_fence_kick;
    screen->base.fence.emit = nvc0_screen_fence_emit;
    screen->base.fence.update = nvc0_screen_fence_update;
 @@ -997,7 +1004,7 @@ nvc0_screen_create(struct nouveau_device *dev)
    if (!nvc0_blitter_create(screen))
       goto fail;
 -   nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
+   nouveau_fence_new(&screen->base.fence, &screen->base.fence.current,
FALSE);
     return pscreen;

diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c index 83d406d..6406cf5 100644

src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c +1 -1
@@ -559,7 +559,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.0.0

_______________________________________________
Nouveau mailing list [email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau