Hey,

Attached is a patch which adds driver hooks to update the status of a
query object (both to core mesa, and the gallium state tracker).  There
is currently an issue with applications that spin waiting for
GL_QUERY_RESULT_AVAILABLE_ARB to be true (eg. arbocclude).  The current
code will simply check return q->Ready, and doesn't give the driver a
chance to actually update this field, so the application will end up
spinning forever.

The workaround in nouveau (current git, and nv4x gallium driver)
currently forces the application to block until a query result is
available when it calls glEndQuery().  Obviously this isn't a nice
solution!

Cheers,
Ben.
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index 96e5037..2228754 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -227,6 +227,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
    driver->BeginQuery = _mesa_begin_query;
    driver->EndQuery = _mesa_end_query;
    driver->WaitQuery = _mesa_wait_query;
+   driver->UpdateQuery = _mesa_update_query;
 
    /* APPLE_vertex_array_object */
    driver->NewArrayObject = _mesa_new_array_object;
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index f089fcb..d45276e 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -814,6 +814,7 @@ struct dd_function_table {
    void (*BeginQuery)(GLcontext *ctx, struct gl_query_object *q);
    void (*EndQuery)(GLcontext *ctx, struct gl_query_object *q);
    void (*WaitQuery)(GLcontext *ctx, struct gl_query_object *q);
+   void (*UpdateQuery)(GLcontext *ctx, struct gl_query_object *q);
    /[EMAIL PROTECTED]/
 
 
diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c
index 688d0fc..1222a58 100644
--- a/src/mesa/main/queryobj.c
+++ b/src/mesa/main/queryobj.c
@@ -88,6 +88,15 @@ _mesa_wait_query(GLcontext *ctx, struct gl_query_object *q)
    assert(q->Ready);
 }
 
+/**
+ * Update a query.  Software driver fallback.
+ * Called via ctx->Driver.EndQuery().
+ */
+void
+_mesa_update_query(GLcontext *ctx, struct gl_query_object *q)
+{
+   q->Ready = GL_TRUE;
+}
 
 /**
  * Delete an occlusion query object.
@@ -386,6 +395,8 @@ _mesa_GetQueryObjectivARB(GLuint id, GLenum pname, GLint *params)
          }
          break;
       case GL_QUERY_RESULT_AVAILABLE_ARB:
+         if (!q->Ready)
+            ctx->Driver.UpdateQuery(ctx, q);
          *params = q->Ready;
          break;
       default:
diff --git a/src/mesa/main/queryobj.h b/src/mesa/main/queryobj.h
index d466aae..670cc03 100644
--- a/src/mesa/main/queryobj.h
+++ b/src/mesa/main/queryobj.h
@@ -45,6 +45,8 @@ _mesa_end_query(GLcontext *ctx, struct gl_query_object *q);
 extern void
 _mesa_wait_query(GLcontext *ctx, struct gl_query_object *q);
 
+extern void
+_mesa_update_query(GLcontext *ctx, struct gl_query_object *q);
 
 extern void GLAPIENTRY
 _mesa_GenQueriesARB(GLsizei n, GLuint *ids);
diff --git a/src/mesa/pipe/p_context.h b/src/mesa/pipe/p_context.h
index 8bed958..58086dc 100644
--- a/src/mesa/pipe/p_context.h
+++ b/src/mesa/pipe/p_context.h
@@ -83,6 +83,7 @@ struct pipe_context {
    void (*begin_query)(struct pipe_context *pipe, struct pipe_query_object *q);
    void (*end_query)(struct pipe_context *pipe, struct pipe_query_object *q);
    void (*wait_query)(struct pipe_context *pipe, struct pipe_query_object *q);
+   void (*update_query)(struct pipe_context *pipe, struct pipe_query_object *q);
 
    /*
     * State functions
diff --git a/src/mesa/pipe/softpipe/sp_context.c b/src/mesa/pipe/softpipe/sp_context.c
index d5e68c1..327c92c 100644
--- a/src/mesa/pipe/softpipe/sp_context.c
+++ b/src/mesa/pipe/softpipe/sp_context.c
@@ -207,6 +207,14 @@ softpipe_wait_query(struct pipe_context *pipe, struct pipe_query_object *q)
    assert(0);
 }
 
+static void
+softpipe_update_query(struct pipe_context *pipe, struct pipe_query_object *q)
+{
+   /* Should never get here since we indicated that the result was
+    * ready in softpipe_end_query().
+    */
+   assert(0);
+}
 
 static const char *softpipe_get_name( struct pipe_context *pipe )
 {
@@ -346,6 +354,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
    softpipe->pipe.begin_query = softpipe_begin_query;
    softpipe->pipe.end_query = softpipe_end_query;
    softpipe->pipe.wait_query = softpipe_wait_query;
+   softpipe->pipe.update_query = softpipe_update_query;
 
    softpipe->pipe.get_name = softpipe_get_name;
    softpipe->pipe.get_vendor = softpipe_get_vendor;
diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c
index 5b95dd7..66b10f8 100644
--- a/src/mesa/state_tracker/st_cb_queryobj.c
+++ b/src/mesa/state_tracker/st_cb_queryobj.c
@@ -134,6 +134,17 @@ st_WaitQuery(GLcontext *ctx, struct gl_query_object *q)
    q->Result = stq->pq.count;
 }
 
+static void
+st_UpdateQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+   struct pipe_context *pipe = ctx->st->pipe;
+   struct st_query_object *stq = st_query_object(q);
+
+   pipe->update_query(pipe, &stq->pq);
+   stq->base.Ready = stq->pq.ready;
+   if (stq->base.Ready)
+      stq->base.Result = stq->pq.count;
+}
 
 
 void st_init_query_functions(struct dd_function_table *functions)
@@ -142,4 +153,5 @@ void st_init_query_functions(struct dd_function_table *functions)
    functions->BeginQuery = st_BeginQuery;
    functions->EndQuery = st_EndQuery;
    functions->WaitQuery = st_WaitQuery;
+   functions->UpdateQuery = st_UpdateQuery;
 }
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to