[Mesa-dev] [PATCH] radeonsi: re-initialize query buffers if they are reused

Marek Olšák maraeo at gmail.com
Sat Jan 26 00:58:30 UTC 2019


From: Marek Olšák <marek.olsak at 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



More information about the mesa-dev mailing list