[Mesa-dev] [PATCH 03/10] radeonsi: set some image descriptor fields at bind time

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Tue May 31 23:18:35 UTC 2016


On Thu, May 19, 2016 at 12:59 PM, Marek Olšák <maraeo at gmail.com> wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> mainly the fields that can change by reallocating a texture and changing
> the tile mode
> ---
>  src/gallium/drivers/radeonsi/si_descriptors.c | 64 +++++++++++++----
>  src/gallium/drivers/radeonsi/si_pipe.h        |  3 +
>  src/gallium/drivers/radeonsi/si_state.c       | 99 ++++++++++++---------------
>  src/gallium/drivers/radeonsi/si_state.h       | 16 ++++-
>  4 files changed, 111 insertions(+), 71 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
> index 855b79e..48b1e14 100644
> --- a/src/gallium/drivers/radeonsi/si_descriptors.c
> +++ b/src/gallium/drivers/radeonsi/si_descriptors.c
> @@ -60,6 +60,7 @@
>  #include "si_shader.h"
>  #include "sid.h"
>
> +#include "util/u_format.h"
>  #include "util/u_math.h"
>  #include "util/u_memory.h"
>  #include "util/u_suballoc.h"
> @@ -294,40 +295,70 @@ static void si_sampler_views_begin_new_cs(struct si_context *sctx,
>                               RADEON_USAGE_READWRITE, RADEON_PRIO_DESCRIPTORS);
>  }
>
> +void si_set_mutable_tex_desc_fields(struct r600_texture *tex,
> +                                   const struct radeon_surf_level *base_level_info,
> +                                   unsigned base_level, unsigned block_width,
> +                                   bool is_stencil, uint32_t *state)
> +{
> +       uint64_t va = tex->resource.gpu_address + base_level_info->offset;
> +       unsigned pitch = base_level_info->nblk_x * block_width;
> +
> +       state[1] &= C_008F14_BASE_ADDRESS_HI;
> +       state[3] &= C_008F1C_TILING_INDEX;
> +       state[4] &= C_008F20_PITCH;
> +       state[6] &= C_008F28_COMPRESSION_EN;

Aren't these fields cleared already? Either way, the series is

Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>

with the v2 of patch 10.

> +
> +       state[0] = va >> 8;
> +       state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);
> +       state[3] |= S_008F1C_TILING_INDEX(si_tile_mode_index(tex, base_level,
> +                                                            is_stencil));
> +       state[4] |= S_008F20_PITCH(pitch - 1);
> +
> +       if (tex->dcc_offset) {
> +               state[6] |= S_008F28_COMPRESSION_EN(1);
> +               state[7] = (tex->resource.gpu_address +
> +                           tex->dcc_offset +
> +                           base_level_info->dcc_offset) >> 8;
> +       }
> +}
> +
>  static void si_set_sampler_view(struct si_context *sctx,
>                                 struct si_sampler_views *views,
>                                 unsigned slot, struct pipe_sampler_view *view)
>  {
>         struct si_sampler_view *rview = (struct si_sampler_view*)view;
>
> -       if (view && view->texture && view->texture->target != PIPE_BUFFER &&
> -           G_008F28_COMPRESSION_EN(rview->state[6]) &&
> -           ((struct r600_texture*)view->texture)->dcc_offset == 0) {
> -               rview->state[6] &= C_008F28_COMPRESSION_EN &
> -                                  C_008F28_ALPHA_IS_ON_MSB;
> -       } else if (views->views[slot] == view)
> +       if (views->views[slot] == view)
>                 return;
>
>         if (view) {
>                 struct r600_texture *rtex = (struct r600_texture *)view->texture;
> +               uint32_t *desc = views->desc.list + slot * 16;
>
>                 si_sampler_view_add_buffer(sctx, view->texture,
>                                            RADEON_USAGE_READ);
>
>                 pipe_sampler_view_reference(&views->views[slot], view);
> -               memcpy(views->desc.list + slot * 16, rview->state, 8*4);
> +               memcpy(desc, rview->state, 8*4);
> +
> +               if (view->texture && view->texture->target != PIPE_BUFFER)
> +                       si_set_mutable_tex_desc_fields(rtex,
> +                                                      rview->base_level_info,
> +                                                      rview->base_level,
> +                                                      rview->block_width,
> +                                                      false, desc);
>
>                 if (view->texture && view->texture->target != PIPE_BUFFER &&
>                     rtex->fmask.size) {
> -                       memcpy(views->desc.list + slot*16 + 8,
> +                       memcpy(desc + 8,
>                                rview->fmask_state, 8*4);
>                 } else {
>                         /* Disable FMASK and bind sampler state in [12:15]. */
> -                       memcpy(views->desc.list + slot*16 + 8,
> +                       memcpy(desc + 8,
>                                null_texture_descriptor, 4*4);
>
>                         if (views->sampler_states[slot])
> -                               memcpy(views->desc.list + slot*16 + 12,
> +                               memcpy(desc + 12,
>                                        views->sampler_states[slot], 4*4);
>                 }
>
> @@ -513,6 +544,7 @@ si_set_shader_images(struct pipe_context *pipe, unsigned shader,
>                         struct r600_texture *tex = (struct r600_texture *)res;
>                         unsigned level;
>                         unsigned width, height, depth;
> +                       uint32_t *desc = images->desc.list + slot * 8;
>
>                         assert(!tex->is_depth);
>                         assert(tex->fmask.size == 0);
> @@ -538,13 +570,17 @@ si_set_shader_images(struct pipe_context *pipe, unsigned shader,
>                         height = u_minify(res->b.b.height0, level);
>                         depth = u_minify(res->b.b.depth0, level);
>
> -                       si_make_texture_descriptor(screen, tex, false, res->b.b.target,
> +                       si_make_texture_descriptor(screen, tex,
> +                                                  false, res->b.b.target,
>                                                    views[i].format, swizzle,
> -                                                  level, 0, 0,
> +                                                  0, 0,
>                                                    views[i].u.tex.first_layer, views[i].u.tex.last_layer,
>                                                    width, height, depth,
> -                                                  images->desc.list + slot * 8,
> -                                                  NULL);
> +                                                  desc, NULL);
> +                       si_set_mutable_tex_desc_fields(tex, tex->surface.level,
> +                                                      level,
> +                                                      util_format_get_blockwidth(views[i].format),
> +                                                      false, desc);
>                 }
>
>                 images->desc.enabled_mask |= 1u << slot;
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
> index 33d3d25..89f4f51 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.h
> +++ b/src/gallium/drivers/radeonsi/si_pipe.h
> @@ -121,6 +121,9 @@ struct si_sampler_view {
>           * [4..7] = buffer descriptor */
>         uint32_t                        state[8];
>         uint32_t                        fmask_state[8];
> +       const struct radeon_surf_level  *base_level_info;
> +       unsigned                        base_level;
> +       unsigned                        block_width;
>         bool is_stencil_sampler;
>  };
>
> diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
> index aefa336..45b4021 100644
> --- a/src/gallium/drivers/radeonsi/si_state.c
> +++ b/src/gallium/drivers/radeonsi/si_state.c
> @@ -1834,19 +1834,6 @@ boolean si_is_format_supported(struct pipe_screen *screen,
>         return retval == usage;
>  }
>
> -static unsigned si_tile_mode_index(struct r600_texture *rtex, unsigned level,
> -                                  bool stencil)
> -{
> -       unsigned tile_mode_index = 0;
> -
> -       if (stencil) {
> -               tile_mode_index = rtex->surface.stencil_tiling_index[level];
> -       } else {
> -               tile_mode_index = rtex->surface.tiling_index[level];
> -       }
> -       return tile_mode_index;
> -}
> -
>  /*
>   * framebuffer handling
>   */
> @@ -2619,42 +2606,19 @@ si_make_texture_descriptor(struct si_screen *screen,
>                            enum pipe_texture_target target,
>                            enum pipe_format pipe_format,
>                            const unsigned char state_swizzle[4],
> -                          unsigned base_level, unsigned first_level, unsigned last_level,
> +                          unsigned first_level, unsigned last_level,
>                            unsigned first_layer, unsigned last_layer,
>                            unsigned width, unsigned height, unsigned depth,
>                            uint32_t *state,
>                            uint32_t *fmask_state)
>  {
>         struct pipe_resource *res = &tex->resource.b.b;
> -       const struct radeon_surf_level *surflevel = tex->surface.level;
>         const struct util_format_description *desc;
>         unsigned char swizzle[4];
>         int first_non_void;
>         unsigned num_format, data_format, type;
> -       uint32_t pitch;
>         uint64_t va;
>
> -       /* Texturing with separate depth and stencil. */
> -       if (tex->is_depth && !tex->is_flushing_texture) {
> -               switch (pipe_format) {
> -               case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
> -                       pipe_format = PIPE_FORMAT_Z32_FLOAT;
> -                       break;
> -               case PIPE_FORMAT_X8Z24_UNORM:
> -               case PIPE_FORMAT_S8_UINT_Z24_UNORM:
> -                       /* Z24 is always stored like this. */
> -                       pipe_format = PIPE_FORMAT_Z24X8_UNORM;
> -                       break;
> -               case PIPE_FORMAT_X24S8_UINT:
> -               case PIPE_FORMAT_S8X24_UINT:
> -               case PIPE_FORMAT_X32_S8X24_UINT:
> -                       pipe_format = PIPE_FORMAT_S8_UINT;
> -                       surflevel = tex->surface.stencil_level;
> -                       break;
> -               default:;
> -               }
> -       }
> -
>         desc = util_format_description(pipe_format);
>
>         if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
> @@ -2774,12 +2738,8 @@ si_make_texture_descriptor(struct si_screen *screen,
>         } else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
>                 depth = res->array_size / 6;
>
> -       pitch = surflevel[base_level].nblk_x * util_format_get_blockwidth(pipe_format);
> -       va = tex->resource.gpu_address + surflevel[base_level].offset;
> -
> -       state[0] = va >> 8;
> -       state[1] = (S_008F14_BASE_ADDRESS_HI(va >> 40) |
> -                   S_008F14_DATA_FORMAT(data_format) |
> +       state[0] = 0;
> +       state[1] = (S_008F14_DATA_FORMAT(data_format) |
>                     S_008F14_NUM_FORMAT(num_format));
>         state[2] = (S_008F18_WIDTH(width - 1) |
>                     S_008F18_HEIGHT(height - 1));
> @@ -2792,24 +2752,19 @@ si_make_texture_descriptor(struct si_screen *screen,
>                     S_008F1C_LAST_LEVEL(res->nr_samples > 1 ?
>                                         util_logbase2(res->nr_samples) :
>                                         last_level) |
> -                   S_008F1C_TILING_INDEX(si_tile_mode_index(tex, base_level, false)) |
>                     S_008F1C_POW2_PAD(res->last_level > 0) |
>                     S_008F1C_TYPE(type));
> -       state[4] = (S_008F20_DEPTH(depth - 1) | S_008F20_PITCH(pitch - 1));
> +       state[4] = S_008F20_DEPTH(depth - 1);
>         state[5] = (S_008F24_BASE_ARRAY(first_layer) |
>                     S_008F24_LAST_ARRAY(last_layer));
> +       state[6] = 0;
> +       state[7] = 0;
>
>         if (tex->dcc_offset) {
>                 unsigned swap = r600_translate_colorswap(pipe_format, FALSE);
>
> -               state[6] = S_008F28_COMPRESSION_EN(1) | S_008F28_ALPHA_IS_ON_MSB(swap <= 1);
> -               state[7] = (tex->resource.gpu_address +
> -                           tex->dcc_offset +
> -                           surflevel[base_level].dcc_offset) >> 8;
> +               state[6] = S_008F28_ALPHA_IS_ON_MSB(swap <= 1);
>         } else {
> -               state[6] = 0;
> -               state[7] = 0;
> -
>                 /* The last dword is unused by hw. The shader uses it to clear
>                  * bits in the first dword of sampler state.
>                  */
> @@ -2887,6 +2842,8 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
>         unsigned char state_swizzle[4];
>         unsigned height, depth, width;
>         unsigned last_layer = state->u.tex.last_layer;
> +       enum pipe_format pipe_format;
> +       const struct radeon_surf_level *surflevel;
>
>         if (!view)
>                 return NULL;
> @@ -2958,13 +2915,40 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
>             state->target == PIPE_TEXTURE_CUBE)
>                 last_layer = state->u.tex.first_layer;
>
> -       si_make_texture_descriptor(sctx->screen, tmp, true, state->target,
> -                                  state->format, state_swizzle,
> -                                  base_level, first_level, last_level,
> +       /* Texturing with separate depth and stencil. */
> +       pipe_format = state->format;
> +       surflevel = tmp->surface.level;
> +
> +       if (tmp->is_depth && !tmp->is_flushing_texture) {
> +               switch (pipe_format) {
> +               case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
> +                       pipe_format = PIPE_FORMAT_Z32_FLOAT;
> +                       break;
> +               case PIPE_FORMAT_X8Z24_UNORM:
> +               case PIPE_FORMAT_S8_UINT_Z24_UNORM:
> +                       /* Z24 is always stored like this. */
> +                       pipe_format = PIPE_FORMAT_Z24X8_UNORM;
> +                       break;
> +               case PIPE_FORMAT_X24S8_UINT:
> +               case PIPE_FORMAT_S8X24_UINT:
> +               case PIPE_FORMAT_X32_S8X24_UINT:
> +                       pipe_format = PIPE_FORMAT_S8_UINT;
> +                       surflevel = tmp->surface.stencil_level;
> +                       break;
> +               default:;
> +               }
> +       }
> +
> +       si_make_texture_descriptor(sctx->screen, tmp, true,
> +                                  state->target, pipe_format, state_swizzle,
> +                                  first_level, last_level,
>                                    state->u.tex.first_layer, last_layer,
>                                    width, height, depth,
>                                    view->state, view->fmask_state);
>
> +       view->base_level_info = &surflevel[base_level];
> +       view->base_level = base_level;
> +       view->block_width = util_format_get_blockwidth(pipe_format);
>         return &view->base;
>  }
>
> @@ -3438,11 +3422,14 @@ static void si_query_opaque_metadata(struct r600_common_screen *rscreen,
>
>         si_make_texture_descriptor(sscreen, rtex, true,
>                                    res->target, res->format,
> -                                  swizzle, 0, 0, res->last_level, 0,
> +                                  swizzle, 0, res->last_level, 0,
>                                    is_array ? res->array_size - 1 : 0,
>                                    res->width0, res->height0, res->depth0,
>                                    desc, NULL);
>
> +       si_set_mutable_tex_desc_fields(rtex, &rtex->surface.level[0], 0,
> +                                      rtex->surface.blk_w, false, desc);
> +
>         /* Clear the base address and set the relative DCC offset. */
>         desc[0] = 0;
>         desc[1] &= C_008F14_BASE_ADDRESS_HI;
> diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
> index f2a3b03..c74214a 100644
> --- a/src/gallium/drivers/radeonsi/si_state.h
> +++ b/src/gallium/drivers/radeonsi/si_state.h
> @@ -248,6 +248,10 @@ struct si_buffer_resources {
>
>  /* si_descriptors.c */
>  void si_ce_enable_loads(struct radeon_winsys_cs *ib);
> +void si_set_mutable_tex_desc_fields(struct r600_texture *tex,
> +                                   const struct radeon_surf_level *base_level_info,
> +                                   unsigned base_level, unsigned block_width,
> +                                   bool is_stencil, uint32_t *state);
>  void si_set_ring_buffer(struct pipe_context *ctx, uint slot,
>                         struct pipe_resource *buffer,
>                         unsigned stride, unsigned num_records,
> @@ -294,7 +298,7 @@ si_make_texture_descriptor(struct si_screen *screen,
>                            enum pipe_texture_target target,
>                            enum pipe_format pipe_format,
>                            const unsigned char state_swizzle[4],
> -                          unsigned base_level, unsigned first_level, unsigned last_level,
> +                          unsigned first_level, unsigned last_level,
>                            unsigned first_layer, unsigned last_layer,
>                            unsigned width, unsigned height, unsigned depth,
>                            uint32_t *state,
> @@ -319,4 +323,14 @@ void si_ce_post_draw_synchronization(struct si_context *sctx);
>  void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo);
>  void si_trace_emit(struct si_context *sctx);
>
> +
> +static inline unsigned
> +si_tile_mode_index(struct r600_texture *rtex, unsigned level, bool stencil)
> +{
> +       if (stencil)
> +               return rtex->surface.stencil_tiling_index[level];
> +       else
> +               return rtex->surface.tiling_index[level];
> +}
> +
>  #endif
> --
> 2.7.4
>
> _______________________________________________
> 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