nv50: move onto shared fence code
authorBen Skeggs <bskeggs@redhat.com>
Tue, 1 Mar 2011 00:17:28 +0000 (10:17 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 1 Mar 2011 04:44:42 +0000 (14:44 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
src/gallium/drivers/nv50/Makefile
src/gallium/drivers/nv50/nv50_buffer.c
src/gallium/drivers/nv50/nv50_context.c
src/gallium/drivers/nv50/nv50_fence.c [deleted file]
src/gallium/drivers/nv50/nv50_fence.h [deleted file]
src/gallium/drivers/nv50/nv50_query.c
src/gallium/drivers/nv50/nv50_resource.h
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_screen.h
src/gallium/drivers/nv50/nv50_vbo.c

index d0a60c7ac13a3d51a982c6f459aa0cdabe15324d..61fb94913b3f130f3dd0dabf3288caaae1d93b1e 100644 (file)
@@ -26,7 +26,6 @@ C_SOURCES = \
        nv50_pc_optimize.c \
        nv50_pc_regalloc.c \
        nv50_push.c \
-       nv50_fence.c \
        nv50_mm.c \
        nv50_query.c
 
index 5cb2e628e7a98f34cf0a8f9aa07500485de909db..21aad9f9496bb86d64507b94cf19aaa644093f1f 100644 (file)
@@ -49,13 +49,9 @@ nv50_buffer_allocate(struct nv50_screen *screen, struct nv50_resource *buf,
 }
 
 static INLINE void
-release_allocation(struct nv50_mm_allocation **mm, struct nv50_fence *fence)
+release_allocation(struct nv50_mm_allocation **mm, struct nouveau_fence *fence)
 {
-   if (fence && fence->state != NV50_FENCE_STATE_SIGNALLED) {
-      nv50_fence_sched_release(fence, *mm);
-   } else {
-      nv50_mm_free(*mm);
-   }
+   nouveau_fence_work(fence, nv50_mm_free, *mm);
    (*mm) = NULL;
 }
 
@@ -153,7 +149,7 @@ nv50_buffer_upload(struct nv50_context *nv50, struct nv50_resource *buf,
 
    nouveau_bo_ref(NULL, &bounce);
    if (mm)
-      release_allocation(&mm, nv50->screen->fence.current);
+      release_allocation(&mm, nv50->screen->base.fence.current);
 
    if (start == 0 && size == buf->base.width0)
       buf->status &= ~NV50_BUFFER_STATUS_DIRTY;
@@ -217,17 +213,17 @@ nv50_buffer_sync(struct nv50_resource *buf, unsigned rw)
    if (rw == PIPE_TRANSFER_READ) {
       if (!buf->fence_wr)
          return TRUE;
-      if (!nv50_fence_wait(buf->fence_wr))
+      if (!nouveau_fence_wait(buf->fence_wr))
          return FALSE;
    } else {
       if (!buf->fence)
          return TRUE;
-      if (!nv50_fence_wait(buf->fence))
+      if (!nouveau_fence_wait(buf->fence))
          return FALSE;
 
-      nv50_fence_reference(&buf->fence, NULL);
+      nouveau_fence_ref(NULL, &buf->fence);
    }
-   nv50_fence_reference(&buf->fence_wr, NULL);
+   nouveau_fence_ref(NULL, &buf->fence_wr);
 
    return TRUE;
 }
@@ -236,9 +232,9 @@ static INLINE boolean
 nv50_buffer_busy(struct nv50_resource *buf, unsigned rw)
 {
    if (rw == PIPE_TRANSFER_READ)
-      return (buf->fence_wr && !nv50_fence_signalled(buf->fence_wr));
+      return (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr));
    else
-      return (buf->fence && !nv50_fence_signalled(buf->fence));
+      return (buf->fence && !nouveau_fence_signalled(buf->fence));
 }
 
 static void *
@@ -453,7 +449,7 @@ nv50_buffer_migrate(struct nv50_context *nv50,
 
       nouveau_bo_ref(NULL, &bo);
       if (mm)
-         release_allocation(&mm, screen->fence.current);
+         release_allocation(&mm, screen->base.fence.current);
    } else
    if (new_domain == NOUVEAU_BO_VRAM && old_domain == 0) {
       if (!nv50_buffer_allocate(screen, buf, NOUVEAU_BO_VRAM))
index 8eb59e20d8dd21fcaad0d97f49a3ba2023497de4..4380945a1ee2eef5aa6759a6bc51ca243a37b5de 100644 (file)
@@ -44,8 +44,8 @@ nv50_flush(struct pipe_context *pipe, unsigned flags,
    }
 
    if (fence)
-      nv50_fence_reference((struct nv50_fence **)fence,
-                           nv50->screen->fence.current);
+      nouveau_fence_ref(nv50->screen->base.fence.current,
+                        (struct nouveau_fence **)fence);
 
    if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME))
       FIRE_RING(chan);
@@ -59,9 +59,8 @@ nv50_default_flush_notify(struct nouveau_channel *chan)
    if (!nv50)
       return;
 
-   nv50_screen_fence_update(nv50->screen, TRUE);
-
-   nv50_screen_fence_next(nv50->screen);
+   nouveau_fence_update(&nv50->screen->base, TRUE);
+   nouveau_fence_next(&nv50->screen->base);
 }
 
 static void
diff --git a/src/gallium/drivers/nv50/nv50_fence.c b/src/gallium/drivers/nv50/nv50_fence.c
deleted file mode 100644 (file)
index 936cf81..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright 2010 Christoph Bumiller
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include "nv50_fence.h"
-#include "nv50_context.h"
-#include "nv50_screen.h"
-
-#ifdef PIPE_OS_UNIX
-#include <sched.h>
-#endif
-
-boolean
-nv50_screen_fence_new(struct nv50_screen *screen, struct nv50_fence **fence,
-                      boolean emit)
-{
-   *fence = CALLOC_STRUCT(nv50_fence);
-   if (!*fence)
-      return FALSE;
-
-   (*fence)->screen = screen;
-   (*fence)->ref = 1;
-
-   if (emit)
-      nv50_fence_emit(*fence);
-
-   return TRUE;
-}
-
-void
-nv50_fence_emit(struct nv50_fence *fence)
-{
-   struct nv50_screen *screen = fence->screen;
-   struct nouveau_channel *chan = screen->base.channel;
-
-   fence->sequence = ++screen->fence.sequence;
-
-   assert(fence->state == NV50_FENCE_STATE_AVAILABLE);
-
-   MARK_RING (chan, 5, 2);
-   BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
-   OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
-   OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
-   OUT_RING  (chan, fence->sequence);
-   OUT_RING  (chan, 
-              NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
-              NV50_3D_QUERY_GET_UNK4 |
-              NV50_3D_QUERY_GET_UNIT_CROP |
-              NV50_3D_QUERY_GET_TYPE_QUERY |
-              NV50_3D_QUERY_GET_QUERY_SELECT_ZERO |
-              NV50_3D_QUERY_GET_SHORT);
-
-
-   ++fence->ref;
-
-   if (screen->fence.tail)
-      screen->fence.tail->next = fence;
-   else
-      screen->fence.head = fence;
-
-   screen->fence.tail = fence;
-
-   fence->state = NV50_FENCE_STATE_EMITTED;
-}
-
-static void
-nv50_fence_trigger_release_buffers(struct nv50_fence *fence);
-
-void
-nv50_fence_del(struct nv50_fence *fence)
-{
-   struct nv50_fence *it;
-   struct nv50_screen *screen = fence->screen;
-
-   if (fence->state == NV50_FENCE_STATE_EMITTED ||
-       fence->state == NV50_FENCE_STATE_FLUSHED) {
-      if (fence == screen->fence.head) {
-         screen->fence.head = fence->next;
-         if (!screen->fence.head)
-            screen->fence.tail = NULL;
-      } else {
-         for (it = screen->fence.head; it && it->next != fence; it = it->next);
-         it->next = fence->next;
-         if (screen->fence.tail == fence)
-            screen->fence.tail = it;
-      }
-   }
-
-   if (fence->buffers) {
-      debug_printf("WARNING: deleting fence with buffers "
-                   "still hooked to it !\n");
-      nv50_fence_trigger_release_buffers(fence);
-   }
-
-   FREE(fence);
-}
-
-static void
-nv50_fence_trigger_release_buffers(struct nv50_fence *fence)
-{
-   struct nv50_mm_allocation *alloc = fence->buffers;
-
-   while (alloc) {
-      struct nv50_mm_allocation *next = alloc->next;
-      nv50_mm_free(alloc);
-      alloc = next;
-   };
-   fence->buffers = NULL;
-}
-
-void
-nv50_screen_fence_update(struct nv50_screen *screen, boolean flushed)
-{
-   struct nv50_fence *fence;
-   struct nv50_fence *next = NULL;
-   uint32_t sequence = screen->fence.map[0];
-
-   if (screen->fence.sequence_ack == sequence)
-      return;
-   screen->fence.sequence_ack = sequence;
-
-   for (fence = screen->fence.head; fence; fence = next) {
-      next = fence->next;
-      sequence = fence->sequence;
-
-      fence->state = NV50_FENCE_STATE_SIGNALLED;
-
-      if (fence->buffers)
-         nv50_fence_trigger_release_buffers(fence);
-
-      nv50_fence_reference(&fence, NULL);
-
-      if (sequence == screen->fence.sequence_ack)
-         break;
-   }
-   screen->fence.head = next;
-   if (!next)
-      screen->fence.tail = NULL;
-
-   if (flushed) {
-      for (fence = next; fence; fence = fence->next)
-         fence->state = NV50_FENCE_STATE_FLUSHED;
-   }
-}
-
-#define NV50_FENCE_MAX_SPINS (1 << 31)
-
-boolean
-nv50_fence_signalled(struct nv50_fence *fence)
-{
-   struct nv50_screen *screen = fence->screen;
-
-   if (fence->state >= NV50_FENCE_STATE_EMITTED)
-      nv50_screen_fence_update(screen, FALSE);
-
-   return fence->state == NV50_FENCE_STATE_SIGNALLED;
-}
-
-boolean
-nv50_fence_wait(struct nv50_fence *fence)
-{
-   struct nv50_screen *screen = fence->screen;
-   uint32_t spins = 0;
-
-   if (fence->state < NV50_FENCE_STATE_EMITTED) {
-      nv50_fence_emit(fence);
-
-      if (fence == screen->fence.current)
-         nv50_screen_fence_new(screen, &screen->fence.current, FALSE);
-   }
-   if (fence->state < NV50_FENCE_STATE_FLUSHED)
-      FIRE_RING(screen->base.channel);
-
-   do {
-      nv50_screen_fence_update(screen, FALSE);
-
-      if (fence->state == NV50_FENCE_STATE_SIGNALLED)
-         return TRUE;
-      spins++;
-#ifdef PIPE_OS_UNIX
-      if (!(spins % 8)) /* donate a few cycles */
-         sched_yield();
-#endif
-   } while (spins < NV50_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);
-
-   return FALSE;
-}
-
-void
-nv50_screen_fence_next(struct nv50_screen *screen)
-{
-   nv50_fence_emit(screen->fence.current);
-   nv50_screen_fence_new(screen, &screen->fence.current, FALSE);
-}
diff --git a/src/gallium/drivers/nv50/nv50_fence.h b/src/gallium/drivers/nv50/nv50_fence.h
deleted file mode 100644 (file)
index dd0b74e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-
-#ifndef __NV50_FENCE_H__
-#define __NV50_FENCE_H__
-
-#include "util/u_inlines.h"
-#include "util/u_double_list.h"
-
-#define NV50_FENCE_STATE_AVAILABLE 0
-#define NV50_FENCE_STATE_EMITTED   1
-#define NV50_FENCE_STATE_FLUSHED   2
-#define NV50_FENCE_STATE_SIGNALLED 3
-
-struct nv50_mm_allocation;
-
-struct nv50_fence {
-   struct nv50_fence *next;
-   struct nv50_screen *screen;
-   int state;
-   int ref;
-   uint32_t sequence;
-   struct nv50_mm_allocation *buffers;
-};
-
-void nv50_fence_emit(struct nv50_fence *);
-void nv50_fence_del(struct nv50_fence *);
-
-boolean nv50_fence_wait(struct nv50_fence *);
-boolean nv50_fence_signalled(struct nv50_fence *);
-
-static INLINE void
-nv50_fence_reference(struct nv50_fence **ref, struct nv50_fence *fence)
-{
-   if (*ref) {
-      if (--(*ref)->ref == 0)
-         nv50_fence_del(*ref);
-   }
-   if (fence)
-      ++fence->ref;
-
-   *ref = fence;
-}
-
-static INLINE struct nv50_fence *
-nv50_fence(struct pipe_fence_handle *fence)
-{
-   return (struct nv50_fence *)fence;
-}
-
-#endif // __NV50_FENCE_H__
index e769aa18fe944a3032c38d90ee8eef1ed57bb15a..42391ec5b1f8d59895a7a154349e2b8b82cb2e95 100644 (file)
@@ -64,7 +64,7 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
          if (q->ready)
             nv50_mm_free(q->mm);
          else
-            nv50_fence_sched_release(screen->fence.current, q->mm);
+            nouveau_fence_work(screen->base.fence.current, nv50_mm_free, q->mm);
       }
    }
    if (size) {
index f0e022b320b517c9e3ca888642b97f5f9e9570ad..f42179c88f3b0f3ffcab203ee47b8f9e837569cb 100644 (file)
@@ -8,8 +8,6 @@
 #include "nouveau/nouveau_winsys.h"
 #undef NOUVEAU_NVC0
 
-#include "nv50_fence.h"
-
 struct pipe_resource;
 struct nouveau_bo;
 struct nv50_context;
@@ -45,8 +43,8 @@ struct nv50_resource {
 
    int16_t score; /* low if mapped very often, if high can move to VRAM */
 
-   struct nv50_fence *fence;
-   struct nv50_fence *fence_wr;
+   struct nouveau_fence *fence;
+   struct nouveau_fence *fence_wr;
 
    struct nv50_mm_allocation *mm;
 };
index 77cf959940dc5368451cd6d7b9d6e0fcf3bed785..e5b50103ef71bbb16dbef64410a14214fe4fa2a9 100644 (file)
@@ -23,7 +23,6 @@
 #include "util/u_format_s3tc.h"
 #include "pipe/p_screen.h"
 
-#include "nv50_fence.h"
 #include "nv50_context.h"
 #include "nv50_screen.h"
 
@@ -211,9 +210,9 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
 {
    struct nv50_screen *screen = nv50_screen(pscreen);
 
-   if (screen->fence.current) {
-      nv50_fence_wait(screen->fence.current);
-      nv50_fence_reference(&screen->fence.current, NULL);
+   if (screen->base.fence.current) {
+      nouveau_fence_wait(screen->base.fence.current);
+      nouveau_fence_ref (NULL, &screen->base.fence.current);
    }
 
    nouveau_bo_ref(NULL, &screen->code);
@@ -246,27 +245,29 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
 }
 
 static void
-nv50_screen_fence_reference(struct pipe_screen *pscreen,
-                            struct pipe_fence_handle **ptr,
-                            struct pipe_fence_handle *fence)
+nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 sequence)
 {
-   nv50_fence_reference((struct nv50_fence **)ptr, nv50_fence(fence));
-}
+   struct nv50_screen *screen = nv50_screen(pscreen);
+   struct nouveau_channel *chan = screen->base.channel;
 
-static int
-nv50_screen_fence_signalled(struct pipe_screen *pscreen,
-                            struct pipe_fence_handle *fence,
-                            unsigned flags)
-{
-   return !(nv50_fence_signalled(nv50_fence(fence)));
+   MARK_RING (chan, 5, 2);
+   BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
+   OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
+   OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
+   OUT_RING  (chan, sequence);
+   OUT_RING  (chan, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
+                    NV50_3D_QUERY_GET_UNK4 |
+                    NV50_3D_QUERY_GET_UNIT_CROP |
+                    NV50_3D_QUERY_GET_TYPE_QUERY |
+                    NV50_3D_QUERY_GET_QUERY_SELECT_ZERO |
+                    NV50_3D_QUERY_GET_SHORT);
 }
 
-static int
-nv50_screen_fence_finish(struct pipe_screen *pscreen,
-                         struct pipe_fence_handle *fence,
-                         unsigned flags)
+static u32
+nv50_screen_fence_update(struct pipe_screen *pscreen)
 {
-   return nv50_fence_wait((struct nv50_fence *)fence) != TRUE;
+   struct nv50_screen *screen = nv50_screen(pscreen);
+   return screen->fence.map[0];
 }
 
 #define FAIL_SCREEN_INIT(str, err)                    \
@@ -306,9 +307,6 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
    pscreen->get_param = nv50_screen_get_param;
    pscreen->get_shader_param = nv50_screen_get_shader_param;
    pscreen->get_paramf = nv50_screen_get_paramf;
-   pscreen->fence_reference = nv50_screen_fence_reference;
-   pscreen->fence_signalled = nv50_screen_fence_signalled;
-   pscreen->fence_finish = nv50_screen_fence_finish;
 
    nv50_screen_init_resource_functions(pscreen);
 
@@ -322,6 +320,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
    nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR);
    screen->fence.map = screen->fence.bo->map;
    nouveau_bo_unmap(screen->fence.bo);
+   screen->base.fence.emit = nv50_screen_fence_emit;
+   screen->base.fence.update = nv50_screen_fence_update;
 
    ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
    if (ret)
@@ -591,7 +591,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
    screen->mm_VRAM = nv50_mm_create(dev, NOUVEAU_BO_VRAM, 0x000);
    screen->mm_VRAM_fe0 = nv50_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0);
 
-   nv50_screen_fence_new(screen, &screen->fence.current, FALSE);
+   nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
 
    return pscreen;
 
index c78ed50fe351224cc6376133be4038ae805493fc..c2ec3b58dc2a821c9c3bfb70d3dd7ce1ad12e140 100644 (file)
@@ -3,6 +3,7 @@
 
 #define NOUVEAU_NVC0
 #include "nouveau/nouveau_screen.h"
+#include "nouveau/nouveau_fence.h"
 #undef NOUVEAU_NVC0
 #include "nv50_winsys.h"
 #include "nv50_stateobj.h"
@@ -12,7 +13,6 @@
 
 struct nv50_mman;
 struct nv50_context;
-struct nv50_fence;
 
 #define NV50_SCRATCH_SIZE (2 << 20)
 #define NV50_SCRATCH_NR_BUFFERS 2
@@ -49,11 +49,6 @@ struct nv50_screen {
 
    struct {
       uint32_t *map;
-      struct nv50_fence *head;
-      struct nv50_fence *tail;
-      struct nv50_fence *current;
-      uint32_t sequence;
-      uint32_t sequence_ack;
       struct nouveau_bo *bo;
    } fence;
 
@@ -83,13 +78,6 @@ struct nv50_mm_allocation {
    uint32_t offset;
 };
 
-static INLINE void
-nv50_fence_sched_release(struct nv50_fence *nf, struct nv50_mm_allocation *mm)
-{
-   mm->next = nf->buffers;
-   nf->buffers = mm;
-}
-
 extern struct nv50_mman *
 nv50_mm_create(struct nouveau_device *, uint32_t domain, uint32_t storage_type);
 
@@ -113,10 +101,10 @@ nv50_resource_fence(struct nv50_resource *res, uint32_t flags)
    struct nv50_screen *screen = nv50_screen(res->base.screen);
 
    if (res->mm) {
-      nv50_fence_reference(&res->fence, screen->fence.current);
+      nouveau_fence_ref(screen->base.fence.current, &res->fence);
 
       if (flags & NOUVEAU_BO_WR)
-         nv50_fence_reference(&res->fence_wr, screen->fence.current);
+         nouveau_fence_ref(screen->base.fence.current, &res->fence_wr);
    }
 }
 
@@ -132,23 +120,6 @@ nv50_resource_validate(struct nv50_resource *res, uint32_t flags)
    }
 }
 
-
-boolean
-nv50_screen_fence_new(struct nv50_screen *, struct nv50_fence **, boolean emit);
-
-void
-nv50_screen_fence_next(struct nv50_screen *);
-void
-nv50_screen_fence_update(struct nv50_screen *, boolean flushed);
-
-static INLINE boolean
-nv50_screen_fence_emit(struct nv50_screen *screen)
-{
-   nv50_fence_emit(screen->fence.current);
-
-   return nv50_screen_fence_new(screen, &screen->fence.current, FALSE);
-}
-
 struct nv50_format {
    uint32_t rt;
    uint32_t tic;
index 0e0d48d661c81911a483fb722b543940549db16d..d18b2dffd1db8a4ec4f6909c2cd5740c22a23e95 100644 (file)
@@ -393,7 +393,7 @@ nv50_draw_vbo_flush_notify(struct nouveau_channel *chan)
 {
    struct nv50_context *nv50 = chan->user_private;
 
-   nv50_screen_fence_update(nv50->screen, TRUE);
+   nouveau_fence_update(&nv50->screen->base, TRUE);
 
    nv50_bufctx_emit_relocs(nv50);
 }