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 <ch...@chris-wilson.co.uk> Cc: Kenneth Graunke <kenn...@whitecape.org> Cc: Matt Turner <matts...@gmail.com> --- src/mesa/drivers/dri/i965/brw_context.c | 4 +++ 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 | 46 +++++++++++++++++++++++++------ 4 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index d0b22d4342..5cf5a67432 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -860,6 +860,8 @@ brwCreateContext(gl_api api, brw->isl_dev = screen->isl_dev; + brw->query.last_index = 4096; + brw->vs.base.stage = MESA_SHADER_VERTEX; brw->tcs.base.stage = MESA_SHADER_TESS_CTRL; brw->tes.base.stage = MESA_SHADER_TESS_EVAL; @@ -1047,6 +1049,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 b415013e47..376bcbb399 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -423,7 +423,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; @@ -435,13 +435,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 { @@ -1103,6 +1103,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 04ce9a94ca..8b14c72176 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 c6887661a5..25ea51503e 100644 --- a/src/mesa/drivers/dri/i965/gen6_queryobj.c +++ b/src/mesa/drivers/dri/i965/gen6_queryobj.c @@ -303,21 +303,51 @@ 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_COHERENT | MAP_PERSISTENT | + MAP_READ | MAP_WRITE); + + 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_COHERENT | MAP_PERSISTENT | + MAP_READ | MAP_WRITE); + brw->query.last_index = 0; + } - query->results = brw_bo_map(brw, query->bo, - MAP_COHERENT | MAP_PERSISTENT | - MAP_READ | MAP_WRITE); + 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; } /** @@ -413,7 +443,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.13.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev