nouveau: Split nouveau_buffers into nouveau_mem and nouveau_fbo
[mesa.git] / src / mesa / drivers / dri / nouveau / nouveau_sync.c
index 0bf20e723bbfa545b169ca5c58e3f294ed18939d..abb3088032ba140b486456b3c1a17e518b0af69f 100644 (file)
@@ -1,57 +1,90 @@
+/*
+ * Copyright (C) 2007 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * 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 (including the
+ * next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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 "vblank.h" /* for DO_USLEEP */
 
 #include "nouveau_context.h"
-#include "nouveau_buffers.h"
-#include "nouveau_object.h"
 #include "nouveau_fifo.h"
-#include "nouveau_reg.h"
+#include "nouveau_mem.h"
 #include "nouveau_msg.h"
+#include "nouveau_object.h"
+#include "nouveau_reg.h"
 #include "nouveau_sync.h"
 
-nouveau_notifier *
-nouveau_notifier_new(GLcontext *ctx, GLuint handle)
+#define NOTIFIER(__v) \
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx); \
+       volatile uint32_t *__v = (void*)nmesa->notifier_block + notifier->offset
+
+struct drm_nouveau_notifierobj_alloc *
+nouveau_notifier_new(GLcontext *ctx, GLuint handle, GLuint count)
 {
        nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
-       nouveau_notifier *notifier;
+       struct drm_nouveau_notifierobj_alloc *notifier;
+       int ret;
 
-       notifier = CALLOC_STRUCT(nouveau_notifier_t);
+#ifdef NOUVEAU_RING_DEBUG
+       return NULL;
+#endif
+       notifier = CALLOC_STRUCT(drm_nouveau_notifierobj_alloc);
        if (!notifier)
                return NULL;
 
-       notifier->mem = nouveau_mem_alloc(ctx,
-                                         NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED,
-                                         32,
-                                         0);
-       if (!notifier->mem) {
+       notifier->channel = nmesa->fifo.channel;
+       notifier->handle  = handle;
+       notifier->count   = count;
+       ret = drmCommandWriteRead(nmesa->driFd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
+                                 notifier, sizeof(*notifier));
+       if (ret) {
+               MESSAGE("Failed to create notifier 0x%08x: %d\n", handle, ret);
                FREE(notifier);
                return NULL;
        }
 
-       if (!nouveauCreateDmaObject(nmesa, handle, notifier->mem->offset,
-                                                  notifier->mem->size,
-                                                  0 /* NV_DMA_TARGET_FB */,
-                                                  0 /* NV_DMA_ACCESS_RW */)) {
-               nouveau_mem_free(ctx, notifier->mem);
-               FREE(notifier);
-               return NULL;
-       }
-
-       notifier->handle = handle;
        return notifier;
 }
 
 void
-nouveau_notifier_destroy(GLcontext *ctx, nouveau_notifier *notifier)
+nouveau_notifier_destroy(GLcontext *ctx,
+                        struct drm_nouveau_notifierobj_alloc *notifier)
 {
-       /*XXX: free DMA object.. */
-       nouveau_mem_free(ctx, notifier->mem);
+       /*XXX: free notifier object.. */
        FREE(notifier);
 }
 
 void
-nouveau_notifier_reset(nouveau_notifier *notifier)
+nouveau_notifier_reset(GLcontext *ctx,
+                      struct drm_nouveau_notifierobj_alloc *notifier,
+                      GLuint id)
 {
-       volatile GLuint *n = notifier->mem->map;
+       NOTIFIER(n);
+
+#ifdef NOUVEAU_RING_DEBUG
+       return;
+#endif
 
        n[NV_NOTIFY_TIME_0      /4] = 0x00000000;
        n[NV_NOTIFY_TIME_1      /4] = 0x00000000;
@@ -60,17 +93,42 @@ nouveau_notifier_reset(nouveau_notifier *notifier)
                                       NV_NOTIFY_STATE_STATUS_SHIFT);
 }
 
+GLuint
+nouveau_notifier_status(GLcontext *ctx,
+                       struct drm_nouveau_notifierobj_alloc *notifier,
+                       GLuint id)
+{
+       NOTIFIER(n);
+
+       return n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT;
+}
+
+GLuint
+nouveau_notifier_return_val(GLcontext *ctx,
+                           struct drm_nouveau_notifierobj_alloc *notifier,
+                           GLuint id)
+{
+       NOTIFIER(n);
+
+       return n[NV_NOTIFY_RETURN_VALUE/4];
+}
+
 GLboolean
-nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status,
-                                                        GLuint timeout)
+nouveau_notifier_wait_status(GLcontext *ctx,
+                            struct drm_nouveau_notifierobj_alloc *notifier,
+                            GLuint id, GLuint status, GLuint timeout)
 {
-       volatile GLuint *n = notifier->mem->map;
+       NOTIFIER(n);
        unsigned int time = 0;
 
+#ifdef NOUVEAU_RING_DEBUG
+       return GL_TRUE;
+#endif
+
        while (time <= timeout) {
                if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) {
                        MESSAGE("Notifier returned error: 0x%04x\n",
-                                       n[NV_NOTIFY_STATE] &
+                                       n[NV_NOTIFY_STATE/4] &
                                        NV_NOTIFY_STATE_ERROR_CODE_MASK);
                        return GL_FALSE;
                }
@@ -90,13 +148,14 @@ nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status,
 }
 
 void
-nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier,
-                                         GLuint subc)
+nouveau_notifier_wait_nop(GLcontext *ctx,
+                         struct drm_nouveau_notifierobj_alloc *notifier,
+                         GLuint subc)
 {
-       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+       NOTIFIER(n);
        GLboolean ret;
 
-       nouveau_notifier_reset(notifier);
+       nouveau_notifier_reset(ctx, notifier, 0);
 
        BEGIN_RING_SIZE(subc, NV_NOTIFY, 1);
        OUT_RING       (NV_NOTIFY_STYLE_WRITE_ONLY);
@@ -104,7 +163,7 @@ nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier,
        OUT_RING       (0);
        FIRE_RING();
 
-       ret = nouveau_notifier_wait_status(notifier,
+       ret = nouveau_notifier_wait_status(ctx, notifier, 0,
                                           NV_NOTIFY_STATE_STATUS_COMPLETED,
                                           0 /* no timeout */);
        if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n");
@@ -114,7 +173,11 @@ GLboolean nouveauSyncInitFuncs(GLcontext *ctx)
 {
        nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
 
-       nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify);
+#ifdef NOUVEAU_RING_DEBUG
+       return GL_TRUE;
+#endif
+
+       nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify, 1);
        if (!nmesa->syncNotifier) {
                MESSAGE("Failed to create channel sync notifier\n");
                return GL_FALSE;