[Mesa-dev] [PATCH 1/2] i965: Don't flush the batch immediately on EndQuery.

Kenneth Graunke kenneth at whitecape.org
Tue Oct 16 21:21:54 PDT 2012


On 10/16/2012 04:32 PM, Eric Anholt wrote:
> The theory I had when I wrote the code was that you wanted to minimize latency
> on your queries because the app was going to ask soon.  Only, it turns out
> that everybody batches up their queries and asks for the results later (often
> after the next SwapBuffers!), so this was a pessimization.
>
> Until now, I had no workload where it mattered enough to benchmark.  Recently
> I started playing some Minecraft, which uses tons of queries to decide whether
> to render chunks of the terrain.  For that app, avoiding the flush in the
> query-generation loop improves performance 22.7% +/- 4.7% (n=3) on an apitrace
> capture of it (confirmed in game by watching the fps meter found by pressing
> F3, 15/16 -> 20/21 fps).
> ---
>   src/mesa/drivers/dri/i965/brw_queryobj.c |   19 ++++++++++++++-----
>   1 file changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c
> index d5c4fdf..89420e9 100644
> --- a/src/mesa/drivers/dri/i965/brw_queryobj.c
> +++ b/src/mesa/drivers/dri/i965/brw_queryobj.c
> @@ -142,6 +142,9 @@ brw_queryobj_get_results(struct gl_context *ctx,
>      if (query->bo == NULL)
>         return;
>
> +   if (drm_intel_bo_references(intel->batch.bo, query->bo))
> +      intel_batchbuffer_flush(intel);
> +
>      if (unlikely(INTEL_DEBUG & DEBUG_PERF)) {
>         if (drm_intel_bo_busy(query->bo)) {
>            perf_debug("Stalling on the GPU waiting for a query object.\n");
> @@ -303,13 +306,8 @@ brw_end_query(struct gl_context *ctx, struct gl_query_object *q)
>         break;
>
>      case GL_SAMPLES_PASSED_ARB:
> -      /* Flush the batchbuffer in case it has writes to our query BO.
> -       * Have later queries write to a new query BO so that further rendering
> -       * doesn't delay the collection of our results.
> -       */
>         if (query->bo) {
>   	 brw_emit_query_end(brw);
> -	 intel_batchbuffer_flush(intel);
>
>   	 drm_intel_bo_unreference(brw->query.bo);
>   	 brw->query.bo = NULL;
> @@ -364,8 +362,19 @@ static void brw_wait_query(struct gl_context *ctx, struct gl_query_object *q)
>
>   static void brw_check_query(struct gl_context *ctx, struct gl_query_object *q)
>   {
> +   struct intel_context *intel = intel_context(ctx);
>      struct brw_query_object *query = (struct brw_query_object *)q;
>
> +   /* From the GL_ARB_occlusion_query spec:
> +    *
> +    *     "Instead of allowing for an infinite loop, performing a
> +    *      QUERY_RESULT_AVAILABLE_ARB will perform a flush if the result is
> +    *      not ready yet on the first time it is queried.  This ensures that
> +    *      the async query will return true in finite time.
> +    */
> +   if (query->bo && drm_intel_bo_references(intel->batch.bo, query->bo))
> +      intel_batchbuffer_flush(intel);
> +
>      if (query->bo == NULL || !drm_intel_bo_busy(query->bo)) {
>         brw_queryobj_get_results(ctx, query);
>         query->Base.Ready = true;
>

Looks good to me!

Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>


More information about the mesa-dev mailing list