<div dir="ltr"><div>Reviewed-by: Marek Olšák <<a href="mailto:marek.olsak@amd.com">marek.olsak@amd.com</a>></div><div><br></div><div>Marek<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Feb 24, 2019 at 6:56 PM Timothy Arceri <<a href="mailto:tarceri@itsqueeze.com">tarceri@itsqueeze.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Fix the logic for buffer full check on alloc.<br>
<br>
This patch just takes the fix Nicolai attached to the bug report<br>
and updates it to work on master.<br>
<br>
Fixes: e0f0d3675d4 ("radeonsi: factor si_query_buffer logic out of si_query_hw")<br>
Bugzilla: <a href="https://bugs.freedesktop.org/show_bug.cgi?id=109561" rel="noreferrer" target="_blank">https://bugs.freedesktop.org/show_bug.cgi?id=109561</a><br>
---<br>
 src/gallium/drivers/radeonsi/si_query.c | 52 ++++++++++++++-----------<br>
 src/gallium/drivers/radeonsi/si_query.h |  5 ++-<br>
 2 files changed, 32 insertions(+), 25 deletions(-)<br>
<br>
diff --git a/src/gallium/drivers/radeonsi/si_query.c b/src/gallium/drivers/radeonsi/si_query.c<br>
index 266b9d3ce84..280eee3a280 100644<br>
--- a/src/gallium/drivers/radeonsi/si_query.c<br>
+++ b/src/gallium/drivers/radeonsi/si_query.c<br>
@@ -549,11 +549,15 @@ void si_query_buffer_reset(struct si_context *sctx, struct si_query_buffer *buff<br>
        }<br>
        buffer->results_end = 0;<br>
<br>
+       if (!buffer->buf)<br>
+               return;<br>
+<br>
        /* Discard even the oldest buffer if it can't be mapped without a stall. */<br>
-       if (buffer->buf &&<br>
-           (si_rings_is_buffer_referenced(sctx, buffer->buf->buf, RADEON_USAGE_READWRITE) ||<br>
-            !sctx->ws->buffer_wait(buffer->buf->buf, 0, RADEON_USAGE_READWRITE))) {<br>
+       if (si_rings_is_buffer_referenced(sctx, buffer->buf->buf, RADEON_USAGE_READWRITE) ||<br>
+           !sctx->ws->buffer_wait(buffer->buf->buf, 0, RADEON_USAGE_READWRITE)) {<br>
                si_resource_reference(&buffer->buf, NULL);<br>
+       } else {<br>
+               buffer->unprepared = true;<br>
        }<br>
 }<br>
<br>
@@ -561,29 +565,31 @@ bool si_query_buffer_alloc(struct si_context *sctx, struct si_query_buffer *buff<br>
                           bool (*prepare_buffer)(struct si_context *, struct si_query_buffer*),<br>
                           unsigned size)<br>
 {<br>
-       if (buffer->buf && buffer->results_end + size >= buffer->buf->b.b.width0)<br>
-               return true;<br>
+       bool unprepared = buffer->unprepared;<br>
+       buffer->unprepared = false;<br>
+<br>
+       if (!buffer->buf || buffer->results_end + size > buffer->buf->b.b.width0) {<br>
+               if (buffer->buf) {<br>
+                       struct si_query_buffer *qbuf = MALLOC_STRUCT(si_query_buffer);<br>
+                       memcpy(qbuf, buffer, sizeof(*qbuf));<br>
+                       buffer->previous = qbuf;<br>
+               }<br>
+               buffer->results_end = 0;<br>
<br>
-       if (buffer->buf) {<br>
-               struct si_query_buffer *qbuf = MALLOC_STRUCT(si_query_buffer);<br>
-               memcpy(qbuf, buffer, sizeof(*qbuf));<br>
-               buffer->previous = qbuf;<br>
+               /* Queries are normally read by the CPU after<br>
+                * being written by the gpu, hence staging is probably a good<br>
+                * usage pattern.<br>
+                */<br>
+               struct si_screen *screen = sctx->screen;<br>
+               unsigned buf_size = MAX2(size, screen->info.min_alloc_size);<br>
+               buffer->buf = si_resource(<br>
+                       pipe_buffer_create(&screen->b, 0, PIPE_USAGE_STAGING, buf_size));<br>
+               if (unlikely(!buffer->buf))<br>
+                       return false;<br>
+               unprepared = true;<br>
        }<br>
<br>
-       buffer->results_end = 0;<br>
-<br>
-       /* Queries are normally read by the CPU after<br>
-        * being written by the gpu, hence staging is probably a good<br>
-        * usage pattern.<br>
-        */<br>
-       struct si_screen *screen = sctx->screen;<br>
-       unsigned buf_size = MAX2(size, screen->info.min_alloc_size);<br>
-       buffer->buf = si_resource(<br>
-               pipe_buffer_create(&screen->b, 0, PIPE_USAGE_STAGING, buf_size));<br>
-       if (unlikely(!buffer->buf))<br>
-               return false;<br>
-<br>
-       if (prepare_buffer) {<br>
+       if (unprepared && prepare_buffer) {<br>
                if (unlikely(!prepare_buffer(sctx, buffer))) {<br>
                        si_resource_reference(&buffer->buf, NULL);<br>
                        return false;<br>
diff --git a/src/gallium/drivers/radeonsi/si_query.h b/src/gallium/drivers/radeonsi/si_query.h<br>
index aaf0bd03aca..c61af51d57c 100644<br>
--- a/src/gallium/drivers/radeonsi/si_query.h<br>
+++ b/src/gallium/drivers/radeonsi/si_query.h<br>
@@ -177,12 +177,13 @@ struct si_query_hw_ops {<br>
 struct si_query_buffer {<br>
        /* The buffer where query results are stored. */<br>
        struct si_resource              *buf;<br>
-       /* Offset of the next free result after current query data */<br>
-       unsigned                        results_end;<br>
        /* If a query buffer is full, a new buffer is created and the old one<br>
         * is put in here. When we calculate the result, we sum up the samples<br>
         * from all buffers. */<br>
        struct si_query_buffer  *previous;<br>
+       /* Offset of the next free result after current query data */<br>
+       unsigned                        results_end;<br>
+       bool unprepared;<br>
 };<br>
<br>
 void si_query_buffer_destroy(struct si_screen *sctx, struct si_query_buffer *buffer);<br>
-- <br>
2.20.1<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a></blockquote></div>