[Mesa-dev] [PATCH 2/2] r600, compute: setup RATs for write-only images

Marek Olšák maraeo at gmail.com
Thu Aug 13 14:23:48 PDT 2015


On Mon, Aug 10, 2015 at 8:32 PM, Zoltan Gilian <zoltan.gilian at gmail.com> wrote:
> ---
>  src/gallium/drivers/r600/evergreen_compute.c | 101 ++++++++++++++++-----------
>  src/gallium/drivers/r600/evergreen_state.c   |  44 +++++++++++-
>  src/gallium/drivers/r600/r600_pipe.h         |   4 +-
>  src/gallium/drivers/radeon/r600_texture.c    |   1 +
>  4 files changed, 109 insertions(+), 41 deletions(-)
>
> diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
> index 8b27a66..6f39507 100644
> --- a/src/gallium/drivers/r600/evergreen_compute.c
> +++ b/src/gallium/drivers/r600/evergreen_compute.c
> @@ -99,8 +99,39 @@ struct r600_resource* r600_compute_buffer_alloc_vram(
>         return (struct r600_resource *)buffer;
>  }
>
> +static void evergreen_set_cbuf(
> +       struct r600_context *ctx,
> +       unsigned id,
> +       struct pipe_surface *surf)
> +{
> +       struct pipe_framebuffer_state *state = &ctx->framebuffer.state;
> +
> +       /* Add the RAT to the list of color buffers */
> +       state->cbufs[id] = surf;
> +
> +       /* Update the number of color buffers */
> +       state->nr_cbufs = MAX2(id + 1, state->nr_cbufs);
> +
> +       /* Update the cb_target_mask
> +        * XXX: I think this is a potential spot for bugs once we start doing
> +        * GL interop.  cb_target_mask may be modified in the 3D sections
> +        * of this driver. */
> +       ctx->compute_cb_target_mask |= (0xf << (id << 2));

CB_TARGET_MASK is ignored by RATs and should be set to 0 for all
compute resources.

> +}
> +
> +static void evergreen_unset_cbuf(
> +       struct r600_context *ctx,
> +       unsigned id)
> +{
> +       struct pipe_framebuffer_state *state = &ctx->framebuffer.state;
> +
> +       state->cbufs[id] = NULL;
> +       ctx->compute_cb_target_mask &= ~(0xf << (id << 2));
> +       /* nr_cbufs = ceil(last_bit / 4) */
> +       state->nr_cbufs = (util_last_bit(ctx->compute_cb_target_mask) + 3) >> 2;
> +}
>
> -static void evergreen_set_rat(
> +static void evergreen_set_rat_buf(
>         struct r600_context *ctx,
>         unsigned id,
>         struct r600_resource* bo,
> @@ -123,23 +154,11 @@ static void evergreen_set_rat(
>         rat_templ.u.tex.first_layer = 0;
>         rat_templ.u.tex.last_layer = 0;
>
> -       /* Add the RAT the list of color buffers */
> -       ctx->framebuffer.state.cbufs[id] = ctx->b.b.create_surface(
> -               (struct pipe_context *)ctx,
> -               (struct pipe_resource *)bo, &rat_templ);
> -
> -       /* Update the number of color buffers */
> -       ctx->framebuffer.state.nr_cbufs =
> -               MAX2(id + 1, ctx->framebuffer.state.nr_cbufs);
> -
> -       /* Update the cb_target_mask
> -        * XXX: I think this is a potential spot for bugs once we start doing
> -        * GL interop.  cb_target_mask may be modified in the 3D sections
> -        * of this driver. */
> -       ctx->compute_cb_target_mask |= (0xf << (id * 4));
> +       evergreen_set_cbuf(ctx, id, ctx->b.b.create_surface(
> +               (struct pipe_context *)ctx, (struct pipe_resource *)bo, &rat_templ));
>
>         surf = (struct r600_surface*)ctx->framebuffer.state.cbufs[id];
> -       evergreen_init_color_surface_rat(rctx, surf);
> +       evergreen_init_color_surface_rat_buf(ctx, surf);
>  }
>
>  static void evergreen_cs_set_vertex_buffer(
> @@ -623,32 +642,34 @@ static void evergreen_set_compute_resources(struct pipe_context * ctx_,
>                 struct pipe_surface ** surfaces)
>  {
>         struct r600_context *ctx = (struct r600_context *)ctx_;
> -       struct r600_surface **resources = (struct r600_surface **)surfaces;
> +       struct pipe_surface *surf = NULL;
>
>         COMPUTE_DBG(ctx->screen, "*** evergreen_set_compute_resources: start = %u count = %u\n",
>                         start, count);
>
> +       if (!surfaces) {
> +               for (unsigned i = 0; i < count; ++i)
> +                       evergreen_unset_cbuf(ctx, 1 + i);
> +               return;
> +       }
> +
>         for (unsigned i = 0; i < count; i++) {
> -               /* The First two vertex buffers are reserved for parameters and
> -                * global buffers. */
> -               unsigned vtx_id = 2 + i;
> -               if (resources[i]) {
> -                       struct r600_resource_global *buffer =
> -                               (struct r600_resource_global*)
> -                               resources[i]->base.texture;
> -                       if (resources[i]->base.writable) {
> -                               assert(i+1 < 12);
> -
> -                               evergreen_set_rat(ctx->cs_shader_state.shader, i+1,
> -                               (struct r600_resource *)resources[i]->base.texture,
> -                               buffer->chunk->start_in_dw*4,
> -                               resources[i]->base.texture->width0);
> -                       }
> -
> -                       evergreen_cs_set_vertex_buffer(ctx, vtx_id,
> -                                       buffer->chunk->start_in_dw * 4,
> -                                       resources[i]->base.texture);
> -               }
> +               surf = surfaces[i];
> +               if (!surf)
> +                       continue;
> +
> +               /* XXX: Implement constant buffers. */
> +               assert(surf->writable &&
> +                      "Constant buffer compute resources are not supported yet.");
> +
> +               /* It is assumed, that surface[i]->texture contains an r600_texture. */
> +
> +               /* The first RAT is reserved for global buffers. */
> +               unsigned rat_id = 1 + i;
> +               assert(rat_id < 12);
> +
> +               evergreen_set_cbuf(ctx, rat_id, surf);
> +               evergreen_init_color_surface_rat_tex(ctx, (struct r600_surface *)surf);
>         }
>  }
>
> @@ -686,7 +707,9 @@ static void evergreen_set_global_binding(
>                         first, n);
>
>         if (!resources) {
> -               /* XXX: Unset */
> +               /* evergreen_set_rat_buf creates a new surface. */
> +               ctx_->surface_destroy(ctx_, ctx->framebuffer.state.cbufs[0]);
> +               evergreen_unset_cbuf(ctx, 0);
>                 return;
>         }
>
> @@ -717,7 +740,7 @@ static void evergreen_set_global_binding(
>                 *(handles[i]) = util_cpu_to_le32(handle);
>         }
>
> -       evergreen_set_rat(ctx, 0, pool->bo, 0, pool->size_in_dw * 4);
> +       evergreen_set_rat_buf(ctx, 0, pool->bo, 0, pool->size_in_dw * 4);
>         evergreen_cs_set_vertex_buffer(ctx, 1, 0,
>                                 (struct pipe_resource*)pool->bo);
>  }
> diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
> index f479698..688a092 100644
> --- a/src/gallium/drivers/r600/evergreen_state.c
> +++ b/src/gallium/drivers/r600/evergreen_state.c
> @@ -45,6 +45,31 @@ static inline unsigned evergreen_array_mode(unsigned mode)
>         }
>  }
>
> +static inline unsigned evergreen_resource_type(enum pipe_texture_target target)
> +{
> +       switch (target) {
> +       case PIPE_BUFFER:
> +               return V_028C70_BUFFER;
> +       case PIPE_TEXTURE_1D:
> +               return V_028C70_TEXTURE1D;
> +       case PIPE_TEXTURE_RECT:
> +       case PIPE_TEXTURE_2D:
> +               return V_028C70_TEXTURE2D;
> +       case PIPE_TEXTURE_3D:
> +               return V_028C70_TEXTURE3D;
> +       case PIPE_TEXTURE_1D_ARRAY:
> +               return V_028C70_TEXTURE1DARRAY;
> +       case PIPE_TEXTURE_2D_ARRAY:
> +               return V_028C70_TEXTURE2DARRAY;
> +       case PIPE_TEXTURE_CUBE:
> +       case PIPE_TEXTURE_CUBE_ARRAY:
> +               assert(0 && "Can't assign CB_COLOR_INFO resource type to "
> +                           "PIPE_TEXTURE_CUBE or PIPE_TEXTURE_CUBE_ARRAY.");
> +       default:
> +               assert(0 && "Unknown pipe texture target.");
> +       }
> +}
> +
>  static uint32_t eg_num_banks(uint32_t nbanks)
>  {
>         switch (nbanks) {
> @@ -923,7 +948,7 @@ static void evergreen_emit_scissor_state(struct r600_context *rctx, struct r600_
>   * to be used for 1D aligned buffers that do not have an associated
>   * radeon_surf.
>   */
> -void evergreen_init_color_surface_rat(struct r600_context *rctx,
> +void evergreen_init_color_surface_rat_buf(struct r600_context *rctx,
>                                         struct r600_surface *surf)
>  {
>         struct pipe_resource *pipe_buffer = surf->base.texture;
> @@ -961,6 +986,7 @@ void evergreen_init_color_surface_rat(struct r600_context *rctx,
>                 | S_028C70_BLEND_BYPASS(1) /* We must set this bit because we
>                                             * are using NUMBER_UINT */
>                 | S_028C70_RAT(1)
> +               | S_028C70_RESOURCE_TYPE(V_028C70_BUFFER)
>                 ;
>
>         surf->cb_color_attrib = S_028C74_NON_DISP_TILING_ORDER(1);
> @@ -977,6 +1003,19 @@ void evergreen_init_color_surface_rat(struct r600_context *rctx,
>         surf->cb_color_fmask_slice = 0;
>  }
>
> +void evergreen_init_color_surface_rat_tex(struct r600_context *rctx,
> +                                          struct r600_surface *surf)
> +{
> +       struct r600_texture *tex = (struct r600_texture *)surf->base.texture;
> +
> +       evergreen_init_color_surface(rctx, surf);
> +
> +       surf->cb_color_info |= S_028C70_RAT(1) |
> +               S_028C70_RESOURCE_TYPE(evergreen_resource_type(
> +                       tex->resource.b.b.target));
> +       util_range_add(&tex->resource.valid_buffer_range, 0, tex->size);

You can remove util_range_add here. It's only required for buffers.

Marek


More information about the mesa-dev mailing list