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 | 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 6d27866fce..a0c0eb71d9 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -959,6 +959,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; @@ -1147,6 +1148,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 44e0d31c6d..32e92d9a2a 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; @@ -433,13 +433,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 { @@ -1085,6 +1085,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 a7b896243d..37c9d8fd0e 100644 --- a/src/mesa/drivers/dri/i965/brw_queryobj.c +++ b/src/mesa/drivers/dri/i965/brw_queryobj.c @@ -177,7 +177,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; @@ -187,7 +187,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; @@ -291,7 +291,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; @@ -423,7 +423,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 @@ -434,7 +434,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; } } @@ -475,7 +475,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; } @@ -497,10 +497,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 ae7fd06c1c..08b9312714 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 | MAP_ASYNC); + 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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev