X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fgen6_queryobj.c;h=de71bb565f53cb35ff9c93ec4ab97fe8650dda77;hb=8776b1b14b229d110f283f5da8c3c36261068ede;hp=3013513b9c2ad3ad01bf5a71c4bebe0d08c36710;hpb=ed8edd71759043ec433bcde599bb9cd28a477273;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/gen6_queryobj.c b/src/mesa/drivers/dri/i965/gen6_queryobj.c index 3013513b9c2..de71bb565f5 100644 --- a/src/mesa/drivers/dri/i965/gen6_queryobj.c +++ b/src/mesa/drivers/dri/i965/gen6_queryobj.c @@ -121,20 +121,7 @@ gen6_queryobj_get_results(struct gl_context *ctx, if (query->bo == NULL) return; - /* If the application has requested the query result, but this batch is - * still contributing to it, flush it now so the results will be present - * when mapped. - */ - if (drm_intel_bo_references(brw->batch.bo, query->bo)) - intel_batchbuffer_flush(brw); - - if (unlikely(brw->perf_debug)) { - if (drm_intel_bo_busy(query->bo)) { - perf_debug("Stalling on the GPU waiting for a query object.\n"); - } - } - - drm_intel_bo_map(query->bo, false); + brw_bo_map(brw, query->bo, false, "query object"); uint64_t *results = query->bo->virtual; switch (query->Base.Target) { case GL_TIME_ELAPSED: @@ -294,6 +281,27 @@ gen6_end_query(struct gl_context *ctx, struct gl_query_object *q) default: unreachable("Unrecognized query target in brw_end_query()"); } + + /* The current batch contains the commands to handle EndQuery(), + * but they won't actually execute until it is flushed. + */ + query->flushed = false; +} + +/** + * Flush the batch if it still references the query object BO. + */ +static void +flush_batch_if_needed(struct brw_context *brw, struct brw_query_object *query) +{ + /* If the batch doesn't reference the BO, it must have been flushed + * (for example, due to being full). Record that it's been flushed. + */ + query->flushed = query->flushed || + !drm_intel_bo_references(brw->batch.bo, query->bo); + + if (!query->flushed) + intel_batchbuffer_flush(brw); } /** @@ -304,8 +312,15 @@ gen6_end_query(struct gl_context *ctx, struct gl_query_object *q) */ static void gen6_wait_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; + /* If the application has requested the query result, but this batch is + * still contributing to it, flush it now to finish that work so the + * result will become available (eventually). + */ + flush_batch_if_needed(brw, query); + gen6_queryobj_get_results(ctx, query); } @@ -320,6 +335,12 @@ static void gen6_check_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; + /* If query->bo is NULL, we've already gathered the results - this is a + * redundant CheckQuery call. Ignore it. + */ + if (query->bo == NULL) + return; + /* From the GL_ARB_occlusion_query spec: * * "Instead of allowing for an infinite loop, performing a @@ -327,10 +348,9 @@ static void gen6_check_query(struct gl_context *ctx, struct gl_query_object *q) * not ready yet on the first time it is queried. This ensures that * the async query will return true in finite time. */ - if (query->bo && drm_intel_bo_references(brw->batch.bo, query->bo)) - intel_batchbuffer_flush(brw); + flush_batch_if_needed(brw, query); - if (query->bo == NULL || !drm_intel_bo_busy(query->bo)) { + if (!drm_intel_bo_busy(query->bo)) { gen6_queryobj_get_results(ctx, query); } }