[Mesa-dev] [PATCH v2] radeonsi: fix query buffer allocation
Marek Olšák
maraeo at gmail.com
Mon Feb 25 21:43:27 UTC 2019
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Marek
On Sun, Feb 24, 2019 at 6:56 PM Timothy Arceri <tarceri at itsqueeze.com>
wrote:
> Fix the logic for buffer full check on alloc.
>
> This patch just takes the fix Nicolai attached to the bug report
> and updates it to work on master.
>
> Fixes: e0f0d3675d4 ("radeonsi: factor si_query_buffer logic out of
> si_query_hw")
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109561
> ---
> src/gallium/drivers/radeonsi/si_query.c | 52 ++++++++++++++-----------
> src/gallium/drivers/radeonsi/si_query.h | 5 ++-
> 2 files changed, 32 insertions(+), 25 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_query.c
> b/src/gallium/drivers/radeonsi/si_query.c
> index 266b9d3ce84..280eee3a280 100644
> --- a/src/gallium/drivers/radeonsi/si_query.c
> +++ b/src/gallium/drivers/radeonsi/si_query.c
> @@ -549,11 +549,15 @@ void si_query_buffer_reset(struct si_context *sctx,
> struct si_query_buffer *buff
> }
> 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 {
> + buffer->unprepared = true;
> }
> }
>
> @@ -561,29 +565,31 @@ bool si_query_buffer_alloc(struct si_context *sctx,
> struct si_query_buffer *buff
> bool (*prepare_buffer)(struct si_context *,
> struct si_query_buffer*),
> unsigned size)
> {
> - if (buffer->buf && buffer->results_end + size >=
> buffer->buf->b.b.width0)
> - return true;
> + bool unprepared = buffer->unprepared;
> + buffer->unprepared = false;
> +
> + if (!buffer->buf || buffer->results_end + size >
> buffer->buf->b.b.width0) {
> + 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;
>
> - if (buffer->buf) {
> - struct si_query_buffer *qbuf =
> MALLOC_STRUCT(si_query_buffer);
> - memcpy(qbuf, buffer, sizeof(*qbuf));
> - buffer->previous = qbuf;
> + /* Queries are normally read by the CPU after
> + * being written by the gpu, hence staging is probably a
> good
> + * usage pattern.
> + */
> + struct si_screen *screen = sctx->screen;
> + unsigned buf_size = MAX2(size,
> screen->info.min_alloc_size);
> + buffer->buf = si_resource(
> + pipe_buffer_create(&screen->b, 0,
> PIPE_USAGE_STAGING, buf_size));
> + if (unlikely(!buffer->buf))
> + return false;
> + unprepared = true;
> }
>
> - buffer->results_end = 0;
> -
> - /* Queries are normally read by the CPU after
> - * being written by the gpu, hence staging is probably a good
> - * usage pattern.
> - */
> - struct si_screen *screen = sctx->screen;
> - unsigned buf_size = MAX2(size, screen->info.min_alloc_size);
> - buffer->buf = si_resource(
> - pipe_buffer_create(&screen->b, 0, PIPE_USAGE_STAGING,
> buf_size));
> - if (unlikely(!buffer->buf))
> - return false;
> -
> - if (prepare_buffer) {
> + if (unprepared && prepare_buffer) {
> if (unlikely(!prepare_buffer(sctx, buffer))) {
> si_resource_reference(&buffer->buf, NULL);
> return false;
> diff --git a/src/gallium/drivers/radeonsi/si_query.h
> b/src/gallium/drivers/radeonsi/si_query.h
> index aaf0bd03aca..c61af51d57c 100644
> --- a/src/gallium/drivers/radeonsi/si_query.h
> +++ b/src/gallium/drivers/radeonsi/si_query.h
> @@ -177,12 +177,13 @@ struct si_query_hw_ops {
> struct si_query_buffer {
> /* The buffer where query results are stored. */
> struct si_resource *buf;
> - /* 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;
> + /* Offset of the next free result after current query data */
> + unsigned results_end;
> + bool unprepared;
> };
>
> void si_query_buffer_destroy(struct si_screen *sctx, struct
> si_query_buffer *buffer);
> --
> 2.20.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20190225/fdd5742f/attachment.html>
More information about the mesa-dev
mailing list