[Mesa-dev] [PATCH v2 03/12] winsys/amdgpu: Add support for const IB.

Marek Olšák maraeo at gmail.com
Sun Apr 17 22:06:01 UTC 2016


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

Marek

On Sun, Apr 17, 2016 at 1:43 AM, Bas Nieuwenhuizen
<bas at basnieuwenhuizen.nl> wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> v2: Use the correct IB to update request (Bas Nieuwenhuizen)
> v3: Add preamble IB. (Bas Nieuwenhuizen)
> ---
>  src/gallium/drivers/radeon/radeon_winsys.h | 30 ++++++++++
>  src/gallium/winsys/amdgpu/drm/amdgpu_cs.c  | 88 ++++++++++++++++++++++++++++--
>  src/gallium/winsys/amdgpu/drm/amdgpu_cs.h  | 11 +++-
>  3 files changed, 124 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h
> index aa94df6..451d8a4 100644
> --- a/src/gallium/drivers/radeon/radeon_winsys.h
> +++ b/src/gallium/drivers/radeon/radeon_winsys.h
> @@ -603,6 +603,36 @@ struct radeon_winsys {
>                                            void *flush_ctx);
>
>      /**
> +     * Add a constant engine IB to a graphics CS. This makes the graphics CS
> +     * from "cs_create" a group of two IBs that share a buffer list and are
> +     * flushed together.
> +     *
> +     * The returned constant CS is only a stream for writing packets to the new
> +     * IB. Calling other winsys functions with it is not allowed, not even
> +     * "cs_destroy".
> +     *
> +     * In order to add buffers and check memory usage, use the graphics CS.
> +     * In order to flush it, use the graphics CS, which will flush both IBs.
> +     * Destroying the graphics CS will destroy both of them.
> +     *
> +     * \param cs  The graphics CS from "cs_create" that will hold the buffer
> +     *            list and will be used for flushing.
> +     */
> +    struct radeon_winsys_cs *(*cs_add_const_ib)(struct radeon_winsys_cs *cs);
> +
> +     /**
> +     * Add a constant engine preamble IB to a graphics CS. This add an extra IB
> +     * in similar manner to cs_add_const_ib. This should always be called after
> +     * cs_add_const_ib.
> +     *
> +     * The returned IB is a constant engine IB that only gets flushed if the
> +     * context changed.
> +     *
> +     * \param cs  The graphics CS from "cs_create" that will hold the buffer
> +     *            list and will be used for flushing.
> +     */
> +    struct radeon_winsys_cs *(*cs_add_const_preamble_ib)(struct radeon_winsys_cs *cs);
> +    /**
>       * Destroy a command stream.
>       *
>       * \param cs        A command stream to destroy.
> diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
> index b0fe8b9..0182660 100644
> --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
> +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c
> @@ -350,19 +350,62 @@ amdgpu_cs_create(struct radeon_winsys_ctx *rwctx,
>        return NULL;
>     }
>
> -   if (!amdgpu_get_new_ib(&ctx->ws->base, &cs->main, &cs->ib)) {
> +   if (!amdgpu_get_new_ib(&ctx->ws->base, &cs->main, &cs->ib[IB_MAIN])) {
>        amdgpu_destroy_cs_context(cs);
>        FREE(cs);
>        return NULL;
>     }
>
>     cs->request.number_of_ibs = 1;
> -   cs->request.ibs = &cs->ib;
> +   cs->request.ibs = &cs->ib[IB_MAIN];
>
>     p_atomic_inc(&ctx->ws->num_cs);
>     return &cs->main.base;
>  }
>
> +static struct radeon_winsys_cs *
> +amdgpu_cs_add_const_ib(struct radeon_winsys_cs *rcs)
> +{
> +   struct amdgpu_cs *cs = (struct amdgpu_cs*)rcs;
> +   struct amdgpu_winsys *ws = cs->ctx->ws;
> +
> +   /* only one const IB can be added */
> +   if (cs->ring_type != RING_GFX || cs->const_ib.ib_mapped)
> +      return NULL;
> +
> +   if (!amdgpu_get_new_ib(&ws->base, &cs->const_ib, &cs->ib[IB_CONST]))
> +      return NULL;
> +
> +   cs->request.number_of_ibs = 2;
> +   cs->request.ibs = &cs->ib[IB_CONST];
> +   cs->ib[IB_CONST].flags = AMDGPU_IB_FLAG_CE;
> +
> +   return &cs->const_ib.base;
> +}
> +
> +static struct radeon_winsys_cs *
> +amdgpu_cs_add_const_preamble_ib(struct radeon_winsys_cs *rcs)
> +{
> +   struct amdgpu_cs *cs = (struct amdgpu_cs*)rcs;
> +   struct amdgpu_winsys *ws = cs->ctx->ws;
> +
> +   /* only one const preamble IB can be added and only when the const IB has
> +    * also been mapped */
> +   if (cs->ring_type != RING_GFX || !cs->const_ib.ib_mapped ||
> +       cs->const_preamble_ib.ib_mapped)
> +      return NULL;
> +
> +   if (!amdgpu_get_new_ib(&ws->base, &cs->const_preamble_ib,
> +                                 &cs->ib[IB_CONST_PREAMBLE], IB_CONST_PREAMBLE))
> +      return NULL;
> +
> +   cs->request.number_of_ibs = 3;
> +   cs->request.ibs = &cs->ib[IB_CONST_PREAMBLE];
> +   cs->ib[IB_CONST_PREAMBLE].flags = AMDGPU_IB_FLAG_CE | AMDGPU_IB_FLAG_PREAMBLE;
> +
> +   return &cs->const_preamble_ib.base;
> +}
> +
>  #define OUT_CS(cs, value) (cs)->buf[(cs)->cdw++] = (value)
>
>  int amdgpu_lookup_buffer(struct amdgpu_cs *cs, struct amdgpu_winsys_bo *bo)
> @@ -621,6 +664,15 @@ static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
>        /* pad GFX ring to 8 DWs to meet CP fetch alignment requirements */
>        while (rcs->cdw & 7)
>           OUT_CS(rcs, 0xffff1000); /* type3 nop packet */
> +
> +      /* Also pad the const IB. */
> +      if (cs->const_ib.ib_mapped)
> +         while (!cs->const_ib.base.cdw || (cs->const_ib.base.cdw & 7))
> +            OUT_CS(&cs->const_ib.base, 0xffff1000); /* type3 nop packet */
> +
> +      if (cs->const_preamble_ib.ib_mapped)
> +         while (!cs->const_preamble_ib.base.cdw || (cs->const_preamble_ib.base.cdw & 7))
> +            OUT_CS(&cs->const_preamble_ib.base, 0xffff1000);
>        break;
>     case RING_UVD:
>        while (rcs->cdw & 15)
> @@ -637,6 +689,14 @@ static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
>     amdgpu_cs_add_buffer(rcs, cs->main.big_ib_buffer,
>                          RADEON_USAGE_READ, 0, RADEON_PRIO_IB1);
>
> +   if (cs->const_ib.ib_mapped)
> +      amdgpu_cs_add_buffer(rcs, cs->const_ib.big_ib_buffer,
> +                           RADEON_USAGE_READ, 0, RADEON_PRIO_IB1);
> +
> +   if (cs->const_preamble_ib.ib_mapped)
> +      amdgpu_cs_add_buffer(rcs, cs->const_preamble_ib.big_ib_buffer,
> +                           RADEON_USAGE_READ, 0, RADEON_PRIO_IB1);
> +
>     /* If the CS is not empty or overflowed.... */
>     if (cs->main.base.cdw && cs->main.base.cdw <= cs->main.base.max_dw && !debug_get_option_noop()) {
>        int r;
> @@ -677,9 +737,19 @@ static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
>          goto cleanup;
>        }
>
> -      cs->ib.size = cs->main.base.cdw;
> +      cs->ib[IB_MAIN].size = cs->main.base.cdw;
>        cs->main.used_ib_space += cs->main.base.cdw * 4;
>
> +      if (cs->const_ib.ib_mapped) {
> +         cs->ib[IB_CONST].size = cs->const_ib.base.cdw;
> +         cs->const_ib.used_ib_space += cs->const_ib.base.cdw * 4;
> +      }
> +
> +      if (cs->const_preamble_ib.ib_mapped) {
> +         cs->ib[IB_CONST_PREAMBLE].size = cs->const_preamble_ib.base.cdw;
> +         cs->const_preamble_ib.used_ib_space += cs->const_preamble_ib.base.cdw * 4;
> +      }
> +
>        amdgpu_cs_do_submission(cs, fence);
>
>        /* Cleanup. */
> @@ -689,7 +759,13 @@ static void amdgpu_cs_flush(struct radeon_winsys_cs *rcs,
>
>  cleanup:
>     amdgpu_cs_context_cleanup(cs);
> -   amdgpu_get_new_ib(&ws->base, &cs->main, &cs->ib);
> +
> +   amdgpu_get_new_ib(&ws->base, &cs->main, &cs->ib[IB_MAIN]);
> +   if (cs->const_ib.ib_mapped)
> +      amdgpu_get_new_ib(&ws->base, &cs->const_ib, &cs->ib[IB_CONST]);
> +   if (cs->const_preamble_ib.ib_mapped)
> +      amdgpu_get_new_ib(&ws->base, &cs->const_preamble_ib,
> +                                 &cs->ib[IB_CONST_PREAMBLE]);
>
>     ws->num_cs_flushes++;
>  }
> @@ -701,6 +777,8 @@ static void amdgpu_cs_destroy(struct radeon_winsys_cs *rcs)
>     amdgpu_destroy_cs_context(cs);
>     p_atomic_dec(&cs->ctx->ws->num_cs);
>     pb_reference(&cs->main.big_ib_buffer, NULL);
> +   pb_reference(&cs->const_ib.big_ib_buffer, NULL);
> +   pb_reference(&cs->const_preamble_ib.big_ib_buffer, NULL);
>     FREE(cs);
>  }
>
> @@ -720,6 +798,8 @@ void amdgpu_cs_init_functions(struct amdgpu_winsys *ws)
>     ws->base.ctx_destroy = amdgpu_ctx_destroy;
>     ws->base.ctx_query_reset_status = amdgpu_ctx_query_reset_status;
>     ws->base.cs_create = amdgpu_cs_create;
> +   ws->base.cs_add_const_ib = amdgpu_cs_add_const_ib;
> +   ws->base.cs_add_const_preamble_ib = amdgpu_cs_add_const_preamble_ib;
>     ws->base.cs_destroy = amdgpu_cs_destroy;
>     ws->base.cs_add_buffer = amdgpu_cs_add_buffer;
>     ws->base.cs_lookup_buffer = amdgpu_cs_lookup_buffer;
> diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
> index 888b85b..4ed830b 100644
> --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
> +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
> @@ -59,8 +59,17 @@ struct amdgpu_ib {
>     unsigned                used_ib_space;
>  };
>
> +enum {
> +   IB_CONST_PREAMBLE = 0,
> +   IB_CONST = 1, /* the const IB must be first */
> +   IB_MAIN = 2,
> +   IB_NUM
> +};
> +
>  struct amdgpu_cs {
>     struct amdgpu_ib main; /* must be first because this is inherited */
> +   struct amdgpu_ib const_ib; /* optional constant engine IB */
> +   struct amdgpu_ib const_preamble_ib;
>     struct amdgpu_ctx *ctx;
>
>     /* Flush CS. */
> @@ -70,7 +79,7 @@ struct amdgpu_cs {
>     /* amdgpu_cs_submit parameters */
>     enum ring_type              ring_type;
>     struct amdgpu_cs_request    request;
> -   struct amdgpu_cs_ib_info    ib;
> +   struct amdgpu_cs_ib_info    ib[IB_NUM];
>
>     /* Buffers. */
>     unsigned                    max_num_buffers;
> --
> 2.8.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list