From b3ab925e910defa0955cac1adb6167a0bff1076f Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 21 Apr 2007 12:36:39 -0600 Subject: Rename occlude.[ch] to queryobj.[ch] to better reflect contents. --- src/mesa/main/occlude.c | 538 ----------------------------------------------- src/mesa/main/occlude.h | 70 ------ src/mesa/main/queryobj.c | 538 +++++++++++++++++++++++++++++++++++++++++++++++ src/mesa/main/queryobj.h | 70 ++++++ 4 files changed, 608 insertions(+), 608 deletions(-) delete mode 100644 src/mesa/main/occlude.c delete mode 100644 src/mesa/main/occlude.h create mode 100644 src/mesa/main/queryobj.c create mode 100644 src/mesa/main/queryobj.h diff --git a/src/mesa/main/occlude.c b/src/mesa/main/occlude.c deleted file mode 100644 index 5fef4a800dc..00000000000 --- a/src/mesa/main/occlude.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.1 - * - * Copyright (C) 1999-2006 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. - */ - - -#include "glheader.h" -#include "context.h" -#include "hash.h" -#include "imports.h" -#include "occlude.h" -#include "mtypes.h" - - -/** - * Allocate a new query object. This is a fallback routine called via - * ctx->Driver.NewQueryObject(). - * \param ctx - rendering context - * \param id - the new object's ID - * \return pointer to new query_object object or NULL if out of memory. - */ -struct gl_query_object * -_mesa_new_query_object(GLcontext *ctx, GLuint id) -{ - struct gl_query_object *q = MALLOC_STRUCT(gl_query_object); - (void) ctx; - if (q) { - q->Id = id; - q->Result = 0; - q->Active = GL_FALSE; - q->Ready = GL_TRUE; /* correct, see spec */ - } - return q; -} - - -/** - * Delete an occlusion query object. - * Not removed from hash table here. - * XXX maybe add Delete() method to gl_query_object class and call that instead - */ -static void -delete_query_object(struct gl_query_object *q) -{ - FREE(q); -} - - -static struct gl_query_object * -lookup_query_object(GLcontext *ctx, GLuint id) -{ - return (struct gl_query_object *) - _mesa_HashLookup(ctx->Query.QueryObjects, id); -} - - - -void GLAPIENTRY -_mesa_GenQueriesARB(GLsizei n, GLuint *ids) -{ - GLuint first; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (n < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)"); - return; - } - - /* No query objects can be active at this time! */ - if (ctx->Query.CurrentOcclusionObject || - ctx->Query.CurrentTimerObject) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGenQueriesARB"); - return; - } - - first = _mesa_HashFindFreeKeyBlock(ctx->Query.QueryObjects, n); - if (first) { - GLsizei i; - for (i = 0; i < n; i++) { - struct gl_query_object *q - = ctx->Driver.NewQueryObject(ctx, first + i); - if (!q) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB"); - return; - } - ids[i] = first + i; - _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q); - } - } -} - - -void GLAPIENTRY -_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids) -{ - GLint i; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (n < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteQueriesARB(n < 0)"); - return; - } - - /* No query objects can be active at this time! */ - if (ctx->Query.CurrentOcclusionObject || - ctx->Query.CurrentTimerObject) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteQueriesARB"); - return; - } - - for (i = 0; i < n; i++) { - if (ids[i] > 0) { - struct gl_query_object *q = lookup_query_object(ctx, ids[i]); - if (q) { - ASSERT(!q->Active); /* should be caught earlier */ - _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]); - delete_query_object(q); - } - } - } -} - - -GLboolean GLAPIENTRY -_mesa_IsQueryARB(GLuint id) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - - if (id && lookup_query_object(ctx, id)) - return GL_TRUE; - else - return GL_FALSE; -} - - -void GLAPIENTRY -_mesa_BeginQueryARB(GLenum target, GLuint id) -{ - struct gl_query_object *q; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - FLUSH_VERTICES(ctx, _NEW_DEPTH); - - switch (target) { - case GL_SAMPLES_PASSED_ARB: - if (!ctx->Extensions.ARB_occlusion_query) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)"); - return; - } - if (ctx->Query.CurrentOcclusionObject) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB"); - return; - } - break; -#if FEATURE_EXT_timer_query - case GL_TIME_ELAPSED_EXT: - if (!ctx->Extensions.EXT_timer_query) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)"); - return; - } - if (ctx->Query.CurrentTimerObject) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB"); - return; - } - break; -#endif - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)"); - return; - } - - if (id == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB(id==0)"); - return; - } - - q = lookup_query_object(ctx, id); - if (!q) { - /* create new object */ - q = ctx->Driver.NewQueryObject(ctx, id); - if (!q) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQueryARB"); - return; - } - _mesa_HashInsert(ctx->Query.QueryObjects, id, q); - } - else { - /* pre-existing object */ - if (q->Active) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBeginQueryARB(query already active)"); - return; - } - } - - q->Active = GL_TRUE; - q->Result = 0; - q->Ready = GL_FALSE; - - if (target == GL_SAMPLES_PASSED_ARB) { - ctx->Query.CurrentOcclusionObject = q; - } -#if FEATURE_EXT_timer_query - else if (target == GL_TIME_ELAPSED_EXT) { - ctx->Query.CurrentTimerObject = q; - } -#endif - - if (ctx->Driver.BeginQuery) { - ctx->Driver.BeginQuery(ctx, target, q); - } -} - - -void GLAPIENTRY -_mesa_EndQueryARB(GLenum target) -{ - struct gl_query_object *q; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - FLUSH_VERTICES(ctx, _NEW_DEPTH); - - switch (target) { - case GL_SAMPLES_PASSED_ARB: - if (!ctx->Extensions.ARB_occlusion_query) { - _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); - return; - } - q = ctx->Query.CurrentOcclusionObject; - ctx->Query.CurrentOcclusionObject = NULL; - break; -#if FEATURE_EXT_timer_query - case GL_TIME_ELAPSED_EXT: - if (!ctx->Extensions.EXT_timer_query) { - _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); - return; - } - q = ctx->Query.CurrentTimerObject; - ctx->Query.CurrentTimerObject = NULL; - break; -#endif - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); - return; - } - - if (!q || !q->Active) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glEndQueryARB(no matching glBeginQueryARB)"); - return; - } - - q->Active = GL_FALSE; - if (ctx->Driver.EndQuery) { - ctx->Driver.EndQuery(ctx, target, q); - } - else { - /* if we're using software rendering/querying */ - q->Ready = GL_TRUE; - } -} - - -void GLAPIENTRY -_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params) -{ - struct gl_query_object *q; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - switch (target) { - case GL_SAMPLES_PASSED_ARB: - if (!ctx->Extensions.ARB_occlusion_query) { - _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); - return; - } - q = ctx->Query.CurrentOcclusionObject; - break; -#if FEATURE_EXT_timer_query - case GL_TIME_ELAPSED_EXT: - if (!ctx->Extensions.EXT_timer_query) { - _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); - return; - } - q = ctx->Query.CurrentTimerObject; - break; -#endif - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(target)"); - return; - } - - switch (pname) { - case GL_QUERY_COUNTER_BITS_ARB: - *params = 8 * sizeof(q->Result); - break; - case GL_CURRENT_QUERY_ARB: - *params = q ? q->Id : 0; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(pname)"); - return; - } -} - - -void GLAPIENTRY -_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params) -{ - struct gl_query_object *q = NULL; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (id) - q = lookup_query_object(ctx, id); - - if (!q || q->Active) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetQueryObjectivARB(id=%d is invalid or active)", id); - return; - } - - switch (pname) { - case GL_QUERY_RESULT_ARB: - while (!q->Ready) { - /* Wait for the query to finish! */ - /* If using software rendering, the result will always be ready - * by time we get here. Otherwise, we must be using hardware! - */ - ASSERT(ctx->Driver.EndQuery); - } - /* if result is too large for returned type, clamp to max value */ - if (q->Result > 0x7fffffff) { - *params = 0x7fffffff; - } - else { - *params = q->Result; - } - break; - case GL_QUERY_RESULT_AVAILABLE_ARB: - /* XXX revisit when we have a hardware implementation! */ - *params = q->Ready; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectivARB(pname)"); - return; - } -} - - -void GLAPIENTRY -_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params) -{ - struct gl_query_object *q = NULL; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (id) - q = lookup_query_object(ctx, id); - - if (!q || q->Active) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetQueryObjectuivARB(id=%d is invalid or active)", id); - return; - } - - switch (pname) { - case GL_QUERY_RESULT_ARB: - while (!q->Ready) { - /* Wait for the query to finish! */ - /* If using software rendering, the result will always be ready - * by time we get here. Otherwise, we must be using hardware! - */ - ASSERT(ctx->Driver.EndQuery); - } - /* if result is too large for returned type, clamp to max value */ - if (q->Result > 0xffffffff) { - *params = 0xffffffff; - } - else { - *params = q->Result; - } - break; - case GL_QUERY_RESULT_AVAILABLE_ARB: - /* XXX revisit when we have a hardware implementation! */ - *params = q->Ready; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)"); - return; - } -} - - -#if FEATURE_EXT_timer_query - -/** - * New with GL_EXT_timer_query - */ -void GLAPIENTRY -_mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params) -{ - struct gl_query_object *q = NULL; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (id) - q = lookup_query_object(ctx, id); - - if (!q || q->Active) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetQueryObjectui64vARB(id=%d is invalid or active)", id); - return; - } - - switch (pname) { - case GL_QUERY_RESULT_ARB: - while (!q->Ready) { - /* Wait for the query to finish! */ - /* If using software rendering, the result will always be ready - * by time we get here. Otherwise, we must be using hardware! - */ - ASSERT(ctx->Driver.EndQuery); - } - *params = q->Result; - break; - case GL_QUERY_RESULT_AVAILABLE_ARB: - /* XXX revisit when we have a hardware implementation! */ - *params = q->Ready; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjecti64vARB(pname)"); - return; - } -} - - -/** - * New with GL_EXT_timer_query - */ -void GLAPIENTRY -_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params) -{ - struct gl_query_object *q = NULL; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (id) - q = lookup_query_object(ctx, id); - - if (!q || q->Active) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetQueryObjectuui64vARB(id=%d is invalid or active)", id); - return; - } - - switch (pname) { - case GL_QUERY_RESULT_ARB: - while (!q->Ready) { - /* Wait for the query to finish! */ - /* If using software rendering, the result will always be ready - * by time we get here. Otherwise, we must be using hardware! - */ - ASSERT(ctx->Driver.EndQuery); - } - *params = q->Result; - break; - case GL_QUERY_RESULT_AVAILABLE_ARB: - /* XXX revisit when we have a hardware implementation! */ - *params = q->Ready; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectui64vARB(pname)"); - return; - } -} - -#endif /* FEATURE_EXT_timer_query */ - - -/** - * Allocate/init the context state related to query objects. - */ -void -_mesa_init_query(GLcontext *ctx) -{ -#if FEATURE_ARB_occlusion_query - ctx->Query.QueryObjects = _mesa_NewHashTable(); - ctx->Query.CurrentOcclusionObject = NULL; -#endif -} - - -/** - * Callback for deleting a query object. Called by _mesa_HashDeleteAll(). - */ -static void -delete_queryobj_cb(GLuint id, void *data, void *userData) -{ - struct gl_query_object *q= (struct gl_query_object *) data; - (void) userData; - delete_query_object(q); -} - - -/** - * Free the context state related to query objects. - */ -void -_mesa_free_query_data(GLcontext *ctx) -{ - _mesa_HashDeleteAll(ctx->Query.QueryObjects, delete_queryobj_cb, NULL); - _mesa_DeleteHashTable(ctx->Query.QueryObjects); -} diff --git a/src/mesa/main/occlude.h b/src/mesa/main/occlude.h deleted file mode 100644 index ada8cf83560..00000000000 --- a/src/mesa/main/occlude.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 1999-2005 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 struct gl_query_object * -_mesa_new_query_object(GLcontext *ctx, GLuint id); - -extern void -_mesa_init_query(GLcontext *ctx); - -extern void -_mesa_free_query_data(GLcontext *ctx); - -extern void GLAPIENTRY -_mesa_GenQueriesARB(GLsizei n, GLuint *ids); - -extern void GLAPIENTRY -_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids); - -extern GLboolean GLAPIENTRY -_mesa_IsQueryARB(GLuint id); - -extern void GLAPIENTRY -_mesa_BeginQueryARB(GLenum target, GLuint id); - -extern void GLAPIENTRY -_mesa_EndQueryARB(GLenum target); - -extern void GLAPIENTRY -_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params); - -extern void GLAPIENTRY -_mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params); - -extern void GLAPIENTRY -_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params); - - -#endif /* OCCLUDE_H */ diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c new file mode 100644 index 00000000000..5fef4a800dc --- /dev/null +++ b/src/mesa/main/queryobj.c @@ -0,0 +1,538 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.1 + * + * Copyright (C) 1999-2006 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. + */ + + +#include "glheader.h" +#include "context.h" +#include "hash.h" +#include "imports.h" +#include "occlude.h" +#include "mtypes.h" + + +/** + * Allocate a new query object. This is a fallback routine called via + * ctx->Driver.NewQueryObject(). + * \param ctx - rendering context + * \param id - the new object's ID + * \return pointer to new query_object object or NULL if out of memory. + */ +struct gl_query_object * +_mesa_new_query_object(GLcontext *ctx, GLuint id) +{ + struct gl_query_object *q = MALLOC_STRUCT(gl_query_object); + (void) ctx; + if (q) { + q->Id = id; + q->Result = 0; + q->Active = GL_FALSE; + q->Ready = GL_TRUE; /* correct, see spec */ + } + return q; +} + + +/** + * Delete an occlusion query object. + * Not removed from hash table here. + * XXX maybe add Delete() method to gl_query_object class and call that instead + */ +static void +delete_query_object(struct gl_query_object *q) +{ + FREE(q); +} + + +static struct gl_query_object * +lookup_query_object(GLcontext *ctx, GLuint id) +{ + return (struct gl_query_object *) + _mesa_HashLookup(ctx->Query.QueryObjects, id); +} + + + +void GLAPIENTRY +_mesa_GenQueriesARB(GLsizei n, GLuint *ids) +{ + GLuint first; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)"); + return; + } + + /* No query objects can be active at this time! */ + if (ctx->Query.CurrentOcclusionObject || + ctx->Query.CurrentTimerObject) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGenQueriesARB"); + return; + } + + first = _mesa_HashFindFreeKeyBlock(ctx->Query.QueryObjects, n); + if (first) { + GLsizei i; + for (i = 0; i < n; i++) { + struct gl_query_object *q + = ctx->Driver.NewQueryObject(ctx, first + i); + if (!q) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB"); + return; + } + ids[i] = first + i; + _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q); + } + } +} + + +void GLAPIENTRY +_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids) +{ + GLint i; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteQueriesARB(n < 0)"); + return; + } + + /* No query objects can be active at this time! */ + if (ctx->Query.CurrentOcclusionObject || + ctx->Query.CurrentTimerObject) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteQueriesARB"); + return; + } + + for (i = 0; i < n; i++) { + if (ids[i] > 0) { + struct gl_query_object *q = lookup_query_object(ctx, ids[i]); + if (q) { + ASSERT(!q->Active); /* should be caught earlier */ + _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]); + delete_query_object(q); + } + } + } +} + + +GLboolean GLAPIENTRY +_mesa_IsQueryARB(GLuint id) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); + + if (id && lookup_query_object(ctx, id)) + return GL_TRUE; + else + return GL_FALSE; +} + + +void GLAPIENTRY +_mesa_BeginQueryARB(GLenum target, GLuint id) +{ + struct gl_query_object *q; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + FLUSH_VERTICES(ctx, _NEW_DEPTH); + + switch (target) { + case GL_SAMPLES_PASSED_ARB: + if (!ctx->Extensions.ARB_occlusion_query) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)"); + return; + } + if (ctx->Query.CurrentOcclusionObject) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB"); + return; + } + break; +#if FEATURE_EXT_timer_query + case GL_TIME_ELAPSED_EXT: + if (!ctx->Extensions.EXT_timer_query) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)"); + return; + } + if (ctx->Query.CurrentTimerObject) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB"); + return; + } + break; +#endif + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)"); + return; + } + + if (id == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQueryARB(id==0)"); + return; + } + + q = lookup_query_object(ctx, id); + if (!q) { + /* create new object */ + q = ctx->Driver.NewQueryObject(ctx, id); + if (!q) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQueryARB"); + return; + } + _mesa_HashInsert(ctx->Query.QueryObjects, id, q); + } + else { + /* pre-existing object */ + if (q->Active) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBeginQueryARB(query already active)"); + return; + } + } + + q->Active = GL_TRUE; + q->Result = 0; + q->Ready = GL_FALSE; + + if (target == GL_SAMPLES_PASSED_ARB) { + ctx->Query.CurrentOcclusionObject = q; + } +#if FEATURE_EXT_timer_query + else if (target == GL_TIME_ELAPSED_EXT) { + ctx->Query.CurrentTimerObject = q; + } +#endif + + if (ctx->Driver.BeginQuery) { + ctx->Driver.BeginQuery(ctx, target, q); + } +} + + +void GLAPIENTRY +_mesa_EndQueryARB(GLenum target) +{ + struct gl_query_object *q; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + FLUSH_VERTICES(ctx, _NEW_DEPTH); + + switch (target) { + case GL_SAMPLES_PASSED_ARB: + if (!ctx->Extensions.ARB_occlusion_query) { + _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); + return; + } + q = ctx->Query.CurrentOcclusionObject; + ctx->Query.CurrentOcclusionObject = NULL; + break; +#if FEATURE_EXT_timer_query + case GL_TIME_ELAPSED_EXT: + if (!ctx->Extensions.EXT_timer_query) { + _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); + return; + } + q = ctx->Query.CurrentTimerObject; + ctx->Query.CurrentTimerObject = NULL; + break; +#endif + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); + return; + } + + if (!q || !q->Active) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glEndQueryARB(no matching glBeginQueryARB)"); + return; + } + + q->Active = GL_FALSE; + if (ctx->Driver.EndQuery) { + ctx->Driver.EndQuery(ctx, target, q); + } + else { + /* if we're using software rendering/querying */ + q->Ready = GL_TRUE; + } +} + + +void GLAPIENTRY +_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params) +{ + struct gl_query_object *q; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (target) { + case GL_SAMPLES_PASSED_ARB: + if (!ctx->Extensions.ARB_occlusion_query) { + _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); + return; + } + q = ctx->Query.CurrentOcclusionObject; + break; +#if FEATURE_EXT_timer_query + case GL_TIME_ELAPSED_EXT: + if (!ctx->Extensions.EXT_timer_query) { + _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); + return; + } + q = ctx->Query.CurrentTimerObject; + break; +#endif + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(target)"); + return; + } + + switch (pname) { + case GL_QUERY_COUNTER_BITS_ARB: + *params = 8 * sizeof(q->Result); + break; + case GL_CURRENT_QUERY_ARB: + *params = q ? q->Id : 0; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(pname)"); + return; + } +} + + +void GLAPIENTRY +_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params) +{ + struct gl_query_object *q = NULL; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (id) + q = lookup_query_object(ctx, id); + + if (!q || q->Active) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetQueryObjectivARB(id=%d is invalid or active)", id); + return; + } + + switch (pname) { + case GL_QUERY_RESULT_ARB: + while (!q->Ready) { + /* Wait for the query to finish! */ + /* If using software rendering, the result will always be ready + * by time we get here. Otherwise, we must be using hardware! + */ + ASSERT(ctx->Driver.EndQuery); + } + /* if result is too large for returned type, clamp to max value */ + if (q->Result > 0x7fffffff) { + *params = 0x7fffffff; + } + else { + *params = q->Result; + } + break; + case GL_QUERY_RESULT_AVAILABLE_ARB: + /* XXX revisit when we have a hardware implementation! */ + *params = q->Ready; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectivARB(pname)"); + return; + } +} + + +void GLAPIENTRY +_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params) +{ + struct gl_query_object *q = NULL; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (id) + q = lookup_query_object(ctx, id); + + if (!q || q->Active) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetQueryObjectuivARB(id=%d is invalid or active)", id); + return; + } + + switch (pname) { + case GL_QUERY_RESULT_ARB: + while (!q->Ready) { + /* Wait for the query to finish! */ + /* If using software rendering, the result will always be ready + * by time we get here. Otherwise, we must be using hardware! + */ + ASSERT(ctx->Driver.EndQuery); + } + /* if result is too large for returned type, clamp to max value */ + if (q->Result > 0xffffffff) { + *params = 0xffffffff; + } + else { + *params = q->Result; + } + break; + case GL_QUERY_RESULT_AVAILABLE_ARB: + /* XXX revisit when we have a hardware implementation! */ + *params = q->Ready; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)"); + return; + } +} + + +#if FEATURE_EXT_timer_query + +/** + * New with GL_EXT_timer_query + */ +void GLAPIENTRY +_mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params) +{ + struct gl_query_object *q = NULL; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (id) + q = lookup_query_object(ctx, id); + + if (!q || q->Active) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetQueryObjectui64vARB(id=%d is invalid or active)", id); + return; + } + + switch (pname) { + case GL_QUERY_RESULT_ARB: + while (!q->Ready) { + /* Wait for the query to finish! */ + /* If using software rendering, the result will always be ready + * by time we get here. Otherwise, we must be using hardware! + */ + ASSERT(ctx->Driver.EndQuery); + } + *params = q->Result; + break; + case GL_QUERY_RESULT_AVAILABLE_ARB: + /* XXX revisit when we have a hardware implementation! */ + *params = q->Ready; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjecti64vARB(pname)"); + return; + } +} + + +/** + * New with GL_EXT_timer_query + */ +void GLAPIENTRY +_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params) +{ + struct gl_query_object *q = NULL; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (id) + q = lookup_query_object(ctx, id); + + if (!q || q->Active) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetQueryObjectuui64vARB(id=%d is invalid or active)", id); + return; + } + + switch (pname) { + case GL_QUERY_RESULT_ARB: + while (!q->Ready) { + /* Wait for the query to finish! */ + /* If using software rendering, the result will always be ready + * by time we get here. Otherwise, we must be using hardware! + */ + ASSERT(ctx->Driver.EndQuery); + } + *params = q->Result; + break; + case GL_QUERY_RESULT_AVAILABLE_ARB: + /* XXX revisit when we have a hardware implementation! */ + *params = q->Ready; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectui64vARB(pname)"); + return; + } +} + +#endif /* FEATURE_EXT_timer_query */ + + +/** + * Allocate/init the context state related to query objects. + */ +void +_mesa_init_query(GLcontext *ctx) +{ +#if FEATURE_ARB_occlusion_query + ctx->Query.QueryObjects = _mesa_NewHashTable(); + ctx->Query.CurrentOcclusionObject = NULL; +#endif +} + + +/** + * Callback for deleting a query object. Called by _mesa_HashDeleteAll(). + */ +static void +delete_queryobj_cb(GLuint id, void *data, void *userData) +{ + struct gl_query_object *q= (struct gl_query_object *) data; + (void) userData; + delete_query_object(q); +} + + +/** + * Free the context state related to query objects. + */ +void +_mesa_free_query_data(GLcontext *ctx) +{ + _mesa_HashDeleteAll(ctx->Query.QueryObjects, delete_queryobj_cb, NULL); + _mesa_DeleteHashTable(ctx->Query.QueryObjects); +} diff --git a/src/mesa/main/queryobj.h b/src/mesa/main/queryobj.h new file mode 100644 index 00000000000..ada8cf83560 --- /dev/null +++ b/src/mesa/main/queryobj.h @@ -0,0 +1,70 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2005 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 struct gl_query_object * +_mesa_new_query_object(GLcontext *ctx, GLuint id); + +extern void +_mesa_init_query(GLcontext *ctx); + +extern void +_mesa_free_query_data(GLcontext *ctx); + +extern void GLAPIENTRY +_mesa_GenQueriesARB(GLsizei n, GLuint *ids); + +extern void GLAPIENTRY +_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids); + +extern GLboolean GLAPIENTRY +_mesa_IsQueryARB(GLuint id); + +extern void GLAPIENTRY +_mesa_BeginQueryARB(GLenum target, GLuint id); + +extern void GLAPIENTRY +_mesa_EndQueryARB(GLenum target); + +extern void GLAPIENTRY +_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params); + +extern void GLAPIENTRY +_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params); + +extern void GLAPIENTRY +_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params); + +extern void GLAPIENTRY +_mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params); + +extern void GLAPIENTRY +_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params); + + +#endif /* OCCLUDE_H */ -- cgit v1.2.3