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)");
      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 */
            _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]);
            ctx->Driver.DeleteQuery(ctx, q);
         }
      }
   }
}
Ejemplo n.º 2
0
/**
 * New with GL_EXT_timer_query
 */
void GLAPIENTRY
_mesa_GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params)
{
   struct gl_query_object *q = NULL;
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glGetQueryObjectui64v(%u, %s)\n", id,
                  _mesa_lookup_enum_by_nr(pname));

   if (id)
      q = _mesa_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;
   }
}
Ejemplo n.º 3
0
void GLAPIENTRY
_mesa_QueryCounter(GLuint id, GLenum target)
{
   struct gl_query_object *q;
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glQueryCounter(%u, %s)\n", id,
                  _mesa_lookup_enum_by_nr(target));

   /* error checking */
   if (target != GL_TIMESTAMP) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glQueryCounter(target)");
      return;
   }

   if (id == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glQueryCounter(id==0)");
      return;
   }

   q = _mesa_lookup_query_object(ctx, id);
   if (!q) {
      /* XXX the Core profile should throw INVALID_OPERATION here */

      /* create new object */
      q = ctx->Driver.NewQueryObject(ctx, id);
      if (!q) {
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glQueryCounter");
         return;
      }
      _mesa_HashInsert(ctx->Query.QueryObjects, id, q);
   }
   else {
      if (q->Target && q->Target != GL_TIMESTAMP) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glQueryCounter(id has an invalid target)");
         return;
      }
   }

   if (q->Active) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glQueryCounter(id is active)");
      return;
   }

   q->Target = target;
   q->Result = 0;
   q->Ready = GL_FALSE;

   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 GLboolean GLAPIENTRY
_mesa_IsQueryARB(GLuint id)
{
   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
      return GL_FALSE;
}
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 = _mesa_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->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:
	 if (!q->Ready)
	    ctx->Driver.CheckQuery( ctx, q );
         *params = q->Ready;
         break;
      default:
         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)");
         return;
   }
}
Ejemplo n.º 6
0
void GLAPIENTRY
_mesa_BeginConditionalRender(GLuint queryId, GLenum mode)
{
   struct gl_query_object *q;
   GET_CURRENT_CONTEXT(ctx);

   if (!ctx->Extensions.NV_conditional_render || ctx->Query.CondRenderQuery ||
       queryId == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()");
      return;
   }

   ASSERT(ctx->Query.CondRenderMode == GL_NONE);

   switch (mode) {
   case GL_QUERY_WAIT:
   case GL_QUERY_NO_WAIT:
   case GL_QUERY_BY_REGION_WAIT:
   case GL_QUERY_BY_REGION_NO_WAIT:
      /* OK */
      break;
   default:
      _mesa_error(ctx, GL_INVALID_ENUM, "glBeginConditionalRender(mode=%s)",
                  _mesa_lookup_enum_by_nr(mode));
      return;
   }

   q = _mesa_lookup_query_object(ctx, queryId);
   if (!q) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glBeginConditionalRender(bad queryId=%u)", queryId);
      return;
   }
   ASSERT(q->Id == queryId);

   if (q->Target != GL_SAMPLES_PASSED || q->Active) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()");
      return;
   }

   ctx->Query.CondRenderQuery = q;
   ctx->Query.CondRenderMode = mode;

   if (ctx->Driver.BeginConditionalRender)
      ctx->Driver.BeginConditionalRender(ctx, q, mode);
}
Ejemplo n.º 7
0
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 == 0)
      return GL_FALSE;

   q = _mesa_lookup_query_object(ctx, id);
   if (q == NULL)
      return GL_FALSE;

   return q->EverBound;
}
static 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",
                  _mesa_lookup_enum_by_nr(target), index, id);

   if (!query_error_check_index(ctx, target, index))
      return;

   FLUSH_VERTICES(ctx, _NEW_DEPTH);

   bindpt = get_query_binding_point(ctx, target);
   if (!bindpt) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQuery{Indexed}(target)");
      return;
   }

   if (id == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginQuery{Indexed}(id==0)");
      return;
   }

   q = _mesa_lookup_query_object(ctx, id);
   if (!q) {
      if (ctx->API == API_OPENGL_CORE) {
         _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);
      }
   }
   else {
      /* pre-existing object */
      if (q->Active) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glBeginQuery{Indexed}(query already active)");
         return;
      }
   }

   q->Target = target;
   q->Active = GL_TRUE;
   q->Result = 0;
   q->Ready = GL_FALSE;

   /* XXX should probably refcount query objects */
   *bindpt = q;

   ctx->Driver.BeginQuery(ctx, q);
}
Ejemplo n.º 9
0
void GLAPIENTRY
_mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id)
{
   struct gl_query_object *q, **bindpt;
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glBeginQueryIndexed(%s, %u, %u)\n",
                  _mesa_lookup_enum_by_nr(target), index, id);

   if (!query_error_check_index(ctx, target, index))
      return;

   FLUSH_VERTICES(ctx, _NEW_DEPTH);

   bindpt = get_query_binding_point(ctx, target);
   if (!bindpt) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBeginQuery{Indexed}(target)");
      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;
   }

   q = _mesa_lookup_query_object(ctx, id);
   if (!q) {
      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);
      }
   }
   else {
      /* pre-existing object */
      if (q->Active) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glBeginQuery{Indexed}(query already active)");
         return;
      }
   }

   q->Target = target;
   q->Active = GL_TRUE;
   q->Result = 0;
   q->Ready = GL_FALSE;
   q->EverBound = GL_TRUE;

   /* XXX should probably refcount query objects */
   *bindpt = q;

   ctx->Driver.BeginQuery(ctx, q);
}
Ejemplo n.º 10
0
void GLAPIENTRY
_mesa_BeginConditionalRender(GLuint queryId, GLenum mode)
{
   struct gl_query_object *q = NULL;
   GET_CURRENT_CONTEXT(ctx);

   /* Section 2.14 (Conditional Rendering) of the OpenGL 3.0 spec says:
    *
    *     "If BeginConditionalRender is called while conditional rendering is
    *     in progress, or if EndConditionalRender is called while conditional
    *     rendering is not in progress, the error INVALID_OPERATION is
    *     generated."
    */
   if (!ctx->Extensions.NV_conditional_render || ctx->Query.CondRenderQuery) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()");
      return;
   }

   ASSERT(ctx->Query.CondRenderMode == GL_NONE);

   /* Section 2.14 (Conditional Rendering) of the OpenGL 3.0 spec says:
    *
    *     "The error INVALID_VALUE is generated if <id> is not the name of an
    *     existing query object query."
    */
   if (queryId != 0)
      q = _mesa_lookup_query_object(ctx, queryId);

   if (!q) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glBeginConditionalRender(bad queryId=%u)", queryId);
      return;
   }
   ASSERT(q->Id == queryId);

   switch (mode) {
   case GL_QUERY_WAIT:
   case GL_QUERY_NO_WAIT:
   case GL_QUERY_BY_REGION_WAIT:
   case GL_QUERY_BY_REGION_NO_WAIT:
      break; /* OK */
   case GL_QUERY_WAIT_INVERTED:
   case GL_QUERY_NO_WAIT_INVERTED:
   case GL_QUERY_BY_REGION_WAIT_INVERTED:
   case GL_QUERY_BY_REGION_NO_WAIT_INVERTED:
      if (ctx->Extensions.ARB_conditional_render_inverted)
         break; /* OK */
      /* fallthrough - invalid */
   default:
      _mesa_error(ctx, GL_INVALID_ENUM, "glBeginConditionalRender(mode=%s)",
                  _mesa_lookup_enum_by_nr(mode));
      return;
   }

   /* Section 2.14 (Conditional Rendering) of the OpenGL 3.0 spec says:
    *
    *     "The error INVALID_OPERATION is generated if <id> is the name of a
    *     query object with a target other than SAMPLES_PASSED, or <id> is the
    *     name of a query currently in progress."
    */
   if ((q->Target != GL_SAMPLES_PASSED &&
        q->Target != GL_ANY_SAMPLES_PASSED &&
        q->Target != GL_ANY_SAMPLES_PASSED_CONSERVATIVE) || q->Active) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()");
      return;
   }

   ctx->Query.CondRenderQuery = q;
   ctx->Query.CondRenderMode = mode;

   if (ctx->Driver.BeginConditionalRender)
      ctx->Driver.BeginConditionalRender(ctx, q, mode);
}
Ejemplo n.º 11
0
static ALWAYS_INLINE void
begin_conditional_render(struct gl_context *ctx, GLuint queryId, GLenum mode,
                         bool no_error)
{
   struct gl_query_object *q = NULL;

   assert(ctx->Query.CondRenderMode == GL_NONE);

   if (queryId != 0)
      q = _mesa_lookup_query_object(ctx, queryId);

   if (!no_error) {
      /* Section 2.14 (Conditional Rendering) of the OpenGL 3.0 spec says:
       *
       *     "The error INVALID_VALUE is generated if <id> is not the name of an
       *     existing query object query."
       */
      if (!q) {
         _mesa_error(ctx, GL_INVALID_VALUE,
                     "glBeginConditionalRender(bad queryId=%u)", queryId);
         return;
      }
      assert(q->Id == queryId);

      switch (mode) {
      case GL_QUERY_WAIT:
      case GL_QUERY_NO_WAIT:
      case GL_QUERY_BY_REGION_WAIT:
      case GL_QUERY_BY_REGION_NO_WAIT:
         break; /* OK */
      case GL_QUERY_WAIT_INVERTED:
      case GL_QUERY_NO_WAIT_INVERTED:
      case GL_QUERY_BY_REGION_WAIT_INVERTED:
      case GL_QUERY_BY_REGION_NO_WAIT_INVERTED:
         if (ctx->Extensions.ARB_conditional_render_inverted)
            break; /* OK */
         /* fallthrough - invalid */
      default:
         _mesa_error(ctx, GL_INVALID_ENUM, "glBeginConditionalRender(mode=%s)",
                     _mesa_enum_to_string(mode));
         return;
      }

      /* Section 2.14 (Conditional Rendering) of the OpenGL 3.0 spec says:
       *
       *     "The error INVALID_OPERATION is generated if <id> is the name of a
       *     query object with a target other than SAMPLES_PASSED, or <id> is
       *     the name of a query currently in progress."
       */
      if ((q->Target != GL_SAMPLES_PASSED &&
           q->Target != GL_ANY_SAMPLES_PASSED &&
           q->Target != GL_ANY_SAMPLES_PASSED_CONSERVATIVE &&
           q->Target != GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB &&
           q->Target != GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB) || q->Active) {
         _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()");
         return;
      }
   }

   ctx->Query.CondRenderQuery = q;
   ctx->Query.CondRenderMode = mode;

   if (ctx->Driver.BeginConditionalRender)
      ctx->Driver.BeginConditionalRender(ctx, q, mode);
}