Implemented GL_ARB_occlusion_query (not 100% finalized).
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 13 Jun 2003 02:37:27 +0000 (02:37 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 13 Jun 2003 02:37:27 +0000 (02:37 +0000)
21 files changed:
docs/RELNOTES-5.1
docs/VERSIONS
include/GL/gl.h
src/mesa/Makefile.X11
src/mesa/glapi/APIspec
src/mesa/glapi/glapioffsets.h
src/mesa/glapi/glapitable.h
src/mesa/glapi/glapitemp.h
src/mesa/glapi/glprocs.h
src/mesa/main/config.h
src/mesa/main/context.c
src/mesa/main/extensions.c
src/mesa/main/mtypes.h
src/mesa/main/occlude.c [new file with mode: 0644]
src/mesa/main/occlude.h [new file with mode: 0644]
src/mesa/main/state.c
src/mesa/sparc/glapi_sparc.S
src/mesa/swrast/s_context.c
src/mesa/swrast/s_span.c
src/mesa/swrast/s_triangle.c
src/mesa/x86/glapi_x86.S

index 0a38006752ff89d2b8e800e7933bf054468217f8..d0619916cc66e850392db99d9a3325ae3f0df4a8 100644 (file)
@@ -60,6 +60,9 @@ GL_NV_light_max_exponent
 GL_EXT_texture_rectangle
    Identical to GL_NV_texture_rectangle
 
+GL_ARB_occlusion_query
+   Useful for visibility-based culling.
+
 
 
 Build System Changes
index 0a35cb518ffee44e1ddf5877d125b8d4ab3b5bd2..7d48f3f325329cceb263024610225243560bdef4 100644 (file)
@@ -1126,6 +1126,7 @@ Mesa Version History
        - GL_NV_fragment_program extension
        - GL_NV_light_max_exponent
        - GL_EXT_texture_rectangle (identical to GL_NV_texture_rectangle)
+       - GL_ARB_occlusion_query
        - new X86 feature detection code (Petr Sebor)
        - less memory used for display lists and vertex buffers
        - demo of per-pixel lighting with a fragment program (demos/fplight.c)
index f7456ef99a0e02fbf4983d550fa551149c2fe126..260b59ac386f972967731c9379eecc02e3e79dec 100644 (file)
@@ -2640,6 +2640,39 @@ typedef void (APIENTRY * PFNGLDEPTHBOUNDSEXTPROC)(GLclampd zmin, GLclampd zmax);
 
 
 
+/* XXX temporary until glext.h is updated! */
+#ifndef GL_ARB_occlusion_query
+#define GL_ARB_occlusion_query 1
+
+#define GL_SAMPLES_PASSED_ARB         0x8914
+#define GL_QUERY_COUNTER_BITS_ARB     0x8864
+#define GL_CURRENT_QUERY_ARB          0x8865
+#define GL_QUERY_RESULT_ARB           0x8866
+#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
+
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void GLAPIENTRY glGenQueriesARB(GLsizei n, GLuint *ids);
+GLAPI void GLAPIENTRY glDeleteQueriesARB(GLsizei n, const GLuint *ids);
+GLAPI GLboolean GLAPIENTRY glIsQueryARB(GLuint id);
+GLAPI void GLAPIENTRY glBeginQueryARB(GLenum target, GLuint id);
+GLAPI void GLAPIENTRY glEndQueryARB(GLenum target);
+GLAPI void GLAPIENTRY glGetQueryivARB(GLenum target, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetQueryObjectivARB(GLuint id, GLenum pname, GLint *params);
+GLAPI void GLAPIENTRY glGetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params);
+#endif
+
+typedef void (APIENTRY * PFNGLGENQUERIESARBPROC)(GLsizei n, GLuint *ids);
+typedef void (APIENTRY * PFNGLDELETEQUERIESARBPROC)(GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRY * PFNGLISQUERYARBPROC)(GLuint id);
+typedef void (APIENTRY * PFNGLBEGINQUERYARBPROC)(GLenum target, GLuint id);
+typedef void (APIENTRY * PFNGLENDQUERYARBPROC)(GLenum target);
+typedef void (APIENTRY * PFNGLGETQUERYIVARBPROC)(GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETQUERYOBJECTIVARBPROC)(GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRY * PFNGLGETQUERYOBJECTUIVARBPROC)(GLuint id, GLenum pname, GLuint *params);
+
+#endif /* GL_ARB_occlusion_query */
+
+
 /**********************************************************************
  * Begin system-specific stuff
  */
index ae9f89cc8c7b6e28cbfef1b974aa2d93dc784559..30ab3bd4b8f23be812ef21a16d39f18f92f978ef 100644 (file)
@@ -58,6 +58,7 @@ MAIN_SOURCES = \
        main/nvfragparse.c \
        main/nvvertexec.c \
        main/nvvertparse.c \
+       main/occlude.c \
        main/pixel.c \
        main/points.c \
        main/polygon.c \
index 5075eaf035928982557518f7dbc3b4606ef4ea91..eba696346c5fa0a1392a481e01e6cce3ef8c7d97 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: APIspec,v 1.17 2003/05/10 04:35:36 brianp Exp $
+# $Id: APIspec,v 1.18 2003/06/13 02:37:28 brianp Exp $
 
 # This file describes all the OpenGL functions.
 # We use a number of Python scripts to parse this file and
@@ -8346,6 +8346,67 @@ offset           699
 
 
 
+# GL_ARB_occlusion_query
+
+name           GenQueriesARB
+return         void
+param          n               GLsizei
+param          ids             GLuint *
+category       GL_ARB_occlusion_query
+offset         700
+
+name           DeleteQueriesARB
+return         void
+param          n               GLsizei
+param          ids             const GLuint *
+category       GL_ARB_occlusion_query
+offset         701
+
+name           IsQueryARB
+return         GLboolean
+param          id              GLuint
+category       GL_ARB_occlusion_query
+offset         702
+
+name           BeginQueryARB
+return         void
+param          target          GLenum
+param          id              GLuint
+category       GL_ARB_occlusion_query
+offset         703
+
+name           EndQueryARB
+return         void
+param          target          GLenum
+category       GL_ARB_occlusion_query
+offset         704
+
+name           GetQueryivARB
+return         void
+param          target          GLenum
+param          pname           GLenum
+param          params          GLint *
+category       GL_ARB_occlusion_query
+offset         705
+
+name           GetQueryObjectivARB
+return         void
+param          id              GLuint
+param          pname           GLenum
+param          params          GLint *
+category       GL_ARB_occlusion_query
+offset         706
+
+name           GetQueryObjectuivARB
+return         void
+param          id              GLuint
+param          pname           GLenum
+param          params          GLuint *
+category       GL_ARB_occlusion_query
+offset         707
+
+
+
 # end of file sentinal
 
 name           dummy
index ccc05daee18d55dd219fd55a96f2518b11830938..0dc699f5c229f6da7daac9b2225fb609df80608c 100644 (file)
 #define _gloffset_MapBufferARB 697
 #define _gloffset_UnmapBufferARB 698
 #define _gloffset_DepthBoundsEXT 699
+#define _gloffset_GenQueriesARB 700
+#define _gloffset_DeleteQueriesARB 701
+#define _gloffset_IsQueryARB 702
+#define _gloffset_BeginQueryARB 703
+#define _gloffset_EndQueryARB 704
+#define _gloffset_GetQueryivARB 705
+#define _gloffset_GetQueryObjectivARB 706
+#define _gloffset_GetQueryObjectuivARB 707
 
 #endif
index 2bb31e2e0db131e97f04e3611aa53caed304c611..42f8408480a810d66a4ef35b12f655e625ad70b6 100644 (file)
@@ -706,6 +706,14 @@ struct _glapi_table
    void * (*MapBufferARB)(GLenum target, GLenum access); /* 697 */
    GLboolean (*UnmapBufferARB)(GLenum target); /* 698 */
    void (*DepthBoundsEXT)(GLclampd zmin, GLclampd zmax); /* 699 */
+   void (*GenQueriesARB)(GLsizei n, GLuint * ids); /* 700 */
+   void (*DeleteQueriesARB)(GLsizei n, const GLuint * ids); /* 701 */
+   GLboolean (*IsQueryARB)(GLuint id); /* 702 */
+   void (*BeginQueryARB)(GLenum target, GLuint id); /* 703 */
+   void (*EndQueryARB)(GLenum target); /* 704 */
+   void (*GetQueryivARB)(GLenum target, GLenum pname, GLint * params); /* 705 */
+   void (*GetQueryObjectivARB)(GLuint id, GLenum pname, GLint * params); /* 706 */
+   void (*GetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint * params); /* 707 */
 };
 
 #endif
index 707333043dcb581d2262570f41e78ca5eee3f8bf..4d373933d4a987662fe1349c71c5bd6cb6c5ba6b 100644 (file)
@@ -4624,6 +4624,46 @@ KEYWORD1 void KEYWORD2 NAME(DepthBoundsEXT)(GLclampd zmin, GLclampd zmax)
    DISPATCH(DepthBoundsEXT, (zmin, zmax), (F, "glDepthBoundsEXT(%f, %f);\n", zmin, zmax));
 }
 
+KEYWORD1 void KEYWORD2 NAME(GenQueriesARB)(GLsizei n, GLuint * ids)
+{
+   DISPATCH(GenQueriesARB, (n, ids), (F, "glGenQueriesARB(%d, %p);\n", n, (const void *) ids));
+}
+
+KEYWORD1 void KEYWORD2 NAME(DeleteQueriesARB)(GLsizei n, const GLuint * ids)
+{
+   DISPATCH(DeleteQueriesARB, (n, ids), (F, "glDeleteQueriesARB(%d, %p);\n", n, (const void *) ids));
+}
+
+KEYWORD1 GLboolean KEYWORD2 NAME(IsQueryARB)(GLuint id)
+{
+   RETURN_DISPATCH(IsQueryARB, (id), (F, "glIsQueryARB(%d);\n", id));
+}
+
+KEYWORD1 void KEYWORD2 NAME(BeginQueryARB)(GLenum target, GLuint id)
+{
+   DISPATCH(BeginQueryARB, (target, id), (F, "glBeginQueryARB(0x%x, %d);\n", target, id));
+}
+
+KEYWORD1 void KEYWORD2 NAME(EndQueryARB)(GLenum target)
+{
+   DISPATCH(EndQueryARB, (target), (F, "glEndQueryARB(0x%x);\n", target));
+}
+
+KEYWORD1 void KEYWORD2 NAME(GetQueryivARB)(GLenum target, GLenum pname, GLint * params)
+{
+   DISPATCH(GetQueryivARB, (target, pname, params), (F, "glGetQueryivARB(0x%x, 0x%x, %p);\n", target, pname, (const void *) params));
+}
+
+KEYWORD1 void KEYWORD2 NAME(GetQueryObjectivARB)(GLuint id, GLenum pname, GLint * params)
+{
+   DISPATCH(GetQueryObjectivARB, (id, pname, params), (F, "glGetQueryObjectivARB(%d, 0x%x, %p);\n", id, pname, (const void *) params));
+}
+
+KEYWORD1 void KEYWORD2 NAME(GetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint * params)
+{
+   DISPATCH(GetQueryObjectuivARB, (id, pname, params), (F, "glGetQueryObjectuivARB(%d, 0x%x, %p);\n", id, pname, (const void *) params));
+}
+
 
 
 /*
@@ -5337,6 +5377,14 @@ void *DISPATCH_TABLE_NAME[] = {
    TABLE_ENTRY(MapBufferARB),
    TABLE_ENTRY(UnmapBufferARB),
    TABLE_ENTRY(DepthBoundsEXT),
+   TABLE_ENTRY(GenQueriesARB),
+   TABLE_ENTRY(DeleteQueriesARB),
+   TABLE_ENTRY(IsQueryARB),
+   TABLE_ENTRY(BeginQueryARB),
+   TABLE_ENTRY(EndQueryARB),
+   TABLE_ENTRY(GetQueryivARB),
+   TABLE_ENTRY(GetQueryObjectivARB),
+   TABLE_ENTRY(GetQueryObjectuivARB),
    /* A whole bunch of no-op functions.  These might be called
     * when someone tries to call a dynamically-registered
     * extension function without a current rendering context.
index ea18fdfc69f1cfd6de616973c388a147dfd3371f..70bac5623b5f5ab4a1d651fe3b6ea94db4e552d6 100644 (file)
@@ -890,5 +890,13 @@ static struct name_address_offset static_functions[] = {
    { "glMapBufferARB", (GLvoid *) glMapBufferARB, _gloffset_MapBufferARB },
    { "glUnmapBufferARB", (GLvoid *) glUnmapBufferARB, _gloffset_UnmapBufferARB },
    { "glDepthBoundsEXT", (GLvoid *) glDepthBoundsEXT, _gloffset_DepthBoundsEXT },
+   { "glGenQueriesARB", (GLvoid *) glGenQueriesARB, _gloffset_GenQueriesARB },
+   { "glDeleteQueriesARB", (GLvoid *) glDeleteQueriesARB, _gloffset_DeleteQueriesARB },
+   { "glIsQueryARB", (GLvoid *) glIsQueryARB, _gloffset_IsQueryARB },
+   { "glBeginQueryARB", (GLvoid *) glBeginQueryARB, _gloffset_BeginQueryARB },
+   { "glEndQueryARB", (GLvoid *) glEndQueryARB, _gloffset_EndQueryARB },
+   { "glGetQueryivARB", (GLvoid *) glGetQueryivARB, _gloffset_GetQueryivARB },
+   { "glGetQueryObjectivARB", (GLvoid *) glGetQueryObjectivARB, _gloffset_GetQueryObjectivARB },
+   { "glGetQueryObjectuivARB", (GLvoid *) glGetQueryObjectuivARB, _gloffset_GetQueryObjectuivARB },
    { NULL, NULL }  /* end of list marker */
 };
index f35f100205d3c0e4b5326f78ea8f9f1733133160..4b4b3ef10aecc32fdeb8cebc3573ee9a6fa3ac78 100644 (file)
 
 #define FEATURE_ARB_fragment_program 1
 
+#define FEATURE_ARB_occlusion_query 1
 
 #endif /* CONFIG_H */
index ae030bce8492b64cc3fe3f6f0f878e5970a4d9c4..666e3403a27a9b6d2210e3663de5bf1b48595098 100644 (file)
@@ -1562,6 +1562,10 @@ init_attrib_groups( GLcontext *ctx )
    ctx->FragmentProgram.Current->Base.RefCount++;
 #endif
 
+#if FEATURE_ARB_occlusion_query
+   ctx->Occlusion.QueryObjects = _mesa_NewHashTable();
+#endif
+
    /* Miscellaneous */
    ctx->NewState = _NEW_ALL;
    ctx->RenderMode = GL_RENDER;
index 50769fed31ea5152d5ef7038372f4321c214c9b7..3b7c21a1622b599b277c90e244f17f5ac8f10f4d 100644 (file)
@@ -54,6 +54,7 @@ static const struct {
    { OFF, "GL_ARB_imaging",                    F(ARB_imaging) },
    { OFF, "GL_ARB_multisample",                F(ARB_multisample) },
    { OFF, "GL_ARB_multitexture",               F(ARB_multitexture) },
+   { OFF, "GL_ARB_occlusion_query",            F(ARB_occlusion_query) },
    { OFF, "GL_ARB_point_parameters",           F(EXT_point_parameters) },
    { OFF, "GL_ARB_shadow",                     F(ARB_shadow) },
    { OFF, "GL_ARB_shadow_ambient",             F(SGIX_shadow_ambient) },
@@ -163,6 +164,9 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
 #endif
       "GL_ARB_imaging",
       "GL_ARB_multitexture",
+#if FEATURE_ARB_occlusion_query
+      "GL_ARB_occlusion_query",
+#endif
       "GL_ARB_point_parameters",
       "GL_ARB_shadow",
       "GL_ARB_shadow_ambient",
index dd660fa3abd2cfc3d3dfe05599e56fa972c4f88d..59a75da8c88b602c17ee306c8180dc2a1c5d3507 100644 (file)
@@ -1314,6 +1314,18 @@ struct fragment_program_state
 };
 
 
+/*
+ * State for GL_ARB_occlusion_query
+ */
+struct occlusion_state
+{
+   GLboolean Active;
+   GLuint CurrentQueryObject;
+   GLuint PassedCounter;
+   struct _mesa_HashTable *QueryObjects;
+};
+
+
 /*
  * State which can be shared by multiple contexts:
  */
@@ -1449,6 +1461,7 @@ struct gl_extensions {
    GLboolean ARB_imaging;
    GLboolean ARB_multisample;
    GLboolean ARB_multitexture;
+   GLboolean ARB_occlusion_query;
    GLboolean ARB_shadow;
    GLboolean ARB_texture_border_clamp;
    GLboolean ARB_texture_compression;
@@ -1827,6 +1840,8 @@ struct __GLcontextRec {
    struct vertex_program_state VertexProgram;      /* GL_NV_vertex_program */
    struct fragment_program_state FragmentProgram;  /* GL_NV_fragment_program */
 
+   struct occlusion_state Occlusion;  /* GL_ARB_occlusion_query */
+
    GLenum ErrorValue;        /* Last error code */
    GLenum RenderMode;        /* either GL_RENDER, GL_SELECT, GL_FEEDBACK */
    GLuint NewState;          /* bitwise-or of _NEW_* flags */
diff --git a/src/mesa/main/occlude.c b/src/mesa/main/occlude.c
new file mode 100644 (file)
index 0000000..029e5d0
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  5.1
+ *
+ * Copyright (C) 1999-2003  Brian Paul   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 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
+ * BRIAN PAUL 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.
+ */
+
+
+/*
+ * \brief Functions to implement the GL_ARB_occlusion_query extension.
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "hash.h"
+#include "imports.h"
+#include "occlude.h"
+#include "mtypes.h"
+
+#ifndef GL_SAMPLES_PASSED_ARB
+#define GL_SAMPLES_PASSED_ARB         0x8914
+#define GL_QUERY_COUNTER_BITS_ARB     0x8864
+#define GL_CURRENT_QUERY_ARB          0x8865
+#define GL_QUERY_RESULT_ARB           0x8866
+#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
+#endif
+
+
+struct occlusion_query
+{
+   GLenum Target;
+   GLuint Id;
+   GLuint PassedCounter;
+   GLboolean Active;
+};
+
+
+/**
+ * Allocate a new occlusion query object.
+ * \param target - must be GL_SAMPLES_PASSED_ARB at this time
+ * \param id - the object's ID
+ * \return pointer to new occlusion_query object or NULL if out of memory.
+ */
+static struct occlusion_query *
+new_query_object(GLenum target, GLuint id)
+{
+   struct occlusion_query *q = MALLOC_STRUCT(occlusion_query);
+   if (q) {
+      q->Target = target;
+      q->Id = id;
+      q->PassedCounter = 0;
+      q->Active = GL_FALSE;
+   }
+   return q;
+}
+
+
+/**
+ * Delete an occlusion query object.
+ */
+static void
+delete_query_object(struct occlusion_query *q)
+{
+   FREE(q);
+}
+
+
+void
+_mesa_GenQueriesARB(GLsizei n, GLuint *ids)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLuint first;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (n < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)");
+      return;
+   }
+
+   if (ctx->Occlusion.Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGenQueriesARB");
+      return;
+   }
+
+   first = _mesa_HashFindFreeKeyBlock(ctx->Occlusion.QueryObjects, n);
+   if (first) {
+      GLuint i;
+      for (i = 0; i < n; i++) {
+         struct occlusion_query *q = new_query_object(GL_SAMPLES_PASSED_ARB,
+                                                      first + i);
+         if (!q) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB");
+            return;
+         }
+         ids[i] = first + i;
+         _mesa_HashInsert(ctx->Occlusion.QueryObjects, first + i, q);
+      }
+   }
+}
+
+
+void
+_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint i;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (n < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteQueriesARB(n < 0)");
+      return;
+   }
+
+   if (ctx->Occlusion.Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteQueriesARB");
+      return;
+   }
+
+   for (i = 0; i < n; i++) {
+      if (ids[i] > 0) {
+         struct occlusion_query *q = (struct occlusion_query *)
+            _mesa_HashLookup(ctx->Occlusion.QueryObjects, ids[i]);
+         if (q) {
+            _mesa_HashRemove(ctx->Occlusion.QueryObjects, ids[i]);
+            delete_query_object(q);
+         }
+      }
+   }
+}
+
+
+GLboolean
+_mesa_IsQueryARB(GLuint id)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+   if (id && _mesa_HashLookup(ctx->Occlusion.QueryObjects, id))
+      return GL_TRUE;
+   else
+      return GL_FALSE;
+}
+
+
+void
+_mesa_BeginQueryARB(GLenum target, GLuint id)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct occlusion_query *q;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_DEPTH);
+
+   if (target != GL_SAMPLES_PASSED_ARB) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)");
+      return;
+   }
+
+   if (ctx->Occlusion.CurrentQueryObject) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB(target)");
+      return;
+   }
+
+   q = (struct occlusion_query *)
+      _mesa_HashLookup(ctx->Occlusion.QueryObjects, id);
+   if (q && q->Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB");
+      return;
+   }
+   else if (!q) {
+      q = new_query_object(target, id);
+      if (!q) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQueryARB");
+         return;
+      }
+      _mesa_HashInsert(ctx->Occlusion.QueryObjects, id, q);
+   }
+
+   q->Active = GL_TRUE;
+   q->PassedCounter = 0;
+   ctx->Occlusion.Active = GL_TRUE;
+   ctx->Occlusion.CurrentQueryObject = id;
+   ctx->Occlusion.PassedCounter = 0;
+}
+
+
+void
+_mesa_EndQueryARB(GLenum target)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct occlusion_query *q;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_DEPTH);
+
+   if (target != GL_SAMPLES_PASSED_ARB) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)");
+      return;
+   }
+
+   q = (struct occlusion_query *)
+      _mesa_HashLookup(ctx->Occlusion.QueryObjects,
+                       ctx->Occlusion.CurrentQueryObject);
+   if (!q || !q->Active) {
+      _mesa_problem(ctx, "bad query object in glEndQueryARB");
+      return;
+   }
+
+   q->PassedCounter = ctx->Occlusion.PassedCounter;
+   q->Active = GL_FALSE;
+   ctx->Occlusion.Active = GL_FALSE;
+   ctx->Occlusion.CurrentQueryObject = 0;
+}
+
+
+void
+_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (target != GL_SAMPLES_PASSED_ARB) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(target)");
+      return;
+   }
+
+   switch (pname) {
+      case GL_QUERY_COUNTER_BITS_ARB:
+         *params = 8 * sizeof(GLuint);
+         break;
+      case GL_CURRENT_QUERY_ARB:
+         *params = ctx->Occlusion.CurrentQueryObject;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(pname)");
+         return;
+   }
+}
+
+
+void
+_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct occlusion_query *q;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   q = (struct occlusion_query *)
+      _mesa_HashLookup(ctx->Occlusion.QueryObjects, id);
+   if (!q || q->Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryObjectivARB");
+      return;
+   }
+
+   switch (pname) {
+      case GL_QUERY_RESULT_ARB:
+         *params = q->PassedCounter;
+         break;
+      case GL_QUERY_RESULT_AVAILABLE_ARB:
+         /* XXX revisit when we have a hardware implementation! */
+         *params = GL_TRUE;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectivARB(pname)");
+         return;
+   }
+}
+
+
+void
+_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct occlusion_query *q;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   q = (struct occlusion_query *)
+      _mesa_HashLookup(ctx->Occlusion.QueryObjects, id);
+   if (!q || q->Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryObjectuivARB");
+      return;
+   }
+
+   switch (pname) {
+      case GL_QUERY_RESULT_ARB:
+         *params = q->PassedCounter;
+         break;
+      case GL_QUERY_RESULT_AVAILABLE_ARB:
+         /* XXX revisit when we have a hardware implementation! */
+         *params = GL_TRUE;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)");
+         return;
+   }
+}
diff --git a/src/mesa/main/occlude.h b/src/mesa/main/occlude.h
new file mode 100644 (file)
index 0000000..cc37867
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  5.1
+ *
+ * Copyright (C) 1999-2003  Brian Paul   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 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
+ * BRIAN PAUL 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 OCCLUDE_H
+#define OCCLUDE_H
+
+
+extern void
+_mesa_GenQueriesARB(GLsizei n, GLuint *ids);
+
+extern void
+_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids);
+
+extern GLboolean
+_mesa_IsQueryARB(GLuint id);
+
+extern void
+_mesa_BeginQueryARB(GLenum target, GLuint id);
+
+extern void
+_mesa_EndQueryARB(GLenum target);
+
+extern void
+_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params);
+
+extern void
+_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params);
+
+extern void
+_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params);
+
+
+#endif /* OCCLUDE_H */
index 63c8bc4abda403a55cbee2c14461e892903ae8c5..2851b8e083b2be7e9bbc0052fdf052e377f03820 100644 (file)
@@ -59,6 +59,9 @@
 #include "light.h"
 #include "lines.h"
 #include "matrix.h"
+#if FEATURE_ARB_occlusion_query
+#include "occlude.h"
+#endif
 #include "pixel.h"
 #include "points.h"
 #include "polygon.h"
@@ -644,6 +647,17 @@ _mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize)
    exec->MapBufferARB = _mesa_MapBufferARB;
    exec->UnmapBufferARB = _mesa_UnmapBufferARB;
 #endif
+
+#if FEATURE_ARB_occlusion_query
+   exec->GenQueriesARB = _mesa_GenQueriesARB;
+   exec->DeleteQueriesARB = _mesa_DeleteQueriesARB;
+   exec->IsQueryARB = _mesa_IsQueryARB;
+   exec->BeginQueryARB = _mesa_BeginQueryARB;
+   exec->EndQueryARB = _mesa_EndQueryARB;
+   exec->GetQueryivARB = _mesa_GetQueryivARB;
+   exec->GetQueryObjectivARB = _mesa_GetQueryObjectivARB;
+   exec->GetQueryObjectuivARB = _mesa_GetQueryObjectuivARB;
+#endif
 }
 
 
index 6c12304077c5a8cdb992737c9e01632fbba4fe65..b44ab68c3b71f5460d3da4fc2f3c267e7cdef206 100644 (file)
@@ -18623,6 +18623,174 @@ glDepthBoundsEXT:
        sethi   %hi(0x00000000), %g1
        ld      [%g1 + %lo(0x00000000)], %g1
        ld      [%g1 + (4 * _gloffset_DepthBoundsEXT)], %g3
+#endif
+       jmpl    %g3, %g0
+       nop
+
+.globl glGenQueriesARB
+.type glGenQueriesARB,#function
+glGenQueriesARB:
+#ifdef __sparc_v9__
+       sethi   %hi(0x00000000), %g2
+       sethi   %hi(0x00000000), %g1
+       or      %g2, %lo(0x00000000), %g2
+       or      %g1, %lo(0x00000000), %g1
+       sllx    %g2, 32, %g2
+       ldx     [%g1 + %g2], %g1
+       sethi   %hi(8 * _gloffset_GenQueriesARB), %g2
+       or      %g2, %lo(8 * _gloffset_GenQueriesARB), %g2
+       ldx     [%g1 + %g2], %g3
+#else
+       sethi   %hi(0x00000000), %g1
+       ld      [%g1 + %lo(0x00000000)], %g1
+       ld      [%g1 + (4 * _gloffset_GenQueriesARB)], %g3
+#endif
+       jmpl    %g3, %g0
+       nop
+
+.globl glDeleteQueriesARB
+.type glDeleteQueriesARB,#function
+glDeleteQueriesARB:
+#ifdef __sparc_v9__
+       sethi   %hi(0x00000000), %g2
+       sethi   %hi(0x00000000), %g1
+       or      %g2, %lo(0x00000000), %g2
+       or      %g1, %lo(0x00000000), %g1
+       sllx    %g2, 32, %g2
+       ldx     [%g1 + %g2], %g1
+       sethi   %hi(8 * _gloffset_DeleteQueriesARB), %g2
+       or      %g2, %lo(8 * _gloffset_DeleteQueriesARB), %g2
+       ldx     [%g1 + %g2], %g3
+#else
+       sethi   %hi(0x00000000), %g1
+       ld      [%g1 + %lo(0x00000000)], %g1
+       ld      [%g1 + (4 * _gloffset_DeleteQueriesARB)], %g3
+#endif
+       jmpl    %g3, %g0
+       nop
+
+.globl glIsQueryARB
+.type glIsQueryARB,#function
+glIsQueryARB:
+#ifdef __sparc_v9__
+       sethi   %hi(0x00000000), %g2
+       sethi   %hi(0x00000000), %g1
+       or      %g2, %lo(0x00000000), %g2
+       or      %g1, %lo(0x00000000), %g1
+       sllx    %g2, 32, %g2
+       ldx     [%g1 + %g2], %g1
+       sethi   %hi(8 * _gloffset_IsQueryARB), %g2
+       or      %g2, %lo(8 * _gloffset_IsQueryARB), %g2
+       ldx     [%g1 + %g2], %g3
+#else
+       sethi   %hi(0x00000000), %g1
+       ld      [%g1 + %lo(0x00000000)], %g1
+       ld      [%g1 + (4 * _gloffset_IsQueryARB)], %g3
+#endif
+       jmpl    %g3, %g0
+       nop
+
+.globl glBeginQueryARB
+.type glBeginQueryARB,#function
+glBeginQueryARB:
+#ifdef __sparc_v9__
+       sethi   %hi(0x00000000), %g2
+       sethi   %hi(0x00000000), %g1
+       or      %g2, %lo(0x00000000), %g2
+       or      %g1, %lo(0x00000000), %g1
+       sllx    %g2, 32, %g2
+       ldx     [%g1 + %g2], %g1
+       sethi   %hi(8 * _gloffset_BeginQueryARB), %g2
+       or      %g2, %lo(8 * _gloffset_BeginQueryARB), %g2
+       ldx     [%g1 + %g2], %g3
+#else
+       sethi   %hi(0x00000000), %g1
+       ld      [%g1 + %lo(0x00000000)], %g1
+       ld      [%g1 + (4 * _gloffset_BeginQueryARB)], %g3
+#endif
+       jmpl    %g3, %g0
+       nop
+
+.globl glEndQueryARB
+.type glEndQueryARB,#function
+glEndQueryARB:
+#ifdef __sparc_v9__
+       sethi   %hi(0x00000000), %g2
+       sethi   %hi(0x00000000), %g1
+       or      %g2, %lo(0x00000000), %g2
+       or      %g1, %lo(0x00000000), %g1
+       sllx    %g2, 32, %g2
+       ldx     [%g1 + %g2], %g1
+       sethi   %hi(8 * _gloffset_EndQueryARB), %g2
+       or      %g2, %lo(8 * _gloffset_EndQueryARB), %g2
+       ldx     [%g1 + %g2], %g3
+#else
+       sethi   %hi(0x00000000), %g1
+       ld      [%g1 + %lo(0x00000000)], %g1
+       ld      [%g1 + (4 * _gloffset_EndQueryARB)], %g3
+#endif
+       jmpl    %g3, %g0
+       nop
+
+.globl glGetQueryivARB
+.type glGetQueryivARB,#function
+glGetQueryivARB:
+#ifdef __sparc_v9__
+       sethi   %hi(0x00000000), %g2
+       sethi   %hi(0x00000000), %g1
+       or      %g2, %lo(0x00000000), %g2
+       or      %g1, %lo(0x00000000), %g1
+       sllx    %g2, 32, %g2
+       ldx     [%g1 + %g2], %g1
+       sethi   %hi(8 * _gloffset_GetQueryivARB), %g2
+       or      %g2, %lo(8 * _gloffset_GetQueryivARB), %g2
+       ldx     [%g1 + %g2], %g3
+#else
+       sethi   %hi(0x00000000), %g1
+       ld      [%g1 + %lo(0x00000000)], %g1
+       ld      [%g1 + (4 * _gloffset_GetQueryivARB)], %g3
+#endif
+       jmpl    %g3, %g0
+       nop
+
+.globl glGetQueryObjectivARB
+.type glGetQueryObjectivARB,#function
+glGetQueryObjectivARB:
+#ifdef __sparc_v9__
+       sethi   %hi(0x00000000), %g2
+       sethi   %hi(0x00000000), %g1
+       or      %g2, %lo(0x00000000), %g2
+       or      %g1, %lo(0x00000000), %g1
+       sllx    %g2, 32, %g2
+       ldx     [%g1 + %g2], %g1
+       sethi   %hi(8 * _gloffset_GetQueryObjectivARB), %g2
+       or      %g2, %lo(8 * _gloffset_GetQueryObjectivARB), %g2
+       ldx     [%g1 + %g2], %g3
+#else
+       sethi   %hi(0x00000000), %g1
+       ld      [%g1 + %lo(0x00000000)], %g1
+       ld      [%g1 + (4 * _gloffset_GetQueryObjectivARB)], %g3
+#endif
+       jmpl    %g3, %g0
+       nop
+
+.globl glGetQueryObjectuivARB
+.type glGetQueryObjectuivARB,#function
+glGetQueryObjectuivARB:
+#ifdef __sparc_v9__
+       sethi   %hi(0x00000000), %g2
+       sethi   %hi(0x00000000), %g1
+       or      %g2, %lo(0x00000000), %g2
+       or      %g1, %lo(0x00000000), %g1
+       sllx    %g2, 32, %g2
+       ldx     [%g1 + %g2], %g1
+       sethi   %hi(8 * _gloffset_GetQueryObjectuivARB), %g2
+       or      %g2, %lo(8 * _gloffset_GetQueryObjectuivARB), %g2
+       ldx     [%g1 + %g2], %g3
+#else
+       sethi   %hi(0x00000000), %g1
+       ld      [%g1 + %lo(0x00000000)], %g1
+       ld      [%g1 + (4 * _gloffset_GetQueryObjectuivARB)], %g3
 #endif
        jmpl    %g3, %g0
        nop
index 5160e810cdb77e03c7b1a4ff65ba42f8d03b4d85..6a25be68f5d86d7f02c0f9ba54827e9982f10263 100644 (file)
@@ -79,7 +79,7 @@ _swrast_update_rasterflags( GLcontext *ctx )
       RasterMask |= CLIP_BIT;
    }
 
-   if (ctx->Depth.OcclusionTest)
+   if (ctx->Depth.OcclusionTest || ctx->Occlusion.Active)
       RasterMask |= OCCLUSION_BIT;
 
 
index cce69b8c4394e0b6ad12d07701a7c62bed6d9744..59e89252a051d490c62640c23d0e7df8fdbaaecf 100644 (file)
@@ -841,6 +841,14 @@ _swrast_write_index_span( GLcontext *ctx, struct sw_span *span)
    /* if we get here, something passed the depth test */
    ctx->OcclusionResult = GL_TRUE;
 
+#if FEATURE_ARB_occlusion_query
+   if (ctx->Occlusion.Active) {
+      GLuint i;
+      for (i = 0; i < span->end; i++)
+         ctx->Occlusion.PassedCounter += span->array->mask[i];
+   }
+#endif
+
    /* we have to wait until after occlusion to do this test */
    if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) {
       /* write no pixels */
@@ -1046,6 +1054,14 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
    /* if we get here, something passed the depth test */
    ctx->OcclusionResult = GL_TRUE;
 
+#if FEATURE_ARB_occlusion_query
+   if (ctx->Occlusion.Active) {
+      GLuint i;
+      for (i = 0; i < span->end; i++)
+         ctx->Occlusion.PassedCounter += span->array->mask[i];
+   }
+#endif
+
    /* can't abort span-writing until after occlusion testing */
    if (colorMask == 0x0) {
       span->interpMask = origInterpMask;
@@ -1288,6 +1304,14 @@ _swrast_write_texture_span( GLcontext *ctx, struct sw_span *span)
    /* if we get here, some fragments passed the depth test */
    ctx->OcclusionResult = GL_TRUE;
 
+#if FEATURE_ARB_occlusion_query
+   if (ctx->Occlusion.Active) {
+      GLuint i;
+      for (i = 0; i < span->end; i++)
+         ctx->Occlusion.PassedCounter += span->array->mask[i];
+   }
+#endif
+
    /* We had to wait until now to check for glColorMask(F,F,F,F) because of
     * the occlusion test.
     */
index 43c131a6e7562616983af176d7567f62ed2c0a2f..0ce3459d544019b665daed19eb0123d8c4297142 100644 (file)
@@ -899,13 +899,16 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
 
 
 
+/*
+ * Special tri function for occlusion testing
+ */
 #define NAME occlusion_zless_triangle
 #define DO_OCCLUSION_TEST
 #define INTERP_Z 1
 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
-#define SETUP_CODE                     \
-   if (ctx->OcclusionResult) {         \
-      return;                          \
+#define SETUP_CODE                                             \
+   if (ctx->OcclusionResult && !ctx->Occlusion.Active) {       \
+      return;                                                  \
    }
 #define RENDER_SPAN( span )                            \
    GLuint i;                                           \
@@ -913,7 +916,7 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span,
       GLdepth z = FixedToDepth(span.z);                        \
       if (z < zRow[i]) {                               \
          ctx->OcclusionResult = GL_TRUE;               \
-         return;                                       \
+         ctx->Occlusion.PassedCounter++;               \
       }                                                        \
       span.z += span.zStep;                            \
    }
@@ -1034,7 +1037,8 @@ _swrast_choose_triangle( GLcontext *ctx )
          return;
       }
 
-      if (ctx->Depth.OcclusionTest &&
+      /* special case for occlusion testing */
+      if ((ctx->Depth.OcclusionTest || ctx->Occlusion.Active) &&
           ctx->Depth.Test &&
           ctx->Depth.Mask == GL_FALSE &&
           ctx->Depth.Func == GL_LESS &&
index a515818e4bab243764f36bc6af48f999ea6be77d..a574c63bcaa0f750190c775b8b08dd7a964855ec 100644 (file)
@@ -5337,5 +5337,53 @@ GL_PREFIX(DepthBoundsEXT):
        MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
        JMP(GL_OFFSET(_gloffset_DepthBoundsEXT))
 
+ALIGNTEXT16
+GLOBL_FN(GL_PREFIX(GenQueriesARB))
+GL_PREFIX(GenQueriesARB):
+       MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
+       JMP(GL_OFFSET(_gloffset_GenQueriesARB))
+
+ALIGNTEXT16
+GLOBL_FN(GL_PREFIX(DeleteQueriesARB))
+GL_PREFIX(DeleteQueriesARB):
+       MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
+       JMP(GL_OFFSET(_gloffset_DeleteQueriesARB))
+
+ALIGNTEXT16
+GLOBL_FN(GL_PREFIX(IsQueryARB))
+GL_PREFIX(IsQueryARB):
+       MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
+       JMP(GL_OFFSET(_gloffset_IsQueryARB))
+
+ALIGNTEXT16
+GLOBL_FN(GL_PREFIX(BeginQueryARB))
+GL_PREFIX(BeginQueryARB):
+       MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
+       JMP(GL_OFFSET(_gloffset_BeginQueryARB))
+
+ALIGNTEXT16
+GLOBL_FN(GL_PREFIX(EndQueryARB))
+GL_PREFIX(EndQueryARB):
+       MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
+       JMP(GL_OFFSET(_gloffset_EndQueryARB))
+
+ALIGNTEXT16
+GLOBL_FN(GL_PREFIX(GetQueryivARB))
+GL_PREFIX(GetQueryivARB):
+       MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
+       JMP(GL_OFFSET(_gloffset_GetQueryivARB))
+
+ALIGNTEXT16
+GLOBL_FN(GL_PREFIX(GetQueryObjectivARB))
+GL_PREFIX(GetQueryObjectivARB):
+       MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
+       JMP(GL_OFFSET(_gloffset_GetQueryObjectivARB))
+
+ALIGNTEXT16
+GLOBL_FN(GL_PREFIX(GetQueryObjectuivARB))
+GL_PREFIX(GetQueryObjectuivARB):
+       MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
+       JMP(GL_OFFSET(_gloffset_GetQueryObjectuivARB))
+
 
 #endif  /* __WIN32__ */