X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fqueryobj.c;h=f0a9a7922b224068a54ab3344b2e69cffe528222;hb=06913497d6b17f454bf4c5b8601d391980eb8265;hp=f6eb4ee7e1b11ea547ee5def8bd46091a2ad93d8;hpb=0d4a05445c6b47b93269a3829afbe509ffec4817;p=mesa.git diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c index f6eb4ee7e1b..f0a9a7922b2 100644 --- a/src/mesa/main/queryobj.c +++ b/src/mesa/main/queryobj.c @@ -25,11 +25,13 @@ #include "glheader.h" #include "context.h" +#include "enums.h" #include "hash.h" #include "imports.h" #include "queryobj.h" +#include "mfeatures.h" #include "mtypes.h" -#include "glapi/dispatch.h" +#include "main/dispatch.h" #if FEATURE_queryobj @@ -43,7 +45,7 @@ * \return pointer to new query_object object or NULL if out of memory. */ static struct gl_query_object * -_mesa_new_query_object(GLcontext *ctx, GLuint id) +_mesa_new_query_object(struct gl_context *ctx, GLuint id) { struct gl_query_object *q = MALLOC_STRUCT(gl_query_object); (void) ctx; @@ -62,7 +64,7 @@ _mesa_new_query_object(GLcontext *ctx, GLuint id) * Called via ctx->Driver.BeginQuery(). */ static void -_mesa_begin_query(GLcontext *ctx, struct gl_query_object *q) +_mesa_begin_query(struct gl_context *ctx, struct gl_query_object *q) { /* no-op */ } @@ -73,7 +75,7 @@ _mesa_begin_query(GLcontext *ctx, struct gl_query_object *q) * Called via ctx->Driver.EndQuery(). */ static void -_mesa_end_query(GLcontext *ctx, struct gl_query_object *q) +_mesa_end_query(struct gl_context *ctx, struct gl_query_object *q) { q->Ready = GL_TRUE; } @@ -84,7 +86,7 @@ _mesa_end_query(GLcontext *ctx, struct gl_query_object *q) * Called via ctx->Driver.WaitQuery(). */ static void -_mesa_wait_query(GLcontext *ctx, struct gl_query_object *q) +_mesa_wait_query(struct gl_context *ctx, struct gl_query_object *q) { /* For software drivers, _mesa_end_query() should have completed the query. * For real hardware, implement a proper WaitQuery() driver function, @@ -99,7 +101,7 @@ _mesa_wait_query(GLcontext *ctx, struct gl_query_object *q) * Called via ctx->Driver.CheckQuery(). */ static void -_mesa_check_query(GLcontext *ctx, struct gl_query_object *q) +_mesa_check_query(struct gl_context *ctx, struct gl_query_object *q) { /* No-op for sw rendering. * HW drivers may need to flush at this time. @@ -112,21 +114,12 @@ _mesa_check_query(GLcontext *ctx, struct gl_query_object *q) * Not removed from hash table here. */ static void -_mesa_delete_query(GLcontext *ctx, struct gl_query_object *q) +_mesa_delete_query(struct gl_context *ctx, struct gl_query_object *q) { - _mesa_free(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 _mesa_init_query_object_functions(struct dd_function_table *driver) { @@ -139,13 +132,57 @@ _mesa_init_query_object_functions(struct dd_function_table *driver) } -void GLAPIENTRY +/** + * Return pointer to the query object binding point for the given target. + * \return NULL if invalid target, else the address of binding point + */ +static struct gl_query_object ** +get_query_binding_point(struct gl_context *ctx, GLenum target) +{ + switch (target) { + case GL_SAMPLES_PASSED_ARB: + if (ctx->Extensions.ARB_occlusion_query) + return &ctx->Query.CurrentOcclusionObject; + else + return NULL; + case GL_ANY_SAMPLES_PASSED: + if (ctx->Extensions.ARB_occlusion_query2) + return &ctx->Query.CurrentOcclusionObject; + else + return NULL; + case GL_TIME_ELAPSED_EXT: + if (ctx->Extensions.EXT_timer_query) + return &ctx->Query.CurrentTimerObject; + else + return NULL; +#if FEATURE_EXT_transform_feedback + case GL_PRIMITIVES_GENERATED: + if (ctx->Extensions.EXT_transform_feedback) + return &ctx->Query.PrimitivesGenerated; + else + return NULL; + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + if (ctx->Extensions.EXT_transform_feedback) + return &ctx->Query.PrimitivesWritten; + else + return NULL; +#endif + default: + return NULL; + } +} + + +static void GLAPIENTRY _mesa_GenQueriesARB(GLsizei n, GLuint *ids) { GLuint first; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glGenQueries(%d)\n", n); + if (n < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)"); return; @@ -175,12 +212,16 @@ _mesa_GenQueriesARB(GLsizei n, GLuint *ids) } -void GLAPIENTRY +static void GLAPIENTRY _mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids) { GLint i; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + FLUSH_VERTICES(ctx, 0); + + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glDeleeteQueries(%d)\n", n); if (n < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteQueriesARB(n < 0)"); @@ -196,7 +237,7 @@ _mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids) for (i = 0; i < n; i++) { if (ids[i] > 0) { - struct gl_query_object *q = lookup_query_object(ctx, ids[i]); + struct gl_query_object *q = _mesa_lookup_query_object(ctx, ids[i]); if (q) { ASSERT(!q->Active); /* should be caught earlier */ _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]); @@ -207,13 +248,16 @@ _mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids) } -GLboolean GLAPIENTRY +static 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)) + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glIsQuery(%u)\n", id); + + if (id && _mesa_lookup_query_object(ctx, id)) return GL_TRUE; else return GL_FALSE; @@ -223,36 +267,20 @@ _mesa_IsQueryARB(GLuint id) static void GLAPIENTRY _mesa_BeginQueryARB(GLenum target, GLuint id) { - struct gl_query_object *q; + struct gl_query_object *q, **bindpt; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glBeginQuery(%s, %u)\n", + _mesa_lookup_enum_by_nr(target), id); + 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; - 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; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)"); - return; + bindpt = get_query_binding_point(ctx, target); + if (!bindpt) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQueryARB(target)"); + return; } if (id == 0) { @@ -260,7 +288,7 @@ _mesa_BeginQueryARB(GLenum target, GLuint id) return; } - q = lookup_query_object(ctx, id); + q = _mesa_lookup_query_object(ctx, id); if (!q) { /* create new object */ q = ctx->Driver.NewQueryObject(ctx, id); @@ -284,12 +312,8 @@ _mesa_BeginQueryARB(GLenum target, GLuint id) q->Result = 0; q->Ready = GL_FALSE; - if (target == GL_SAMPLES_PASSED_ARB) { - ctx->Query.CurrentOcclusionObject = q; - } - else if (target == GL_TIME_ELAPSED_EXT) { - ctx->Query.CurrentTimerObject = q; - } + /* XXX should probably refcount query objects */ + *bindpt = q; ctx->Driver.BeginQuery(ctx, q); } @@ -298,34 +322,25 @@ _mesa_BeginQueryARB(GLenum target, GLuint id) static void GLAPIENTRY _mesa_EndQueryARB(GLenum target) { - struct gl_query_object *q; + struct gl_query_object *q, **bindpt; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glEndQuery(%s)\n", _mesa_lookup_enum_by_nr(target)); + 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; - 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; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); - return; + bindpt = get_query_binding_point(ctx, target); + if (!bindpt) { + _mesa_error(ctx, GL_INVALID_ENUM, "glEndQueryARB(target)"); + return; } + /* XXX should probably refcount query objects */ + q = *bindpt; + *bindpt = NULL; + if (!q || !q->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, "glEndQueryARB(no matching glBeginQueryARB)"); @@ -337,33 +352,26 @@ _mesa_EndQueryARB(GLenum target) } -void GLAPIENTRY +static void GLAPIENTRY _mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params) { - struct gl_query_object *q; + struct gl_query_object *q, **bindpt; 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; - 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; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryivARB(target)"); - return; + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glGetQueryiv(%s, %s)\n", + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(pname)); + + bindpt = get_query_binding_point(ctx, target); + if (!bindpt) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryARB(target)"); + return; } + q = *bindpt; + switch (pname) { case GL_QUERY_COUNTER_BITS_ARB: *params = 8 * sizeof(q->Result); @@ -378,15 +386,19 @@ _mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params) } -void GLAPIENTRY +static 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 (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glGetQueryObjectiv(%u, %s)\n", id, + _mesa_lookup_enum_by_nr(pname)); + if (id) - q = lookup_query_object(ctx, id); + q = _mesa_lookup_query_object(ctx, id); if (!q || q->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -399,11 +411,18 @@ _mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params) if (!q->Ready) ctx->Driver.WaitQuery(ctx, q); /* if result is too large for returned type, clamp to max value */ - if (q->Result > 0x7fffffff) { - *params = 0x7fffffff; - } - else { - *params = (GLint)q->Result; + if (q->Target == GL_ANY_SAMPLES_PASSED) { + if (q->Result) + *params = GL_TRUE; + else + *params = GL_FALSE; + } else { + if (q->Result > 0x7fffffff) { + *params = 0x7fffffff; + } + else { + *params = (GLint)q->Result; + } } break; case GL_QUERY_RESULT_AVAILABLE_ARB: @@ -418,15 +437,19 @@ _mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params) } -void GLAPIENTRY +static 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 (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glGetQueryObjectuiv(%u, %s)\n", id, + _mesa_lookup_enum_by_nr(pname)); + if (id) - q = lookup_query_object(ctx, id); + q = _mesa_lookup_query_object(ctx, id); if (!q || q->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -439,11 +462,18 @@ _mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params) if (!q->Ready) ctx->Driver.WaitQuery(ctx, q); /* if result is too large for returned type, clamp to max value */ - if (q->Result > 0xffffffff) { - *params = 0xffffffff; - } - else { - *params = (GLuint)q->Result; + if (q->Target == GL_ANY_SAMPLES_PASSED) { + if (q->Result) + *params = GL_TRUE; + else + *params = GL_FALSE; + } else { + if (q->Result > 0xffffffff) { + *params = 0xffffffff; + } + else { + *params = (GLuint)q->Result; + } } break; case GL_QUERY_RESULT_AVAILABLE_ARB: @@ -468,8 +498,12 @@ _mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glGetQueryObjecti64v(%u, %s)\n", id, + _mesa_lookup_enum_by_nr(pname)); + if (id) - q = lookup_query_object(ctx, id); + q = _mesa_lookup_query_object(ctx, id); if (!q || q->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -505,8 +539,12 @@ _mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + if (MESA_VERBOSE & VERBOSE_API) + _mesa_debug(ctx, "glGetQueryObjectui64v(%u, %s)\n", id, + _mesa_lookup_enum_by_nr(pname)); + if (id) - q = lookup_query_object(ctx, id); + q = _mesa_lookup_query_object(ctx, id); if (!q || q->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -556,7 +594,7 @@ _mesa_init_queryobj_dispatch(struct _glapi_table *disp) * Allocate/init the context state related to query objects. */ void -_mesa_init_queryobj(GLcontext *ctx) +_mesa_init_queryobj(struct gl_context *ctx) { ctx->Query.QueryObjects = _mesa_NewHashTable(); ctx->Query.CurrentOcclusionObject = NULL; @@ -570,7 +608,7 @@ static void delete_queryobj_cb(GLuint id, void *data, void *userData) { struct gl_query_object *q= (struct gl_query_object *) data; - GLcontext *ctx = (GLcontext *)userData; + struct gl_context *ctx = (struct gl_context *)userData; ctx->Driver.DeleteQuery(ctx, q); } @@ -579,7 +617,7 @@ delete_queryobj_cb(GLuint id, void *data, void *userData) * Free the context state related to query objects. */ void -_mesa_free_queryobj_data(GLcontext *ctx) +_mesa_free_queryobj_data(struct gl_context *ctx) { _mesa_HashDeleteAll(ctx->Query.QueryObjects, delete_queryobj_cb, ctx); _mesa_DeleteHashTable(ctx->Query.QueryObjects);