[Mesa-dev] [PATCH v2 06/10] i965: Map the query results for the life of the bo

Chris Wilson chris at chris-wilson.co.uk
Mon Jun 19 10:55:05 UTC 2017


If we map the bo upon creation, we can avoid the latency of mmapping it
when querying, and later use the asynchronous, persistent map of the
predicate to do a quick query.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Kenneth Graunke <kenneth at whitecape.org>
Cc: Matt Turner <mattst88 at gmail.com>
---
 src/mesa/drivers/dri/i965/brw_bufmgr.c    | 15 +++++++++++++
 src/mesa/drivers/dri/i965/brw_bufmgr.h    |  2 ++
 src/mesa/drivers/dri/i965/brw_context.h   |  1 +
 src/mesa/drivers/dri/i965/gen6_queryobj.c | 37 ++++++++++++++++++++++---------
 4 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.c b/src/mesa/drivers/dri/i965/brw_bufmgr.c
index f847220843..7af3725640 100644
--- a/src/mesa/drivers/dri/i965/brw_bufmgr.c
+++ b/src/mesa/drivers/dri/i965/brw_bufmgr.c
@@ -815,6 +815,21 @@ brw_bo_map(struct brw_context *brw, struct brw_bo *bo, unsigned flags)
       return brw_bo_map_gtt(brw, bo, flags);
 }
 
+void
+brw_bo_map_sync(struct brw_context *brw, struct brw_bo *bo, unsigned flags)
+{
+   unsigned domain;
+
+   if (bo->tiling_mode != I915_TILING_NONE && !(flags & MAP_RAW))
+      domain = I915_GEM_DOMAIN_GTT;
+   else if (can_map_cpu(bo, flags))
+      domain = I915_GEM_DOMAIN_CPU;
+   else
+      domain = I915_GEM_DOMAIN_GTT;
+
+   set_domain(brw, __func__, bo, domain, flags & MAP_WRITE ? domain : 0);
+}
+
 int
 brw_bo_unmap(struct brw_bo *bo)
 {
diff --git a/src/mesa/drivers/dri/i965/brw_bufmgr.h b/src/mesa/drivers/dri/i965/brw_bufmgr.h
index 1582119a24..9a0f2e4f3b 100644
--- a/src/mesa/drivers/dri/i965/brw_bufmgr.h
+++ b/src/mesa/drivers/dri/i965/brw_bufmgr.h
@@ -229,6 +229,8 @@ void brw_bo_unreference(struct brw_bo *bo);
  */
 MUST_CHECK void *brw_bo_map(struct brw_context *brw, struct brw_bo *bo, unsigned flags);
 
+void brw_bo_map_sync(struct brw_context *brw, struct brw_bo *bo, unsigned flags);
+
 /**
  * Reduces the refcount on the userspace mapping of the buffer
  * object.
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index fe04adb2d4..5a5d261009 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -419,6 +419,7 @@ struct brw_query_object {
 
    /** Last query BO associated with this query. */
    struct brw_bo *bo;
+   uint64_t *results;
 
    /** Last index in bo with query data for this object. */
    int last_index;
diff --git a/src/mesa/drivers/dri/i965/gen6_queryobj.c b/src/mesa/drivers/dri/i965/gen6_queryobj.c
index a0b786f5d9..e0a02972bd 100644
--- a/src/mesa/drivers/dri/i965/gen6_queryobj.c
+++ b/src/mesa/drivers/dri/i965/gen6_queryobj.c
@@ -221,7 +221,9 @@ gen6_queryobj_get_results(struct gl_context *ctx,
    if (query->bo == NULL)
       return;
 
-   uint64_t *results = brw_bo_map(brw, query->bo, MAP_READ);
+   brw_bo_map_sync(brw, query->bo, MAP_READ | MAP_COHERENT);
+   uint64_t *results = query->results;
+
    switch (query->Base.Target) {
    case GL_TIME_ELAPSED:
       /* The query BO contains the starting and ending timestamps.
@@ -296,7 +298,6 @@ gen6_queryobj_get_results(struct gl_context *ctx,
    default:
       unreachable("Unrecognized query target in brw_queryobj_get_results()");
    }
-   brw_bo_unmap(query->bo);
 
    /* Now that we've processed the data stored in the query's buffer object,
     * we can release it.
@@ -307,6 +308,23 @@ gen6_queryobj_get_results(struct gl_context *ctx,
    query->Base.Ready = true;
 }
 
+static int
+gen6_alloc_query(struct brw_context *brw, struct brw_query_object *query)
+{
+   /* Since we're starting a new query, we need to throw away old results. */
+   if (query->bo)
+      brw_bo_unreference(query->bo);
+
+   query->bo = brw_bo_alloc(brw->bufmgr, "query results", 4096, 4096);
+   query->results = brw_bo_map(brw, query->bo,
+                               MAP_READ | MAP_COHERENT | MAP_ASYNC);
+
+   /* For ARB_query_buffer_object: The result is not available */
+   set_query_availability(brw, query, false);
+
+   return 0;
+}
+
 /**
  * Driver hook for glBeginQuery().
  *
@@ -318,14 +336,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;
-   const int idx = GEN6_QUERY_RESULTS;
-
-   /* Since we're starting a new query, we need to throw away old results. */
-   brw_bo_unreference(query->bo);
-   query->bo = brw_bo_alloc(brw->bufmgr, "query results", 4096, 4096);
-
-   /* For ARB_query_buffer_object: The result is not available */
-   set_query_availability(brw, query, false);
+   const int idx = gen6_alloc_query(brw, query) + GEN6_QUERY_RESULTS;
 
    switch (query->Base.Target) {
    case GL_TIME_ELAPSED:
@@ -539,8 +550,12 @@ gen6_query_counter(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;
-   brw_query_counter(ctx, 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);
+
+   query->flushed = false;
 }
 
 /* Initialize Gen6+-specific query object functions. */
-- 
2.11.0



More information about the mesa-dev mailing list