diff --git a/src/gallium/drivers/freedreno/freedreno_batch_cache.c b/src/gallium/drivers/freedreno/freedreno_batch_cache.c index 9028f0a5d25..a8ce3101d67 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch_cache.c +++ b/src/gallium/drivers/freedreno/freedreno_batch_cache.c @@ -440,6 +440,34 @@ alloc_batch_locked(struct fd_batch_cache *cache, struct fd_context *ctx, return batch; } +static void +alloc_query_buf(struct fd_context *ctx, struct fd_batch *batch) +{ + if (batch->query_buf) + return; + + if ((ctx->screen->gen < 3) || (ctx->screen->gen > 4)) + return; + + /* For gens that use fd_hw_query, pre-allocate an initially zero-sized + * (unbacked) query buffer. This simplifies draw/grid/etc-time resource + * tracking. + */ + struct pipe_screen *pscreen = &ctx->screen->base; + struct pipe_resource templ = { + .target = PIPE_BUFFER, + .format = PIPE_FORMAT_R8_UNORM, + .bind = PIPE_BIND_QUERY_BUFFER, + .width0 = 0, /* create initially zero size buffer */ + .height0 = 1, + .depth0 = 1, + .array_size = 1, + .last_level = 0, + .nr_samples = 1, + }; + batch->query_buf = pscreen->resource_create(pscreen, &templ); +} + struct fd_batch * fd_bc_alloc_batch(struct fd_context *ctx, bool nondraw) { @@ -457,6 +485,8 @@ fd_bc_alloc_batch(struct fd_context *ctx, bool nondraw) batch = alloc_batch_locked(cache, ctx, nondraw); fd_screen_unlock(ctx->screen); + alloc_query_buf(ctx, batch); + if (batch && nondraw) fd_context_switch_to(ctx, batch); @@ -552,6 +582,8 @@ fd_batch_from_fb(struct fd_context *ctx, struct fd_batch *batch = batch_from_key(ctx, key); fd_screen_unlock(ctx->screen); + alloc_query_buf(ctx, batch); + fd_batch_set_fb(batch, pfb); return batch; diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index 872b642dfb7..f94a6fa7b54 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -234,13 +234,8 @@ batch_draw_tracking(struct fd_batch *batch, const struct pipe_draw_info *info, { struct fd_context *ctx = batch->ctx; - /* NOTE: needs to be before resource_written(batch->query_buf), otherwise - * query_buf may not be created yet. - */ - fd_batch_update_queries(batch); - if (!needs_draw_tracking(batch, info, indirect)) - return; + goto out; /* * Figure out the buffers/features we need: @@ -268,6 +263,9 @@ batch_draw_tracking(struct fd_batch *batch, const struct pipe_draw_info *info, resource_written(batch, batch->query_buf); fd_screen_unlock(ctx->screen); + +out: + fd_batch_update_queries(batch); } static void @@ -585,11 +583,6 @@ fd_launch_grid(struct pipe_context *pctx, fd_batch_reference(&save_batch, ctx->batch); fd_batch_reference(&ctx->batch, batch); - /* NOTE: needs to be before resource_written(batch->query_buf), otherwise - * query_buf may not be created yet. - */ - fd_batch_update_queries(batch); - fd_screen_lock(ctx->screen); /* Mark SSBOs */ @@ -636,6 +629,8 @@ fd_launch_grid(struct pipe_context *pctx, fd_screen_unlock(ctx->screen); + fd_batch_update_queries(batch); + DBG("%p: work_dim=%u, block=%ux%ux%u, grid=%ux%ux%u", batch, info->work_dim, info->block[0], info->block[1], info->block[2], diff --git a/src/gallium/drivers/freedreno/freedreno_query_hw.c b/src/gallium/drivers/freedreno/freedreno_query_hw.c index d709c8f255f..6ed0582dada 100644 --- a/src/gallium/drivers/freedreno/freedreno_query_hw.c +++ b/src/gallium/drivers/freedreno/freedreno_query_hw.c @@ -299,22 +299,6 @@ fd_hw_sample_init(struct fd_batch *batch, uint32_t size) samp->tile_stride = 0; batch->next_sample_offset += size; - if (!batch->query_buf) { - struct pipe_screen *pscreen = &batch->ctx->screen->base; - struct pipe_resource templ = { - .target = PIPE_BUFFER, - .format = PIPE_FORMAT_R8_UNORM, - .bind = PIPE_BIND_QUERY_BUFFER, - .width0 = 0, /* create initially zero size buffer */ - .height0 = 1, - .depth0 = 1, - .array_size = 1, - .last_level = 0, - .nr_samples = 1, - }; - batch->query_buf = pscreen->resource_create(pscreen, &templ); - } - pipe_resource_reference(&samp->prsc, batch->query_buf); return samp;