[Mesa-dev] [PATCH] radeonsi: Fix calculation of number of banks for SI

Alex Deucher alexdeucher at gmail.com
Mon Apr 21 08:05:54 PDT 2014


On Mon, Apr 21, 2014 at 5:27 AM, Michel Dänzer <michel at daenzer.net> wrote:
> From: Michel Dänzer <michel.daenzer at amd.com>
>
> The way cik_num_banks() was calculating the index only makes sense for
> the CIK specific macrotile mode array. For SI, we need to use the tile
> mode index directly.
>
> This happened to work most of the time because most of the SI tiling
> modes use the same number of banks.

Thanks for catching this.

Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

I think the kernel could use a similar fix for the display setup.

Alex


>
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
> ---
>  src/gallium/drivers/radeonsi/si_dma.c   |  6 ++++--
>  src/gallium/drivers/radeonsi/si_state.c | 27 ++++++++++++++-------------
>  src/gallium/drivers/radeonsi/si_state.h |  3 ++-
>  3 files changed, 20 insertions(+), 16 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_dma.c b/src/gallium/drivers/radeonsi/si_dma.c
> index 97ea08b..dc8c609 100644
> --- a/src/gallium/drivers/radeonsi/si_dma.c
> +++ b/src/gallium/drivers/radeonsi/si_dma.c
> @@ -169,10 +169,11 @@ static void si_dma_copy_tile(struct si_context *ctx,
>                 bank_h = cik_bank_wh(rsrc->surface.bankh);
>                 bank_w = cik_bank_wh(rsrc->surface.bankw);
>                 mt_aspect = cik_macro_tile_aspect(rsrc->surface.mtilea);
> -               nbanks = cik_num_banks(sscreen, rsrc->surface.bpe, rsrc->surface.tile_split);
>                 tile_split = cik_tile_split(rsrc->surface.tile_split);
>                 tile_mode_index = si_tile_mode_index(rsrc, src_level,
>                                                      util_format_has_stencil(util_format_description(src->format)));
> +               nbanks = si_num_banks(sscreen, rsrc->surface.bpe, rsrc->surface.tile_split,
> +                                     tile_mode_index);
>                 base += r600_resource_va(&ctx->screen->b.b, src);
>                 addr += r600_resource_va(&ctx->screen->b.b, dst);
>         } else {
> @@ -197,10 +198,11 @@ static void si_dma_copy_tile(struct si_context *ctx,
>                 bank_h = cik_bank_wh(rdst->surface.bankh);
>                 bank_w = cik_bank_wh(rdst->surface.bankw);
>                 mt_aspect = cik_macro_tile_aspect(rdst->surface.mtilea);
> -               nbanks = cik_num_banks(sscreen, rdst->surface.bpe, rdst->surface.tile_split);
>                 tile_split = cik_tile_split(rdst->surface.tile_split);
>                 tile_mode_index = si_tile_mode_index(rdst, dst_level,
>                                                      util_format_has_stencil(util_format_description(dst->format)));
> +               nbanks = si_num_banks(sscreen, rdst->surface.bpe, rdst->surface.tile_split,
> +                                     tile_mode_index);
>                 base += r600_resource_va(&ctx->screen->b.b, dst);
>                 addr += r600_resource_va(&ctx->screen->b.b, src);
>         }
> diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
> index 211a615..921264e 100644
> --- a/src/gallium/drivers/radeonsi/si_state.c
> +++ b/src/gallium/drivers/radeonsi/si_state.c
> @@ -47,19 +47,19 @@ static void si_init_atom(struct r600_atom *atom, struct r600_atom **list_elem,
>         *list_elem = atom;
>  }
>
> -uint32_t cik_num_banks(struct si_screen *sscreen, unsigned bpe, unsigned tile_split)
> +uint32_t si_num_banks(struct si_screen *sscreen, unsigned bpe, unsigned tile_split,
> +                     unsigned tile_mode_index)
>  {
> -       unsigned index, tileb;
> -
> -       tileb = 8 * 8 * bpe;
> -       tileb = MIN2(tile_split, tileb);
> -
> -       for (index = 0; tileb > 64; index++) {
> -               tileb >>= 1;
> -       }
> -
>         if ((sscreen->b.chip_class == CIK) &&
>             sscreen->b.info.cik_macrotile_mode_array_valid) {
> +               unsigned index, tileb;
> +
> +               tileb = 8 * 8 * bpe;
> +               tileb = MIN2(tile_split, tileb);
> +
> +               for (index = 0; tileb > 64; index++) {
> +                       tileb >>= 1;
> +               }
>                 assert(index < 16);
>
>                 return (sscreen->b.info.cik_macrotile_mode_array[index] >> 6) & 0x3;
> @@ -67,9 +67,9 @@ uint32_t cik_num_banks(struct si_screen *sscreen, unsigned bpe, unsigned tile_sp
>
>         if ((sscreen->b.chip_class == SI) &&
>             sscreen->b.info.si_tile_mode_array_valid) {
> -               assert(index < 16);
> +               assert(tile_mode_index < 32);
>
> -               return (sscreen->b.info.si_tile_mode_array[index] >> 20) & 0x3;
> +               return (sscreen->b.info.si_tile_mode_array[tile_mode_index] >> 20) & 0x3;
>         }
>
>         /* The old way. */
> @@ -1785,7 +1785,8 @@ static void si_init_depth_surface(struct si_context *sctx,
>                 macro_aspect = cik_macro_tile_aspect(macro_aspect);
>                 bankw = cik_bank_wh(bankw);
>                 bankh = cik_bank_wh(bankh);
> -               nbanks = cik_num_banks(sscreen, rtex->surface.bpe, rtex->surface.tile_split);
> +               nbanks = si_num_banks(sscreen, rtex->surface.bpe, rtex->surface.tile_split,
> +                                     ~0);
>                 tile_mode_index = si_tile_mode_index(rtex, level, false);
>                 pipe_config = cik_db_pipe_config(sscreen, tile_mode_index);
>
> diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
> index 0f37cd9..4c5b09e 100644
> --- a/src/gallium/drivers/radeonsi/si_state.h
> +++ b/src/gallium/drivers/radeonsi/si_state.h
> @@ -233,7 +233,8 @@ unsigned cik_bank_wh(unsigned bankwh);
>  unsigned cik_db_pipe_config(struct si_screen *sscreen, unsigned tile_mode);
>  unsigned cik_macro_tile_aspect(unsigned macro_tile_aspect);
>  unsigned cik_tile_split(unsigned tile_split);
> -uint32_t cik_num_banks(struct si_screen *sscreen, unsigned bpe, unsigned tile_split);
> +uint32_t si_num_banks(struct si_screen *sscreen, unsigned bpe, unsigned tile_split,
> +                     unsigned tile_mode_index);
>  unsigned si_tile_mode_index(struct r600_texture *rtex, unsigned level, bool stencil);
>
>  /* si_state_draw.c */
> --
> 1.9.2
>
> _______________________________________________
> 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