[PATCH 8/8] drm/amd/display: Expose modifiers.

Marek Olšák maraeo at gmail.com
Thu Sep 3 02:42:42 UTC 2020


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

Marek

On Wed, Sep 2, 2020 at 6:31 AM Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
wrote:

> On Fri, Aug 7, 2020 at 9:43 PM Marek Olšák <maraeo at gmail.com> wrote:
> >
> > On Tue, Aug 4, 2020 at 5:32 PM Bas Nieuwenhuizen <
> bas at basnieuwenhuizen.nl> wrote:
> >>
> >> This expose modifier support on GFX9+.
> >>
> >> Only modifiers that can be rendered on the current GPU are
> >> added. This is to reduce the number of modifiers exposed.
> >>
> >> The HW could expose more, but the best mechanism to decide
> >> what to expose without an explosion in modifiers is still
> >> to be decided, and in the meantime this should not regress
> >> things from pre-modifiers and does not risk regressions as
> >> we make up our mind in the future.
> >>
> >> Signed-off-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
> >> ---
> >>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 343 +++++++++++++++++-
> >>  1 file changed, 342 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >> index c38257081868..6594cbe625f9 100644
> >> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >> @@ -3891,6 +3891,340 @@ fill_gfx9_tiling_info_from_modifier(const
> struct amdgpu_device *adev,
> >>         }
> >>  }
> >>
> >> +enum dm_micro_swizzle {
> >> +       MICRO_SWIZZLE_Z = 0,
> >> +       MICRO_SWIZZLE_S = 1,
> >> +       MICRO_SWIZZLE_D = 2,
> >> +       MICRO_SWIZZLE_R = 3
> >> +};
> >> +
> >> +static bool dm_plane_format_mod_supported(struct drm_plane *plane,
> >> +                                         uint32_t format,
> >> +                                         uint64_t modifier)
> >> +{
> >> +       struct amdgpu_device *adev = plane->dev->dev_private;
> >> +       const struct drm_format_info *info = drm_format_info(format);
> >> +
> >> +       enum dm_micro_swizzle microtile =
> modifier_gfx9_swizzle_mode(modifier) & 3;
> >> +
> >> +       if (!info)
> >> +               return false;
> >> +
> >> +       /*
> >> +        * We always have to allow this modifier, because core DRM still
> >> +        * checks LINEAR support if userspace does not provide modifers.
> >> +        */
> >> +       if (modifier == DRM_FORMAT_MOD_LINEAR)
> >> +               return true;
> >> +
> >> +       /*
> >> +        * The arbitrary tiling support for multiplane formats has not
> been hooked
> >> +        * up.
> >> +        */
> >> +       if (info->num_planes > 1)
> >> +               return false;
> >> +
> >> +       /*
> >> +        * For D swizzle the canonical modifier depends on the bpp, so
> check
> >> +        * it here.
> >> +        */
> >> +       if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) ==
> AMD_FMT_MOD_TILE_VER_GFX9 &&
> >> +           adev->family >= AMDGPU_FAMILY_NV) {
> >> +               if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4)
> >> +                       return false;
> >> +       }
> >> +
> >> +       if (adev->family >= AMDGPU_FAMILY_RV && microtile ==
> MICRO_SWIZZLE_D &&
> >> +           info->cpp[0] < 8)
> >> +               return false;
> >> +
> >> +       if (modifier_has_dcc(modifier)) {
> >> +               /* Per radeonsi comments 16/64 bpp are more
> complicated. */
> >> +               if (info->cpp[0] != 4)
> >> +                       return false;
> >> +       }
> >> +
> >> +       return true;
> >> +}
> >> +
> >> +static void
> >> +add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_t
> mod)
> >> +{
> >> +       if (!*mods)
> >> +               return;
> >> +
> >> +       if (*cap - *size < 1) {
> >> +               uint64_t new_cap = *cap * 2;
> >> +               uint64_t *new_mods = kmalloc(new_cap *
> sizeof(uint64_t), GFP_KERNEL);
> >> +
> >> +               if (!new_mods) {
> >> +                       kfree(*mods);
> >> +                       *mods = NULL;
> >> +                       return;
> >> +               }
> >> +
> >> +               memcpy(new_mods, *mods, sizeof(uint64_t) * *size);
> >> +               kfree(*mods);
> >> +               *mods = new_mods;
> >> +               *cap = new_cap;
> >> +       }
> >> +
> >> +       (*mods)[*size] = mod;
> >> +       *size += 1;
> >> +}
> >> +
> >> +static void
> >> +add_gfx9_modifiers(const struct amdgpu_device *adev,
> >> +                 uint64_t **mods, uint64_t *size, uint64_t *capacity)
> >> +{
> >> +       int pipes =
> ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
> >> +       int pipe_xor_bits = min(8, pipes +
> >> +
>  ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
> >> +       int bank_xor_bits = min(8 - pipe_xor_bits,
> >> +
>  ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
> >> +       int rb = ilog2(adev->gfx.config.gb_addr_config_fields.num_se) +
> >> +
> ilog2(adev->gfx.config.gb_addr_config_fields.num_rb_per_se);
> >> +
> >> +
> >> +       if (adev->family == AMDGPU_FAMILY_RV) {
> >> +               /*
> >> +                * No _D DCC swizzles yet because we only allow 32bpp,
> which
> >> +                * doesn't support _D on DCN
> >> +                */
> >> +
> >> +               /*
> >> +                * Always enable constant encoding, because the only
> unit that
> >> +                * didn't support it was CB. But on texture/display we
> can
> >> +                * always interpret it.
> >> +                */
> >> +               add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                           AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
> >> +                           AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX9) |
> >> +                           AMD_FMT_MOD_SET(PIPE_XOR_BITS,
> pipe_xor_bits) |
> >> +                           AMD_FMT_MOD_SET(BANK_XOR_BITS,
> bank_xor_bits) |
> >> +                           AMD_FMT_MOD_SET(DCC, 1) |
> >> +                           AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> >> +                           AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B) |
> >> +                           AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1));
> >
> >
> > I don't think Raven1 can do DCC constant encoding in DCN and GL2.
> >
> >> +
> >> +               add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                           AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
> >> +                           AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX9) |
> >> +                           AMD_FMT_MOD_SET(PIPE_XOR_BITS,
> pipe_xor_bits) |
> >> +                           AMD_FMT_MOD_SET(BANK_XOR_BITS,
> bank_xor_bits) |
> >> +                           AMD_FMT_MOD_SET(DCC, 1) |
> >> +                           AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> >> +                           AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B) |
> >> +                           AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0));
> >> +
> >> +               add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                           AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
> >> +                           AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX9) |
> >> +                           AMD_FMT_MOD_SET(PIPE_XOR_BITS,
> pipe_xor_bits) |
> >> +                           AMD_FMT_MOD_SET(BANK_XOR_BITS,
> bank_xor_bits) |
> >> +                           AMD_FMT_MOD_SET(DCC, 1) |
> >> +                           AMD_FMT_MOD_SET(DCC_RETILE, 1) |
> >> +                           AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> >> +                           AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B) |
> >> +                           AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
> >> +                           AMD_FMT_MOD_SET(RB, rb) |
> >> +                           AMD_FMT_MOD_SET(PIPE, pipes));
> >> +
> >> +               add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                           AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
> >> +                           AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX9) |
> >> +                           AMD_FMT_MOD_SET(PIPE_XOR_BITS,
> pipe_xor_bits) |
> >> +                           AMD_FMT_MOD_SET(BANK_XOR_BITS,
> bank_xor_bits) |
> >> +                           AMD_FMT_MOD_SET(DCC, 1) |
> >> +                           AMD_FMT_MOD_SET(DCC_RETILE, 1) |
> >> +                           AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> >> +                           AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B) |
> >> +                           AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0) |
> >> +                           AMD_FMT_MOD_SET(RB, rb) |
> >> +                           AMD_FMT_MOD_SET(PIPE, pipes));
> >> +       }
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_D_X) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX9) |
> >> +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
> >> +                   AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits));
> >
> >
> > Addrlib says that D swizzle modes are unsupported for 32bpp in DCN1.
> They are only supported in DCE12. The swizzle modes between the two have no
> intersection.
>
> Right, but we don't have the format here. These get further filtered
> by dm_plane_format_mod_supported, which does:
>
>         if (adev->family >= AMDGPU_FAMILY_RV && microtile ==
> MICRO_SWIZZLE_D &&
>             info->cpp[0] < 8)
>                 return false;
>
> (cpp is in bytes)
>
> >
> >>
> >> +
> >> +       if (adev->family == AMDGPU_FAMILY_RV) {
> >> +               add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                           AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
> >> +                           AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX9) |
> >> +                           AMD_FMT_MOD_SET(PIPE_XOR_BITS,
> pipe_xor_bits) |
> >> +                           AMD_FMT_MOD_SET(BANK_XOR_BITS,
> bank_xor_bits));
> >> +       }
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX9));
> >> +
> >> +       if (adev->family == AMDGPU_FAMILY_RV) {
> >> +               add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                           AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_S) |
> >> +                           AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX9));
> >> +       }
> >> +}
> >> +
> >> +static void
> >> +add_gfx10_1_modifiers(const struct amdgpu_device *adev,
> >> +                    uint64_t **mods, uint64_t *size, uint64_t
> *capacity)
> >> +{
> >> +       int pipe_xor_bits =
> ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10) |
> >> +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
> >> +                   AMD_FMT_MOD_SET(DCC, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B));
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10) |
> >> +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
> >> +                   AMD_FMT_MOD_SET(DCC, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_RETILE, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_64B));
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10) |
> >> +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_D_X) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10) |
> >> +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
> >
> >
> > D swizzle modes are unsupported according to Addrlib.
>
> Seems to be supported for DCN2:
>
>
> https://gitlab.freedesktop.org/mesa/mesa/-/blob/master/src/amd/addrlib/src/gfx10/gfx10addrlib.cpp#L1942
>
> which seems to be both gfx10.1 and gfx10.3 GPUs:
>
>
> https://gitlab.freedesktop.org/mesa/mesa/-/blob/master/src/amd/addrlib/src/gfx10/gfx10addrlib.cpp#L923
>
> >
> >>
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10) |
> >> +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10));
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX9));
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX9));
> >> +}
> >> +
> >> +static void
> >> +add_gfx10_3_modifiers(const struct amdgpu_device *adev,
> >> +                    uint64_t **mods, uint64_t *size, uint64_t
> *capacity)
> >> +{
> >> +       int pipe_xor_bits =
> ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
> >> +       int pkrs =
> ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs);
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> >> +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
> >> +                   AMD_FMT_MOD_SET(PACKERS, pkrs) |
> >> +                   AMD_FMT_MOD_SET(DCC, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_128B));
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> >> +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
> >> +                   AMD_FMT_MOD_SET(PACKERS, pkrs) |
> >> +                   AMD_FMT_MOD_SET(DCC, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_RETILE, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
> >> +                   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK,
> AMD_FMT_MOD_DCC_BLOCK_128B));
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> >> +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
> >> +                   AMD_FMT_MOD_SET(PACKERS, pkrs));
> >> +
> >> +       add_modifier(mods, size, capacity, AMD_FMT_MOD |
> >> +                   AMD_FMT_MOD_SET(TILE,
> AMD_FMT_MOD_TILE_GFX9_64K_D_X) |
> >> +                   AMD_FMT_MOD_SET(TILE_VERSION,
> AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
> >> +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
> >> +                   AMD_FMT_MOD_SET(PACKERS, pkrs));
> >
> >
> > D swizzle modes are unsupported.
>
> Same as above.
> >
> > Marek
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/amd-gfx/attachments/20200902/d93b229a/attachment-0001.htm>


More information about the amd-gfx mailing list