[Mesa-dev] [PATCH v2 09/10] i965: Pack simple pipelined query objects into the same buffer
Chris Wilson
chris at chris-wilson.co.uk
Mon Jun 19 10:55:08 UTC 2017
Reuse the same query object buffer for multiple queries within the same
batch.
A task for the future is propagating the GL_NO_MEMORY errors.
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_context.c | 3 +++
src/mesa/drivers/dri/i965/brw_context.h | 10 ++++---
src/mesa/drivers/dri/i965/brw_queryobj.c | 16 +++++------
src/mesa/drivers/dri/i965/gen6_queryobj.c | 44 ++++++++++++++++++++++++++-----
4 files changed, 55 insertions(+), 18 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 157d8550de..1d418bfac4 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -960,6 +960,7 @@ brwCreateContext(gl_api api,
brw->has_swizzling = screen->hw_has_swizzling;
isl_device_init(&brw->isl_dev, devinfo, screen->hw_has_swizzling);
+ brw->query.last_index = 4096;
brw->vs.base.stage = MESA_SHADER_VERTEX;
brw->tcs.base.stage = MESA_SHADER_TESS_CTRL;
@@ -1148,6 +1149,8 @@ intelDestroyContext(__DRIcontext * driContextPriv)
brw_bo_unreference(brw->gs.base.scratch_bo);
if (brw->wm.base.scratch_bo)
brw_bo_unreference(brw->wm.base.scratch_bo);
+ if (brw->query.bo)
+ brw_bo_unreference(brw->query.bo);
brw_destroy_hw_context(brw->bufmgr, brw->hw_ctx);
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index cc30dbcf51..7206f8fead 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -422,7 +422,7 @@ struct brw_query_object {
uint64_t *results;
/** Last index in bo with query data for this object. */
- int last_index;
+ unsigned index;
/** True if we know the batch has been flushed since we ended the query. */
bool flushed;
@@ -434,13 +434,13 @@ struct brw_query_object {
static inline unsigned
gen6_query_predicate_offset(const struct brw_query_object *query)
{
- return GEN6_QUERY_PREDICATE * sizeof(uint64_t);
+ return (query->index + GEN6_QUERY_PREDICATE) * sizeof(uint64_t);
}
static inline unsigned
gen6_query_results_offset(const struct brw_query_object *query, unsigned idx)
{
- return (GEN6_QUERY_RESULTS + idx) * sizeof(uint64_t);
+ return (query->index + GEN6_QUERY_RESULTS + idx) * sizeof(uint64_t);
}
enum brw_gpu_ring {
@@ -1077,6 +1077,10 @@ struct brw_context
} cc;
struct {
+ struct brw_bo *bo;
+ uint64_t *map;
+ unsigned last_index;
+
struct brw_query_object *obj;
bool begin_emitted;
} query;
diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c
index bccd33b9d3..964ebf7572 100644
--- a/src/mesa/drivers/dri/i965/brw_queryobj.c
+++ b/src/mesa/drivers/dri/i965/brw_queryobj.c
@@ -184,7 +184,7 @@ brw_queryobj_get_results(struct gl_context *ctx,
* run out of space in the query's BO and allocated a new one. If so,
* this function was already called to accumulate the results so far.
*/
- for (i = 0; i < query->last_index; i++) {
+ for (i = 0; i < query->index; i++) {
query->Base.Result += results[i * 2 + 1] - results[i * 2];
}
break;
@@ -194,7 +194,7 @@ brw_queryobj_get_results(struct gl_context *ctx,
/* If the starting and ending PS_DEPTH_COUNT from any of the batches
* differ, then some fragments passed the depth test.
*/
- for (i = 0; i < query->last_index; i++) {
+ for (i = 0; i < query->index; i++) {
if (results[i * 2 + 1] != results[i * 2]) {
query->Base.Result = GL_TRUE;
break;
@@ -298,7 +298,7 @@ brw_begin_query(struct gl_context *ctx, struct gl_query_object *q)
*/
brw_bo_unreference(query->bo);
query->bo = NULL;
- query->last_index = -1;
+ query->index = -1;
brw->query.obj = query;
@@ -430,7 +430,7 @@ ensure_bo_has_space(struct gl_context *ctx, struct brw_query_object *query)
assert(brw->gen < 6);
- if (!query->bo || query->last_index * 2 + 1 >= 4096 / sizeof(uint64_t)) {
+ if (!query->bo || query->index * 2 + 1 >= 4096 / sizeof(uint64_t)) {
if (query->bo != NULL) {
/* The old query BO did not have enough space, so we allocated a new
@@ -441,7 +441,7 @@ ensure_bo_has_space(struct gl_context *ctx, struct brw_query_object *query)
}
query->bo = brw_bo_alloc(brw->bufmgr, "query", 4096, 1);
- query->last_index = 0;
+ query->index = 0;
}
}
@@ -482,7 +482,7 @@ brw_emit_query_begin(struct brw_context *brw)
ensure_bo_has_space(ctx, query);
- brw_write_depth_count(brw, query->bo, query->last_index * 2);
+ brw_write_depth_count(brw, query->bo, query->index * 2);
brw->query.begin_emitted = true;
}
@@ -504,10 +504,10 @@ brw_emit_query_end(struct brw_context *brw)
if (!brw->query.begin_emitted)
return;
- brw_write_depth_count(brw, query->bo, query->last_index * 2 + 1);
+ brw_write_depth_count(brw, query->bo, query->index * 2 + 1);
brw->query.begin_emitted = false;
- query->last_index++;
+ query->index++;
}
/**
diff --git a/src/mesa/drivers/dri/i965/gen6_queryobj.c b/src/mesa/drivers/dri/i965/gen6_queryobj.c
index aee3b2ae14..1d739c7b86 100644
--- a/src/mesa/drivers/dri/i965/gen6_queryobj.c
+++ b/src/mesa/drivers/dri/i965/gen6_queryobj.c
@@ -298,20 +298,50 @@ gen6_queryobj_get_results(struct gl_context *ctx,
static int
gen6_alloc_query(struct brw_context *brw, struct brw_query_object *query)
{
+ int idx;
+
/* 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);
- brw_bo_set_cache_coherent(query->bo);
+ if (!brw_is_query_pipelined(query)) {
+ /* Non-pipecontrol queries may be large so give each their own page */
+ query->bo = brw_bo_alloc(brw->bufmgr, "query results", 4096, 4096);
+ brw_bo_set_cache_coherent(query->bo);
+
+ query->results =
+ brw_bo_map(brw, query->bo,
+ MAP_READ | MAP_WRITE | MAP_COHERENT);
+
+ idx = 0;
+ } else {
+ /* Pack small queries in the same batch together into a common buffer */
+ if (brw->query.last_index > 4096/sizeof(uint64_t) - 3 ||
+ !brw->query.bo->idle) {
+ if (brw->query.bo)
+ brw_bo_unreference(brw->query.bo);
+
+ brw->query.bo = brw_bo_alloc(brw->bufmgr, "query results", 4096, 4096);
+ brw_bo_set_cache_coherent(brw->query.bo);
+
+ brw->query.map =
+ brw_bo_map(brw, brw->query.bo, MAP_READ | MAP_WRITE | MAP_COHERENT);
+ brw->query.last_index = 0;
+ }
- query->results = brw_bo_map(brw, query->bo,
- MAP_READ | MAP_WRITE | MAP_COHERENT);
+ idx = brw->query.last_index;
+ brw->query.last_index += 3;
+
+ query->bo = brw->query.bo;
+ brw_bo_reference(brw->query.bo);
+
+ query->results = brw->query.map + idx;
+ }
/* For ARB_query_buffer_object: The result is not available */
query->results[GEN6_QUERY_PREDICATE] = false;
-
- return 0;
+ query->index = idx;
+ return idx;
}
/**
@@ -407,7 +437,7 @@ gen6_end_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 + 1;
+ const int idx = query->index + GEN6_QUERY_RESULTS + 1;
switch (query->Base.Target) {
case GL_TIME_ELAPSED:
--
2.11.0
More information about the mesa-dev
mailing list