If we use DCC modifiers this can increase the number of planes from
the initial 1 plane with metadata, so that we get a valid modifier
from getfb2.

Since the code didn't update the format_info getfb2 would only ever
return 1 plane with a modifier for which userspace expects > 1.

This moves the format lookup to amdgpu_display.c so we do not have
issues when DC is not compiled.

Signed-off-by: Bas Nieuwenhuizen <b...@basnieuwenhuizen.nl>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 97 +++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.h   |  2 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 88 +----------------
 3 files changed, 100 insertions(+), 87 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index e33acc3de286..f66ce6ec4843 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -542,6 +542,95 @@ uint32_t amdgpu_display_supported_domains(struct 
amdgpu_device *adev,
        return domain;
 }
 
+static const struct drm_format_info dcc_formats[] = {
+       { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2,
+         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+        { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2,
+         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+       { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2,
+         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+          .has_alpha = true, },
+       { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2,
+         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+         .has_alpha = true, },
+       { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 2,
+         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+         .has_alpha = true, },
+       { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
+         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+       { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
+         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+       { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
+         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+         .has_alpha = true, },
+       { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
+         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
+         .has_alpha = true, },
+       { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 2,
+         .cpp = { 2, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
+};
+
+static const struct drm_format_info dcc_retile_formats[] = {
+       { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 3,
+         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+        { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 3,
+         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+       { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 3,
+         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+          .has_alpha = true, },
+       { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 3,
+         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+         .has_alpha = true, },
+       { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 3,
+         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+         .has_alpha = true, },
+       { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3,
+         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+       { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3,
+         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+       { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3,
+         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+         .has_alpha = true, },
+       { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 3,
+         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
+         .has_alpha = true, },
+       { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 3,
+         .cpp = { 2, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
+};
+
+static const struct drm_format_info *
+lookup_format_info(const struct drm_format_info formats[],
+                 int num_formats, u32 format)
+{
+       int i;
+
+       for (i = 0; i < num_formats; i++) {
+               if (formats[i].format == format)
+                       return &formats[i];
+       }
+
+       return NULL;
+}
+
+const struct drm_format_info *
+amdgpu_lookup_format_info(u32 format, uint64_t modifier)
+{
+       if (!IS_AMD_FMT_MOD(modifier))
+               return NULL;
+
+       if (AMD_FMT_MOD_GET(DCC_RETILE, modifier))
+               return lookup_format_info(dcc_retile_formats,
+                                         ARRAY_SIZE(dcc_retile_formats),
+                                         format);
+
+       if (AMD_FMT_MOD_GET(DCC, modifier))
+               return lookup_format_info(dcc_formats, ARRAY_SIZE(dcc_formats),
+                                         format);
+
+       /* returning NULL will cause the default format structs to be used. */
+       return NULL;
+}
+
 static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
 {
        struct amdgpu_device *adev = drm_to_adev(afb->base.dev);
@@ -631,6 +720,7 @@ static int convert_tiling_flags_to_modifier(struct 
amdgpu_framebuffer *afb)
                if (dcc_offset != 0) {
                        bool dcc_i64b = AMDGPU_TILING_GET(afb->tiling_flags, 
DCC_INDEPENDENT_64B) != 0;
                        bool dcc_i128b = version >= 
AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
+                       const struct drm_format_info *format_info;
 
                        /* Enable constant encode on RAVEN2 and later. */
                        bool dcc_constant_encode = adev->asic_type > CHIP_RAVEN 
||
@@ -649,6 +739,13 @@ static int convert_tiling_flags_to_modifier(struct 
amdgpu_framebuffer *afb)
 
                        afb->base.offsets[1] = dcc_offset * 256 + 
afb->base.offsets[0];
                        afb->base.pitches[1] = 
AMDGPU_TILING_GET(afb->tiling_flags, DCC_PITCH_MAX) + 1;
+
+                       format_info = 
amdgpu_lookup_format_info(afb->base.format->format,
+                                                               modifier);
+                       if (!format_info)
+                               return -EINVAL;
+
+                       afb->base.format = format_info;
                }
        }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.h
index 3620b24785e1..dc7b7d116549 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.h
@@ -44,5 +44,7 @@ struct drm_framebuffer *
 amdgpu_display_user_framebuffer_create(struct drm_device *dev,
                                       struct drm_file *file_priv,
                                       const struct drm_mode_fb_cmd2 *mode_cmd);
+const struct drm_format_info *
+amdgpu_lookup_format_info(u32 format, uint64_t modifier);
 
 #endif
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 423f6f07a070..234a04043a86 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3963,96 +3963,10 @@ modifier_gfx9_swizzle_mode(uint64_t modifier)
        return AMD_FMT_MOD_GET(TILE, modifier);
 }
 
-static const struct drm_format_info dcc_formats[] = {
-       { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2,
-         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
-        { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2,
-         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
-       { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2,
-         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
-          .has_alpha = true, },
-       { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2,
-         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
-         .has_alpha = true, },
-       { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 2,
-         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
-         .has_alpha = true, },
-       { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 2,
-         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
-       { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 2,
-         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
-       { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 2,
-         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
-         .has_alpha = true, },
-       { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 2,
-         .cpp = { 4, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1,
-         .has_alpha = true, },
-       { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 2,
-         .cpp = { 2, 0, }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub = 
1, .vsub = 1, },
-};
-
-static const struct drm_format_info dcc_retile_formats[] = {
-       { .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 3,
-         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
-        { .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 3,
-         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
-       { .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 3,
-         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
-          .has_alpha = true, },
-       { .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 3,
-         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
-         .has_alpha = true, },
-       { .format = DRM_FORMAT_BGRA8888, .depth = 32, .num_planes = 3,
-         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
-         .has_alpha = true, },
-       { .format = DRM_FORMAT_XRGB2101010, .depth = 30, .num_planes = 3,
-         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
-       { .format = DRM_FORMAT_XBGR2101010, .depth = 30, .num_planes = 3,
-         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
-       { .format = DRM_FORMAT_ARGB2101010, .depth = 30, .num_planes = 3,
-         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
-         .has_alpha = true, },
-       { .format = DRM_FORMAT_ABGR2101010, .depth = 30, .num_planes = 3,
-         .cpp = { 4, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1,
-         .has_alpha = true, },
-       { .format = DRM_FORMAT_RGB565, .depth = 16, .num_planes = 3,
-         .cpp = { 2, 0, 0 }, .block_w = {1, 1, 1}, .block_h = {1, 1, 1}, .hsub 
= 1, .vsub = 1, },
-};
-
-
-static const struct drm_format_info *
-lookup_format_info(const struct drm_format_info formats[],
-                 int num_formats, u32 format)
-{
-       int i;
-
-       for (i = 0; i < num_formats; i++) {
-               if (formats[i].format == format)
-                       return &formats[i];
-       }
-
-       return NULL;
-}
-
 static const struct drm_format_info *
 amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd)
 {
-       uint64_t modifier = cmd->modifier[0];
-
-       if (!IS_AMD_FMT_MOD(modifier))
-               return NULL;
-
-       if (AMD_FMT_MOD_GET(DCC_RETILE, modifier))
-               return lookup_format_info(dcc_retile_formats,
-                                         ARRAY_SIZE(dcc_retile_formats),
-                                         cmd->pixel_format);
-
-       if (AMD_FMT_MOD_GET(DCC, modifier))
-               return lookup_format_info(dcc_formats, ARRAY_SIZE(dcc_formats),
-                                         cmd->pixel_format);
-
-       /* returning NULL will cause the default format structs to be used. */
-       return NULL;
+       return amdgpu_lookup_format_info(cmd->pixel_format, cmd->modifier[0]);
 }
 
 static void
-- 
2.29.2

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to