diff options
author | Timothy Arceri <[email protected]> | 2019-02-25 10:55:57 +1100 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2019-02-26 09:55:41 +1100 |
commit | 603206d0a61628deba3f0754324d4b7f382effe5 (patch) | |
tree | 79934723dae4c509cc2c65385108d2ce86c3b300 /src/gallium/drivers/radeonsi/si_query.c | |
parent | 7c1bf075f30527ec9724fe03f0a32d9110bebd0b (diff) |
radeonsi: fix query buffer allocation
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")
Reviewed-by: Marek Olšák <[email protected]>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109561
Diffstat (limited to 'src/gallium/drivers/radeonsi/si_query.c')
-rw-r--r-- | src/gallium/drivers/radeonsi/si_query.c | 52 |
1 files changed, 29 insertions, 23 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; |