On Fri, Aug 7, 2020 at 9:43 PM Marek Olšák <[email protected]> wrote:
>
> On Tue, Aug 4, 2020 at 5:32 PM Bas Nieuwenhuizen <[email protected]>
> 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 <[email protected]>
>> ---
>> .../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
>
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel