On 10/02/2018 11:06 AM, Chris Wilson wrote:
> If we always write the 'available' flag after writing the final result
> of the query, we can probe that predicate to quickly query whether the
> result is ready from userspace. The primary advantage of checking the
> predicate is that it allows for more fine-grained queries, we do not
> have to wait for the batch to finish before the query is marked as
> ready.
> 
> We still do check the status of the batch after probing the query so
> that if the worst happens and the batch did hang without completing the
> query, we do not spin forever (although it is not as nice as completely
> eliminating the ioctl, the busy-ioctl is lightweight!).
> 
> Signed-off-by: Chris Wilson <ch...@chris-wilson.co.uk>
> Cc: Kenneth Graunke <kenn...@whitecape.org>
> Cc: Matt Turner <matts...@gmail.com>
> ---
>  src/mesa/drivers/dri/i965/brw_context.h   |  4 +-
>  src/mesa/drivers/dri/i965/gen6_queryobj.c | 54 ++++++++++-------------
>  2 files changed, 25 insertions(+), 33 deletions(-)
> 
> diff --git a/src/mesa/drivers/dri/i965/brw_context.h 
> b/src/mesa/drivers/dri/i965/brw_context.h
> index 840332294e6..418941c9194 100644
> --- a/src/mesa/drivers/dri/i965/brw_context.h
> +++ b/src/mesa/drivers/dri/i965/brw_context.h
> @@ -468,8 +468,8 @@ struct brw_query_object {
>     bool flushed;
>  };
>  
> -#define GEN6_QUERY_PREDICATE (2)
> -#define GEN6_QUERY_RESULTS (0)
> +#define GEN6_QUERY_PREDICATE (0)
> +#define GEN6_QUERY_RESULTS (1)
>  
>  static inline unsigned
>  gen6_query_predicate_offset(const struct brw_query_object *query)
> diff --git a/src/mesa/drivers/dri/i965/gen6_queryobj.c 
> b/src/mesa/drivers/dri/i965/gen6_queryobj.c
> index dc70e2a568a..b6832588333 100644
> --- a/src/mesa/drivers/dri/i965/gen6_queryobj.c
> +++ b/src/mesa/drivers/dri/i965/gen6_queryobj.c
> @@ -40,8 +40,7 @@
>  #include "intel_buffer_objects.h"
>  
>  static inline void
> -set_query_availability(struct brw_context *brw, struct brw_query_object 
> *query,
> -                       bool available)
> +set_query_available(struct brw_context *brw, struct brw_query_object *query)
>  {
>     /* For platforms that support ARB_query_buffer_object, we write the
>      * query availability for "pipelined" queries.
> @@ -58,22 +57,12 @@ set_query_availability(struct brw_context *brw, struct 
> brw_query_object *query,
>      * PIPE_CONTROL with an immediate write will synchronize with
>      * those earlier writes, so we write 1 when the value has landed.
>      */
> -   if (brw->ctx.Extensions.ARB_query_buffer_object &&
> -       brw_is_query_pipelined(query)) {
> -      unsigned flags = PIPE_CONTROL_WRITE_IMMEDIATE;
>  
> -      if (available) {
> -         /* Order available *after* the query results. */
> -         flags |= PIPE_CONTROL_FLUSH_ENABLE;
> -      } else {
> -         /* Make it unavailable *before* any pipelined reads. */
> -         flags |= PIPE_CONTROL_CS_STALL;
> -      }
> -
> -      brw_emit_pipe_control_write(brw, flags,
> -                                  query->bo, 
> gen6_query_predicate_offset(query),
> -                                  available);
> -   }
> +   brw_emit_pipe_control_write(brw,
> +                               PIPE_CONTROL_WRITE_IMMEDIATE |
> +                               PIPE_CONTROL_FLUSH_ENABLE,
> +                               query->bo, gen6_query_predicate_offset(query),
> +                               true);
>  }
>  
>  static void
> @@ -144,12 +133,12 @@ write_xfb_overflow_streams(struct gl_context *ctx,
>  }
>  
>  static bool
> -check_xfb_overflow_streams(uint64_t *results, int count)
> +check_xfb_overflow_streams(const uint64_t *results, int count)
>  {
>     bool overflow = false;
>  
>     for (int i = 0; i < count; i++) {
> -      uint64_t *result_i = &results[4 * i];
> +      const uint64_t *result_i = &results[4 * i];
>  
>        if ((result_i[3] - result_i[2]) != (result_i[1] - result_i[0])) {
>           overflow = true;

This hunk seems unrelated, but I'm almost always in favor of more const.

> @@ -221,7 +210,8 @@ emit_pipeline_stat(struct brw_context *brw, struct brw_bo 
> *bo,
>   */
>  static void
>  gen6_queryobj_get_results(struct gl_context *ctx,
> -                          struct brw_query_object *query)
> +                          struct brw_query_object *query,
> +                          uint64_t *results)
>  {
>     struct brw_context *brw = brw_context(ctx);
>     const struct gen_device_info *devinfo = &brw->screen->devinfo;
> @@ -229,9 +219,6 @@ gen6_queryobj_get_results(struct gl_context *ctx,
>     if (query->bo == NULL)
>        return;
>  
> -   brw_bo_wait_rendering(query->bo);
> -   uint64_t *results = query->results;
> -
>     switch (query->Base.Target) {
>     case GL_TIME_ELAPSED:
>        /* The query BO contains the starting and ending timestamps.
> @@ -329,10 +316,10 @@ gen6_alloc_query(struct brw_context *brw, struct 
> brw_query_object *query)
>  
>     query->results = brw_bo_map(brw, query->bo,
>                                 MAP_COHERENT | MAP_PERSISTENT |
> -                               MAP_READ | MAP_ASYNC);
> +                               MAP_READ | MAP_WRITE);
>  
>     /* For ARB_query_buffer_object: The result is not available */
> -   set_query_availability(brw, query, false);
> +   query->results[GEN6_QUERY_PREDICATE] = false;
>  
>     return 0;
>  }
> @@ -487,7 +474,7 @@ gen6_end_query(struct gl_context *ctx, struct 
> gl_query_object *q)
>     query->flushed = false;
>  
>     /* For ARB_query_buffer_object: The result is now available */
> -   set_query_availability(brw, query, true);
> +   set_query_available(brw, query);
>  }
>  
>  /**
> @@ -523,7 +510,11 @@ static void gen6_wait_query(struct gl_context *ctx, 
> struct gl_query_object *q)
>      */
>     flush_batch_if_needed(brw, query);
>  
> -   gen6_queryobj_get_results(ctx, query);
> +   uint64_t *results = query->results;
> +   if (!results[GEN6_QUERY_PREDICATE]) /* not yet available, must wait */
> +      brw_bo_wait_rendering(query->bo);
> +
> +   gen6_queryobj_get_results(ctx, query, results + GEN6_QUERY_RESULTS);
>  }
>  
>  /**
> @@ -552,9 +543,10 @@ static void gen6_check_query(struct gl_context *ctx, 
> struct gl_query_object *q)
>      */
>     flush_batch_if_needed(brw, query);
>  
> -   if (!brw_bo_busy(query->bo)) {
> -      gen6_queryobj_get_results(ctx, query);
> -   }
> +   uint64_t *results = query->results;
> +   if (results[GEN6_QUERY_PREDICATE] || /* already available, can read async 
> */
> +       !brw_bo_map_busy(query->bo, MAP_READ)) /* GPU hang, results lost? */
> +      gen6_queryobj_get_results(ctx, query, results + GEN6_QUERY_RESULTS);
>  }
>  
>  static void
> @@ -565,7 +557,7 @@ gen6_query_counter(struct gl_context *ctx, struct 
> gl_query_object *q)
>     const int idx = gen6_alloc_query(brw, query) + GEN6_QUERY_RESULTS;
>  
>     brw_write_timestamp(brw, query->bo, idx);
> -   set_query_availability(brw, query, true);
> +   set_query_available(brw, query);
>  
>     query->flushed = false;
>  }
> 

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to