X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fqueryobj.c;h=86e7c3ad0a1423aca89e8cec8bf31a593bab5555;hb=3815264d7d07e8dd216674a32568daa55aeed680;hp=2b3b259331d207e64b1faf1913aa36245df66f53;hpb=25ee9617ff0b537bb30de92983baa745e49556b6;p=mesa.git diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c index 2b3b259331d..86e7c3ad0a1 100644 --- a/src/mesa/main/queryobj.c +++ b/src/mesa/main/queryobj.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -17,9 +16,10 @@ * 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. + * THE AUTHORS OR COPYRIGHT HOLDERS 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. */ @@ -29,7 +29,6 @@ #include "hash.h" #include "imports.h" #include "queryobj.h" -#include "mfeatures.h" #include "mtypes.h" #include "main/dispatch.h" @@ -44,13 +43,26 @@ static struct gl_query_object * _mesa_new_query_object(struct gl_context *ctx, GLuint id) { - struct gl_query_object *q = MALLOC_STRUCT(gl_query_object); + struct gl_query_object *q = CALLOC_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 */ + + /* This is to satisfy the language of the specification: "In the initial + * state of a query object, the result is available" (OpenGL 3.1 § + * 2.13). + */ + q->Ready = GL_TRUE; + + /* OpenGL 3.1 § 2.13 says about GenQueries, "These names are marked as + * used, but no object is associated with them until the first time they + * are used by BeginQuery." Since our implementation actually does + * allocate an object at this point, use a flag to indicate that this + * object has not yet been bound so should not be considered a query. + */ + q->EverBound = GL_FALSE; } return q; } @@ -63,7 +75,7 @@ _mesa_new_query_object(struct gl_context *ctx, GLuint id) static void _mesa_begin_query(struct gl_context *ctx, struct gl_query_object *q) { - /* no-op */ + ctx->NewState |= _NEW_DEPTH; /* for swrast */ } @@ -74,6 +86,7 @@ _mesa_begin_query(struct gl_context *ctx, struct gl_query_object *q) static void _mesa_end_query(struct gl_context *ctx, struct gl_query_object *q) { + ctx->NewState |= _NEW_DEPTH; /* for swrast */ q->Ready = GL_TRUE; } @@ -113,6 +126,7 @@ _mesa_check_query(struct gl_context *ctx, struct gl_query_object *q) static void _mesa_delete_query(struct gl_context *ctx, struct gl_query_object *q) { + free(q->Label); free(q); } @@ -147,12 +161,17 @@ get_query_binding_point(struct gl_context *ctx, GLenum target) return &ctx->Query.CurrentOcclusionObject; else return NULL; + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + if (ctx->Extensions.ARB_ES3_compatibility + || (ctx->API == API_OPENGLES2 && ctx->Version >= 30)) + 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; @@ -163,19 +182,17 @@ get_query_binding_point(struct gl_context *ctx, GLenum target) return &ctx->Query.PrimitivesWritten; else return NULL; -#endif default: return NULL; } } -static void GLAPIENTRY -_mesa_GenQueriesARB(GLsizei n, GLuint *ids) +void GLAPIENTRY +_mesa_GenQueries(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); @@ -185,13 +202,6 @@ _mesa_GenQueriesARB(GLsizei n, GLuint *ids) 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; @@ -209,34 +219,35 @@ _mesa_GenQueriesARB(GLsizei n, GLuint *ids) } -static void GLAPIENTRY -_mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids) +void GLAPIENTRY +_mesa_DeleteQueries(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); + _mesa_debug(ctx, "glDeleteQueries(%d)\n", n); 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 = _mesa_lookup_query_object(ctx, ids[i]); if (q) { - ASSERT(!q->Active); /* should be caught earlier */ + if (q->Active) { + struct gl_query_object **bindpt; + bindpt = get_query_binding_point(ctx, q->Target); + assert(bindpt); /* Should be non-null for active q. */ + if (bindpt) { + *bindpt = NULL; + } + q->Active = GL_FALSE; + ctx->Driver.EndQuery(ctx, q); + } _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]); ctx->Driver.DeleteQuery(ctx, q); } @@ -245,19 +256,25 @@ _mesa_DeleteQueriesARB(GLsizei n, const GLuint *ids) } -static GLboolean GLAPIENTRY -_mesa_IsQueryARB(GLuint id) +GLboolean GLAPIENTRY +_mesa_IsQuery(GLuint id) { + struct gl_query_object *q; + GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glIsQuery(%u)\n", id); - if (id && _mesa_lookup_query_object(ctx, id)) - return GL_TRUE; - else + if (id == 0) + return GL_FALSE; + + q = _mesa_lookup_query_object(ctx, id); + if (q == NULL) return GL_FALSE; + + return q->EverBound; } static GLboolean @@ -281,12 +298,11 @@ query_error_check_index(struct gl_context *ctx, GLenum target, GLuint index) return GL_TRUE; } -static void GLAPIENTRY +void GLAPIENTRY _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) { struct gl_query_object *q, **bindpt; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBeginQueryIndexed(%s, %u, %u)\n", @@ -295,7 +311,7 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) if (!query_error_check_index(ctx, target, index)) return; - FLUSH_VERTICES(ctx, _NEW_DEPTH); + FLUSH_VERTICES(ctx, 0); bindpt = get_query_binding_point(ctx, target); if (!bindpt) { @@ -303,6 +319,19 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) return; } + /* From the GL_ARB_occlusion_query spec: + * + * "If BeginQueryARB is called while another query is already in + * progress with the same target, an INVALID_OPERATION error is + * generated." + */ + if (*bindpt) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBeginQuery{Indexed}(target=%s is active)", + _mesa_lookup_enum_by_nr(target)); + return; + } + if (id == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQuery{Indexed}(id==0)"); return; @@ -310,13 +339,19 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) q = _mesa_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, "glBeginQuery{Indexed}"); + if (ctx->API != API_OPENGL_COMPAT) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBeginQuery{Indexed}(non-gen name)"); return; + } else { + /* create new object */ + q = ctx->Driver.NewQueryObject(ctx, id); + if (!q) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQuery{Indexed}"); + return; + } + _mesa_HashInsert(ctx->Query.QueryObjects, id, q); } - _mesa_HashInsert(ctx->Query.QueryObjects, id, q); } else { /* pre-existing object */ @@ -331,6 +366,7 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) q->Active = GL_TRUE; q->Result = 0; q->Ready = GL_FALSE; + q->EverBound = GL_TRUE; /* XXX should probably refcount query objects */ *bindpt = q; @@ -339,12 +375,11 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) } -static void GLAPIENTRY +void GLAPIENTRY _mesa_EndQueryIndexed(GLenum target, GLuint index) { struct gl_query_object *q, **bindpt; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glEndQueryIndexed(%s, %u)\n", @@ -353,7 +388,7 @@ _mesa_EndQueryIndexed(GLenum target, GLuint index) if (!query_error_check_index(ctx, target, index)) return; - FLUSH_VERTICES(ctx, _NEW_DEPTH); + FLUSH_VERTICES(ctx, 0); bindpt = get_query_binding_point(ctx, target); if (!bindpt) { @@ -363,6 +398,16 @@ _mesa_EndQueryIndexed(GLenum target, GLuint index) /* XXX should probably refcount query objects */ q = *bindpt; + + /* Check for GL_ANY_SAMPLES_PASSED vs GL_SAMPLES_PASSED. */ + if (q && q->Target != target) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glEndQuery(target=%s with active query of target %s)", + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(q->Target)); + return; + } + *bindpt = NULL; if (!q || !q->Active) { @@ -375,24 +420,23 @@ _mesa_EndQueryIndexed(GLenum target, GLuint index) ctx->Driver.EndQuery(ctx, q); } -static void GLAPIENTRY -_mesa_BeginQueryARB(GLenum target, GLuint id) +void GLAPIENTRY +_mesa_BeginQuery(GLenum target, GLuint id) { _mesa_BeginQueryIndexed(target, 0, id); } -static void GLAPIENTRY -_mesa_EndQueryARB(GLenum target) +void GLAPIENTRY +_mesa_EndQuery(GLenum target) { _mesa_EndQueryIndexed(target, 0); } -static void GLAPIENTRY +void GLAPIENTRY _mesa_QueryCounter(GLuint id, GLenum target) { struct gl_query_object *q; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glQueryCounter(%u, %s)\n", id, @@ -437,20 +481,25 @@ _mesa_QueryCounter(GLuint id, GLenum target) q->Target = target; q->Result = 0; q->Ready = GL_FALSE; - - /* QueryCounter is implemented using EndQuery without BeginQuery - * in drivers. This is actually Direct3D and Gallium convention. */ - ctx->Driver.EndQuery(ctx, q); + q->EverBound = GL_TRUE; + + if (ctx->Driver.QueryCounter) { + ctx->Driver.QueryCounter(ctx, q); + } else { + /* QueryCounter is implemented using EndQuery without BeginQuery + * in drivers. This is actually Direct3D and Gallium convention. + */ + ctx->Driver.EndQuery(ctx, q); + } } -static void GLAPIENTRY +void GLAPIENTRY _mesa_GetQueryIndexediv(GLenum target, GLuint index, GLenum pname, GLint *params) { struct gl_query_object *q = NULL, **bindpt = NULL; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glGetQueryIndexediv(%s, %u, %s)\n", @@ -511,7 +560,7 @@ _mesa_GetQueryIndexediv(GLenum target, GLuint index, GLenum pname, } break; case GL_CURRENT_QUERY_ARB: - *params = q ? q->Id : 0; + *params = (q && q->Target == target) ? q->Id : 0; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetQuery{Indexed}iv(pname)"); @@ -519,18 +568,17 @@ _mesa_GetQueryIndexediv(GLenum target, GLuint index, GLenum pname, } } -static void GLAPIENTRY -_mesa_GetQueryivARB(GLenum target, GLenum pname, GLint *params) +void GLAPIENTRY +_mesa_GetQueryiv(GLenum target, GLenum pname, GLint *params) { _mesa_GetQueryIndexediv(target, 0, pname, params); } -static void GLAPIENTRY -_mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params) +void GLAPIENTRY +_mesa_GetQueryObjectiv(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, @@ -550,7 +598,8 @@ _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->Target == GL_ANY_SAMPLES_PASSED) { + if (q->Target == GL_ANY_SAMPLES_PASSED + || q->Target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) { if (q->Result) *params = GL_TRUE; else @@ -576,12 +625,11 @@ _mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params) } -static void GLAPIENTRY -_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params) +void GLAPIENTRY +_mesa_GetQueryObjectuiv(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, @@ -601,7 +649,8 @@ _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->Target == GL_ANY_SAMPLES_PASSED) { + if (q->Target == GL_ANY_SAMPLES_PASSED + || q->Target == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) { if (q->Result) *params = GL_TRUE; else @@ -630,12 +679,11 @@ _mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params) /** * New with GL_EXT_timer_query */ -static void GLAPIENTRY -_mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params) +void GLAPIENTRY +_mesa_GetQueryObjecti64v(GLuint id, GLenum pname, GLint64EXT *params) { struct gl_query_object *q = NULL; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glGetQueryObjecti64v(%u, %s)\n", id, @@ -671,12 +719,11 @@ _mesa_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64EXT *params) /** * New with GL_EXT_timer_query */ -static void GLAPIENTRY -_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params) +void GLAPIENTRY +_mesa_GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params) { struct gl_query_object *q = NULL; GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glGetQueryObjectui64v(%u, %s)\n", id, @@ -708,29 +755,6 @@ _mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params) } } - -void -_mesa_init_queryobj_dispatch(struct _glapi_table *disp) -{ - SET_GenQueriesARB(disp, _mesa_GenQueriesARB); - SET_DeleteQueriesARB(disp, _mesa_DeleteQueriesARB); - SET_IsQueryARB(disp, _mesa_IsQueryARB); - SET_BeginQueryARB(disp, _mesa_BeginQueryARB); - SET_EndQueryARB(disp, _mesa_EndQueryARB); - SET_GetQueryivARB(disp, _mesa_GetQueryivARB); - SET_GetQueryObjectivARB(disp, _mesa_GetQueryObjectivARB); - SET_GetQueryObjectuivARB(disp, _mesa_GetQueryObjectuivARB); - SET_QueryCounter(disp, _mesa_QueryCounter); - - SET_GetQueryObjecti64vEXT(disp, _mesa_GetQueryObjecti64vEXT); - SET_GetQueryObjectui64vEXT(disp, _mesa_GetQueryObjectui64vEXT); - - SET_BeginQueryIndexed(disp, _mesa_BeginQueryIndexed); - SET_EndQueryIndexed(disp, _mesa_EndQueryIndexed); - SET_GetQueryIndexediv(disp, _mesa_GetQueryIndexediv); -} - - /** * Allocate/init the context state related to query objects. */