[Mesa-dev] [PATCH] radeonsi: re-initialize query buffers if they are reused
Dieter Nützel
Dieter at nuetzel-hh.de
Tue Feb 12 04:38:29 UTC 2019
Tested-by: Dieter Nützel <Dieter at nuetzel-hh.de>
Calmed mostly some hiccups with Rocket League which our son found around
XMass on Polaris. All was fine after additional Mesa git clean ups.
Thanks,
Dieter
Am 26.01.2019 01:58, schrieb Marek Olšák:
> 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);
More information about the mesa-dev
mailing list