summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/RELNOTES-5.13
-rw-r--r--docs/VERSIONS1
-rw-r--r--include/GL/gl.h33
-rw-r--r--src/mesa/Makefile.X111
-rw-r--r--src/mesa/glapi/APIspec63
-rw-r--r--src/mesa/glapi/glapioffsets.h8
-rw-r--r--src/mesa/glapi/glapitable.h8
-rw-r--r--src/mesa/glapi/glapitemp.h48
-rw-r--r--src/mesa/glapi/glprocs.h8
-rw-r--r--src/mesa/main/config.h1
-rw-r--r--src/mesa/main/context.c4
-rw-r--r--src/mesa/main/extensions.c4
-rw-r--r--src/mesa/main/mtypes.h15
-rw-r--r--src/mesa/main/occlude.c314
-rw-r--r--src/mesa/main/occlude.h55
-rw-r--r--src/mesa/main/state.c14
-rw-r--r--src/mesa/sparc/glapi_sparc.S168
-rw-r--r--src/mesa/swrast/s_context.c2
-rw-r--r--src/mesa/swrast/s_span.c24
-rw-r--r--src/mesa/swrast/s_triangle.c14
-rw-r--r--src/mesa/x86/glapi_x86.S48
21 files changed, 829 insertions, 7 deletions
diff --git a/docs/RELNOTES-5.1 b/docs/RELNOTES-5.1
index 0a38006752f..d0619916cc6 100644
--- a/docs/RELNOTES-5.1
+++ b/docs/RELNOTES-5.1
@@ -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
diff --git a/docs/VERSIONS b/docs/VERSIONS
index 0a35cb518ff..7d48f3f3253 100644
--- a/docs/VERSIONS
+++ b/docs/VERSIONS
@@ -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)
diff --git a/include/GL/gl.h b/include/GL/gl.h
index f7456ef99a0..260b59ac386 100644
--- a/include/GL/gl.h
+++ b/include/GL/gl.h
@@ -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
*/
diff --git a/src/mesa/Makefile.X11 b/src/mesa/Makefile.X11
index ae9f89cc8c7..30ab3bd4b8f 100644
--- a/src/mesa/Makefile.X11
+++ b/src/mesa/Makefile.X11
@@ -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 \
diff --git a/src/mesa/glapi/APIspec b/src/mesa/glapi/APIspec
index 5075eaf0359..eba696346c5 100644
--- a/src/mesa/glapi/APIspec
+++ b/src/mesa/glapi/APIspec
@@ -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
diff --git a/src/mesa/glapi/glapioffsets.h b/src/mesa/glapi/glapioffsets.h
index ccc05daee18..0dc699f5c22 100644
--- a/src/mesa/glapi/glapioffsets.h
+++ b/src/mesa/glapi/glapioffsets.h
@@ -702,5 +702,13 @@
#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
diff --git a/src/mesa/glapi/glapitable.h b/src/mesa/glapi/glapitable.h
index 2bb31e2e0db..42f8408480a 100644
--- a/src/mesa/glapi/glapitable.h
+++ b/src/mesa/glapi/glapitable.h
@@ -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
diff --git a/src/mesa/glapi/glapitemp.h b/src/mesa/glapi/glapitemp.h
index 707333043dc..4d373933d4a 100644
--- a/src/mesa/glapi/glapitemp.h
+++ b/src/mesa/glapi/glapitemp.h
@@ -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.
diff --git a/src/mesa/glapi/glprocs.h b/src/mesa/glapi/glprocs.h
index ea18fdfc69f..70bac5623b5 100644
--- a/src/mesa/glapi/glprocs.h
+++ b/src/mesa/glapi/glprocs.h
@@ -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 */
};
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index f35f100205d..4b4b3ef10ae 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -243,5 +243,6 @@
#define FEATURE_ARB_fragment_program 1
+#define FEATURE_ARB_occlusion_query 1
#endif /* CONFIG_H */
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index ae030bce849..666e3403a27 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -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;
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 50769fed31e..3b7c21a1622 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -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",
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index dd660fa3abd..59a75da8c88 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1315,6 +1315,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:
*/
struct gl_shared_state {
@@ -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
index 00000000000..029e5d08946
--- /dev/null
+++ b/src/mesa/main/occlude.c
@@ -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
index 00000000000..cc3786772bc
--- /dev/null
+++ b/src/mesa/main/occlude.h
@@ -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 */
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 63c8bc4abda..2851b8e083b 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -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
}
diff --git a/src/mesa/sparc/glapi_sparc.S b/src/mesa/sparc/glapi_sparc.S
index 6c12304077c..b44ab68c3b7 100644
--- a/src/mesa/sparc/glapi_sparc.S
+++ b/src/mesa/sparc/glapi_sparc.S
@@ -18626,6 +18626,174 @@ glDepthBoundsEXT:
#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
nop
.globl _mesa_sparc_glapi_end
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index 5160e810cdb..6a25be68f5d 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -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;
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index cce69b8c439..59e89252a05 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -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.
*/
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index 43c131a6e75..0ce3459d544 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -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 &&
diff --git a/src/mesa/x86/glapi_x86.S b/src/mesa/x86/glapi_x86.S
index a515818e4ba..a574c63bcaa 100644
--- a/src/mesa/x86/glapi_x86.S
+++ b/src/mesa/x86/glapi_x86.S
@@ -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__ */