[Mesa-dev] [PATCH 2/2] radeon: re-prepare query buffers on begin_query for predicate queries

Marek Olšák maraeo at gmail.com
Fri Nov 20 12:15:30 PST 2015


For the series:

Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Fri, Nov 20, 2015 at 5:38 PM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> The point of prepare_buffer is to ensure that the query buffer contains valid
> initial data for conditional rendering: as long as the buffer is initialized
> correctly, the GPU is able to tell whether query results have been written
> already (and wait or fall back to unconditional rendering if desired).
>
> This means prepare_buffer needs to be called again when a buffer is reused.
>
> Conversely, for queries that cannot be used for conditional rendering
> (notably pipeline statistics), we can re-use buffers immediately, and they
> do not need to be initialized.
> ---
>  src/gallium/drivers/radeon/r600_query.c | 32 +++++++++++++++++---------------
>  src/gallium/drivers/radeon/r600_query.h |  1 +
>  2 files changed, 18 insertions(+), 15 deletions(-)
>
> diff --git a/src/gallium/drivers/radeon/r600_query.c b/src/gallium/drivers/radeon/r600_query.c
> index 4726b78..fb974c7 100644
> --- a/src/gallium/drivers/radeon/r600_query.c
> +++ b/src/gallium/drivers/radeon/r600_query.c
> @@ -242,7 +242,7 @@ static struct r600_resource *r600_new_query_buffer(struct r600_common_context *c
>                 pipe_buffer_create(ctx->b.screen, PIPE_BIND_CUSTOM,
>                                    PIPE_USAGE_STAGING, buf_size);
>
> -       if (query->ops->prepare_buffer)
> +       if (query->flags & R600_QUERY_HW_FLAG_PREDICATE)
>                 query->ops->prepare_buffer(ctx, query, buf);
>
>         return buf;
> @@ -251,15 +251,11 @@ static struct r600_resource *r600_new_query_buffer(struct r600_common_context *c
>  static void r600_query_hw_prepare_buffer(struct r600_common_context *ctx,
>                                          struct r600_query_hw *query,
>                                          struct r600_resource *buffer)
> - {
> -       uint32_t *results;
> -
> -       if (query->b.type == PIPE_QUERY_TIME_ELAPSED ||
> -           query->b.type == PIPE_QUERY_TIMESTAMP)
> -               return;
> -
> -       results = r600_buffer_map_sync_with_rings(ctx, buffer,
> -                                                 PIPE_TRANSFER_WRITE);
> +{
> +       /* Callers ensure that the buffer is currently unused by the GPU. */
> +       uint32_t *results = ctx->ws->buffer_map(buffer->cs_buf, NULL,
> +                                               PIPE_TRANSFER_WRITE |
> +                                               PIPE_TRANSFER_UNSYNCHRONIZED);
>
>         memset(results, 0, buffer->b.b.width0);
>
> @@ -339,6 +335,7 @@ static struct pipe_query *r600_query_hw_create(struct r600_common_context *rctx,
>                 query->result_size = 16 * rctx->max_db;
>                 query->num_cs_dw_begin = 6;
>                 query->num_cs_dw_end = 6;
> +               query->flags |= R600_QUERY_HW_FLAG_PREDICATE;
>                 break;
>         case PIPE_QUERY_TIME_ELAPSED:
>                 query->result_size = 16;
> @@ -361,6 +358,7 @@ static struct pipe_query *r600_query_hw_create(struct r600_common_context *rctx,
>                 query->num_cs_dw_begin = 6;
>                 query->num_cs_dw_end = 6;
>                 query->stream = index;
> +               query->flags |= R600_QUERY_HW_FLAG_PREDICATE;
>                 break;
>         case PIPE_QUERY_PIPELINE_STATISTICS:
>                 /* 11 values on EG, 8 on R600. */
> @@ -667,11 +665,15 @@ static void r600_query_hw_reset_buffers(struct r600_common_context *rctx,
>                 FREE(qbuf);
>         }
>
> -       /* Obtain a new buffer if the current one can't be mapped without a stall. */
> -       if (r600_rings_is_buffer_referenced(rctx, query->buffer.buf->cs_buf, RADEON_USAGE_READWRITE) ||
> -           !rctx->ws->buffer_wait(query->buffer.buf->buf, 0, RADEON_USAGE_READWRITE)) {
> -               pipe_resource_reference((struct pipe_resource**)&query->buffer.buf, NULL);
> -               query->buffer.buf = r600_new_query_buffer(rctx, query);
> +       if (query->flags & R600_QUERY_HW_FLAG_PREDICATE) {
> +               /* Obtain a new buffer if the current one can't be mapped without a stall. */
> +               if (r600_rings_is_buffer_referenced(rctx, query->buffer.buf->cs_buf, RADEON_USAGE_READWRITE) ||
> +                   !rctx->ws->buffer_wait(query->buffer.buf->buf, 0, RADEON_USAGE_READWRITE)) {
> +                       pipe_resource_reference((struct pipe_resource**)&query->buffer.buf, NULL);
> +                       query->buffer.buf = r600_new_query_buffer(rctx, query);
> +               } else {
> +                       query->ops->prepare_buffer(rctx, query, query->buffer.buf);
> +               }
>         }
>
>         query->buffer.results_end = 0;
> diff --git a/src/gallium/drivers/radeon/r600_query.h b/src/gallium/drivers/radeon/r600_query.h
> index 5d12191..b20beec 100644
> --- a/src/gallium/drivers/radeon/r600_query.h
> +++ b/src/gallium/drivers/radeon/r600_query.h
> @@ -75,6 +75,7 @@ struct r600_query {
>  enum {
>         R600_QUERY_HW_FLAG_NO_START = (1 << 0),
>         R600_QUERY_HW_FLAG_TIMER = (1 << 1),
> +       R600_QUERY_HW_FLAG_PREDICATE = (1 << 2),
>  };
>
>  struct r600_query_hw_ops {
> --
> 2.5.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list