diff options
author | Brian Paul <[email protected]> | 2005-08-27 13:56:08 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 2005-08-27 13:56:08 +0000 |
commit | 23ffc3a85d6172f8a98d17d7f23610bab808d84e (patch) | |
tree | 07211e0ccdc4f3418d8e434b39c43d80894e1077 /src/mesa/main | |
parent | ca1ac986a1d6d3f292e3d20540de884ad08d9816 (diff) |
Rearrange the code related to GL_ARB_occlusion_object to generalize query
objects for future types of queries.
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/dd.h | 8 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 30 | ||||
-rw-r--r-- | src/mesa/main/occlude.c | 172 |
3 files changed, 126 insertions, 84 deletions
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index e4c103c55e4..311278000f2 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -816,6 +816,14 @@ struct dd_function_table { /*@}*/ #endif + /** + * \name Query objects + */ + /*@{*/ + void (*BeginQuery)(GLcontext *ctx, struct gl_query_object *q); + void (*EndQuery)(GLcontext *ctx, struct gl_query_object *q); + /*@}*/ + /** * \name Support for multiple T&L engines diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 2ec3868befb..17ef921738c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1853,7 +1853,7 @@ struct gl_vertex_program_state }; -/* +/** * State for GL_ARB/NV_fragment_program */ struct gl_fragment_program_state @@ -1874,8 +1874,9 @@ struct gl_fragment_program_state #endif }; -/* - * State for GL_fragment_shader + +/** + * State for GL_ATI_fragment_shader */ struct gl_ati_fragment_shader_state { @@ -1886,17 +1887,24 @@ struct gl_ati_fragment_shader_state struct ati_fragment_shader *Current; }; -/* - * State for GL_ARB_occlusion_query - */ -struct gl_occlusion_state + +struct gl_query_object +{ + GLenum Target; + GLuint Id; + GLuint Result; /* the counter */ + GLboolean Active; /* inside Begin/EndQuery */ + GLboolean Ready; /* result is ready */ +}; + + +struct gl_query_state { - GLboolean Active; - GLuint CurrentQueryObject; - GLuint PassedCounter; struct _mesa_HashTable *QueryObjects; + struct gl_query_object *CurrentOcclusionObject; /* GL_ARB_occlusion_query */ }; + /** * gl2 unique interface identifier. * Each gl2 interface has its own interface id used for object queries. @@ -2802,7 +2810,7 @@ struct __GLcontextRec GLboolean _MaintainTexEnvProgram; GLboolean _MaintainTnlProgram; - struct gl_occlusion_state Occlusion; /**< GL_ARB_occlusion_query */ + struct gl_query_state Query; /**< GL_ARB_occlusion_query */ struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */ /*@}*/ diff --git a/src/mesa/main/occlude.c b/src/mesa/main/occlude.c index 3583e50703f..2f57a3cfe2e 100644 --- a/src/mesa/main/occlude.c +++ b/src/mesa/main/occlude.c @@ -36,29 +36,20 @@ #include "mtypes.h" -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. + * \return pointer to new query_object object or NULL if out of memory. */ -static struct occlusion_query * +static struct gl_query_object * new_query_object(GLenum target, GLuint id) { - struct occlusion_query *q = MALLOC_STRUCT(occlusion_query); + struct gl_query_object *q = MALLOC_STRUCT(gl_query_object); if (q) { q->Target = target; q->Id = id; - q->PassedCounter = 0; + q->Result = 0; q->Active = GL_FALSE; } return q; @@ -67,14 +58,24 @@ new_query_object(GLenum target, GLuint id) /** * Delete an occlusion query object. + * Not removed from hash table here. */ static void -delete_query_object(struct occlusion_query *q) +delete_query_object(struct gl_query_object *q) { FREE(q); } +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) { @@ -87,23 +88,24 @@ _mesa_GenQueriesARB(GLsizei n, GLuint *ids) return; } - if (ctx->Occlusion.Active) { + /* No query objects can be active at this time! */ + if (ctx->Query.CurrentOcclusionObject) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGenQueriesARB"); return; } - first = _mesa_HashFindFreeKeyBlock(ctx->Occlusion.QueryObjects, n); + first = _mesa_HashFindFreeKeyBlock(ctx->Query.QueryObjects, n); if (first) { GLsizei i; for (i = 0; i < n; i++) { - struct occlusion_query *q = new_query_object(GL_SAMPLES_PASSED_ARB, + struct gl_query_object *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); + _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q); } } } @@ -121,17 +123,18 @@ _mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids) return; } - if (ctx->Occlusion.Active) { + /* No query objects can be active at this time! */ + if (ctx->Query.CurrentOcclusionObject) { _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]); + struct gl_query_object *q = lookup_query_object(ctx, ids[i]); if (q) { - _mesa_HashRemove(ctx->Occlusion.QueryObjects, ids[i]); + ASSERT(!q->Active); /* should be caught earlier */ + _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]); delete_query_object(q); } } @@ -145,7 +148,7 @@ _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)) + if (id && lookup_query_object(ctx, id)) return GL_TRUE; else return GL_FALSE; @@ -156,7 +159,7 @@ void GLAPIENTRY _mesa_BeginQueryARB(GLenum target, GLuint id) { GET_CURRENT_CONTEXT(ctx); - struct occlusion_query *q; + struct gl_query_object *q; ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_DEPTH); @@ -171,31 +174,43 @@ _mesa_BeginQueryARB(GLenum target, GLuint id) return; } - if (ctx->Occlusion.CurrentQueryObject) { + if (ctx->Query.CurrentOcclusionObject) { _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 = lookup_query_object(ctx, id); + if (!q) { + /* create new object */ q = new_query_object(target, id); if (!q) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQueryARB"); return; } - _mesa_HashInsert(ctx->Occlusion.QueryObjects, id, q); + _mesa_HashInsert(ctx->Query.QueryObjects, id, q); + } + else { + /* pre-existing object */ + if (q->Target != target) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBeginQueryARB(target mismatch)"); + return; + } + if (q->Active) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBeginQueryARB(query already active)"); + return; + } } q->Active = GL_TRUE; - q->PassedCounter = 0; - ctx->Occlusion.Active = GL_TRUE; - ctx->Occlusion.CurrentQueryObject = id; - ctx->Occlusion.PassedCounter = 0; + q->Result = 0; + q->Ready = GL_FALSE; + ctx->Query.CurrentOcclusionObject = q; + + if (ctx->Driver.BeginQuery) { + ctx->Driver.BeginQuery(ctx, q); + } } @@ -203,29 +218,34 @@ void GLAPIENTRY _mesa_EndQueryARB(GLenum target) { GET_CURRENT_CONTEXT(ctx); - struct occlusion_query *q = NULL; + struct gl_query_object *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; + switch (target) { + case GL_SAMPLES_PASSED_ARB: + q = ctx->Query.CurrentOcclusionObject; + ctx->Query.CurrentOcclusionObject = NULL; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); + return; } - if (ctx->Occlusion.CurrentQueryObject) - q = (struct occlusion_query *) - _mesa_HashLookup(ctx->Occlusion.QueryObjects, - ctx->Occlusion.CurrentQueryObject); if (!q || !q->Active) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glEndQuery with no glBeginQuery"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glEndQueryARB(no matching glBeginQueryARB)"); return; } - q->PassedCounter = ctx->Occlusion.PassedCounter; q->Active = GL_FALSE; - ctx->Occlusion.Active = GL_FALSE; - ctx->Occlusion.CurrentQueryObject = 0; + if (ctx->Driver.EndQuery) { + ctx->Driver.EndQuery(ctx, q); + } + else { + q->Ready = GL_TRUE; + } } @@ -233,19 +253,24 @@ void GLAPIENTRY _mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params) { GET_CURRENT_CONTEXT(ctx); + struct gl_query_object *q; ASSERT_OUTSIDE_BEGIN_END(ctx); - if (target != GL_SAMPLES_PASSED_ARB) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(target)"); - return; + switch (target) { + case GL_SAMPLES_PASSED_ARB: + q = ctx->Query.CurrentOcclusionObject; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(target)"); + return; } switch (pname) { case GL_QUERY_COUNTER_BITS_ARB: - *params = 8 * sizeof(GLuint); + *params = 8 * sizeof(q->Result); break; case GL_CURRENT_QUERY_ARB: - *params = ctx->Occlusion.CurrentQueryObject; + *params = q ? q->Id : 0; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(pname)"); @@ -258,25 +283,25 @@ void GLAPIENTRY _mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params) { GET_CURRENT_CONTEXT(ctx); - struct occlusion_query *q = NULL; + struct gl_query_object *q = NULL; ASSERT_OUTSIDE_BEGIN_END(ctx); if (id) - q = (struct occlusion_query *) - _mesa_HashLookup(ctx->Occlusion.QueryObjects, id); + q = lookup_query_object(ctx, id); if (!q || q->Active) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryObjectivARB(id=%d)", id); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetQueryObjectivARB(id=%d is active)", id); return; } switch (pname) { case GL_QUERY_RESULT_ARB: - *params = q->PassedCounter; + *params = q->Result; break; case GL_QUERY_RESULT_AVAILABLE_ARB: /* XXX revisit when we have a hardware implementation! */ - *params = GL_TRUE; + *params = q->Ready; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectivARB(pname)"); @@ -289,24 +314,25 @@ void GLAPIENTRY _mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params) { GET_CURRENT_CONTEXT(ctx); - struct occlusion_query *q = NULL; + struct gl_query_object *q = NULL; ASSERT_OUTSIDE_BEGIN_END(ctx); if (id) - q = (struct occlusion_query *) - _mesa_HashLookup(ctx->Occlusion.QueryObjects, id); + q = lookup_query_object(ctx, id); + if (!q || q->Active) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryObjectuivARB(id=%d", id); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetQueryObjectuivARB(id=%d is active)", id); return; } switch (pname) { case GL_QUERY_RESULT_ARB: - *params = q->PassedCounter; + *params = q->Result; break; case GL_QUERY_RESULT_AVAILABLE_ARB: /* XXX revisit when we have a hardware implementation! */ - *params = GL_TRUE; + *params = q->Ready; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)"); @@ -323,7 +349,8 @@ void _mesa_init_occlude(GLcontext *ctx) { #if FEATURE_ARB_occlusion_query - ctx->Occlusion.QueryObjects = _mesa_NewHashTable(); + ctx->Query.QueryObjects = _mesa_NewHashTable(); + ctx->Query.CurrentOcclusionObject = NULL; #endif } @@ -335,17 +362,16 @@ void _mesa_free_occlude_data(GLcontext *ctx) { while (1) { - GLuint query = _mesa_HashFirstEntry(ctx->Occlusion.QueryObjects); - if (query) { - struct occlusion_query *q = (struct occlusion_query *) - _mesa_HashLookup(ctx->Occlusion.QueryObjects, query); + GLuint id = _mesa_HashFirstEntry(ctx->Query.QueryObjects); + if (id) { + struct gl_query_object *q = lookup_query_object(ctx, id); ASSERT(q); delete_query_object(q); - _mesa_HashRemove(ctx->Occlusion.QueryObjects, query); + _mesa_HashRemove(ctx->Query.QueryObjects, id); } else { break; } } - _mesa_DeleteHashTable(ctx->Occlusion.QueryObjects); + _mesa_DeleteHashTable(ctx->Query.QueryObjects); } |