Merge branch 'gallium-front-ccw'
[mesa.git] / src / mesa / state_tracker / st_cb_queryobj.c
index 10629e92254453e2f2f5a6049195ae1a5a1cce59..e423d9d8a51dbb9e9340ed98f1696d9a2dc54ced 100644 (file)
 #include "pipe/p_defines.h"
 #include "st_context.h"
 #include "st_cb_queryobj.h"
-#include "st_public.h"
 
 
+#if FEATURE_queryobj
+
 static struct gl_query_object *
 st_NewQueryObject(GLcontext *ctx, GLuint id)
 {
@@ -52,6 +53,7 @@ st_NewQueryObject(GLcontext *ctx, GLuint id)
       stq->base.Id = id;
       stq->base.Ready = GL_TRUE;
       stq->pq = NULL;
+      stq->type = PIPE_QUERY_TYPES; /* an invalid value */
       return &stq->base;
    }
    return NULL;
@@ -62,7 +64,7 @@ st_NewQueryObject(GLcontext *ctx, GLuint id)
 static void
 st_DeleteQuery(GLcontext *ctx, struct gl_query_object *q)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
+   struct pipe_context *pipe = st_context(ctx)->pipe;
    struct st_query_object *stq = st_query_object(q);
 
    if (stq->pq) {
@@ -70,26 +72,50 @@ st_DeleteQuery(GLcontext *ctx, struct gl_query_object *q)
       stq->pq = NULL;
    }
 
-   _mesa_free(stq);
+   free(stq);
 }
 
 
 static void
 st_BeginQuery(GLcontext *ctx, struct gl_query_object *q)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
+   struct pipe_context *pipe = st_context(ctx)->pipe;
    struct st_query_object *stq = st_query_object(q);
+   unsigned type;
 
+   /* convert GL query type to Gallium query type */
    switch (q->Target) {
    case GL_SAMPLES_PASSED_ARB:
-      if (!stq->pq)
-        stq->pq = pipe->create_query( pipe, PIPE_QUERY_OCCLUSION_COUNTER );
+      type = PIPE_QUERY_OCCLUSION_COUNTER;
+      break;
+   case GL_PRIMITIVES_GENERATED:
+      type = PIPE_QUERY_PRIMITIVES_GENERATED;
+      break;
+   case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+      type = PIPE_QUERY_PRIMITIVES_EMITTED;
+      break;
+   case GL_TIME_ELAPSED_EXT:
+      type = PIPE_QUERY_TIME_ELAPSED;
       break;
    default:
-      assert(0);
+      assert(0 && "unexpected query target in st_BeginQuery()");
       return;
    }
 
+   if (stq->pq && stq->type != type) {
+      /* free old query of different type */
+      pipe->destroy_query(pipe, stq->pq);
+      stq->pq = NULL;
+      stq->type = PIPE_QUERY_TYPES; /* an invalid value */
+   }
+
+   if (!stq->pq) {
+      stq->pq = pipe->create_query(pipe, type);
+      stq->type = type;
+   }
+
+   assert(stq->type == type);
+
    pipe->begin_query(pipe, stq->pq);
 }
 
@@ -97,7 +123,7 @@ st_BeginQuery(GLcontext *ctx, struct gl_query_object *q)
 static void
 st_EndQuery(GLcontext *ctx, struct gl_query_object *q)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
+   struct pipe_context *pipe = st_context(ctx)->pipe;
    struct st_query_object *stq = st_query_object(q);
 
    pipe->end_query(pipe, stq->pq);
@@ -107,7 +133,7 @@ st_EndQuery(GLcontext *ctx, struct gl_query_object *q)
 static void
 st_WaitQuery(GLcontext *ctx, struct gl_query_object *q)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
+   struct pipe_context *pipe = st_context(ctx)->pipe;
    struct st_query_object *stq = st_query_object(q);
 
    /* this function should only be called if we don't have a ready result */
@@ -129,15 +155,10 @@ st_WaitQuery(GLcontext *ctx, struct gl_query_object *q)
 static void
 st_CheckQuery(GLcontext *ctx, struct gl_query_object *q)
 {
-   struct pipe_context *pipe = ctx->st->pipe;
+   struct pipe_context *pipe = st_context(ctx)->pipe;
    struct st_query_object *stq = st_query_object(q);
-
-   if (!q->Ready) {
-      q->Ready = pipe->get_query_result(pipe, 
-                                       stq->pq,
-                                       FALSE,
-                                       &q->Result);
-   }
+   assert(!q->Ready);   /* we should not get called if Ready is TRUE */
+   q->Ready = pipe->get_query_result(pipe, stq->pq, FALSE, &q->Result);
 }
 
 
@@ -152,3 +173,5 @@ void st_init_query_functions(struct dd_function_table *functions)
    functions->WaitQuery = st_WaitQuery;
    functions->CheckQuery = st_CheckQuery;
 }
+
+#endif /* FEATURE_queryobj */