nouveau: initial GL_ARB_occlusion_query support
authorBen Skeggs <darktama@iinet.net.au>
Sun, 28 Jan 2007 06:02:40 +0000 (17:02 +1100)
committerBen Skeggs <darktama@iinet.net.au>
Sun, 28 Jan 2007 06:02:40 +0000 (17:02 +1100)
Only enabled on NV40, NV20/NV30 code is untested.. However, NV30
should be identical to NV40.

src/mesa/drivers/dri/nouveau/Makefile
src/mesa/drivers/dri/nouveau/nouveau_context.c
src/mesa/drivers/dri/nouveau/nouveau_context.h
src/mesa/drivers/dri/nouveau/nouveau_object.h
src/mesa/drivers/dri/nouveau/nouveau_query.c [new file with mode: 0644]
src/mesa/drivers/dri/nouveau/nouveau_query.h [new file with mode: 0644]
src/mesa/drivers/dri/nouveau/nouveau_sync.c
src/mesa/drivers/dri/nouveau/nouveau_sync.h

index 492e743..20d2de5 100644 (file)
@@ -27,6 +27,7 @@ DRIVER_SOURCES = \
        nouveau_tex.c            \
        nouveau_swtcl.c          \
        nouveau_sync.c           \
+       nouveau_query.c          \
        nv04_state.c             \
        nv04_swtcl.c             \
        nv10_state.c             \
index 5db93eb..e18cebc 100644 (file)
@@ -50,6 +50,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "nouveau_msg.h"
 #include "nouveau_reg.h"
 #include "nouveau_lock.h"
+#include "nouveau_query.h"
 #include "nv04_swtcl.h"
 #include "nv10_swtcl.h"
 
@@ -71,6 +72,7 @@ static const struct dri_debug_control debug_control[] =
 };
 
 #define need_GL_ARB_vertex_program
+#define need_GL_ARB_occlusion_query
 #include "extension_helper.h"
 
 const struct dri_extension common_extensions[] =
@@ -100,6 +102,7 @@ const struct dri_extension nv40_extensions[] =
     * written for those cards.
     */
        { "GL_ARB_vertex_program",      GL_ARB_vertex_program_functions },
+       { "GL_ARB_occlusion_query",     GL_ARB_occlusion_query_functions},
        { NULL, 0 }
 };
 
@@ -229,6 +232,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual,
        nouveauInitBufferObjects(ctx);
        if (!nouveauSyncInitFuncs(ctx))
           return GL_FALSE;
+       nouveauQueryInitFuncs(ctx);
        nmesa->hw_func.InitCard(nmesa);
         nouveauInitState(ctx);
 
index bcfbb9f..c1d0665 100644 (file)
@@ -105,6 +105,11 @@ typedef struct nouveau_context {
        /* Channel synchronisation */
        nouveau_notifier *syncNotifier;
 
+       /* ARB_occlusion_query / EXT_timer_query */
+       GLuint            query_object_max;
+       GLboolean *       query_alloc;
+       nouveau_notifier *queryNotifier;
+
        /* Additional hw-specific functions */
        nouveau_hw_func hw_func;
 
index e154e0a..daad281 100644 (file)
@@ -15,7 +15,8 @@ enum DMAObjects {
        NvCtxSurf3D             = 0x80000023,
        NvDmaFB                 = 0xD0FB0001,
        NvDmaAGP                = 0xD0AA0001,
-       NvSyncNotify            = 0xD0000001
+       NvSyncNotify            = 0xD0000001,
+       NvQueryNotify           = 0xD0000002
 };
 
 enum DMASubchannel {
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.c b/src/mesa/drivers/dri/nouveau/nouveau_query.c
new file mode 100644 (file)
index 0000000..de3f5b0
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * 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.
+ *
+ */
+
+/* GL_ARB_occlusion_query support for NV20/30/40 */
+
+#include "mtypes.h"
+
+#include "nouveau_fifo.h"
+#include "nouveau_msg.h"
+#include "nouveau_object.h"
+#include "nouveau_reg.h"
+#include "nouveau_sync.h"
+#include "nouveau_query.h"
+
+static struct gl_query_object *
+nouveauNewQueryObject(GLcontext *ctx, GLuint id)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+       nouveau_query_object *nq;
+       int i;
+
+       for (i=0; i<nmesa->query_object_max; i++)
+               if (nmesa->query_alloc[i] == GL_FALSE)
+                       break;
+       if (i==nmesa->query_object_max)
+               return NULL;
+
+       nq = CALLOC_STRUCT(nouveau_query_object_t);
+       if (nq) {
+               nq->notifier_id = i;
+
+               nq->mesa.Id     = id;
+               nq->mesa.Result = 0;
+               nq->mesa.Active = GL_FALSE;
+               nq->mesa.Ready  = GL_TRUE;
+       }
+
+       return (struct gl_query_object *)nq;
+}
+
+static void
+nouveauBeginQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+       nouveau_query_object *nq = (nouveau_query_object *)q;
+
+       nouveau_notifier_reset(nmesa->queryNotifier, nq->notifier_id);
+
+       switch (nmesa->screen->card->type) {
+       case NV_20:
+               BEGIN_RING_CACHE(NvSub3D, 0x17c8, 1);
+               OUT_RING_CACHE  (1);
+               BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1);
+               OUT_RING_CACHE  (1);
+               break;
+       case NV_30:
+       case NV_40:
+       case NV_44:
+               /* I don't think this is OCC_QUERY enable, but it *is* needed to make
+                * the SET_OBJECT7 notifier block work with STORE_RESULT.
+                *
+                * Also, this appears to reset the pixel pass counter */
+               BEGIN_RING_SIZE(NvSub3D,
+                                NV30_TCL_PRIMITIVE_3D_OCC_QUERY_OR_COLOR_BUFF_ENABLE,
+                                1);
+               OUT_RING        (1);
+               /* Probably OCC_QUERY_ENABLE */
+               BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1);
+               OUT_RING_CACHE  (1);
+               break;
+       default:
+               WARN_ONCE("no support for this card\n");
+               break;
+       }
+}
+
+static void
+nouveauUpdateQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+       nouveau_query_object *nq = (nouveau_query_object *)q;
+       int status;
+
+       status = nouveau_notifier_status(nmesa->queryNotifier,
+                                        nq->notifier_id);
+
+       q->Ready = (status == NV_NOTIFY_STATE_STATUS_COMPLETED);
+       if (q->Ready)
+               q->Result = nouveau_notifier_return_val(nmesa->queryNotifier,
+                                                       nq->notifier_id);
+}
+
+static void
+nouveauWaitQueryResult(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+       nouveau_query_object *nq = (nouveau_query_object *)q;
+
+       nouveau_notifier_wait_status(nmesa->queryNotifier, nq->notifier_id,
+                                    NV_NOTIFY_STATE_STATUS_COMPLETED, 0);
+       nouveauUpdateQuery(ctx, target, q);
+}
+
+static void
+nouveauEndQuery(GLcontext *ctx, GLenum target, struct gl_query_object *q)
+{
+       nouveau_query_object *nq = (nouveau_query_object *)q;
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+       switch (nmesa->screen->card->type) {
+       case NV_20:
+               BEGIN_RING_SIZE(NvSub3D, 0x17d0, 1);
+               OUT_RING       (0x01000000 | nq->notifier_id*32);
+               break;
+       case NV_30:
+       case NV_40:
+       case NV_44:
+               BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_STORE_RESULT, 1);
+               OUT_RING       (0x01000000 | nq->notifier_id*32);
+               break;
+       default:
+               WARN_ONCE("no support for this card\n");
+               break;
+       }
+       FIRE_RING();
+
+       /*XXX: wait for query to complete, mesa doesn't give the driver
+        *     an interface to query the status of a query object so 
+        *     this has to stall the channel.
+        */
+       nouveauWaitQueryResult(ctx, target, q);
+
+       BEGIN_RING_CACHE(NvSub3D, 0x17cc, 1);
+       OUT_RING_CACHE  (0);
+}
+
+void
+nouveauQueryInitFuncs(GLcontext *ctx)
+{
+       nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
+
+       if (nmesa->screen->card->type < NV_20)
+               return;
+
+       nmesa->query_object_max = (0x4000 / 32);
+       nmesa->queryNotifier =
+               nouveau_notifier_new(ctx, NvQueryNotify,
+                                         nmesa->query_object_max);
+       nmesa->query_alloc = calloc(nmesa->query_object_max, sizeof(GLboolean));
+
+       switch (nmesa->screen->card->type) {
+       case NV_20:
+               BEGIN_RING_CACHE(NvSub3D, NV20_TCL_PRIMITIVE_3D_SET_OBJECT8, 1);
+               OUT_RING_CACHE  (NvQueryNotify);
+               break;
+       case NV_30:
+       case NV_40:
+       case NV_44:
+               BEGIN_RING_CACHE(NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT7, 1);
+               OUT_RING_CACHE  (NvQueryNotify);
+               break;
+       default:
+               break;
+       };
+
+       ctx->Driver.NewQueryObject      = nouveauNewQueryObject;
+       ctx->Driver.BeginQuery          = nouveauBeginQuery;
+       ctx->Driver.EndQuery            = nouveauEndQuery;
+#if 0
+       ctx->Driver.UpdateQuery         = nouveauUpdateQuery;
+       ctx->Driver.WaitQueryResult     = nouveauWaitQueryResult;
+#endif
+}
+
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_query.h b/src/mesa/drivers/dri/nouveau/nouveau_query.h
new file mode 100644 (file)
index 0000000..3ded414
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef __NOUVEAU_QUERY_H__
+#define __NOUVEAU_QUERY_H__
+
+typedef struct nouveau_query_object_t {
+       struct gl_query_object mesa;
+
+       int notifier_id;
+} nouveau_query_object;
+
+extern void nouveauQueryInitFuncs(GLcontext *ctx);
+#endif
index 5fb8dec..c47ff3a 100644 (file)
@@ -1,3 +1,30 @@
+/*
+ * 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"
index 5c941bb..019d5f6 100644 (file)
@@ -1,3 +1,30 @@
+/*
+ * 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.
+ *
+ */
+
 #ifndef __NOUVEAU_SYNC_H__
 #define __NOUVEAU_SYNC_H__