[Mesa-dev] [SQUASH] i965: Zero out query buffer done bit
Jordan Justen
jordan.l.justen at intel.com
Wed Apr 27 20:48:16 UTC 2016
On 2016-04-27 12:28:15, Kenneth Graunke wrote:
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
> src/mesa/drivers/dri/i965/brw_context.h | 2 ++
> src/mesa/drivers/dri/i965/brw_queryobj.c | 4 ++--
> src/mesa/drivers/dri/i965/gen6_queryobj.c | 30 ++++++++++++++++++++++++++----
> 3 files changed, 30 insertions(+), 6 deletions(-)
>
> Jordan,
>
> I'm pretty sure you need to zero out the "Done?" bit in query->bo. The BOs
> we allocate aren't guaranteed to be zero...so we may end up copying garbage
> to the MI_PREDICATE registers, rather than 0/1 as we wanted.
I think in gen6_begin_query, when we call:
/* For ARB_query_buffer_object: The result is not available */
set_query_availability(brw, query, false);
it should insert a CS write immediate to set it to 0. (Only for
'pipelined' queries.) Will that work?
-Jordan
>
> Here's some code that Eric wrote a long time ago to do that; I've updated
> it a couple times now. Feel free to squash it into your patch.
>
> With all of my feedback addressed, you get a Reviewed-by :)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
> index b75eabd..3805b56 100644
> --- a/src/mesa/drivers/dri/i965/brw_context.h
> +++ b/src/mesa/drivers/dri/i965/brw_context.h
> @@ -1429,6 +1429,8 @@ void brw_query_counter(struct gl_context *ctx, struct gl_query_object *q);
> bool brw_is_query_pipelined(struct brw_query_object *query);
>
> /** gen6_queryobj.c */
> +void brw_allocate_query_bo(struct brw_context *brw,
> + struct brw_query_object *query);
> void gen6_init_queryobj_functions(struct dd_function_table *functions);
> void brw_write_timestamp(struct brw_context *brw, drm_intel_bo *bo, int idx);
> void brw_write_depth_count(struct brw_context *brw, drm_intel_bo *bo, int idx);
> diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c
> index 81ee5ea..b7c2726 100644
> --- a/src/mesa/drivers/dri/i965/brw_queryobj.c
> +++ b/src/mesa/drivers/dri/i965/brw_queryobj.c
> @@ -470,8 +470,8 @@ brw_query_counter(struct gl_context *ctx, struct gl_query_object *q)
>
> assert(q->Target == GL_TIMESTAMP);
>
> - drm_intel_bo_unreference(query->bo);
> - query->bo = drm_intel_bo_alloc(brw->bufmgr, "timestamp query", 4096, 4096);
> + brw_allocate_query_bo(brw, query);
> +
> brw_write_timestamp(brw, query->bo, 0);
>
> query->flushed = false;
> diff --git a/src/mesa/drivers/dri/i965/gen6_queryobj.c b/src/mesa/drivers/dri/i965/gen6_queryobj.c
> index f95c9fc..04f58f6 100644
> --- a/src/mesa/drivers/dri/i965/gen6_queryobj.c
> +++ b/src/mesa/drivers/dri/i965/gen6_queryobj.c
> @@ -40,6 +40,8 @@
> #include "intel_buffer_objects.h"
> #include "intel_reg.h"
>
> +#define QUERY_DONE_OFFSET (2 * sizeof(uint64_t))
> +
> static inline void
> set_query_availability(struct brw_context *brw, struct brw_query_object *query,
> bool available)
> @@ -51,7 +53,7 @@ set_query_availability(struct brw_context *brw, struct brw_query_object *query,
> brw_is_query_pipelined(query)) {
> brw_emit_pipe_control_write(brw,
> PIPE_CONTROL_WRITE_IMMEDIATE,
> - query->bo, 2 * sizeof(uint64_t),
> + query->bo, QUERY_DONE_OFFSET,
> available, 0);
> }
> }
> @@ -140,6 +142,28 @@ emit_pipeline_stat(struct brw_context *brw, drm_intel_bo *bo,
> brw_store_register_mem64(brw, bo, reg, idx * sizeof(uint64_t));
> }
>
> +void
> +brw_allocate_query_bo(struct brw_context *brw, struct brw_query_object *query)
> +{
> + /* Since we're starting a new query, we need to throw away previous
> + * uncollected results if there are any.
> + */
> + drm_intel_bo_unreference(query->bo);
> +
> + query->bo = drm_intel_bo_alloc(brw->bufmgr, "query results", 4096, 4096);
> +
> + if (ctx->Extensions.ARB_query_buffer_object) {
> + /* Clear the "done" field.
> + *
> + * We can safely use _unsynchronized here (and possibly avoid bothering
> + * the kernel for this mapping at all on a cached buffer on an LLC
> + * system), because drm_intel_bo_alloc() guarantees you an idle BO.
> + */
> + drm_intel_gem_bo_map_unsynchronized(query->bo);
> + *(uint32_t *)(query->bo->virtual + QUERY_DONE_OFFSET) = 0;
> + drm_intel_bo_unmap(query->bo);
> + }
> +}
>
> /**
> * Wait on the query object's BO and calculate the final result.
> @@ -256,9 +280,7 @@ gen6_begin_query(struct gl_context *ctx, struct gl_query_object *q)
> struct brw_context *brw = brw_context(ctx);
> struct brw_query_object *query = (struct brw_query_object *)q;
>
> - /* Since we're starting a new query, we need to throw away old results. */
> - drm_intel_bo_unreference(query->bo);
> - query->bo = drm_intel_bo_alloc(brw->bufmgr, "query results", 4096, 4096);
> + brw_allocate_query_bo(brw, query);
>
> /* For ARB_query_buffer_object: The result is not available */
> set_query_availability(brw, query, false);
> --
> 2.8.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list