amd-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 00/11] amd/display: Add GFX9+ modifier support.
@ 2020-10-21 23:31 Bas Nieuwenhuizen
  2020-10-21 23:31 ` [PATCH v3 01/11] drm/amd/display: Do not silently accept DCC for multiplane formats Bas Nieuwenhuizen
                   ` (12 more replies)
  0 siblings, 13 replies; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, daniel, Bas Nieuwenhuizen, alexdeucher,
	harry.wentland, nicholas.kazlauskas

This adds modifier support to the amdgpu kernel drivers for GFX9 and
later GPUs. It has been tested on

- VEGA10, RAVEN, NAVI14
- weston, sway, X with xf86-video-amdgpu (i.e. legacy path still works)

and includes some basic testing of the layout code.

The main goal is to keep it somewhat simple and regression free, so
on the display side this series only exposes what the current GPU
can render to. While we could expose more I think that is more
suitable for follow-up work as the benefit would be minimal and
there are some more design discussion there to discuss that are
orthogonal from the initial implementation.

Similarly this series only exposes 32-bpp displayable DCC in the cases
that radeonsi would use it and any extra capabilities here should be
future work.

I believe these are by far the most complicated modifiers we've seen
up till now, mostly related to

- GPU identification for cases where it matters wrt tiling.
- Every generation having tiling layout changes
- Compression settings.

I believe the complexity is necessary as every layout should be different
and all layouts should be the best in some situation (though not all
combinations of GPU parameters will actually have an existing GPU).

That said, on the render side the number of modifiers actually listed for
a given GPU is ~10, and in the current implementation that is the same
for the display side. (we could expose more actually differing layouts
on the display side for cross-GPU compatibility, but I consider that
out of scope for this initial work).

This series can be found on
https://github.com/BNieuwenhuizen/linux/tree/modifiers

An userspace implementation in radeonsi can be found on
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6176

which has been reviewed and is ready for submission once these kernel
patches land.

v2:

Per suggestion from Daniel Vetter I added logic to get the tiling_flags at
addfb2 time and convert them into modifiers for GFX9+.  Furthermore, the DCC
constant econding modifers only get exposed on RAVEN2 and newer.

v3:

Fixed some typos, rebased and CCing more people to actually get a review.

Bas Nieuwenhuizen (11):
  drm/amd/display: Do not silently accept DCC for multiplane formats.
  drm/amd: Init modifier field of helper fb.
  drm/amd/display: Honor the offset for plane 0.
  drm/fourcc:  Add AMD DRM modifiers.
  drm/amd/display: Store tiling_flags in the framebuffer.
  drm/amd/display: Convert tiling_flags to modifiers.
  drm/amd/display: Refactor surface tiling setup.
  drm/amd/display: Set DC options from modifiers.
  drm/amd/display: Add formats for DCC with 2/3 planes.
  drm/amd/display: Expose modifiers.
  drm/amd/display: Clean up GFX9 tiling_flags path.

 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 169 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c        |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |   3 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 754 ++++++++++++++----
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   2 -
 include/uapi/drm/drm_fourcc.h                 | 115 +++
 6 files changed, 880 insertions(+), 165 deletions(-)

-- 
2.28.0

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH v3 01/11] drm/amd/display: Do not silently accept DCC for multiplane formats.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
@ 2020-10-21 23:31 ` Bas Nieuwenhuizen
  2020-10-26 13:50   ` Kazlauskas, Nicholas
  2020-10-21 23:31 ` [PATCH v3 02/11] drm/amd: Init modifier field of helper fb Bas Nieuwenhuizen
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, daniel, Bas Nieuwenhuizen, alexdeucher,
	harry.wentland, nicholas.kazlauskas

Silently accepting it could result in corruption.

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 1 file changed, 1 insertion(+), 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 2713caac4f2a..73987fdb6a09 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3908,7 +3908,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
 		return 0;
 
 	if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
-		return 0;
+		return -EINVAL;
 
 	if (!dc->cap_funcs.get_dcc_compression_cap)
 		return -EINVAL;
-- 
2.28.0

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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 02/11] drm/amd: Init modifier field of helper fb.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
  2020-10-21 23:31 ` [PATCH v3 01/11] drm/amd/display: Do not silently accept DCC for multiplane formats Bas Nieuwenhuizen
@ 2020-10-21 23:31 ` Bas Nieuwenhuizen
  2020-10-26 13:50   ` Kazlauskas, Nicholas
  2020-10-21 23:31 ` [PATCH v3 03/11] drm/amd/display: Honor the offset for plane 0 Bas Nieuwenhuizen
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, daniel, Bas Nieuwenhuizen, alexdeucher,
	harry.wentland, nicholas.kazlauskas

Otherwise the field ends up being used uninitialized when
enabling modifiers, failing validation with high likelyhood.

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index e2c2eb45a793..77dd2a189746 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -201,7 +201,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
 	struct amdgpu_device *adev = rfbdev->adev;
 	struct fb_info *info;
 	struct drm_framebuffer *fb = NULL;
-	struct drm_mode_fb_cmd2 mode_cmd;
+	struct drm_mode_fb_cmd2 mode_cmd = {0};
 	struct drm_gem_object *gobj = NULL;
 	struct amdgpu_bo *abo = NULL;
 	int ret;
-- 
2.28.0

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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 03/11] drm/amd/display: Honor the offset for plane 0.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
  2020-10-21 23:31 ` [PATCH v3 01/11] drm/amd/display: Do not silently accept DCC for multiplane formats Bas Nieuwenhuizen
  2020-10-21 23:31 ` [PATCH v3 02/11] drm/amd: Init modifier field of helper fb Bas Nieuwenhuizen
@ 2020-10-21 23:31 ` Bas Nieuwenhuizen
  2020-10-22 15:36   ` Alex Deucher
  2020-10-26 13:51   ` Kazlauskas, Nicholas
  2020-10-21 23:31 ` [PATCH v3 04/11] drm/fourcc: Add AMD DRM modifiers Bas Nieuwenhuizen
                   ` (9 subsequent siblings)
  12 siblings, 2 replies; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, stable, daniel, Bas Nieuwenhuizen,
	alexdeucher, harry.wentland, nicholas.kazlauskas

With modifiers I'd like to support non-dedicated buffers for
images.

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Cc: stable@vger.kernel.org # 5.1.0
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

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 73987fdb6a09..833887b9b0ad 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3894,6 +3894,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
 	struct dc *dc = adev->dm.dc;
 	struct dc_dcc_surface_param input;
 	struct dc_surface_dcc_cap output;
+	uint64_t plane_address = afb->address + afb->base.offsets[0];
 	uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
 	uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
 	uint64_t dcc_address;
@@ -3937,7 +3938,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
 		AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
 	dcc->independent_64b_blks = i64b;
 
-	dcc_address = get_dcc_address(afb->address, info);
+	dcc_address = get_dcc_address(plane_address, info);
 	address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
 	address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
 
@@ -3968,6 +3969,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 	address->tmz_surface = tmz_surface;
 
 	if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
+		uint64_t addr = afb->address + fb->offsets[0];
+
 		plane_size->surface_size.x = 0;
 		plane_size->surface_size.y = 0;
 		plane_size->surface_size.width = fb->width;
@@ -3976,9 +3979,10 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 			fb->pitches[0] / fb->format->cpp[0];
 
 		address->type = PLN_ADDR_TYPE_GRAPHICS;
-		address->grph.addr.low_part = lower_32_bits(afb->address);
-		address->grph.addr.high_part = upper_32_bits(afb->address);
+		address->grph.addr.low_part = lower_32_bits(addr);
+		address->grph.addr.high_part = upper_32_bits(addr);
 	} else if (format < SURFACE_PIXEL_FORMAT_INVALID) {
+		uint64_t luma_addr = afb->address + fb->offsets[0];
 		uint64_t chroma_addr = afb->address + fb->offsets[1];
 
 		plane_size->surface_size.x = 0;
@@ -3999,9 +4003,9 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 
 		address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
 		address->video_progressive.luma_addr.low_part =
-			lower_32_bits(afb->address);
+			lower_32_bits(luma_addr);
 		address->video_progressive.luma_addr.high_part =
-			upper_32_bits(afb->address);
+			upper_32_bits(luma_addr);
 		address->video_progressive.chroma_addr.low_part =
 			lower_32_bits(chroma_addr);
 		address->video_progressive.chroma_addr.high_part =
-- 
2.28.0

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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 04/11] drm/fourcc: Add AMD DRM modifiers.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
                   ` (2 preceding siblings ...)
  2020-10-21 23:31 ` [PATCH v3 03/11] drm/amd/display: Honor the offset for plane 0 Bas Nieuwenhuizen
@ 2020-10-21 23:31 ` Bas Nieuwenhuizen
  2020-10-22 15:41   ` Alex Deucher
  2020-10-21 23:31 ` [PATCH v3 05/11] drm/amd/display: Store tiling_flags in the framebuffer Bas Nieuwenhuizen
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, daniel, Bas Nieuwenhuizen, alexdeucher,
	harry.wentland, nicholas.kazlauskas

This adds modifiers for GFX9+ AMD GPUs.

As the modifiers need a lot of parameters I split things out in
getters and setters.
  - Advantage: simplifies the code a lot
  - Disadvantage: Makes it harder to check that you're setting all
                  the required fields.

The tiling modes seem to change every generation, but the structure
of what each tiling mode is good for stays really similar. As such
the core of the modifier is
 - the tiling mode
 - a version. Not explicitly a GPU generation, but splitting out
   a new set of tiling equations.

Sometimes one or two tiling modes stay the same and for those we
specify a canonical version.

Then we have a bunch of parameters on how the compression works.
Different HW units have different requirements for these and we
actually have some conflicts here.

e.g. the render backends need a specific alignment but the display
unit only works with unaligned compression surfaces. To work around
that we have a DCC_RETILE option where both an aligned and unaligned
compression surface are allocated and a writer has to sync the
aligned surface to the unaligned surface on handoff.

Finally there are some GPU parameters that participate in the tiling
equations. These are constant for each GPU on the rendering/texturing
side. The display unit is very flexible however and supports all
of them :|

Some estimates:
 - Single GPU, render+texture: ~10 modifiers
 - All possible configs in a gen, display: ~1000 modifiers
 - Configs of actually existing GPUs in a gen: ~100 modifiers

For formats with a single plane everything gets put in a separate
DRM plane. However, this doesn't fit for some YUV formats, so if
the format has >1 plane, we let the driver pack the surfaces into
1 DRM plane per format plane.

This way we avoid X11 rendering onto the frontbuffer with DCC, but
still fit into 4 DRM planes.

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 include/uapi/drm/drm_fourcc.h | 115 ++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 82f327801267..df56e71a7380 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -1056,6 +1056,121 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
  */
 #define AMLOGIC_FBC_OPTION_MEM_SAVING		(1ULL << 0)
 
+/*
+ * AMD modifiers
+ *
+ * Memory layout:
+ *
+ * without DCC:
+ *   - main surface
+ *
+ * with DCC & without DCC_RETILE:
+ *   - main surface in plane 0
+ *   - DCC surface in plane 1 (RB-aligned, pipe-aligned if DCC_PIPE_ALIGN is set)
+ *
+ * with DCC & DCC_RETILE:
+ *   - main surface in plane 0
+ *   - displayable DCC surface in plane 1 (not RB-aligned & not pipe-aligned)
+ *   - pipe-aligned DCC surface in plane 2 (RB-aligned & pipe-aligned)
+ *
+ * For multi-plane formats the above surfaces get merged into one plane for
+ * each format plane, based on the required alignment only.
+ */
+#define AMD_FMT_MOD fourcc_mod_code(AMD, 0)
+
+#define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD)
+
+/* Reserve 0 for GFX8 and older */
+#define AMD_FMT_MOD_TILE_VER_GFX9 1
+#define AMD_FMT_MOD_TILE_VER_GFX10 2
+#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
+
+/*
+ * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical
+ * version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_S 9
+
+/*
+ * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has
+ * GFX9 as canonical version.
+ */
+#define AMD_FMT_MOD_TILE_GFX9_64K_D 10
+#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
+#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26
+#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
+
+#define AMD_FMT_MOD_DCC_BLOCK_64B 0
+#define AMD_FMT_MOD_DCC_BLOCK_128B 1
+#define AMD_FMT_MOD_DCC_BLOCK_256B 2
+
+#define AMD_FMT_MOD_TILE_VERSION_SHIFT 0
+#define AMD_FMT_MOD_TILE_VERSION_MASK 0xFF
+#define AMD_FMT_MOD_TILE_SHIFT 8
+#define AMD_FMT_MOD_TILE_MASK 0x1F
+
+/* Whether DCC compression is enabled. */
+#define AMD_FMT_MOD_DCC_SHIFT 13
+#define AMD_FMT_MOD_DCC_MASK 0x1
+
+/*
+ * Whether to include two DCC surfaces, one which is rb & pipe aligned, and
+ * one which is not-aligned.
+ */
+#define AMD_FMT_MOD_DCC_RETILE_SHIFT 14
+#define AMD_FMT_MOD_DCC_RETILE_MASK 0x1
+
+/* Only set if DCC_RETILE = false */
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_SHIFT 15
+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_MASK 0x1
+
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_SHIFT 16
+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_MASK 0x1
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_SHIFT 17
+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_MASK 0x1
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18
+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x1
+
+/*
+ * DCC supports embedding some clear colors directly in the DCC surface.
+ * However, on older GPUs the rendering HW ignores the embedded clear color
+ * and prefers the driver provided color. This necessitates doing a fastclear
+ * eliminate operation before a process transfers control.
+ *
+ * If this bit is set that means the fastclear eliminate is not needed for these
+ * embeddable colors.
+ */
+#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_SHIFT 19
+#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_MASK 0x1
+
+/*
+ * The below fields are for accounting for per GPU differences. These are only
+ * relevant for GFX9 and later and if the tile field is *_X/_T.
+ *
+ * PIPE_XOR_BITS = always needed
+ * BANK_XOR_BITS = only for TILE_VER_GFX9
+ * PACKERS = only for TILE_VER_GFX10_RBPLUS
+ * RB = only for TILE_VER_GFX9 & DCC
+ * PIPE = only for TILE_VER_GFX9 & DCC & (DCC_RETILE | DCC_PIPE_ALIGN)
+ */
+#define AMD_FMT_MOD_PIPE_XOR_BITS_SHIFT 20
+#define AMD_FMT_MOD_PIPE_XOR_BITS_MASK 0x7
+#define AMD_FMT_MOD_BANK_XOR_BITS_SHIFT 23
+#define AMD_FMT_MOD_BANK_XOR_BITS_MASK 0x7
+#define AMD_FMT_MOD_PACKERS_SHIFT 26 /* aliases with BANK_XOR_BITS */
+#define AMD_FMT_MOD_PACKERS_MASK 0x7
+#define AMD_FMT_MOD_RB_SHIFT 29
+#define AMD_FMT_MOD_RB_MASK 0x7
+#define AMD_FMT_MOD_PIPE_SHIFT 32
+#define AMD_FMT_MOD_PIPE_MASK 0x7
+
+#define AMD_FMT_MOD_SET(field, value) \
+	((uint64_t)(value) << AMD_FMT_MOD_##field##_SHIFT)
+#define AMD_FMT_MOD_GET(field, value) \
+	(((value) >> AMD_FMT_MOD_##field##_SHIFT) & AMD_FMT_MOD_##field##_MASK)
+#define AMD_FMT_MOD_CLEAR(field) \
+	(~((uint64_t)AMD_FMT_MOD_##field##_MASK << AMD_FMT_MOD_##field##_SHIFT))
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.28.0

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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 05/11] drm/amd/display: Store tiling_flags in the framebuffer.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
                   ` (3 preceding siblings ...)
  2020-10-21 23:31 ` [PATCH v3 04/11] drm/fourcc: Add AMD DRM modifiers Bas Nieuwenhuizen
@ 2020-10-21 23:31 ` Bas Nieuwenhuizen
  2020-10-26 13:54   ` Kazlauskas, Nicholas
  2020-10-21 23:31 ` [PATCH v3 06/11] drm/amd/display: Convert tiling_flags to modifiers Bas Nieuwenhuizen
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, daniel, Bas Nieuwenhuizen, alexdeucher,
	harry.wentland, nicholas.kazlauskas

This moves the tiling_flags to the framebuffer creation.
This way the time of the "tiling" decision is the same as it
would be with modifiers.

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 48 +++++++++++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  3 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 73 +++----------------
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 -
 4 files changed, 59 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 9e92d2a070ac..1a2664c3fc26 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -541,6 +541,39 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
 	return domain;
 }
 
+static int amdgpu_display_get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
+				      uint64_t *tiling_flags, bool *tmz_surface)
+{
+	struct amdgpu_bo *rbo;
+	int r;
+
+	if (!amdgpu_fb) {
+		*tiling_flags = 0;
+		*tmz_surface = false;
+		return 0;
+	}
+
+	rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
+	r = amdgpu_bo_reserve(rbo, false);
+
+	if (unlikely(r)) {
+		/* Don't show error message when returning -ERESTARTSYS */
+		if (r != -ERESTARTSYS)
+			DRM_ERROR("Unable to reserve buffer: %d\n", r);
+		return r;
+	}
+
+	if (tiling_flags)
+		amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
+
+	if (tmz_surface)
+		*tmz_surface = amdgpu_bo_encrypted(rbo);
+
+	amdgpu_bo_unreserve(rbo);
+
+	return r;
+}
+
 int amdgpu_display_framebuffer_init(struct drm_device *dev,
 				    struct amdgpu_framebuffer *rfb,
 				    const struct drm_mode_fb_cmd2 *mode_cmd,
@@ -550,11 +583,18 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
 	rfb->base.obj[0] = obj;
 	drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
 	ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
-	if (ret) {
-		rfb->base.obj[0] = NULL;
-		return ret;
-	}
+	if (ret)
+		goto fail;
+
+	ret = amdgpu_display_get_fb_info(rfb, &rfb->tiling_flags, &rfb->tmz_surface);
+	if (ret)
+		goto fail;
+
 	return 0;
+
+fail:
+	rfb->base.obj[0] = NULL;
+	return ret;
 }
 
 struct drm_framebuffer *
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 345cb0464370..39866ed81c16 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -304,6 +304,9 @@ struct amdgpu_display_funcs {
 struct amdgpu_framebuffer {
 	struct drm_framebuffer base;
 
+	uint64_t tiling_flags;
+	bool tmz_surface;
+
 	/* caching for later use */
 	uint64_t address;
 };
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 833887b9b0ad..5a0efaefbd7f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3839,39 +3839,6 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state,
 	return 0;
 }
 
-static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
-		       uint64_t *tiling_flags, bool *tmz_surface)
-{
-	struct amdgpu_bo *rbo;
-	int r;
-
-	if (!amdgpu_fb) {
-		*tiling_flags = 0;
-		*tmz_surface = false;
-		return 0;
-	}
-
-	rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
-	r = amdgpu_bo_reserve(rbo, false);
-
-	if (unlikely(r)) {
-		/* Don't show error message when returning -ERESTARTSYS */
-		if (r != -ERESTARTSYS)
-			DRM_ERROR("Unable to reserve buffer: %d\n", r);
-		return r;
-	}
-
-	if (tiling_flags)
-		amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
-
-	if (tmz_surface)
-		*tmz_surface = amdgpu_bo_encrypted(rbo);
-
-	amdgpu_bo_unreserve(rbo);
-
-	return r;
-}
-
 static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
 {
 	uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
@@ -4287,7 +4254,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
 				    struct drm_crtc_state *crtc_state)
 {
 	struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state);
-	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+	struct amdgpu_framebuffer *afb = (struct amdgpu_framebuffer *)plane_state->fb;
 	struct dc_scaling_info scaling_info;
 	struct dc_plane_info plane_info;
 	int ret;
@@ -4304,10 +4271,10 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
 
 	force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
 	ret = fill_dc_plane_info_and_addr(adev, plane_state,
-					  dm_plane_state->tiling_flags,
+					  afb->tiling_flags,
 					  &plane_info,
 					  &dc_plane_state->address,
-					  dm_plane_state->tmz_surface,
+					  afb->tmz_surface,
 					  force_disable_dcc);
 	if (ret)
 		return ret;
@@ -5913,10 +5880,6 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 		dc_plane_state_retain(dm_plane_state->dc_state);
 	}
 
-	/* Framebuffer hasn't been updated yet, so retain old flags. */
-	dm_plane_state->tiling_flags = old_dm_plane_state->tiling_flags;
-	dm_plane_state->tmz_surface = old_dm_plane_state->tmz_surface;
-
 	return &dm_plane_state->base;
 }
 
@@ -6021,10 +5984,10 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
 
 		fill_plane_buffer_attributes(
 			adev, afb, plane_state->format, plane_state->rotation,
-			dm_plane_state_new->tiling_flags,
+			afb->tiling_flags,
 			&plane_state->tiling_info, &plane_state->plane_size,
 			&plane_state->dcc, &plane_state->address,
-			dm_plane_state_new->tmz_surface, force_disable_dcc);
+			afb->tmz_surface, force_disable_dcc);
 	}
 
 	return 0;
@@ -7287,6 +7250,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 		struct drm_crtc *crtc = new_plane_state->crtc;
 		struct drm_crtc_state *new_crtc_state;
 		struct drm_framebuffer *fb = new_plane_state->fb;
+		struct amdgpu_framebuffer *afb = (struct amdgpu_framebuffer *)fb;
 		bool plane_needs_flip;
 		struct dc_plane_state *dc_plane;
 		struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state);
@@ -7341,10 +7305,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 
 		fill_dc_plane_info_and_addr(
 			dm->adev, new_plane_state,
-			dm_new_plane_state->tiling_flags,
+			afb->tiling_flags,
 			&bundle->plane_infos[planes_count],
 			&bundle->flip_addrs[planes_count].address,
-			dm_new_plane_state->tmz_surface, false);
+			afb->tmz_surface, false);
 
 		DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n",
 				 new_plane_state->plane->index,
@@ -8483,8 +8447,7 @@ static bool should_reset_plane(struct drm_atomic_state *state,
 	 * TODO: Come up with a more elegant solution for this.
 	 */
 	for_each_oldnew_plane_in_state(state, other, old_other_state, new_other_state, i) {
-		struct dm_plane_state *old_dm_plane_state, *new_dm_plane_state;
-
+		struct amdgpu_framebuffer *old_afb, *new_afb;
 		if (other->type == DRM_PLANE_TYPE_CURSOR)
 			continue;
 
@@ -8528,12 +8491,11 @@ static bool should_reset_plane(struct drm_atomic_state *state,
 		if (old_other_state->fb->format != new_other_state->fb->format)
 			return true;
 
-		old_dm_plane_state = to_dm_plane_state(old_other_state);
-		new_dm_plane_state = to_dm_plane_state(new_other_state);
+		old_afb = (struct amdgpu_framebuffer *)old_other_state->fb;
+		new_afb = (struct amdgpu_framebuffer *)new_other_state->fb;
 
 		/* Tiling and DCC changes also require bandwidth updates. */
-		if (old_dm_plane_state->tiling_flags !=
-		    new_dm_plane_state->tiling_flags)
+		if (old_afb->tiling_flags != new_afb->tiling_flags)
 			return true;
 	}
 
@@ -8859,17 +8821,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 		}
 	}
 
-	/* Prepass for updating tiling flags on new planes. */
-	for_each_new_plane_in_state(state, plane, new_plane_state, i) {
-		struct dm_plane_state *new_dm_plane_state = to_dm_plane_state(new_plane_state);
-		struct amdgpu_framebuffer *new_afb = to_amdgpu_framebuffer(new_plane_state->fb);
-
-		ret = get_fb_info(new_afb, &new_dm_plane_state->tiling_flags,
-				  &new_dm_plane_state->tmz_surface);
-		if (ret)
-			goto fail;
-	}
-
 	/* Remove exiting planes if they are modified */
 	for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
 		ret = dm_update_plane_state(dc, state, plane,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
index a46338410ddd..9308bed3c4fe 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -420,8 +420,6 @@ struct dc_plane_state;
 struct dm_plane_state {
 	struct drm_plane_state base;
 	struct dc_plane_state *dc_state;
-	uint64_t tiling_flags;
-	bool tmz_surface;
 };
 
 struct dm_crtc_state {
-- 
2.28.0

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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 06/11] drm/amd/display: Convert tiling_flags to modifiers.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
                   ` (4 preceding siblings ...)
  2020-10-21 23:31 ` [PATCH v3 05/11] drm/amd/display: Store tiling_flags in the framebuffer Bas Nieuwenhuizen
@ 2020-10-21 23:31 ` Bas Nieuwenhuizen
  2020-10-21 23:31 ` [PATCH v3 07/11] drm/amd/display: Refactor surface tiling setup Bas Nieuwenhuizen
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, daniel, Bas Nieuwenhuizen, alexdeucher,
	harry.wentland, nicholas.kazlauskas

This way the modifier path gets exercised all the time, improving
testing. Furthermore, for modifiers this is required as getfb2
will always return the modifier if the driver sets allow_fb_modifiers.

This only triggers once allow_fb_modifiers is set.

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 123 ++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 1a2664c3fc26..89c3ead36501 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -38,6 +38,7 @@
 #include <drm/drm_edid.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_fb_helper.h>
+#include <drm/drm_fourcc.h>
 #include <drm/drm_vblank.h>
 
 static void amdgpu_display_flip_callback(struct dma_fence *f,
@@ -541,6 +542,121 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
 	return domain;
 }
 
+static int convert_tiling_flags_to_modifier(struct amdgpu_framebuffer *afb)
+{
+	struct amdgpu_device *adev = drm_to_adev(afb->base.dev);
+	uint64_t modifier = 0;
+
+	if (!afb->tiling_flags || !AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) {
+		modifier = DRM_FORMAT_MOD_LINEAR;
+	} else {
+		int swizzle = AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE);
+		bool has_xor = swizzle >= 16;
+		int block_size_bits;
+		int version;
+		int pipe_xor_bits = 0;
+		int bank_xor_bits = 0;
+		int packers = 0;
+		uint32_t dcc_offset = AMDGPU_TILING_GET(afb->tiling_flags, DCC_OFFSET_256B);
+
+		switch (swizzle >> 2) {
+		case 0: /* 256B */
+			block_size_bits = 8;
+			break;
+		case 1: /* 4KiB */
+		case 5: /* 4KiB _X */
+			block_size_bits = 12;
+			break;
+		case 2: /* 64KiB */
+		case 4: /* 64 KiB _T */
+		case 6: /* 64 KiB _X */
+			block_size_bits = 16;
+			break;
+		default:
+			/* RESERVED or VAR */
+			return -EINVAL;
+		}
+
+		if (adev->asic_type >= CHIP_SIENNA_CICHLID)
+			version = AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS;
+		else if (adev->family == AMDGPU_FAMILY_NV)
+			version = AMD_FMT_MOD_TILE_VER_GFX10;
+		else
+			version = AMD_FMT_MOD_TILE_VER_GFX9;
+
+		switch (swizzle & 3) {
+		case 0: /* Z microtiling */
+			return -EINVAL;
+		case 1: /* S microtiling */
+			if (!has_xor)
+				version = AMD_FMT_MOD_TILE_VER_GFX9;
+			break;
+		case 2:
+			if (!has_xor && afb->base.format->cpp[0] != 4)
+				version = AMD_FMT_MOD_TILE_VER_GFX9;
+			break;
+		case 3:
+			break;
+		}
+
+		if (has_xor) {
+			switch (version) {
+			case AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS:
+				pipe_xor_bits = min(block_size_bits - 8,
+						    ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
+				packers = min(block_size_bits - 8 - pipe_xor_bits,
+					      ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs));
+				break;
+			case AMD_FMT_MOD_TILE_VER_GFX10:
+				pipe_xor_bits = min(block_size_bits - 8,
+						    ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes));
+				break;
+			case AMD_FMT_MOD_TILE_VER_GFX9:
+				pipe_xor_bits = min(block_size_bits - 8,
+						    ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes) +
+						    ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
+				bank_xor_bits = min(block_size_bits - 8 - pipe_xor_bits,
+						    ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
+				break;
+			}
+		}
+
+		modifier = AMD_FMT_MOD |
+			   AMD_FMT_MOD_SET(TILE, AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE)) |
+			   AMD_FMT_MOD_SET(TILE_VERSION, version) |
+			   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
+			   AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
+			   AMD_FMT_MOD_SET(PACKERS, packers);
+
+		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;
+
+			/* Enable constant encode on RAVEN2 and later. */
+			bool dcc_constant_encode = adev->asic_type > CHIP_RAVEN ||
+						   (adev->asic_type == CHIP_RAVEN &&
+						    adev->external_rev_id >= 0x81);
+
+			int max_cblock_size = dcc_i64b ? AMD_FMT_MOD_DCC_BLOCK_64B :
+					      dcc_i128b ? AMD_FMT_MOD_DCC_BLOCK_128B :
+					      AMD_FMT_MOD_DCC_BLOCK_256B;
+
+			modifier |= AMD_FMT_MOD_SET(DCC, 1) |
+				    AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, dcc_constant_encode) |
+				    AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, dcc_i64b) |
+				    AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, dcc_i128b) |
+				    AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, max_cblock_size);
+
+			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;
+		}
+	}
+
+	afb->base.modifier = modifier;
+	afb->base.flags |= DRM_MODE_FB_MODIFIERS;
+	return 0;
+}
+
 static int amdgpu_display_get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
 				      uint64_t *tiling_flags, bool *tmz_surface)
 {
@@ -590,6 +706,13 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
 	if (ret)
 		goto fail;
 
+	if (dev->mode_config.allow_fb_modifiers &&
+	    !(rfb->base.flags & DRM_MODE_FB_MODIFIERS)) {
+		ret = convert_tiling_flags_to_modifier(rfb);
+		if (ret)
+			goto fail;
+	}
+
 	return 0;
 
 fail:
-- 
2.28.0

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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 07/11] drm/amd/display: Refactor surface tiling setup.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
                   ` (5 preceding siblings ...)
  2020-10-21 23:31 ` [PATCH v3 06/11] drm/amd/display: Convert tiling_flags to modifiers Bas Nieuwenhuizen
@ 2020-10-21 23:31 ` Bas Nieuwenhuizen
  2020-10-26 13:58   ` Kazlauskas, Nicholas
  2020-10-21 23:31 ` [PATCH v3 08/11] drm/amd/display: Set DC options from modifiers Bas Nieuwenhuizen
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, daniel, Bas Nieuwenhuizen, alexdeucher,
	harry.wentland, nicholas.kazlauskas

Prepare for inserting modifiers based configuration, while sharing
a bunch of DCC validation & initializing the device-based configuration.

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 222 ++++++++++--------
 1 file changed, 119 insertions(+), 103 deletions(-)

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 5a0efaefbd7f..479c886816d9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3839,46 +3839,86 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state,
 	return 0;
 }
 
-static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
+static void
+fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info,
+				 uint64_t tiling_flags)
 {
-	uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
+	/* Fill GFX8 params */
+	if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) {
+		unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
+
+		bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
+		bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
+		mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
+		tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT);
+		num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
+
+		/* XXX fix me for VI */
+		tiling_info->gfx8.num_banks = num_banks;
+		tiling_info->gfx8.array_mode =
+				DC_ARRAY_2D_TILED_THIN1;
+		tiling_info->gfx8.tile_split = tile_split;
+		tiling_info->gfx8.bank_width = bankw;
+		tiling_info->gfx8.bank_height = bankh;
+		tiling_info->gfx8.tile_aspect = mtaspect;
+		tiling_info->gfx8.tile_mode =
+				DC_ADDR_SURF_MICRO_TILING_DISPLAY;
+	} else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE)
+			== DC_ARRAY_1D_TILED_THIN1) {
+		tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1;
+	}
 
-	return offset ? (address + offset * 256) : 0;
+	tiling_info->gfx8.pipe_config =
+			AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
+}
+
+static void
+fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev,
+				  union dc_tiling_info *tiling_info)
+{
+	tiling_info->gfx9.num_pipes =
+		adev->gfx.config.gb_addr_config_fields.num_pipes;
+	tiling_info->gfx9.num_banks =
+		adev->gfx.config.gb_addr_config_fields.num_banks;
+	tiling_info->gfx9.pipe_interleave =
+		adev->gfx.config.gb_addr_config_fields.pipe_interleave_size;
+	tiling_info->gfx9.num_shader_engines =
+		adev->gfx.config.gb_addr_config_fields.num_se;
+	tiling_info->gfx9.max_compressed_frags =
+		adev->gfx.config.gb_addr_config_fields.max_compress_frags;
+	tiling_info->gfx9.num_rb_per_se =
+		adev->gfx.config.gb_addr_config_fields.num_rb_per_se;
+	tiling_info->gfx9.shaderEnable = 1;
+#ifdef CONFIG_DRM_AMD_DC_DCN3_0
+	if (adev->asic_type == CHIP_SIENNA_CICHLID ||
+	    adev->asic_type == CHIP_NAVY_FLOUNDER ||
+	    adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
+	    adev->asic_type == CHIP_VANGOGH)
+		tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs;
+#endif
 }
 
 static int
-fill_plane_dcc_attributes(struct amdgpu_device *adev,
-			  const struct amdgpu_framebuffer *afb,
-			  const enum surface_pixel_format format,
-			  const enum dc_rotation_angle rotation,
-			  const struct plane_size *plane_size,
-			  const union dc_tiling_info *tiling_info,
-			  const uint64_t info,
-			  struct dc_plane_dcc_param *dcc,
-			  struct dc_plane_address *address,
-			  bool force_disable_dcc)
+validate_dcc(struct amdgpu_device *adev,
+	     const enum surface_pixel_format format,
+	     const enum dc_rotation_angle rotation,
+	     const union dc_tiling_info *tiling_info,
+	     const struct dc_plane_dcc_param *dcc,
+	     const struct dc_plane_address *address,
+	     const struct plane_size *plane_size)
 {
 	struct dc *dc = adev->dm.dc;
 	struct dc_dcc_surface_param input;
 	struct dc_surface_dcc_cap output;
-	uint64_t plane_address = afb->address + afb->base.offsets[0];
-	uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
-	uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
-	uint64_t dcc_address;
 
 	memset(&input, 0, sizeof(input));
 	memset(&output, 0, sizeof(output));
 
-	if (force_disable_dcc)
+	if (!dcc->enable)
 		return 0;
 
-	if (!offset)
-		return 0;
-
-	if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
-		return -EINVAL;
-
-	if (!dc->cap_funcs.get_dcc_compression_cap)
+	if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ||
+	    !dc->cap_funcs.get_dcc_compression_cap)
 		return -EINVAL;
 
 	input.format = format;
@@ -3897,17 +3937,60 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
 	if (!output.capable)
 		return -EINVAL;
 
-	if (i64b == 0 && output.grph.rgb.independent_64b_blks != 0)
+	if (dcc->independent_64b_blks == 0 &&
+	    output.grph.rgb.independent_64b_blks != 0)
 		return -EINVAL;
 
+	return 0;
+}
+
+static void
+fill_dcc_params_from_flags(const struct amdgpu_framebuffer *afb,
+			   struct dc_plane_dcc_param *dcc,
+			   struct dc_plane_address *address,
+			   const uint64_t flags, bool force_disable_dcc)
+{
+	uint64_t dcc_address;
+	uint64_t plane_address = afb->address + afb->base.offsets[0];
+	uint32_t offset = AMDGPU_TILING_GET(flags, DCC_OFFSET_256B);
+	uint32_t i64b = AMDGPU_TILING_GET(flags, DCC_INDEPENDENT_64B) != 0;
+
+	if (!offset || force_disable_dcc)
+		return;
+
 	dcc->enable = 1;
-	dcc->meta_pitch =
-		AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
+	dcc->meta_pitch = AMDGPU_TILING_GET(flags, DCC_PITCH_MAX) + 1;
 	dcc->independent_64b_blks = i64b;
 
-	dcc_address = get_dcc_address(plane_address, info);
+	dcc_address = plane_address + (uint64_t)offset * 256;
 	address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
 	address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
+}
+
+
+static int
+fill_gfx9_plane_attributes_from_flags(struct amdgpu_device *adev,
+				      const struct amdgpu_framebuffer *afb,
+				      const enum surface_pixel_format format,
+				      const enum dc_rotation_angle rotation,
+				      const struct plane_size *plane_size,
+				      union dc_tiling_info *tiling_info,
+				      struct dc_plane_dcc_param *dcc,
+				      struct dc_plane_address *address,
+				      uint64_t tiling_flags,
+				      bool force_disable_dcc)
+{
+	int ret;
+
+	fill_gfx9_tiling_info_from_device(adev, tiling_info);
+
+	tiling_info->gfx9.swizzle =
+		AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
+
+	fill_dcc_params_from_flags(afb, dcc, address, tiling_flags, force_disable_dcc);
+	ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size);
+	if (ret)
+		return ret;
 
 	return 0;
 }
@@ -3979,82 +4062,15 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 			upper_32_bits(chroma_addr);
 	}
 
-	/* Fill GFX8 params */
-	if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) {
-		unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
-
-		bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
-		bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
-		mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
-		tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT);
-		num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
-
-		/* XXX fix me for VI */
-		tiling_info->gfx8.num_banks = num_banks;
-		tiling_info->gfx8.array_mode =
-				DC_ARRAY_2D_TILED_THIN1;
-		tiling_info->gfx8.tile_split = tile_split;
-		tiling_info->gfx8.bank_width = bankw;
-		tiling_info->gfx8.bank_height = bankh;
-		tiling_info->gfx8.tile_aspect = mtaspect;
-		tiling_info->gfx8.tile_mode =
-				DC_ADDR_SURF_MICRO_TILING_DISPLAY;
-	} else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE)
-			== DC_ARRAY_1D_TILED_THIN1) {
-		tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1;
-	}
-
-	tiling_info->gfx8.pipe_config =
-			AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
-
-	if (adev->asic_type == CHIP_VEGA10 ||
-	    adev->asic_type == CHIP_VEGA12 ||
-	    adev->asic_type == CHIP_VEGA20 ||
-	    adev->asic_type == CHIP_NAVI10 ||
-	    adev->asic_type == CHIP_NAVI14 ||
-	    adev->asic_type == CHIP_NAVI12 ||
-#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
-		adev->asic_type == CHIP_SIENNA_CICHLID ||
-		adev->asic_type == CHIP_NAVY_FLOUNDER ||
-#endif
-#if defined(CONFIG_DRM_AMD_DC_DCN3_02)
-		adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
-#endif
-#if defined(CONFIG_DRM_AMD_DC_DCN3_01)
-		adev->asic_type == CHIP_VANGOGH ||
-#endif
-	    adev->asic_type == CHIP_RENOIR ||
-	    adev->asic_type == CHIP_RAVEN) {
-		/* Fill GFX9 params */
-		tiling_info->gfx9.num_pipes =
-			adev->gfx.config.gb_addr_config_fields.num_pipes;
-		tiling_info->gfx9.num_banks =
-			adev->gfx.config.gb_addr_config_fields.num_banks;
-		tiling_info->gfx9.pipe_interleave =
-			adev->gfx.config.gb_addr_config_fields.pipe_interleave_size;
-		tiling_info->gfx9.num_shader_engines =
-			adev->gfx.config.gb_addr_config_fields.num_se;
-		tiling_info->gfx9.max_compressed_frags =
-			adev->gfx.config.gb_addr_config_fields.max_compress_frags;
-		tiling_info->gfx9.num_rb_per_se =
-			adev->gfx.config.gb_addr_config_fields.num_rb_per_se;
-		tiling_info->gfx9.swizzle =
-			AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
-		tiling_info->gfx9.shaderEnable = 1;
-
-#ifdef CONFIG_DRM_AMD_DC_DCN3_0
-		if (adev->asic_type == CHIP_SIENNA_CICHLID ||
-		    adev->asic_type == CHIP_NAVY_FLOUNDER ||
-		    adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
-		    adev->asic_type == CHIP_VANGOGH)
-			tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs;
-#endif
-		ret = fill_plane_dcc_attributes(adev, afb, format, rotation,
-						plane_size, tiling_info,
-						tiling_flags, dcc, address,
-						force_disable_dcc);
+	if (adev->family >= AMDGPU_FAMILY_AI) {
+		ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, rotation,
+							    plane_size, tiling_info, dcc,
+							    address, tiling_flags,
+							    force_disable_dcc);
 		if (ret)
 			return ret;
+	} else {
+		fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
 	}
 
 	return 0;
-- 
2.28.0

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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 08/11] drm/amd/display: Set DC options from modifiers.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
                   ` (6 preceding siblings ...)
  2020-10-21 23:31 ` [PATCH v3 07/11] drm/amd/display: Refactor surface tiling setup Bas Nieuwenhuizen
@ 2020-10-21 23:31 ` Bas Nieuwenhuizen
  2020-10-21 23:31 ` [PATCH v3 09/11] drm/amd/display: Add formats for DCC with 2/3 planes Bas Nieuwenhuizen
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, daniel, Bas Nieuwenhuizen, alexdeucher,
	harry.wentland, nicholas.kazlauskas

This sets the DC tiling options from the modifier, if modifiers
are used for the FB. This patch by itself does not expose the
support yet though.

There is not much validation yet to limit the scope of this
patch, but the current validation is at the same level as
the BO metadata path.

v2: Add modifier check to should_reset_plane.

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 102 ++++++++++++++++--
 1 file changed, 95 insertions(+), 7 deletions(-)

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 479c886816d9..034397c1f2b1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3995,6 +3995,83 @@ fill_gfx9_plane_attributes_from_flags(struct amdgpu_device *adev,
 	return 0;
 }
 
+static bool
+modifier_has_dcc(uint64_t modifier)
+{
+	return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
+}
+
+static unsigned
+modifier_gfx9_swizzle_mode(uint64_t modifier)
+{
+	if (modifier == DRM_FORMAT_MOD_LINEAR)
+		return 0;
+
+	return AMD_FMT_MOD_GET(TILE, modifier);
+}
+
+static void
+fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev,
+				    union dc_tiling_info *tiling_info,
+				    uint64_t modifier)
+{
+	unsigned int mod_bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, modifier);
+	unsigned int mod_pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier);
+	unsigned int pkrs_log2 = AMD_FMT_MOD_GET(PACKERS, modifier);
+	unsigned int pipes_log2 = min(4u, mod_pipe_xor_bits);
+
+	fill_gfx9_tiling_info_from_device(adev, tiling_info);
+
+	if (!IS_AMD_FMT_MOD(modifier))
+		return;
+
+	tiling_info->gfx9.num_pipes = 1u << pipes_log2;
+	tiling_info->gfx9.num_shader_engines = 1u << (mod_pipe_xor_bits - pipes_log2);
+
+	if (adev->family >= AMDGPU_FAMILY_NV) {
+		tiling_info->gfx9.num_pkrs = 1u << pkrs_log2;
+	} else {
+		tiling_info->gfx9.num_banks = 1u << mod_bank_xor_bits;
+
+		/* for DCC we know it isn't rb aligned, so rb_per_se doesn't matter. */
+	}
+}
+
+static int
+fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
+					  const struct amdgpu_framebuffer *afb,
+					  const enum surface_pixel_format format,
+					  const enum dc_rotation_angle rotation,
+					  const struct plane_size *plane_size,
+					  union dc_tiling_info *tiling_info,
+					  struct dc_plane_dcc_param *dcc,
+					  struct dc_plane_address *address,
+					  const bool force_disable_dcc)
+{
+	const uint64_t modifier = afb->base.modifier;
+	int ret;
+
+	fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier);
+	tiling_info->gfx9.swizzle = modifier_gfx9_swizzle_mode(modifier);
+
+	if (modifier_has_dcc(modifier) && !force_disable_dcc) {
+		uint64_t dcc_address = afb->address + afb->base.offsets[1];
+
+		dcc->enable = 1;
+		dcc->meta_pitch = afb->base.pitches[1];
+		dcc->independent_64b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier);
+
+		address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
+		address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
+	}
+
+	ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int
 fill_plane_buffer_attributes(struct amdgpu_device *adev,
 			     const struct amdgpu_framebuffer *afb,
@@ -4063,12 +4140,22 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 	}
 
 	if (adev->family >= AMDGPU_FAMILY_AI) {
-		ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, rotation,
-							    plane_size, tiling_info, dcc,
-							    address, tiling_flags,
-							    force_disable_dcc);
-		if (ret)
-			return ret;
+		if (afb->base.flags & DRM_MODE_FB_MODIFIERS) {
+			ret = fill_gfx9_plane_attributes_from_modifiers(adev, afb, format,
+									rotation, plane_size,
+									tiling_info, dcc,
+									address,
+									force_disable_dcc);
+			if (ret)
+				return ret;
+		} else {
+			ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, rotation,
+								    plane_size, tiling_info, dcc,
+								    address, tiling_flags,
+								    force_disable_dcc);
+			if (ret)
+				return ret;
+		}
 	} else {
 		fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
 	}
@@ -8511,7 +8598,8 @@ static bool should_reset_plane(struct drm_atomic_state *state,
 		new_afb = (struct amdgpu_framebuffer *)new_other_state->fb;
 
 		/* Tiling and DCC changes also require bandwidth updates. */
-		if (old_afb->tiling_flags != new_afb->tiling_flags)
+		if (old_afb->tiling_flags != new_afb->tiling_flags ||
+		    old_afb->base.modifier != new_afb->base.modifier)
 			return true;
 	}
 
-- 
2.28.0

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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 09/11] drm/amd/display: Add formats for DCC with 2/3 planes.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
                   ` (7 preceding siblings ...)
  2020-10-21 23:31 ` [PATCH v3 08/11] drm/amd/display: Set DC options from modifiers Bas Nieuwenhuizen
@ 2020-10-21 23:31 ` Bas Nieuwenhuizen
  2020-10-21 23:31 ` [PATCH v3 10/11] drm/amd/display: Expose modifiers Bas Nieuwenhuizen
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, daniel, Bas Nieuwenhuizen, alexdeucher,
	harry.wentland, nicholas.kazlauskas

For DCC we will use 2/3 planes to avoid X rendering to the frontbuffer
with DCC compressed images. To make this work with the core KMS
validation we need to add extra formats with the extra planes.

However, due to flexibility we set bpp = 0 for the extra planes and
do the validation ourselves.

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 96 +++++++++++++++++++
 1 file changed, 96 insertions(+)

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 034397c1f2b1..6b33e030fe20 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -185,6 +185,9 @@ static bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream);
 static bool amdgpu_dm_psr_disable(struct dc_stream_state *stream);
 static bool amdgpu_dm_psr_disable_all(struct amdgpu_display_manager *dm);
 
+static const struct drm_format_info *
+amd_get_format_info(const struct drm_mode_fb_cmd2 *cmd);
+
 /*
  * dm_vblank_get_counter
  *
@@ -2160,6 +2163,7 @@ const struct amdgpu_ip_block_version dm_ip_block =
 
 static const struct drm_mode_config_funcs amdgpu_dm_mode_funcs = {
 	.fb_create = amdgpu_display_user_framebuffer_create,
+	.get_format_info = amd_get_format_info,
 	.output_poll_changed = drm_fb_helper_output_poll_changed,
 	.atomic_check = amdgpu_dm_atomic_check,
 	.atomic_commit = amdgpu_dm_atomic_commit,
@@ -4010,6 +4014,98 @@ 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;
+}
+
 static void
 fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev,
 				    union dc_tiling_info *tiling_info,
-- 
2.28.0

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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 10/11] drm/amd/display: Expose modifiers.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
                   ` (8 preceding siblings ...)
  2020-10-21 23:31 ` [PATCH v3 09/11] drm/amd/display: Add formats for DCC with 2/3 planes Bas Nieuwenhuizen
@ 2020-10-21 23:31 ` Bas Nieuwenhuizen
  2020-10-22  5:50   ` Alex Deucher
  2020-10-21 23:31 ` [PATCH v3 11/11] drm/amd/display: Clean up GFX9 tiling_flags path Bas Nieuwenhuizen
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, daniel, Bas Nieuwenhuizen, alexdeucher,
	harry.wentland, nicholas.kazlauskas

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.

v2:
  - Added comment that D on Raven is only valid for 64bpp
    and will be filtered based on format later.
  - Removed D tiling modes that weren't useful for 64bpp
    on GFX10+.

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 338 +++++++++++++++++-
 1 file changed, 337 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 6b33e030fe20..a1ce325f2fd1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4133,6 +4133,335 @@ 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 = drm_to_adev(plane->dev);
+	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) {
+		/* Raven2 and later */
+		bool has_constant_encode = adev->asic_type > CHIP_RAVEN || adev->external_rev_id >= 0x81;
+
+		/*
+		 * No _D DCC swizzles yet because we only allow 32bpp, which
+		 * doesn't support _D on DCN
+		 */
+
+		if (has_constant_encode) {
+			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));
+		}
+
+		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));
+
+		if (has_constant_encode) {
+			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));
+	}
+
+	/*
+	 * Only supported for 64bpp on Raven, will be filtered on format in
+	 * dm_plane_format_mod_supported.
+	 */
+	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));
+
+	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));
+	}
+
+	/*
+	 * Only supported for 64bpp on Raven, will be filtered on format in
+	 * dm_plane_format_mod_supported.
+	 */
+	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_S_X) |
+		    AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
+		    AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
+
+
+	/* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */
+	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_S_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));
+
+	/* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */
+	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 int
+get_plane_modifiers(const struct amdgpu_device *adev, unsigned int plane_type, uint64_t **mods)
+{
+	uint64_t size = 0, capacity = 128;
+	*mods = NULL;
+
+	/* We have not hooked up any pre-GFX9 modifiers. */
+	if (adev->family < AMDGPU_FAMILY_AI)
+		return 0;
+
+	*mods = kmalloc(capacity * sizeof(uint64_t), GFP_KERNEL);
+
+	if (plane_type == DRM_PLANE_TYPE_CURSOR) {
+		add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
+		add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
+		return *mods ? 0 : -ENOMEM;
+	}
+
+	switch (adev->family) {
+	case AMDGPU_FAMILY_AI:
+	case AMDGPU_FAMILY_RV:
+		add_gfx9_modifiers(adev, mods, &size, &capacity);
+		break;
+	case AMDGPU_FAMILY_NV:
+		if (adev->asic_type >= CHIP_SIENNA_CICHLID)
+			add_gfx10_3_modifiers(adev, mods, &size, &capacity);
+		else
+			add_gfx10_1_modifiers(adev, mods, &size, &capacity);
+		break;
+	}
+
+	add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
+
+	/* INVALID marks the end of the list. */
+	add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
+
+	if (!*mods)
+		return -ENOMEM;
+
+	return 0;
+}
+
 static int
 fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
 					  const struct amdgpu_framebuffer *afb,
@@ -6100,6 +6429,7 @@ static const struct drm_plane_funcs dm_plane_funcs = {
 	.reset = dm_drm_plane_reset,
 	.atomic_duplicate_state = dm_drm_plane_duplicate_state,
 	.atomic_destroy_state = dm_drm_plane_destroy_state,
+	.format_mod_supported = dm_plane_format_mod_supported,
 };
 
 static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
@@ -6392,13 +6722,19 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
 	int num_formats;
 	int res = -EPERM;
 	unsigned int supported_rotations;
+	uint64_t *modifiers = NULL;
 
 	num_formats = get_plane_formats(plane, plane_cap, formats,
 					ARRAY_SIZE(formats));
 
+	res = get_plane_modifiers(dm->adev, plane->type, &modifiers);
+	if (res)
+		return res;
+
 	res = drm_universal_plane_init(adev_to_drm(dm->adev), plane, possible_crtcs,
 				       &dm_plane_funcs, formats, num_formats,
-				       NULL, plane->type, NULL);
+				       modifiers, plane->type, NULL);
+	kfree(modifiers);
 	if (res)
 		return res;
 
-- 
2.28.0

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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH v3 11/11] drm/amd/display: Clean up GFX9 tiling_flags path.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
                   ` (9 preceding siblings ...)
  2020-10-21 23:31 ` [PATCH v3 10/11] drm/amd/display: Expose modifiers Bas Nieuwenhuizen
@ 2020-10-21 23:31 ` Bas Nieuwenhuizen
  2020-10-22 16:55 ` [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Alex Deucher
  2020-10-26  8:28 ` Pierre-Eric Pelloux-Prayer
  12 siblings, 0 replies; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-21 23:31 UTC (permalink / raw)
  To: amd-gfx
  Cc: maraeo, sunpeng.li, daniel, Bas Nieuwenhuizen, alexdeucher,
	harry.wentland, nicholas.kazlauskas

We're unconditionally using modifiers internally for GFX9+ now.

Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 74 ++-----------------
 1 file changed, 7 insertions(+), 67 deletions(-)

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 a1ce325f2fd1..ed7215737b22 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3948,57 +3948,6 @@ validate_dcc(struct amdgpu_device *adev,
 	return 0;
 }
 
-static void
-fill_dcc_params_from_flags(const struct amdgpu_framebuffer *afb,
-			   struct dc_plane_dcc_param *dcc,
-			   struct dc_plane_address *address,
-			   const uint64_t flags, bool force_disable_dcc)
-{
-	uint64_t dcc_address;
-	uint64_t plane_address = afb->address + afb->base.offsets[0];
-	uint32_t offset = AMDGPU_TILING_GET(flags, DCC_OFFSET_256B);
-	uint32_t i64b = AMDGPU_TILING_GET(flags, DCC_INDEPENDENT_64B) != 0;
-
-	if (!offset || force_disable_dcc)
-		return;
-
-	dcc->enable = 1;
-	dcc->meta_pitch = AMDGPU_TILING_GET(flags, DCC_PITCH_MAX) + 1;
-	dcc->independent_64b_blks = i64b;
-
-	dcc_address = plane_address + (uint64_t)offset * 256;
-	address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
-	address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
-}
-
-
-static int
-fill_gfx9_plane_attributes_from_flags(struct amdgpu_device *adev,
-				      const struct amdgpu_framebuffer *afb,
-				      const enum surface_pixel_format format,
-				      const enum dc_rotation_angle rotation,
-				      const struct plane_size *plane_size,
-				      union dc_tiling_info *tiling_info,
-				      struct dc_plane_dcc_param *dcc,
-				      struct dc_plane_address *address,
-				      uint64_t tiling_flags,
-				      bool force_disable_dcc)
-{
-	int ret;
-
-	fill_gfx9_tiling_info_from_device(adev, tiling_info);
-
-	tiling_info->gfx9.swizzle =
-		AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
-
-	fill_dcc_params_from_flags(afb, dcc, address, tiling_flags, force_disable_dcc);
-	ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
 static bool
 modifier_has_dcc(uint64_t modifier)
 {
@@ -4565,22 +4514,13 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
 	}
 
 	if (adev->family >= AMDGPU_FAMILY_AI) {
-		if (afb->base.flags & DRM_MODE_FB_MODIFIERS) {
-			ret = fill_gfx9_plane_attributes_from_modifiers(adev, afb, format,
-									rotation, plane_size,
-									tiling_info, dcc,
-									address,
-									force_disable_dcc);
-			if (ret)
-				return ret;
-		} else {
-			ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, rotation,
-								    plane_size, tiling_info, dcc,
-								    address, tiling_flags,
-								    force_disable_dcc);
-			if (ret)
-				return ret;
-		}
+		ret = fill_gfx9_plane_attributes_from_modifiers(adev, afb, format,
+								rotation, plane_size,
+								tiling_info, dcc,
+								address,
+								force_disable_dcc);
+		if (ret)
+			return ret;
 	} else {
 		fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
 	}
-- 
2.28.0

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

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 10/11] drm/amd/display: Expose modifiers.
  2020-10-21 23:31 ` [PATCH v3 10/11] drm/amd/display: Expose modifiers Bas Nieuwenhuizen
@ 2020-10-22  5:50   ` Alex Deucher
  2020-10-22 11:44     ` Bas Nieuwenhuizen
  0 siblings, 1 reply; 25+ messages in thread
From: Alex Deucher @ 2020-10-22  5:50 UTC (permalink / raw)
  To: Bas Nieuwenhuizen
  Cc: Marek Olsak, Leo (Sunpeng) Li, amd-gfx list, Daniel Vetter,
	Wentland, Harry, Kazlauskas, Nicholas

On Wed, Oct 21, 2020 at 7:31 PM Bas Nieuwenhuizen
<bas@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.
>
> v2:
>   - Added comment that D on Raven is only valid for 64bpp
>     and will be filtered based on format later.
>   - Removed D tiling modes that weren't useful for 64bpp
>     on GFX10+.
>
> Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 338 +++++++++++++++++-
>  1 file changed, 337 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 6b33e030fe20..a1ce325f2fd1 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -4133,6 +4133,335 @@ 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 = drm_to_adev(plane->dev);
> +       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) {
> +               /* Raven2 and later */
> +               bool has_constant_encode = adev->asic_type > CHIP_RAVEN || adev->external_rev_id >= 0x81;
> +
> +               /*
> +                * No _D DCC swizzles yet because we only allow 32bpp, which
> +                * doesn't support _D on DCN
> +                */
> +
> +               if (has_constant_encode) {
> +                       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));
> +               }
> +
> +               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));
> +
> +               if (has_constant_encode) {
> +                       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));
> +       }
> +
> +       /*
> +        * Only supported for 64bpp on Raven, will be filtered on format in
> +        * dm_plane_format_mod_supported.
> +        */
> +       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));
> +
> +       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));
> +       }
> +
> +       /*
> +        * Only supported for 64bpp on Raven, will be filtered on format in
> +        * dm_plane_format_mod_supported.
> +        */
> +       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_S_X) |
> +                   AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
> +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
> +
> +
> +       /* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */
> +       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_S_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));
> +
> +       /* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */
> +       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 int
> +get_plane_modifiers(const struct amdgpu_device *adev, unsigned int plane_type, uint64_t **mods)
> +{
> +       uint64_t size = 0, capacity = 128;
> +       *mods = NULL;
> +
> +       /* We have not hooked up any pre-GFX9 modifiers. */
> +       if (adev->family < AMDGPU_FAMILY_AI)
> +               return 0;
> +
> +       *mods = kmalloc(capacity * sizeof(uint64_t), GFP_KERNEL);
> +
> +       if (plane_type == DRM_PLANE_TYPE_CURSOR) {
> +               add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
> +               add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
> +               return *mods ? 0 : -ENOMEM;
> +       }
> +
> +       switch (adev->family) {
> +       case AMDGPU_FAMILY_AI:
> +       case AMDGPU_FAMILY_RV:
> +               add_gfx9_modifiers(adev, mods, &size, &capacity);
> +               break;
> +       case AMDGPU_FAMILY_NV:

Should probably add:
case AMDGPU_FAMILY_VGH:
here as well.

Alex

> +               if (adev->asic_type >= CHIP_SIENNA_CICHLID)
> +                       add_gfx10_3_modifiers(adev, mods, &size, &capacity);
> +               else
> +                       add_gfx10_1_modifiers(adev, mods, &size, &capacity);
> +               break;
> +       }
> +
> +       add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
> +
> +       /* INVALID marks the end of the list. */
> +       add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
> +
> +       if (!*mods)
> +               return -ENOMEM;
> +
> +       return 0;
> +}
> +
>  static int
>  fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
>                                           const struct amdgpu_framebuffer *afb,
> @@ -6100,6 +6429,7 @@ static const struct drm_plane_funcs dm_plane_funcs = {
>         .reset = dm_drm_plane_reset,
>         .atomic_duplicate_state = dm_drm_plane_duplicate_state,
>         .atomic_destroy_state = dm_drm_plane_destroy_state,
> +       .format_mod_supported = dm_plane_format_mod_supported,
>  };
>
>  static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
> @@ -6392,13 +6722,19 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
>         int num_formats;
>         int res = -EPERM;
>         unsigned int supported_rotations;
> +       uint64_t *modifiers = NULL;
>
>         num_formats = get_plane_formats(plane, plane_cap, formats,
>                                         ARRAY_SIZE(formats));
>
> +       res = get_plane_modifiers(dm->adev, plane->type, &modifiers);
> +       if (res)
> +               return res;
> +
>         res = drm_universal_plane_init(adev_to_drm(dm->adev), plane, possible_crtcs,
>                                        &dm_plane_funcs, formats, num_formats,
> -                                      NULL, plane->type, NULL);
> +                                      modifiers, plane->type, NULL);
> +       kfree(modifiers);
>         if (res)
>                 return res;
>
> --
> 2.28.0
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 10/11] drm/amd/display: Expose modifiers.
  2020-10-22  5:50   ` Alex Deucher
@ 2020-10-22 11:44     ` Bas Nieuwenhuizen
  0 siblings, 0 replies; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-22 11:44 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Marek Olsak, Leo (Sunpeng) Li, amd-gfx list, Daniel Vetter,
	Wentland, Harry, Kazlauskas, Nicholas

You are totally right! Added that locally.

Thanks!

On Thu, Oct 22, 2020 at 7:51 AM Alex Deucher <alexdeucher@gmail.com> wrote:
>
> On Wed, Oct 21, 2020 at 7:31 PM Bas Nieuwenhuizen
> <bas@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.
> >
> > v2:
> >   - Added comment that D on Raven is only valid for 64bpp
> >     and will be filtered based on format later.
> >   - Removed D tiling modes that weren't useful for 64bpp
> >     on GFX10+.
> >
> > Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> > ---
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 338 +++++++++++++++++-
> >  1 file changed, 337 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 6b33e030fe20..a1ce325f2fd1 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > @@ -4133,6 +4133,335 @@ 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 = drm_to_adev(plane->dev);
> > +       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) {
> > +               /* Raven2 and later */
> > +               bool has_constant_encode = adev->asic_type > CHIP_RAVEN || adev->external_rev_id >= 0x81;
> > +
> > +               /*
> > +                * No _D DCC swizzles yet because we only allow 32bpp, which
> > +                * doesn't support _D on DCN
> > +                */
> > +
> > +               if (has_constant_encode) {
> > +                       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));
> > +               }
> > +
> > +               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));
> > +
> > +               if (has_constant_encode) {
> > +                       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));
> > +       }
> > +
> > +       /*
> > +        * Only supported for 64bpp on Raven, will be filtered on format in
> > +        * dm_plane_format_mod_supported.
> > +        */
> > +       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));
> > +
> > +       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));
> > +       }
> > +
> > +       /*
> > +        * Only supported for 64bpp on Raven, will be filtered on format in
> > +        * dm_plane_format_mod_supported.
> > +        */
> > +       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_S_X) |
> > +                   AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
> > +                   AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
> > +
> > +
> > +       /* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */
> > +       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_S_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));
> > +
> > +       /* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */
> > +       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 int
> > +get_plane_modifiers(const struct amdgpu_device *adev, unsigned int plane_type, uint64_t **mods)
> > +{
> > +       uint64_t size = 0, capacity = 128;
> > +       *mods = NULL;
> > +
> > +       /* We have not hooked up any pre-GFX9 modifiers. */
> > +       if (adev->family < AMDGPU_FAMILY_AI)
> > +               return 0;
> > +
> > +       *mods = kmalloc(capacity * sizeof(uint64_t), GFP_KERNEL);
> > +
> > +       if (plane_type == DRM_PLANE_TYPE_CURSOR) {
> > +               add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
> > +               add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
> > +               return *mods ? 0 : -ENOMEM;
> > +       }
> > +
> > +       switch (adev->family) {
> > +       case AMDGPU_FAMILY_AI:
> > +       case AMDGPU_FAMILY_RV:
> > +               add_gfx9_modifiers(adev, mods, &size, &capacity);
> > +               break;
> > +       case AMDGPU_FAMILY_NV:
>
> Should probably add:
> case AMDGPU_FAMILY_VGH:
> here as well.
>
> Alex
>
> > +               if (adev->asic_type >= CHIP_SIENNA_CICHLID)
> > +                       add_gfx10_3_modifiers(adev, mods, &size, &capacity);
> > +               else
> > +                       add_gfx10_1_modifiers(adev, mods, &size, &capacity);
> > +               break;
> > +       }
> > +
> > +       add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
> > +
> > +       /* INVALID marks the end of the list. */
> > +       add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
> > +
> > +       if (!*mods)
> > +               return -ENOMEM;
> > +
> > +       return 0;
> > +}
> > +
> >  static int
> >  fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
> >                                           const struct amdgpu_framebuffer *afb,
> > @@ -6100,6 +6429,7 @@ static const struct drm_plane_funcs dm_plane_funcs = {
> >         .reset = dm_drm_plane_reset,
> >         .atomic_duplicate_state = dm_drm_plane_duplicate_state,
> >         .atomic_destroy_state = dm_drm_plane_destroy_state,
> > +       .format_mod_supported = dm_plane_format_mod_supported,
> >  };
> >
> >  static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
> > @@ -6392,13 +6722,19 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
> >         int num_formats;
> >         int res = -EPERM;
> >         unsigned int supported_rotations;
> > +       uint64_t *modifiers = NULL;
> >
> >         num_formats = get_plane_formats(plane, plane_cap, formats,
> >                                         ARRAY_SIZE(formats));
> >
> > +       res = get_plane_modifiers(dm->adev, plane->type, &modifiers);
> > +       if (res)
> > +               return res;
> > +
> >         res = drm_universal_plane_init(adev_to_drm(dm->adev), plane, possible_crtcs,
> >                                        &dm_plane_funcs, formats, num_formats,
> > -                                      NULL, plane->type, NULL);
> > +                                      modifiers, plane->type, NULL);
> > +       kfree(modifiers);
> >         if (res)
> >                 return res;
> >
> > --
> > 2.28.0
> >
> > _______________________________________________
> > amd-gfx mailing list
> > amd-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 03/11] drm/amd/display: Honor the offset for plane 0.
  2020-10-21 23:31 ` [PATCH v3 03/11] drm/amd/display: Honor the offset for plane 0 Bas Nieuwenhuizen
@ 2020-10-22 15:36   ` Alex Deucher
  2020-10-22 16:10     ` Greg KH
  2020-10-26 13:51   ` Kazlauskas, Nicholas
  1 sibling, 1 reply; 25+ messages in thread
From: Alex Deucher @ 2020-10-22 15:36 UTC (permalink / raw)
  To: Bas Nieuwenhuizen
  Cc: Marek Olsak, Leo (Sunpeng) Li, amd-gfx list, for 3.8,
	Daniel Vetter, Wentland, Harry, Kazlauskas, Nicholas

On Wed, Oct 21, 2020 at 7:31 PM Bas Nieuwenhuizen
<bas@basnieuwenhuizen.nl> wrote:
>
> With modifiers I'd like to support non-dedicated buffers for
> images.
>
> Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> Cc: stable@vger.kernel.org # 5.1.0

I think you need # 5.1.x- for it to be applied to all stable kernels
since 5.1 otherwise it will just apply to 5.1.x

Alex

> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)
>
> 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 73987fdb6a09..833887b9b0ad 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3894,6 +3894,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
>         struct dc *dc = adev->dm.dc;
>         struct dc_dcc_surface_param input;
>         struct dc_surface_dcc_cap output;
> +       uint64_t plane_address = afb->address + afb->base.offsets[0];
>         uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
>         uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
>         uint64_t dcc_address;
> @@ -3937,7 +3938,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
>                 AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
>         dcc->independent_64b_blks = i64b;
>
> -       dcc_address = get_dcc_address(afb->address, info);
> +       dcc_address = get_dcc_address(plane_address, info);
>         address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
>         address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
>
> @@ -3968,6 +3969,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
>         address->tmz_surface = tmz_surface;
>
>         if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
> +               uint64_t addr = afb->address + fb->offsets[0];
> +
>                 plane_size->surface_size.x = 0;
>                 plane_size->surface_size.y = 0;
>                 plane_size->surface_size.width = fb->width;
> @@ -3976,9 +3979,10 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
>                         fb->pitches[0] / fb->format->cpp[0];
>
>                 address->type = PLN_ADDR_TYPE_GRAPHICS;
> -               address->grph.addr.low_part = lower_32_bits(afb->address);
> -               address->grph.addr.high_part = upper_32_bits(afb->address);
> +               address->grph.addr.low_part = lower_32_bits(addr);
> +               address->grph.addr.high_part = upper_32_bits(addr);
>         } else if (format < SURFACE_PIXEL_FORMAT_INVALID) {
> +               uint64_t luma_addr = afb->address + fb->offsets[0];
>                 uint64_t chroma_addr = afb->address + fb->offsets[1];
>
>                 plane_size->surface_size.x = 0;
> @@ -3999,9 +4003,9 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
>
>                 address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
>                 address->video_progressive.luma_addr.low_part =
> -                       lower_32_bits(afb->address);
> +                       lower_32_bits(luma_addr);
>                 address->video_progressive.luma_addr.high_part =
> -                       upper_32_bits(afb->address);
> +                       upper_32_bits(luma_addr);
>                 address->video_progressive.chroma_addr.low_part =
>                         lower_32_bits(chroma_addr);
>                 address->video_progressive.chroma_addr.high_part =
> --
> 2.28.0
>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 04/11] drm/fourcc: Add AMD DRM modifiers.
  2020-10-21 23:31 ` [PATCH v3 04/11] drm/fourcc: Add AMD DRM modifiers Bas Nieuwenhuizen
@ 2020-10-22 15:41   ` Alex Deucher
  2020-10-22 16:39     ` Bas Nieuwenhuizen
  0 siblings, 1 reply; 25+ messages in thread
From: Alex Deucher @ 2020-10-22 15:41 UTC (permalink / raw)
  To: Bas Nieuwenhuizen
  Cc: Marek Olsak, Leo (Sunpeng) Li, amd-gfx list, Daniel Vetter,
	Wentland, Harry, Kazlauskas, Nicholas

On Wed, Oct 21, 2020 at 7:31 PM Bas Nieuwenhuizen
<bas@basnieuwenhuizen.nl> wrote:
>
> This adds modifiers for GFX9+ AMD GPUs.
>
> As the modifiers need a lot of parameters I split things out in
> getters and setters.
>   - Advantage: simplifies the code a lot
>   - Disadvantage: Makes it harder to check that you're setting all
>                   the required fields.
>
> The tiling modes seem to change every generation, but the structure
> of what each tiling mode is good for stays really similar. As such
> the core of the modifier is
>  - the tiling mode
>  - a version. Not explicitly a GPU generation, but splitting out
>    a new set of tiling equations.
>
> Sometimes one or two tiling modes stay the same and for those we
> specify a canonical version.
>
> Then we have a bunch of parameters on how the compression works.
> Different HW units have different requirements for these and we
> actually have some conflicts here.
>
> e.g. the render backends need a specific alignment but the display
> unit only works with unaligned compression surfaces. To work around
> that we have a DCC_RETILE option where both an aligned and unaligned
> compression surface are allocated and a writer has to sync the
> aligned surface to the unaligned surface on handoff.
>
> Finally there are some GPU parameters that participate in the tiling
> equations. These are constant for each GPU on the rendering/texturing
> side. The display unit is very flexible however and supports all
> of them :|

I think the idea is that the display engine can scanout just about
anything thrown at it (e.g., if you have multiple GPUs in a system).
E.g., you may have a laptop with a navi14 dGPU and a renoir APU.
You'd want the APU to be able to scanout from whatever format the dGPU
gave you.

Alex


>
> Some estimates:
>  - Single GPU, render+texture: ~10 modifiers
>  - All possible configs in a gen, display: ~1000 modifiers
>  - Configs of actually existing GPUs in a gen: ~100 modifiers
>
> For formats with a single plane everything gets put in a separate
> DRM plane. However, this doesn't fit for some YUV formats, so if
> the format has >1 plane, we let the driver pack the surfaces into
> 1 DRM plane per format plane.
>
> This way we avoid X11 rendering onto the frontbuffer with DCC, but
> still fit into 4 DRM planes.
>
> Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> ---
>  include/uapi/drm/drm_fourcc.h | 115 ++++++++++++++++++++++++++++++++++
>  1 file changed, 115 insertions(+)
>
> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> index 82f327801267..df56e71a7380 100644
> --- a/include/uapi/drm/drm_fourcc.h
> +++ b/include/uapi/drm/drm_fourcc.h
> @@ -1056,6 +1056,121 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
>   */
>  #define AMLOGIC_FBC_OPTION_MEM_SAVING          (1ULL << 0)
>
> +/*
> + * AMD modifiers
> + *
> + * Memory layout:
> + *
> + * without DCC:
> + *   - main surface
> + *
> + * with DCC & without DCC_RETILE:
> + *   - main surface in plane 0
> + *   - DCC surface in plane 1 (RB-aligned, pipe-aligned if DCC_PIPE_ALIGN is set)
> + *
> + * with DCC & DCC_RETILE:
> + *   - main surface in plane 0
> + *   - displayable DCC surface in plane 1 (not RB-aligned & not pipe-aligned)
> + *   - pipe-aligned DCC surface in plane 2 (RB-aligned & pipe-aligned)
> + *
> + * For multi-plane formats the above surfaces get merged into one plane for
> + * each format plane, based on the required alignment only.
> + */
> +#define AMD_FMT_MOD fourcc_mod_code(AMD, 0)
> +
> +#define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD)
> +
> +/* Reserve 0 for GFX8 and older */
> +#define AMD_FMT_MOD_TILE_VER_GFX9 1
> +#define AMD_FMT_MOD_TILE_VER_GFX10 2
> +#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
> +
> +/*
> + * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical
> + * version.
> + */
> +#define AMD_FMT_MOD_TILE_GFX9_64K_S 9
> +
> +/*
> + * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has
> + * GFX9 as canonical version.
> + */
> +#define AMD_FMT_MOD_TILE_GFX9_64K_D 10
> +#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
> +#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26
> +#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
> +
> +#define AMD_FMT_MOD_DCC_BLOCK_64B 0
> +#define AMD_FMT_MOD_DCC_BLOCK_128B 1
> +#define AMD_FMT_MOD_DCC_BLOCK_256B 2
> +
> +#define AMD_FMT_MOD_TILE_VERSION_SHIFT 0
> +#define AMD_FMT_MOD_TILE_VERSION_MASK 0xFF
> +#define AMD_FMT_MOD_TILE_SHIFT 8
> +#define AMD_FMT_MOD_TILE_MASK 0x1F
> +
> +/* Whether DCC compression is enabled. */
> +#define AMD_FMT_MOD_DCC_SHIFT 13
> +#define AMD_FMT_MOD_DCC_MASK 0x1
> +
> +/*
> + * Whether to include two DCC surfaces, one which is rb & pipe aligned, and
> + * one which is not-aligned.
> + */
> +#define AMD_FMT_MOD_DCC_RETILE_SHIFT 14
> +#define AMD_FMT_MOD_DCC_RETILE_MASK 0x1
> +
> +/* Only set if DCC_RETILE = false */
> +#define AMD_FMT_MOD_DCC_PIPE_ALIGN_SHIFT 15
> +#define AMD_FMT_MOD_DCC_PIPE_ALIGN_MASK 0x1
> +
> +#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_SHIFT 16
> +#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_MASK 0x1
> +#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_SHIFT 17
> +#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_MASK 0x1
> +#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18
> +#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x1
> +
> +/*
> + * DCC supports embedding some clear colors directly in the DCC surface.
> + * However, on older GPUs the rendering HW ignores the embedded clear color
> + * and prefers the driver provided color. This necessitates doing a fastclear
> + * eliminate operation before a process transfers control.
> + *
> + * If this bit is set that means the fastclear eliminate is not needed for these
> + * embeddable colors.
> + */
> +#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_SHIFT 19
> +#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_MASK 0x1
> +
> +/*
> + * The below fields are for accounting for per GPU differences. These are only
> + * relevant for GFX9 and later and if the tile field is *_X/_T.
> + *
> + * PIPE_XOR_BITS = always needed
> + * BANK_XOR_BITS = only for TILE_VER_GFX9
> + * PACKERS = only for TILE_VER_GFX10_RBPLUS
> + * RB = only for TILE_VER_GFX9 & DCC
> + * PIPE = only for TILE_VER_GFX9 & DCC & (DCC_RETILE | DCC_PIPE_ALIGN)
> + */
> +#define AMD_FMT_MOD_PIPE_XOR_BITS_SHIFT 20
> +#define AMD_FMT_MOD_PIPE_XOR_BITS_MASK 0x7
> +#define AMD_FMT_MOD_BANK_XOR_BITS_SHIFT 23
> +#define AMD_FMT_MOD_BANK_XOR_BITS_MASK 0x7
> +#define AMD_FMT_MOD_PACKERS_SHIFT 26 /* aliases with BANK_XOR_BITS */
> +#define AMD_FMT_MOD_PACKERS_MASK 0x7
> +#define AMD_FMT_MOD_RB_SHIFT 29
> +#define AMD_FMT_MOD_RB_MASK 0x7
> +#define AMD_FMT_MOD_PIPE_SHIFT 32
> +#define AMD_FMT_MOD_PIPE_MASK 0x7
> +
> +#define AMD_FMT_MOD_SET(field, value) \
> +       ((uint64_t)(value) << AMD_FMT_MOD_##field##_SHIFT)
> +#define AMD_FMT_MOD_GET(field, value) \
> +       (((value) >> AMD_FMT_MOD_##field##_SHIFT) & AMD_FMT_MOD_##field##_MASK)
> +#define AMD_FMT_MOD_CLEAR(field) \
> +       (~((uint64_t)AMD_FMT_MOD_##field##_MASK << AMD_FMT_MOD_##field##_SHIFT))
> +
>  #if defined(__cplusplus)
>  }
>  #endif
> --
> 2.28.0
>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 03/11] drm/amd/display: Honor the offset for plane 0.
  2020-10-22 15:36   ` Alex Deucher
@ 2020-10-22 16:10     ` Greg KH
  0 siblings, 0 replies; 25+ messages in thread
From: Greg KH @ 2020-10-22 16:10 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Marek Olsak, Leo (Sunpeng) Li, amd-gfx list, for 3.8,
	Daniel Vetter, Bas Nieuwenhuizen, Wentland, Harry, Kazlauskas,
	Nicholas

On Thu, Oct 22, 2020 at 11:36:12AM -0400, Alex Deucher wrote:
> On Wed, Oct 21, 2020 at 7:31 PM Bas Nieuwenhuizen
> <bas@basnieuwenhuizen.nl> wrote:
> >
> > With modifiers I'd like to support non-dedicated buffers for
> > images.
> >
> > Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> > Cc: stable@vger.kernel.org # 5.1.0
> 
> I think you need # 5.1.x- for it to be applied to all stable kernels
> since 5.1 otherwise it will just apply to 5.1.x

Not true, I will try from the number up to the latest version.  So all
should be fine here.

thanks,

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 04/11] drm/fourcc: Add AMD DRM modifiers.
  2020-10-22 15:41   ` Alex Deucher
@ 2020-10-22 16:39     ` Bas Nieuwenhuizen
  0 siblings, 0 replies; 25+ messages in thread
From: Bas Nieuwenhuizen @ 2020-10-22 16:39 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Marek Olsak, Leo (Sunpeng) Li, amd-gfx list, Daniel Vetter,
	Wentland, Harry, Kazlauskas, Nicholas

On Thu, Oct 22, 2020 at 5:41 PM Alex Deucher <alexdeucher@gmail.com> wrote:
>
> On Wed, Oct 21, 2020 at 7:31 PM Bas Nieuwenhuizen
> <bas@basnieuwenhuizen.nl> wrote:
> >
> > This adds modifiers for GFX9+ AMD GPUs.
> >
> > As the modifiers need a lot of parameters I split things out in
> > getters and setters.
> >   - Advantage: simplifies the code a lot
> >   - Disadvantage: Makes it harder to check that you're setting all
> >                   the required fields.
> >
> > The tiling modes seem to change every generation, but the structure
> > of what each tiling mode is good for stays really similar. As such
> > the core of the modifier is
> >  - the tiling mode
> >  - a version. Not explicitly a GPU generation, but splitting out
> >    a new set of tiling equations.
> >
> > Sometimes one or two tiling modes stay the same and for those we
> > specify a canonical version.
> >
> > Then we have a bunch of parameters on how the compression works.
> > Different HW units have different requirements for these and we
> > actually have some conflicts here.
> >
> > e.g. the render backends need a specific alignment but the display
> > unit only works with unaligned compression surfaces. To work around
> > that we have a DCC_RETILE option where both an aligned and unaligned
> > compression surface are allocated and a writer has to sync the
> > aligned surface to the unaligned surface on handoff.
> >
> > Finally there are some GPU parameters that participate in the tiling
> > equations. These are constant for each GPU on the rendering/texturing
> > side. The display unit is very flexible however and supports all
> > of them :|
>
> I think the idea is that the display engine can scanout just about
> anything thrown at it (e.g., if you have multiple GPUs in a system).
> E.g., you may have a laptop with a navi14 dGPU and a renoir APU.
> You'd want the APU to be able to scanout from whatever format the dGPU
> gave you.

I think this agrees with what I wrote in the commit description?

This encoding should support that in a reasonably scalable way, though
in the rest of the patches I don't enable this yet and mostly keep
feature parity with existing PRIME paths.

>
> Alex
>
>
> >
> > Some estimates:
> >  - Single GPU, render+texture: ~10 modifiers
> >  - All possible configs in a gen, display: ~1000 modifiers
> >  - Configs of actually existing GPUs in a gen: ~100 modifiers
> >
> > For formats with a single plane everything gets put in a separate
> > DRM plane. However, this doesn't fit for some YUV formats, so if
> > the format has >1 plane, we let the driver pack the surfaces into
> > 1 DRM plane per format plane.
> >
> > This way we avoid X11 rendering onto the frontbuffer with DCC, but
> > still fit into 4 DRM planes.
> >
> > Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> > ---
> >  include/uapi/drm/drm_fourcc.h | 115 ++++++++++++++++++++++++++++++++++
> >  1 file changed, 115 insertions(+)
> >
> > diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> > index 82f327801267..df56e71a7380 100644
> > --- a/include/uapi/drm/drm_fourcc.h
> > +++ b/include/uapi/drm/drm_fourcc.h
> > @@ -1056,6 +1056,121 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
> >   */
> >  #define AMLOGIC_FBC_OPTION_MEM_SAVING          (1ULL << 0)
> >
> > +/*
> > + * AMD modifiers
> > + *
> > + * Memory layout:
> > + *
> > + * without DCC:
> > + *   - main surface
> > + *
> > + * with DCC & without DCC_RETILE:
> > + *   - main surface in plane 0
> > + *   - DCC surface in plane 1 (RB-aligned, pipe-aligned if DCC_PIPE_ALIGN is set)
> > + *
> > + * with DCC & DCC_RETILE:
> > + *   - main surface in plane 0
> > + *   - displayable DCC surface in plane 1 (not RB-aligned & not pipe-aligned)
> > + *   - pipe-aligned DCC surface in plane 2 (RB-aligned & pipe-aligned)
> > + *
> > + * For multi-plane formats the above surfaces get merged into one plane for
> > + * each format plane, based on the required alignment only.
> > + */
> > +#define AMD_FMT_MOD fourcc_mod_code(AMD, 0)
> > +
> > +#define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD)
> > +
> > +/* Reserve 0 for GFX8 and older */
> > +#define AMD_FMT_MOD_TILE_VER_GFX9 1
> > +#define AMD_FMT_MOD_TILE_VER_GFX10 2
> > +#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3
> > +
> > +/*
> > + * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical
> > + * version.
> > + */
> > +#define AMD_FMT_MOD_TILE_GFX9_64K_S 9
> > +
> > +/*
> > + * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has
> > + * GFX9 as canonical version.
> > + */
> > +#define AMD_FMT_MOD_TILE_GFX9_64K_D 10
> > +#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25
> > +#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26
> > +#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27
> > +
> > +#define AMD_FMT_MOD_DCC_BLOCK_64B 0
> > +#define AMD_FMT_MOD_DCC_BLOCK_128B 1
> > +#define AMD_FMT_MOD_DCC_BLOCK_256B 2
> > +
> > +#define AMD_FMT_MOD_TILE_VERSION_SHIFT 0
> > +#define AMD_FMT_MOD_TILE_VERSION_MASK 0xFF
> > +#define AMD_FMT_MOD_TILE_SHIFT 8
> > +#define AMD_FMT_MOD_TILE_MASK 0x1F
> > +
> > +/* Whether DCC compression is enabled. */
> > +#define AMD_FMT_MOD_DCC_SHIFT 13
> > +#define AMD_FMT_MOD_DCC_MASK 0x1
> > +
> > +/*
> > + * Whether to include two DCC surfaces, one which is rb & pipe aligned, and
> > + * one which is not-aligned.
> > + */
> > +#define AMD_FMT_MOD_DCC_RETILE_SHIFT 14
> > +#define AMD_FMT_MOD_DCC_RETILE_MASK 0x1
> > +
> > +/* Only set if DCC_RETILE = false */
> > +#define AMD_FMT_MOD_DCC_PIPE_ALIGN_SHIFT 15
> > +#define AMD_FMT_MOD_DCC_PIPE_ALIGN_MASK 0x1
> > +
> > +#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_SHIFT 16
> > +#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_MASK 0x1
> > +#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_SHIFT 17
> > +#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_MASK 0x1
> > +#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18
> > +#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x1
> > +
> > +/*
> > + * DCC supports embedding some clear colors directly in the DCC surface.
> > + * However, on older GPUs the rendering HW ignores the embedded clear color
> > + * and prefers the driver provided color. This necessitates doing a fastclear
> > + * eliminate operation before a process transfers control.
> > + *
> > + * If this bit is set that means the fastclear eliminate is not needed for these
> > + * embeddable colors.
> > + */
> > +#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_SHIFT 19
> > +#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_MASK 0x1
> > +
> > +/*
> > + * The below fields are for accounting for per GPU differences. These are only
> > + * relevant for GFX9 and later and if the tile field is *_X/_T.
> > + *
> > + * PIPE_XOR_BITS = always needed
> > + * BANK_XOR_BITS = only for TILE_VER_GFX9
> > + * PACKERS = only for TILE_VER_GFX10_RBPLUS
> > + * RB = only for TILE_VER_GFX9 & DCC
> > + * PIPE = only for TILE_VER_GFX9 & DCC & (DCC_RETILE | DCC_PIPE_ALIGN)
> > + */
> > +#define AMD_FMT_MOD_PIPE_XOR_BITS_SHIFT 20
> > +#define AMD_FMT_MOD_PIPE_XOR_BITS_MASK 0x7
> > +#define AMD_FMT_MOD_BANK_XOR_BITS_SHIFT 23
> > +#define AMD_FMT_MOD_BANK_XOR_BITS_MASK 0x7
> > +#define AMD_FMT_MOD_PACKERS_SHIFT 26 /* aliases with BANK_XOR_BITS */
> > +#define AMD_FMT_MOD_PACKERS_MASK 0x7
> > +#define AMD_FMT_MOD_RB_SHIFT 29
> > +#define AMD_FMT_MOD_RB_MASK 0x7
> > +#define AMD_FMT_MOD_PIPE_SHIFT 32
> > +#define AMD_FMT_MOD_PIPE_MASK 0x7
> > +
> > +#define AMD_FMT_MOD_SET(field, value) \
> > +       ((uint64_t)(value) << AMD_FMT_MOD_##field##_SHIFT)
> > +#define AMD_FMT_MOD_GET(field, value) \
> > +       (((value) >> AMD_FMT_MOD_##field##_SHIFT) & AMD_FMT_MOD_##field##_MASK)
> > +#define AMD_FMT_MOD_CLEAR(field) \
> > +       (~((uint64_t)AMD_FMT_MOD_##field##_MASK << AMD_FMT_MOD_##field##_SHIFT))
> > +
> >  #if defined(__cplusplus)
> >  }
> >  #endif
> > --
> > 2.28.0
> >
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 00/11] amd/display: Add GFX9+ modifier support.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
                   ` (10 preceding siblings ...)
  2020-10-21 23:31 ` [PATCH v3 11/11] drm/amd/display: Clean up GFX9 tiling_flags path Bas Nieuwenhuizen
@ 2020-10-22 16:55 ` Alex Deucher
  2020-10-26  8:28 ` Pierre-Eric Pelloux-Prayer
  12 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-10-22 16:55 UTC (permalink / raw)
  To: Bas Nieuwenhuizen
  Cc: Marek Olsak, Leo (Sunpeng) Li, amd-gfx list, Daniel Vetter,
	Wentland, Harry, Kazlauskas, Nicholas

I don't claim to be an expert with modifiers, but the changes all look
logical to me.  With VGH added to patch 10, this series is:
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>


On Wed, Oct 21, 2020 at 7:31 PM Bas Nieuwenhuizen
<bas@basnieuwenhuizen.nl> wrote:
>
> This adds modifier support to the amdgpu kernel drivers for GFX9 and
> later GPUs. It has been tested on
>
> - VEGA10, RAVEN, NAVI14
> - weston, sway, X with xf86-video-amdgpu (i.e. legacy path still works)
>
> and includes some basic testing of the layout code.
>
> The main goal is to keep it somewhat simple and regression free, so
> on the display side this series only exposes what the current GPU
> can render to. While we could expose more I think that is more
> suitable for follow-up work as the benefit would be minimal and
> there are some more design discussion there to discuss that are
> orthogonal from the initial implementation.
>
> Similarly this series only exposes 32-bpp displayable DCC in the cases
> that radeonsi would use it and any extra capabilities here should be
> future work.
>
> I believe these are by far the most complicated modifiers we've seen
> up till now, mostly related to
>
> - GPU identification for cases where it matters wrt tiling.
> - Every generation having tiling layout changes
> - Compression settings.
>
> I believe the complexity is necessary as every layout should be different
> and all layouts should be the best in some situation (though not all
> combinations of GPU parameters will actually have an existing GPU).
>
> That said, on the render side the number of modifiers actually listed for
> a given GPU is ~10, and in the current implementation that is the same
> for the display side. (we could expose more actually differing layouts
> on the display side for cross-GPU compatibility, but I consider that
> out of scope for this initial work).
>
> This series can be found on
> https://github.com/BNieuwenhuizen/linux/tree/modifiers
>
> An userspace implementation in radeonsi can be found on
> https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6176
>
> which has been reviewed and is ready for submission once these kernel
> patches land.
>
> v2:
>
> Per suggestion from Daniel Vetter I added logic to get the tiling_flags at
> addfb2 time and convert them into modifiers for GFX9+.  Furthermore, the DCC
> constant econding modifers only get exposed on RAVEN2 and newer.
>
> v3:
>
> Fixed some typos, rebased and CCing more people to actually get a review.
>
> Bas Nieuwenhuizen (11):
>   drm/amd/display: Do not silently accept DCC for multiplane formats.
>   drm/amd: Init modifier field of helper fb.
>   drm/amd/display: Honor the offset for plane 0.
>   drm/fourcc:  Add AMD DRM modifiers.
>   drm/amd/display: Store tiling_flags in the framebuffer.
>   drm/amd/display: Convert tiling_flags to modifiers.
>   drm/amd/display: Refactor surface tiling setup.
>   drm/amd/display: Set DC options from modifiers.
>   drm/amd/display: Add formats for DCC with 2/3 planes.
>   drm/amd/display: Expose modifiers.
>   drm/amd/display: Clean up GFX9 tiling_flags path.
>
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 169 +++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c        |   2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |   3 +
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 754 ++++++++++++++----
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   2 -
>  include/uapi/drm/drm_fourcc.h                 | 115 +++
>  6 files changed, 880 insertions(+), 165 deletions(-)
>
> --
> 2.28.0
>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 00/11] amd/display: Add GFX9+ modifier support.
  2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
                   ` (11 preceding siblings ...)
  2020-10-22 16:55 ` [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Alex Deucher
@ 2020-10-26  8:28 ` Pierre-Eric Pelloux-Prayer
  12 siblings, 0 replies; 25+ messages in thread
From: Pierre-Eric Pelloux-Prayer @ 2020-10-26  8:28 UTC (permalink / raw)
  To: Bas Nieuwenhuizen, amd-gfx
  Cc: maraeo, sunpeng.li, daniel, alexdeucher, harry.wentland,
	nicholas.kazlauskas

Hi Bas,

I've been using v2 for a while so you can tag the series as:
Tested-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>



On 22/10/2020 01:31, Bas Nieuwenhuizen wrote:
> This adds modifier support to the amdgpu kernel drivers for GFX9 and
> later GPUs. It has been tested on
> 
> - VEGA10, RAVEN, NAVI14
> - weston, sway, X with xf86-video-amdgpu (i.e. legacy path still works)
> 
> and includes some basic testing of the layout code.
> 
> The main goal is to keep it somewhat simple and regression free, so
> on the display side this series only exposes what the current GPU
> can render to. While we could expose more I think that is more
> suitable for follow-up work as the benefit would be minimal and
> there are some more design discussion there to discuss that are
> orthogonal from the initial implementation.
> 
> Similarly this series only exposes 32-bpp displayable DCC in the cases
> that radeonsi would use it and any extra capabilities here should be
> future work.
> 
> I believe these are by far the most complicated modifiers we've seen
> up till now, mostly related to
> 
> - GPU identification for cases where it matters wrt tiling.
> - Every generation having tiling layout changes
> - Compression settings.
> 
> I believe the complexity is necessary as every layout should be different
> and all layouts should be the best in some situation (though not all
> combinations of GPU parameters will actually have an existing GPU).
> 
> That said, on the render side the number of modifiers actually listed for
> a given GPU is ~10, and in the current implementation that is the same
> for the display side. (we could expose more actually differing layouts
> on the display side for cross-GPU compatibility, but I consider that
> out of scope for this initial work).
> 
> This series can be found on
> https://github.com/BNieuwenhuizen/linux/tree/modifiers
> 
> An userspace implementation in radeonsi can be found on
> https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6176
> 
> which has been reviewed and is ready for submission once these kernel
> patches land.
> 
> v2:
> 
> Per suggestion from Daniel Vetter I added logic to get the tiling_flags at
> addfb2 time and convert them into modifiers for GFX9+.  Furthermore, the DCC
> constant econding modifers only get exposed on RAVEN2 and newer.
> 
> v3:
> 
> Fixed some typos, rebased and CCing more people to actually get a review.
> 
> Bas Nieuwenhuizen (11):
>   drm/amd/display: Do not silently accept DCC for multiplane formats.
>   drm/amd: Init modifier field of helper fb.
>   drm/amd/display: Honor the offset for plane 0.
>   drm/fourcc:  Add AMD DRM modifiers.
>   drm/amd/display: Store tiling_flags in the framebuffer.
>   drm/amd/display: Convert tiling_flags to modifiers.
>   drm/amd/display: Refactor surface tiling setup.
>   drm/amd/display: Set DC options from modifiers.
>   drm/amd/display: Add formats for DCC with 2/3 planes.
>   drm/amd/display: Expose modifiers.
>   drm/amd/display: Clean up GFX9 tiling_flags path.
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 169 +++-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c        |   2 +-
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |   3 +
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 754 ++++++++++++++----
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   2 -
>  include/uapi/drm/drm_fourcc.h                 | 115 +++
>  6 files changed, 880 insertions(+), 165 deletions(-)
> 
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 01/11] drm/amd/display: Do not silently accept DCC for multiplane formats.
  2020-10-21 23:31 ` [PATCH v3 01/11] drm/amd/display: Do not silently accept DCC for multiplane formats Bas Nieuwenhuizen
@ 2020-10-26 13:50   ` Kazlauskas, Nicholas
  0 siblings, 0 replies; 25+ messages in thread
From: Kazlauskas, Nicholas @ 2020-10-26 13:50 UTC (permalink / raw)
  To: Bas Nieuwenhuizen, amd-gfx
  Cc: alexdeucher, sunpeng.li, harry.wentland, maraeo, daniel

On 2020-10-21 7:31 p.m., Bas Nieuwenhuizen wrote:
> Silently accepting it could result in corruption.
> 
> Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

> ---
>   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
>   1 file changed, 1 insertion(+), 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 2713caac4f2a..73987fdb6a09 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3908,7 +3908,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
>   		return 0;
>   
>   	if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
> -		return 0;
> +		return -EINVAL;
>   
>   	if (!dc->cap_funcs.get_dcc_compression_cap)
>   		return -EINVAL;
> 

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 02/11] drm/amd: Init modifier field of helper fb.
  2020-10-21 23:31 ` [PATCH v3 02/11] drm/amd: Init modifier field of helper fb Bas Nieuwenhuizen
@ 2020-10-26 13:50   ` Kazlauskas, Nicholas
  0 siblings, 0 replies; 25+ messages in thread
From: Kazlauskas, Nicholas @ 2020-10-26 13:50 UTC (permalink / raw)
  To: Bas Nieuwenhuizen, amd-gfx
  Cc: alexdeucher, sunpeng.li, harry.wentland, maraeo, daniel

On 2020-10-21 7:31 p.m., Bas Nieuwenhuizen wrote:
> Otherwise the field ends up being used uninitialized when
> enabling modifiers, failing validation with high likelyhood.
> 
> Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> index e2c2eb45a793..77dd2a189746 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> @@ -201,7 +201,7 @@ static int amdgpufb_create(struct drm_fb_helper *helper,
>   	struct amdgpu_device *adev = rfbdev->adev;
>   	struct fb_info *info;
>   	struct drm_framebuffer *fb = NULL;
> -	struct drm_mode_fb_cmd2 mode_cmd;
> +	struct drm_mode_fb_cmd2 mode_cmd = {0};

I think we should prefer a memset in this case. I always forget which 
compilers complain about this syntax but I know we've had to swap out a 
bunch of zero initializers to satisfy them.

Regards,
Nicholas Kazlauskas

>   	struct drm_gem_object *gobj = NULL;
>   	struct amdgpu_bo *abo = NULL;
>   	int ret;
> 

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 03/11] drm/amd/display: Honor the offset for plane 0.
  2020-10-21 23:31 ` [PATCH v3 03/11] drm/amd/display: Honor the offset for plane 0 Bas Nieuwenhuizen
  2020-10-22 15:36   ` Alex Deucher
@ 2020-10-26 13:51   ` Kazlauskas, Nicholas
  1 sibling, 0 replies; 25+ messages in thread
From: Kazlauskas, Nicholas @ 2020-10-26 13:51 UTC (permalink / raw)
  To: Bas Nieuwenhuizen, amd-gfx
  Cc: maraeo, sunpeng.li, stable, daniel, alexdeucher, harry.wentland

On 2020-10-21 7:31 p.m., Bas Nieuwenhuizen wrote:
> With modifiers I'd like to support non-dedicated buffers for
> images.
> 
> Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
> Cc: stable@vger.kernel.org # 5.1.0

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

Regards,
Nicholas Kazlauskas

> ---
>   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++++++++-----
>   1 file changed, 9 insertions(+), 5 deletions(-)
> 
> 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 73987fdb6a09..833887b9b0ad 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3894,6 +3894,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
>   	struct dc *dc = adev->dm.dc;
>   	struct dc_dcc_surface_param input;
>   	struct dc_surface_dcc_cap output;
> +	uint64_t plane_address = afb->address + afb->base.offsets[0];
>   	uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
>   	uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
>   	uint64_t dcc_address;
> @@ -3937,7 +3938,7 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
>   		AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
>   	dcc->independent_64b_blks = i64b;
>   
> -	dcc_address = get_dcc_address(afb->address, info);
> +	dcc_address = get_dcc_address(plane_address, info);
>   	address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
>   	address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
>   
> @@ -3968,6 +3969,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
>   	address->tmz_surface = tmz_surface;
>   
>   	if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
> +		uint64_t addr = afb->address + fb->offsets[0];
> +
>   		plane_size->surface_size.x = 0;
>   		plane_size->surface_size.y = 0;
>   		plane_size->surface_size.width = fb->width;
> @@ -3976,9 +3979,10 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
>   			fb->pitches[0] / fb->format->cpp[0];
>   
>   		address->type = PLN_ADDR_TYPE_GRAPHICS;
> -		address->grph.addr.low_part = lower_32_bits(afb->address);
> -		address->grph.addr.high_part = upper_32_bits(afb->address);
> +		address->grph.addr.low_part = lower_32_bits(addr);
> +		address->grph.addr.high_part = upper_32_bits(addr);
>   	} else if (format < SURFACE_PIXEL_FORMAT_INVALID) {
> +		uint64_t luma_addr = afb->address + fb->offsets[0];
>   		uint64_t chroma_addr = afb->address + fb->offsets[1];
>   
>   		plane_size->surface_size.x = 0;
> @@ -3999,9 +4003,9 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
>   
>   		address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
>   		address->video_progressive.luma_addr.low_part =
> -			lower_32_bits(afb->address);
> +			lower_32_bits(luma_addr);
>   		address->video_progressive.luma_addr.high_part =
> -			upper_32_bits(afb->address);
> +			upper_32_bits(luma_addr);
>   		address->video_progressive.chroma_addr.low_part =
>   			lower_32_bits(chroma_addr);
>   		address->video_progressive.chroma_addr.high_part =
> 

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 05/11] drm/amd/display: Store tiling_flags in the framebuffer.
  2020-10-21 23:31 ` [PATCH v3 05/11] drm/amd/display: Store tiling_flags in the framebuffer Bas Nieuwenhuizen
@ 2020-10-26 13:54   ` Kazlauskas, Nicholas
  0 siblings, 0 replies; 25+ messages in thread
From: Kazlauskas, Nicholas @ 2020-10-26 13:54 UTC (permalink / raw)
  To: Bas Nieuwenhuizen, amd-gfx
  Cc: alexdeucher, sunpeng.li, harry.wentland, maraeo, daniel

On 2020-10-21 7:31 p.m., Bas Nieuwenhuizen wrote:
> This moves the tiling_flags to the framebuffer creation.
> This way the time of the "tiling" decision is the same as it
> would be with modifiers.
> 
> Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

Regards,
Nicholas Kazlauskas

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 48 +++++++++++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  3 +
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 73 +++----------------
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  2 -
>   4 files changed, 59 insertions(+), 67 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index 9e92d2a070ac..1a2664c3fc26 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -541,6 +541,39 @@ uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev,
>   	return domain;
>   }
>   
> +static int amdgpu_display_get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
> +				      uint64_t *tiling_flags, bool *tmz_surface)
> +{
> +	struct amdgpu_bo *rbo;
> +	int r;
> +
> +	if (!amdgpu_fb) {
> +		*tiling_flags = 0;
> +		*tmz_surface = false;
> +		return 0;
> +	}
> +
> +	rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
> +	r = amdgpu_bo_reserve(rbo, false);
> +
> +	if (unlikely(r)) {
> +		/* Don't show error message when returning -ERESTARTSYS */
> +		if (r != -ERESTARTSYS)
> +			DRM_ERROR("Unable to reserve buffer: %d\n", r);
> +		return r;
> +	}
> +
> +	if (tiling_flags)
> +		amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
> +
> +	if (tmz_surface)
> +		*tmz_surface = amdgpu_bo_encrypted(rbo);
> +
> +	amdgpu_bo_unreserve(rbo);
> +
> +	return r;
> +}
> +
>   int amdgpu_display_framebuffer_init(struct drm_device *dev,
>   				    struct amdgpu_framebuffer *rfb,
>   				    const struct drm_mode_fb_cmd2 *mode_cmd,
> @@ -550,11 +583,18 @@ int amdgpu_display_framebuffer_init(struct drm_device *dev,
>   	rfb->base.obj[0] = obj;
>   	drm_helper_mode_fill_fb_struct(dev, &rfb->base, mode_cmd);
>   	ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs);
> -	if (ret) {
> -		rfb->base.obj[0] = NULL;
> -		return ret;
> -	}
> +	if (ret)
> +		goto fail;
> +
> +	ret = amdgpu_display_get_fb_info(rfb, &rfb->tiling_flags, &rfb->tmz_surface);
> +	if (ret)
> +		goto fail;
> +
>   	return 0;
> +
> +fail:
> +	rfb->base.obj[0] = NULL;
> +	return ret;
>   }
>   
>   struct drm_framebuffer *
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> index 345cb0464370..39866ed81c16 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> @@ -304,6 +304,9 @@ struct amdgpu_display_funcs {
>   struct amdgpu_framebuffer {
>   	struct drm_framebuffer base;
>   
> +	uint64_t tiling_flags;
> +	bool tmz_surface;
> +
>   	/* caching for later use */
>   	uint64_t address;
>   };
> 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 833887b9b0ad..5a0efaefbd7f 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3839,39 +3839,6 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state,
>   	return 0;
>   }
>   
> -static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
> -		       uint64_t *tiling_flags, bool *tmz_surface)
> -{
> -	struct amdgpu_bo *rbo;
> -	int r;
> -
> -	if (!amdgpu_fb) {
> -		*tiling_flags = 0;
> -		*tmz_surface = false;
> -		return 0;
> -	}
> -
> -	rbo = gem_to_amdgpu_bo(amdgpu_fb->base.obj[0]);
> -	r = amdgpu_bo_reserve(rbo, false);
> -
> -	if (unlikely(r)) {
> -		/* Don't show error message when returning -ERESTARTSYS */
> -		if (r != -ERESTARTSYS)
> -			DRM_ERROR("Unable to reserve buffer: %d\n", r);
> -		return r;
> -	}
> -
> -	if (tiling_flags)
> -		amdgpu_bo_get_tiling_flags(rbo, tiling_flags);
> -
> -	if (tmz_surface)
> -		*tmz_surface = amdgpu_bo_encrypted(rbo);
> -
> -	amdgpu_bo_unreserve(rbo);
> -
> -	return r;
> -}
> -
>   static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
>   {
>   	uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
> @@ -4287,7 +4254,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
>   				    struct drm_crtc_state *crtc_state)
>   {
>   	struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state);
> -	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
> +	struct amdgpu_framebuffer *afb = (struct amdgpu_framebuffer *)plane_state->fb;
>   	struct dc_scaling_info scaling_info;
>   	struct dc_plane_info plane_info;
>   	int ret;
> @@ -4304,10 +4271,10 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
>   
>   	force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
>   	ret = fill_dc_plane_info_and_addr(adev, plane_state,
> -					  dm_plane_state->tiling_flags,
> +					  afb->tiling_flags,
>   					  &plane_info,
>   					  &dc_plane_state->address,
> -					  dm_plane_state->tmz_surface,
> +					  afb->tmz_surface,
>   					  force_disable_dcc);
>   	if (ret)
>   		return ret;
> @@ -5913,10 +5880,6 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
>   		dc_plane_state_retain(dm_plane_state->dc_state);
>   	}
>   
> -	/* Framebuffer hasn't been updated yet, so retain old flags. */
> -	dm_plane_state->tiling_flags = old_dm_plane_state->tiling_flags;
> -	dm_plane_state->tmz_surface = old_dm_plane_state->tmz_surface;
> -
>   	return &dm_plane_state->base;
>   }
>   
> @@ -6021,10 +5984,10 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
>   
>   		fill_plane_buffer_attributes(
>   			adev, afb, plane_state->format, plane_state->rotation,
> -			dm_plane_state_new->tiling_flags,
> +			afb->tiling_flags,
>   			&plane_state->tiling_info, &plane_state->plane_size,
>   			&plane_state->dcc, &plane_state->address,
> -			dm_plane_state_new->tmz_surface, force_disable_dcc);
> +			afb->tmz_surface, force_disable_dcc);
>   	}
>   
>   	return 0;
> @@ -7287,6 +7250,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
>   		struct drm_crtc *crtc = new_plane_state->crtc;
>   		struct drm_crtc_state *new_crtc_state;
>   		struct drm_framebuffer *fb = new_plane_state->fb;
> +		struct amdgpu_framebuffer *afb = (struct amdgpu_framebuffer *)fb;
>   		bool plane_needs_flip;
>   		struct dc_plane_state *dc_plane;
>   		struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state);
> @@ -7341,10 +7305,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
>   
>   		fill_dc_plane_info_and_addr(
>   			dm->adev, new_plane_state,
> -			dm_new_plane_state->tiling_flags,
> +			afb->tiling_flags,
>   			&bundle->plane_infos[planes_count],
>   			&bundle->flip_addrs[planes_count].address,
> -			dm_new_plane_state->tmz_surface, false);
> +			afb->tmz_surface, false);
>   
>   		DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n",
>   				 new_plane_state->plane->index,
> @@ -8483,8 +8447,7 @@ static bool should_reset_plane(struct drm_atomic_state *state,
>   	 * TODO: Come up with a more elegant solution for this.
>   	 */
>   	for_each_oldnew_plane_in_state(state, other, old_other_state, new_other_state, i) {
> -		struct dm_plane_state *old_dm_plane_state, *new_dm_plane_state;
> -
> +		struct amdgpu_framebuffer *old_afb, *new_afb;
>   		if (other->type == DRM_PLANE_TYPE_CURSOR)
>   			continue;
>   
> @@ -8528,12 +8491,11 @@ static bool should_reset_plane(struct drm_atomic_state *state,
>   		if (old_other_state->fb->format != new_other_state->fb->format)
>   			return true;
>   
> -		old_dm_plane_state = to_dm_plane_state(old_other_state);
> -		new_dm_plane_state = to_dm_plane_state(new_other_state);
> +		old_afb = (struct amdgpu_framebuffer *)old_other_state->fb;
> +		new_afb = (struct amdgpu_framebuffer *)new_other_state->fb;
>   
>   		/* Tiling and DCC changes also require bandwidth updates. */
> -		if (old_dm_plane_state->tiling_flags !=
> -		    new_dm_plane_state->tiling_flags)
> +		if (old_afb->tiling_flags != new_afb->tiling_flags)
>   			return true;
>   	}
>   
> @@ -8859,17 +8821,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
>   		}
>   	}
>   
> -	/* Prepass for updating tiling flags on new planes. */
> -	for_each_new_plane_in_state(state, plane, new_plane_state, i) {
> -		struct dm_plane_state *new_dm_plane_state = to_dm_plane_state(new_plane_state);
> -		struct amdgpu_framebuffer *new_afb = to_amdgpu_framebuffer(new_plane_state->fb);
> -
> -		ret = get_fb_info(new_afb, &new_dm_plane_state->tiling_flags,
> -				  &new_dm_plane_state->tmz_surface);
> -		if (ret)
> -			goto fail;
> -	}
> -
>   	/* Remove exiting planes if they are modified */
>   	for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
>   		ret = dm_update_plane_state(dc, state, plane,
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> index a46338410ddd..9308bed3c4fe 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -420,8 +420,6 @@ struct dc_plane_state;
>   struct dm_plane_state {
>   	struct drm_plane_state base;
>   	struct dc_plane_state *dc_state;
> -	uint64_t tiling_flags;
> -	bool tmz_surface;
>   };
>   
>   struct dm_crtc_state {
> 

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH v3 07/11] drm/amd/display: Refactor surface tiling setup.
  2020-10-21 23:31 ` [PATCH v3 07/11] drm/amd/display: Refactor surface tiling setup Bas Nieuwenhuizen
@ 2020-10-26 13:58   ` Kazlauskas, Nicholas
  0 siblings, 0 replies; 25+ messages in thread
From: Kazlauskas, Nicholas @ 2020-10-26 13:58 UTC (permalink / raw)
  To: Bas Nieuwenhuizen, amd-gfx
  Cc: alexdeucher, sunpeng.li, harry.wentland, maraeo, daniel

On 2020-10-21 7:31 p.m., Bas Nieuwenhuizen wrote:
> Prepare for inserting modifiers based configuration, while sharing
> a bunch of DCC validation & initializing the device-based configuration.
> 
> Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

Regards,
Nicholas Kazlauskas

> ---
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 222 ++++++++++--------
>   1 file changed, 119 insertions(+), 103 deletions(-)
> 
> 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 5a0efaefbd7f..479c886816d9 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -3839,46 +3839,86 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state,
>   	return 0;
>   }
>   
> -static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags)
> +static void
> +fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info,
> +				 uint64_t tiling_flags)
>   {
> -	uint32_t offset = AMDGPU_TILING_GET(tiling_flags, DCC_OFFSET_256B);
> +	/* Fill GFX8 params */
> +	if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) {
> +		unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
> +
> +		bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
> +		bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
> +		mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
> +		tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT);
> +		num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
> +
> +		/* XXX fix me for VI */
> +		tiling_info->gfx8.num_banks = num_banks;
> +		tiling_info->gfx8.array_mode =
> +				DC_ARRAY_2D_TILED_THIN1;
> +		tiling_info->gfx8.tile_split = tile_split;
> +		tiling_info->gfx8.bank_width = bankw;
> +		tiling_info->gfx8.bank_height = bankh;
> +		tiling_info->gfx8.tile_aspect = mtaspect;
> +		tiling_info->gfx8.tile_mode =
> +				DC_ADDR_SURF_MICRO_TILING_DISPLAY;
> +	} else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE)
> +			== DC_ARRAY_1D_TILED_THIN1) {
> +		tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1;
> +	}
>   
> -	return offset ? (address + offset * 256) : 0;
> +	tiling_info->gfx8.pipe_config =
> +			AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
> +}
> +
> +static void
> +fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev,
> +				  union dc_tiling_info *tiling_info)
> +{
> +	tiling_info->gfx9.num_pipes =
> +		adev->gfx.config.gb_addr_config_fields.num_pipes;
> +	tiling_info->gfx9.num_banks =
> +		adev->gfx.config.gb_addr_config_fields.num_banks;
> +	tiling_info->gfx9.pipe_interleave =
> +		adev->gfx.config.gb_addr_config_fields.pipe_interleave_size;
> +	tiling_info->gfx9.num_shader_engines =
> +		adev->gfx.config.gb_addr_config_fields.num_se;
> +	tiling_info->gfx9.max_compressed_frags =
> +		adev->gfx.config.gb_addr_config_fields.max_compress_frags;
> +	tiling_info->gfx9.num_rb_per_se =
> +		adev->gfx.config.gb_addr_config_fields.num_rb_per_se;
> +	tiling_info->gfx9.shaderEnable = 1;
> +#ifdef CONFIG_DRM_AMD_DC_DCN3_0
> +	if (adev->asic_type == CHIP_SIENNA_CICHLID ||
> +	    adev->asic_type == CHIP_NAVY_FLOUNDER ||
> +	    adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
> +	    adev->asic_type == CHIP_VANGOGH)
> +		tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs;
> +#endif
>   }
>   
>   static int
> -fill_plane_dcc_attributes(struct amdgpu_device *adev,
> -			  const struct amdgpu_framebuffer *afb,
> -			  const enum surface_pixel_format format,
> -			  const enum dc_rotation_angle rotation,
> -			  const struct plane_size *plane_size,
> -			  const union dc_tiling_info *tiling_info,
> -			  const uint64_t info,
> -			  struct dc_plane_dcc_param *dcc,
> -			  struct dc_plane_address *address,
> -			  bool force_disable_dcc)
> +validate_dcc(struct amdgpu_device *adev,
> +	     const enum surface_pixel_format format,
> +	     const enum dc_rotation_angle rotation,
> +	     const union dc_tiling_info *tiling_info,
> +	     const struct dc_plane_dcc_param *dcc,
> +	     const struct dc_plane_address *address,
> +	     const struct plane_size *plane_size)
>   {
>   	struct dc *dc = adev->dm.dc;
>   	struct dc_dcc_surface_param input;
>   	struct dc_surface_dcc_cap output;
> -	uint64_t plane_address = afb->address + afb->base.offsets[0];
> -	uint32_t offset = AMDGPU_TILING_GET(info, DCC_OFFSET_256B);
> -	uint32_t i64b = AMDGPU_TILING_GET(info, DCC_INDEPENDENT_64B) != 0;
> -	uint64_t dcc_address;
>   
>   	memset(&input, 0, sizeof(input));
>   	memset(&output, 0, sizeof(output));
>   
> -	if (force_disable_dcc)
> +	if (!dcc->enable)
>   		return 0;
>   
> -	if (!offset)
> -		return 0;
> -
> -	if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
> -		return -EINVAL;
> -
> -	if (!dc->cap_funcs.get_dcc_compression_cap)
> +	if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ||
> +	    !dc->cap_funcs.get_dcc_compression_cap)
>   		return -EINVAL;
>   
>   	input.format = format;
> @@ -3897,17 +3937,60 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
>   	if (!output.capable)
>   		return -EINVAL;
>   
> -	if (i64b == 0 && output.grph.rgb.independent_64b_blks != 0)
> +	if (dcc->independent_64b_blks == 0 &&
> +	    output.grph.rgb.independent_64b_blks != 0)
>   		return -EINVAL;
>   
> +	return 0;
> +}
> +
> +static void
> +fill_dcc_params_from_flags(const struct amdgpu_framebuffer *afb,
> +			   struct dc_plane_dcc_param *dcc,
> +			   struct dc_plane_address *address,
> +			   const uint64_t flags, bool force_disable_dcc)
> +{
> +	uint64_t dcc_address;
> +	uint64_t plane_address = afb->address + afb->base.offsets[0];
> +	uint32_t offset = AMDGPU_TILING_GET(flags, DCC_OFFSET_256B);
> +	uint32_t i64b = AMDGPU_TILING_GET(flags, DCC_INDEPENDENT_64B) != 0;
> +
> +	if (!offset || force_disable_dcc)
> +		return;
> +
>   	dcc->enable = 1;
> -	dcc->meta_pitch =
> -		AMDGPU_TILING_GET(info, DCC_PITCH_MAX) + 1;
> +	dcc->meta_pitch = AMDGPU_TILING_GET(flags, DCC_PITCH_MAX) + 1;
>   	dcc->independent_64b_blks = i64b;
>   
> -	dcc_address = get_dcc_address(plane_address, info);
> +	dcc_address = plane_address + (uint64_t)offset * 256;
>   	address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
>   	address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
> +}
> +
> +
> +static int
> +fill_gfx9_plane_attributes_from_flags(struct amdgpu_device *adev,
> +				      const struct amdgpu_framebuffer *afb,
> +				      const enum surface_pixel_format format,
> +				      const enum dc_rotation_angle rotation,
> +				      const struct plane_size *plane_size,
> +				      union dc_tiling_info *tiling_info,
> +				      struct dc_plane_dcc_param *dcc,
> +				      struct dc_plane_address *address,
> +				      uint64_t tiling_flags,
> +				      bool force_disable_dcc)
> +{
> +	int ret;
> +
> +	fill_gfx9_tiling_info_from_device(adev, tiling_info);
> +
> +	tiling_info->gfx9.swizzle =
> +		AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
> +
> +	fill_dcc_params_from_flags(afb, dcc, address, tiling_flags, force_disable_dcc);
> +	ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size);
> +	if (ret)
> +		return ret;
>   
>   	return 0;
>   }
> @@ -3979,82 +4062,15 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
>   			upper_32_bits(chroma_addr);
>   	}
>   
> -	/* Fill GFX8 params */
> -	if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) {
> -		unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
> -
> -		bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
> -		bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
> -		mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
> -		tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT);
> -		num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
> -
> -		/* XXX fix me for VI */
> -		tiling_info->gfx8.num_banks = num_banks;
> -		tiling_info->gfx8.array_mode =
> -				DC_ARRAY_2D_TILED_THIN1;
> -		tiling_info->gfx8.tile_split = tile_split;
> -		tiling_info->gfx8.bank_width = bankw;
> -		tiling_info->gfx8.bank_height = bankh;
> -		tiling_info->gfx8.tile_aspect = mtaspect;
> -		tiling_info->gfx8.tile_mode =
> -				DC_ADDR_SURF_MICRO_TILING_DISPLAY;
> -	} else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE)
> -			== DC_ARRAY_1D_TILED_THIN1) {
> -		tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1;
> -	}
> -
> -	tiling_info->gfx8.pipe_config =
> -			AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
> -
> -	if (adev->asic_type == CHIP_VEGA10 ||
> -	    adev->asic_type == CHIP_VEGA12 ||
> -	    adev->asic_type == CHIP_VEGA20 ||
> -	    adev->asic_type == CHIP_NAVI10 ||
> -	    adev->asic_type == CHIP_NAVI14 ||
> -	    adev->asic_type == CHIP_NAVI12 ||
> -#if defined(CONFIG_DRM_AMD_DC_DCN3_0)
> -		adev->asic_type == CHIP_SIENNA_CICHLID ||
> -		adev->asic_type == CHIP_NAVY_FLOUNDER ||
> -#endif
> -#if defined(CONFIG_DRM_AMD_DC_DCN3_02)
> -		adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
> -#endif
> -#if defined(CONFIG_DRM_AMD_DC_DCN3_01)
> -		adev->asic_type == CHIP_VANGOGH ||
> -#endif
> -	    adev->asic_type == CHIP_RENOIR ||
> -	    adev->asic_type == CHIP_RAVEN) {
> -		/* Fill GFX9 params */
> -		tiling_info->gfx9.num_pipes =
> -			adev->gfx.config.gb_addr_config_fields.num_pipes;
> -		tiling_info->gfx9.num_banks =
> -			adev->gfx.config.gb_addr_config_fields.num_banks;
> -		tiling_info->gfx9.pipe_interleave =
> -			adev->gfx.config.gb_addr_config_fields.pipe_interleave_size;
> -		tiling_info->gfx9.num_shader_engines =
> -			adev->gfx.config.gb_addr_config_fields.num_se;
> -		tiling_info->gfx9.max_compressed_frags =
> -			adev->gfx.config.gb_addr_config_fields.max_compress_frags;
> -		tiling_info->gfx9.num_rb_per_se =
> -			adev->gfx.config.gb_addr_config_fields.num_rb_per_se;
> -		tiling_info->gfx9.swizzle =
> -			AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
> -		tiling_info->gfx9.shaderEnable = 1;
> -
> -#ifdef CONFIG_DRM_AMD_DC_DCN3_0
> -		if (adev->asic_type == CHIP_SIENNA_CICHLID ||
> -		    adev->asic_type == CHIP_NAVY_FLOUNDER ||
> -		    adev->asic_type == CHIP_DIMGREY_CAVEFISH ||
> -		    adev->asic_type == CHIP_VANGOGH)
> -			tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs;
> -#endif
> -		ret = fill_plane_dcc_attributes(adev, afb, format, rotation,
> -						plane_size, tiling_info,
> -						tiling_flags, dcc, address,
> -						force_disable_dcc);
> +	if (adev->family >= AMDGPU_FAMILY_AI) {
> +		ret = fill_gfx9_plane_attributes_from_flags(adev, afb, format, rotation,
> +							    plane_size, tiling_info, dcc,
> +							    address, tiling_flags,
> +							    force_disable_dcc);
>   		if (ret)
>   			return ret;
> +	} else {
> +		fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
>   	}
>   
>   	return 0;
> 

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2020-10-26 13:58 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-21 23:31 [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Bas Nieuwenhuizen
2020-10-21 23:31 ` [PATCH v3 01/11] drm/amd/display: Do not silently accept DCC for multiplane formats Bas Nieuwenhuizen
2020-10-26 13:50   ` Kazlauskas, Nicholas
2020-10-21 23:31 ` [PATCH v3 02/11] drm/amd: Init modifier field of helper fb Bas Nieuwenhuizen
2020-10-26 13:50   ` Kazlauskas, Nicholas
2020-10-21 23:31 ` [PATCH v3 03/11] drm/amd/display: Honor the offset for plane 0 Bas Nieuwenhuizen
2020-10-22 15:36   ` Alex Deucher
2020-10-22 16:10     ` Greg KH
2020-10-26 13:51   ` Kazlauskas, Nicholas
2020-10-21 23:31 ` [PATCH v3 04/11] drm/fourcc: Add AMD DRM modifiers Bas Nieuwenhuizen
2020-10-22 15:41   ` Alex Deucher
2020-10-22 16:39     ` Bas Nieuwenhuizen
2020-10-21 23:31 ` [PATCH v3 05/11] drm/amd/display: Store tiling_flags in the framebuffer Bas Nieuwenhuizen
2020-10-26 13:54   ` Kazlauskas, Nicholas
2020-10-21 23:31 ` [PATCH v3 06/11] drm/amd/display: Convert tiling_flags to modifiers Bas Nieuwenhuizen
2020-10-21 23:31 ` [PATCH v3 07/11] drm/amd/display: Refactor surface tiling setup Bas Nieuwenhuizen
2020-10-26 13:58   ` Kazlauskas, Nicholas
2020-10-21 23:31 ` [PATCH v3 08/11] drm/amd/display: Set DC options from modifiers Bas Nieuwenhuizen
2020-10-21 23:31 ` [PATCH v3 09/11] drm/amd/display: Add formats for DCC with 2/3 planes Bas Nieuwenhuizen
2020-10-21 23:31 ` [PATCH v3 10/11] drm/amd/display: Expose modifiers Bas Nieuwenhuizen
2020-10-22  5:50   ` Alex Deucher
2020-10-22 11:44     ` Bas Nieuwenhuizen
2020-10-21 23:31 ` [PATCH v3 11/11] drm/amd/display: Clean up GFX9 tiling_flags path Bas Nieuwenhuizen
2020-10-22 16:55 ` [PATCH v3 00/11] amd/display: Add GFX9+ modifier support Alex Deucher
2020-10-26  8:28 ` Pierre-Eric Pelloux-Prayer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).