From: Marek Olšák <marek.ol...@amd.com> Fixes: e0f0d3675d4 "radeonsi: factor si_query_buffer logic out of si_query_hw" --- src/gallium/drivers/radeonsi/si_query.c | 20 ++++++++++++++++---- src/gallium/drivers/radeonsi/si_query.h | 1 + 2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_query.c b/src/gallium/drivers/radeonsi/si_query.c index 266b9d3ce84..c115e7787b2 100644 --- a/src/gallium/drivers/radeonsi/si_query.c +++ b/src/gallium/drivers/radeonsi/si_query.c @@ -542,34 +542,46 @@ void si_query_buffer_reset(struct si_context *sctx, struct si_query_buffer *buff while (buffer->previous) { struct si_query_buffer *qbuf = buffer->previous; buffer->previous = qbuf->previous; si_resource_reference(&buffer->buf, NULL); buffer->buf = qbuf->buf; /* move ownership */ FREE(qbuf); } buffer->results_end = 0; + if (!buffer->buf) + return; + /* Discard even the oldest buffer if it can't be mapped without a stall. */ - if (buffer->buf && - (si_rings_is_buffer_referenced(sctx, buffer->buf->buf, RADEON_USAGE_READWRITE) || - !sctx->ws->buffer_wait(buffer->buf->buf, 0, RADEON_USAGE_READWRITE))) { + if (si_rings_is_buffer_referenced(sctx, buffer->buf->buf, RADEON_USAGE_READWRITE) || + !sctx->ws->buffer_wait(buffer->buf->buf, 0, RADEON_USAGE_READWRITE)) { si_resource_reference(&buffer->buf, NULL); + } else { + /* Re-initialize it before begin. */ + buffer->prepare_buffer_before_begin = true; } } bool si_query_buffer_alloc(struct si_context *sctx, struct si_query_buffer *buffer, bool (*prepare_buffer)(struct si_context *, struct si_query_buffer*), unsigned size) { - if (buffer->buf && buffer->results_end + size >= buffer->buf->b.b.width0) + if (buffer->buf && buffer->results_end + size >= buffer->buf->b.b.width0) { + if (buffer->prepare_buffer_before_begin && + prepare_buffer && unlikely(!prepare_buffer(sctx, buffer))) { + si_resource_reference(&buffer->buf, NULL); + return false; + } + buffer->prepare_buffer_before_begin = false; return true; + } if (buffer->buf) { struct si_query_buffer *qbuf = MALLOC_STRUCT(si_query_buffer); memcpy(qbuf, buffer, sizeof(*qbuf)); buffer->previous = qbuf; } buffer->results_end = 0; /* Queries are normally read by the CPU after diff --git a/src/gallium/drivers/radeonsi/si_query.h b/src/gallium/drivers/radeonsi/si_query.h index aaf0bd03aca..be393c2fbd2 100644 --- a/src/gallium/drivers/radeonsi/si_query.h +++ b/src/gallium/drivers/radeonsi/si_query.h @@ -170,20 +170,21 @@ struct si_query_hw_ops { struct si_resource *buffer, uint64_t va); void (*clear_result)(struct si_query_hw *, union pipe_query_result *); void (*add_result)(struct si_screen *screen, struct si_query_hw *, void *buffer, union pipe_query_result *result); }; struct si_query_buffer { /* The buffer where query results are stored. */ struct si_resource *buf; + bool prepare_buffer_before_begin; /* Offset of the next free result after current query data */ unsigned results_end; /* If a query buffer is full, a new buffer is created and the old one * is put in here. When we calculate the result, we sum up the samples * from all buffers. */ struct si_query_buffer *previous; }; void si_query_buffer_destroy(struct si_screen *sctx, struct si_query_buffer *buffer); void si_query_buffer_reset(struct si_context *sctx, struct si_query_buffer *buffer); -- 2.17.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev