[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