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]); ctx->Driver.DeleteQuery(ctx, q); } } } }
/** * 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: if (!q->Ready) ctx->Driver.WaitQuery(ctx, q); *params = q->Result; break; case GL_QUERY_RESULT_AVAILABLE_ARB: if (!q->Ready) ctx->Driver.CheckQuery( ctx, q ); *params = q->Ready; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectui64vARB(pname)"); return; } }
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; }
/** * Free the context state related to query objects. */ void _mesa_free_query_data(GLcontext *ctx) { while (1) { 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->Query.QueryObjects, id); } else { break; } } _mesa_DeleteHashTable(ctx->Query.QueryObjects); }
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; } }
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: 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; } break; case GL_QUERY_RESULT_AVAILABLE_ARB: if (!q->Ready) ctx->Driver.CheckQuery( ctx, q ); *params = q->Ready; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)"); return; } }
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->Target = target; 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 ctx->Driver.BeginQuery(ctx, q); }