On Tue, Aug 4, 2020 at 5:32 PM Bas Nieuwenhuizen <b...@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 <b...@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. > + > + 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. > + > + 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. Marek
_______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel