All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt
@ 2023-04-23 14:10 ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, airlied, christian.koenig, daniel,
	maarten.lankhorst, mripard, tzimmermann, Xinhui.Pan
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

Hi all,

Joshua Ashton and I (with the great collaboration of Harry Wentland -
thanks) have been working on KMS color pipeline enhancement for Steam
Deck/SteamOS by exposing the large set of color caps available in AMD
display HW.

This patchset results from this full-stack work, including pre-blending
and post-blending new color properties. The first two patches fix
quantization issues on shaper LUT programming. Just after, we have one
patch that adds a config option to restrict AMD colo feature usage. The
following 13 patches implement AMD driver-private color properties
(pending detachment of property counter and plane color_mgmt_changed
from DRM). Finally, the last 24 patches rework the AMD display manager
and color management to support the properties exposed.

In short, for pre-blending, we added the following:
- plane degamma LUT and predefined transfer function;
- plane HDR multiplier
- plane shaper LUT/transfer function;
- plane 3D LUT; and finally,
- plane blend LUT/transfer function, just before blending.

After blending, we already have DRM CRTC degamma/gamma LUTs and CTM,
therefore, we extend CRTC color pipeline with the following:
- CRTC shaper LUT/transfer function;
- CRTC 3D LUT; and
- CRTC gamma transfer function.

You can already find the AMD color capabilities and color management
pipeline documented here:
https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties

In previous iterations, we tried to provide a generic solution for
post-blending shaper and 3D LUT [1][2][3], and also Alex Hung worked on
a pre-blending 3D LUT solution[4] extending plane color mgmt proposal
from Uma Shankar [5]. However, we identified during our work [6] that
AMD provides many other valuable capabilities that we don't find in
other vendors, so we started to work on AMD driver-private color
properties that better describe its color pipeline, enabling us to
expose full AMD color capabilities on Deck HW.

Our primary purpose is to avoid usage limitations of color calibration
features provided by HW just because we don't have an interface for
that. At the same time, a generic solution doesn't fit well since some
of these capabilities seem AMD HW specific, such as hardcoded
curve/predefined transfer function and shaper 1D LUTs sandwiching 3D
LUT.

So far, we keep these properties' usage under an AMD display config
option (STEAM_DECK). However, we are fine with having them fully
available to other DCN HW generations. In the current proposal, we are
already checking ASICs before exposing a color feature. We can work on
3D LUT resource acquisition details to fit them to DCN 3+ families that
support them. Indeed, before moving to these config boundaries, we
started working on an open solution for any AMD HW [7].

The userspace case here is Gamescope which is the compositor for
SteamOS. It's already using all of this functionality (although with a
VALVE1_ prefix instead of AMD) to implement its color management
pipeline right now:
https://github.com/ValveSoftware/gamescope

We are planning on shipping our color management support with gamut
mapping, HDR, SDR on HDR, HDR on SDR, and much more in Steam OS 3.5. A
brief overview of our color pipeline can be found here:
https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png

We have also had some other userspace interests from Xaver Hugl (KDE) in
experimenting with these properties for their HDR/color bring-up before
a generic interface is settled on also.

It still needs AMD-specific IGT tests; we are working on documentation
and adding plane CTM support too. 

We decided first to share our work to collect thoughts and open for
discussion, even with missing refinements, since driver-private
properties are not the usual DMR/KMS color management approach.

Please, let us know your thoughts.

Best Regards,

Signed-off-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Melissa Wen<mwen@igalia.com>

[1] https://lore.kernel.org/dri-devel/20220619223104.667413-1-mwen@igalia.com/
[2] https://lore.kernel.org/amd-gfx/20220906164628.2361811-1-mwen@igalia.com/
[3] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-mwen@igalia.com/
[4] https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.hung@amd.com/
[5] https://lore.kernel.org/dri-devel/20210906213904.27918-1-uma.shankar@intel.com/
[6] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-color-mgmt
[7] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-private-color-mgmt

Harry Wentland (2):
  drm/amd/display: fix segment distribution for linear LUTs
  drm/amd/display: fix the delta clamping for shaper LUT

Joshua Ashton (15):
  drm/amd/display: add CRTC gamma TF to driver-private props
  drm/amd/display: add plane degamma LUT driver-private props
  drm/amd/display: add plane degamma TF driver-private property
  drm/amd/display: add plane HDR multiplier driver-private property
  drm/amd/display: add plane blend LUT and TF driver-private properties
  drm/amd/display: copy 3D LUT settings from crtc state to stream_update
  drm/amd/display: dynamically acquire 3DLUT resources for color changes
  drm/amd/display: add CRTC regamma TF support
  drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
  drm/amd/display: add support for plane degamma TF and LUT properties
  drm/amd/display: add dc_fixpt_from_s3132 helper
  drm/adm/display: add HDR multiplier support
  drm/amd/display: handle empty LUTs in __set_input_tf
  drm/amd/display: add DRM plane blend LUT and TF support
  drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG

Melissa Wen (23):
  drm/amd/display: introduce Steam Deck color features to AMD display
    driver
  drm/drm_mode_object: increase max objects to accommodate new color
    props
  drm/amd/display: add shaper LUT driver-private props
  drm/amd/display: add 3D LUT driver-private props
  drm/drm_plane: track color mgmt changes per plane
  drm/amd/display: move replace blob func to dm plane
  drm/amd/display: add plane 3D LUT driver-private properties
  drm/amd/display: add plane shaper LUT driver-private properties
  drm/amd/display: add plane shaper TF driver-private property
  drm/amd/display: add comments to describe DM crtc color mgmt behavior
  drm/amd/display: encapsulate atomic regamma operation
  drm/amd/display: update lut3d and shaper lut to stream
  drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
  drm/amd/display: handle MPC 3D LUT resources for a given context
  drm/amd/display: add CRTC 3D LUT support to amd color pipeline
  drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
  drm/amd/display: add CRTC shaper LUT support to amd color pipeline
  drm/amd/display: add CRTC shaper TF support
  drm/amd/display: mark plane as needing reset if plane color mgmt
    changes
  drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
  drm/amd/display: reject atomic commit if setting both plane and CRTC
    degamma
  drm/amd/display: add plane shaper/3D LUT and shaper TF support
  drm/amd/display: copy dc_plane color settings to surface_updates

 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 153 +++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  92 +++
 drivers/gpu/drm/amd/display/Kconfig           |   6 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  31 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 120 +++-
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 613 ++++++++++++++++--
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 124 +++-
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 238 +++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |   7 +
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  49 +-
 drivers/gpu/drm/amd/display/dc/dc.h           |   8 +
 .../amd/display/dc/dcn10/dcn10_cm_common.c    | 109 +++-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   5 +-
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   9 +-
 .../amd/display/dc/dcn301/dcn301_resource.c   |  26 +-
 .../gpu/drm/amd/display/include/fixed31_32.h  |  12 +
 drivers/gpu/drm/drm_atomic.c                  |   1 +
 drivers/gpu/drm/drm_atomic_state_helper.c     |   1 +
 include/drm/drm_mode_object.h                 |   2 +-
 include/drm/drm_plane.h                       |   7 +
 20 files changed, 1509 insertions(+), 104 deletions(-)

-- 
2.39.2


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

* [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt
@ 2023-04-23 14:10 ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, airlied, christian.koenig, daniel,
	maarten.lankhorst, mripard, tzimmermann, Xinhui.Pan
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

Hi all,

Joshua Ashton and I (with the great collaboration of Harry Wentland -
thanks) have been working on KMS color pipeline enhancement for Steam
Deck/SteamOS by exposing the large set of color caps available in AMD
display HW.

This patchset results from this full-stack work, including pre-blending
and post-blending new color properties. The first two patches fix
quantization issues on shaper LUT programming. Just after, we have one
patch that adds a config option to restrict AMD colo feature usage. The
following 13 patches implement AMD driver-private color properties
(pending detachment of property counter and plane color_mgmt_changed
from DRM). Finally, the last 24 patches rework the AMD display manager
and color management to support the properties exposed.

In short, for pre-blending, we added the following:
- plane degamma LUT and predefined transfer function;
- plane HDR multiplier
- plane shaper LUT/transfer function;
- plane 3D LUT; and finally,
- plane blend LUT/transfer function, just before blending.

After blending, we already have DRM CRTC degamma/gamma LUTs and CTM,
therefore, we extend CRTC color pipeline with the following:
- CRTC shaper LUT/transfer function;
- CRTC 3D LUT; and
- CRTC gamma transfer function.

You can already find the AMD color capabilities and color management
pipeline documented here:
https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties

In previous iterations, we tried to provide a generic solution for
post-blending shaper and 3D LUT [1][2][3], and also Alex Hung worked on
a pre-blending 3D LUT solution[4] extending plane color mgmt proposal
from Uma Shankar [5]. However, we identified during our work [6] that
AMD provides many other valuable capabilities that we don't find in
other vendors, so we started to work on AMD driver-private color
properties that better describe its color pipeline, enabling us to
expose full AMD color capabilities on Deck HW.

Our primary purpose is to avoid usage limitations of color calibration
features provided by HW just because we don't have an interface for
that. At the same time, a generic solution doesn't fit well since some
of these capabilities seem AMD HW specific, such as hardcoded
curve/predefined transfer function and shaper 1D LUTs sandwiching 3D
LUT.

So far, we keep these properties' usage under an AMD display config
option (STEAM_DECK). However, we are fine with having them fully
available to other DCN HW generations. In the current proposal, we are
already checking ASICs before exposing a color feature. We can work on
3D LUT resource acquisition details to fit them to DCN 3+ families that
support them. Indeed, before moving to these config boundaries, we
started working on an open solution for any AMD HW [7].

The userspace case here is Gamescope which is the compositor for
SteamOS. It's already using all of this functionality (although with a
VALVE1_ prefix instead of AMD) to implement its color management
pipeline right now:
https://github.com/ValveSoftware/gamescope

We are planning on shipping our color management support with gamut
mapping, HDR, SDR on HDR, HDR on SDR, and much more in Steam OS 3.5. A
brief overview of our color pipeline can be found here:
https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png

We have also had some other userspace interests from Xaver Hugl (KDE) in
experimenting with these properties for their HDR/color bring-up before
a generic interface is settled on also.

It still needs AMD-specific IGT tests; we are working on documentation
and adding plane CTM support too. 

We decided first to share our work to collect thoughts and open for
discussion, even with missing refinements, since driver-private
properties are not the usual DMR/KMS color management approach.

Please, let us know your thoughts.

Best Regards,

Signed-off-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Melissa Wen<mwen@igalia.com>

[1] https://lore.kernel.org/dri-devel/20220619223104.667413-1-mwen@igalia.com/
[2] https://lore.kernel.org/amd-gfx/20220906164628.2361811-1-mwen@igalia.com/
[3] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-mwen@igalia.com/
[4] https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.hung@amd.com/
[5] https://lore.kernel.org/dri-devel/20210906213904.27918-1-uma.shankar@intel.com/
[6] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-color-mgmt
[7] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-private-color-mgmt

Harry Wentland (2):
  drm/amd/display: fix segment distribution for linear LUTs
  drm/amd/display: fix the delta clamping for shaper LUT

Joshua Ashton (15):
  drm/amd/display: add CRTC gamma TF to driver-private props
  drm/amd/display: add plane degamma LUT driver-private props
  drm/amd/display: add plane degamma TF driver-private property
  drm/amd/display: add plane HDR multiplier driver-private property
  drm/amd/display: add plane blend LUT and TF driver-private properties
  drm/amd/display: copy 3D LUT settings from crtc state to stream_update
  drm/amd/display: dynamically acquire 3DLUT resources for color changes
  drm/amd/display: add CRTC regamma TF support
  drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
  drm/amd/display: add support for plane degamma TF and LUT properties
  drm/amd/display: add dc_fixpt_from_s3132 helper
  drm/adm/display: add HDR multiplier support
  drm/amd/display: handle empty LUTs in __set_input_tf
  drm/amd/display: add DRM plane blend LUT and TF support
  drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG

Melissa Wen (23):
  drm/amd/display: introduce Steam Deck color features to AMD display
    driver
  drm/drm_mode_object: increase max objects to accommodate new color
    props
  drm/amd/display: add shaper LUT driver-private props
  drm/amd/display: add 3D LUT driver-private props
  drm/drm_plane: track color mgmt changes per plane
  drm/amd/display: move replace blob func to dm plane
  drm/amd/display: add plane 3D LUT driver-private properties
  drm/amd/display: add plane shaper LUT driver-private properties
  drm/amd/display: add plane shaper TF driver-private property
  drm/amd/display: add comments to describe DM crtc color mgmt behavior
  drm/amd/display: encapsulate atomic regamma operation
  drm/amd/display: update lut3d and shaper lut to stream
  drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
  drm/amd/display: handle MPC 3D LUT resources for a given context
  drm/amd/display: add CRTC 3D LUT support to amd color pipeline
  drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
  drm/amd/display: add CRTC shaper LUT support to amd color pipeline
  drm/amd/display: add CRTC shaper TF support
  drm/amd/display: mark plane as needing reset if plane color mgmt
    changes
  drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
  drm/amd/display: reject atomic commit if setting both plane and CRTC
    degamma
  drm/amd/display: add plane shaper/3D LUT and shaper TF support
  drm/amd/display: copy dc_plane color settings to surface_updates

 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 153 +++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  92 +++
 drivers/gpu/drm/amd/display/Kconfig           |   6 +
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  31 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 120 +++-
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 613 ++++++++++++++++--
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 124 +++-
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 238 +++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |   7 +
 drivers/gpu/drm/amd/display/dc/core/dc.c      |  49 +-
 drivers/gpu/drm/amd/display/dc/dc.h           |   8 +
 .../amd/display/dc/dcn10/dcn10_cm_common.c    | 109 +++-
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   5 +-
 .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   9 +-
 .../amd/display/dc/dcn301/dcn301_resource.c   |  26 +-
 .../gpu/drm/amd/display/include/fixed31_32.h  |  12 +
 drivers/gpu/drm/drm_atomic.c                  |   1 +
 drivers/gpu/drm/drm_atomic_state_helper.c     |   1 +
 include/drm/drm_mode_object.h                 |   2 +-
 include/drm/drm_plane.h                       |   7 +
 20 files changed, 1509 insertions(+), 104 deletions(-)

-- 
2.39.2


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

* [RFC PATCH 01/40] drm/amd/display: fix segment distribution for linear LUTs
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Harry Wentland <harry.wentland@amd.com>

The region and segment calculation was incapable of dealing
with regions of more than 16 segments. We first fix this.

Now that we can support regions up to 256 elements we can
define a better segment distribution for near-linear LUTs
for our maximum of 256 HW-supported points.

With these changes an "identity" LUT looks visually
indistinguishable from bypass and allows us to use
our 3DLUT.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
---
 .../amd/display/dc/dcn10/dcn10_cm_common.c    | 95 +++++++++++++++----
 1 file changed, 76 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index 7a00fe525dfb..f27413e94280 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -346,20 +346,37 @@ bool cm_helper_translate_curve_to_hw_format(
 		 * segment is from 2^-10 to 2^1
 		 * There are less than 256 points, for optimization
 		 */
-		seg_distr[0] = 3;
-		seg_distr[1] = 4;
-		seg_distr[2] = 4;
-		seg_distr[3] = 4;
-		seg_distr[4] = 4;
-		seg_distr[5] = 4;
-		seg_distr[6] = 4;
-		seg_distr[7] = 4;
-		seg_distr[8] = 4;
-		seg_distr[9] = 4;
-		seg_distr[10] = 1;
-
-		region_start = -10;
-		region_end = 1;
+		if (output_tf->tf == TRANSFER_FUNCTION_LINEAR) {
+			seg_distr[0] = 0; /* 2 */
+			seg_distr[1] = 1; /* 4 */
+			seg_distr[2] = 2; /* 4 */
+			seg_distr[3] = 3; /* 8 */
+			seg_distr[4] = 4; /* 16 */
+			seg_distr[5] = 5; /* 32 */
+			seg_distr[6] = 6; /* 64 */
+			seg_distr[7] = 7; /* 128 */
+
+			region_start = -8;
+			region_end = 1;
+		} else {
+			seg_distr[0] = 3; /* 8 */
+			seg_distr[1] = 4; /* 16 */
+			seg_distr[2] = 4;
+			seg_distr[3] = 4;
+			seg_distr[4] = 4;
+			seg_distr[5] = 4;
+			seg_distr[6] = 4;
+			seg_distr[7] = 4;
+			seg_distr[8] = 4;
+			seg_distr[9] = 4;
+			seg_distr[10] = 1; /* 2 */
+			/* total = 8*16 + 8 + 64 + 2 = */
+
+			region_start = -10;
+			region_end = 1;
+		}
+
+
 	}
 
 	for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
@@ -372,16 +389,56 @@ bool cm_helper_translate_curve_to_hw_format(
 
 	j = 0;
 	for (k = 0; k < (region_end - region_start); k++) {
-		increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
+		/*
+		 * We're using an ugly-ish hack here. Our HW allows for
+		 * 256 segments per region but SW_SEGMENTS is 16.
+		 * SW_SEGMENTS has some undocumented relationship to
+		 * the number of points in the tf_pts struct, which
+		 * is 512, unlike what's suggested TRANSFER_FUNC_POINTS.
+		 *
+		 * In order to work past this dilemma we'll scale our
+		 * increment by (1 << 4) and then do the inverse (1 >> 4)
+		 * when accessing the elements in tf_pts.
+		 *
+		 * TODO: find a better way using SW_SEGMENTS and
+		 *       TRANSFER_FUNC_POINTS definitions
+		 */
+		increment = (NUMBER_SW_SEGMENTS << 4) / (1 << seg_distr[k]);
 		start_index = (region_start + k + MAX_LOW_POINT) *
 				NUMBER_SW_SEGMENTS;
-		for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
+		for (i = (start_index << 4); i < (start_index << 4) + (NUMBER_SW_SEGMENTS << 4);
 				i += increment) {
+			struct fixed31_32 in_plus_one, in;
+			struct fixed31_32 value, red_value, green_value, blue_value;
+			uint32_t t = i & 0xf;
+
 			if (j == hw_points - 1)
 				break;
-			rgb_resulted[j].red = output_tf->tf_pts.red[i];
-			rgb_resulted[j].green = output_tf->tf_pts.green[i];
-			rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
+
+			in_plus_one = output_tf->tf_pts.red[(i >> 4) + 1];
+			in = output_tf->tf_pts.red[i >> 4];
+			value = dc_fixpt_sub(in_plus_one, in);
+			value = dc_fixpt_shr(dc_fixpt_mul_int(value, t),  4);
+			value = dc_fixpt_add(in, value);
+			red_value = value;
+
+			in_plus_one = output_tf->tf_pts.green[(i >> 4) + 1];
+			in = output_tf->tf_pts.green[i >> 4];
+			value = dc_fixpt_sub(in_plus_one, in);
+			value = dc_fixpt_shr(dc_fixpt_mul_int(value, t),  4);
+			value = dc_fixpt_add(in, value);
+			green_value = value;
+
+			in_plus_one = output_tf->tf_pts.blue[(i >> 4) + 1];
+			in = output_tf->tf_pts.blue[i >> 4];
+			value = dc_fixpt_sub(in_plus_one, in);
+			value = dc_fixpt_shr(dc_fixpt_mul_int(value, t),  4);
+			value = dc_fixpt_add(in, value);
+			blue_value = value;
+
+			rgb_resulted[j].red = red_value;
+			rgb_resulted[j].green = green_value;
+			rgb_resulted[j].blue = blue_value;
 			j++;
 		}
 	}
-- 
2.39.2


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

* [RFC PATCH 01/40] drm/amd/display: fix segment distribution for linear LUTs
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Harry Wentland <harry.wentland@amd.com>

The region and segment calculation was incapable of dealing
with regions of more than 16 segments. We first fix this.

Now that we can support regions up to 256 elements we can
define a better segment distribution for near-linear LUTs
for our maximum of 256 HW-supported points.

With these changes an "identity" LUT looks visually
indistinguishable from bypass and allows us to use
our 3DLUT.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
---
 .../amd/display/dc/dcn10/dcn10_cm_common.c    | 95 +++++++++++++++----
 1 file changed, 76 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index 7a00fe525dfb..f27413e94280 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -346,20 +346,37 @@ bool cm_helper_translate_curve_to_hw_format(
 		 * segment is from 2^-10 to 2^1
 		 * There are less than 256 points, for optimization
 		 */
-		seg_distr[0] = 3;
-		seg_distr[1] = 4;
-		seg_distr[2] = 4;
-		seg_distr[3] = 4;
-		seg_distr[4] = 4;
-		seg_distr[5] = 4;
-		seg_distr[6] = 4;
-		seg_distr[7] = 4;
-		seg_distr[8] = 4;
-		seg_distr[9] = 4;
-		seg_distr[10] = 1;
-
-		region_start = -10;
-		region_end = 1;
+		if (output_tf->tf == TRANSFER_FUNCTION_LINEAR) {
+			seg_distr[0] = 0; /* 2 */
+			seg_distr[1] = 1; /* 4 */
+			seg_distr[2] = 2; /* 4 */
+			seg_distr[3] = 3; /* 8 */
+			seg_distr[4] = 4; /* 16 */
+			seg_distr[5] = 5; /* 32 */
+			seg_distr[6] = 6; /* 64 */
+			seg_distr[7] = 7; /* 128 */
+
+			region_start = -8;
+			region_end = 1;
+		} else {
+			seg_distr[0] = 3; /* 8 */
+			seg_distr[1] = 4; /* 16 */
+			seg_distr[2] = 4;
+			seg_distr[3] = 4;
+			seg_distr[4] = 4;
+			seg_distr[5] = 4;
+			seg_distr[6] = 4;
+			seg_distr[7] = 4;
+			seg_distr[8] = 4;
+			seg_distr[9] = 4;
+			seg_distr[10] = 1; /* 2 */
+			/* total = 8*16 + 8 + 64 + 2 = */
+
+			region_start = -10;
+			region_end = 1;
+		}
+
+
 	}
 
 	for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
@@ -372,16 +389,56 @@ bool cm_helper_translate_curve_to_hw_format(
 
 	j = 0;
 	for (k = 0; k < (region_end - region_start); k++) {
-		increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]);
+		/*
+		 * We're using an ugly-ish hack here. Our HW allows for
+		 * 256 segments per region but SW_SEGMENTS is 16.
+		 * SW_SEGMENTS has some undocumented relationship to
+		 * the number of points in the tf_pts struct, which
+		 * is 512, unlike what's suggested TRANSFER_FUNC_POINTS.
+		 *
+		 * In order to work past this dilemma we'll scale our
+		 * increment by (1 << 4) and then do the inverse (1 >> 4)
+		 * when accessing the elements in tf_pts.
+		 *
+		 * TODO: find a better way using SW_SEGMENTS and
+		 *       TRANSFER_FUNC_POINTS definitions
+		 */
+		increment = (NUMBER_SW_SEGMENTS << 4) / (1 << seg_distr[k]);
 		start_index = (region_start + k + MAX_LOW_POINT) *
 				NUMBER_SW_SEGMENTS;
-		for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS;
+		for (i = (start_index << 4); i < (start_index << 4) + (NUMBER_SW_SEGMENTS << 4);
 				i += increment) {
+			struct fixed31_32 in_plus_one, in;
+			struct fixed31_32 value, red_value, green_value, blue_value;
+			uint32_t t = i & 0xf;
+
 			if (j == hw_points - 1)
 				break;
-			rgb_resulted[j].red = output_tf->tf_pts.red[i];
-			rgb_resulted[j].green = output_tf->tf_pts.green[i];
-			rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
+
+			in_plus_one = output_tf->tf_pts.red[(i >> 4) + 1];
+			in = output_tf->tf_pts.red[i >> 4];
+			value = dc_fixpt_sub(in_plus_one, in);
+			value = dc_fixpt_shr(dc_fixpt_mul_int(value, t),  4);
+			value = dc_fixpt_add(in, value);
+			red_value = value;
+
+			in_plus_one = output_tf->tf_pts.green[(i >> 4) + 1];
+			in = output_tf->tf_pts.green[i >> 4];
+			value = dc_fixpt_sub(in_plus_one, in);
+			value = dc_fixpt_shr(dc_fixpt_mul_int(value, t),  4);
+			value = dc_fixpt_add(in, value);
+			green_value = value;
+
+			in_plus_one = output_tf->tf_pts.blue[(i >> 4) + 1];
+			in = output_tf->tf_pts.blue[i >> 4];
+			value = dc_fixpt_sub(in_plus_one, in);
+			value = dc_fixpt_shr(dc_fixpt_mul_int(value, t),  4);
+			value = dc_fixpt_add(in, value);
+			blue_value = value;
+
+			rgb_resulted[j].red = red_value;
+			rgb_resulted[j].green = green_value;
+			rgb_resulted[j].blue = blue_value;
 			j++;
 		}
 	}
-- 
2.39.2


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

* [RFC PATCH 02/40] drm/amd/display: fix the delta clamping for shaper LUT
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Harry Wentland <harry.wentland@amd.com>

The shaper LUT requires a 10-bit value of the delta between
segments. We were using dc_fixpt_clamp_u0d10() to do that
but it doesn't do what we want it to do. It will preserve
10-bit precision after the decimal point, but that's not
quite what we want. We want 14-bit precision and discard
the 4 most-significant bytes.

To do that we'll do dc_fixpt_clamp_u0d14() & 0x3ff instead.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
---
 .../gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index f27413e94280..efa6cee649d0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -539,10 +539,18 @@ bool cm_helper_translate_curve_to_hw_format(
 		rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
 		rgb->delta_blue  = dc_fixpt_sub(rgb_plus_1->blue,  rgb->blue);
 
+
 		if (fixpoint == true) {
-			rgb->delta_red_reg   = dc_fixpt_clamp_u0d10(rgb->delta_red);
-			rgb->delta_green_reg = dc_fixpt_clamp_u0d10(rgb->delta_green);
-			rgb->delta_blue_reg  = dc_fixpt_clamp_u0d10(rgb->delta_blue);
+			uint32_t red_clamp = dc_fixpt_clamp_u0d14(rgb->delta_red);
+			uint32_t green_clamp = dc_fixpt_clamp_u0d14(rgb->delta_green);
+			uint32_t blue_clamp = dc_fixpt_clamp_u0d14(rgb->delta_blue);
+
+			if (red_clamp >> 10 || green_clamp >> 10 || blue_clamp >> 10)
+				DC_LOG_WARNING("Losing delta precision while programming shaper LUT.");
+
+			rgb->delta_red_reg   = red_clamp & 0x3ff;
+			rgb->delta_green_reg = green_clamp & 0x3ff;
+			rgb->delta_blue_reg  = blue_clamp & 0x3ff;
 			rgb->red_reg         = dc_fixpt_clamp_u0d14(rgb->red);
 			rgb->green_reg       = dc_fixpt_clamp_u0d14(rgb->green);
 			rgb->blue_reg        = dc_fixpt_clamp_u0d14(rgb->blue);
-- 
2.39.2


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

* [RFC PATCH 02/40] drm/amd/display: fix the delta clamping for shaper LUT
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Harry Wentland <harry.wentland@amd.com>

The shaper LUT requires a 10-bit value of the delta between
segments. We were using dc_fixpt_clamp_u0d10() to do that
but it doesn't do what we want it to do. It will preserve
10-bit precision after the decimal point, but that's not
quite what we want. We want 14-bit precision and discard
the 4 most-significant bytes.

To do that we'll do dc_fixpt_clamp_u0d14() & 0x3ff instead.

Signed-off-by: Harry Wentland <harry.wentland@amd.com>
---
 .../gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
index f27413e94280..efa6cee649d0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -539,10 +539,18 @@ bool cm_helper_translate_curve_to_hw_format(
 		rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
 		rgb->delta_blue  = dc_fixpt_sub(rgb_plus_1->blue,  rgb->blue);
 
+
 		if (fixpoint == true) {
-			rgb->delta_red_reg   = dc_fixpt_clamp_u0d10(rgb->delta_red);
-			rgb->delta_green_reg = dc_fixpt_clamp_u0d10(rgb->delta_green);
-			rgb->delta_blue_reg  = dc_fixpt_clamp_u0d10(rgb->delta_blue);
+			uint32_t red_clamp = dc_fixpt_clamp_u0d14(rgb->delta_red);
+			uint32_t green_clamp = dc_fixpt_clamp_u0d14(rgb->delta_green);
+			uint32_t blue_clamp = dc_fixpt_clamp_u0d14(rgb->delta_blue);
+
+			if (red_clamp >> 10 || green_clamp >> 10 || blue_clamp >> 10)
+				DC_LOG_WARNING("Losing delta precision while programming shaper LUT.");
+
+			rgb->delta_red_reg   = red_clamp & 0x3ff;
+			rgb->delta_green_reg = green_clamp & 0x3ff;
+			rgb->delta_blue_reg  = blue_clamp & 0x3ff;
 			rgb->red_reg         = dc_fixpt_clamp_u0d14(rgb->red);
 			rgb->green_reg       = dc_fixpt_clamp_u0d14(rgb->green);
 			rgb->blue_reg        = dc_fixpt_clamp_u0d14(rgb->blue);
-- 
2.39.2


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

* [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

We are enabling a large set of color calibration features to enhance KMS
color mgmt but these properties are specific of AMD display HW, and
cannot be provided by other vendors. Therefore, set a config option to
enable AMD driver-private properties used on Steam Deck color mgmt
pipeline.

Co-developed-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index 06b438217c61..c45a8deb1098 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
             of crc of specific region via debugfs.
             Cooperate with specific DMCU FW.
 
+config STEAM_DECK
+	bool "Enable color calibration features for Steam Deck"
+	depends on DRM_AMD_DC
+	help
+	  Choose this option if you want to use AMDGPU features for broader
+	  color management support on Steam Deck.
 
 endmenu
-- 
2.39.2


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

* [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

We are enabling a large set of color calibration features to enhance KMS
color mgmt but these properties are specific of AMD display HW, and
cannot be provided by other vendors. Therefore, set a config option to
enable AMD driver-private properties used on Steam Deck color mgmt
pipeline.

Co-developed-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index 06b438217c61..c45a8deb1098 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
             of crc of specific region via debugfs.
             Cooperate with specific DMCU FW.
 
+config STEAM_DECK
+	bool "Enable color calibration features for Steam Deck"
+	depends on DRM_AMD_DC
+	help
+	  Choose this option if you want to use AMDGPU features for broader
+	  color management support on Steam Deck.
 
 endmenu
-- 
2.39.2


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

* [RFC PATCH 04/40] drm/drm_mode_object: increase max objects to accommodate new color props
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, maarten.lankhorst, mripard, tzimmermann,
	airlied, daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

In the next patches we are adding 17 new properties for color
correction:
- CRTC: 3D LUT+size, shaper LUT+size, regamma TF (5)
- Plane: Degamma LUT+size+TF, HDR multiplier, shaper LUT+size+TF, 3D LUT+size, blend
  LUT+size+TF (12)
We still need to detach driver-private counter from DRM/KMS-generic, by
now, increase max objs to 41.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 include/drm/drm_mode_object.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index 912f1e415685..7e4fb7536c6a 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -60,7 +60,7 @@ struct drm_mode_object {
 	void (*free_cb)(struct kref *kref);
 };
 
-#define DRM_OBJECT_MAX_PROPERTY 24
+#define DRM_OBJECT_MAX_PROPERTY 47
 /**
  * struct drm_object_properties - property tracking for &drm_mode_object
  */
-- 
2.39.2


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

* [RFC PATCH 04/40] drm/drm_mode_object: increase max objects to accommodate new color props
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, maarten.lankhorst, mripard, tzimmermann,
	airlied, daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

In the next patches we are adding 17 new properties for color
correction:
- CRTC: 3D LUT+size, shaper LUT+size, regamma TF (5)
- Plane: Degamma LUT+size+TF, HDR multiplier, shaper LUT+size+TF, 3D LUT+size, blend
  LUT+size+TF (12)
We still need to detach driver-private counter from DRM/KMS-generic, by
now, increase max objs to 41.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 include/drm/drm_mode_object.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index 912f1e415685..7e4fb7536c6a 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -60,7 +60,7 @@ struct drm_mode_object {
 	void (*free_cb)(struct kref *kref);
 };
 
-#define DRM_OBJECT_MAX_PROPERTY 24
+#define DRM_OBJECT_MAX_PROPERTY 47
 /**
  * struct drm_object_properties - property tracking for &drm_mode_object
  */
-- 
2.39.2


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

* [RFC PATCH 05/40] drm/amd/display: add shaper LUT driver-private props
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

CRTC shaper LUT shapes the content after blending, i.e., de-linearizes
or normalizes space before applying a 3D LUT color correction. In the
next patch, we add CRTC 3D LUT property to DRM color management after
this shaper LUT and before the current CRTC gamma LUT.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  28 ++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  14 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  17 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 122 +++++++++++++++++-
 4 files changed, 179 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 8632ab695a6c..44c22cb87dde 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1247,6 +1247,30 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
 	return &amdgpu_fb->base;
 }
 
+#ifdef CONFIG_STEAM_DECK
+static int
+amdgpu_display_create_color_properties(struct amdgpu_device *adev)
+{
+	struct drm_property *prop;
+
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_SHAPER_LUT", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.shaper_lut_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_SHAPER_LUT_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.shaper_lut_size_property = prop;
+
+	return 0;
+}
+#endif
+
 const struct drm_mode_config_funcs amdgpu_mode_funcs = {
 	.fb_create = amdgpu_display_user_framebuffer_create,
 };
@@ -1323,6 +1347,10 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
 			return -ENOMEM;
 	}
 
+#ifdef CONFIG_STEAM_DECK
+	if (amdgpu_display_create_color_properties(adev))
+		return -ENOMEM;
+#endif
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index b8633df418d4..1fd3497af3b5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -344,6 +344,20 @@ struct amdgpu_mode_info {
 	int			disp_priority;
 	const struct amdgpu_display_funcs *funcs;
 	const enum drm_plane_type *plane_type;
+
+	/* Driver-private color mgmt props */
+#ifdef CONFIG_STEAM_DECK
+	/**
+	 * @shaper_lut_property: CRTC property to set post-blending shaper LUT
+	 * that converts content before 3D LUT gamma correction.
+	 */
+	struct drm_property *shaper_lut_property;
+	/**
+	 * @shaper_lut_size_property: CRTC property for the size of
+	 * post-blending shaper LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *shaper_lut_size_property;
+#endif
 };
 
 #define AMDGPU_MAX_BL_LEVEL 0xFF
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 2e2413fd73a4..de63455896cc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -726,6 +726,23 @@ struct dm_crtc_state {
 	struct dc_info_packet vrr_infopacket;
 
 	int abm_level;
+
+#ifdef CONFIG_STEAM_DECK
+	/* AMD driver-private color mgmt pipeline
+	 *
+	 * DRM provides CRTC degamma/ctm/gamma color mgmt features, but AMD HW
+	 * has a larger set of post-blending color calibration features, as
+	 * below:
+	 */
+	/**
+	 * @shaper_lut:
+	 *
+	 * Lookup table used to de-linearize pixel data for gamma correction.
+	 * See drm_crtc_enable_color_mgmt(). The blob (if not NULL) is an array
+	 * of &struct drm_color_lut.
+	 */
+	struct drm_property_blob *shaper_lut;
+#endif
 };
 
 #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index e3762e806617..503433e5cb38 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -229,7 +229,9 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
 	if (cur->stream)
 		dc_stream_release(cur->stream);
 
-
+#ifdef CONFIG_STEAM_DECK
+	drm_property_blob_put(cur->shaper_lut);
+#endif
 	__drm_atomic_helper_crtc_destroy_state(state);
 
 
@@ -266,7 +268,12 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
 	state->crc_skip_count = cur->crc_skip_count;
 	state->mpo_requested = cur->mpo_requested;
 	/* TODO Duplicate dc_stream after objects are stream object is flattened */
+#ifdef CONFIG_STEAM_DECK
+	state->shaper_lut = cur->shaper_lut;
 
+	if (state->shaper_lut)
+		drm_property_blob_get(state->shaper_lut);
+#endif
 	return &state->base;
 }
 
@@ -299,6 +306,111 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc)
 }
 #endif
 
+#ifdef CONFIG_STEAM_DECK
+/**
+ * drm_crtc_additional_color_mgmt - enable additional color properties
+ * @crtc: DRM CRTC
+ *
+ * This function lets the driver enable the 3D LUT color correction property
+ * on a CRTC. This includes shaper LUT, 3D LUT and regamma TF. The shaper
+ * LUT and 3D LUT property is only attached if its size is not 0.
+ */
+static void
+dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
+{
+	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
+
+	if (adev->dm.dc->caps.color.mpc.num_3dluts) {
+		drm_object_attach_property(&crtc->base,
+					   adev->mode_info.shaper_lut_property, 0);
+		drm_object_attach_property(&crtc->base,
+					   adev->mode_info.shaper_lut_size_property,
+					   MAX_COLOR_LUT_ENTRIES);
+	}
+}
+
+static int
+atomic_replace_property_blob_from_id(struct drm_device *dev,
+					 struct drm_property_blob **blob,
+					 uint64_t blob_id,
+					 ssize_t expected_size,
+					 ssize_t expected_elem_size,
+					 bool *replaced)
+{
+	struct drm_property_blob *new_blob = NULL;
+
+	if (blob_id != 0) {
+		new_blob = drm_property_lookup_blob(dev, blob_id);
+		if (new_blob == NULL)
+			return -EINVAL;
+
+		if (expected_size > 0 &&
+		    new_blob->length != expected_size) {
+			drm_property_blob_put(new_blob);
+			return -EINVAL;
+		}
+		if (expected_elem_size > 0 &&
+		    new_blob->length % expected_elem_size != 0) {
+			drm_property_blob_put(new_blob);
+			return -EINVAL;
+		}
+	}
+
+	*replaced |= drm_property_replace_blob(blob, new_blob);
+	drm_property_blob_put(new_blob);
+
+	return 0;
+}
+
+static int
+amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
+				   struct drm_crtc_state *state,
+				   struct drm_property *property,
+				   uint64_t val)
+{
+	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
+	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
+	bool replaced = false;
+	int ret;
+
+	if (property == adev->mode_info.shaper_lut_property) {
+		ret = atomic_replace_property_blob_from_id(crtc->dev,
+					&acrtc_state->shaper_lut,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		acrtc_state->base.color_mgmt_changed |= replaced;
+		return ret;
+	} else {
+		drm_dbg_atomic(crtc->dev,
+			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
+			       crtc->base.id, crtc->name,
+			       property->base.id, property->name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
+				   const struct drm_crtc_state *state,
+				   struct drm_property *property,
+				   uint64_t *val)
+{
+	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
+	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
+
+	if (property == adev->mode_info.shaper_lut_property)
+		*val = (acrtc_state->shaper_lut) ?
+			acrtc_state->shaper_lut->base.id : 0;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+#endif
+
 /* Implemented only the options currently available for the driver */
 static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
 	.reset = dm_crtc_reset_state,
@@ -317,6 +429,10 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
 #if defined(CONFIG_DEBUG_FS)
 	.late_register = amdgpu_dm_crtc_late_register,
 #endif
+#ifdef CONFIG_STEAM_DECK
+	.atomic_set_property = amdgpu_dm_atomic_crtc_set_property,
+	.atomic_get_property = amdgpu_dm_atomic_crtc_get_property,
+#endif
 };
 
 static void dm_crtc_helper_disable(struct drm_crtc *crtc)
@@ -477,9 +593,11 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
 	is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch;
 	drm_crtc_enable_color_mgmt(&acrtc->base, is_dcn ? MAX_COLOR_LUT_ENTRIES : 0,
 				   true, MAX_COLOR_LUT_ENTRIES);
-
 	drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES);
 
+#ifdef CONFIG_STEAM_DECK
+	dm_crtc_additional_color_mgmt(&acrtc->base);
+#endif
 	return 0;
 
 fail:
-- 
2.39.2


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

* [RFC PATCH 05/40] drm/amd/display: add shaper LUT driver-private props
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

CRTC shaper LUT shapes the content after blending, i.e., de-linearizes
or normalizes space before applying a 3D LUT color correction. In the
next patch, we add CRTC 3D LUT property to DRM color management after
this shaper LUT and before the current CRTC gamma LUT.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  28 ++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  14 ++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  17 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 122 +++++++++++++++++-
 4 files changed, 179 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 8632ab695a6c..44c22cb87dde 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1247,6 +1247,30 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
 	return &amdgpu_fb->base;
 }
 
+#ifdef CONFIG_STEAM_DECK
+static int
+amdgpu_display_create_color_properties(struct amdgpu_device *adev)
+{
+	struct drm_property *prop;
+
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_SHAPER_LUT", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.shaper_lut_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_SHAPER_LUT_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.shaper_lut_size_property = prop;
+
+	return 0;
+}
+#endif
+
 const struct drm_mode_config_funcs amdgpu_mode_funcs = {
 	.fb_create = amdgpu_display_user_framebuffer_create,
 };
@@ -1323,6 +1347,10 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
 			return -ENOMEM;
 	}
 
+#ifdef CONFIG_STEAM_DECK
+	if (amdgpu_display_create_color_properties(adev))
+		return -ENOMEM;
+#endif
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index b8633df418d4..1fd3497af3b5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -344,6 +344,20 @@ struct amdgpu_mode_info {
 	int			disp_priority;
 	const struct amdgpu_display_funcs *funcs;
 	const enum drm_plane_type *plane_type;
+
+	/* Driver-private color mgmt props */
+#ifdef CONFIG_STEAM_DECK
+	/**
+	 * @shaper_lut_property: CRTC property to set post-blending shaper LUT
+	 * that converts content before 3D LUT gamma correction.
+	 */
+	struct drm_property *shaper_lut_property;
+	/**
+	 * @shaper_lut_size_property: CRTC property for the size of
+	 * post-blending shaper LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *shaper_lut_size_property;
+#endif
 };
 
 #define AMDGPU_MAX_BL_LEVEL 0xFF
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 2e2413fd73a4..de63455896cc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -726,6 +726,23 @@ struct dm_crtc_state {
 	struct dc_info_packet vrr_infopacket;
 
 	int abm_level;
+
+#ifdef CONFIG_STEAM_DECK
+	/* AMD driver-private color mgmt pipeline
+	 *
+	 * DRM provides CRTC degamma/ctm/gamma color mgmt features, but AMD HW
+	 * has a larger set of post-blending color calibration features, as
+	 * below:
+	 */
+	/**
+	 * @shaper_lut:
+	 *
+	 * Lookup table used to de-linearize pixel data for gamma correction.
+	 * See drm_crtc_enable_color_mgmt(). The blob (if not NULL) is an array
+	 * of &struct drm_color_lut.
+	 */
+	struct drm_property_blob *shaper_lut;
+#endif
 };
 
 #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index e3762e806617..503433e5cb38 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -229,7 +229,9 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
 	if (cur->stream)
 		dc_stream_release(cur->stream);
 
-
+#ifdef CONFIG_STEAM_DECK
+	drm_property_blob_put(cur->shaper_lut);
+#endif
 	__drm_atomic_helper_crtc_destroy_state(state);
 
 
@@ -266,7 +268,12 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
 	state->crc_skip_count = cur->crc_skip_count;
 	state->mpo_requested = cur->mpo_requested;
 	/* TODO Duplicate dc_stream after objects are stream object is flattened */
+#ifdef CONFIG_STEAM_DECK
+	state->shaper_lut = cur->shaper_lut;
 
+	if (state->shaper_lut)
+		drm_property_blob_get(state->shaper_lut);
+#endif
 	return &state->base;
 }
 
@@ -299,6 +306,111 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc)
 }
 #endif
 
+#ifdef CONFIG_STEAM_DECK
+/**
+ * drm_crtc_additional_color_mgmt - enable additional color properties
+ * @crtc: DRM CRTC
+ *
+ * This function lets the driver enable the 3D LUT color correction property
+ * on a CRTC. This includes shaper LUT, 3D LUT and regamma TF. The shaper
+ * LUT and 3D LUT property is only attached if its size is not 0.
+ */
+static void
+dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
+{
+	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
+
+	if (adev->dm.dc->caps.color.mpc.num_3dluts) {
+		drm_object_attach_property(&crtc->base,
+					   adev->mode_info.shaper_lut_property, 0);
+		drm_object_attach_property(&crtc->base,
+					   adev->mode_info.shaper_lut_size_property,
+					   MAX_COLOR_LUT_ENTRIES);
+	}
+}
+
+static int
+atomic_replace_property_blob_from_id(struct drm_device *dev,
+					 struct drm_property_blob **blob,
+					 uint64_t blob_id,
+					 ssize_t expected_size,
+					 ssize_t expected_elem_size,
+					 bool *replaced)
+{
+	struct drm_property_blob *new_blob = NULL;
+
+	if (blob_id != 0) {
+		new_blob = drm_property_lookup_blob(dev, blob_id);
+		if (new_blob == NULL)
+			return -EINVAL;
+
+		if (expected_size > 0 &&
+		    new_blob->length != expected_size) {
+			drm_property_blob_put(new_blob);
+			return -EINVAL;
+		}
+		if (expected_elem_size > 0 &&
+		    new_blob->length % expected_elem_size != 0) {
+			drm_property_blob_put(new_blob);
+			return -EINVAL;
+		}
+	}
+
+	*replaced |= drm_property_replace_blob(blob, new_blob);
+	drm_property_blob_put(new_blob);
+
+	return 0;
+}
+
+static int
+amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
+				   struct drm_crtc_state *state,
+				   struct drm_property *property,
+				   uint64_t val)
+{
+	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
+	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
+	bool replaced = false;
+	int ret;
+
+	if (property == adev->mode_info.shaper_lut_property) {
+		ret = atomic_replace_property_blob_from_id(crtc->dev,
+					&acrtc_state->shaper_lut,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		acrtc_state->base.color_mgmt_changed |= replaced;
+		return ret;
+	} else {
+		drm_dbg_atomic(crtc->dev,
+			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
+			       crtc->base.id, crtc->name,
+			       property->base.id, property->name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
+				   const struct drm_crtc_state *state,
+				   struct drm_property *property,
+				   uint64_t *val)
+{
+	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
+	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
+
+	if (property == adev->mode_info.shaper_lut_property)
+		*val = (acrtc_state->shaper_lut) ?
+			acrtc_state->shaper_lut->base.id : 0;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+#endif
+
 /* Implemented only the options currently available for the driver */
 static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
 	.reset = dm_crtc_reset_state,
@@ -317,6 +429,10 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
 #if defined(CONFIG_DEBUG_FS)
 	.late_register = amdgpu_dm_crtc_late_register,
 #endif
+#ifdef CONFIG_STEAM_DECK
+	.atomic_set_property = amdgpu_dm_atomic_crtc_set_property,
+	.atomic_get_property = amdgpu_dm_atomic_crtc_get_property,
+#endif
 };
 
 static void dm_crtc_helper_disable(struct drm_crtc *crtc)
@@ -477,9 +593,11 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
 	is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch;
 	drm_crtc_enable_color_mgmt(&acrtc->base, is_dcn ? MAX_COLOR_LUT_ENTRIES : 0,
 				   true, MAX_COLOR_LUT_ENTRIES);
-
 	drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES);
 
+#ifdef CONFIG_STEAM_DECK
+	dm_crtc_additional_color_mgmt(&acrtc->base);
+#endif
 	return 0;
 
 fail:
-- 
2.39.2


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

* [RFC PATCH 06/40] drm/amd/display: add 3D LUT driver-private props
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

Add CRTC 3D LUT for gamma correction using a 3D lookup table. A shaper
lut must be set to shape the content for a non-linear space. That
details should be handled by the driver according to HW color
capabilities.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 +++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      | 11 ++++++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 13 ++++++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 20 +++++++++++++++++++
 4 files changed, 58 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 44c22cb87dde..2abe5fe87c10 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1267,6 +1267,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.shaper_lut_size_property = prop;
 
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_LUT3D", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.lut3d_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_LUT3D_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.lut3d_size_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 1fd3497af3b5..205fa4f5bea7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -357,6 +357,17 @@ struct amdgpu_mode_info {
 	 * post-blending shaper LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *shaper_lut_size_property;
+	/**
+	 * lut3d_property: CRTC property to set post-blending 3D LUT gamma
+	 * correction; a shaper LUT can be used before applying 3D LUT to
+	 * delinearize content.
+	 */
+	struct drm_property *lut3d_property;
+	/**
+	 * @lut3d_size_property: CRTC property for the size of post-blending 3D
+	 * LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *lut3d_size_property;
 #endif
 };
 
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 de63455896cc..09c3e1858b56 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -742,6 +742,15 @@ struct dm_crtc_state {
 	 * of &struct drm_color_lut.
 	 */
 	struct drm_property_blob *shaper_lut;
+	/**
+	 * @lut3d:
+	 *
+	 * 3D Lookup table for converting pixel data. Position where it takes
+	 * place depends on hw design, after @ctm or @gamma_lut. See
+	 * drm_crtc_enable_color_mgmt(). The blob (if not NULL) is an array of
+	 * &struct drm_color_lut.
+	 */
+	struct drm_property_blob *lut3d;
 #endif
 };
 
@@ -804,6 +813,10 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
 
 void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
+/* 3D LUT max size is 17x17x17 */
+#define MAX_COLOR_3DLUT_ENTRIES 4913
+#define MAX_COLOR_3DLUT_BITDEPTH 12
+/* 1D LUT degamma, regamma and shaper*/
 #define MAX_COLOR_LUT_ENTRIES 4096
 /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
 #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 503433e5cb38..0e1280228e6e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -231,6 +231,7 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
 
 #ifdef CONFIG_STEAM_DECK
 	drm_property_blob_put(cur->shaper_lut);
+	drm_property_blob_put(cur->lut3d);
 #endif
 	__drm_atomic_helper_crtc_destroy_state(state);
 
@@ -270,9 +271,12 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
 	/* TODO Duplicate dc_stream after objects are stream object is flattened */
 #ifdef CONFIG_STEAM_DECK
 	state->shaper_lut = cur->shaper_lut;
+	state->lut3d = cur->lut3d;
 
 	if (state->shaper_lut)
 		drm_property_blob_get(state->shaper_lut);
+	if (state->lut3d)
+		drm_property_blob_get(state->lut3d);
 #endif
 	return &state->base;
 }
@@ -326,6 +330,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
 		drm_object_attach_property(&crtc->base,
 					   adev->mode_info.shaper_lut_size_property,
 					   MAX_COLOR_LUT_ENTRIES);
+		drm_object_attach_property(&crtc->base,
+					   adev->mode_info.lut3d_property, 0);
+		drm_object_attach_property(&crtc->base,
+					   adev->mode_info.lut3d_size_property,
+					   MAX_COLOR_3DLUT_ENTRIES);
 	}
 }
 
@@ -381,6 +390,14 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
 					&replaced);
 		acrtc_state->base.color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == adev->mode_info.lut3d_property) {
+		ret = atomic_replace_property_blob_from_id(crtc->dev,
+					&acrtc_state->lut3d,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		acrtc_state->base.color_mgmt_changed |= replaced;
+		return ret;
 	} else {
 		drm_dbg_atomic(crtc->dev,
 			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -404,6 +421,9 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
 	if (property == adev->mode_info.shaper_lut_property)
 		*val = (acrtc_state->shaper_lut) ?
 			acrtc_state->shaper_lut->base.id : 0;
+	else if (property == adev->mode_info.lut3d_property)
+		*val = (acrtc_state->lut3d) ?
+			acrtc_state->lut3d->base.id : 0;
 	else
 		return -EINVAL;
 
-- 
2.39.2


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

* [RFC PATCH 06/40] drm/amd/display: add 3D LUT driver-private props
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

Add CRTC 3D LUT for gamma correction using a 3D lookup table. A shaper
lut must be set to shape the content for a non-linear space. That
details should be handled by the driver according to HW color
capabilities.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 +++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      | 11 ++++++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 13 ++++++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 20 +++++++++++++++++++
 4 files changed, 58 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 44c22cb87dde..2abe5fe87c10 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1267,6 +1267,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.shaper_lut_size_property = prop;
 
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_LUT3D", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.lut3d_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_LUT3D_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.lut3d_size_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 1fd3497af3b5..205fa4f5bea7 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -357,6 +357,17 @@ struct amdgpu_mode_info {
 	 * post-blending shaper LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *shaper_lut_size_property;
+	/**
+	 * lut3d_property: CRTC property to set post-blending 3D LUT gamma
+	 * correction; a shaper LUT can be used before applying 3D LUT to
+	 * delinearize content.
+	 */
+	struct drm_property *lut3d_property;
+	/**
+	 * @lut3d_size_property: CRTC property for the size of post-blending 3D
+	 * LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *lut3d_size_property;
 #endif
 };
 
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 de63455896cc..09c3e1858b56 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -742,6 +742,15 @@ struct dm_crtc_state {
 	 * of &struct drm_color_lut.
 	 */
 	struct drm_property_blob *shaper_lut;
+	/**
+	 * @lut3d:
+	 *
+	 * 3D Lookup table for converting pixel data. Position where it takes
+	 * place depends on hw design, after @ctm or @gamma_lut. See
+	 * drm_crtc_enable_color_mgmt(). The blob (if not NULL) is an array of
+	 * &struct drm_color_lut.
+	 */
+	struct drm_property_blob *lut3d;
 #endif
 };
 
@@ -804,6 +813,10 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
 
 void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
+/* 3D LUT max size is 17x17x17 */
+#define MAX_COLOR_3DLUT_ENTRIES 4913
+#define MAX_COLOR_3DLUT_BITDEPTH 12
+/* 1D LUT degamma, regamma and shaper*/
 #define MAX_COLOR_LUT_ENTRIES 4096
 /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
 #define MAX_COLOR_LEGACY_LUT_ENTRIES 256
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 503433e5cb38..0e1280228e6e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -231,6 +231,7 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
 
 #ifdef CONFIG_STEAM_DECK
 	drm_property_blob_put(cur->shaper_lut);
+	drm_property_blob_put(cur->lut3d);
 #endif
 	__drm_atomic_helper_crtc_destroy_state(state);
 
@@ -270,9 +271,12 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
 	/* TODO Duplicate dc_stream after objects are stream object is flattened */
 #ifdef CONFIG_STEAM_DECK
 	state->shaper_lut = cur->shaper_lut;
+	state->lut3d = cur->lut3d;
 
 	if (state->shaper_lut)
 		drm_property_blob_get(state->shaper_lut);
+	if (state->lut3d)
+		drm_property_blob_get(state->lut3d);
 #endif
 	return &state->base;
 }
@@ -326,6 +330,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
 		drm_object_attach_property(&crtc->base,
 					   adev->mode_info.shaper_lut_size_property,
 					   MAX_COLOR_LUT_ENTRIES);
+		drm_object_attach_property(&crtc->base,
+					   adev->mode_info.lut3d_property, 0);
+		drm_object_attach_property(&crtc->base,
+					   adev->mode_info.lut3d_size_property,
+					   MAX_COLOR_3DLUT_ENTRIES);
 	}
 }
 
@@ -381,6 +390,14 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
 					&replaced);
 		acrtc_state->base.color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == adev->mode_info.lut3d_property) {
+		ret = atomic_replace_property_blob_from_id(crtc->dev,
+					&acrtc_state->lut3d,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		acrtc_state->base.color_mgmt_changed |= replaced;
+		return ret;
 	} else {
 		drm_dbg_atomic(crtc->dev,
 			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -404,6 +421,9 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
 	if (property == adev->mode_info.shaper_lut_property)
 		*val = (acrtc_state->shaper_lut) ?
 			acrtc_state->shaper_lut->base.id : 0;
+	else if (property == adev->mode_info.lut3d_property)
+		*val = (acrtc_state->lut3d) ?
+			acrtc_state->lut3d->base.id : 0;
 	else
 		return -EINVAL;
 
-- 
2.39.2


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

* [RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to driver-private props
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

From: Joshua Ashton <joshua@froggi.es>

Add predefined transfer function property to DRM CRTC gamma to convert
to wire encoding with or without gamma LUT.

Co-developed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 22 ++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 ++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 23 +++++++++++++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 13 +++++++++++
 4 files changed, 62 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 2abe5fe87c10..1913903cab88 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1248,6 +1248,19 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
 }
 
 #ifdef CONFIG_STEAM_DECK
+static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
+	{ DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
+	{ DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
+	{ DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
+	{ DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
+	{ DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
+	{ DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
+	{ DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
+};
+
 static int
 amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 {
@@ -1281,6 +1294,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.lut3d_size_property = prop;
 
+	prop = drm_property_create_enum(adev_to_drm(adev),
+					DRM_MODE_PROP_ENUM,
+					"GAMMA_TF",
+					drm_transfer_function_enum_list,
+					ARRAY_SIZE(drm_transfer_function_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.gamma_tf_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 205fa4f5bea7..76337e18c728 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -368,6 +368,10 @@ struct amdgpu_mode_info {
 	 * LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *lut3d_size_property;
+	/**
+	 * @gamma_tf_property: Transfer function for CRTC regamma.
+	 */
+	struct drm_property *gamma_tf_property;
 #endif
 };
 
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 09c3e1858b56..1e90a2dd445e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -699,6 +699,23 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
 
 extern const struct amdgpu_ip_block_version dm_ip_block;
 
+#ifdef CONFIG_STEAM_DECK
+enum drm_transfer_function {
+	DRM_TRANSFER_FUNCTION_DEFAULT,
+
+	DRM_TRANSFER_FUNCTION_SRGB,
+	DRM_TRANSFER_FUNCTION_BT709,
+	DRM_TRANSFER_FUNCTION_PQ,
+	DRM_TRANSFER_FUNCTION_LINEAR,
+	DRM_TRANSFER_FUNCTION_UNITY,
+	DRM_TRANSFER_FUNCTION_HLG,
+	DRM_TRANSFER_FUNCTION_GAMMA22,
+	DRM_TRANSFER_FUNCTION_GAMMA24,
+	DRM_TRANSFER_FUNCTION_GAMMA26,
+	DRM_TRANSFER_FUNCTION_MAX,
+};
+#endif
+
 struct dm_plane_state {
 	struct drm_plane_state base;
 	struct dc_plane_state *dc_state;
@@ -751,6 +768,12 @@ struct dm_crtc_state {
 	 * &struct drm_color_lut.
 	 */
 	struct drm_property_blob *lut3d;
+        /**
+	 * @gamma_tf:
+	 *
+	 * Pre-defined transfer function for converting internal FB -> wire encoding.
+	 */
+	enum drm_transfer_function gamma_tf;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 0e1280228e6e..79324fbab1f1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -272,6 +272,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
 #ifdef CONFIG_STEAM_DECK
 	state->shaper_lut = cur->shaper_lut;
 	state->lut3d = cur->lut3d;
+	state->gamma_tf = cur->gamma_tf;
 
 	if (state->shaper_lut)
 		drm_property_blob_get(state->shaper_lut);
@@ -336,6 +337,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
 					   adev->mode_info.lut3d_size_property,
 					   MAX_COLOR_3DLUT_ENTRIES);
 	}
+
+	if(adev->dm.dc->caps.color.mpc.ogam_ram)
+		drm_object_attach_property(&crtc->base,
+					   adev->mode_info.gamma_tf_property,
+					   DRM_TRANSFER_FUNCTION_DEFAULT);
 }
 
 static int
@@ -398,6 +404,11 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
 					&replaced);
 		acrtc_state->base.color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == adev->mode_info.gamma_tf_property) {
+		if (acrtc_state->gamma_tf != val) {
+			acrtc_state->gamma_tf = val;
+			acrtc_state->base.color_mgmt_changed |= 1;
+		}
 	} else {
 		drm_dbg_atomic(crtc->dev,
 			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -424,6 +435,8 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
 	else if (property == adev->mode_info.lut3d_property)
 		*val = (acrtc_state->lut3d) ?
 			acrtc_state->lut3d->base.id : 0;
+	else if (property == adev->mode_info.gamma_tf_property)
+		*val = acrtc_state->gamma_tf;
 	else
 		return -EINVAL;
 
-- 
2.39.2


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

* [RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to driver-private props
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

Add predefined transfer function property to DRM CRTC gamma to convert
to wire encoding with or without gamma LUT.

Co-developed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 22 ++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 ++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 23 +++++++++++++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 13 +++++++++++
 4 files changed, 62 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 2abe5fe87c10..1913903cab88 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1248,6 +1248,19 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
 }
 
 #ifdef CONFIG_STEAM_DECK
+static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
+	{ DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
+	{ DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
+	{ DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
+	{ DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
+	{ DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
+	{ DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
+	{ DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
+};
+
 static int
 amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 {
@@ -1281,6 +1294,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.lut3d_size_property = prop;
 
+	prop = drm_property_create_enum(adev_to_drm(adev),
+					DRM_MODE_PROP_ENUM,
+					"GAMMA_TF",
+					drm_transfer_function_enum_list,
+					ARRAY_SIZE(drm_transfer_function_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.gamma_tf_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 205fa4f5bea7..76337e18c728 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -368,6 +368,10 @@ struct amdgpu_mode_info {
 	 * LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *lut3d_size_property;
+	/**
+	 * @gamma_tf_property: Transfer function for CRTC regamma.
+	 */
+	struct drm_property *gamma_tf_property;
 #endif
 };
 
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 09c3e1858b56..1e90a2dd445e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -699,6 +699,23 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
 
 extern const struct amdgpu_ip_block_version dm_ip_block;
 
+#ifdef CONFIG_STEAM_DECK
+enum drm_transfer_function {
+	DRM_TRANSFER_FUNCTION_DEFAULT,
+
+	DRM_TRANSFER_FUNCTION_SRGB,
+	DRM_TRANSFER_FUNCTION_BT709,
+	DRM_TRANSFER_FUNCTION_PQ,
+	DRM_TRANSFER_FUNCTION_LINEAR,
+	DRM_TRANSFER_FUNCTION_UNITY,
+	DRM_TRANSFER_FUNCTION_HLG,
+	DRM_TRANSFER_FUNCTION_GAMMA22,
+	DRM_TRANSFER_FUNCTION_GAMMA24,
+	DRM_TRANSFER_FUNCTION_GAMMA26,
+	DRM_TRANSFER_FUNCTION_MAX,
+};
+#endif
+
 struct dm_plane_state {
 	struct drm_plane_state base;
 	struct dc_plane_state *dc_state;
@@ -751,6 +768,12 @@ struct dm_crtc_state {
 	 * &struct drm_color_lut.
 	 */
 	struct drm_property_blob *lut3d;
+        /**
+	 * @gamma_tf:
+	 *
+	 * Pre-defined transfer function for converting internal FB -> wire encoding.
+	 */
+	enum drm_transfer_function gamma_tf;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 0e1280228e6e..79324fbab1f1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -272,6 +272,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
 #ifdef CONFIG_STEAM_DECK
 	state->shaper_lut = cur->shaper_lut;
 	state->lut3d = cur->lut3d;
+	state->gamma_tf = cur->gamma_tf;
 
 	if (state->shaper_lut)
 		drm_property_blob_get(state->shaper_lut);
@@ -336,6 +337,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
 					   adev->mode_info.lut3d_size_property,
 					   MAX_COLOR_3DLUT_ENTRIES);
 	}
+
+	if(adev->dm.dc->caps.color.mpc.ogam_ram)
+		drm_object_attach_property(&crtc->base,
+					   adev->mode_info.gamma_tf_property,
+					   DRM_TRANSFER_FUNCTION_DEFAULT);
 }
 
 static int
@@ -398,6 +404,11 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
 					&replaced);
 		acrtc_state->base.color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == adev->mode_info.gamma_tf_property) {
+		if (acrtc_state->gamma_tf != val) {
+			acrtc_state->gamma_tf = val;
+			acrtc_state->base.color_mgmt_changed |= 1;
+		}
 	} else {
 		drm_dbg_atomic(crtc->dev,
 			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -424,6 +435,8 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
 	else if (property == adev->mode_info.lut3d_property)
 		*val = (acrtc_state->lut3d) ?
 			acrtc_state->lut3d->base.id : 0;
+	else if (property == adev->mode_info.gamma_tf_property)
+		*val = acrtc_state->gamma_tf;
 	else
 		return -EINVAL;
 
-- 
2.39.2


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

* [RFC PATCH 08/40] drm/drm_plane: track color mgmt changes per plane
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, maarten.lankhorst, mripard, tzimmermann,
	airlied, daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

We will add color mgmt properties to DRM planes in the text patches and
we want to track when one of this properties change to define atomic
commit behaviors. Using a similar approach from CRTC color props, we set
a color_mgmt_changed boolean whenever a plane color prop changes.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/drm_atomic.c              | 1 +
 drivers/gpu/drm/drm_atomic_state_helper.c | 1 +
 include/drm/drm_plane.h                   | 7 +++++++
 3 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c0dc5858a723..da2429470c4f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -724,6 +724,7 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
 		   drm_get_color_encoding_name(state->color_encoding));
 	drm_printf(p, "\tcolor-range=%s\n",
 		   drm_get_color_range_name(state->color_range));
+	drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
 
 	if (plane->funcs->atomic_print_state)
 		plane->funcs->atomic_print_state(p, state);
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index dfb57217253b..3df4c96a902e 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -338,6 +338,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
 	state->fence = NULL;
 	state->commit = NULL;
 	state->fb_damage_clips = NULL;
+	state->color_mgmt_changed = false;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
 
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 447e664e49d5..6c97380b8c76 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -237,6 +237,13 @@ struct drm_plane_state {
 
 	/** @state: backpointer to global drm_atomic_state */
 	struct drm_atomic_state *state;
+
+	/**
+	 * @color_mgmt_changed: Color management properties have changed. Used
+	 * by the atomic helpers and drivers to steer the atomic commit control
+	 * flow.
+	 */
+	bool color_mgmt_changed : 1;
 };
 
 static inline struct drm_rect
-- 
2.39.2


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

* [RFC PATCH 08/40] drm/drm_plane: track color mgmt changes per plane
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, maarten.lankhorst, mripard, tzimmermann,
	airlied, daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

We will add color mgmt properties to DRM planes in the text patches and
we want to track when one of this properties change to define atomic
commit behaviors. Using a similar approach from CRTC color props, we set
a color_mgmt_changed boolean whenever a plane color prop changes.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/drm_atomic.c              | 1 +
 drivers/gpu/drm/drm_atomic_state_helper.c | 1 +
 include/drm/drm_plane.h                   | 7 +++++++
 3 files changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c0dc5858a723..da2429470c4f 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -724,6 +724,7 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
 		   drm_get_color_encoding_name(state->color_encoding));
 	drm_printf(p, "\tcolor-range=%s\n",
 		   drm_get_color_range_name(state->color_range));
+	drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
 
 	if (plane->funcs->atomic_print_state)
 		plane->funcs->atomic_print_state(p, state);
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index dfb57217253b..3df4c96a902e 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -338,6 +338,7 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
 	state->fence = NULL;
 	state->commit = NULL;
 	state->fb_damage_clips = NULL;
+	state->color_mgmt_changed = false;
 }
 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
 
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 447e664e49d5..6c97380b8c76 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -237,6 +237,13 @@ struct drm_plane_state {
 
 	/** @state: backpointer to global drm_atomic_state */
 	struct drm_atomic_state *state;
+
+	/**
+	 * @color_mgmt_changed: Color management properties have changed. Used
+	 * by the atomic helpers and drivers to steer the atomic commit control
+	 * flow.
+	 */
+	bool color_mgmt_changed : 1;
 };
 
 static inline struct drm_rect
-- 
2.39.2


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

* [RFC PATCH 09/40] drm/amd/display: move replace blob func to dm plane
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

From amdgpu_dm_plane we can get it for both CRTC and plane color
properties. We are adding new plane properties for AMD driver-private
color mgmt.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 37 +------------------
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 35 ++++++++++++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |  7 ++++
 3 files changed, 44 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 79324fbab1f1..27d7a8b18013 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -344,39 +344,6 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
 					   DRM_TRANSFER_FUNCTION_DEFAULT);
 }
 
-static int
-atomic_replace_property_blob_from_id(struct drm_device *dev,
-					 struct drm_property_blob **blob,
-					 uint64_t blob_id,
-					 ssize_t expected_size,
-					 ssize_t expected_elem_size,
-					 bool *replaced)
-{
-	struct drm_property_blob *new_blob = NULL;
-
-	if (blob_id != 0) {
-		new_blob = drm_property_lookup_blob(dev, blob_id);
-		if (new_blob == NULL)
-			return -EINVAL;
-
-		if (expected_size > 0 &&
-		    new_blob->length != expected_size) {
-			drm_property_blob_put(new_blob);
-			return -EINVAL;
-		}
-		if (expected_elem_size > 0 &&
-		    new_blob->length % expected_elem_size != 0) {
-			drm_property_blob_put(new_blob);
-			return -EINVAL;
-		}
-	}
-
-	*replaced |= drm_property_replace_blob(blob, new_blob);
-	drm_property_blob_put(new_blob);
-
-	return 0;
-}
-
 static int
 amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
 				   struct drm_crtc_state *state,
@@ -389,7 +356,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
 	int ret;
 
 	if (property == adev->mode_info.shaper_lut_property) {
-		ret = atomic_replace_property_blob_from_id(crtc->dev,
+		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
 					&acrtc_state->shaper_lut,
 					val,
 					-1, sizeof(struct drm_color_lut),
@@ -397,7 +364,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
 		acrtc_state->base.color_mgmt_changed |= replaced;
 		return ret;
 	} else if (property == adev->mode_info.lut3d_property) {
-		ret = atomic_replace_property_blob_from_id(crtc->dev,
+		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
 					&acrtc_state->lut3d,
 					val,
 					-1, sizeof(struct drm_color_lut),
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 322668973747..4e5498153be2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1411,6 +1411,41 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 	drm_atomic_helper_plane_destroy_state(plane, state);
 }
 
+#ifdef CONFIG_STEAM_DECK
+int
+amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
+					       struct drm_property_blob **blob,
+					       uint64_t blob_id,
+					       ssize_t expected_size,
+					       ssize_t expected_elem_size,
+					       bool *replaced)
+{
+	struct drm_property_blob *new_blob = NULL;
+
+	if (blob_id != 0) {
+		new_blob = drm_property_lookup_blob(dev, blob_id);
+		if (new_blob == NULL)
+			return -EINVAL;
+
+		if (expected_size > 0 &&
+		    new_blob->length != expected_size) {
+			drm_property_blob_put(new_blob);
+			return -EINVAL;
+		}
+		if (expected_elem_size > 0 &&
+		    new_blob->length % expected_elem_size != 0) {
+			drm_property_blob_put(new_blob);
+			return -EINVAL;
+		}
+	}
+
+	*replaced |= drm_property_replace_blob(blob, new_blob);
+	drm_property_blob_put(new_blob);
+
+	return 0;
+}
+#endif
+
 static const struct drm_plane_funcs dm_plane_funcs = {
 	.update_plane	= drm_atomic_helper_update_plane,
 	.disable_plane	= drm_atomic_helper_disable_plane,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
index 930f1572f898..1b05ac4c15f6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
@@ -51,6 +51,13 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev,
 				 bool tmz_surface,
 				 bool force_disable_dcc);
 
+int amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
+					    struct drm_property_blob **blob,
+					    uint64_t blob_id,
+					    ssize_t expected_size,
+					    ssize_t expected_elem_size,
+					    bool *replaced);
+
 int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
 			 struct drm_plane *plane,
 			 unsigned long possible_crtcs,
-- 
2.39.2


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

* [RFC PATCH 09/40] drm/amd/display: move replace blob func to dm plane
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

From amdgpu_dm_plane we can get it for both CRTC and plane color
properties. We are adding new plane properties for AMD driver-private
color mgmt.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 37 +------------------
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 35 ++++++++++++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |  7 ++++
 3 files changed, 44 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 79324fbab1f1..27d7a8b18013 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -344,39 +344,6 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
 					   DRM_TRANSFER_FUNCTION_DEFAULT);
 }
 
-static int
-atomic_replace_property_blob_from_id(struct drm_device *dev,
-					 struct drm_property_blob **blob,
-					 uint64_t blob_id,
-					 ssize_t expected_size,
-					 ssize_t expected_elem_size,
-					 bool *replaced)
-{
-	struct drm_property_blob *new_blob = NULL;
-
-	if (blob_id != 0) {
-		new_blob = drm_property_lookup_blob(dev, blob_id);
-		if (new_blob == NULL)
-			return -EINVAL;
-
-		if (expected_size > 0 &&
-		    new_blob->length != expected_size) {
-			drm_property_blob_put(new_blob);
-			return -EINVAL;
-		}
-		if (expected_elem_size > 0 &&
-		    new_blob->length % expected_elem_size != 0) {
-			drm_property_blob_put(new_blob);
-			return -EINVAL;
-		}
-	}
-
-	*replaced |= drm_property_replace_blob(blob, new_blob);
-	drm_property_blob_put(new_blob);
-
-	return 0;
-}
-
 static int
 amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
 				   struct drm_crtc_state *state,
@@ -389,7 +356,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
 	int ret;
 
 	if (property == adev->mode_info.shaper_lut_property) {
-		ret = atomic_replace_property_blob_from_id(crtc->dev,
+		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
 					&acrtc_state->shaper_lut,
 					val,
 					-1, sizeof(struct drm_color_lut),
@@ -397,7 +364,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
 		acrtc_state->base.color_mgmt_changed |= replaced;
 		return ret;
 	} else if (property == adev->mode_info.lut3d_property) {
-		ret = atomic_replace_property_blob_from_id(crtc->dev,
+		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
 					&acrtc_state->lut3d,
 					val,
 					-1, sizeof(struct drm_color_lut),
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 322668973747..4e5498153be2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1411,6 +1411,41 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 	drm_atomic_helper_plane_destroy_state(plane, state);
 }
 
+#ifdef CONFIG_STEAM_DECK
+int
+amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
+					       struct drm_property_blob **blob,
+					       uint64_t blob_id,
+					       ssize_t expected_size,
+					       ssize_t expected_elem_size,
+					       bool *replaced)
+{
+	struct drm_property_blob *new_blob = NULL;
+
+	if (blob_id != 0) {
+		new_blob = drm_property_lookup_blob(dev, blob_id);
+		if (new_blob == NULL)
+			return -EINVAL;
+
+		if (expected_size > 0 &&
+		    new_blob->length != expected_size) {
+			drm_property_blob_put(new_blob);
+			return -EINVAL;
+		}
+		if (expected_elem_size > 0 &&
+		    new_blob->length % expected_elem_size != 0) {
+			drm_property_blob_put(new_blob);
+			return -EINVAL;
+		}
+	}
+
+	*replaced |= drm_property_replace_blob(blob, new_blob);
+	drm_property_blob_put(new_blob);
+
+	return 0;
+}
+#endif
+
 static const struct drm_plane_funcs dm_plane_funcs = {
 	.update_plane	= drm_atomic_helper_update_plane,
 	.disable_plane	= drm_atomic_helper_disable_plane,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
index 930f1572f898..1b05ac4c15f6 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
@@ -51,6 +51,13 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev,
 				 bool tmz_surface,
 				 bool force_disable_dcc);
 
+int amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
+					    struct drm_property_blob **blob,
+					    uint64_t blob_id,
+					    ssize_t expected_size,
+					    ssize_t expected_elem_size,
+					    bool *replaced);
+
 int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
 			 struct drm_plane *plane,
 			 unsigned long possible_crtcs,
-- 
2.39.2


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

* [RFC PATCH 10/40] drm/amd/display: add plane degamma LUT driver-private props
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

Create driver-private properties (not DRM KMS generic) for plane degamma
LUT (user-blob and its size).

Co-developed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 ++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      | 10 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 11 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 78 ++++++++++++++++++-
 4 files changed, 111 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 1913903cab88..996c9c3fd471 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1303,6 +1303,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.gamma_tf_property = prop;
 
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_PLANE_DEGAMMA_LUT", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_degamma_lut_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_PLANE_DEGAMMA_LUT_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_degamma_lut_size_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 76337e18c728..d4e609a8b67e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -372,6 +372,16 @@ struct amdgpu_mode_info {
 	 * @gamma_tf_property: Transfer function for CRTC regamma.
 	 */
 	struct drm_property *gamma_tf_property;
+	/**
+	 * @plane_degamma_lut_property: Plane property to set a degamma LUT to
+	 * convert color space before blending.
+	 */
+	struct drm_property *plane_degamma_lut_property;
+	/**
+	 * @plane_degamma_lut_size_property: Plane property to define the max
+	 * size of degamma LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *plane_degamma_lut_size_property;
 #endif
 };
 
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 1e90a2dd445e..b1d0c65d821d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -719,6 +719,17 @@ enum drm_transfer_function {
 struct dm_plane_state {
 	struct drm_plane_state base;
 	struct dc_plane_state *dc_state;
+
+#ifdef CONFIG_STEAM_DECK
+	/* Plane color mgmt */
+	/**
+	 * @degamma_lut:
+	 *
+	 * LUT for converting plane pixel data before going into plane merger.
+	 * The blob (if not NULL) is an array of &struct drm_color_lut.
+	 */
+	struct drm_property_blob *degamma_lut;
+#endif
 };
 
 struct dm_crtc_state {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 4e5498153be2..7b9d62c70b30 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1337,7 +1337,10 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 		dm_plane_state->dc_state = old_dm_plane_state->dc_state;
 		dc_plane_state_retain(dm_plane_state->dc_state);
 	}
-
+#ifdef CONFIG_STEAM_DECK
+	if (dm_plane_state->degamma_lut)
+		drm_property_blob_get(dm_plane_state->degamma_lut);
+#endif
 	return &dm_plane_state->base;
 }
 
@@ -1404,7 +1407,9 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 				struct drm_plane_state *state)
 {
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
-
+#ifdef CONFIG_STEAM_DECK
+	drm_property_blob_put(dm_plane_state->degamma_lut);
+#endif
 	if (dm_plane_state->dc_state)
 		dc_plane_state_release(dm_plane_state->dc_state);
 
@@ -1444,6 +1449,68 @@ amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
 
 	return 0;
 }
+
+static void
+dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
+				      struct drm_plane *plane)
+{
+	if (dm->dc->caps.color.dpp.dgam_ram || dm->dc->caps.color.dpp.gamma_corr ) {
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_degamma_lut_property, 0);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_degamma_lut_size_property,
+					   MAX_COLOR_LUT_ENTRIES);
+	}
+}
+
+static int
+dm_atomic_plane_set_property(struct drm_plane *plane,
+			     struct drm_plane_state *state,
+			     struct drm_property *property, uint64_t val)
+{
+	struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
+	struct amdgpu_device *adev = drm_to_adev(plane->dev);
+	bool replaced = false;
+	int ret;
+
+	if (property == adev->mode_info.plane_degamma_lut_property) {
+		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
+					&dm_plane_state->degamma_lut,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		dm_plane_state->base.color_mgmt_changed |= replaced;
+		return ret;
+	} else {
+		drm_dbg_atomic(plane->dev,
+			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
+			       plane->base.id, plane->name,
+			       property->base.id, property->name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+dm_atomic_plane_get_property(struct drm_plane *plane,
+			     const struct drm_plane_state *state,
+			     struct drm_property *property,
+			     uint64_t *val)
+
+{
+	struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
+	struct amdgpu_device *adev = drm_to_adev(plane->dev);
+
+	if (property == adev->mode_info.plane_degamma_lut_property) {
+		*val = (dm_plane_state->degamma_lut) ?
+			dm_plane_state->degamma_lut->base.id : 0;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
 #endif
 
 static const struct drm_plane_funcs dm_plane_funcs = {
@@ -1454,6 +1521,10 @@ static const struct drm_plane_funcs dm_plane_funcs = {
 	.atomic_duplicate_state = dm_drm_plane_duplicate_state,
 	.atomic_destroy_state = dm_drm_plane_destroy_state,
 	.format_mod_supported = dm_plane_format_mod_supported,
+#ifdef CONFIG_STEAM_DECK
+	.atomic_set_property = dm_atomic_plane_set_property,
+	.atomic_get_property = dm_atomic_plane_get_property,
+#endif
 };
 
 int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
@@ -1524,6 +1595,9 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
 
 	drm_plane_helper_add(plane, &dm_plane_helper_funcs);
 
+#ifdef CONFIG_STEAM_DECK
+	dm_plane_attach_color_mgmt_properties(dm, plane);
+#endif
 	/* Create (reset) the plane state */
 	if (plane->funcs->reset)
 		plane->funcs->reset(plane);
-- 
2.39.2


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

* [RFC PATCH 10/40] drm/amd/display: add plane degamma LUT driver-private props
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

From: Joshua Ashton <joshua@froggi.es>

Create driver-private properties (not DRM KMS generic) for plane degamma
LUT (user-blob and its size).

Co-developed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 ++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      | 10 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 11 +++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 78 ++++++++++++++++++-
 4 files changed, 111 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 1913903cab88..996c9c3fd471 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1303,6 +1303,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.gamma_tf_property = prop;
 
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_PLANE_DEGAMMA_LUT", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_degamma_lut_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_PLANE_DEGAMMA_LUT_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_degamma_lut_size_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 76337e18c728..d4e609a8b67e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -372,6 +372,16 @@ struct amdgpu_mode_info {
 	 * @gamma_tf_property: Transfer function for CRTC regamma.
 	 */
 	struct drm_property *gamma_tf_property;
+	/**
+	 * @plane_degamma_lut_property: Plane property to set a degamma LUT to
+	 * convert color space before blending.
+	 */
+	struct drm_property *plane_degamma_lut_property;
+	/**
+	 * @plane_degamma_lut_size_property: Plane property to define the max
+	 * size of degamma LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *plane_degamma_lut_size_property;
 #endif
 };
 
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 1e90a2dd445e..b1d0c65d821d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -719,6 +719,17 @@ enum drm_transfer_function {
 struct dm_plane_state {
 	struct drm_plane_state base;
 	struct dc_plane_state *dc_state;
+
+#ifdef CONFIG_STEAM_DECK
+	/* Plane color mgmt */
+	/**
+	 * @degamma_lut:
+	 *
+	 * LUT for converting plane pixel data before going into plane merger.
+	 * The blob (if not NULL) is an array of &struct drm_color_lut.
+	 */
+	struct drm_property_blob *degamma_lut;
+#endif
 };
 
 struct dm_crtc_state {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 4e5498153be2..7b9d62c70b30 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1337,7 +1337,10 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 		dm_plane_state->dc_state = old_dm_plane_state->dc_state;
 		dc_plane_state_retain(dm_plane_state->dc_state);
 	}
-
+#ifdef CONFIG_STEAM_DECK
+	if (dm_plane_state->degamma_lut)
+		drm_property_blob_get(dm_plane_state->degamma_lut);
+#endif
 	return &dm_plane_state->base;
 }
 
@@ -1404,7 +1407,9 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 				struct drm_plane_state *state)
 {
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
-
+#ifdef CONFIG_STEAM_DECK
+	drm_property_blob_put(dm_plane_state->degamma_lut);
+#endif
 	if (dm_plane_state->dc_state)
 		dc_plane_state_release(dm_plane_state->dc_state);
 
@@ -1444,6 +1449,68 @@ amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
 
 	return 0;
 }
+
+static void
+dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
+				      struct drm_plane *plane)
+{
+	if (dm->dc->caps.color.dpp.dgam_ram || dm->dc->caps.color.dpp.gamma_corr ) {
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_degamma_lut_property, 0);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_degamma_lut_size_property,
+					   MAX_COLOR_LUT_ENTRIES);
+	}
+}
+
+static int
+dm_atomic_plane_set_property(struct drm_plane *plane,
+			     struct drm_plane_state *state,
+			     struct drm_property *property, uint64_t val)
+{
+	struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
+	struct amdgpu_device *adev = drm_to_adev(plane->dev);
+	bool replaced = false;
+	int ret;
+
+	if (property == adev->mode_info.plane_degamma_lut_property) {
+		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
+					&dm_plane_state->degamma_lut,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		dm_plane_state->base.color_mgmt_changed |= replaced;
+		return ret;
+	} else {
+		drm_dbg_atomic(plane->dev,
+			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
+			       plane->base.id, plane->name,
+			       property->base.id, property->name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int
+dm_atomic_plane_get_property(struct drm_plane *plane,
+			     const struct drm_plane_state *state,
+			     struct drm_property *property,
+			     uint64_t *val)
+
+{
+	struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
+	struct amdgpu_device *adev = drm_to_adev(plane->dev);
+
+	if (property == adev->mode_info.plane_degamma_lut_property) {
+		*val = (dm_plane_state->degamma_lut) ?
+			dm_plane_state->degamma_lut->base.id : 0;
+	} else {
+		return -EINVAL;
+	}
+
+	return 0;
+}
 #endif
 
 static const struct drm_plane_funcs dm_plane_funcs = {
@@ -1454,6 +1521,10 @@ static const struct drm_plane_funcs dm_plane_funcs = {
 	.atomic_duplicate_state = dm_drm_plane_duplicate_state,
 	.atomic_destroy_state = dm_drm_plane_destroy_state,
 	.format_mod_supported = dm_plane_format_mod_supported,
+#ifdef CONFIG_STEAM_DECK
+	.atomic_set_property = dm_atomic_plane_set_property,
+	.atomic_get_property = dm_atomic_plane_get_property,
+#endif
 };
 
 int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
@@ -1524,6 +1595,9 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
 
 	drm_plane_helper_add(plane, &dm_plane_helper_funcs);
 
+#ifdef CONFIG_STEAM_DECK
+	dm_plane_attach_color_mgmt_properties(dm, plane);
+#endif
 	/* Create (reset) the plane state */
 	if (plane->funcs->reset)
 		plane->funcs->reset(plane);
-- 
2.39.2


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

* [RFC PATCH 11/40] drm/amd/display: add plane degamma TF driver-private property
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

Allow userspace to tell the kernel driver the input space and,
therefore, uses correct predefined transfer function (TF) to delinearize
content with or without LUT (using hardcoded curve caps).

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  9 ++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  5 ++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  7 +++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 28 +++++++++++++++++++
 4 files changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 996c9c3fd471..24595906dab1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1317,6 +1317,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_degamma_lut_size_property = prop;
 
+	prop = drm_property_create_enum(adev_to_drm(adev),
+					DRM_MODE_PROP_ENUM,
+					"AMD_PLANE_DEGAMMA_TF",
+					drm_transfer_function_enum_list,
+					ARRAY_SIZE(drm_transfer_function_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_degamma_tf_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index d4e609a8b67e..ab9ce6f26c90 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -382,6 +382,11 @@ struct amdgpu_mode_info {
 	 * size of degamma LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *plane_degamma_lut_size_property;
+	/**
+	 * @plane_degamma_tf_property: Predefined transfer function to
+	 * linearize content with or without LUT.
+	 */
+	struct drm_property *plane_degamma_tf_property;
 #endif
 };
 
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 b1d0c65d821d..005632c1c9ec 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -729,6 +729,13 @@ struct dm_plane_state {
 	 * The blob (if not NULL) is an array of &struct drm_color_lut.
 	 */
 	struct drm_property_blob *degamma_lut;
+	/**
+	 * @degamma_tf:
+	 *
+	 * Predefined transfer function to tell DC driver the input space to
+	 * linearize.
+	 */
+	enum drm_transfer_function degamma_tf;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 7b9d62c70b30..5b458cc0781c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1319,6 +1319,11 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
 
 	if (amdgpu_state)
 		__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
+
+#ifdef CONFIG_STEAM_DECK
+	if (amdgpu_state)
+		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+#endif
 }
 
 static struct drm_plane_state *
@@ -1450,6 +1455,19 @@ amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
 	return 0;
 }
 
+static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
+	{ DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
+	{ DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
+	{ DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
+	{ DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
+	{ DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
+	{ DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
+	{ DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
+};
+
 static void
 dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 				      struct drm_plane *plane)
@@ -1460,6 +1478,9 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 		drm_object_attach_property(&plane->base,
 					   dm->adev->mode_info.plane_degamma_lut_size_property,
 					   MAX_COLOR_LUT_ENTRIES);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_degamma_tf_property,
+					   DRM_TRANSFER_FUNCTION_DEFAULT);
 	}
 }
 
@@ -1481,6 +1502,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 					&replaced);
 		dm_plane_state->base.color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == adev->mode_info.plane_degamma_tf_property) {
+		if (dm_plane_state->degamma_tf != val) {
+			dm_plane_state->degamma_tf = val;
+			dm_plane_state->base.color_mgmt_changed = 1;
+		}
 	} else {
 		drm_dbg_atomic(plane->dev,
 			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -1505,6 +1531,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 	if (property == adev->mode_info.plane_degamma_lut_property) {
 		*val = (dm_plane_state->degamma_lut) ?
 			dm_plane_state->degamma_lut->base.id : 0;
+	} else if (property == adev->mode_info.plane_degamma_tf_property) {
+		*val = dm_plane_state->degamma_tf;
 	} else {
 		return -EINVAL;
 	}
-- 
2.39.2


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

* [RFC PATCH 11/40] drm/amd/display: add plane degamma TF driver-private property
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Joshua Ashton <joshua@froggi.es>

Allow userspace to tell the kernel driver the input space and,
therefore, uses correct predefined transfer function (TF) to delinearize
content with or without LUT (using hardcoded curve caps).

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  9 ++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  5 ++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  7 +++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 28 +++++++++++++++++++
 4 files changed, 49 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 996c9c3fd471..24595906dab1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1317,6 +1317,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_degamma_lut_size_property = prop;
 
+	prop = drm_property_create_enum(adev_to_drm(adev),
+					DRM_MODE_PROP_ENUM,
+					"AMD_PLANE_DEGAMMA_TF",
+					drm_transfer_function_enum_list,
+					ARRAY_SIZE(drm_transfer_function_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_degamma_tf_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index d4e609a8b67e..ab9ce6f26c90 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -382,6 +382,11 @@ struct amdgpu_mode_info {
 	 * size of degamma LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *plane_degamma_lut_size_property;
+	/**
+	 * @plane_degamma_tf_property: Predefined transfer function to
+	 * linearize content with or without LUT.
+	 */
+	struct drm_property *plane_degamma_tf_property;
 #endif
 };
 
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 b1d0c65d821d..005632c1c9ec 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -729,6 +729,13 @@ struct dm_plane_state {
 	 * The blob (if not NULL) is an array of &struct drm_color_lut.
 	 */
 	struct drm_property_blob *degamma_lut;
+	/**
+	 * @degamma_tf:
+	 *
+	 * Predefined transfer function to tell DC driver the input space to
+	 * linearize.
+	 */
+	enum drm_transfer_function degamma_tf;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 7b9d62c70b30..5b458cc0781c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1319,6 +1319,11 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
 
 	if (amdgpu_state)
 		__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
+
+#ifdef CONFIG_STEAM_DECK
+	if (amdgpu_state)
+		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+#endif
 }
 
 static struct drm_plane_state *
@@ -1450,6 +1455,19 @@ amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
 	return 0;
 }
 
+static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
+	{ DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
+	{ DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
+	{ DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
+	{ DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
+	{ DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
+	{ DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
+	{ DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
+	{ DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
+};
+
 static void
 dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 				      struct drm_plane *plane)
@@ -1460,6 +1478,9 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 		drm_object_attach_property(&plane->base,
 					   dm->adev->mode_info.plane_degamma_lut_size_property,
 					   MAX_COLOR_LUT_ENTRIES);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_degamma_tf_property,
+					   DRM_TRANSFER_FUNCTION_DEFAULT);
 	}
 }
 
@@ -1481,6 +1502,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 					&replaced);
 		dm_plane_state->base.color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == adev->mode_info.plane_degamma_tf_property) {
+		if (dm_plane_state->degamma_tf != val) {
+			dm_plane_state->degamma_tf = val;
+			dm_plane_state->base.color_mgmt_changed = 1;
+		}
 	} else {
 		drm_dbg_atomic(plane->dev,
 			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -1505,6 +1531,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 	if (property == adev->mode_info.plane_degamma_lut_property) {
 		*val = (dm_plane_state->degamma_lut) ?
 			dm_plane_state->degamma_lut->base.id : 0;
+	} else if (property == adev->mode_info.plane_degamma_tf_property) {
+		*val = dm_plane_state->degamma_tf;
 	} else {
 		return -EINVAL;
 	}
-- 
2.39.2


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

* [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
nits for SDR content. So if you want, 203 nits for SDR content, pass in
(203.0 / 80.0).

Co-developed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
 4 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 24595906dab1..dd658f162f6f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_degamma_tf_property = prop;
 
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_hdr_mult_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index ab9ce6f26c90..65a9d62ffbe4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -387,6 +387,10 @@ struct amdgpu_mode_info {
 	 * linearize content with or without LUT.
 	 */
 	struct drm_property *plane_degamma_tf_property;
+	/**
+	 * @plane_hdr_mult_property:
+	 */
+	struct drm_property *plane_hdr_mult_property;
 #endif
 };
 
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 005632c1c9ec..bb7307b9cfd5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -51,6 +51,7 @@
 
 #define AMDGPU_DMUB_NOTIFICATION_MAX 5
 
+#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
 /*
 #include "include/amdgpu_dal_power_if.h"
 #include "amdgpu_dm_irq.h"
@@ -736,6 +737,17 @@ struct dm_plane_state {
 	 * linearize.
 	 */
 	enum drm_transfer_function degamma_tf;
+	/**
+	 * @hdr_mult:
+	 *
+	 * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
+	 * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
+	 * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
+	 * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
+	 * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
+	 * S31.32 sign-magnitude.
+	 */
+	__u64 hdr_mult;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 5b458cc0781c..57169dae8b3d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
 		__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
 
 #ifdef CONFIG_STEAM_DECK
-	if (amdgpu_state)
+	if (amdgpu_state) {
 		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+		amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
+	}
 #endif
 }
 
@@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 #ifdef CONFIG_STEAM_DECK
 int
 amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
-					       struct drm_property_blob **blob,
-					       uint64_t blob_id,
-					       ssize_t expected_size,
-					       ssize_t expected_elem_size,
-					       bool *replaced)
+					struct drm_property_blob **blob,
+					uint64_t blob_id,
+					ssize_t expected_size,
+					ssize_t expected_elem_size,
+					bool *replaced)
 {
 	struct drm_property_blob *new_blob = NULL;
 
@@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 					   dm->adev->mode_info.plane_degamma_tf_property,
 					   DRM_TRANSFER_FUNCTION_DEFAULT);
 	}
+	/* HDR MULT is always available */
+	drm_object_attach_property(&plane->base,
+				   dm->adev->mode_info.plane_hdr_mult_property,
+				   AMDGPU_HDR_MULT_DEFAULT);
 }
 
 static int
@@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 			dm_plane_state->degamma_tf = val;
 			dm_plane_state->base.color_mgmt_changed = 1;
 		}
+	} else if (property == adev->mode_info.plane_hdr_mult_property) {
+		if (dm_plane_state->hdr_mult != val) {
+			dm_plane_state->hdr_mult = val;
+			dm_plane_state->base.color_mgmt_changed = 1;
+		}
 	} else {
 		drm_dbg_atomic(plane->dev,
 			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 			dm_plane_state->degamma_lut->base.id : 0;
 	} else if (property == adev->mode_info.plane_degamma_tf_property) {
 		*val = dm_plane_state->degamma_tf;
+	} else if (property == adev->mode_info.plane_hdr_mult_property) {
+		*val = dm_plane_state->hdr_mult;
 	} else {
 		return -EINVAL;
 	}
-- 
2.39.2


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

* [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

From: Joshua Ashton <joshua@froggi.es>

Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
nits for SDR content. So if you want, 203 nits for SDR content, pass in
(203.0 / 80.0).

Co-developed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
 4 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 24595906dab1..dd658f162f6f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_degamma_tf_property = prop;
 
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_hdr_mult_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index ab9ce6f26c90..65a9d62ffbe4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -387,6 +387,10 @@ struct amdgpu_mode_info {
 	 * linearize content with or without LUT.
 	 */
 	struct drm_property *plane_degamma_tf_property;
+	/**
+	 * @plane_hdr_mult_property:
+	 */
+	struct drm_property *plane_hdr_mult_property;
 #endif
 };
 
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 005632c1c9ec..bb7307b9cfd5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -51,6 +51,7 @@
 
 #define AMDGPU_DMUB_NOTIFICATION_MAX 5
 
+#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
 /*
 #include "include/amdgpu_dal_power_if.h"
 #include "amdgpu_dm_irq.h"
@@ -736,6 +737,17 @@ struct dm_plane_state {
 	 * linearize.
 	 */
 	enum drm_transfer_function degamma_tf;
+	/**
+	 * @hdr_mult:
+	 *
+	 * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
+	 * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
+	 * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
+	 * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
+	 * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
+	 * S31.32 sign-magnitude.
+	 */
+	__u64 hdr_mult;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 5b458cc0781c..57169dae8b3d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
 		__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
 
 #ifdef CONFIG_STEAM_DECK
-	if (amdgpu_state)
+	if (amdgpu_state) {
 		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+		amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
+	}
 #endif
 }
 
@@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 #ifdef CONFIG_STEAM_DECK
 int
 amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
-					       struct drm_property_blob **blob,
-					       uint64_t blob_id,
-					       ssize_t expected_size,
-					       ssize_t expected_elem_size,
-					       bool *replaced)
+					struct drm_property_blob **blob,
+					uint64_t blob_id,
+					ssize_t expected_size,
+					ssize_t expected_elem_size,
+					bool *replaced)
 {
 	struct drm_property_blob *new_blob = NULL;
 
@@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 					   dm->adev->mode_info.plane_degamma_tf_property,
 					   DRM_TRANSFER_FUNCTION_DEFAULT);
 	}
+	/* HDR MULT is always available */
+	drm_object_attach_property(&plane->base,
+				   dm->adev->mode_info.plane_hdr_mult_property,
+				   AMDGPU_HDR_MULT_DEFAULT);
 }
 
 static int
@@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 			dm_plane_state->degamma_tf = val;
 			dm_plane_state->base.color_mgmt_changed = 1;
 		}
+	} else if (property == adev->mode_info.plane_hdr_mult_property) {
+		if (dm_plane_state->hdr_mult != val) {
+			dm_plane_state->hdr_mult = val;
+			dm_plane_state->base.color_mgmt_changed = 1;
+		}
 	} else {
 		drm_dbg_atomic(plane->dev,
 			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 			dm_plane_state->degamma_lut->base.id : 0;
 	} else if (property == adev->mode_info.plane_degamma_tf_property) {
 		*val = dm_plane_state->degamma_tf;
+	} else if (property == adev->mode_info.plane_hdr_mult_property) {
+		*val = dm_plane_state->hdr_mult;
 	} else {
 		return -EINVAL;
 	}
-- 
2.39.2


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

* [RFC PATCH 13/40] drm/amd/display: add plane 3D LUT driver-private properties
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

Add 3D LUT property for plane gamma correction using a 3D lookup table.
3D LUT is more effective when applying in non-linear space, therefore,
userpace may need one 1D LUT (shaper) before it to delinearize content
and another 1D LUT after 3D LUT (blend) to linearize content again for
blending. The next patches add these 1D LUTs to the plane color mgmt
pipeline.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 +++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      | 10 ++++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  5 ++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 24 +++++++++++++++++++
 4 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index dd658f162f6f..8d4726978c6e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1332,6 +1332,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_hdr_mult_property = prop;
 
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_PLANE_LUT3D", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_lut3d_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_PLANE_LUT3D_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_lut3d_size_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 65a9d62ffbe4..9d9dac26edfc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -391,6 +391,16 @@ struct amdgpu_mode_info {
 	 * @plane_hdr_mult_property:
 	 */
 	struct drm_property *plane_hdr_mult_property;
+	/**
+	 * @plane_lut3d_property: Plane property for gamma correction using a
+	 * 3D LUT (pre-blending).
+	 */
+	struct drm_property *plane_lut3d_property;
+	/**
+	 * @plane_degamma_lut_size_property: Plane property to define the max
+	 * size of 3D LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *plane_lut3d_size_property;
 #endif
 };
 
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 bb7307b9cfd5..b0ba0279dc25 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -748,6 +748,11 @@ struct dm_plane_state {
 	 * S31.32 sign-magnitude.
 	 */
 	__u64 hdr_mult;
+	/**
+	 * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
+	 * &struct drm_color_lut.
+	 */
+	struct drm_property_blob *lut3d;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 57169dae8b3d..0e418e161b0b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1347,7 +1347,10 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 #ifdef CONFIG_STEAM_DECK
 	if (dm_plane_state->degamma_lut)
 		drm_property_blob_get(dm_plane_state->degamma_lut);
+	if (dm_plane_state->lut3d)
+		drm_property_blob_get(dm_plane_state->lut3d);
 #endif
+
 	return &dm_plane_state->base;
 }
 
@@ -1416,7 +1419,9 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
 #ifdef CONFIG_STEAM_DECK
 	drm_property_blob_put(dm_plane_state->degamma_lut);
+	drm_property_blob_put(dm_plane_state->lut3d);
 #endif
+
 	if (dm_plane_state->dc_state)
 		dc_plane_state_release(dm_plane_state->dc_state);
 
@@ -1488,6 +1493,14 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 	drm_object_attach_property(&plane->base,
 				   dm->adev->mode_info.plane_hdr_mult_property,
 				   AMDGPU_HDR_MULT_DEFAULT);
+
+	if (dm->dc->caps.color.dpp.hw_3d_lut) {
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_lut3d_property, 0);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_lut3d_size_property,
+					   MAX_COLOR_3DLUT_ENTRIES);
+	}
 }
 
 static int
@@ -1518,6 +1531,14 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 			dm_plane_state->hdr_mult = val;
 			dm_plane_state->base.color_mgmt_changed = 1;
 		}
+	} else if (property == adev->mode_info.plane_lut3d_property) {
+		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
+					&dm_plane_state->lut3d,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		dm_plane_state->base.color_mgmt_changed |= replaced;
+		return ret;
 	} else {
 		drm_dbg_atomic(plane->dev,
 			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -1546,6 +1567,9 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 		*val = dm_plane_state->degamma_tf;
 	} else if (property == adev->mode_info.plane_hdr_mult_property) {
 		*val = dm_plane_state->hdr_mult;
+	} else 	if (property == adev->mode_info.plane_lut3d_property) {
+		*val = (dm_plane_state->lut3d) ?
+			dm_plane_state->lut3d->base.id : 0;
 	} else {
 		return -EINVAL;
 	}
-- 
2.39.2


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

* [RFC PATCH 13/40] drm/amd/display: add plane 3D LUT driver-private properties
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

Add 3D LUT property for plane gamma correction using a 3D lookup table.
3D LUT is more effective when applying in non-linear space, therefore,
userpace may need one 1D LUT (shaper) before it to delinearize content
and another 1D LUT after 3D LUT (blend) to linearize content again for
blending. The next patches add these 1D LUTs to the plane color mgmt
pipeline.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 +++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      | 10 ++++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  5 ++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 24 +++++++++++++++++++
 4 files changed, 53 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index dd658f162f6f..8d4726978c6e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1332,6 +1332,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_hdr_mult_property = prop;
 
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_PLANE_LUT3D", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_lut3d_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_PLANE_LUT3D_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_lut3d_size_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 65a9d62ffbe4..9d9dac26edfc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -391,6 +391,16 @@ struct amdgpu_mode_info {
 	 * @plane_hdr_mult_property:
 	 */
 	struct drm_property *plane_hdr_mult_property;
+	/**
+	 * @plane_lut3d_property: Plane property for gamma correction using a
+	 * 3D LUT (pre-blending).
+	 */
+	struct drm_property *plane_lut3d_property;
+	/**
+	 * @plane_degamma_lut_size_property: Plane property to define the max
+	 * size of 3D LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *plane_lut3d_size_property;
 #endif
 };
 
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 bb7307b9cfd5..b0ba0279dc25 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -748,6 +748,11 @@ struct dm_plane_state {
 	 * S31.32 sign-magnitude.
 	 */
 	__u64 hdr_mult;
+	/**
+	 * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
+	 * &struct drm_color_lut.
+	 */
+	struct drm_property_blob *lut3d;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 57169dae8b3d..0e418e161b0b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1347,7 +1347,10 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 #ifdef CONFIG_STEAM_DECK
 	if (dm_plane_state->degamma_lut)
 		drm_property_blob_get(dm_plane_state->degamma_lut);
+	if (dm_plane_state->lut3d)
+		drm_property_blob_get(dm_plane_state->lut3d);
 #endif
+
 	return &dm_plane_state->base;
 }
 
@@ -1416,7 +1419,9 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
 #ifdef CONFIG_STEAM_DECK
 	drm_property_blob_put(dm_plane_state->degamma_lut);
+	drm_property_blob_put(dm_plane_state->lut3d);
 #endif
+
 	if (dm_plane_state->dc_state)
 		dc_plane_state_release(dm_plane_state->dc_state);
 
@@ -1488,6 +1493,14 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 	drm_object_attach_property(&plane->base,
 				   dm->adev->mode_info.plane_hdr_mult_property,
 				   AMDGPU_HDR_MULT_DEFAULT);
+
+	if (dm->dc->caps.color.dpp.hw_3d_lut) {
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_lut3d_property, 0);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_lut3d_size_property,
+					   MAX_COLOR_3DLUT_ENTRIES);
+	}
 }
 
 static int
@@ -1518,6 +1531,14 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 			dm_plane_state->hdr_mult = val;
 			dm_plane_state->base.color_mgmt_changed = 1;
 		}
+	} else if (property == adev->mode_info.plane_lut3d_property) {
+		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
+					&dm_plane_state->lut3d,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		dm_plane_state->base.color_mgmt_changed |= replaced;
+		return ret;
 	} else {
 		drm_dbg_atomic(plane->dev,
 			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -1546,6 +1567,9 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 		*val = dm_plane_state->degamma_tf;
 	} else if (property == adev->mode_info.plane_hdr_mult_property) {
 		*val = dm_plane_state->hdr_mult;
+	} else 	if (property == adev->mode_info.plane_lut3d_property) {
+		*val = (dm_plane_state->lut3d) ?
+			dm_plane_state->lut3d->base.id : 0;
 	} else {
 		return -EINVAL;
 	}
-- 
2.39.2


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

* [RFC PATCH 14/40] drm/amd/display: add plane shaper LUT driver-private properties
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

Shaper 1D LUT delinearizes content before applying 3D LUT so that, it
comes before 3D LUT. It's an optional property and drivers should attach
it according to HW caps.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 ++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      | 10 ++++++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  5 +++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 19 +++++++++++++++++++
 4 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 8d4726978c6e..f41406ee96ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1332,6 +1332,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_hdr_mult_property = prop;
 
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_PLANE_SHAPER_LUT", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_shaper_lut_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_PLANE_SHAPER_LUT_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_shaper_lut_size_property = prop;
+
 	prop = drm_property_create(adev_to_drm(adev),
 				   DRM_MODE_PROP_BLOB,
 				   "AMD_PLANE_LUT3D", 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 9d9dac26edfc..756d5f70be0a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -391,6 +391,16 @@ struct amdgpu_mode_info {
 	 * @plane_hdr_mult_property:
 	 */
 	struct drm_property *plane_hdr_mult_property;
+	/**
+	 * @shaper_lut_property: Plane property to set pre-blending shaper LUT
+	 * that converts color content before 3D LUT.
+	 */
+	struct drm_property *plane_shaper_lut_property;
+	/**
+	 * @shaper_lut_size_property: Plane property for the size of
+	 * pre-blending shaper LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *plane_shaper_lut_size_property;
 	/**
 	 * @plane_lut3d_property: Plane property for gamma correction using a
 	 * 3D LUT (pre-blending).
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 b0ba0279dc25..d3ecc73129ff 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -748,6 +748,11 @@ struct dm_plane_state {
 	 * S31.32 sign-magnitude.
 	 */
 	__u64 hdr_mult;
+	/**
+	 * @shaper_lut: shaper lookup table blob. The blob (if not NULL) is an
+	 * array of &struct drm_color_lut.
+	 */
+	struct drm_property_blob *shaper_lut;
 	/**
 	 * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
 	 * &struct drm_color_lut.
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 0e418e161b0b..69e2f1f86cce 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1347,6 +1347,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 #ifdef CONFIG_STEAM_DECK
 	if (dm_plane_state->degamma_lut)
 		drm_property_blob_get(dm_plane_state->degamma_lut);
+	if (dm_plane_state->shaper_lut)
+		drm_property_blob_get(dm_plane_state->shaper_lut);
 	if (dm_plane_state->lut3d)
 		drm_property_blob_get(dm_plane_state->lut3d);
 #endif
@@ -1419,6 +1421,7 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
 #ifdef CONFIG_STEAM_DECK
 	drm_property_blob_put(dm_plane_state->degamma_lut);
+	drm_property_blob_put(dm_plane_state->shaper_lut);
 	drm_property_blob_put(dm_plane_state->lut3d);
 #endif
 
@@ -1495,6 +1498,11 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 				   AMDGPU_HDR_MULT_DEFAULT);
 
 	if (dm->dc->caps.color.dpp.hw_3d_lut) {
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_shaper_lut_property, 0);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_shaper_lut_size_property,
+					   MAX_COLOR_LUT_ENTRIES);
 		drm_object_attach_property(&plane->base,
 					   dm->adev->mode_info.plane_lut3d_property, 0);
 		drm_object_attach_property(&plane->base,
@@ -1531,6 +1539,14 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 			dm_plane_state->hdr_mult = val;
 			dm_plane_state->base.color_mgmt_changed = 1;
 		}
+	} else if (property == adev->mode_info.plane_shaper_lut_property) {
+		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
+					&dm_plane_state->shaper_lut,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		dm_plane_state->base.color_mgmt_changed |= replaced;
+		return ret;
 	} else if (property == adev->mode_info.plane_lut3d_property) {
 		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
 					&dm_plane_state->lut3d,
@@ -1567,6 +1583,9 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 		*val = dm_plane_state->degamma_tf;
 	} else if (property == adev->mode_info.plane_hdr_mult_property) {
 		*val = dm_plane_state->hdr_mult;
+	} else 	if (property == adev->mode_info.plane_shaper_lut_property) {
+		*val = (dm_plane_state->shaper_lut) ?
+			dm_plane_state->shaper_lut->base.id : 0;
 	} else 	if (property == adev->mode_info.plane_lut3d_property) {
 		*val = (dm_plane_state->lut3d) ?
 			dm_plane_state->lut3d->base.id : 0;
-- 
2.39.2


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

* [RFC PATCH 14/40] drm/amd/display: add plane shaper LUT driver-private properties
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

Shaper 1D LUT delinearizes content before applying 3D LUT so that, it
comes before 3D LUT. It's an optional property and drivers should attach
it according to HW caps.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 14 ++++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      | 10 ++++++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  5 +++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 19 +++++++++++++++++++
 4 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 8d4726978c6e..f41406ee96ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1332,6 +1332,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_hdr_mult_property = prop;
 
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_PLANE_SHAPER_LUT", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_shaper_lut_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_PLANE_SHAPER_LUT_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_shaper_lut_size_property = prop;
+
 	prop = drm_property_create(adev_to_drm(adev),
 				   DRM_MODE_PROP_BLOB,
 				   "AMD_PLANE_LUT3D", 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 9d9dac26edfc..756d5f70be0a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -391,6 +391,16 @@ struct amdgpu_mode_info {
 	 * @plane_hdr_mult_property:
 	 */
 	struct drm_property *plane_hdr_mult_property;
+	/**
+	 * @shaper_lut_property: Plane property to set pre-blending shaper LUT
+	 * that converts color content before 3D LUT.
+	 */
+	struct drm_property *plane_shaper_lut_property;
+	/**
+	 * @shaper_lut_size_property: Plane property for the size of
+	 * pre-blending shaper LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *plane_shaper_lut_size_property;
 	/**
 	 * @plane_lut3d_property: Plane property for gamma correction using a
 	 * 3D LUT (pre-blending).
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 b0ba0279dc25..d3ecc73129ff 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -748,6 +748,11 @@ struct dm_plane_state {
 	 * S31.32 sign-magnitude.
 	 */
 	__u64 hdr_mult;
+	/**
+	 * @shaper_lut: shaper lookup table blob. The blob (if not NULL) is an
+	 * array of &struct drm_color_lut.
+	 */
+	struct drm_property_blob *shaper_lut;
 	/**
 	 * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
 	 * &struct drm_color_lut.
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 0e418e161b0b..69e2f1f86cce 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1347,6 +1347,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 #ifdef CONFIG_STEAM_DECK
 	if (dm_plane_state->degamma_lut)
 		drm_property_blob_get(dm_plane_state->degamma_lut);
+	if (dm_plane_state->shaper_lut)
+		drm_property_blob_get(dm_plane_state->shaper_lut);
 	if (dm_plane_state->lut3d)
 		drm_property_blob_get(dm_plane_state->lut3d);
 #endif
@@ -1419,6 +1421,7 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
 #ifdef CONFIG_STEAM_DECK
 	drm_property_blob_put(dm_plane_state->degamma_lut);
+	drm_property_blob_put(dm_plane_state->shaper_lut);
 	drm_property_blob_put(dm_plane_state->lut3d);
 #endif
 
@@ -1495,6 +1498,11 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 				   AMDGPU_HDR_MULT_DEFAULT);
 
 	if (dm->dc->caps.color.dpp.hw_3d_lut) {
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_shaper_lut_property, 0);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_shaper_lut_size_property,
+					   MAX_COLOR_LUT_ENTRIES);
 		drm_object_attach_property(&plane->base,
 					   dm->adev->mode_info.plane_lut3d_property, 0);
 		drm_object_attach_property(&plane->base,
@@ -1531,6 +1539,14 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 			dm_plane_state->hdr_mult = val;
 			dm_plane_state->base.color_mgmt_changed = 1;
 		}
+	} else if (property == adev->mode_info.plane_shaper_lut_property) {
+		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
+					&dm_plane_state->shaper_lut,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		dm_plane_state->base.color_mgmt_changed |= replaced;
+		return ret;
 	} else if (property == adev->mode_info.plane_lut3d_property) {
 		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
 					&dm_plane_state->lut3d,
@@ -1567,6 +1583,9 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 		*val = dm_plane_state->degamma_tf;
 	} else if (property == adev->mode_info.plane_hdr_mult_property) {
 		*val = dm_plane_state->hdr_mult;
+	} else 	if (property == adev->mode_info.plane_shaper_lut_property) {
+		*val = (dm_plane_state->shaper_lut) ?
+			dm_plane_state->shaper_lut->base.id : 0;
 	} else 	if (property == adev->mode_info.plane_lut3d_property) {
 		*val = (dm_plane_state->lut3d) ?
 			dm_plane_state->lut3d->base.id : 0;
-- 
2.39.2


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

* [RFC PATCH 15/40] drm/amd/display: add plane shaper TF driver-private property
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

Add property to set predefined transfer function to enable delinearizing
content with or without shaper LUT. Drivers should advertize this
property acoording to HW caps.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c           |  9 +++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h              |  6 ++++++
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h     |  6 ++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 11 +++++++++++
 4 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index f41406ee96ad..2bf8b19feae4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1346,6 +1346,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_shaper_lut_size_property = prop;
 
+	prop = drm_property_create_enum(adev_to_drm(adev),
+					DRM_MODE_PROP_ENUM,
+					"AMD_PLANE_SHAPER_TF",
+					drm_transfer_function_enum_list,
+					ARRAY_SIZE(drm_transfer_function_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_shaper_tf_property = prop;
+
 	prop = drm_property_create(adev_to_drm(adev),
 				   DRM_MODE_PROP_BLOB,
 				   "AMD_PLANE_LUT3D", 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 756d5f70be0a..17c7669ad9ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -401,6 +401,12 @@ struct amdgpu_mode_info {
 	 * pre-blending shaper LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *plane_shaper_lut_size_property;
+	/**
+	 * @plane_shaper_tf_property: Plane property to set a predefined
+	 * transfer function for pre-blending shaper (before applying 3D LUT)
+	 * with or without LUT.
+	 */
+	struct drm_property *plane_shaper_tf_property;
 	/**
 	 * @plane_lut3d_property: Plane property for gamma correction using a
 	 * 3D LUT (pre-blending).
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 d3ecc73129ff..8a425e7a7e89 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -753,6 +753,12 @@ struct dm_plane_state {
 	 * array of &struct drm_color_lut.
 	 */
 	struct drm_property_blob *shaper_lut;
+	/**
+	 * @shaper_tf:
+	 *
+	 * Predefined transfer function to delinearize color space.
+	 */
+	enum drm_transfer_function shaper_tf;
 	/**
 	 * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
 	 * &struct drm_color_lut.
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 69e2f1f86cce..e4f28fbf6613 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1324,6 +1324,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
 	if (amdgpu_state) {
 		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
 		amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
+		amdgpu_state->shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
 	}
 #endif
 }
@@ -1503,6 +1504,9 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 		drm_object_attach_property(&plane->base,
 					   dm->adev->mode_info.plane_shaper_lut_size_property,
 					   MAX_COLOR_LUT_ENTRIES);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_shaper_tf_property,
+					   DRM_TRANSFER_FUNCTION_DEFAULT);
 		drm_object_attach_property(&plane->base,
 					   dm->adev->mode_info.plane_lut3d_property, 0);
 		drm_object_attach_property(&plane->base,
@@ -1547,6 +1551,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 					&replaced);
 		dm_plane_state->base.color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == adev->mode_info.plane_shaper_tf_property) {
+		if (dm_plane_state->shaper_tf != val) {
+			dm_plane_state->shaper_tf = val;
+			dm_plane_state->base.color_mgmt_changed = 1;
+		}
 	} else if (property == adev->mode_info.plane_lut3d_property) {
 		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
 					&dm_plane_state->lut3d,
@@ -1586,6 +1595,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 	} else 	if (property == adev->mode_info.plane_shaper_lut_property) {
 		*val = (dm_plane_state->shaper_lut) ?
 			dm_plane_state->shaper_lut->base.id : 0;
+	} else if (property == adev->mode_info.plane_shaper_tf_property) {
+		*val = dm_plane_state->shaper_tf;
 	} else 	if (property == adev->mode_info.plane_lut3d_property) {
 		*val = (dm_plane_state->lut3d) ?
 			dm_plane_state->lut3d->base.id : 0;
-- 
2.39.2


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

* [RFC PATCH 15/40] drm/amd/display: add plane shaper TF driver-private property
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

Add property to set predefined transfer function to enable delinearizing
content with or without shaper LUT. Drivers should advertize this
property acoording to HW caps.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c           |  9 +++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h              |  6 ++++++
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h     |  6 ++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 11 +++++++++++
 4 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index f41406ee96ad..2bf8b19feae4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1346,6 +1346,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_shaper_lut_size_property = prop;
 
+	prop = drm_property_create_enum(adev_to_drm(adev),
+					DRM_MODE_PROP_ENUM,
+					"AMD_PLANE_SHAPER_TF",
+					drm_transfer_function_enum_list,
+					ARRAY_SIZE(drm_transfer_function_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_shaper_tf_property = prop;
+
 	prop = drm_property_create(adev_to_drm(adev),
 				   DRM_MODE_PROP_BLOB,
 				   "AMD_PLANE_LUT3D", 0);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 756d5f70be0a..17c7669ad9ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -401,6 +401,12 @@ struct amdgpu_mode_info {
 	 * pre-blending shaper LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *plane_shaper_lut_size_property;
+	/**
+	 * @plane_shaper_tf_property: Plane property to set a predefined
+	 * transfer function for pre-blending shaper (before applying 3D LUT)
+	 * with or without LUT.
+	 */
+	struct drm_property *plane_shaper_tf_property;
 	/**
 	 * @plane_lut3d_property: Plane property for gamma correction using a
 	 * 3D LUT (pre-blending).
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 d3ecc73129ff..8a425e7a7e89 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -753,6 +753,12 @@ struct dm_plane_state {
 	 * array of &struct drm_color_lut.
 	 */
 	struct drm_property_blob *shaper_lut;
+	/**
+	 * @shaper_tf:
+	 *
+	 * Predefined transfer function to delinearize color space.
+	 */
+	enum drm_transfer_function shaper_tf;
 	/**
 	 * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of
 	 * &struct drm_color_lut.
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 69e2f1f86cce..e4f28fbf6613 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1324,6 +1324,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
 	if (amdgpu_state) {
 		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
 		amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
+		amdgpu_state->shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
 	}
 #endif
 }
@@ -1503,6 +1504,9 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 		drm_object_attach_property(&plane->base,
 					   dm->adev->mode_info.plane_shaper_lut_size_property,
 					   MAX_COLOR_LUT_ENTRIES);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_shaper_tf_property,
+					   DRM_TRANSFER_FUNCTION_DEFAULT);
 		drm_object_attach_property(&plane->base,
 					   dm->adev->mode_info.plane_lut3d_property, 0);
 		drm_object_attach_property(&plane->base,
@@ -1547,6 +1551,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 					&replaced);
 		dm_plane_state->base.color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == adev->mode_info.plane_shaper_tf_property) {
+		if (dm_plane_state->shaper_tf != val) {
+			dm_plane_state->shaper_tf = val;
+			dm_plane_state->base.color_mgmt_changed = 1;
+		}
 	} else if (property == adev->mode_info.plane_lut3d_property) {
 		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
 					&dm_plane_state->lut3d,
@@ -1586,6 +1595,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 	} else 	if (property == adev->mode_info.plane_shaper_lut_property) {
 		*val = (dm_plane_state->shaper_lut) ?
 			dm_plane_state->shaper_lut->base.id : 0;
+	} else if (property == adev->mode_info.plane_shaper_tf_property) {
+		*val = dm_plane_state->shaper_tf;
 	} else 	if (property == adev->mode_info.plane_lut3d_property) {
 		*val = (dm_plane_state->lut3d) ?
 			dm_plane_state->lut3d->base.id : 0;
-- 
2.39.2


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

* [RFC PATCH 16/40] drm/amd/display: add plane blend LUT and TF driver-private properties
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

Blend 1D LUT or a predefined transfer function can be set to linearize
content before blending, so that it's positioned just before blending
planes, and after 3D LUT (non-linear space). Shaper and Blend LUTs are
1D LUTs that sandwich 3D LUT. Drivers should advertize blend properties
according to HW caps.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 23 +++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      | 18 ++++++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 34 +++++++++++++++++++
 4 files changed, 87 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 2bf8b19feae4..0bcf0bc6baff 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1369,6 +1369,29 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_lut3d_size_property = prop;
 
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_PLANE_BLEND_LUT", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_blend_lut_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_PLANE_BLEND_LUT_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_blend_lut_size_property = prop;
+
+	prop = drm_property_create_enum(adev_to_drm(adev),
+					DRM_MODE_PROP_ENUM,
+					"AMD_PLANE_BLEND_TF",
+					drm_transfer_function_enum_list,
+					ARRAY_SIZE(drm_transfer_function_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_blend_tf_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 17c7669ad9ab..f640dbd53b8c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -417,6 +417,24 @@ struct amdgpu_mode_info {
 	 * size of 3D LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *plane_lut3d_size_property;
+	/**
+	 * @plane_blend_lut_property: Plane property for output gamma before
+	 * blending. Userspace set a blend LUT to convert colors after 3D LUT
+	 * conversion. It works as a post-3D LUT 1D LUT, with shaper LUT, they
+	 * are sandwiching 3D LUT with two 1D LUT.
+	 */
+	struct drm_property *plane_blend_lut_property;
+	/**
+	 * @plane_blend_lut_size_property: Plane property to define the max
+	 * size of blend LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *plane_blend_lut_size_property;
+	/**
+	 * @plane_blend_tf_property: Plane property to set a predefined
+	 * transfer function for pre-blending blend (before applying 3D LUT)
+	 * with or without LUT.
+	 */
+	struct drm_property *plane_blend_tf_property;
 #endif
 };
 
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 8a425e7a7e89..54121c3fa040 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -764,6 +764,18 @@ struct dm_plane_state {
 	 * &struct drm_color_lut.
 	 */
 	struct drm_property_blob *lut3d;
+	/**
+	 * @blend_lut: blend lut lookup table blob. The blob (if not NULL) is an
+	 * array of &struct drm_color_lut.
+	 */
+	struct drm_property_blob *blend_lut;
+	/**
+	 * @blend_tf:
+	 *
+	 * Pre-defined transfer function for converting plane pixel data before
+	 * applying blend LUT.
+	 */
+	enum drm_transfer_function blend_tf;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index e4f28fbf6613..cdbd11f3be20 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1325,6 +1325,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
 		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
 		amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
 		amdgpu_state->shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+		amdgpu_state->blend_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
 	}
 #endif
 }
@@ -1352,6 +1353,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 		drm_property_blob_get(dm_plane_state->shaper_lut);
 	if (dm_plane_state->lut3d)
 		drm_property_blob_get(dm_plane_state->lut3d);
+	if (dm_plane_state->blend_lut)
+		drm_property_blob_get(dm_plane_state->blend_lut);
 #endif
 
 	return &dm_plane_state->base;
@@ -1424,6 +1427,7 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 	drm_property_blob_put(dm_plane_state->degamma_lut);
 	drm_property_blob_put(dm_plane_state->shaper_lut);
 	drm_property_blob_put(dm_plane_state->lut3d);
+	drm_property_blob_put(dm_plane_state->blend_lut);
 #endif
 
 	if (dm_plane_state->dc_state)
@@ -1513,6 +1517,17 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 					   dm->adev->mode_info.plane_lut3d_size_property,
 					   MAX_COLOR_3DLUT_ENTRIES);
 	}
+
+	if (dm->dc->caps.color.dpp.ogam_ram) {
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_blend_lut_property, 0);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_blend_lut_size_property,
+					   MAX_COLOR_LUT_ENTRIES);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_blend_tf_property,
+					   DRM_TRANSFER_FUNCTION_DEFAULT);
+	}
 }
 
 static int
@@ -1564,6 +1579,19 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 					&replaced);
 		dm_plane_state->base.color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == adev->mode_info.plane_blend_lut_property) {
+		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
+					&dm_plane_state->blend_lut,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		dm_plane_state->base.color_mgmt_changed |= replaced;
+		return ret;
+	} else if (property == adev->mode_info.plane_blend_tf_property) {
+		if (dm_plane_state->blend_tf != val) {
+			dm_plane_state->blend_tf = val;
+			dm_plane_state->base.color_mgmt_changed = 1;
+		}
 	} else {
 		drm_dbg_atomic(plane->dev,
 			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -1600,6 +1628,12 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 	} else 	if (property == adev->mode_info.plane_lut3d_property) {
 		*val = (dm_plane_state->lut3d) ?
 			dm_plane_state->lut3d->base.id : 0;
+	} else 	if (property == adev->mode_info.plane_blend_lut_property) {
+		*val = (dm_plane_state->blend_lut) ?
+			dm_plane_state->blend_lut->base.id : 0;
+	} else if (property == adev->mode_info.plane_blend_tf_property) {
+		*val = dm_plane_state->blend_tf;
+
 	} else {
 		return -EINVAL;
 	}
-- 
2.39.2


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

* [RFC PATCH 16/40] drm/amd/display: add plane blend LUT and TF driver-private properties
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Joshua Ashton <joshua@froggi.es>

Blend 1D LUT or a predefined transfer function can be set to linearize
content before blending, so that it's positioned just before blending
planes, and after 3D LUT (non-linear space). Shaper and Blend LUTs are
1D LUTs that sandwich 3D LUT. Drivers should advertize blend properties
according to HW caps.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 23 +++++++++++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      | 18 ++++++++++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++
 .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 34 +++++++++++++++++++
 4 files changed, 87 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 2bf8b19feae4..0bcf0bc6baff 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1369,6 +1369,29 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
 		return -ENOMEM;
 	adev->mode_info.plane_lut3d_size_property = prop;
 
+	prop = drm_property_create(adev_to_drm(adev),
+				   DRM_MODE_PROP_BLOB,
+				   "AMD_PLANE_BLEND_LUT", 0);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_blend_lut_property = prop;
+
+	prop = drm_property_create_range(adev_to_drm(adev),
+					 DRM_MODE_PROP_IMMUTABLE,
+					 "AMD_PLANE_BLEND_LUT_SIZE", 0, UINT_MAX);
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_blend_lut_size_property = prop;
+
+	prop = drm_property_create_enum(adev_to_drm(adev),
+					DRM_MODE_PROP_ENUM,
+					"AMD_PLANE_BLEND_TF",
+					drm_transfer_function_enum_list,
+					ARRAY_SIZE(drm_transfer_function_enum_list));
+	if (!prop)
+		return -ENOMEM;
+	adev->mode_info.plane_blend_tf_property = prop;
+
 	return 0;
 }
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
index 17c7669ad9ab..f640dbd53b8c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
@@ -417,6 +417,24 @@ struct amdgpu_mode_info {
 	 * size of 3D LUT as supported by the driver (read-only).
 	 */
 	struct drm_property *plane_lut3d_size_property;
+	/**
+	 * @plane_blend_lut_property: Plane property for output gamma before
+	 * blending. Userspace set a blend LUT to convert colors after 3D LUT
+	 * conversion. It works as a post-3D LUT 1D LUT, with shaper LUT, they
+	 * are sandwiching 3D LUT with two 1D LUT.
+	 */
+	struct drm_property *plane_blend_lut_property;
+	/**
+	 * @plane_blend_lut_size_property: Plane property to define the max
+	 * size of blend LUT as supported by the driver (read-only).
+	 */
+	struct drm_property *plane_blend_lut_size_property;
+	/**
+	 * @plane_blend_tf_property: Plane property to set a predefined
+	 * transfer function for pre-blending blend (before applying 3D LUT)
+	 * with or without LUT.
+	 */
+	struct drm_property *plane_blend_tf_property;
 #endif
 };
 
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 8a425e7a7e89..54121c3fa040 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -764,6 +764,18 @@ struct dm_plane_state {
 	 * &struct drm_color_lut.
 	 */
 	struct drm_property_blob *lut3d;
+	/**
+	 * @blend_lut: blend lut lookup table blob. The blob (if not NULL) is an
+	 * array of &struct drm_color_lut.
+	 */
+	struct drm_property_blob *blend_lut;
+	/**
+	 * @blend_tf:
+	 *
+	 * Pre-defined transfer function for converting plane pixel data before
+	 * applying blend LUT.
+	 */
+	enum drm_transfer_function blend_tf;
 #endif
 };
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index e4f28fbf6613..cdbd11f3be20 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1325,6 +1325,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
 		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
 		amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
 		amdgpu_state->shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+		amdgpu_state->blend_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
 	}
 #endif
 }
@@ -1352,6 +1353,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane)
 		drm_property_blob_get(dm_plane_state->shaper_lut);
 	if (dm_plane_state->lut3d)
 		drm_property_blob_get(dm_plane_state->lut3d);
+	if (dm_plane_state->blend_lut)
+		drm_property_blob_get(dm_plane_state->blend_lut);
 #endif
 
 	return &dm_plane_state->base;
@@ -1424,6 +1427,7 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
 	drm_property_blob_put(dm_plane_state->degamma_lut);
 	drm_property_blob_put(dm_plane_state->shaper_lut);
 	drm_property_blob_put(dm_plane_state->lut3d);
+	drm_property_blob_put(dm_plane_state->blend_lut);
 #endif
 
 	if (dm_plane_state->dc_state)
@@ -1513,6 +1517,17 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
 					   dm->adev->mode_info.plane_lut3d_size_property,
 					   MAX_COLOR_3DLUT_ENTRIES);
 	}
+
+	if (dm->dc->caps.color.dpp.ogam_ram) {
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_blend_lut_property, 0);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_blend_lut_size_property,
+					   MAX_COLOR_LUT_ENTRIES);
+		drm_object_attach_property(&plane->base,
+					   dm->adev->mode_info.plane_blend_tf_property,
+					   DRM_TRANSFER_FUNCTION_DEFAULT);
+	}
 }
 
 static int
@@ -1564,6 +1579,19 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
 					&replaced);
 		dm_plane_state->base.color_mgmt_changed |= replaced;
 		return ret;
+	} else if (property == adev->mode_info.plane_blend_lut_property) {
+		ret = amdgpu_dm_replace_property_blob_from_id(plane->dev,
+					&dm_plane_state->blend_lut,
+					val,
+					-1, sizeof(struct drm_color_lut),
+					&replaced);
+		dm_plane_state->base.color_mgmt_changed |= replaced;
+		return ret;
+	} else if (property == adev->mode_info.plane_blend_tf_property) {
+		if (dm_plane_state->blend_tf != val) {
+			dm_plane_state->blend_tf = val;
+			dm_plane_state->base.color_mgmt_changed = 1;
+		}
 	} else {
 		drm_dbg_atomic(plane->dev,
 			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -1600,6 +1628,12 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
 	} else 	if (property == adev->mode_info.plane_lut3d_property) {
 		*val = (dm_plane_state->lut3d) ?
 			dm_plane_state->lut3d->base.id : 0;
+	} else 	if (property == adev->mode_info.plane_blend_lut_property) {
+		*val = (dm_plane_state->blend_lut) ?
+			dm_plane_state->blend_lut->base.id : 0;
+	} else if (property == adev->mode_info.plane_blend_tf_property) {
+		*val = dm_plane_state->blend_tf;
+
 	} else {
 		return -EINVAL;
 	}
-- 
2.39.2


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

* [RFC PATCH 17/40] drm/amd/display: add comments to describe DM crtc color mgmt behavior
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

Describe some expected behavior of the AMD DM color mgmt programming.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a4cb23d059bd..fe779d10834e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -440,12 +440,23 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
 		stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
 
+		/* Note: although we pass has_rom as parameter here, we never
+		 * actually use ROM because the color module only takes the ROM
+		 * path if transfer_func->type == PREDEFINED.
+		 *
+		 * See more in mod_color_calculate_regamma_params()
+		 */
 		r = __set_legacy_tf(stream->out_transfer_func, regamma_lut,
 				    regamma_size, has_rom);
 		if (r)
 			return r;
 	} else if (has_regamma) {
-		/* If atomic regamma, CRTC RGM goes into RGM LUT. */
+		/* CRTC RGM goes into RGM LUT.
+		 *
+		 * Note: there is no implicit sRGB regamma here. We are using
+		 * degamma calculation from color module to calculate the curve
+		 * from a linear base.
+		 */
 		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
 		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 
-- 
2.39.2


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

* [RFC PATCH 17/40] drm/amd/display: add comments to describe DM crtc color mgmt behavior
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

Describe some expected behavior of the AMD DM color mgmt programming.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a4cb23d059bd..fe779d10834e 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -440,12 +440,23 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
 		stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
 
+		/* Note: although we pass has_rom as parameter here, we never
+		 * actually use ROM because the color module only takes the ROM
+		 * path if transfer_func->type == PREDEFINED.
+		 *
+		 * See more in mod_color_calculate_regamma_params()
+		 */
 		r = __set_legacy_tf(stream->out_transfer_func, regamma_lut,
 				    regamma_size, has_rom);
 		if (r)
 			return r;
 	} else if (has_regamma) {
-		/* If atomic regamma, CRTC RGM goes into RGM LUT. */
+		/* CRTC RGM goes into RGM LUT.
+		 *
+		 * Note: there is no implicit sRGB regamma here. We are using
+		 * degamma calculation from color module to calculate the curve
+		 * from a linear base.
+		 */
 		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
 		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 
-- 
2.39.2


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

* [RFC PATCH 18/40] drm/amd/display: encapsulate atomic regamma operation
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

We are introducing DRM 3D LUT property to DM color pipeline in the next
patch, but so far, only for atomic interface. By checking
set_output_transfer_func in DC drivers with MPC 3D LUT support, we can
verify that regamma is only programmed when 3D LUT programming fails. As
a groundwork to introduce 3D LUT programming and better understand each
step, detach atomic regamma programming from the crtc colocr updating
code.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 52 ++++++++++++-------
 1 file changed, 33 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index fe779d10834e..f1885e9c614d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -303,6 +303,35 @@ static int __set_output_tf(struct dc_transfer_func *func,
 	return res ? 0 : -ENOMEM;
 }
 
+static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
+					const struct drm_color_lut *regamma_lut,
+					uint32_t regamma_size, bool has_rom)
+{
+	int ret = 0;
+	if (regamma_size) {
+		/* CRTC RGM goes into RGM LUT.
+		 *
+		 * Note: there is no implicit sRGB regamma here. We are using
+		 * degamma calculation from color module to calculate the curve
+		 * from a linear base.
+		 */
+		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
+		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+
+		ret = __set_output_tf(stream->out_transfer_func,
+				      regamma_lut, regamma_size, has_rom);
+	} else {
+		/*
+		 * No CRTC RGM means we can just put the block into bypass
+		 * since we don't have any plane level adjustments using it.
+		 */
+		stream->out_transfer_func->type = TF_TYPE_BYPASS;
+		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+	}
+
+	return ret;
+}
+
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
@@ -450,27 +479,12 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 				    regamma_size, has_rom);
 		if (r)
 			return r;
-	} else if (has_regamma) {
-		/* CRTC RGM goes into RGM LUT.
-		 *
-		 * Note: there is no implicit sRGB regamma here. We are using
-		 * degamma calculation from color module to calculate the curve
-		 * from a linear base.
-		 */
-		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
-		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
-
-		r = __set_output_tf(stream->out_transfer_func, regamma_lut,
-				    regamma_size, has_rom);
+	} else {
+		regamma_size = has_regamma ? regamma_size : 0;
+		r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut,
+						 regamma_size, has_rom);
 		if (r)
 			return r;
-	} else {
-		/*
-		 * No CRTC RGM means we can just put the block into bypass
-		 * since we don't have any plane level adjustments using it.
-		 */
-		stream->out_transfer_func->type = TF_TYPE_BYPASS;
-		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 	}
 
 	/*
-- 
2.39.2


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

* [RFC PATCH 18/40] drm/amd/display: encapsulate atomic regamma operation
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

We are introducing DRM 3D LUT property to DM color pipeline in the next
patch, but so far, only for atomic interface. By checking
set_output_transfer_func in DC drivers with MPC 3D LUT support, we can
verify that regamma is only programmed when 3D LUT programming fails. As
a groundwork to introduce 3D LUT programming and better understand each
step, detach atomic regamma programming from the crtc colocr updating
code.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 52 ++++++++++++-------
 1 file changed, 33 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index fe779d10834e..f1885e9c614d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -303,6 +303,35 @@ static int __set_output_tf(struct dc_transfer_func *func,
 	return res ? 0 : -ENOMEM;
 }
 
+static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
+					const struct drm_color_lut *regamma_lut,
+					uint32_t regamma_size, bool has_rom)
+{
+	int ret = 0;
+	if (regamma_size) {
+		/* CRTC RGM goes into RGM LUT.
+		 *
+		 * Note: there is no implicit sRGB regamma here. We are using
+		 * degamma calculation from color module to calculate the curve
+		 * from a linear base.
+		 */
+		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
+		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+
+		ret = __set_output_tf(stream->out_transfer_func,
+				      regamma_lut, regamma_size, has_rom);
+	} else {
+		/*
+		 * No CRTC RGM means we can just put the block into bypass
+		 * since we don't have any plane level adjustments using it.
+		 */
+		stream->out_transfer_func->type = TF_TYPE_BYPASS;
+		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+	}
+
+	return ret;
+}
+
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
@@ -450,27 +479,12 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 				    regamma_size, has_rom);
 		if (r)
 			return r;
-	} else if (has_regamma) {
-		/* CRTC RGM goes into RGM LUT.
-		 *
-		 * Note: there is no implicit sRGB regamma here. We are using
-		 * degamma calculation from color module to calculate the curve
-		 * from a linear base.
-		 */
-		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
-		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
-
-		r = __set_output_tf(stream->out_transfer_func, regamma_lut,
-				    regamma_size, has_rom);
+	} else {
+		regamma_size = has_regamma ? regamma_size : 0;
+		r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut,
+						 regamma_size, has_rom);
 		if (r)
 			return r;
-	} else {
-		/*
-		 * No CRTC RGM means we can just put the block into bypass
-		 * since we don't have any plane level adjustments using it.
-		 */
-		stream->out_transfer_func->type = TF_TYPE_BYPASS;
-		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 	}
 
 	/*
-- 
2.39.2


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

* [RFC PATCH 19/40] drm/amd/display: update lut3d and shaper lut to stream
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

It follows the same path of out_transfer_func for stream updates, since
shaper LUT and 3D LUT is programmed in funcs.set_output_transfer_func()
and this function is called in the atomic commit_tail when
update_flags.bits.out_tf is set.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index e65ba87ee2c5..9230c122d77e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2581,7 +2581,7 @@ static enum surface_update_type check_update_surfaces_for_stream(
 			stream_update->integer_scaling_update)
 			su_flags->bits.scaling = 1;
 
-		if (stream_update->out_transfer_func)
+		if (stream_update->out_transfer_func || stream_update->lut3d_func)
 			su_flags->bits.out_tf = 1;
 
 		if (stream_update->abm_level)
@@ -2936,6 +2936,14 @@ static void copy_stream_update_to_stream(struct dc *dc,
 		       sizeof(struct dc_transfer_func_distributed_points));
 	}
 
+	if (update->func_shaper &&
+	    stream->func_shaper != update->func_shaper)
+		stream->func_shaper = update->func_shaper;
+
+	if (update->lut3d_func &&
+	    stream->lut3d_func != update->lut3d_func)
+		stream->lut3d_func = update->lut3d_func;
+
 	if (update->hdr_static_metadata)
 		stream->hdr_static_metadata = *update->hdr_static_metadata;
 
-- 
2.39.2


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

* [RFC PATCH 19/40] drm/amd/display: update lut3d and shaper lut to stream
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

It follows the same path of out_transfer_func for stream updates, since
shaper LUT and 3D LUT is programmed in funcs.set_output_transfer_func()
and this function is called in the atomic commit_tail when
update_flags.bits.out_tf is set.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index e65ba87ee2c5..9230c122d77e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2581,7 +2581,7 @@ static enum surface_update_type check_update_surfaces_for_stream(
 			stream_update->integer_scaling_update)
 			su_flags->bits.scaling = 1;
 
-		if (stream_update->out_transfer_func)
+		if (stream_update->out_transfer_func || stream_update->lut3d_func)
 			su_flags->bits.out_tf = 1;
 
 		if (stream_update->abm_level)
@@ -2936,6 +2936,14 @@ static void copy_stream_update_to_stream(struct dc *dc,
 		       sizeof(struct dc_transfer_func_distributed_points));
 	}
 
+	if (update->func_shaper &&
+	    stream->func_shaper != update->func_shaper)
+		stream->func_shaper = update->func_shaper;
+
+	if (update->lut3d_func &&
+	    stream->lut3d_func != update->lut3d_func)
+		stream->lut3d_func = update->lut3d_func;
+
 	if (update->hdr_static_metadata)
 		stream->hdr_static_metadata = *update->hdr_static_metadata;
 
-- 
2.39.2


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

* [RFC PATCH 20/40] drm/amd/display: copy 3D LUT settings from crtc state to stream_update
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

When commiting planes, we copy color mgmt resources to the stream state.
Do the same for shaper and 3D LUTs.

Co-developed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++++
 1 file changed, 4 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 76a776fd8437..729e37fa1873 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8190,6 +8190,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 				&acrtc_state->stream->csc_color_matrix;
 			bundle->stream_update.out_transfer_func =
 				acrtc_state->stream->out_transfer_func;
+			bundle->stream_update.lut3d_func =
+				(struct dc_3dlut *) acrtc_state->stream->lut3d_func;
+			bundle->stream_update.func_shaper =
+				(struct dc_transfer_func *) acrtc_state->stream->func_shaper;
 		}
 
 		acrtc_state->stream->abm_level = acrtc_state->abm_level;
-- 
2.39.2


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

* [RFC PATCH 20/40] drm/amd/display: copy 3D LUT settings from crtc state to stream_update
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

From: Joshua Ashton <joshua@froggi.es>

When commiting planes, we copy color mgmt resources to the stream state.
Do the same for shaper and 3D LUTs.

Co-developed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++++
 1 file changed, 4 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 76a776fd8437..729e37fa1873 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8190,6 +8190,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 				&acrtc_state->stream->csc_color_matrix;
 			bundle->stream_update.out_transfer_func =
 				acrtc_state->stream->out_transfer_func;
+			bundle->stream_update.lut3d_func =
+				(struct dc_3dlut *) acrtc_state->stream->lut3d_func;
+			bundle->stream_update.func_shaper =
+				(struct dc_transfer_func *) acrtc_state->stream->func_shaper;
 		}
 
 		acrtc_state->stream->abm_level = acrtc_state->abm_level;
-- 
2.39.2


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

* [RFC PATCH 21/40] drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

HW allows us to program shaper LUT without 3D LUT settings and it is
also good for testing shaper LUT behavior, therefore, DC driver should
allow acquiring both 3D and shaper LUT, but programing shaper LUT
without 3D LUT (not initialized).

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index 3303c9aae068..bacb0a001d68 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -113,7 +113,6 @@ static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx,
 	}
 
 	if (stream->lut3d_func &&
-	    stream->lut3d_func->state.bits.initialized == 1 &&
 	    stream->lut3d_func->state.bits.rmu_idx_valid == 1) {
 		if (stream->lut3d_func->state.bits.rmu_mux_num == 0)
 			mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu0_mux;
@@ -131,8 +130,12 @@ static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx,
 		if (acquired_rmu != stream->lut3d_func->state.bits.rmu_mux_num)
 			BREAK_TO_DEBUGGER();
 
-		result = mpc->funcs->program_3dlut(mpc, &stream->lut3d_func->lut_3d,
-						   stream->lut3d_func->state.bits.rmu_mux_num);
+		if (stream->lut3d_func->state.bits.initialized == 1)
+			result = mpc->funcs->program_3dlut(mpc, &stream->lut3d_func->lut_3d,
+							   stream->lut3d_func->state.bits.rmu_mux_num);
+		else
+			result = mpc->funcs->program_3dlut(mpc, NULL,
+							   stream->lut3d_func->state.bits.rmu_mux_num);
 		result = mpc->funcs->program_shaper(mpc, shaper_lut,
 						    stream->lut3d_func->state.bits.rmu_mux_num);
 	} else {
-- 
2.39.2


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

* [RFC PATCH 21/40] drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

HW allows us to program shaper LUT without 3D LUT settings and it is
also good for testing shaper LUT behavior, therefore, DC driver should
allow acquiring both 3D and shaper LUT, but programing shaper LUT
without 3D LUT (not initialized).

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
index 3303c9aae068..bacb0a001d68 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c
@@ -113,7 +113,6 @@ static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx,
 	}
 
 	if (stream->lut3d_func &&
-	    stream->lut3d_func->state.bits.initialized == 1 &&
 	    stream->lut3d_func->state.bits.rmu_idx_valid == 1) {
 		if (stream->lut3d_func->state.bits.rmu_mux_num == 0)
 			mpcc_id_projected = stream->lut3d_func->state.bits.mpc_rmu0_mux;
@@ -131,8 +130,12 @@ static bool dcn30_set_mpc_shaper_3dlut(struct pipe_ctx *pipe_ctx,
 		if (acquired_rmu != stream->lut3d_func->state.bits.rmu_mux_num)
 			BREAK_TO_DEBUGGER();
 
-		result = mpc->funcs->program_3dlut(mpc, &stream->lut3d_func->lut_3d,
-						   stream->lut3d_func->state.bits.rmu_mux_num);
+		if (stream->lut3d_func->state.bits.initialized == 1)
+			result = mpc->funcs->program_3dlut(mpc, &stream->lut3d_func->lut_3d,
+							   stream->lut3d_func->state.bits.rmu_mux_num);
+		else
+			result = mpc->funcs->program_3dlut(mpc, NULL,
+							   stream->lut3d_func->state.bits.rmu_mux_num);
 		result = mpc->funcs->program_shaper(mpc, shaper_lut,
 						    stream->lut3d_func->state.bits.rmu_mux_num);
 	} else {
-- 
2.39.2


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

* [RFC PATCH 22/40] drm/amd/display: handle MPC 3D LUT resources for a given context
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

In the original dc_acquire_release_mpc_3dlut(), only current ctx is
considered, which doesn't fit the steps for atomic checking new ctx.
Therefore, create a function to handle 3D LUT resource for a given
context, so that we can check resources availability in atomic_check
time and handle failures properly.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 39 ++++++++++++++++++++++++
 drivers/gpu/drm/amd/display/dc/dc.h      |  8 +++++
 2 files changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 9230c122d77e..ee3fe4eae22e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2101,6 +2101,45 @@ bool dc_acquire_release_mpc_3dlut(
 	return ret;
 }
 
+bool
+dc_acquire_release_mpc_3dlut_for_ctx(struct dc *dc,
+				     bool acquire,
+				     struct dc_state *state,
+				     struct dc_stream_state *stream,
+				     struct dc_3dlut **lut,
+				     struct dc_transfer_func **shaper)
+{
+	int pipe_idx;
+	bool ret = false;
+	bool found_pipe_idx = false;
+	const struct resource_pool *pool = dc->res_pool;
+	struct resource_context *res_ctx = &state->res_ctx;
+	int mpcc_id = 0;
+
+	if (pool && res_ctx) {
+		if (acquire) {
+			/*find pipe idx for the given stream*/
+			for (pipe_idx = 0; pipe_idx < pool->pipe_count; pipe_idx++) {
+				if (res_ctx->pipe_ctx[pipe_idx].stream == stream) {
+					found_pipe_idx = true;
+					mpcc_id = res_ctx->pipe_ctx[pipe_idx].plane_res.hubp->inst;
+					break;
+				}
+			}
+		} else
+			found_pipe_idx = true;/*for release pipe_idx is not required*/
+
+		if (found_pipe_idx) {
+			if (acquire && pool->funcs->acquire_post_bldn_3dlut)
+				ret = pool->funcs->acquire_post_bldn_3dlut(res_ctx, pool, mpcc_id, lut, shaper);
+			else if (!acquire && pool->funcs->release_post_bldn_3dlut)
+				ret = pool->funcs->release_post_bldn_3dlut(res_ctx, pool, lut, shaper);
+		}
+	}
+	return ret;
+}
+
+
 static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
 {
 	int i;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index b45974a2dec3..7fdb0bbb2df9 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1350,6 +1350,14 @@ bool dc_acquire_release_mpc_3dlut(
 		struct dc_3dlut **lut,
 		struct dc_transfer_func **shaper);
 
+bool
+dc_acquire_release_mpc_3dlut_for_ctx(struct dc *dc,
+				     bool acquire,
+				     struct dc_state *state,
+				     struct dc_stream_state *stream,
+				     struct dc_3dlut **lut,
+				     struct dc_transfer_func **shaper);
+
 void dc_resource_state_copy_construct(
 		const struct dc_state *src_ctx,
 		struct dc_state *dst_ctx);
-- 
2.39.2


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

* [RFC PATCH 22/40] drm/amd/display: handle MPC 3D LUT resources for a given context
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

In the original dc_acquire_release_mpc_3dlut(), only current ctx is
considered, which doesn't fit the steps for atomic checking new ctx.
Therefore, create a function to handle 3D LUT resource for a given
context, so that we can check resources availability in atomic_check
time and handle failures properly.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c | 39 ++++++++++++++++++++++++
 drivers/gpu/drm/amd/display/dc/dc.h      |  8 +++++
 2 files changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 9230c122d77e..ee3fe4eae22e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2101,6 +2101,45 @@ bool dc_acquire_release_mpc_3dlut(
 	return ret;
 }
 
+bool
+dc_acquire_release_mpc_3dlut_for_ctx(struct dc *dc,
+				     bool acquire,
+				     struct dc_state *state,
+				     struct dc_stream_state *stream,
+				     struct dc_3dlut **lut,
+				     struct dc_transfer_func **shaper)
+{
+	int pipe_idx;
+	bool ret = false;
+	bool found_pipe_idx = false;
+	const struct resource_pool *pool = dc->res_pool;
+	struct resource_context *res_ctx = &state->res_ctx;
+	int mpcc_id = 0;
+
+	if (pool && res_ctx) {
+		if (acquire) {
+			/*find pipe idx for the given stream*/
+			for (pipe_idx = 0; pipe_idx < pool->pipe_count; pipe_idx++) {
+				if (res_ctx->pipe_ctx[pipe_idx].stream == stream) {
+					found_pipe_idx = true;
+					mpcc_id = res_ctx->pipe_ctx[pipe_idx].plane_res.hubp->inst;
+					break;
+				}
+			}
+		} else
+			found_pipe_idx = true;/*for release pipe_idx is not required*/
+
+		if (found_pipe_idx) {
+			if (acquire && pool->funcs->acquire_post_bldn_3dlut)
+				ret = pool->funcs->acquire_post_bldn_3dlut(res_ctx, pool, mpcc_id, lut, shaper);
+			else if (!acquire && pool->funcs->release_post_bldn_3dlut)
+				ret = pool->funcs->release_post_bldn_3dlut(res_ctx, pool, lut, shaper);
+		}
+	}
+	return ret;
+}
+
+
 static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context)
 {
 	int i;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index b45974a2dec3..7fdb0bbb2df9 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -1350,6 +1350,14 @@ bool dc_acquire_release_mpc_3dlut(
 		struct dc_3dlut **lut,
 		struct dc_transfer_func **shaper);
 
+bool
+dc_acquire_release_mpc_3dlut_for_ctx(struct dc *dc,
+				     bool acquire,
+				     struct dc_state *state,
+				     struct dc_stream_state *stream,
+				     struct dc_3dlut **lut,
+				     struct dc_transfer_func **shaper);
+
 void dc_resource_state_copy_construct(
 		const struct dc_state *src_ctx,
 		struct dc_state *dst_ctx);
-- 
2.39.2


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

* [RFC PATCH 23/40] drm/amd/display: dynamically acquire 3DLUT resources for color changes
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

dc_acquire_release_mpc_3dlut_for_ctx initializes the bits required to
program 3DLUT in DC MPC hw block, applied in set_output_transfer_func().
Since acquire/release can fail, we should check resources availability
during atomic check considering the new context created. We dynamically
acquire 3D LUT resources when we actually use them, so we don't limit
ourselves with the stream count.

Co-developed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  7 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  3 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 55 ++++++++++++++++++-
 .../amd/display/dc/dcn301/dcn301_resource.c   | 26 ++++++++-
 4 files changed, 87 insertions(+), 4 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 729e37fa1873..6b40e17892e5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9380,7 +9380,12 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
 	 */
 	if (dm_new_crtc_state->base.color_mgmt_changed ||
 	    drm_atomic_crtc_needs_modeset(new_crtc_state)) {
-		ret = amdgpu_dm_update_crtc_color_mgmt(dm_new_crtc_state);
+		if (!dm_state) {
+			ret = dm_atomic_get_state(state, &dm_state);
+			if (ret)
+				goto fail;
+		}
+		ret = amdgpu_dm_update_crtc_color_mgmt(dm_new_crtc_state, dm_state->context);
 		if (ret)
 			goto fail;
 	}
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 54121c3fa040..5faf4fc87701 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -904,7 +904,8 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
 void amdgpu_dm_init_color_mod(void);
 int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
-int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
+int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
+				     struct dc_state *ctx);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 				      struct dc_plane_state *dc_plane_state);
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index f1885e9c614d..99b1738c98d3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -332,6 +332,49 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 	return ret;
 }
 
+/* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
+ * interface
+ * @dc: Display Core control structure
+ * @ctx: <add desc>
+ * @stream: DC stream state to set shaper LUT and 3D LUT
+ * @drm_shaper_lut: DRM CRTC (user) shaper LUT
+ * @drm_shaper_size: size of shaper LUT
+ * @drm_lut3d: DRM CRTC (user) 3D LUT
+ * @drm_lut3d_size: size of 3D LUT
+ *
+ * Returns:
+ * 0 on success.
+ */
+static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
+					 struct dc_state *ctx,
+					 struct dc_stream_state *stream,
+					 const struct drm_color_lut *drm_shaper_lut,
+					 uint32_t drm_shaper_size,
+					 const struct drm_color_lut *drm_lut3d,
+					 uint32_t drm_lut3d_size)
+{
+	struct dc_3dlut *lut3d_func;
+	struct dc_transfer_func *func_shaper;
+	bool acquire = drm_shaper_size && drm_lut3d_size;
+
+	lut3d_func = (struct dc_3dlut *)stream->lut3d_func;
+	func_shaper = (struct dc_transfer_func *)stream->func_shaper;
+
+	ASSERT((lut3d_func && func_shaper) || (!lut3d_func && !func_shaper));
+	if ((acquire && !lut3d_func && !func_shaper) ||
+	    (!acquire && lut3d_func && func_shaper))
+	{
+		if (!dc_acquire_release_mpc_3dlut_for_ctx(dc, acquire, ctx, stream,
+							  &lut3d_func, &func_shaper))
+			return DC_ERROR_UNEXPECTED;
+	}
+
+	stream->lut3d_func = lut3d_func;
+	stream->func_shaper = func_shaper;
+
+	return 0;
+}
+
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
@@ -402,6 +445,7 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
 /**
  * amdgpu_dm_update_crtc_color_mgmt: Maps DRM color management to DC stream.
  * @crtc: amdgpu_dm crtc state
+ * @ctx: <add desc>
  *
  * With no plane level color management properties we're free to use any
  * of the HW blocks as long as the CRTC CTM always comes before the
@@ -421,7 +465,8 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
  * Returns:
  * 0 on success. Error code if setup fails.
  */
-int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
+int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
+				     struct dc_state *ctx)
 {
 	struct dc_stream_state *stream = crtc->stream;
 	struct amdgpu_device *adev = drm_to_adev(crtc->base.state->dev);
@@ -480,6 +525,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 		if (r)
 			return r;
 	} else {
+		r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream,
+						  NULL, 0, NULL, 0);
+		if (r)
+			return r;
+		/* Note: OGAM is disabled if 3D LUT is successfully programmed.
+		 * See params and set_output_gamma in
+		 * dcn30_set_output_transfer_func()
+		 */
 		regamma_size = has_regamma ? regamma_size : 0;
 		r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut,
 						 regamma_size, has_rom);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
index 5ac2a272c380..a6d6fcaaca1c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
@@ -1258,6 +1258,30 @@ static struct display_stream_compressor *dcn301_dsc_create(
 	return &dsc->base;
 }
 
+static enum dc_status
+dcn301_remove_stream_from_ctx(struct dc *dc,
+			      struct dc_state *new_ctx,
+			      struct dc_stream_state *dc_stream)
+{
+	struct dc_3dlut *lut3d_func;
+	struct dc_transfer_func *func_shaper;
+
+	lut3d_func = (struct dc_3dlut *)dc_stream->lut3d_func;
+	func_shaper = (struct dc_transfer_func *)dc_stream->func_shaper;
+
+	ASSERT((lut3d_func && func_shaper) || (!lut3d_func && !func_shaper));
+	if (lut3d_func && func_shaper)
+	{
+		if (!dc_acquire_release_mpc_3dlut_for_ctx(dc, false, new_ctx, dc_stream,
+							&lut3d_func, &func_shaper))
+			return DC_ERROR_UNEXPECTED;
+	}
+
+	dc_stream->lut3d_func = lut3d_func;
+	dc_stream->func_shaper = func_shaper;
+
+	return dcn20_remove_stream_from_ctx(dc, new_ctx, dc_stream);
+}
 
 static void dcn301_destroy_resource_pool(struct resource_pool **pool)
 {
@@ -1406,7 +1430,7 @@ static struct resource_funcs dcn301_res_pool_funcs = {
 	.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
 	.add_stream_to_ctx = dcn30_add_stream_to_ctx,
 	.add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
-	.remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
+	.remove_stream_from_ctx = dcn301_remove_stream_from_ctx,
 	.populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context,
 	.set_mcif_arb_params = dcn30_set_mcif_arb_params,
 	.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
-- 
2.39.2


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

* [RFC PATCH 23/40] drm/amd/display: dynamically acquire 3DLUT resources for color changes
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

From: Joshua Ashton <joshua@froggi.es>

dc_acquire_release_mpc_3dlut_for_ctx initializes the bits required to
program 3DLUT in DC MPC hw block, applied in set_output_transfer_func().
Since acquire/release can fail, we should check resources availability
during atomic check considering the new context created. We dynamically
acquire 3D LUT resources when we actually use them, so we don't limit
ourselves with the stream count.

Co-developed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  7 ++-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  3 +-
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 55 ++++++++++++++++++-
 .../amd/display/dc/dcn301/dcn301_resource.c   | 26 ++++++++-
 4 files changed, 87 insertions(+), 4 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 729e37fa1873..6b40e17892e5 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9380,7 +9380,12 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm,
 	 */
 	if (dm_new_crtc_state->base.color_mgmt_changed ||
 	    drm_atomic_crtc_needs_modeset(new_crtc_state)) {
-		ret = amdgpu_dm_update_crtc_color_mgmt(dm_new_crtc_state);
+		if (!dm_state) {
+			ret = dm_atomic_get_state(state, &dm_state);
+			if (ret)
+				goto fail;
+		}
+		ret = amdgpu_dm_update_crtc_color_mgmt(dm_new_crtc_state, dm_state->context);
 		if (ret)
 			goto fail;
 	}
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 54121c3fa040..5faf4fc87701 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -904,7 +904,8 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
 void amdgpu_dm_init_color_mod(void);
 int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
-int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
+int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
+				     struct dc_state *ctx);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 				      struct dc_plane_state *dc_plane_state);
 
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index f1885e9c614d..99b1738c98d3 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -332,6 +332,49 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 	return ret;
 }
 
+/* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
+ * interface
+ * @dc: Display Core control structure
+ * @ctx: <add desc>
+ * @stream: DC stream state to set shaper LUT and 3D LUT
+ * @drm_shaper_lut: DRM CRTC (user) shaper LUT
+ * @drm_shaper_size: size of shaper LUT
+ * @drm_lut3d: DRM CRTC (user) 3D LUT
+ * @drm_lut3d_size: size of 3D LUT
+ *
+ * Returns:
+ * 0 on success.
+ */
+static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
+					 struct dc_state *ctx,
+					 struct dc_stream_state *stream,
+					 const struct drm_color_lut *drm_shaper_lut,
+					 uint32_t drm_shaper_size,
+					 const struct drm_color_lut *drm_lut3d,
+					 uint32_t drm_lut3d_size)
+{
+	struct dc_3dlut *lut3d_func;
+	struct dc_transfer_func *func_shaper;
+	bool acquire = drm_shaper_size && drm_lut3d_size;
+
+	lut3d_func = (struct dc_3dlut *)stream->lut3d_func;
+	func_shaper = (struct dc_transfer_func *)stream->func_shaper;
+
+	ASSERT((lut3d_func && func_shaper) || (!lut3d_func && !func_shaper));
+	if ((acquire && !lut3d_func && !func_shaper) ||
+	    (!acquire && lut3d_func && func_shaper))
+	{
+		if (!dc_acquire_release_mpc_3dlut_for_ctx(dc, acquire, ctx, stream,
+							  &lut3d_func, &func_shaper))
+			return DC_ERROR_UNEXPECTED;
+	}
+
+	stream->lut3d_func = lut3d_func;
+	stream->func_shaper = func_shaper;
+
+	return 0;
+}
+
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
@@ -402,6 +445,7 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
 /**
  * amdgpu_dm_update_crtc_color_mgmt: Maps DRM color management to DC stream.
  * @crtc: amdgpu_dm crtc state
+ * @ctx: <add desc>
  *
  * With no plane level color management properties we're free to use any
  * of the HW blocks as long as the CRTC CTM always comes before the
@@ -421,7 +465,8 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
  * Returns:
  * 0 on success. Error code if setup fails.
  */
-int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
+int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
+				     struct dc_state *ctx)
 {
 	struct dc_stream_state *stream = crtc->stream;
 	struct amdgpu_device *adev = drm_to_adev(crtc->base.state->dev);
@@ -480,6 +525,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 		if (r)
 			return r;
 	} else {
+		r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream,
+						  NULL, 0, NULL, 0);
+		if (r)
+			return r;
+		/* Note: OGAM is disabled if 3D LUT is successfully programmed.
+		 * See params and set_output_gamma in
+		 * dcn30_set_output_transfer_func()
+		 */
 		regamma_size = has_regamma ? regamma_size : 0;
 		r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut,
 						 regamma_size, has_rom);
diff --git a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
index 5ac2a272c380..a6d6fcaaca1c 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_resource.c
@@ -1258,6 +1258,30 @@ static struct display_stream_compressor *dcn301_dsc_create(
 	return &dsc->base;
 }
 
+static enum dc_status
+dcn301_remove_stream_from_ctx(struct dc *dc,
+			      struct dc_state *new_ctx,
+			      struct dc_stream_state *dc_stream)
+{
+	struct dc_3dlut *lut3d_func;
+	struct dc_transfer_func *func_shaper;
+
+	lut3d_func = (struct dc_3dlut *)dc_stream->lut3d_func;
+	func_shaper = (struct dc_transfer_func *)dc_stream->func_shaper;
+
+	ASSERT((lut3d_func && func_shaper) || (!lut3d_func && !func_shaper));
+	if (lut3d_func && func_shaper)
+	{
+		if (!dc_acquire_release_mpc_3dlut_for_ctx(dc, false, new_ctx, dc_stream,
+							&lut3d_func, &func_shaper))
+			return DC_ERROR_UNEXPECTED;
+	}
+
+	dc_stream->lut3d_func = lut3d_func;
+	dc_stream->func_shaper = func_shaper;
+
+	return dcn20_remove_stream_from_ctx(dc, new_ctx, dc_stream);
+}
 
 static void dcn301_destroy_resource_pool(struct resource_pool **pool)
 {
@@ -1406,7 +1430,7 @@ static struct resource_funcs dcn301_res_pool_funcs = {
 	.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,
 	.add_stream_to_ctx = dcn30_add_stream_to_ctx,
 	.add_dsc_to_stream_resource = dcn20_add_dsc_to_stream_resource,
-	.remove_stream_from_ctx = dcn20_remove_stream_from_ctx,
+	.remove_stream_from_ctx = dcn301_remove_stream_from_ctx,
 	.populate_dml_writeback_from_context = dcn30_populate_dml_writeback_from_context,
 	.set_mcif_arb_params = dcn30_set_mcif_arb_params,
 	.find_first_free_match_stream_enc_for_link = dcn10_find_first_free_match_stream_enc_for_link,
-- 
2.39.2


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

* [RFC PATCH 24/40] drm/amd/display: add CRTC 3D LUT support to amd color pipeline
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

Map DRM CRTC 3D LUT in the atomic color mgmt pipeline to DC
(post-blending). 3D LUT works better in a non-linear color space,
therefore using a degamma to linearize the input space may produce
unexpected results. The next patch introduces shaper LUT support that
can be used to delinearize the color space before applying 3D LUT
conversion.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   8 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   5 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 185 +++++++++++++++---
 3 files changed, 174 insertions(+), 24 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 6b40e17892e5..760080e4a4da 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9945,7 +9945,13 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 			DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() failed\n");
 			goto fail;
 		}
-
+#ifdef CONFIG_STEAM_DECK
+		ret = amdgpu_dm_verify_lut3d_size(adev, new_crtc_state);
+		if (ret) {
+			DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() failed\n");
+			goto fail;
+		}
+#endif
 		if (!new_crtc_state->enable)
 			continue;
 
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 5faf4fc87701..b9840c1f3cdf 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -894,9 +894,14 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
 
 void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
+#ifdef CONFIG_STEAM_DECK
 /* 3D LUT max size is 17x17x17 */
 #define MAX_COLOR_3DLUT_ENTRIES 4913
 #define MAX_COLOR_3DLUT_BITDEPTH 12
+int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
+				const struct drm_crtc_state *crtc_state);
+#endif
+
 /* 1D LUT degamma, regamma and shaper*/
 #define MAX_COLOR_LUT_ENTRIES 4096
 /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 99b1738c98d3..25010fa19bc8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -332,6 +332,117 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 	return ret;
 }
 
+/**
+ * __set_input_tf - calculates the input transfer function based on expected
+ * input space.
+ * @func: transfer function
+ * @lut: lookup table that defines the color space
+ * @lut_size: size of respective lut.
+ *
+ * Returns:
+ * 0 in case of success. -ENOMEM if fails.
+ */
+static int __set_input_tf(struct dc_transfer_func *func,
+			  const struct drm_color_lut *lut, uint32_t lut_size)
+{
+	struct dc_gamma *gamma = NULL;
+	bool res;
+
+	gamma = dc_create_gamma();
+	if (!gamma)
+		return -ENOMEM;
+
+	gamma->type = GAMMA_CUSTOM;
+	gamma->num_entries = lut_size;
+
+	__drm_lut_to_dc_gamma(lut, gamma, false);
+
+	res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
+	dc_gamma_release(&gamma);
+
+	return res ? 0 : -ENOMEM;
+}
+
+#ifdef CONFIG_STEAM_DECK
+static void __to_dc_lut3d_color(struct dc_rgb *rgb,
+				const struct drm_color_lut lut,
+				int bit_precision)
+{
+	rgb->red = drm_color_lut_extract(lut.red, bit_precision);
+	rgb->green = drm_color_lut_extract(lut.green, bit_precision);
+	rgb->blue  = drm_color_lut_extract(lut.blue, bit_precision);
+}
+
+static void __drm_3dlut_to_dc_3dlut(const struct drm_color_lut *lut,
+				    uint32_t lut3d_size,
+				    struct tetrahedral_params *params,
+				    bool use_tetrahedral_9,
+				    int bit_depth)
+{
+	struct dc_rgb *lut0;
+	struct dc_rgb *lut1;
+	struct dc_rgb *lut2;
+	struct dc_rgb *lut3;
+	int lut_i, i;
+
+
+	if (use_tetrahedral_9) {
+		lut0 = params->tetrahedral_9.lut0;
+		lut1 = params->tetrahedral_9.lut1;
+		lut2 = params->tetrahedral_9.lut2;
+		lut3 = params->tetrahedral_9.lut3;
+	} else {
+		lut0 = params->tetrahedral_17.lut0;
+		lut1 = params->tetrahedral_17.lut1;
+		lut2 = params->tetrahedral_17.lut2;
+		lut3 = params->tetrahedral_17.lut3;
+	}
+
+	for (lut_i = 0, i = 0; i < lut3d_size - 4; lut_i++, i += 4) {
+		/* We should consider the 3dlut RGB values are distributed
+		 * along four arrays lut0-3 where the first sizes 1229 and the
+		 * other 1228. The bit depth supported for 3dlut channel is
+		 * 12-bit, but DC also supports 10-bit.
+		 *
+		 * TODO: improve color pipeline API to enable the userspace set
+		 * bit depth and 3D LUT size/stride, as specified by VA-API.
+		 */
+		__to_dc_lut3d_color(&lut0[lut_i], lut[i], bit_depth);
+		__to_dc_lut3d_color(&lut1[lut_i], lut[i + 1], bit_depth);
+		__to_dc_lut3d_color(&lut2[lut_i], lut[i + 2], bit_depth);
+		__to_dc_lut3d_color(&lut3[lut_i], lut[i + 3], bit_depth);
+	}
+	/* lut0 has 1229 points (lut_size/4 + 1) */
+	__to_dc_lut3d_color(&lut0[lut_i], lut[i], bit_depth);
+}
+
+/* amdgpu_dm_atomic_lut3d - set DRM 3D LUT to DC stream
+ * @drm_lut3d: DRM CRTC (user) 3D LUT
+ * @drm_lut3d_size: size of 3D LUT
+ * @lut3d: DC 3D LUT
+ *
+ * Map DRM CRTC 3D LUT to DC 3D LUT and all necessary bits to program it
+ * on DCN MPC accordingly.
+ */
+static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut,
+				   uint32_t drm_lut3d_size,
+				   struct dc_3dlut *lut)
+{
+	if (!drm_lut3d_size) {
+		lut->state.bits.initialized = 0;
+	} else {
+		/* Stride and bit depth are not programmable by API yet.
+		 * Therefore, only supports 17x17x17 3D LUT (12-bit).
+		 */
+		lut->lut_3d.use_tetrahedral_9 = false;
+		lut->lut_3d.use_12bits = true;
+		lut->state.bits.initialized = 1;
+		__drm_3dlut_to_dc_3dlut(drm_lut, drm_lut3d_size, &lut->lut_3d,
+					lut->lut_3d.use_tetrahedral_9,
+					MAX_COLOR_3DLUT_BITDEPTH);
+	}
+}
+
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
  * interface
  * @dc: Display Core control structure
@@ -355,7 +466,7 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 {
 	struct dc_3dlut *lut3d_func;
 	struct dc_transfer_func *func_shaper;
-	bool acquire = drm_shaper_size && drm_lut3d_size;
+	bool acquire = drm_shaper_size || drm_lut3d_size;
 
 	lut3d_func = (struct dc_3dlut *)stream->lut3d_func;
 	func_shaper = (struct dc_transfer_func *)stream->func_shaper;
@@ -369,42 +480,56 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 			return DC_ERROR_UNEXPECTED;
 	}
 
-	stream->lut3d_func = lut3d_func;
 	stream->func_shaper = func_shaper;
+	stream->lut3d_func = lut3d_func;
+
+	if (!acquire)
+		return 0;
+
+	/* We don't get DRM shaper LUT yet. We assume the input color
+	 * space is already delinearized, so we don't need a shaper LUT
+	 * and we can just BYPASS.
+	 */
+	func_shaper->type = TF_TYPE_BYPASS;
+	func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+	amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func);
 
 	return 0;
 }
 
 /**
- * __set_input_tf - calculates the input transfer function based on expected
- * input space.
- * @func: transfer function
- * @lut: lookup table that defines the color space
- * @lut_size: size of respective lut.
+ * amdgpu_dm_verify_lut3d_size - verifies if 3D LUT is supported and if DRM 3D
+ * LUT matches the hw supported size
+ * @adev: amdgpu device
+ * @crtc_state: the DRM CRTC state
+ *
+ * Verifies if post-blending (MPC) 3D LUT is supported by the HW (DCN 3.0 or
+ * newer) and if the DRM 3D LUT matches the supported size.
  *
  * Returns:
- * 0 in case of success. -ENOMEM if fails.
+ * 0 on success. -EINVAL if lut size are invalid.
  */
-static int __set_input_tf(struct dc_transfer_func *func,
-			  const struct drm_color_lut *lut, uint32_t lut_size)
+int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
+				const struct drm_crtc_state *crtc_state)
 {
-	struct dc_gamma *gamma = NULL;
-	bool res;
+	const struct drm_color_lut *lut3d = NULL;
+	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc_state);
+	uint32_t exp_size, size;
 
-	gamma = dc_create_gamma();
-	if (!gamma)
-		return -ENOMEM;
+	exp_size = adev->dm.dc->caps.color.mpc.num_3dluts ?
+		   MAX_COLOR_3DLUT_ENTRIES : 0;
 
-	gamma->type = GAMMA_CUSTOM;
-	gamma->num_entries = lut_size;
-
-	__drm_lut_to_dc_gamma(lut, gamma, false);
+	lut3d = __extract_blob_lut(acrtc_state->lut3d, &size);
 
-	res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
-	dc_gamma_release(&gamma);
+	if (lut3d && size != exp_size) {
+		DRM_DEBUG_DRIVER("Invalid Gamma 3D LUT size. Should be %u but got %u.\n",
+				 exp_size, size);
+		return -EINVAL;
+	}
 
-	return res ? 0 : -ENOMEM;
+	return 0;
 }
+#endif
 
 /**
  * amdgpu_dm_verify_lut_sizes - verifies if DRM luts match the hw supported sizes
@@ -477,6 +602,16 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 	bool has_regamma, has_degamma;
 	bool is_legacy;
 	int r;
+#ifdef CONFIG_STEAM_DECK
+	const struct drm_color_lut *lut3d;
+	uint32_t lut3d_size;
+
+	r =  amdgpu_dm_verify_lut3d_size(adev, &crtc->base);
+	if (r)
+		return r;
+
+	lut3d = __extract_blob_lut(crtc->lut3d, &lut3d_size);
+#endif
 
 	r = amdgpu_dm_verify_lut_sizes(&crtc->base);
 	if (r)
@@ -525,10 +660,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 		if (r)
 			return r;
 	} else {
+#ifdef CONFIG_STEAM_DECK
+		lut3d_size = lut3d != NULL ? lut3d_size : 0;
 		r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream,
-						  NULL, 0, NULL, 0);
+						  NULL, 0,
+						  lut3d, lut3d_size);
 		if (r)
 			return r;
+#endif
 		/* Note: OGAM is disabled if 3D LUT is successfully programmed.
 		 * See params and set_output_gamma in
 		 * dcn30_set_output_transfer_func()
-- 
2.39.2


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

* [RFC PATCH 24/40] drm/amd/display: add CRTC 3D LUT support to amd color pipeline
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

Map DRM CRTC 3D LUT in the atomic color mgmt pipeline to DC
(post-blending). 3D LUT works better in a non-linear color space,
therefore using a degamma to linearize the input space may produce
unexpected results. The next patch introduces shaper LUT support that
can be used to delinearize the color space before applying 3D LUT
conversion.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   8 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   5 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 185 +++++++++++++++---
 3 files changed, 174 insertions(+), 24 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 6b40e17892e5..760080e4a4da 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9945,7 +9945,13 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 			DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() failed\n");
 			goto fail;
 		}
-
+#ifdef CONFIG_STEAM_DECK
+		ret = amdgpu_dm_verify_lut3d_size(adev, new_crtc_state);
+		if (ret) {
+			DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() failed\n");
+			goto fail;
+		}
+#endif
 		if (!new_crtc_state->enable)
 			continue;
 
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 5faf4fc87701..b9840c1f3cdf 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -894,9 +894,14 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
 
 void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
 
+#ifdef CONFIG_STEAM_DECK
 /* 3D LUT max size is 17x17x17 */
 #define MAX_COLOR_3DLUT_ENTRIES 4913
 #define MAX_COLOR_3DLUT_BITDEPTH 12
+int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
+				const struct drm_crtc_state *crtc_state);
+#endif
+
 /* 1D LUT degamma, regamma and shaper*/
 #define MAX_COLOR_LUT_ENTRIES 4096
 /* Legacy gamm LUT users such as X doesn't like large LUT sizes */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 99b1738c98d3..25010fa19bc8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -332,6 +332,117 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 	return ret;
 }
 
+/**
+ * __set_input_tf - calculates the input transfer function based on expected
+ * input space.
+ * @func: transfer function
+ * @lut: lookup table that defines the color space
+ * @lut_size: size of respective lut.
+ *
+ * Returns:
+ * 0 in case of success. -ENOMEM if fails.
+ */
+static int __set_input_tf(struct dc_transfer_func *func,
+			  const struct drm_color_lut *lut, uint32_t lut_size)
+{
+	struct dc_gamma *gamma = NULL;
+	bool res;
+
+	gamma = dc_create_gamma();
+	if (!gamma)
+		return -ENOMEM;
+
+	gamma->type = GAMMA_CUSTOM;
+	gamma->num_entries = lut_size;
+
+	__drm_lut_to_dc_gamma(lut, gamma, false);
+
+	res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
+	dc_gamma_release(&gamma);
+
+	return res ? 0 : -ENOMEM;
+}
+
+#ifdef CONFIG_STEAM_DECK
+static void __to_dc_lut3d_color(struct dc_rgb *rgb,
+				const struct drm_color_lut lut,
+				int bit_precision)
+{
+	rgb->red = drm_color_lut_extract(lut.red, bit_precision);
+	rgb->green = drm_color_lut_extract(lut.green, bit_precision);
+	rgb->blue  = drm_color_lut_extract(lut.blue, bit_precision);
+}
+
+static void __drm_3dlut_to_dc_3dlut(const struct drm_color_lut *lut,
+				    uint32_t lut3d_size,
+				    struct tetrahedral_params *params,
+				    bool use_tetrahedral_9,
+				    int bit_depth)
+{
+	struct dc_rgb *lut0;
+	struct dc_rgb *lut1;
+	struct dc_rgb *lut2;
+	struct dc_rgb *lut3;
+	int lut_i, i;
+
+
+	if (use_tetrahedral_9) {
+		lut0 = params->tetrahedral_9.lut0;
+		lut1 = params->tetrahedral_9.lut1;
+		lut2 = params->tetrahedral_9.lut2;
+		lut3 = params->tetrahedral_9.lut3;
+	} else {
+		lut0 = params->tetrahedral_17.lut0;
+		lut1 = params->tetrahedral_17.lut1;
+		lut2 = params->tetrahedral_17.lut2;
+		lut3 = params->tetrahedral_17.lut3;
+	}
+
+	for (lut_i = 0, i = 0; i < lut3d_size - 4; lut_i++, i += 4) {
+		/* We should consider the 3dlut RGB values are distributed
+		 * along four arrays lut0-3 where the first sizes 1229 and the
+		 * other 1228. The bit depth supported for 3dlut channel is
+		 * 12-bit, but DC also supports 10-bit.
+		 *
+		 * TODO: improve color pipeline API to enable the userspace set
+		 * bit depth and 3D LUT size/stride, as specified by VA-API.
+		 */
+		__to_dc_lut3d_color(&lut0[lut_i], lut[i], bit_depth);
+		__to_dc_lut3d_color(&lut1[lut_i], lut[i + 1], bit_depth);
+		__to_dc_lut3d_color(&lut2[lut_i], lut[i + 2], bit_depth);
+		__to_dc_lut3d_color(&lut3[lut_i], lut[i + 3], bit_depth);
+	}
+	/* lut0 has 1229 points (lut_size/4 + 1) */
+	__to_dc_lut3d_color(&lut0[lut_i], lut[i], bit_depth);
+}
+
+/* amdgpu_dm_atomic_lut3d - set DRM 3D LUT to DC stream
+ * @drm_lut3d: DRM CRTC (user) 3D LUT
+ * @drm_lut3d_size: size of 3D LUT
+ * @lut3d: DC 3D LUT
+ *
+ * Map DRM CRTC 3D LUT to DC 3D LUT and all necessary bits to program it
+ * on DCN MPC accordingly.
+ */
+static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut,
+				   uint32_t drm_lut3d_size,
+				   struct dc_3dlut *lut)
+{
+	if (!drm_lut3d_size) {
+		lut->state.bits.initialized = 0;
+	} else {
+		/* Stride and bit depth are not programmable by API yet.
+		 * Therefore, only supports 17x17x17 3D LUT (12-bit).
+		 */
+		lut->lut_3d.use_tetrahedral_9 = false;
+		lut->lut_3d.use_12bits = true;
+		lut->state.bits.initialized = 1;
+		__drm_3dlut_to_dc_3dlut(drm_lut, drm_lut3d_size, &lut->lut_3d,
+					lut->lut_3d.use_tetrahedral_9,
+					MAX_COLOR_3DLUT_BITDEPTH);
+	}
+}
+
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
  * interface
  * @dc: Display Core control structure
@@ -355,7 +466,7 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 {
 	struct dc_3dlut *lut3d_func;
 	struct dc_transfer_func *func_shaper;
-	bool acquire = drm_shaper_size && drm_lut3d_size;
+	bool acquire = drm_shaper_size || drm_lut3d_size;
 
 	lut3d_func = (struct dc_3dlut *)stream->lut3d_func;
 	func_shaper = (struct dc_transfer_func *)stream->func_shaper;
@@ -369,42 +480,56 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 			return DC_ERROR_UNEXPECTED;
 	}
 
-	stream->lut3d_func = lut3d_func;
 	stream->func_shaper = func_shaper;
+	stream->lut3d_func = lut3d_func;
+
+	if (!acquire)
+		return 0;
+
+	/* We don't get DRM shaper LUT yet. We assume the input color
+	 * space is already delinearized, so we don't need a shaper LUT
+	 * and we can just BYPASS.
+	 */
+	func_shaper->type = TF_TYPE_BYPASS;
+	func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+	amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func);
 
 	return 0;
 }
 
 /**
- * __set_input_tf - calculates the input transfer function based on expected
- * input space.
- * @func: transfer function
- * @lut: lookup table that defines the color space
- * @lut_size: size of respective lut.
+ * amdgpu_dm_verify_lut3d_size - verifies if 3D LUT is supported and if DRM 3D
+ * LUT matches the hw supported size
+ * @adev: amdgpu device
+ * @crtc_state: the DRM CRTC state
+ *
+ * Verifies if post-blending (MPC) 3D LUT is supported by the HW (DCN 3.0 or
+ * newer) and if the DRM 3D LUT matches the supported size.
  *
  * Returns:
- * 0 in case of success. -ENOMEM if fails.
+ * 0 on success. -EINVAL if lut size are invalid.
  */
-static int __set_input_tf(struct dc_transfer_func *func,
-			  const struct drm_color_lut *lut, uint32_t lut_size)
+int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
+				const struct drm_crtc_state *crtc_state)
 {
-	struct dc_gamma *gamma = NULL;
-	bool res;
+	const struct drm_color_lut *lut3d = NULL;
+	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc_state);
+	uint32_t exp_size, size;
 
-	gamma = dc_create_gamma();
-	if (!gamma)
-		return -ENOMEM;
+	exp_size = adev->dm.dc->caps.color.mpc.num_3dluts ?
+		   MAX_COLOR_3DLUT_ENTRIES : 0;
 
-	gamma->type = GAMMA_CUSTOM;
-	gamma->num_entries = lut_size;
-
-	__drm_lut_to_dc_gamma(lut, gamma, false);
+	lut3d = __extract_blob_lut(acrtc_state->lut3d, &size);
 
-	res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
-	dc_gamma_release(&gamma);
+	if (lut3d && size != exp_size) {
+		DRM_DEBUG_DRIVER("Invalid Gamma 3D LUT size. Should be %u but got %u.\n",
+				 exp_size, size);
+		return -EINVAL;
+	}
 
-	return res ? 0 : -ENOMEM;
+	return 0;
 }
+#endif
 
 /**
  * amdgpu_dm_verify_lut_sizes - verifies if DRM luts match the hw supported sizes
@@ -477,6 +602,16 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 	bool has_regamma, has_degamma;
 	bool is_legacy;
 	int r;
+#ifdef CONFIG_STEAM_DECK
+	const struct drm_color_lut *lut3d;
+	uint32_t lut3d_size;
+
+	r =  amdgpu_dm_verify_lut3d_size(adev, &crtc->base);
+	if (r)
+		return r;
+
+	lut3d = __extract_blob_lut(crtc->lut3d, &lut3d_size);
+#endif
 
 	r = amdgpu_dm_verify_lut_sizes(&crtc->base);
 	if (r)
@@ -525,10 +660,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 		if (r)
 			return r;
 	} else {
+#ifdef CONFIG_STEAM_DECK
+		lut3d_size = lut3d != NULL ? lut3d_size : 0;
 		r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream,
-						  NULL, 0, NULL, 0);
+						  NULL, 0,
+						  lut3d, lut3d_size);
 		if (r)
 			return r;
+#endif
 		/* Note: OGAM is disabled if 3D LUT is successfully programmed.
 		 * See params and set_output_gamma in
 		 * dcn30_set_output_transfer_func()
-- 
2.39.2


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

* [RFC PATCH 25/40] drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

Decouple steps of post-blending shaper LUT setup and LUT size validation
according to HW caps as a preparation for DRM CRTC shaper LUT support.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 67 ++++++++++++++++---
 1 file changed, 58 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 25010fa19bc8..672ca5e9e59c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -443,6 +443,48 @@ static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut,
 	}
 }
 
+/**
+ * __set_input_tf - calculates the input transfer function based on expected
+ * input space.
+ * @func: transfer function
+ * @lut: lookup table that defines the color space
+ * @lut_size: size of respective lut.
+ *
+ * Returns:
+ * 0 in case of success. -ENOMEM if fails.
+ */
+static int __set_input_tf(struct dc_transfer_func *func,
+			  const struct drm_color_lut *lut, uint32_t lut_size)
+{
+	struct dc_gamma *gamma = NULL;
+	bool res;
+
+	gamma = dc_create_gamma();
+	if (!gamma)
+		return -ENOMEM;
+
+	gamma->type = GAMMA_CUSTOM;
+	gamma->num_entries = lut_size;
+
+	__drm_lut_to_dc_gamma(lut, gamma, false);
+
+	res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
+	dc_gamma_release(&gamma);
+
+	return res ? 0 : -ENOMEM;
+}
+
+static int amdgpu_dm_atomic_shaper_lut(struct dc_transfer_func *func_shaper)
+{
+	/* We don't get DRM shaper LUT yet. We assume the input color space is already
+	 * delinearized, so we don't need a shaper LUT and we can just BYPASS
+	 */
+	func_shaper->type = TF_TYPE_BYPASS;
+	func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+
+	return 0;
+}
+
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
  * interface
  * @dc: Display Core control structure
@@ -486,15 +528,23 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 	if (!acquire)
 		return 0;
 
-	/* We don't get DRM shaper LUT yet. We assume the input color
-	 * space is already delinearized, so we don't need a shaper LUT
-	 * and we can just BYPASS.
-	 */
-	func_shaper->type = TF_TYPE_BYPASS;
-	func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
 	amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func);
 
-	return 0;
+	return amdgpu_dm_atomic_shaper_lut(func_shaper);
+}
+
+/**
+ * amdgpu_dm_lut3d_size - get expected size according to hw color caps
+ * @adev: amdgpu device
+ * @lut_size: default size
+ *
+ * Return:
+ * lut_size if DC 3D LUT is supported, zero otherwise.
+ */
+static uint32_t amdgpu_dm_get_lut3d_size(struct amdgpu_device *adev,
+					 uint32_t lut_size)
+{
+	return adev->dm.dc->caps.color.mpc.num_3dluts ? lut_size : 0;
 }
 
 /**
@@ -516,8 +566,7 @@ int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
 	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc_state);
 	uint32_t exp_size, size;
 
-	exp_size = adev->dm.dc->caps.color.mpc.num_3dluts ?
-		   MAX_COLOR_3DLUT_ENTRIES : 0;
+	exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES);
 
 	lut3d = __extract_blob_lut(acrtc_state->lut3d, &size);
 
-- 
2.39.2


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

* [RFC PATCH 25/40] drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

Decouple steps of post-blending shaper LUT setup and LUT size validation
according to HW caps as a preparation for DRM CRTC shaper LUT support.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 67 ++++++++++++++++---
 1 file changed, 58 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 25010fa19bc8..672ca5e9e59c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -443,6 +443,48 @@ static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut,
 	}
 }
 
+/**
+ * __set_input_tf - calculates the input transfer function based on expected
+ * input space.
+ * @func: transfer function
+ * @lut: lookup table that defines the color space
+ * @lut_size: size of respective lut.
+ *
+ * Returns:
+ * 0 in case of success. -ENOMEM if fails.
+ */
+static int __set_input_tf(struct dc_transfer_func *func,
+			  const struct drm_color_lut *lut, uint32_t lut_size)
+{
+	struct dc_gamma *gamma = NULL;
+	bool res;
+
+	gamma = dc_create_gamma();
+	if (!gamma)
+		return -ENOMEM;
+
+	gamma->type = GAMMA_CUSTOM;
+	gamma->num_entries = lut_size;
+
+	__drm_lut_to_dc_gamma(lut, gamma, false);
+
+	res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
+	dc_gamma_release(&gamma);
+
+	return res ? 0 : -ENOMEM;
+}
+
+static int amdgpu_dm_atomic_shaper_lut(struct dc_transfer_func *func_shaper)
+{
+	/* We don't get DRM shaper LUT yet. We assume the input color space is already
+	 * delinearized, so we don't need a shaper LUT and we can just BYPASS
+	 */
+	func_shaper->type = TF_TYPE_BYPASS;
+	func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+
+	return 0;
+}
+
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
  * interface
  * @dc: Display Core control structure
@@ -486,15 +528,23 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 	if (!acquire)
 		return 0;
 
-	/* We don't get DRM shaper LUT yet. We assume the input color
-	 * space is already delinearized, so we don't need a shaper LUT
-	 * and we can just BYPASS.
-	 */
-	func_shaper->type = TF_TYPE_BYPASS;
-	func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
 	amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func);
 
-	return 0;
+	return amdgpu_dm_atomic_shaper_lut(func_shaper);
+}
+
+/**
+ * amdgpu_dm_lut3d_size - get expected size according to hw color caps
+ * @adev: amdgpu device
+ * @lut_size: default size
+ *
+ * Return:
+ * lut_size if DC 3D LUT is supported, zero otherwise.
+ */
+static uint32_t amdgpu_dm_get_lut3d_size(struct amdgpu_device *adev,
+					 uint32_t lut_size)
+{
+	return adev->dm.dc->caps.color.mpc.num_3dluts ? lut_size : 0;
 }
 
 /**
@@ -516,8 +566,7 @@ int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
 	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc_state);
 	uint32_t exp_size, size;
 
-	exp_size = adev->dm.dc->caps.color.mpc.num_3dluts ?
-		   MAX_COLOR_3DLUT_ENTRIES : 0;
+	exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES);
 
 	lut3d = __extract_blob_lut(acrtc_state->lut3d, &size);
 
-- 
2.39.2


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

* [RFC PATCH 26/40] drm/amd/display: add CRTC shaper LUT support to amd color pipeline
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

Now, we can use DRM CRTC shaper LUT to delinearize and/or normalize the
color space for a more efficient 3D LUT support (so far, only for DRM
atomic color mgmt). If a degamma 1D LUT is passed to linearize the color
space, a custom shaper 1D LUT can be used before applying 3D LUT.

NOTE: although DRM CRTC shaper and 3D LUTs are optional properties, from
our tests, AMD HW doesn't allow 3D LUT when shaper LUT is set to BYPASS
(without user shaper LUT)

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 81 +++++++++----------
 1 file changed, 38 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 672ca5e9e59c..ff29be3929af 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -443,46 +443,26 @@ static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut,
 	}
 }
 
-/**
- * __set_input_tf - calculates the input transfer function based on expected
- * input space.
- * @func: transfer function
- * @lut: lookup table that defines the color space
- * @lut_size: size of respective lut.
- *
- * Returns:
- * 0 in case of success. -ENOMEM if fails.
- */
-static int __set_input_tf(struct dc_transfer_func *func,
-			  const struct drm_color_lut *lut, uint32_t lut_size)
+static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut,
+				       uint32_t shaper_size,
+				       struct dc_transfer_func *func_shaper)
 {
-	struct dc_gamma *gamma = NULL;
-	bool res;
-
-	gamma = dc_create_gamma();
-	if (!gamma)
-		return -ENOMEM;
-
-	gamma->type = GAMMA_CUSTOM;
-	gamma->num_entries = lut_size;
-
-	__drm_lut_to_dc_gamma(lut, gamma, false);
-
-	res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
-	dc_gamma_release(&gamma);
+	int ret = 0;
 
-	return res ? 0 : -ENOMEM;
-}
+	if (shaper_size) {
+		/* If DRM shaper LUT is set, we assume a linear color space
+		 * (linearized by DRM degamma 1D LUT or not)
+		 */
+		func_shaper->type = TF_TYPE_DISTRIBUTED_POINTS;
+		func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
 
-static int amdgpu_dm_atomic_shaper_lut(struct dc_transfer_func *func_shaper)
-{
-	/* We don't get DRM shaper LUT yet. We assume the input color space is already
-	 * delinearized, so we don't need a shaper LUT and we can just BYPASS
-	 */
-	func_shaper->type = TF_TYPE_BYPASS;
-	func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+		ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, false);
+	} else {
+		func_shaper->type = TF_TYPE_BYPASS;
+		func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+	}
 
-	return 0;
+	return ret;
 }
 
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
@@ -530,7 +510,8 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 
 	amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func);
 
-	return amdgpu_dm_atomic_shaper_lut(func_shaper);
+	return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut,
+					   drm_shaper_size, func_shaper);
 }
 
 /**
@@ -562,12 +543,22 @@ static uint32_t amdgpu_dm_get_lut3d_size(struct amdgpu_device *adev,
 int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
 				const struct drm_crtc_state *crtc_state)
 {
-	const struct drm_color_lut *lut3d = NULL;
 	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc_state);
+	const struct drm_color_lut *shaper = NULL, *lut3d = NULL;
 	uint32_t exp_size, size;
 
-	exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES);
+	/* shaper LUT is only available if 3D LUT color caps*/
+	exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_LUT_ENTRIES);
+	shaper = __extract_blob_lut(acrtc_state->shaper_lut, &size);
 
+	if (shaper && size != exp_size) {
+		DRM_DEBUG_DRIVER(
+			"Invalid Shaper LUT size. Should be %u but got %u.\n",
+			exp_size, size);
+		return -EINVAL;
+	}
+
+	exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES);
 	lut3d = __extract_blob_lut(acrtc_state->lut3d, &size);
 
 	if (lut3d && size != exp_size) {
@@ -652,14 +643,15 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 	bool is_legacy;
 	int r;
 #ifdef CONFIG_STEAM_DECK
-	const struct drm_color_lut *lut3d;
-	uint32_t lut3d_size;
+	const struct drm_color_lut *shaper_lut, *lut3d;
+	uint32_t shaper_size, lut3d_size;
 
 	r =  amdgpu_dm_verify_lut3d_size(adev, &crtc->base);
 	if (r)
 		return r;
 
 	lut3d = __extract_blob_lut(crtc->lut3d, &lut3d_size);
+	shaper_lut = __extract_blob_lut(crtc->shaper_lut, &shaper_size);
 #endif
 
 	r = amdgpu_dm_verify_lut_sizes(&crtc->base);
@@ -711,11 +703,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 	} else {
 #ifdef CONFIG_STEAM_DECK
 		lut3d_size = lut3d != NULL ? lut3d_size : 0;
+		shaper_size = shaper_lut != NULL ? shaper_size : 0;
 		r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream,
-						  NULL, 0,
+						  shaper_lut, shaper_size,
 						  lut3d, lut3d_size);
-		if (r)
+		if (r) {
+			DRM_DEBUG_DRIVER("Failed on shaper/3D LUTs setup\n");
 			return r;
+		}
 #endif
 		/* Note: OGAM is disabled if 3D LUT is successfully programmed.
 		 * See params and set_output_gamma in
-- 
2.39.2


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

* [RFC PATCH 26/40] drm/amd/display: add CRTC shaper LUT support to amd color pipeline
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

Now, we can use DRM CRTC shaper LUT to delinearize and/or normalize the
color space for a more efficient 3D LUT support (so far, only for DRM
atomic color mgmt). If a degamma 1D LUT is passed to linearize the color
space, a custom shaper 1D LUT can be used before applying 3D LUT.

NOTE: although DRM CRTC shaper and 3D LUTs are optional properties, from
our tests, AMD HW doesn't allow 3D LUT when shaper LUT is set to BYPASS
(without user shaper LUT)

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 81 +++++++++----------
 1 file changed, 38 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 672ca5e9e59c..ff29be3929af 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -443,46 +443,26 @@ static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut,
 	}
 }
 
-/**
- * __set_input_tf - calculates the input transfer function based on expected
- * input space.
- * @func: transfer function
- * @lut: lookup table that defines the color space
- * @lut_size: size of respective lut.
- *
- * Returns:
- * 0 in case of success. -ENOMEM if fails.
- */
-static int __set_input_tf(struct dc_transfer_func *func,
-			  const struct drm_color_lut *lut, uint32_t lut_size)
+static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut,
+				       uint32_t shaper_size,
+				       struct dc_transfer_func *func_shaper)
 {
-	struct dc_gamma *gamma = NULL;
-	bool res;
-
-	gamma = dc_create_gamma();
-	if (!gamma)
-		return -ENOMEM;
-
-	gamma->type = GAMMA_CUSTOM;
-	gamma->num_entries = lut_size;
-
-	__drm_lut_to_dc_gamma(lut, gamma, false);
-
-	res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
-	dc_gamma_release(&gamma);
+	int ret = 0;
 
-	return res ? 0 : -ENOMEM;
-}
+	if (shaper_size) {
+		/* If DRM shaper LUT is set, we assume a linear color space
+		 * (linearized by DRM degamma 1D LUT or not)
+		 */
+		func_shaper->type = TF_TYPE_DISTRIBUTED_POINTS;
+		func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
 
-static int amdgpu_dm_atomic_shaper_lut(struct dc_transfer_func *func_shaper)
-{
-	/* We don't get DRM shaper LUT yet. We assume the input color space is already
-	 * delinearized, so we don't need a shaper LUT and we can just BYPASS
-	 */
-	func_shaper->type = TF_TYPE_BYPASS;
-	func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+		ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, false);
+	} else {
+		func_shaper->type = TF_TYPE_BYPASS;
+		func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+	}
 
-	return 0;
+	return ret;
 }
 
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
@@ -530,7 +510,8 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 
 	amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func);
 
-	return amdgpu_dm_atomic_shaper_lut(func_shaper);
+	return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut,
+					   drm_shaper_size, func_shaper);
 }
 
 /**
@@ -562,12 +543,22 @@ static uint32_t amdgpu_dm_get_lut3d_size(struct amdgpu_device *adev,
 int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev,
 				const struct drm_crtc_state *crtc_state)
 {
-	const struct drm_color_lut *lut3d = NULL;
 	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc_state);
+	const struct drm_color_lut *shaper = NULL, *lut3d = NULL;
 	uint32_t exp_size, size;
 
-	exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES);
+	/* shaper LUT is only available if 3D LUT color caps*/
+	exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_LUT_ENTRIES);
+	shaper = __extract_blob_lut(acrtc_state->shaper_lut, &size);
 
+	if (shaper && size != exp_size) {
+		DRM_DEBUG_DRIVER(
+			"Invalid Shaper LUT size. Should be %u but got %u.\n",
+			exp_size, size);
+		return -EINVAL;
+	}
+
+	exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES);
 	lut3d = __extract_blob_lut(acrtc_state->lut3d, &size);
 
 	if (lut3d && size != exp_size) {
@@ -652,14 +643,15 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 	bool is_legacy;
 	int r;
 #ifdef CONFIG_STEAM_DECK
-	const struct drm_color_lut *lut3d;
-	uint32_t lut3d_size;
+	const struct drm_color_lut *shaper_lut, *lut3d;
+	uint32_t shaper_size, lut3d_size;
 
 	r =  amdgpu_dm_verify_lut3d_size(adev, &crtc->base);
 	if (r)
 		return r;
 
 	lut3d = __extract_blob_lut(crtc->lut3d, &lut3d_size);
+	shaper_lut = __extract_blob_lut(crtc->shaper_lut, &shaper_size);
 #endif
 
 	r = amdgpu_dm_verify_lut_sizes(&crtc->base);
@@ -711,11 +703,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 	} else {
 #ifdef CONFIG_STEAM_DECK
 		lut3d_size = lut3d != NULL ? lut3d_size : 0;
+		shaper_size = shaper_lut != NULL ? shaper_size : 0;
 		r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream,
-						  NULL, 0,
+						  shaper_lut, shaper_size,
 						  lut3d, lut3d_size);
-		if (r)
+		if (r) {
+			DRM_DEBUG_DRIVER("Failed on shaper/3D LUTs setup\n");
 			return r;
+		}
 #endif
 		/* Note: OGAM is disabled if 3D LUT is successfully programmed.
 		 * See params and set_output_gamma in
-- 
2.39.2


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

* [RFC PATCH 27/40] drm/amd/display: add CRTC regamma TF support
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

Add predefined transfer function programming. There is no out gamma ROM,
but we can use AMD color modules to program LUT parameters from a
predefined TF and an empty regamma LUT (or power LUT parameters with
predefined TF setup).

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 60 ++++++++++++++-----
 1 file changed, 44 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index ff29be3929af..55aa876a5008 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -268,16 +268,18 @@ static int __set_output_tf(struct dc_transfer_func *func,
 	struct calculate_buffer cal_buffer = {0};
 	bool res;
 
-	ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES);
-
 	cal_buffer.buffer_index = -1;
 
-	gamma = dc_create_gamma();
-	if (!gamma)
-		return -ENOMEM;
+	if (lut_size) {
+		ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES);
 
-	gamma->num_entries = lut_size;
-	__drm_lut_to_dc_gamma(lut, gamma, false);
+		gamma = dc_create_gamma();
+		if (!gamma)
+			return -ENOMEM;
+
+		gamma->num_entries = lut_size;
+		__drm_lut_to_dc_gamma(lut, gamma, false);
+	}
 
 	if (func->tf == TRANSFER_FUNCTION_LINEAR) {
 		/*
@@ -285,30 +287,34 @@ static int __set_output_tf(struct dc_transfer_func *func,
 		 * on top of a linear input. But degamma params can be used
 		 * instead to simulate this.
 		 */
-		gamma->type = GAMMA_CUSTOM;
+		if (gamma)
+			gamma->type = GAMMA_CUSTOM;
 		res = mod_color_calculate_degamma_params(NULL, func,
-							gamma, true);
+							 gamma, gamma != NULL);
 	} else {
 		/*
 		 * Assume sRGB. The actual mapping will depend on whether the
 		 * input was legacy or not.
 		 */
-		gamma->type = GAMMA_CS_TFM_1D;
-		res = mod_color_calculate_regamma_params(func, gamma, false,
+		if (gamma)
+			gamma->type = GAMMA_CS_TFM_1D;
+		res = mod_color_calculate_regamma_params(func, gamma, gamma != NULL,
 							 has_rom, NULL, &cal_buffer);
 	}
 
-	dc_gamma_release(&gamma);
+	if (gamma)
+		dc_gamma_release(&gamma);
 
 	return res ? 0 : -ENOMEM;
 }
 
 static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 					const struct drm_color_lut *regamma_lut,
-					uint32_t regamma_size, bool has_rom)
+					uint32_t regamma_size, bool has_rom,
+					enum dc_transfer_func_predefined tf)
 {
 	int ret = 0;
-	if (regamma_size) {
+	if (regamma_size || tf != TRANSFER_FUNCTION_LINEAR) {
 		/* CRTC RGM goes into RGM LUT.
 		 *
 		 * Note: there is no implicit sRGB regamma here. We are using
@@ -316,7 +322,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 		 * from a linear base.
 		 */
 		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
-		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+		stream->out_transfer_func->tf = tf;
 
 		ret = __set_output_tf(stream->out_transfer_func,
 				      regamma_lut, regamma_size, has_rom);
@@ -364,6 +370,25 @@ static int __set_input_tf(struct dc_transfer_func *func,
 }
 
 #ifdef CONFIG_STEAM_DECK
+static enum dc_transfer_func_predefined drm_tf_to_dc_tf(enum drm_transfer_function drm_tf)
+{
+	switch (drm_tf)
+	{
+	default:
+	case DRM_TRANSFER_FUNCTION_DEFAULT:	return TRANSFER_FUNCTION_LINEAR;
+	case DRM_TRANSFER_FUNCTION_SRGB:	return TRANSFER_FUNCTION_SRGB;
+
+	case DRM_TRANSFER_FUNCTION_BT709:	return TRANSFER_FUNCTION_BT709;
+	case DRM_TRANSFER_FUNCTION_PQ:		return TRANSFER_FUNCTION_PQ;
+	case DRM_TRANSFER_FUNCTION_LINEAR:	return TRANSFER_FUNCTION_LINEAR;
+	case DRM_TRANSFER_FUNCTION_UNITY:	return TRANSFER_FUNCTION_UNITY;
+	case DRM_TRANSFER_FUNCTION_HLG:		return TRANSFER_FUNCTION_HLG;
+	case DRM_TRANSFER_FUNCTION_GAMMA22:	return TRANSFER_FUNCTION_GAMMA22;
+	case DRM_TRANSFER_FUNCTION_GAMMA24:	return TRANSFER_FUNCTION_GAMMA24;
+	case DRM_TRANSFER_FUNCTION_GAMMA26:	return TRANSFER_FUNCTION_GAMMA26;
+	}
+}
+
 static void __to_dc_lut3d_color(struct dc_rgb *rgb,
 				const struct drm_color_lut lut,
 				int bit_precision)
@@ -640,6 +665,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 	const struct drm_color_lut *degamma_lut, *regamma_lut;
 	uint32_t degamma_size, regamma_size;
 	bool has_regamma, has_degamma;
+	enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_LINEAR;
 	bool is_legacy;
 	int r;
 #ifdef CONFIG_STEAM_DECK
@@ -652,6 +678,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 
 	lut3d = __extract_blob_lut(crtc->lut3d, &lut3d_size);
 	shaper_lut = __extract_blob_lut(crtc->shaper_lut, &shaper_size);
+
+	tf = drm_tf_to_dc_tf(crtc->gamma_tf);
 #endif
 
 	r = amdgpu_dm_verify_lut_sizes(&crtc->base);
@@ -718,7 +746,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 		 */
 		regamma_size = has_regamma ? regamma_size : 0;
 		r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut,
-						 regamma_size, has_rom);
+						 regamma_size, has_rom, tf);
 		if (r)
 			return r;
 	}
-- 
2.39.2


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

* [RFC PATCH 27/40] drm/amd/display: add CRTC regamma TF support
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Joshua Ashton <joshua@froggi.es>

Add predefined transfer function programming. There is no out gamma ROM,
but we can use AMD color modules to program LUT parameters from a
predefined TF and an empty regamma LUT (or power LUT parameters with
predefined TF setup).

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 60 ++++++++++++++-----
 1 file changed, 44 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index ff29be3929af..55aa876a5008 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -268,16 +268,18 @@ static int __set_output_tf(struct dc_transfer_func *func,
 	struct calculate_buffer cal_buffer = {0};
 	bool res;
 
-	ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES);
-
 	cal_buffer.buffer_index = -1;
 
-	gamma = dc_create_gamma();
-	if (!gamma)
-		return -ENOMEM;
+	if (lut_size) {
+		ASSERT(lut && lut_size == MAX_COLOR_LUT_ENTRIES);
 
-	gamma->num_entries = lut_size;
-	__drm_lut_to_dc_gamma(lut, gamma, false);
+		gamma = dc_create_gamma();
+		if (!gamma)
+			return -ENOMEM;
+
+		gamma->num_entries = lut_size;
+		__drm_lut_to_dc_gamma(lut, gamma, false);
+	}
 
 	if (func->tf == TRANSFER_FUNCTION_LINEAR) {
 		/*
@@ -285,30 +287,34 @@ static int __set_output_tf(struct dc_transfer_func *func,
 		 * on top of a linear input. But degamma params can be used
 		 * instead to simulate this.
 		 */
-		gamma->type = GAMMA_CUSTOM;
+		if (gamma)
+			gamma->type = GAMMA_CUSTOM;
 		res = mod_color_calculate_degamma_params(NULL, func,
-							gamma, true);
+							 gamma, gamma != NULL);
 	} else {
 		/*
 		 * Assume sRGB. The actual mapping will depend on whether the
 		 * input was legacy or not.
 		 */
-		gamma->type = GAMMA_CS_TFM_1D;
-		res = mod_color_calculate_regamma_params(func, gamma, false,
+		if (gamma)
+			gamma->type = GAMMA_CS_TFM_1D;
+		res = mod_color_calculate_regamma_params(func, gamma, gamma != NULL,
 							 has_rom, NULL, &cal_buffer);
 	}
 
-	dc_gamma_release(&gamma);
+	if (gamma)
+		dc_gamma_release(&gamma);
 
 	return res ? 0 : -ENOMEM;
 }
 
 static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 					const struct drm_color_lut *regamma_lut,
-					uint32_t regamma_size, bool has_rom)
+					uint32_t regamma_size, bool has_rom,
+					enum dc_transfer_func_predefined tf)
 {
 	int ret = 0;
-	if (regamma_size) {
+	if (regamma_size || tf != TRANSFER_FUNCTION_LINEAR) {
 		/* CRTC RGM goes into RGM LUT.
 		 *
 		 * Note: there is no implicit sRGB regamma here. We are using
@@ -316,7 +322,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 		 * from a linear base.
 		 */
 		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
-		stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+		stream->out_transfer_func->tf = tf;
 
 		ret = __set_output_tf(stream->out_transfer_func,
 				      regamma_lut, regamma_size, has_rom);
@@ -364,6 +370,25 @@ static int __set_input_tf(struct dc_transfer_func *func,
 }
 
 #ifdef CONFIG_STEAM_DECK
+static enum dc_transfer_func_predefined drm_tf_to_dc_tf(enum drm_transfer_function drm_tf)
+{
+	switch (drm_tf)
+	{
+	default:
+	case DRM_TRANSFER_FUNCTION_DEFAULT:	return TRANSFER_FUNCTION_LINEAR;
+	case DRM_TRANSFER_FUNCTION_SRGB:	return TRANSFER_FUNCTION_SRGB;
+
+	case DRM_TRANSFER_FUNCTION_BT709:	return TRANSFER_FUNCTION_BT709;
+	case DRM_TRANSFER_FUNCTION_PQ:		return TRANSFER_FUNCTION_PQ;
+	case DRM_TRANSFER_FUNCTION_LINEAR:	return TRANSFER_FUNCTION_LINEAR;
+	case DRM_TRANSFER_FUNCTION_UNITY:	return TRANSFER_FUNCTION_UNITY;
+	case DRM_TRANSFER_FUNCTION_HLG:		return TRANSFER_FUNCTION_HLG;
+	case DRM_TRANSFER_FUNCTION_GAMMA22:	return TRANSFER_FUNCTION_GAMMA22;
+	case DRM_TRANSFER_FUNCTION_GAMMA24:	return TRANSFER_FUNCTION_GAMMA24;
+	case DRM_TRANSFER_FUNCTION_GAMMA26:	return TRANSFER_FUNCTION_GAMMA26;
+	}
+}
+
 static void __to_dc_lut3d_color(struct dc_rgb *rgb,
 				const struct drm_color_lut lut,
 				int bit_precision)
@@ -640,6 +665,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 	const struct drm_color_lut *degamma_lut, *regamma_lut;
 	uint32_t degamma_size, regamma_size;
 	bool has_regamma, has_degamma;
+	enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_LINEAR;
 	bool is_legacy;
 	int r;
 #ifdef CONFIG_STEAM_DECK
@@ -652,6 +678,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 
 	lut3d = __extract_blob_lut(crtc->lut3d, &lut3d_size);
 	shaper_lut = __extract_blob_lut(crtc->shaper_lut, &shaper_size);
+
+	tf = drm_tf_to_dc_tf(crtc->gamma_tf);
 #endif
 
 	r = amdgpu_dm_verify_lut_sizes(&crtc->base);
@@ -718,7 +746,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 		 */
 		regamma_size = has_regamma ? regamma_size : 0;
 		r = amdgpu_dm_set_atomic_regamma(stream, regamma_lut,
-						 regamma_size, has_rom);
+						 regamma_size, has_rom, tf);
 		if (r)
 			return r;
 	}
-- 
2.39.2


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

* [RFC PATCH 28/40] drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

Otherwise this is just initialized to 0.

This needs to actually have a value so that compute_curve can work
for PQ EOTF.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 55aa876a5008..6e7271065a56 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -323,6 +323,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 		 */
 		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
 		stream->out_transfer_func->tf = tf;
+		stream->out_transfer_func->sdr_ref_white_level = 80;
 
 		ret = __set_output_tf(stream->out_transfer_func,
 				      regamma_lut, regamma_size, has_rom);
-- 
2.39.2


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

* [RFC PATCH 28/40] drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Joshua Ashton <joshua@froggi.es>

Otherwise this is just initialized to 0.

This needs to actually have a value so that compute_curve can work
for PQ EOTF.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 55aa876a5008..6e7271065a56 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -323,6 +323,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 		 */
 		stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
 		stream->out_transfer_func->tf = tf;
+		stream->out_transfer_func->sdr_ref_white_level = 80;
 
 		ret = __set_output_tf(stream->out_transfer_func,
 				      regamma_lut, regamma_size, has_rom);
-- 
2.39.2


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

* [RFC PATCH 29/40] drm/amd/display: add CRTC shaper TF support
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

Inspired by regamma TF, follow similar steps to add TF + 1D LUT for
shaper func. Reuse gamma_tf property, since the driver doesn't support
shaper and out gamma at the same time. We could rename gamma_tf, if
necessary to avoid misunderstandings, or add a specific property for
shaper lut.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_color.c  | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 6e7271065a56..6a233380f284 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -470,19 +470,22 @@ static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut,
 }
 
 static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut,
+				       bool has_rom,
+				       enum dc_transfer_func_predefined tf,
 				       uint32_t shaper_size,
 				       struct dc_transfer_func *func_shaper)
 {
 	int ret = 0;
 
-	if (shaper_size) {
+	if (shaper_size || tf != TRANSFER_FUNCTION_LINEAR) {
 		/* If DRM shaper LUT is set, we assume a linear color space
 		 * (linearized by DRM degamma 1D LUT or not)
 		 */
 		func_shaper->type = TF_TYPE_DISTRIBUTED_POINTS;
-		func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+		func_shaper->tf = tf;
+		func_shaper->sdr_ref_white_level = 80; /* hardcoded for now */
 
-		ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, false);
+		ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, has_rom);
 	} else {
 		func_shaper->type = TF_TYPE_BYPASS;
 		func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
@@ -509,12 +512,14 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 					 struct dc_stream_state *stream,
 					 const struct drm_color_lut *drm_shaper_lut,
 					 uint32_t drm_shaper_size,
+					 bool has_rom,
+					 enum dc_transfer_func_predefined tf,
 					 const struct drm_color_lut *drm_lut3d,
 					 uint32_t drm_lut3d_size)
 {
 	struct dc_3dlut *lut3d_func;
 	struct dc_transfer_func *func_shaper;
-	bool acquire = drm_shaper_size || drm_lut3d_size;
+	bool acquire = drm_shaper_size || drm_lut3d_size || tf != TRANSFER_FUNCTION_LINEAR;
 
 	lut3d_func = (struct dc_3dlut *)stream->lut3d_func;
 	func_shaper = (struct dc_transfer_func *)stream->func_shaper;
@@ -536,7 +541,7 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 
 	amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func);
 
-	return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut,
+	return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut, has_rom, tf,
 					   drm_shaper_size, func_shaper);
 }
 
@@ -735,6 +740,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 		shaper_size = shaper_lut != NULL ? shaper_size : 0;
 		r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream,
 						  shaper_lut, shaper_size,
+						  has_rom, tf,
 						  lut3d, lut3d_size);
 		if (r) {
 			DRM_DEBUG_DRIVER("Failed on shaper/3D LUTs setup\n");
-- 
2.39.2


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

* [RFC PATCH 29/40] drm/amd/display: add CRTC shaper TF support
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

Inspired by regamma TF, follow similar steps to add TF + 1D LUT for
shaper func. Reuse gamma_tf property, since the driver doesn't support
shaper and out gamma at the same time. We could rename gamma_tf, if
necessary to avoid misunderstandings, or add a specific property for
shaper lut.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_color.c  | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 6e7271065a56..6a233380f284 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -470,19 +470,22 @@ static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut,
 }
 
 static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut,
+				       bool has_rom,
+				       enum dc_transfer_func_predefined tf,
 				       uint32_t shaper_size,
 				       struct dc_transfer_func *func_shaper)
 {
 	int ret = 0;
 
-	if (shaper_size) {
+	if (shaper_size || tf != TRANSFER_FUNCTION_LINEAR) {
 		/* If DRM shaper LUT is set, we assume a linear color space
 		 * (linearized by DRM degamma 1D LUT or not)
 		 */
 		func_shaper->type = TF_TYPE_DISTRIBUTED_POINTS;
-		func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
+		func_shaper->tf = tf;
+		func_shaper->sdr_ref_white_level = 80; /* hardcoded for now */
 
-		ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, false);
+		ret = __set_output_tf(func_shaper, shaper_lut, shaper_size, has_rom);
 	} else {
 		func_shaper->type = TF_TYPE_BYPASS;
 		func_shaper->tf = TRANSFER_FUNCTION_LINEAR;
@@ -509,12 +512,14 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 					 struct dc_stream_state *stream,
 					 const struct drm_color_lut *drm_shaper_lut,
 					 uint32_t drm_shaper_size,
+					 bool has_rom,
+					 enum dc_transfer_func_predefined tf,
 					 const struct drm_color_lut *drm_lut3d,
 					 uint32_t drm_lut3d_size)
 {
 	struct dc_3dlut *lut3d_func;
 	struct dc_transfer_func *func_shaper;
-	bool acquire = drm_shaper_size || drm_lut3d_size;
+	bool acquire = drm_shaper_size || drm_lut3d_size || tf != TRANSFER_FUNCTION_LINEAR;
 
 	lut3d_func = (struct dc_3dlut *)stream->lut3d_func;
 	func_shaper = (struct dc_transfer_func *)stream->func_shaper;
@@ -536,7 +541,7 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 
 	amdgpu_dm_atomic_lut3d(drm_lut3d, drm_lut3d_size, lut3d_func);
 
-	return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut,
+	return amdgpu_dm_atomic_shaper_lut(drm_shaper_lut, has_rom, tf,
 					   drm_shaper_size, func_shaper);
 }
 
@@ -735,6 +740,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 		shaper_size = shaper_lut != NULL ? shaper_size : 0;
 		r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, ctx, stream,
 						  shaper_lut, shaper_size,
+						  has_rom, tf,
 						  lut3d, lut3d_size);
 		if (r) {
 			DRM_DEBUG_DRIVER("Failed on shaper/3D LUTs setup\n");
-- 
2.39.2


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

* [RFC PATCH 30/40] drm/amd/display: mark plane as needing reset if plane color mgmt changes
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

We took a similar path for CRTC color mgmt changes, since we remap CRTC
degamma to plane/DPP block. Here we can use the status of
`plane->color_mgmt_changed` to detect when a plane color property
changed and recreate the plane accordingly.

Co-developed-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++
 1 file changed, 3 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 760080e4a4da..1dac311cab67 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9441,6 +9441,9 @@ static bool should_reset_plane(struct drm_atomic_state *state,
 	if (drm_atomic_crtc_needs_modeset(new_crtc_state))
 		return true;
 
+	if (new_plane_state->color_mgmt_changed)
+		return true;
+
 	/*
 	 * If there are any new primary or overlay planes being added or
 	 * removed then the z-order can potentially change. To ensure
-- 
2.39.2


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

* [RFC PATCH 30/40] drm/amd/display: mark plane as needing reset if plane color mgmt changes
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

We took a similar path for CRTC color mgmt changes, since we remap CRTC
degamma to plane/DPP block. Here we can use the status of
`plane->color_mgmt_changed` to detect when a plane color property
changed and recreate the plane accordingly.

Co-developed-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Joshua Ashton <joshua@froggi.es>
Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++
 1 file changed, 3 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 760080e4a4da..1dac311cab67 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -9441,6 +9441,9 @@ static bool should_reset_plane(struct drm_atomic_state *state,
 	if (drm_atomic_crtc_needs_modeset(new_crtc_state))
 		return true;
 
+	if (new_plane_state->color_mgmt_changed)
+		return true;
+
 	/*
 	 * If there are any new primary or overlay planes being added or
 	 * removed then the z-order can potentially change. To ensure
-- 
2.39.2


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

* [RFC PATCH 31/40] drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

The next patch adds pre-blending degamma to AMD color mgmt pipeline, but
pre-blending degamma caps (DPP) is currently in use to provide DRM CRTC
atomic degamma or implict degamma on legacy gamma. Detach degamma usage
regarging CRTC color properties to manage plane and CRTC color
correction combinations.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 55 +++++++++++++------
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 6a233380f284..518082222fff 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -791,20 +791,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 	return 0;
 }
 
-/**
- * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
- * @crtc: amdgpu_dm crtc state
- * @dc_plane_state: target DC surface
- *
- * Update the underlying dc_stream_state's input transfer function (ITF) in
- * preparation for hardware commit. The transfer function used depends on
- * the preparation done on the stream for color management.
- *
- * Returns:
- * 0 on success. -ENOMEM if mem allocation fails.
- */
-int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
-				      struct dc_plane_state *dc_plane_state)
+static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
+					struct dc_plane_state *dc_plane_state)
 {
 	const struct drm_color_lut *degamma_lut;
 	enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
@@ -827,8 +815,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 						 &degamma_size);
 		ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES);
 
-		dc_plane_state->in_transfer_func->type =
-			TF_TYPE_DISTRIBUTED_POINTS;
+		dc_plane_state->in_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
 
 		/*
 		 * This case isn't fully correct, but also fairly
@@ -864,7 +851,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 				   degamma_lut, degamma_size);
 		if (r)
 			return r;
-	} else if (crtc->cm_is_degamma_srgb) {
+	} else {
 		/*
 		 * For legacy gamma support we need the regamma input
 		 * in linear space. Assume that the input is sRGB.
@@ -876,6 +863,40 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 		    !mod_color_calculate_degamma_params(NULL,
 			    dc_plane_state->in_transfer_func, NULL, false))
 			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/**
+ * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
+ * @crtc: amdgpu_dm crtc state
+ * @dc_plane_state: target DC surface
+ *
+ * Update the underlying dc_stream_state's input transfer function (ITF) in
+ * preparation for hardware commit. The transfer function used depends on
+ * the preparation done on the stream for color management.
+ *
+ * Returns:
+ * 0 on success. -ENOMEM if mem allocation fails.
+ */
+int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+				      struct dc_plane_state *dc_plane_state)
+{
+	bool has_crtc_cm_degamma;
+	int ret;
+
+	has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb);
+	if (has_crtc_cm_degamma){
+		/* AMD HW doesn't have post-blending degamma caps. When DRM
+		 * CRTC atomic degamma is set, we maps it to DPP degamma block
+		 * (pre-blending) or, on legacy gamma, we use DPP degamma to
+		 * linearize (implicit degamma) from sRGB/BT709 according to
+		 * the input space.
+		 */
+		ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state);
+		if (ret)
+			return ret;
 	} else {
 		/* ...Otherwise we can just bypass the DGM block. */
 		dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
-- 
2.39.2


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

* [RFC PATCH 31/40] drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

The next patch adds pre-blending degamma to AMD color mgmt pipeline, but
pre-blending degamma caps (DPP) is currently in use to provide DRM CRTC
atomic degamma or implict degamma on legacy gamma. Detach degamma usage
regarging CRTC color properties to manage plane and CRTC color
correction combinations.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 55 +++++++++++++------
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 6a233380f284..518082222fff 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -791,20 +791,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 	return 0;
 }
 
-/**
- * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
- * @crtc: amdgpu_dm crtc state
- * @dc_plane_state: target DC surface
- *
- * Update the underlying dc_stream_state's input transfer function (ITF) in
- * preparation for hardware commit. The transfer function used depends on
- * the preparation done on the stream for color management.
- *
- * Returns:
- * 0 on success. -ENOMEM if mem allocation fails.
- */
-int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
-				      struct dc_plane_state *dc_plane_state)
+static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
+					struct dc_plane_state *dc_plane_state)
 {
 	const struct drm_color_lut *degamma_lut;
 	enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
@@ -827,8 +815,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 						 &degamma_size);
 		ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES);
 
-		dc_plane_state->in_transfer_func->type =
-			TF_TYPE_DISTRIBUTED_POINTS;
+		dc_plane_state->in_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
 
 		/*
 		 * This case isn't fully correct, but also fairly
@@ -864,7 +851,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 				   degamma_lut, degamma_size);
 		if (r)
 			return r;
-	} else if (crtc->cm_is_degamma_srgb) {
+	} else {
 		/*
 		 * For legacy gamma support we need the regamma input
 		 * in linear space. Assume that the input is sRGB.
@@ -876,6 +863,40 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 		    !mod_color_calculate_degamma_params(NULL,
 			    dc_plane_state->in_transfer_func, NULL, false))
 			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/**
+ * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
+ * @crtc: amdgpu_dm crtc state
+ * @dc_plane_state: target DC surface
+ *
+ * Update the underlying dc_stream_state's input transfer function (ITF) in
+ * preparation for hardware commit. The transfer function used depends on
+ * the preparation done on the stream for color management.
+ *
+ * Returns:
+ * 0 on success. -ENOMEM if mem allocation fails.
+ */
+int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+				      struct dc_plane_state *dc_plane_state)
+{
+	bool has_crtc_cm_degamma;
+	int ret;
+
+	has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb);
+	if (has_crtc_cm_degamma){
+		/* AMD HW doesn't have post-blending degamma caps. When DRM
+		 * CRTC atomic degamma is set, we maps it to DPP degamma block
+		 * (pre-blending) or, on legacy gamma, we use DPP degamma to
+		 * linearize (implicit degamma) from sRGB/BT709 according to
+		 * the input space.
+		 */
+		ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state);
+		if (ret)
+			return ret;
 	} else {
 		/* ...Otherwise we can just bypass the DGM block. */
 		dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
-- 
2.39.2


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

* [RFC PATCH 32/40] drm/amd/display: add support for plane degamma TF and LUT properties
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

We only set CRTC degamma if we don't have plane degamma LUT or TF to
configure. We return -EINVAL if we don't have plane degamma settings, so
we can continue and check CRTC degamma.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  4 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 71 +++++++++++++++++--
 3 files changed, 70 insertions(+), 6 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 1dac311cab67..c0321272c129 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5043,7 +5043,9 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
 	 * Always set input transfer function, since plane state is refreshed
 	 * every time.
 	 */
-	ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state, dc_plane_state);
+	ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state,
+						plane_state,
+						dc_plane_state);
 	if (ret)
 		return ret;
 
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 b9840c1f3cdf..bcf74b7391c9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -912,6 +912,7 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
 int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 				     struct dc_state *ctx);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+				      struct drm_plane_state *plane_state,
 				      struct dc_plane_state *dc_plane_state);
 
 void amdgpu_dm_update_connector_after_detect(
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 518082222fff..693168cc1d9c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -868,9 +868,59 @@ static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
 	return 0;
 }
 
+#ifdef CONFIG_STEAM_DECK
+static int
+__set_dm_plane_degamma(struct drm_plane_state *plane_state,
+		       struct dc_plane_state *dc_plane_state)
+{
+	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+	const struct drm_color_lut *degamma_lut;
+	enum drm_transfer_function drm_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+	uint32_t degamma_size;
+	bool has_degamma_lut;
+	int ret;
+
+	degamma_lut = __extract_blob_lut(dm_plane_state->degamma_lut, &degamma_size);
+
+	has_degamma_lut = degamma_lut &&
+			  !__is_lut_linear(degamma_lut, degamma_size);
+
+	drm_tf = dm_plane_state->degamma_tf;
+
+	/* If we don't have plane degamma LUT nor TF to set on DC, we have
+	 * nothing to do here, return.
+	 */
+	if (!has_degamma_lut && drm_tf == DRM_TRANSFER_FUNCTION_DEFAULT)
+		return -EINVAL;
+
+	dc_plane_state->in_transfer_func->tf = drm_tf_to_dc_tf(drm_tf);
+
+	if (has_degamma_lut) {
+		ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES);
+
+		dc_plane_state->in_transfer_func->type =
+			TF_TYPE_DISTRIBUTED_POINTS;
+
+		ret = __set_input_tf(dc_plane_state->in_transfer_func,
+				   degamma_lut, degamma_size);
+		if (ret)
+			return ret;
+       } else {
+		dc_plane_state->in_transfer_func->type =
+			TF_TYPE_PREDEFINED;
+
+		if (!mod_color_calculate_degamma_params(NULL,
+		    dc_plane_state->in_transfer_func, NULL, false))
+			return -ENOMEM;
+	}
+	return 0;
+}
+#endif
+
 /**
  * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
  * @crtc: amdgpu_dm crtc state
+ * @plane_state: DRM plane state
  * @dc_plane_state: target DC surface
  *
  * Update the underlying dc_stream_state's input transfer function (ITF) in
@@ -881,13 +931,28 @@ static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
  * 0 on success. -ENOMEM if mem allocation fails.
  */
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+				      struct drm_plane_state *plane_state,
 				      struct dc_plane_state *dc_plane_state)
 {
 	bool has_crtc_cm_degamma;
 	int ret;
 
+	/* Initially, we can just bypass the DGM block. */
+	dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
+	dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+
+	/* After, we start to update values according to color props */
 	has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb);
-	if (has_crtc_cm_degamma){
+
+#ifdef CONFIG_STEAM_DECK
+	ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
+	if (ret != -EINVAL)
+		return ret;
+
+	/* As we don't have plane degamma, check if we have CRTC degamma
+	 * waiting for mapping to pre-blending degamma block */
+#endif
+	if (has_crtc_cm_degamma) {
 		/* AMD HW doesn't have post-blending degamma caps. When DRM
 		 * CRTC atomic degamma is set, we maps it to DPP degamma block
 		 * (pre-blending) or, on legacy gamma, we use DPP degamma to
@@ -897,10 +962,6 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 		ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state);
 		if (ret)
 			return ret;
-	} else {
-		/* ...Otherwise we can just bypass the DGM block. */
-		dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
-		dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 	}
 
 	return 0;
-- 
2.39.2


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

* [RFC PATCH 32/40] drm/amd/display: add support for plane degamma TF and LUT properties
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Joshua Ashton <joshua@froggi.es>

We only set CRTC degamma if we don't have plane degamma LUT or TF to
configure. We return -EINVAL if we don't have plane degamma settings, so
we can continue and check CRTC degamma.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  4 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 71 +++++++++++++++++--
 3 files changed, 70 insertions(+), 6 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 1dac311cab67..c0321272c129 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -5043,7 +5043,9 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
 	 * Always set input transfer function, since plane state is refreshed
 	 * every time.
 	 */
-	ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state, dc_plane_state);
+	ret = amdgpu_dm_update_plane_color_mgmt(dm_crtc_state,
+						plane_state,
+						dc_plane_state);
 	if (ret)
 		return ret;
 
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 b9840c1f3cdf..bcf74b7391c9 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -912,6 +912,7 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
 int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 				     struct dc_state *ctx);
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+				      struct drm_plane_state *plane_state,
 				      struct dc_plane_state *dc_plane_state);
 
 void amdgpu_dm_update_connector_after_detect(
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 518082222fff..693168cc1d9c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -868,9 +868,59 @@ static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
 	return 0;
 }
 
+#ifdef CONFIG_STEAM_DECK
+static int
+__set_dm_plane_degamma(struct drm_plane_state *plane_state,
+		       struct dc_plane_state *dc_plane_state)
+{
+	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+	const struct drm_color_lut *degamma_lut;
+	enum drm_transfer_function drm_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+	uint32_t degamma_size;
+	bool has_degamma_lut;
+	int ret;
+
+	degamma_lut = __extract_blob_lut(dm_plane_state->degamma_lut, &degamma_size);
+
+	has_degamma_lut = degamma_lut &&
+			  !__is_lut_linear(degamma_lut, degamma_size);
+
+	drm_tf = dm_plane_state->degamma_tf;
+
+	/* If we don't have plane degamma LUT nor TF to set on DC, we have
+	 * nothing to do here, return.
+	 */
+	if (!has_degamma_lut && drm_tf == DRM_TRANSFER_FUNCTION_DEFAULT)
+		return -EINVAL;
+
+	dc_plane_state->in_transfer_func->tf = drm_tf_to_dc_tf(drm_tf);
+
+	if (has_degamma_lut) {
+		ASSERT(degamma_size == MAX_COLOR_LUT_ENTRIES);
+
+		dc_plane_state->in_transfer_func->type =
+			TF_TYPE_DISTRIBUTED_POINTS;
+
+		ret = __set_input_tf(dc_plane_state->in_transfer_func,
+				   degamma_lut, degamma_size);
+		if (ret)
+			return ret;
+       } else {
+		dc_plane_state->in_transfer_func->type =
+			TF_TYPE_PREDEFINED;
+
+		if (!mod_color_calculate_degamma_params(NULL,
+		    dc_plane_state->in_transfer_func, NULL, false))
+			return -ENOMEM;
+	}
+	return 0;
+}
+#endif
+
 /**
  * amdgpu_dm_update_plane_color_mgmt: Maps DRM color management to DC plane.
  * @crtc: amdgpu_dm crtc state
+ * @plane_state: DRM plane state
  * @dc_plane_state: target DC surface
  *
  * Update the underlying dc_stream_state's input transfer function (ITF) in
@@ -881,13 +931,28 @@ static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
  * 0 on success. -ENOMEM if mem allocation fails.
  */
 int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
+				      struct drm_plane_state *plane_state,
 				      struct dc_plane_state *dc_plane_state)
 {
 	bool has_crtc_cm_degamma;
 	int ret;
 
+	/* Initially, we can just bypass the DGM block. */
+	dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
+	dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
+
+	/* After, we start to update values according to color props */
 	has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb);
-	if (has_crtc_cm_degamma){
+
+#ifdef CONFIG_STEAM_DECK
+	ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
+	if (ret != -EINVAL)
+		return ret;
+
+	/* As we don't have plane degamma, check if we have CRTC degamma
+	 * waiting for mapping to pre-blending degamma block */
+#endif
+	if (has_crtc_cm_degamma) {
 		/* AMD HW doesn't have post-blending degamma caps. When DRM
 		 * CRTC atomic degamma is set, we maps it to DPP degamma block
 		 * (pre-blending) or, on legacy gamma, we use DPP degamma to
@@ -897,10 +962,6 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 		ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state);
 		if (ret)
 			return ret;
-	} else {
-		/* ...Otherwise we can just bypass the DGM block. */
-		dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
-		dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
 	}
 
 	return 0;
-- 
2.39.2


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

* [RFC PATCH 33/40] drm/amd/display: reject atomic commit if setting both plane and CRTC degamma
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

DC only has pre-blending degamma caps (pre-blending/DPP) that is
currently in use for CRTC/post-blending degamma, so that we don't have
HW caps to perform plane and CRTC degamma at the same time. Reject
atomic updates when serspace sets both plane and CRTC degamma
properties.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c   | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 693168cc1d9c..07303c9f3618 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -949,6 +949,17 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 	if (ret != -EINVAL)
 		return ret;
 
+	/* We only have one degamma block available (pre-blending) for the
+	 * whole color correction pipeline, so that we can't actually perform
+	 * plane and CRTC degamma at the same time. Reject atomic updates when
+	 * userspace sets both plane and CRTC degamma properties.
+	 */
+	if (has_crtc_cm_degamma && ret == -EINVAL){
+		drm_dbg_kms(crtc->base.crtc->dev,
+			    "doesn't support plane and CRTC degamma at the same time\n");
+			return -EINVAL;
+	}
+
 	/* As we don't have plane degamma, check if we have CRTC degamma
 	 * waiting for mapping to pre-blending degamma block */
 #endif
-- 
2.39.2


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

* [RFC PATCH 33/40] drm/amd/display: reject atomic commit if setting both plane and CRTC degamma
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

DC only has pre-blending degamma caps (pre-blending/DPP) that is
currently in use for CRTC/post-blending degamma, so that we don't have
HW caps to perform plane and CRTC degamma at the same time. Reject
atomic updates when serspace sets both plane and CRTC degamma
properties.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c   | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 693168cc1d9c..07303c9f3618 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -949,6 +949,17 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 	if (ret != -EINVAL)
 		return ret;
 
+	/* We only have one degamma block available (pre-blending) for the
+	 * whole color correction pipeline, so that we can't actually perform
+	 * plane and CRTC degamma at the same time. Reject atomic updates when
+	 * userspace sets both plane and CRTC degamma properties.
+	 */
+	if (has_crtc_cm_degamma && ret == -EINVAL){
+		drm_dbg_kms(crtc->base.crtc->dev,
+			    "doesn't support plane and CRTC degamma at the same time\n");
+			return -EINVAL;
+	}
+
 	/* As we don't have plane degamma, check if we have CRTC degamma
 	 * waiting for mapping to pre-blending degamma block */
 #endif
-- 
2.39.2


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

* [RFC PATCH 34/40] drm/amd/display: add dc_fixpt_from_s3132 helper
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

Detach value translation from CTM to reuse it for programming HDR
multiplier property.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c  |  8 +-------
 drivers/gpu/drm/amd/display/include/fixed31_32.h     | 12 ++++++++++++
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 07303c9f3618..d714728ca143 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -182,7 +182,6 @@ static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
 static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
 				   struct fixed31_32 *matrix)
 {
-	int64_t val;
 	int i;
 
 	/*
@@ -201,12 +200,7 @@ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
 		}
 
 		/* gamut_remap_matrix[i] = ctm[i - floor(i/4)] */
-		val = ctm->matrix[i - (i / 4)];
-		/* If negative, convert to 2's complement. */
-		if (val & (1ULL << 63))
-			val = -(val & ~(1ULL << 63));
-
-		matrix[i].value = val;
+		matrix[i] = dc_fixpt_from_s3132(ctm->matrix[i - (i / 4)]);
 	}
 }
 
diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h b/drivers/gpu/drm/amd/display/include/fixed31_32.h
index ece97ae0e826..f4cc7f97329f 100644
--- a/drivers/gpu/drm/amd/display/include/fixed31_32.h
+++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h
@@ -69,6 +69,18 @@ static const struct fixed31_32 dc_fixpt_epsilon = { 1LL };
 static const struct fixed31_32 dc_fixpt_half = { 0x80000000LL };
 static const struct fixed31_32 dc_fixpt_one = { 0x100000000LL };
 
+static inline struct fixed31_32 dc_fixpt_from_s3132(__u64 x)
+{
+	struct fixed31_32 val;
+
+	/* If negative, convert to 2's complement. */
+	if (x & (1ULL << 63))
+		x = -(x & ~(1ULL << 63));
+
+	val.value = x;
+	return val;
+}
+
 /*
  * @brief
  * Initialization routines
-- 
2.39.2


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

* [RFC PATCH 34/40] drm/amd/display: add dc_fixpt_from_s3132 helper
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Joshua Ashton <joshua@froggi.es>

Detach value translation from CTM to reuse it for programming HDR
multiplier property.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c  |  8 +-------
 drivers/gpu/drm/amd/display/include/fixed31_32.h     | 12 ++++++++++++
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 07303c9f3618..d714728ca143 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -182,7 +182,6 @@ static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
 static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
 				   struct fixed31_32 *matrix)
 {
-	int64_t val;
 	int i;
 
 	/*
@@ -201,12 +200,7 @@ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
 		}
 
 		/* gamut_remap_matrix[i] = ctm[i - floor(i/4)] */
-		val = ctm->matrix[i - (i / 4)];
-		/* If negative, convert to 2's complement. */
-		if (val & (1ULL << 63))
-			val = -(val & ~(1ULL << 63));
-
-		matrix[i].value = val;
+		matrix[i] = dc_fixpt_from_s3132(ctm->matrix[i - (i / 4)]);
 	}
 }
 
diff --git a/drivers/gpu/drm/amd/display/include/fixed31_32.h b/drivers/gpu/drm/amd/display/include/fixed31_32.h
index ece97ae0e826..f4cc7f97329f 100644
--- a/drivers/gpu/drm/amd/display/include/fixed31_32.h
+++ b/drivers/gpu/drm/amd/display/include/fixed31_32.h
@@ -69,6 +69,18 @@ static const struct fixed31_32 dc_fixpt_epsilon = { 1LL };
 static const struct fixed31_32 dc_fixpt_half = { 0x80000000LL };
 static const struct fixed31_32 dc_fixpt_one = { 0x100000000LL };
 
+static inline struct fixed31_32 dc_fixpt_from_s3132(__u64 x)
+{
+	struct fixed31_32 val;
+
+	/* If negative, convert to 2's complement. */
+	if (x & (1ULL << 63))
+		x = -(x & ~(1ULL << 63));
+
+	val.value = x;
+	return val;
+}
+
 /*
  * @brief
  * Initialization routines
-- 
2.39.2


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

* [RFC PATCH 35/40] drm/adm/display: add HDR multiplier support
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

With `dc_fixpt_from_s3132()` translation, we can just use it to set
hdr_mult.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c       | 1 +
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 3 +++
 2 files changed, 4 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 c0321272c129..0e3b6d414ec4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7991,6 +7991,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 			bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction;
 			bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func;
 			bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix;
+			bundle->surface_updates[planes_count].hdr_mult = dc_plane->hdr_mult;
 		}
 
 		amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index d714728ca143..854510b05194 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -939,6 +939,8 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 	has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb);
 
 #ifdef CONFIG_STEAM_DECK
+	dc_plane_state->hdr_mult = dc_fixpt_from_s3132(dm_plane_state->hdr_mult);
+
 	ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
 	if (ret != -EINVAL)
 		return ret;
@@ -969,5 +971,6 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 			return ret;
 	}
 
+
 	return 0;
 }
-- 
2.39.2


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

* [RFC PATCH 35/40] drm/adm/display: add HDR multiplier support
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Joshua Ashton <joshua@froggi.es>

With `dc_fixpt_from_s3132()` translation, we can just use it to set
hdr_mult.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c       | 1 +
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 3 +++
 2 files changed, 4 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 c0321272c129..0e3b6d414ec4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7991,6 +7991,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 			bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction;
 			bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func;
 			bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix;
+			bundle->surface_updates[planes_count].hdr_mult = dc_plane->hdr_mult;
 		}
 
 		amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index d714728ca143..854510b05194 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -939,6 +939,8 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 	has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb);
 
 #ifdef CONFIG_STEAM_DECK
+	dc_plane_state->hdr_mult = dc_fixpt_from_s3132(dm_plane_state->hdr_mult);
+
 	ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
 	if (ret != -EINVAL)
 		return ret;
@@ -969,5 +971,6 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 			return ret;
 	}
 
+
 	return 0;
 }
-- 
2.39.2


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

* [RFC PATCH 36/40] drm/amd/display: add plane shaper/3D LUT and shaper TF support
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

We already have the steps to program post-blending shaper/3D LUT on AMD
display driver, so that we can reuse them and map plane properties to DC
plane for pre-blending (plane) shaper/3D LUT setup.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 34 +++++++++++++++++--
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |  5 +--
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 854510b05194..e17141fc8d12 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -909,6 +909,35 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
 	}
 	return 0;
 }
+
+static int
+amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state,
+				     struct dc_plane_state *dc_plane_state)
+{
+	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+	enum drm_transfer_function shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+	const struct drm_color_lut *shaper_lut, *lut3d;
+	uint32_t lut3d_size, shaper_size;
+
+	/* We have nothing to do here, return */
+	if (!plane_state->color_mgmt_changed)
+		return 0;
+
+	dc_plane_state->hdr_mult = dc_fixpt_from_s3132(dm_plane_state->hdr_mult);
+
+	shaper_tf = dm_plane_state->shaper_tf;
+	shaper_lut = __extract_blob_lut(dm_plane_state->shaper_lut, &shaper_size);
+	lut3d = __extract_blob_lut(dm_plane_state->lut3d, &lut3d_size);
+	lut3d_size = lut3d != NULL ? lut3d_size : 0;
+	shaper_size = shaper_lut != NULL ? shaper_size : 0;
+
+	amdgpu_dm_atomic_lut3d(lut3d, lut3d_size, dc_plane_state->lut3d_func);
+	ret = amdgpu_dm_atomic_shaper_lut(shaper_lut, false,
+					  drm_tf_to_dc_tf(shaper_tf),
+					  shaper_size, dc_plane_state->in_shaper_func);
+
+	return ret;
+}
 #endif
 
 /**
@@ -939,7 +968,9 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 	has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb);
 
 #ifdef CONFIG_STEAM_DECK
-	dc_plane_state->hdr_mult = dc_fixpt_from_s3132(dm_plane_state->hdr_mult);
+	ret = amdgpu_dm_plane_set_color_properties(plane_state, dc_plane_state);
+	if(ret)
+		return ret;
 
 	ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
 	if (ret != -EINVAL)
@@ -971,6 +1002,5 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 			return ret;
 	}
 
-
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 5800acf6aae1..91fee60410f4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1759,8 +1759,9 @@ static void dcn20_program_pipe(
 		hws->funcs.set_hdr_multiplier(pipe_ctx);
 
 	if (pipe_ctx->update_flags.bits.enable ||
-			pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
-			pipe_ctx->plane_state->update_flags.bits.gamma_change)
+	    pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+	    pipe_ctx->plane_state->update_flags.bits.gamma_change ||
+	    pipe_ctx->plane_state->update_flags.bits.lut_3d)
 		hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
 
 	/* dcn10_translate_regamma_to_hw_format takes 750us to finish
-- 
2.39.2


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

* [RFC PATCH 36/40] drm/amd/display: add plane shaper/3D LUT and shaper TF support
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

We already have the steps to program post-blending shaper/3D LUT on AMD
display driver, so that we can reuse them and map plane properties to DC
plane for pre-blending (plane) shaper/3D LUT setup.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 34 +++++++++++++++++--
 .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |  5 +--
 2 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index 854510b05194..e17141fc8d12 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -909,6 +909,35 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
 	}
 	return 0;
 }
+
+static int
+amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state,
+				     struct dc_plane_state *dc_plane_state)
+{
+	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
+	enum drm_transfer_function shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+	const struct drm_color_lut *shaper_lut, *lut3d;
+	uint32_t lut3d_size, shaper_size;
+
+	/* We have nothing to do here, return */
+	if (!plane_state->color_mgmt_changed)
+		return 0;
+
+	dc_plane_state->hdr_mult = dc_fixpt_from_s3132(dm_plane_state->hdr_mult);
+
+	shaper_tf = dm_plane_state->shaper_tf;
+	shaper_lut = __extract_blob_lut(dm_plane_state->shaper_lut, &shaper_size);
+	lut3d = __extract_blob_lut(dm_plane_state->lut3d, &lut3d_size);
+	lut3d_size = lut3d != NULL ? lut3d_size : 0;
+	shaper_size = shaper_lut != NULL ? shaper_size : 0;
+
+	amdgpu_dm_atomic_lut3d(lut3d, lut3d_size, dc_plane_state->lut3d_func);
+	ret = amdgpu_dm_atomic_shaper_lut(shaper_lut, false,
+					  drm_tf_to_dc_tf(shaper_tf),
+					  shaper_size, dc_plane_state->in_shaper_func);
+
+	return ret;
+}
 #endif
 
 /**
@@ -939,7 +968,9 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 	has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb);
 
 #ifdef CONFIG_STEAM_DECK
-	dc_plane_state->hdr_mult = dc_fixpt_from_s3132(dm_plane_state->hdr_mult);
+	ret = amdgpu_dm_plane_set_color_properties(plane_state, dc_plane_state);
+	if(ret)
+		return ret;
 
 	ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
 	if (ret != -EINVAL)
@@ -971,6 +1002,5 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 			return ret;
 	}
 
-
 	return 0;
 }
diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
index 5800acf6aae1..91fee60410f4 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
@@ -1759,8 +1759,9 @@ static void dcn20_program_pipe(
 		hws->funcs.set_hdr_multiplier(pipe_ctx);
 
 	if (pipe_ctx->update_flags.bits.enable ||
-			pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
-			pipe_ctx->plane_state->update_flags.bits.gamma_change)
+	    pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
+	    pipe_ctx->plane_state->update_flags.bits.gamma_change ||
+	    pipe_ctx->plane_state->update_flags.bits.lut_3d)
 		hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
 
 	/* dcn10_translate_regamma_to_hw_format takes 750us to finish
-- 
2.39.2


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

* [RFC PATCH 37/40] drm/amd/display: handle empty LUTs in __set_input_tf
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

Unlike degamma, blend gamma doesn't support hardcoded curve
(predefined/ROM), but we can use AMD color module to fill blend gamma
parameters when we have non-linear plane gamma TF without plane gamma
LUT. The regular degamma path doesn't hit this.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 21 ++++++++++++-------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index e17141fc8d12..baa7fea9ebae 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -349,21 +349,26 @@ static int __set_input_tf(struct dc_transfer_func *func,
 	struct dc_gamma *gamma = NULL;
 	bool res;
 
-	gamma = dc_create_gamma();
-	if (!gamma)
-		return -ENOMEM;
+	if (lut_size) {
+		gamma = dc_create_gamma();
+		if (!gamma)
+			return -ENOMEM;
 
-	gamma->type = GAMMA_CUSTOM;
-	gamma->num_entries = lut_size;
+		gamma->type = GAMMA_CUSTOM;
+		gamma->num_entries = lut_size;
 
-	__drm_lut_to_dc_gamma(lut, gamma, false);
+		__drm_lut_to_dc_gamma(lut, gamma, false);
+	}
 
-	res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
-	dc_gamma_release(&gamma);
+	res = mod_color_calculate_degamma_params(NULL, func, gamma, gamma != NULL);
+
+	if (gamma)
+		dc_gamma_release(&gamma);
 
 	return res ? 0 : -ENOMEM;
 }
 
+
 #ifdef CONFIG_STEAM_DECK
 static enum dc_transfer_func_predefined drm_tf_to_dc_tf(enum drm_transfer_function drm_tf)
 {
-- 
2.39.2


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

* [RFC PATCH 37/40] drm/amd/display: handle empty LUTs in __set_input_tf
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Joshua Ashton <joshua@froggi.es>

Unlike degamma, blend gamma doesn't support hardcoded curve
(predefined/ROM), but we can use AMD color module to fill blend gamma
parameters when we have non-linear plane gamma TF without plane gamma
LUT. The regular degamma path doesn't hit this.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 21 ++++++++++++-------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index e17141fc8d12..baa7fea9ebae 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -349,21 +349,26 @@ static int __set_input_tf(struct dc_transfer_func *func,
 	struct dc_gamma *gamma = NULL;
 	bool res;
 
-	gamma = dc_create_gamma();
-	if (!gamma)
-		return -ENOMEM;
+	if (lut_size) {
+		gamma = dc_create_gamma();
+		if (!gamma)
+			return -ENOMEM;
 
-	gamma->type = GAMMA_CUSTOM;
-	gamma->num_entries = lut_size;
+		gamma->type = GAMMA_CUSTOM;
+		gamma->num_entries = lut_size;
 
-	__drm_lut_to_dc_gamma(lut, gamma, false);
+		__drm_lut_to_dc_gamma(lut, gamma, false);
+	}
 
-	res = mod_color_calculate_degamma_params(NULL, func, gamma, true);
-	dc_gamma_release(&gamma);
+	res = mod_color_calculate_degamma_params(NULL, func, gamma, gamma != NULL);
+
+	if (gamma)
+		dc_gamma_release(&gamma);
 
 	return res ? 0 : -ENOMEM;
 }
 
+
 #ifdef CONFIG_STEAM_DECK
 static enum dc_transfer_func_predefined drm_tf_to_dc_tf(enum drm_transfer_function drm_tf)
 {
-- 
2.39.2


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

* [RFC PATCH 38/40] drm/amd/display: add DRM plane blend LUT and TF support
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

Map DRM plane blend properties to DPP blend gamma. Plane blend is a
post-3D LUT curve that linearizes color space for blending. It may be
defined by a user-blob LUT and/or predefined transfer function. As
hardcoded curve (ROM) is not supported on blend gamma, we use AMD color
module to fill parameters when setting non-linear TF with empty LUT.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 60 +++++++++++++++++--
 1 file changed, 56 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index baa7fea9ebae..a034c0c0d383 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -493,6 +493,34 @@ static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut,
 	return ret;
 }
 
+static int amdgpu_dm_atomic_blend_lut(const struct drm_color_lut *blend_lut,
+				       bool has_rom,
+				       enum dc_transfer_func_predefined tf,
+				       uint32_t blend_size,
+				       struct dc_transfer_func *func_blend)
+{
+	int ret = 0;
+
+	if (blend_size || tf != TRANSFER_FUNCTION_LINEAR) {
+		/* DRM plane gamma LUT or TF means we are linearizing color
+		 * space before blending (similar to degamma programming). As
+		 * we don't have hardcoded curve support, or we use AMD color
+		 * module to fill the parameters that will be translated to HW
+		 * points.
+		 */
+		func_blend->type = TF_TYPE_DISTRIBUTED_POINTS;
+		func_blend->tf = tf;
+		func_blend->sdr_ref_white_level = 80; /* hardcoded for now */
+
+		ret = __set_input_tf(func_blend, blend_lut, blend_size);
+	} else {
+		func_blend->type = TF_TYPE_BYPASS;
+		func_blend->tf = TRANSFER_FUNCTION_LINEAR;
+	}
+
+	return ret;
+}
+
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
  * interface
  * @dc: Display Core control structure
@@ -921,9 +949,11 @@ amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state,
 {
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
 	enum drm_transfer_function shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
-	const struct drm_color_lut *shaper_lut, *lut3d;
-	uint32_t lut3d_size, shaper_size;
-
+	enum drm_transfer_function blend_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+	const struct drm_color_lut *shaper_lut, *lut3d, *blend_lut;
+	uint32_t lut3d_size, shaper_size, blend_size;
+	int ret;
+	
 	/* We have nothing to do here, return */
 	if (!plane_state->color_mgmt_changed)
 		return 0;
@@ -940,8 +970,30 @@ amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state,
 	ret = amdgpu_dm_atomic_shaper_lut(shaper_lut, false,
 					  drm_tf_to_dc_tf(shaper_tf),
 					  shaper_size, dc_plane_state->in_shaper_func);
+	if (ret) {
+		drm_dbg_kms(plane_state->plane->dev,
+			    "setting plane %d shaper/3d lut failed.\n",
+			    plane_state->plane->index);
 
-	return ret;
+		return ret;
+	}
+
+	blend_tf = dm_plane_state->blend_tf;
+	blend_lut = __extract_blob_lut(dm_plane_state->blend_lut, &blend_size);
+	blend_size = blend_lut != NULL ? blend_size : 0;
+
+	ret = amdgpu_dm_atomic_blend_lut(blend_lut, false,
+					 drm_tf_to_dc_tf(blend_tf),
+					 blend_size, dc_plane_state->blend_tf);
+	if (ret) {
+		drm_dbg_kms(plane_state->plane->dev,
+			    "setting plane %d gamma lut failed.\n",
+			    plane_state->plane->index);
+
+		return ret;
+	}
+
+	return 0;
 }
 #endif
 
-- 
2.39.2


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

* [RFC PATCH 38/40] drm/amd/display: add DRM plane blend LUT and TF support
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Joshua Ashton <joshua@froggi.es>

Map DRM plane blend properties to DPP blend gamma. Plane blend is a
post-3D LUT curve that linearizes color space for blending. It may be
defined by a user-blob LUT and/or predefined transfer function. As
hardcoded curve (ROM) is not supported on blend gamma, we use AMD color
module to fill parameters when setting non-linear TF with empty LUT.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 60 +++++++++++++++++--
 1 file changed, 56 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index baa7fea9ebae..a034c0c0d383 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -493,6 +493,34 @@ static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut,
 	return ret;
 }
 
+static int amdgpu_dm_atomic_blend_lut(const struct drm_color_lut *blend_lut,
+				       bool has_rom,
+				       enum dc_transfer_func_predefined tf,
+				       uint32_t blend_size,
+				       struct dc_transfer_func *func_blend)
+{
+	int ret = 0;
+
+	if (blend_size || tf != TRANSFER_FUNCTION_LINEAR) {
+		/* DRM plane gamma LUT or TF means we are linearizing color
+		 * space before blending (similar to degamma programming). As
+		 * we don't have hardcoded curve support, or we use AMD color
+		 * module to fill the parameters that will be translated to HW
+		 * points.
+		 */
+		func_blend->type = TF_TYPE_DISTRIBUTED_POINTS;
+		func_blend->tf = tf;
+		func_blend->sdr_ref_white_level = 80; /* hardcoded for now */
+
+		ret = __set_input_tf(func_blend, blend_lut, blend_size);
+	} else {
+		func_blend->type = TF_TYPE_BYPASS;
+		func_blend->tf = TRANSFER_FUNCTION_LINEAR;
+	}
+
+	return ret;
+}
+
 /* amdgpu_dm_atomic_shaper_lut3d - set DRM CRTC shaper LUT and 3D LUT to DC
  * interface
  * @dc: Display Core control structure
@@ -921,9 +949,11 @@ amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state,
 {
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
 	enum drm_transfer_function shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
-	const struct drm_color_lut *shaper_lut, *lut3d;
-	uint32_t lut3d_size, shaper_size;
-
+	enum drm_transfer_function blend_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
+	const struct drm_color_lut *shaper_lut, *lut3d, *blend_lut;
+	uint32_t lut3d_size, shaper_size, blend_size;
+	int ret;
+	
 	/* We have nothing to do here, return */
 	if (!plane_state->color_mgmt_changed)
 		return 0;
@@ -940,8 +970,30 @@ amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state,
 	ret = amdgpu_dm_atomic_shaper_lut(shaper_lut, false,
 					  drm_tf_to_dc_tf(shaper_tf),
 					  shaper_size, dc_plane_state->in_shaper_func);
+	if (ret) {
+		drm_dbg_kms(plane_state->plane->dev,
+			    "setting plane %d shaper/3d lut failed.\n",
+			    plane_state->plane->index);
 
-	return ret;
+		return ret;
+	}
+
+	blend_tf = dm_plane_state->blend_tf;
+	blend_lut = __extract_blob_lut(dm_plane_state->blend_lut, &blend_size);
+	blend_size = blend_lut != NULL ? blend_size : 0;
+
+	ret = amdgpu_dm_atomic_blend_lut(blend_lut, false,
+					 drm_tf_to_dc_tf(blend_tf),
+					 blend_size, dc_plane_state->blend_tf);
+	if (ret) {
+		drm_dbg_kms(plane_state->plane->dev,
+			    "setting plane %d gamma lut failed.\n",
+			    plane_state->plane->index);
+
+		return ret;
+	}
+
+	return 0;
 }
 #endif
 
-- 
2.39.2


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

* [RFC PATCH 39/40] drm/amd/display: copy dc_plane color settings to surface_updates
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Melissa Wen, Nicholas Kazlauskas, Joshua Ashton,
	sungjoon.kim

As per previous code, copy shaper, 3d and blend settings from dc_plane
to surface_updates before commit.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++-
 1 file changed, 3 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 0e3b6d414ec4..cdaaec1b2a3a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7987,11 +7987,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 			continue;
 
 		bundle->surface_updates[planes_count].surface = dc_plane;
-		if (new_pcrtc_state->color_mgmt_changed) {
+		if (new_pcrtc_state->color_mgmt_changed || new_plane_state->color_mgmt_changed) {
 			bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction;
 			bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func;
 			bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix;
 			bundle->surface_updates[planes_count].hdr_mult = dc_plane->hdr_mult;
+			bundle->surface_updates[planes_count].func_shaper = dc_plane->in_shaper_func;
+			bundle->surface_updates[planes_count].lut3d_func = dc_plane->lut3d_func;
 		}
 
 		amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state,
-- 
2.39.2


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

* [RFC PATCH 39/40] drm/amd/display: copy dc_plane color settings to surface_updates
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, Melissa Wen,
	linux-kernel

As per previous code, copy shaper, 3d and blend settings from dc_plane
to surface_updates before commit.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 +++-
 1 file changed, 3 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 0e3b6d414ec4..cdaaec1b2a3a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -7987,11 +7987,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 			continue;
 
 		bundle->surface_updates[planes_count].surface = dc_plane;
-		if (new_pcrtc_state->color_mgmt_changed) {
+		if (new_pcrtc_state->color_mgmt_changed || new_plane_state->color_mgmt_changed) {
 			bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction;
 			bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func;
 			bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix;
 			bundle->surface_updates[planes_count].hdr_mult = dc_plane->hdr_mult;
+			bundle->surface_updates[planes_count].func_shaper = dc_plane->in_shaper_func;
+			bundle->surface_updates[planes_count].lut3d_func = dc_plane->lut3d_func;
 		}
 
 		amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state,
-- 
2.39.2


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

* [RFC PATCH 40/40] drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG
  2023-04-23 14:10 ` Melissa Wen
@ 2023-04-23 14:10   ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

From: Joshua Ashton <joshua@froggi.es>

Need to funnel the color caps through to these functions so it can check
that the hardware is capable.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 34 ++++++++++++-------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a034c0c0d383..f0b5f09b9146 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -336,6 +336,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
+ * @caps: dc color capabilities
  * @func: transfer function
  * @lut: lookup table that defines the color space
  * @lut_size: size of respective lut.
@@ -343,7 +344,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
  * Returns:
  * 0 in case of success. -ENOMEM if fails.
  */
-static int __set_input_tf(struct dc_transfer_func *func,
+static int __set_input_tf(struct dc_color_caps *caps, struct dc_transfer_func *func,
 			  const struct drm_color_lut *lut, uint32_t lut_size)
 {
 	struct dc_gamma *gamma = NULL;
@@ -360,7 +361,7 @@ static int __set_input_tf(struct dc_transfer_func *func,
 		__drm_lut_to_dc_gamma(lut, gamma, false);
 	}
 
-	res = mod_color_calculate_degamma_params(NULL, func, gamma, gamma != NULL);
+	res = mod_color_calculate_degamma_params(caps, func, gamma, gamma != NULL);
 
 	if (gamma)
 		dc_gamma_release(&gamma);
@@ -512,7 +513,7 @@ static int amdgpu_dm_atomic_blend_lut(const struct drm_color_lut *blend_lut,
 		func_blend->tf = tf;
 		func_blend->sdr_ref_white_level = 80; /* hardcoded for now */
 
-		ret = __set_input_tf(func_blend, blend_lut, blend_size);
+		ret = __set_input_tf(NULL, func_blend, blend_lut, blend_size);
 	} else {
 		func_blend->type = TF_TYPE_BYPASS;
 		func_blend->tf = TRANSFER_FUNCTION_LINEAR;
@@ -819,7 +820,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 }
 
 static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
-					struct dc_plane_state *dc_plane_state)
+					struct dc_plane_state *dc_plane_state,
+					struct dc_color_caps *caps)
 {
 	const struct drm_color_lut *degamma_lut;
 	enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
@@ -874,7 +876,7 @@ static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
 			dc_plane_state->in_transfer_func->tf =
 				TRANSFER_FUNCTION_LINEAR;
 
-		r = __set_input_tf(dc_plane_state->in_transfer_func,
+		r = __set_input_tf(caps, dc_plane_state->in_transfer_func,
 				   degamma_lut, degamma_size);
 		if (r)
 			return r;
@@ -887,7 +889,7 @@ static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
 		dc_plane_state->in_transfer_func->tf = tf;
 
 		if (tf != TRANSFER_FUNCTION_SRGB &&
-		    !mod_color_calculate_degamma_params(NULL,
+		    !mod_color_calculate_degamma_params(caps,
 			    dc_plane_state->in_transfer_func, NULL, false))
 			return -ENOMEM;
 	}
@@ -898,7 +900,8 @@ static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
 #ifdef CONFIG_STEAM_DECK
 static int
 __set_dm_plane_degamma(struct drm_plane_state *plane_state,
-		       struct dc_plane_state *dc_plane_state)
+		       struct dc_plane_state *dc_plane_state,
+		       struct dc_color_caps *color_caps)
 {
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
 	const struct drm_color_lut *degamma_lut;
@@ -907,6 +910,9 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
 	bool has_degamma_lut;
 	int ret;
 
+	if (dc_plane_state->ctx && dc_plane_state->ctx->dc)
+		color_caps = &dc_plane_state->ctx->dc->caps.color;
+
 	degamma_lut = __extract_blob_lut(dm_plane_state->degamma_lut, &degamma_size);
 
 	has_degamma_lut = degamma_lut &&
@@ -928,8 +934,8 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
 		dc_plane_state->in_transfer_func->type =
 			TF_TYPE_DISTRIBUTED_POINTS;
 
-		ret = __set_input_tf(dc_plane_state->in_transfer_func,
-				   degamma_lut, degamma_size);
+		ret = __set_input_tf(color_caps, dc_plane_state->in_transfer_func,
+				     degamma_lut, degamma_size);
 		if (ret)
 			return ret;
        } else {
@@ -945,7 +951,8 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
 
 static int
 amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state,
-				     struct dc_plane_state *dc_plane_state)
+				     struct dc_plane_state *dc_plane_state,
+				     struct dc_color_caps *color_caps)
 {
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
 	enum drm_transfer_function shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
@@ -1014,6 +1021,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 				      struct drm_plane_state *plane_state,
 				      struct dc_plane_state *dc_plane_state)
 {
+	struct dc_color_caps *color_caps = NULL;
 	bool has_crtc_cm_degamma;
 	int ret;
 
@@ -1025,11 +1033,11 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 	has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb);
 
 #ifdef CONFIG_STEAM_DECK
-	ret = amdgpu_dm_plane_set_color_properties(plane_state, dc_plane_state);
+	ret = amdgpu_dm_plane_set_color_properties(plane_state, dc_plane_state, color_caps);
 	if(ret)
 		return ret;
 
-	ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
+	ret = __set_dm_plane_degamma(plane_state, dc_plane_state, color_caps);
 	if (ret != -EINVAL)
 		return ret;
 
@@ -1054,7 +1062,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 		 * linearize (implicit degamma) from sRGB/BT709 according to
 		 * the input space.
 		 */
-		ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state);
+		ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state, color_caps);
 		if (ret)
 			return ret;
 	}
-- 
2.39.2


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

* [RFC PATCH 40/40] drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG
@ 2023-04-23 14:10   ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-04-23 14:10 UTC (permalink / raw)
  To: amd-gfx, Harry Wentland, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

From: Joshua Ashton <joshua@froggi.es>

Need to funnel the color caps through to these functions so it can check
that the hardware is capable.

Signed-off-by: Joshua Ashton <joshua@froggi.es>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 34 ++++++++++++-------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
index a034c0c0d383..f0b5f09b9146 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
@@ -336,6 +336,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
 /**
  * __set_input_tf - calculates the input transfer function based on expected
  * input space.
+ * @caps: dc color capabilities
  * @func: transfer function
  * @lut: lookup table that defines the color space
  * @lut_size: size of respective lut.
@@ -343,7 +344,7 @@ static int amdgpu_dm_set_atomic_regamma(struct dc_stream_state *stream,
  * Returns:
  * 0 in case of success. -ENOMEM if fails.
  */
-static int __set_input_tf(struct dc_transfer_func *func,
+static int __set_input_tf(struct dc_color_caps *caps, struct dc_transfer_func *func,
 			  const struct drm_color_lut *lut, uint32_t lut_size)
 {
 	struct dc_gamma *gamma = NULL;
@@ -360,7 +361,7 @@ static int __set_input_tf(struct dc_transfer_func *func,
 		__drm_lut_to_dc_gamma(lut, gamma, false);
 	}
 
-	res = mod_color_calculate_degamma_params(NULL, func, gamma, gamma != NULL);
+	res = mod_color_calculate_degamma_params(caps, func, gamma, gamma != NULL);
 
 	if (gamma)
 		dc_gamma_release(&gamma);
@@ -512,7 +513,7 @@ static int amdgpu_dm_atomic_blend_lut(const struct drm_color_lut *blend_lut,
 		func_blend->tf = tf;
 		func_blend->sdr_ref_white_level = 80; /* hardcoded for now */
 
-		ret = __set_input_tf(func_blend, blend_lut, blend_size);
+		ret = __set_input_tf(NULL, func_blend, blend_lut, blend_size);
 	} else {
 		func_blend->type = TF_TYPE_BYPASS;
 		func_blend->tf = TRANSFER_FUNCTION_LINEAR;
@@ -819,7 +820,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc,
 }
 
 static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
-					struct dc_plane_state *dc_plane_state)
+					struct dc_plane_state *dc_plane_state,
+					struct dc_color_caps *caps)
 {
 	const struct drm_color_lut *degamma_lut;
 	enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
@@ -874,7 +876,7 @@ static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
 			dc_plane_state->in_transfer_func->tf =
 				TRANSFER_FUNCTION_LINEAR;
 
-		r = __set_input_tf(dc_plane_state->in_transfer_func,
+		r = __set_input_tf(caps, dc_plane_state->in_transfer_func,
 				   degamma_lut, degamma_size);
 		if (r)
 			return r;
@@ -887,7 +889,7 @@ static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
 		dc_plane_state->in_transfer_func->tf = tf;
 
 		if (tf != TRANSFER_FUNCTION_SRGB &&
-		    !mod_color_calculate_degamma_params(NULL,
+		    !mod_color_calculate_degamma_params(caps,
 			    dc_plane_state->in_transfer_func, NULL, false))
 			return -ENOMEM;
 	}
@@ -898,7 +900,8 @@ static int map_crtc_degamma_to_dc_plane(struct dm_crtc_state *crtc,
 #ifdef CONFIG_STEAM_DECK
 static int
 __set_dm_plane_degamma(struct drm_plane_state *plane_state,
-		       struct dc_plane_state *dc_plane_state)
+		       struct dc_plane_state *dc_plane_state,
+		       struct dc_color_caps *color_caps)
 {
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
 	const struct drm_color_lut *degamma_lut;
@@ -907,6 +910,9 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
 	bool has_degamma_lut;
 	int ret;
 
+	if (dc_plane_state->ctx && dc_plane_state->ctx->dc)
+		color_caps = &dc_plane_state->ctx->dc->caps.color;
+
 	degamma_lut = __extract_blob_lut(dm_plane_state->degamma_lut, &degamma_size);
 
 	has_degamma_lut = degamma_lut &&
@@ -928,8 +934,8 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
 		dc_plane_state->in_transfer_func->type =
 			TF_TYPE_DISTRIBUTED_POINTS;
 
-		ret = __set_input_tf(dc_plane_state->in_transfer_func,
-				   degamma_lut, degamma_size);
+		ret = __set_input_tf(color_caps, dc_plane_state->in_transfer_func,
+				     degamma_lut, degamma_size);
 		if (ret)
 			return ret;
        } else {
@@ -945,7 +951,8 @@ __set_dm_plane_degamma(struct drm_plane_state *plane_state,
 
 static int
 amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state,
-				     struct dc_plane_state *dc_plane_state)
+				     struct dc_plane_state *dc_plane_state,
+				     struct dc_color_caps *color_caps)
 {
 	struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state);
 	enum drm_transfer_function shaper_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
@@ -1014,6 +1021,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 				      struct drm_plane_state *plane_state,
 				      struct dc_plane_state *dc_plane_state)
 {
+	struct dc_color_caps *color_caps = NULL;
 	bool has_crtc_cm_degamma;
 	int ret;
 
@@ -1025,11 +1033,11 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 	has_crtc_cm_degamma = (crtc->cm_has_degamma || crtc->cm_is_degamma_srgb);
 
 #ifdef CONFIG_STEAM_DECK
-	ret = amdgpu_dm_plane_set_color_properties(plane_state, dc_plane_state);
+	ret = amdgpu_dm_plane_set_color_properties(plane_state, dc_plane_state, color_caps);
 	if(ret)
 		return ret;
 
-	ret = __set_dm_plane_degamma(plane_state, dc_plane_state);
+	ret = __set_dm_plane_degamma(plane_state, dc_plane_state, color_caps);
 	if (ret != -EINVAL)
 		return ret;
 
@@ -1054,7 +1062,7 @@ int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
 		 * linearize (implicit degamma) from sRGB/BT709 according to
 		 * the input space.
 		 */
-		ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state);
+		ret = map_crtc_degamma_to_dc_plane(crtc, dc_plane_state, color_caps);
 		if (ret)
 			return ret;
 	}
-- 
2.39.2


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

* Re: [RFC PATCH 05/40] drm/amd/display: add shaper LUT driver-private props
  2023-04-23 14:10   ` Melissa Wen
  (?)
@ 2023-04-23 17:26   ` kernel test robot
  -1 siblings, 0 replies; 141+ messages in thread
From: kernel test robot @ 2023-04-23 17:26 UTC (permalink / raw)
  To: Melissa Wen; +Cc: oe-kbuild-all

Hi Melissa,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build warnings:

[auto build test WARNING on next-20230421]
[also build test WARNING on linus/master v6.3-rc7]
[cannot apply to drm-misc/drm-misc-next v6.3-rc7 v6.3-rc6 v6.3-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Melissa-Wen/drm-amd-display-fix-segment-distribution-for-linear-LUTs/20230423-221602
base:   next-20230421
patch link:    https://lore.kernel.org/r/20230423141051.702990-6-mwen%40igalia.com
patch subject: [RFC PATCH 05/40] drm/amd/display: add shaper LUT driver-private props
config: sparc-allyesconfig (https://download.01.org/0day-ci/archive/20230424/202304240140.BTgpUYgN-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/6ff0b9c8b0f775b8dfc3201db5b743c17728c5a7
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Melissa-Wen/drm-amd-display-fix-segment-distribution-for-linear-LUTs/20230423-221602
        git checkout 6ff0b9c8b0f775b8dfc3201db5b743c17728c5a7
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc SHELL=/bin/bash drivers/gpu/drm/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202304240140.BTgpUYgN-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_crtc.c:320: warning: expecting prototype for drm_crtc_additional_color_mgmt(). Prototype was for dm_crtc_additional_color_mgmt() instead


vim +320 drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_crtc.c

   308	
   309	#ifdef CONFIG_STEAM_DECK
   310	/**
   311	 * drm_crtc_additional_color_mgmt - enable additional color properties
   312	 * @crtc: DRM CRTC
   313	 *
   314	 * This function lets the driver enable the 3D LUT color correction property
   315	 * on a CRTC. This includes shaper LUT, 3D LUT and regamma TF. The shaper
   316	 * LUT and 3D LUT property is only attached if its size is not 0.
   317	 */
   318	static void
   319	dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
 > 320	{
   321		struct amdgpu_device *adev = drm_to_adev(crtc->dev);
   322	
   323		if (adev->dm.dc->caps.color.mpc.num_3dluts) {
   324			drm_object_attach_property(&crtc->base,
   325						   adev->mode_info.shaper_lut_property, 0);
   326			drm_object_attach_property(&crtc->base,
   327						   adev->mode_info.shaper_lut_size_property,
   328						   MAX_COLOR_LUT_ENTRIES);
   329		}
   330	}
   331	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

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

* Re: [RFC PATCH 26/40] drm/amd/display: add CRTC shaper LUT support to amd color pipeline
  2023-04-23 14:10   ` Melissa Wen
  (?)
@ 2023-04-23 18:48   ` kernel test robot
  -1 siblings, 0 replies; 141+ messages in thread
From: kernel test robot @ 2023-04-23 18:48 UTC (permalink / raw)
  To: Melissa Wen; +Cc: oe-kbuild-all

Hi Melissa,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build warnings:

[auto build test WARNING on next-20230421]
[cannot apply to drm-misc/drm-misc-next v6.3-rc7 v6.3-rc6 v6.3-rc5 linus/master v6.3-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Melissa-Wen/drm-amd-display-fix-segment-distribution-for-linear-LUTs/20230423-221602
base:   next-20230421
patch link:    https://lore.kernel.org/r/20230423141051.702990-27-mwen%40igalia.com
patch subject: [RFC PATCH 26/40] drm/amd/display: add CRTC shaper LUT support to amd color pipeline
config: sparc-allyesconfig (https://download.01.org/0day-ci/archive/20230424/202304240219.4mzX9F5L-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/474b7772c7abf6138de47078874bc4b00b5bf881
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Melissa-Wen/drm-amd-display-fix-segment-distribution-for-linear-LUTs/20230423-221602
        git checkout 474b7772c7abf6138de47078874bc4b00b5bf881
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc SHELL=/bin/bash drivers/gpu/drm/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202304240219.4mzX9F5L-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_color.c:527: warning: expecting prototype for amdgpu_dm_lut3d_size(). Prototype was for amdgpu_dm_get_lut3d_size() instead


vim +527 drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm_color.c

bacba5117b71f1 Melissa Wen   2023-04-23  516  
bacba5117b71f1 Melissa Wen   2023-04-23  517  /**
bacba5117b71f1 Melissa Wen   2023-04-23  518   * amdgpu_dm_lut3d_size - get expected size according to hw color caps
bacba5117b71f1 Melissa Wen   2023-04-23  519   * @adev: amdgpu device
bacba5117b71f1 Melissa Wen   2023-04-23  520   * @lut_size: default size
bacba5117b71f1 Melissa Wen   2023-04-23  521   *
bacba5117b71f1 Melissa Wen   2023-04-23  522   * Return:
bacba5117b71f1 Melissa Wen   2023-04-23  523   * lut_size if DC 3D LUT is supported, zero otherwise.
bacba5117b71f1 Melissa Wen   2023-04-23  524   */
bacba5117b71f1 Melissa Wen   2023-04-23  525  static uint32_t amdgpu_dm_get_lut3d_size(struct amdgpu_device *adev,
bacba5117b71f1 Melissa Wen   2023-04-23  526  					 uint32_t lut_size)
bacba5117b71f1 Melissa Wen   2023-04-23 @527  {
bacba5117b71f1 Melissa Wen   2023-04-23  528  	return adev->dm.dc->caps.color.mpc.num_3dluts ? lut_size : 0;
2da05dc4c5ba22 Joshua Ashton 2023-04-23  529  }
2da05dc4c5ba22 Joshua Ashton 2023-04-23  530  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests

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

* Re: [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt
  2023-04-23 14:10 ` Melissa Wen
@ 2023-05-08 21:24   ` Harry Wentland
  -1 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, airlied, christian.koenig, daniel, maarten.lankhorst,
	mripard, tzimmermann, Xinhui.Pan
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel



On 4/23/23 10:10, Melissa Wen wrote:
> Hi all,
> 
> Joshua Ashton and I (with the great collaboration of Harry Wentland -
> thanks) have been working on KMS color pipeline enhancement for Steam
> Deck/SteamOS by exposing the large set of color caps available in AMD
> display HW.
> 

Thank you for your work on this.

> This patchset results from this full-stack work, including pre-blending
> and post-blending new color properties. The first two patches fix
> quantization issues on shaper LUT programming. Just after, we have one
> patch that adds a config option to restrict AMD colo feature usage. The
> following 13 patches implement AMD driver-private color properties
> (pending detachment of property counter and plane color_mgmt_changed
> from DRM). Finally, the last 24 patches rework the AMD display manager
> and color management to support the properties exposed.
> 
> In short, for pre-blending, we added the following:
> - plane degamma LUT and predefined transfer function;
> - plane HDR multiplier
> - plane shaper LUT/transfer function;
> - plane 3D LUT; and finally,
> - plane blend LUT/transfer function, just before blending.
> 
> After blending, we already have DRM CRTC degamma/gamma LUTs and CTM,
> therefore, we extend CRTC color pipeline with the following:
> - CRTC shaper LUT/transfer function;
> - CRTC 3D LUT; and
> - CRTC gamma transfer function.
> 
> You can already find the AMD color capabilities and color management
> pipeline documented here:
> https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties
> 
> In previous iterations, we tried to provide a generic solution for
> post-blending shaper and 3D LUT [1][2][3], and also Alex Hung worked on
> a pre-blending 3D LUT solution[4] extending plane color mgmt proposal
> from Uma Shankar [5]. However, we identified during our work [6] that
> AMD provides many other valuable capabilities that we don't find in
> other vendors, so we started to work on AMD driver-private color
> properties that better describe its color pipeline, enabling us to
> expose full AMD color capabilities on Deck HW.
> 
> Our primary purpose is to avoid usage limitations of color calibration
> features provided by HW just because we don't have an interface for
> that. At the same time, a generic solution doesn't fit well since some
> of these capabilities seem AMD HW specific, such as hardcoded
> curve/predefined transfer function and shaper 1D LUTs sandwiching 3D
> LUT.
> 
> So far, we keep these properties' usage under an AMD display config
> option (STEAM_DECK). However, we are fine with having them fully
> available to other DCN HW generations. In the current proposal, we are
> already checking ASICs before exposing a color feature. We can work on
> 3D LUT resource acquisition details to fit them to DCN 3+ families that
> support them. Indeed, before moving to these config boundaries, we
> started working on an open solution for any AMD HW [7].
> 

The problem with a CONFIG_XYZ option is that it becomes uAPI and can't be
removed. I feel we have a good proposal going for the generic solution.
Would it work for you if we don't make this a CONFIG_ option? What I mean
is using

#define AMD_PRIVATE_COLOR

around the interface bits, which are only compiled when building with
-DAMD_PRIVATE_COLOR

That way we have the option to rip the driver-private stuff out later
while still allowing for experimentation now.

Or, alternatively, we can merge everything but the stuff currently
guarded by CONFIG_STEAM_DECK, so that custom kernels can enable this
functionality by simply merging one patch that includes all the
CONFIG_STEAM_DECK stuff.

This will allow us to merge the vast majority of the code without
having to maintain it in downstream repo.

> The userspace case here is Gamescope which is the compositor for
> SteamOS. It's already using all of this functionality (although with a
> VALVE1_ prefix instead of AMD) to implement its color management
> pipeline right now:
> https://github.com/ValveSoftware/gamescope
> 
> We are planning on shipping our color management support with gamut
> mapping, HDR, SDR on HDR, HDR on SDR, and much more in Steam OS 3.5. A
> brief overview of our color pipeline can be found here:
> https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png
> 
> We have also had some other userspace interests from Xaver Hugl (KDE) in
> experimenting with these properties for their HDR/color bring-up before
> a generic interface is settled on also.
> 
> It still needs AMD-specific IGT tests; we are working on documentation
> and adding plane CTM support too. 
> 
> We decided first to share our work to collect thoughts and open for
> discussion, even with missing refinements, since driver-private
> properties are not the usual DMR/KMS color management approach.
> 
> Please, let us know your thoughts.
> 

As discussed at the hackfest I think it's a good idea to have something
that's easy to enable for the purposes of experimentation (and to
help downstream users that help us figure out how this all fits
together, i.e. SteamOS).

Harry

> Best Regards,
> 
> Signed-off-by: Joshua Ashton <joshua@froggi.es>
> Signed-off-by: Melissa Wen<mwen@igalia.com>
> 
> [1] https://lore.kernel.org/dri-devel/20220619223104.667413-1-mwen@igalia.com/
> [2] https://lore.kernel.org/amd-gfx/20220906164628.2361811-1-mwen@igalia.com/
> [3] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-mwen@igalia.com/
> [4] https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.hung@amd.com/
> [5] https://lore.kernel.org/dri-devel/20210906213904.27918-1-uma.shankar@intel.com/
> [6] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-color-mgmt
> [7] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-private-color-mgmt
> 
> Harry Wentland (2):
>   drm/amd/display: fix segment distribution for linear LUTs
>   drm/amd/display: fix the delta clamping for shaper LUT
> 
> Joshua Ashton (15):
>   drm/amd/display: add CRTC gamma TF to driver-private props
>   drm/amd/display: add plane degamma LUT driver-private props
>   drm/amd/display: add plane degamma TF driver-private property
>   drm/amd/display: add plane HDR multiplier driver-private property
>   drm/amd/display: add plane blend LUT and TF driver-private properties
>   drm/amd/display: copy 3D LUT settings from crtc state to stream_update
>   drm/amd/display: dynamically acquire 3DLUT resources for color changes
>   drm/amd/display: add CRTC regamma TF support
>   drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
>   drm/amd/display: add support for plane degamma TF and LUT properties
>   drm/amd/display: add dc_fixpt_from_s3132 helper
>   drm/adm/display: add HDR multiplier support
>   drm/amd/display: handle empty LUTs in __set_input_tf
>   drm/amd/display: add DRM plane blend LUT and TF support
>   drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG
> 
> Melissa Wen (23):
>   drm/amd/display: introduce Steam Deck color features to AMD display
>     driver
>   drm/drm_mode_object: increase max objects to accommodate new color
>     props
>   drm/amd/display: add shaper LUT driver-private props
>   drm/amd/display: add 3D LUT driver-private props
>   drm/drm_plane: track color mgmt changes per plane
>   drm/amd/display: move replace blob func to dm plane
>   drm/amd/display: add plane 3D LUT driver-private properties
>   drm/amd/display: add plane shaper LUT driver-private properties
>   drm/amd/display: add plane shaper TF driver-private property
>   drm/amd/display: add comments to describe DM crtc color mgmt behavior
>   drm/amd/display: encapsulate atomic regamma operation
>   drm/amd/display: update lut3d and shaper lut to stream
>   drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
>   drm/amd/display: handle MPC 3D LUT resources for a given context
>   drm/amd/display: add CRTC 3D LUT support to amd color pipeline
>   drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
>   drm/amd/display: add CRTC shaper LUT support to amd color pipeline
>   drm/amd/display: add CRTC shaper TF support
>   drm/amd/display: mark plane as needing reset if plane color mgmt
>     changes
>   drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
>   drm/amd/display: reject atomic commit if setting both plane and CRTC
>     degamma
>   drm/amd/display: add plane shaper/3D LUT and shaper TF support
>   drm/amd/display: copy dc_plane color settings to surface_updates
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 153 +++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  92 +++
>  drivers/gpu/drm/amd/display/Kconfig           |   6 +
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  31 +-
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 120 +++-
>  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 613 ++++++++++++++++--
>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 124 +++-
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 238 +++++++
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |   7 +
>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  49 +-
>  drivers/gpu/drm/amd/display/dc/dc.h           |   8 +
>  .../amd/display/dc/dcn10/dcn10_cm_common.c    | 109 +++-
>  .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   5 +-
>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   9 +-
>  .../amd/display/dc/dcn301/dcn301_resource.c   |  26 +-
>  .../gpu/drm/amd/display/include/fixed31_32.h  |  12 +
>  drivers/gpu/drm/drm_atomic.c                  |   1 +
>  drivers/gpu/drm/drm_atomic_state_helper.c     |   1 +
>  include/drm/drm_mode_object.h                 |   2 +-
>  include/drm/drm_plane.h                       |   7 +
>  20 files changed, 1509 insertions(+), 104 deletions(-)
> 



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

* Re: [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt
@ 2023-05-08 21:24   ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, airlied, christian.koenig, daniel, maarten.lankhorst,
	mripard, tzimmermann, Xinhui.Pan
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim



On 4/23/23 10:10, Melissa Wen wrote:
> Hi all,
> 
> Joshua Ashton and I (with the great collaboration of Harry Wentland -
> thanks) have been working on KMS color pipeline enhancement for Steam
> Deck/SteamOS by exposing the large set of color caps available in AMD
> display HW.
> 

Thank you for your work on this.

> This patchset results from this full-stack work, including pre-blending
> and post-blending new color properties. The first two patches fix
> quantization issues on shaper LUT programming. Just after, we have one
> patch that adds a config option to restrict AMD colo feature usage. The
> following 13 patches implement AMD driver-private color properties
> (pending detachment of property counter and plane color_mgmt_changed
> from DRM). Finally, the last 24 patches rework the AMD display manager
> and color management to support the properties exposed.
> 
> In short, for pre-blending, we added the following:
> - plane degamma LUT and predefined transfer function;
> - plane HDR multiplier
> - plane shaper LUT/transfer function;
> - plane 3D LUT; and finally,
> - plane blend LUT/transfer function, just before blending.
> 
> After blending, we already have DRM CRTC degamma/gamma LUTs and CTM,
> therefore, we extend CRTC color pipeline with the following:
> - CRTC shaper LUT/transfer function;
> - CRTC 3D LUT; and
> - CRTC gamma transfer function.
> 
> You can already find the AMD color capabilities and color management
> pipeline documented here:
> https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties
> 
> In previous iterations, we tried to provide a generic solution for
> post-blending shaper and 3D LUT [1][2][3], and also Alex Hung worked on
> a pre-blending 3D LUT solution[4] extending plane color mgmt proposal
> from Uma Shankar [5]. However, we identified during our work [6] that
> AMD provides many other valuable capabilities that we don't find in
> other vendors, so we started to work on AMD driver-private color
> properties that better describe its color pipeline, enabling us to
> expose full AMD color capabilities on Deck HW.
> 
> Our primary purpose is to avoid usage limitations of color calibration
> features provided by HW just because we don't have an interface for
> that. At the same time, a generic solution doesn't fit well since some
> of these capabilities seem AMD HW specific, such as hardcoded
> curve/predefined transfer function and shaper 1D LUTs sandwiching 3D
> LUT.
> 
> So far, we keep these properties' usage under an AMD display config
> option (STEAM_DECK). However, we are fine with having them fully
> available to other DCN HW generations. In the current proposal, we are
> already checking ASICs before exposing a color feature. We can work on
> 3D LUT resource acquisition details to fit them to DCN 3+ families that
> support them. Indeed, before moving to these config boundaries, we
> started working on an open solution for any AMD HW [7].
> 

The problem with a CONFIG_XYZ option is that it becomes uAPI and can't be
removed. I feel we have a good proposal going for the generic solution.
Would it work for you if we don't make this a CONFIG_ option? What I mean
is using

#define AMD_PRIVATE_COLOR

around the interface bits, which are only compiled when building with
-DAMD_PRIVATE_COLOR

That way we have the option to rip the driver-private stuff out later
while still allowing for experimentation now.

Or, alternatively, we can merge everything but the stuff currently
guarded by CONFIG_STEAM_DECK, so that custom kernels can enable this
functionality by simply merging one patch that includes all the
CONFIG_STEAM_DECK stuff.

This will allow us to merge the vast majority of the code without
having to maintain it in downstream repo.

> The userspace case here is Gamescope which is the compositor for
> SteamOS. It's already using all of this functionality (although with a
> VALVE1_ prefix instead of AMD) to implement its color management
> pipeline right now:
> https://github.com/ValveSoftware/gamescope
> 
> We are planning on shipping our color management support with gamut
> mapping, HDR, SDR on HDR, HDR on SDR, and much more in Steam OS 3.5. A
> brief overview of our color pipeline can be found here:
> https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png
> 
> We have also had some other userspace interests from Xaver Hugl (KDE) in
> experimenting with these properties for their HDR/color bring-up before
> a generic interface is settled on also.
> 
> It still needs AMD-specific IGT tests; we are working on documentation
> and adding plane CTM support too. 
> 
> We decided first to share our work to collect thoughts and open for
> discussion, even with missing refinements, since driver-private
> properties are not the usual DMR/KMS color management approach.
> 
> Please, let us know your thoughts.
> 

As discussed at the hackfest I think it's a good idea to have something
that's easy to enable for the purposes of experimentation (and to
help downstream users that help us figure out how this all fits
together, i.e. SteamOS).

Harry

> Best Regards,
> 
> Signed-off-by: Joshua Ashton <joshua@froggi.es>
> Signed-off-by: Melissa Wen<mwen@igalia.com>
> 
> [1] https://lore.kernel.org/dri-devel/20220619223104.667413-1-mwen@igalia.com/
> [2] https://lore.kernel.org/amd-gfx/20220906164628.2361811-1-mwen@igalia.com/
> [3] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-mwen@igalia.com/
> [4] https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.hung@amd.com/
> [5] https://lore.kernel.org/dri-devel/20210906213904.27918-1-uma.shankar@intel.com/
> [6] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-color-mgmt
> [7] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-private-color-mgmt
> 
> Harry Wentland (2):
>   drm/amd/display: fix segment distribution for linear LUTs
>   drm/amd/display: fix the delta clamping for shaper LUT
> 
> Joshua Ashton (15):
>   drm/amd/display: add CRTC gamma TF to driver-private props
>   drm/amd/display: add plane degamma LUT driver-private props
>   drm/amd/display: add plane degamma TF driver-private property
>   drm/amd/display: add plane HDR multiplier driver-private property
>   drm/amd/display: add plane blend LUT and TF driver-private properties
>   drm/amd/display: copy 3D LUT settings from crtc state to stream_update
>   drm/amd/display: dynamically acquire 3DLUT resources for color changes
>   drm/amd/display: add CRTC regamma TF support
>   drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
>   drm/amd/display: add support for plane degamma TF and LUT properties
>   drm/amd/display: add dc_fixpt_from_s3132 helper
>   drm/adm/display: add HDR multiplier support
>   drm/amd/display: handle empty LUTs in __set_input_tf
>   drm/amd/display: add DRM plane blend LUT and TF support
>   drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG
> 
> Melissa Wen (23):
>   drm/amd/display: introduce Steam Deck color features to AMD display
>     driver
>   drm/drm_mode_object: increase max objects to accommodate new color
>     props
>   drm/amd/display: add shaper LUT driver-private props
>   drm/amd/display: add 3D LUT driver-private props
>   drm/drm_plane: track color mgmt changes per plane
>   drm/amd/display: move replace blob func to dm plane
>   drm/amd/display: add plane 3D LUT driver-private properties
>   drm/amd/display: add plane shaper LUT driver-private properties
>   drm/amd/display: add plane shaper TF driver-private property
>   drm/amd/display: add comments to describe DM crtc color mgmt behavior
>   drm/amd/display: encapsulate atomic regamma operation
>   drm/amd/display: update lut3d and shaper lut to stream
>   drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
>   drm/amd/display: handle MPC 3D LUT resources for a given context
>   drm/amd/display: add CRTC 3D LUT support to amd color pipeline
>   drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
>   drm/amd/display: add CRTC shaper LUT support to amd color pipeline
>   drm/amd/display: add CRTC shaper TF support
>   drm/amd/display: mark plane as needing reset if plane color mgmt
>     changes
>   drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
>   drm/amd/display: reject atomic commit if setting both plane and CRTC
>     degamma
>   drm/amd/display: add plane shaper/3D LUT and shaper TF support
>   drm/amd/display: copy dc_plane color settings to surface_updates
> 
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 153 +++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  92 +++
>  drivers/gpu/drm/amd/display/Kconfig           |   6 +
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  31 +-
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 120 +++-
>  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 613 ++++++++++++++++--
>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 124 +++-
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 238 +++++++
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |   7 +
>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  49 +-
>  drivers/gpu/drm/amd/display/dc/dc.h           |   8 +
>  .../amd/display/dc/dcn10/dcn10_cm_common.c    | 109 +++-
>  .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   5 +-
>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   9 +-
>  .../amd/display/dc/dcn301/dcn301_resource.c   |  26 +-
>  .../gpu/drm/amd/display/include/fixed31_32.h  |  12 +
>  drivers/gpu/drm/drm_atomic.c                  |   1 +
>  drivers/gpu/drm/drm_atomic_state_helper.c     |   1 +
>  include/drm/drm_mode_object.h                 |   2 +-
>  include/drm/drm_plane.h                       |   7 +
>  20 files changed, 1509 insertions(+), 104 deletions(-)
> 



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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
  2023-04-23 14:10   ` Melissa Wen
@ 2023-05-08 21:24     ` Harry Wentland
  -1 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

On 4/23/23 10:10, Melissa Wen wrote:
> We are enabling a large set of color calibration features to enhance KMS
> color mgmt but these properties are specific of AMD display HW, and
> cannot be provided by other vendors. Therefore, set a config option to
> enable AMD driver-private properties used on Steam Deck color mgmt
> pipeline.
> 
> Co-developed-by: Joshua Ashton <joshua@froggi.es>
> Signed-off-by: Joshua Ashton <joshua@froggi.es>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> ---
>  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
> index 06b438217c61..c45a8deb1098 100644
> --- a/drivers/gpu/drm/amd/display/Kconfig
> +++ b/drivers/gpu/drm/amd/display/Kconfig
> @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
>              of crc of specific region via debugfs.
>              Cooperate with specific DMCU FW.
>  
> +config STEAM_DECK
> +	bool "Enable color calibration features for Steam Deck"
> +	depends on DRM_AMD_DC
> +	help
> +	  Choose this option if you want to use AMDGPU features for broader
> +	  color management support on Steam Deck.
>  

If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
us from requiring to support this forever.

Harry

>  endmenu



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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
@ 2023-05-08 21:24     ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim

On 4/23/23 10:10, Melissa Wen wrote:
> We are enabling a large set of color calibration features to enhance KMS
> color mgmt but these properties are specific of AMD display HW, and
> cannot be provided by other vendors. Therefore, set a config option to
> enable AMD driver-private properties used on Steam Deck color mgmt
> pipeline.
> 
> Co-developed-by: Joshua Ashton <joshua@froggi.es>
> Signed-off-by: Joshua Ashton <joshua@froggi.es>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> ---
>  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
> index 06b438217c61..c45a8deb1098 100644
> --- a/drivers/gpu/drm/amd/display/Kconfig
> +++ b/drivers/gpu/drm/amd/display/Kconfig
> @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
>              of crc of specific region via debugfs.
>              Cooperate with specific DMCU FW.
>  
> +config STEAM_DECK
> +	bool "Enable color calibration features for Steam Deck"
> +	depends on DRM_AMD_DC
> +	help
> +	  Choose this option if you want to use AMDGPU features for broader
> +	  color management support on Steam Deck.
>  

If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
us from requiring to support this forever.

Harry

>  endmenu



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

* Re: [RFC PATCH 05/40] drm/amd/display: add shaper LUT driver-private props
  2023-04-23 14:10   ` Melissa Wen
@ 2023-05-08 21:24     ` Harry Wentland
  -1 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim



On 4/23/23 10:10, Melissa Wen wrote:
> CRTC shaper LUT shapes the content after blending, i.e., de-linearizes
> or normalizes space before applying a 3D LUT color correction. In the
> next patch, we add CRTC 3D LUT property to DRM color management after
> this shaper LUT and before the current CRTC gamma LUT.
> 

It might be good to describe the motivation behind the "de-linearization"
of pixels. Since a 3DLUT has a limited number of entries in each dimension
we want to use them in an optimal fashion. This means using the 3DLUT in
a colorspace that is optimized for human vision, such as sRGB, PQ, or
another non-linear space.

> Signed-off-by: Melissa Wen <mwen@igalia.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  28 ++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  14 ++
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  17 +++
>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 122 +++++++++++++++++-
>  4 files changed, 179 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index 8632ab695a6c..44c22cb87dde 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -1247,6 +1247,30 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
>  	return &amdgpu_fb->base;
>  }
>  
> +#ifdef CONFIG_STEAM_DECK

Something like AMD_PRIVATE_COLOR would be better.

It might also be enough to guard only the bits that make the uAPI
appear, such as drm_property_create, etc.

Harry

> +static int
> +amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> +{
> +	struct drm_property *prop;
> +
> +	prop = drm_property_create(adev_to_drm(adev),
> +				   DRM_MODE_PROP_BLOB,
> +				   "AMD_SHAPER_LUT", 0);
> +	if (!prop)
> +		return -ENOMEM;
> +	adev->mode_info.shaper_lut_property = prop;
> +
> +	prop = drm_property_create_range(adev_to_drm(adev),
> +					 DRM_MODE_PROP_IMMUTABLE,
> +					 "AMD_SHAPER_LUT_SIZE", 0, UINT_MAX);
> +	if (!prop)
> +		return -ENOMEM;
> +	adev->mode_info.shaper_lut_size_property = prop;
> +
> +	return 0;
> +}
> +#endif
> +
>  const struct drm_mode_config_funcs amdgpu_mode_funcs = {
>  	.fb_create = amdgpu_display_user_framebuffer_create,
>  };
> @@ -1323,6 +1347,10 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
>  			return -ENOMEM;
>  	}
>  
> +#ifdef CONFIG_STEAM_DECK
> +	if (amdgpu_display_create_color_properties(adev))
> +		return -ENOMEM;
> +#endif
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> index b8633df418d4..1fd3497af3b5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> @@ -344,6 +344,20 @@ struct amdgpu_mode_info {
>  	int			disp_priority;
>  	const struct amdgpu_display_funcs *funcs;
>  	const enum drm_plane_type *plane_type;
> +
> +	/* Driver-private color mgmt props */
> +#ifdef CONFIG_STEAM_DECK
> +	/**
> +	 * @shaper_lut_property: CRTC property to set post-blending shaper LUT
> +	 * that converts content before 3D LUT gamma correction.
> +	 */
> +	struct drm_property *shaper_lut_property;
> +	/**
> +	 * @shaper_lut_size_property: CRTC property for the size of
> +	 * post-blending shaper LUT as supported by the driver (read-only).
> +	 */
> +	struct drm_property *shaper_lut_size_property;
> +#endif
>  };
>  
>  #define AMDGPU_MAX_BL_LEVEL 0xFF
> 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 2e2413fd73a4..de63455896cc 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -726,6 +726,23 @@ struct dm_crtc_state {
>  	struct dc_info_packet vrr_infopacket;
>  
>  	int abm_level;
> +
> +#ifdef CONFIG_STEAM_DECK
> +	/* AMD driver-private color mgmt pipeline
> +	 *
> +	 * DRM provides CRTC degamma/ctm/gamma color mgmt features, but AMD HW
> +	 * has a larger set of post-blending color calibration features, as
> +	 * below:
> +	 */
> +	/**
> +	 * @shaper_lut:
> +	 *
> +	 * Lookup table used to de-linearize pixel data for gamma correction.
> +	 * See drm_crtc_enable_color_mgmt(). The blob (if not NULL) is an array
> +	 * of &struct drm_color_lut.
> +	 */
> +	struct drm_property_blob *shaper_lut;
> +#endif
>  };
>  
>  #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> index e3762e806617..503433e5cb38 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> @@ -229,7 +229,9 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
>  	if (cur->stream)
>  		dc_stream_release(cur->stream);
>  
> -
> +#ifdef CONFIG_STEAM_DECK
> +	drm_property_blob_put(cur->shaper_lut);
> +#endif
>  	__drm_atomic_helper_crtc_destroy_state(state);
>  
>  
> @@ -266,7 +268,12 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
>  	state->crc_skip_count = cur->crc_skip_count;
>  	state->mpo_requested = cur->mpo_requested;
>  	/* TODO Duplicate dc_stream after objects are stream object is flattened */
> +#ifdef CONFIG_STEAM_DECK
> +	state->shaper_lut = cur->shaper_lut;
>  
> +	if (state->shaper_lut)
> +		drm_property_blob_get(state->shaper_lut);
> +#endif
>  	return &state->base;
>  }
>  
> @@ -299,6 +306,111 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc)
>  }
>  #endif
>  
> +#ifdef CONFIG_STEAM_DECK
> +/**
> + * drm_crtc_additional_color_mgmt - enable additional color properties
> + * @crtc: DRM CRTC
> + *
> + * This function lets the driver enable the 3D LUT color correction property
> + * on a CRTC. This includes shaper LUT, 3D LUT and regamma TF. The shaper
> + * LUT and 3D LUT property is only attached if its size is not 0.
> + */
> +static void
> +dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> +{
> +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> +
> +	if (adev->dm.dc->caps.color.mpc.num_3dluts) {
> +		drm_object_attach_property(&crtc->base,
> +					   adev->mode_info.shaper_lut_property, 0);
> +		drm_object_attach_property(&crtc->base,
> +					   adev->mode_info.shaper_lut_size_property,
> +					   MAX_COLOR_LUT_ENTRIES);
> +	}
> +}
> +
> +static int
> +atomic_replace_property_blob_from_id(struct drm_device *dev,
> +					 struct drm_property_blob **blob,
> +					 uint64_t blob_id,
> +					 ssize_t expected_size,
> +					 ssize_t expected_elem_size,
> +					 bool *replaced)
> +{
> +	struct drm_property_blob *new_blob = NULL;
> +
> +	if (blob_id != 0) {
> +		new_blob = drm_property_lookup_blob(dev, blob_id);
> +		if (new_blob == NULL)
> +			return -EINVAL;
> +
> +		if (expected_size > 0 &&
> +		    new_blob->length != expected_size) {
> +			drm_property_blob_put(new_blob);
> +			return -EINVAL;
> +		}
> +		if (expected_elem_size > 0 &&
> +		    new_blob->length % expected_elem_size != 0) {
> +			drm_property_blob_put(new_blob);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	*replaced |= drm_property_replace_blob(blob, new_blob);
> +	drm_property_blob_put(new_blob);
> +
> +	return 0;
> +}
> +
> +static int
> +amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> +				   struct drm_crtc_state *state,
> +				   struct drm_property *property,
> +				   uint64_t val)
> +{
> +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> +	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> +	bool replaced = false;
> +	int ret;
> +
> +	if (property == adev->mode_info.shaper_lut_property) {
> +		ret = atomic_replace_property_blob_from_id(crtc->dev,
> +					&acrtc_state->shaper_lut,
> +					val,
> +					-1, sizeof(struct drm_color_lut),
> +					&replaced);
> +		acrtc_state->base.color_mgmt_changed |= replaced;
> +		return ret;
> +	} else {
> +		drm_dbg_atomic(crtc->dev,
> +			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> +			       crtc->base.id, crtc->name,
> +			       property->base.id, property->name);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> +				   const struct drm_crtc_state *state,
> +				   struct drm_property *property,
> +				   uint64_t *val)
> +{
> +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> +	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> +
> +	if (property == adev->mode_info.shaper_lut_property)
> +		*val = (acrtc_state->shaper_lut) ?
> +			acrtc_state->shaper_lut->base.id : 0;
> +	else
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +#endif
> +
>  /* Implemented only the options currently available for the driver */
>  static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
>  	.reset = dm_crtc_reset_state,
> @@ -317,6 +429,10 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
>  #if defined(CONFIG_DEBUG_FS)
>  	.late_register = amdgpu_dm_crtc_late_register,
>  #endif
> +#ifdef CONFIG_STEAM_DECK
> +	.atomic_set_property = amdgpu_dm_atomic_crtc_set_property,
> +	.atomic_get_property = amdgpu_dm_atomic_crtc_get_property,
> +#endif
>  };
>  
>  static void dm_crtc_helper_disable(struct drm_crtc *crtc)
> @@ -477,9 +593,11 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
>  	is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch;
>  	drm_crtc_enable_color_mgmt(&acrtc->base, is_dcn ? MAX_COLOR_LUT_ENTRIES : 0,
>  				   true, MAX_COLOR_LUT_ENTRIES);
> -
>  	drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES);
>  
> +#ifdef CONFIG_STEAM_DECK
> +	dm_crtc_additional_color_mgmt(&acrtc->base);
> +#endif
>  	return 0;
>  
>  fail:



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

* Re: [RFC PATCH 05/40] drm/amd/display: add shaper LUT driver-private props
@ 2023-05-08 21:24     ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel



On 4/23/23 10:10, Melissa Wen wrote:
> CRTC shaper LUT shapes the content after blending, i.e., de-linearizes
> or normalizes space before applying a 3D LUT color correction. In the
> next patch, we add CRTC 3D LUT property to DRM color management after
> this shaper LUT and before the current CRTC gamma LUT.
> 

It might be good to describe the motivation behind the "de-linearization"
of pixels. Since a 3DLUT has a limited number of entries in each dimension
we want to use them in an optimal fashion. This means using the 3DLUT in
a colorspace that is optimized for human vision, such as sRGB, PQ, or
another non-linear space.

> Signed-off-by: Melissa Wen <mwen@igalia.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  28 ++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  14 ++
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  17 +++
>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 122 +++++++++++++++++-
>  4 files changed, 179 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index 8632ab695a6c..44c22cb87dde 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -1247,6 +1247,30 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
>  	return &amdgpu_fb->base;
>  }
>  
> +#ifdef CONFIG_STEAM_DECK

Something like AMD_PRIVATE_COLOR would be better.

It might also be enough to guard only the bits that make the uAPI
appear, such as drm_property_create, etc.

Harry

> +static int
> +amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> +{
> +	struct drm_property *prop;
> +
> +	prop = drm_property_create(adev_to_drm(adev),
> +				   DRM_MODE_PROP_BLOB,
> +				   "AMD_SHAPER_LUT", 0);
> +	if (!prop)
> +		return -ENOMEM;
> +	adev->mode_info.shaper_lut_property = prop;
> +
> +	prop = drm_property_create_range(adev_to_drm(adev),
> +					 DRM_MODE_PROP_IMMUTABLE,
> +					 "AMD_SHAPER_LUT_SIZE", 0, UINT_MAX);
> +	if (!prop)
> +		return -ENOMEM;
> +	adev->mode_info.shaper_lut_size_property = prop;
> +
> +	return 0;
> +}
> +#endif
> +
>  const struct drm_mode_config_funcs amdgpu_mode_funcs = {
>  	.fb_create = amdgpu_display_user_framebuffer_create,
>  };
> @@ -1323,6 +1347,10 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
>  			return -ENOMEM;
>  	}
>  
> +#ifdef CONFIG_STEAM_DECK
> +	if (amdgpu_display_create_color_properties(adev))
> +		return -ENOMEM;
> +#endif
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> index b8633df418d4..1fd3497af3b5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> @@ -344,6 +344,20 @@ struct amdgpu_mode_info {
>  	int			disp_priority;
>  	const struct amdgpu_display_funcs *funcs;
>  	const enum drm_plane_type *plane_type;
> +
> +	/* Driver-private color mgmt props */
> +#ifdef CONFIG_STEAM_DECK
> +	/**
> +	 * @shaper_lut_property: CRTC property to set post-blending shaper LUT
> +	 * that converts content before 3D LUT gamma correction.
> +	 */
> +	struct drm_property *shaper_lut_property;
> +	/**
> +	 * @shaper_lut_size_property: CRTC property for the size of
> +	 * post-blending shaper LUT as supported by the driver (read-only).
> +	 */
> +	struct drm_property *shaper_lut_size_property;
> +#endif
>  };
>  
>  #define AMDGPU_MAX_BL_LEVEL 0xFF
> 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 2e2413fd73a4..de63455896cc 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -726,6 +726,23 @@ struct dm_crtc_state {
>  	struct dc_info_packet vrr_infopacket;
>  
>  	int abm_level;
> +
> +#ifdef CONFIG_STEAM_DECK
> +	/* AMD driver-private color mgmt pipeline
> +	 *
> +	 * DRM provides CRTC degamma/ctm/gamma color mgmt features, but AMD HW
> +	 * has a larger set of post-blending color calibration features, as
> +	 * below:
> +	 */
> +	/**
> +	 * @shaper_lut:
> +	 *
> +	 * Lookup table used to de-linearize pixel data for gamma correction.
> +	 * See drm_crtc_enable_color_mgmt(). The blob (if not NULL) is an array
> +	 * of &struct drm_color_lut.
> +	 */
> +	struct drm_property_blob *shaper_lut;
> +#endif
>  };
>  
>  #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> index e3762e806617..503433e5cb38 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> @@ -229,7 +229,9 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
>  	if (cur->stream)
>  		dc_stream_release(cur->stream);
>  
> -
> +#ifdef CONFIG_STEAM_DECK
> +	drm_property_blob_put(cur->shaper_lut);
> +#endif
>  	__drm_atomic_helper_crtc_destroy_state(state);
>  
>  
> @@ -266,7 +268,12 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
>  	state->crc_skip_count = cur->crc_skip_count;
>  	state->mpo_requested = cur->mpo_requested;
>  	/* TODO Duplicate dc_stream after objects are stream object is flattened */
> +#ifdef CONFIG_STEAM_DECK
> +	state->shaper_lut = cur->shaper_lut;
>  
> +	if (state->shaper_lut)
> +		drm_property_blob_get(state->shaper_lut);
> +#endif
>  	return &state->base;
>  }
>  
> @@ -299,6 +306,111 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc)
>  }
>  #endif
>  
> +#ifdef CONFIG_STEAM_DECK
> +/**
> + * drm_crtc_additional_color_mgmt - enable additional color properties
> + * @crtc: DRM CRTC
> + *
> + * This function lets the driver enable the 3D LUT color correction property
> + * on a CRTC. This includes shaper LUT, 3D LUT and regamma TF. The shaper
> + * LUT and 3D LUT property is only attached if its size is not 0.
> + */
> +static void
> +dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> +{
> +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> +
> +	if (adev->dm.dc->caps.color.mpc.num_3dluts) {
> +		drm_object_attach_property(&crtc->base,
> +					   adev->mode_info.shaper_lut_property, 0);
> +		drm_object_attach_property(&crtc->base,
> +					   adev->mode_info.shaper_lut_size_property,
> +					   MAX_COLOR_LUT_ENTRIES);
> +	}
> +}
> +
> +static int
> +atomic_replace_property_blob_from_id(struct drm_device *dev,
> +					 struct drm_property_blob **blob,
> +					 uint64_t blob_id,
> +					 ssize_t expected_size,
> +					 ssize_t expected_elem_size,
> +					 bool *replaced)
> +{
> +	struct drm_property_blob *new_blob = NULL;
> +
> +	if (blob_id != 0) {
> +		new_blob = drm_property_lookup_blob(dev, blob_id);
> +		if (new_blob == NULL)
> +			return -EINVAL;
> +
> +		if (expected_size > 0 &&
> +		    new_blob->length != expected_size) {
> +			drm_property_blob_put(new_blob);
> +			return -EINVAL;
> +		}
> +		if (expected_elem_size > 0 &&
> +		    new_blob->length % expected_elem_size != 0) {
> +			drm_property_blob_put(new_blob);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	*replaced |= drm_property_replace_blob(blob, new_blob);
> +	drm_property_blob_put(new_blob);
> +
> +	return 0;
> +}
> +
> +static int
> +amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> +				   struct drm_crtc_state *state,
> +				   struct drm_property *property,
> +				   uint64_t val)
> +{
> +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> +	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> +	bool replaced = false;
> +	int ret;
> +
> +	if (property == adev->mode_info.shaper_lut_property) {
> +		ret = atomic_replace_property_blob_from_id(crtc->dev,
> +					&acrtc_state->shaper_lut,
> +					val,
> +					-1, sizeof(struct drm_color_lut),
> +					&replaced);
> +		acrtc_state->base.color_mgmt_changed |= replaced;
> +		return ret;
> +	} else {
> +		drm_dbg_atomic(crtc->dev,
> +			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> +			       crtc->base.id, crtc->name,
> +			       property->base.id, property->name);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> +				   const struct drm_crtc_state *state,
> +				   struct drm_property *property,
> +				   uint64_t *val)
> +{
> +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> +	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> +
> +	if (property == adev->mode_info.shaper_lut_property)
> +		*val = (acrtc_state->shaper_lut) ?
> +			acrtc_state->shaper_lut->base.id : 0;
> +	else
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +#endif
> +
>  /* Implemented only the options currently available for the driver */
>  static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
>  	.reset = dm_crtc_reset_state,
> @@ -317,6 +429,10 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
>  #if defined(CONFIG_DEBUG_FS)
>  	.late_register = amdgpu_dm_crtc_late_register,
>  #endif
> +#ifdef CONFIG_STEAM_DECK
> +	.atomic_set_property = amdgpu_dm_atomic_crtc_set_property,
> +	.atomic_get_property = amdgpu_dm_atomic_crtc_get_property,
> +#endif
>  };
>  
>  static void dm_crtc_helper_disable(struct drm_crtc *crtc)
> @@ -477,9 +593,11 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
>  	is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch;
>  	drm_crtc_enable_color_mgmt(&acrtc->base, is_dcn ? MAX_COLOR_LUT_ENTRIES : 0,
>  				   true, MAX_COLOR_LUT_ENTRIES);
> -
>  	drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES);
>  
> +#ifdef CONFIG_STEAM_DECK
> +	dm_crtc_additional_color_mgmt(&acrtc->base);
> +#endif
>  	return 0;
>  
>  fail:



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

* Re: [RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to driver-private props
  2023-04-23 14:10   ` Melissa Wen
@ 2023-05-08 21:24     ` Harry Wentland
  -1 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim



On 4/23/23 10:10, Melissa Wen wrote:
> From: Joshua Ashton <joshua@froggi.es>
> 
> Add predefined transfer function property to DRM CRTC gamma to convert
> to wire encoding with or without gamma LUT.
> 

Are all these new CRTC properties used by gamescope? I would be reluctant
to merge them if they're currently not needed.

> Co-developed-by: Melissa Wen <mwen@igalia.com>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> Signed-off-by: Joshua Ashton <joshua@froggi.es>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 22 ++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 ++++
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 23 +++++++++++++++++++
>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 13 +++++++++++
>  4 files changed, 62 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index 2abe5fe87c10..1913903cab88 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -1248,6 +1248,19 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
>  }
>  
>  #ifdef CONFIG_STEAM_DECK
> +static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
> +	{ DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
> +	{ DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
> +	{ DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
> +	{ DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
> +	{ DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
> +	{ DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
> +	{ DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
> +	{ DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
> +	{ DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
> +	{ DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
> +};
> +

Would it be better to prefix things with AMD_/amd_ to avoid confusion? On the other
hand, these will likely just move into DRM core once we get the generic color uAPI.

Harry

>  static int
>  amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>  {
> @@ -1281,6 +1294,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>  		return -ENOMEM;
>  	adev->mode_info.lut3d_size_property = prop;
>  
> +	prop = drm_property_create_enum(adev_to_drm(adev),
> +					DRM_MODE_PROP_ENUM,
> +					"GAMMA_TF",
> +					drm_transfer_function_enum_list,
> +					ARRAY_SIZE(drm_transfer_function_enum_list));
> +	if (!prop)
> +		return -ENOMEM;
> +	adev->mode_info.gamma_tf_property = prop;
> +
>  	return 0;
>  }
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> index 205fa4f5bea7..76337e18c728 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> @@ -368,6 +368,10 @@ struct amdgpu_mode_info {
>  	 * LUT as supported by the driver (read-only).
>  	 */
>  	struct drm_property *lut3d_size_property;
> +	/**
> +	 * @gamma_tf_property: Transfer function for CRTC regamma.
> +	 */
> +	struct drm_property *gamma_tf_property;
>  #endif
>  };
>  
> 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 09c3e1858b56..1e90a2dd445e 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -699,6 +699,23 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
>  
>  extern const struct amdgpu_ip_block_version dm_ip_block;
>  
> +#ifdef CONFIG_STEAM_DECK
> +enum drm_transfer_function {
> +	DRM_TRANSFER_FUNCTION_DEFAULT,
> +
> +	DRM_TRANSFER_FUNCTION_SRGB,
> +	DRM_TRANSFER_FUNCTION_BT709,
> +	DRM_TRANSFER_FUNCTION_PQ,
> +	DRM_TRANSFER_FUNCTION_LINEAR,
> +	DRM_TRANSFER_FUNCTION_UNITY,
> +	DRM_TRANSFER_FUNCTION_HLG,
> +	DRM_TRANSFER_FUNCTION_GAMMA22,
> +	DRM_TRANSFER_FUNCTION_GAMMA24,
> +	DRM_TRANSFER_FUNCTION_GAMMA26,
> +	DRM_TRANSFER_FUNCTION_MAX,
> +};
> +#endif
> +
>  struct dm_plane_state {
>  	struct drm_plane_state base;
>  	struct dc_plane_state *dc_state;
> @@ -751,6 +768,12 @@ struct dm_crtc_state {
>  	 * &struct drm_color_lut.
>  	 */
>  	struct drm_property_blob *lut3d;
> +        /**
> +	 * @gamma_tf:
> +	 *
> +	 * Pre-defined transfer function for converting internal FB -> wire encoding.
> +	 */
> +	enum drm_transfer_function gamma_tf;
>  #endif
>  };
>  
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> index 0e1280228e6e..79324fbab1f1 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> @@ -272,6 +272,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
>  #ifdef CONFIG_STEAM_DECK
>  	state->shaper_lut = cur->shaper_lut;
>  	state->lut3d = cur->lut3d;
> +	state->gamma_tf = cur->gamma_tf;
>  
>  	if (state->shaper_lut)
>  		drm_property_blob_get(state->shaper_lut);
> @@ -336,6 +337,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
>  					   adev->mode_info.lut3d_size_property,
>  					   MAX_COLOR_3DLUT_ENTRIES);
>  	}
> +
> +	if(adev->dm.dc->caps.color.mpc.ogam_ram)
> +		drm_object_attach_property(&crtc->base,
> +					   adev->mode_info.gamma_tf_property,
> +					   DRM_TRANSFER_FUNCTION_DEFAULT);
>  }
>  
>  static int
> @@ -398,6 +404,11 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
>  					&replaced);
>  		acrtc_state->base.color_mgmt_changed |= replaced;
>  		return ret;
> +	} else if (property == adev->mode_info.gamma_tf_property) {
> +		if (acrtc_state->gamma_tf != val) {
> +			acrtc_state->gamma_tf = val;
> +			acrtc_state->base.color_mgmt_changed |= 1;
> +		}
>  	} else {
>  		drm_dbg_atomic(crtc->dev,
>  			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> @@ -424,6 +435,8 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
>  	else if (property == adev->mode_info.lut3d_property)
>  		*val = (acrtc_state->lut3d) ?
>  			acrtc_state->lut3d->base.id : 0;
> +	else if (property == adev->mode_info.gamma_tf_property)
> +		*val = acrtc_state->gamma_tf;
>  	else
>  		return -EINVAL;
>  



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

* Re: [RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to driver-private props
@ 2023-05-08 21:24     ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel



On 4/23/23 10:10, Melissa Wen wrote:
> From: Joshua Ashton <joshua@froggi.es>
> 
> Add predefined transfer function property to DRM CRTC gamma to convert
> to wire encoding with or without gamma LUT.
> 

Are all these new CRTC properties used by gamescope? I would be reluctant
to merge them if they're currently not needed.

> Co-developed-by: Melissa Wen <mwen@igalia.com>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> Signed-off-by: Joshua Ashton <joshua@froggi.es>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 22 ++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 ++++
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 23 +++++++++++++++++++
>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 13 +++++++++++
>  4 files changed, 62 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index 2abe5fe87c10..1913903cab88 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -1248,6 +1248,19 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
>  }
>  
>  #ifdef CONFIG_STEAM_DECK
> +static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
> +	{ DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
> +	{ DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
> +	{ DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
> +	{ DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
> +	{ DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
> +	{ DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
> +	{ DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
> +	{ DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
> +	{ DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
> +	{ DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
> +};
> +

Would it be better to prefix things with AMD_/amd_ to avoid confusion? On the other
hand, these will likely just move into DRM core once we get the generic color uAPI.

Harry

>  static int
>  amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>  {
> @@ -1281,6 +1294,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>  		return -ENOMEM;
>  	adev->mode_info.lut3d_size_property = prop;
>  
> +	prop = drm_property_create_enum(adev_to_drm(adev),
> +					DRM_MODE_PROP_ENUM,
> +					"GAMMA_TF",
> +					drm_transfer_function_enum_list,
> +					ARRAY_SIZE(drm_transfer_function_enum_list));
> +	if (!prop)
> +		return -ENOMEM;
> +	adev->mode_info.gamma_tf_property = prop;
> +
>  	return 0;
>  }
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> index 205fa4f5bea7..76337e18c728 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> @@ -368,6 +368,10 @@ struct amdgpu_mode_info {
>  	 * LUT as supported by the driver (read-only).
>  	 */
>  	struct drm_property *lut3d_size_property;
> +	/**
> +	 * @gamma_tf_property: Transfer function for CRTC regamma.
> +	 */
> +	struct drm_property *gamma_tf_property;
>  #endif
>  };
>  
> 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 09c3e1858b56..1e90a2dd445e 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -699,6 +699,23 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
>  
>  extern const struct amdgpu_ip_block_version dm_ip_block;
>  
> +#ifdef CONFIG_STEAM_DECK
> +enum drm_transfer_function {
> +	DRM_TRANSFER_FUNCTION_DEFAULT,
> +
> +	DRM_TRANSFER_FUNCTION_SRGB,
> +	DRM_TRANSFER_FUNCTION_BT709,
> +	DRM_TRANSFER_FUNCTION_PQ,
> +	DRM_TRANSFER_FUNCTION_LINEAR,
> +	DRM_TRANSFER_FUNCTION_UNITY,
> +	DRM_TRANSFER_FUNCTION_HLG,
> +	DRM_TRANSFER_FUNCTION_GAMMA22,
> +	DRM_TRANSFER_FUNCTION_GAMMA24,
> +	DRM_TRANSFER_FUNCTION_GAMMA26,
> +	DRM_TRANSFER_FUNCTION_MAX,
> +};
> +#endif
> +
>  struct dm_plane_state {
>  	struct drm_plane_state base;
>  	struct dc_plane_state *dc_state;
> @@ -751,6 +768,12 @@ struct dm_crtc_state {
>  	 * &struct drm_color_lut.
>  	 */
>  	struct drm_property_blob *lut3d;
> +        /**
> +	 * @gamma_tf:
> +	 *
> +	 * Pre-defined transfer function for converting internal FB -> wire encoding.
> +	 */
> +	enum drm_transfer_function gamma_tf;
>  #endif
>  };
>  
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> index 0e1280228e6e..79324fbab1f1 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> @@ -272,6 +272,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
>  #ifdef CONFIG_STEAM_DECK
>  	state->shaper_lut = cur->shaper_lut;
>  	state->lut3d = cur->lut3d;
> +	state->gamma_tf = cur->gamma_tf;
>  
>  	if (state->shaper_lut)
>  		drm_property_blob_get(state->shaper_lut);
> @@ -336,6 +337,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
>  					   adev->mode_info.lut3d_size_property,
>  					   MAX_COLOR_3DLUT_ENTRIES);
>  	}
> +
> +	if(adev->dm.dc->caps.color.mpc.ogam_ram)
> +		drm_object_attach_property(&crtc->base,
> +					   adev->mode_info.gamma_tf_property,
> +					   DRM_TRANSFER_FUNCTION_DEFAULT);
>  }
>  
>  static int
> @@ -398,6 +404,11 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
>  					&replaced);
>  		acrtc_state->base.color_mgmt_changed |= replaced;
>  		return ret;
> +	} else if (property == adev->mode_info.gamma_tf_property) {
> +		if (acrtc_state->gamma_tf != val) {
> +			acrtc_state->gamma_tf = val;
> +			acrtc_state->base.color_mgmt_changed |= 1;
> +		}
>  	} else {
>  		drm_dbg_atomic(crtc->dev,
>  			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> @@ -424,6 +435,8 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
>  	else if (property == adev->mode_info.lut3d_property)
>  		*val = (acrtc_state->lut3d) ?
>  			acrtc_state->lut3d->base.id : 0;
> +	else if (property == adev->mode_info.gamma_tf_property)
> +		*val = acrtc_state->gamma_tf;
>  	else
>  		return -EINVAL;
>  



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

* Re: [RFC PATCH 09/40] drm/amd/display: move replace blob func to dm plane
  2023-04-23 14:10   ` Melissa Wen
@ 2023-05-08 21:24     ` Harry Wentland
  -1 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim



On 4/23/23 10:10, Melissa Wen wrote:
> From amdgpu_dm_plane we can get it for both CRTC and plane color
> properties. We are adding new plane properties for AMD driver-private
> color mgmt.
> 
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> ---
>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 37 +------------------
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 35 ++++++++++++++++++
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |  7 ++++
>  3 files changed, 44 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> index 79324fbab1f1..27d7a8b18013 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> @@ -344,39 +344,6 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
>  					   DRM_TRANSFER_FUNCTION_DEFAULT);
>  }
>  
> -static int
> -atomic_replace_property_blob_from_id(struct drm_device *dev,
> -					 struct drm_property_blob **blob,
> -					 uint64_t blob_id,
> -					 ssize_t expected_size,
> -					 ssize_t expected_elem_size,
> -					 bool *replaced)
> -{
> -	struct drm_property_blob *new_blob = NULL;
> -
> -	if (blob_id != 0) {
> -		new_blob = drm_property_lookup_blob(dev, blob_id);
> -		if (new_blob == NULL)
> -			return -EINVAL;
> -
> -		if (expected_size > 0 &&
> -		    new_blob->length != expected_size) {
> -			drm_property_blob_put(new_blob);
> -			return -EINVAL;
> -		}
> -		if (expected_elem_size > 0 &&
> -		    new_blob->length % expected_elem_size != 0) {
> -			drm_property_blob_put(new_blob);
> -			return -EINVAL;
> -		}
> -	}
> -
> -	*replaced |= drm_property_replace_blob(blob, new_blob);
> -	drm_property_blob_put(new_blob);
> -
> -	return 0;
> -}
> -
>  static int
>  amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
>  				   struct drm_crtc_state *state,
> @@ -389,7 +356,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
>  	int ret;
>  
>  	if (property == adev->mode_info.shaper_lut_property) {
> -		ret = atomic_replace_property_blob_from_id(crtc->dev,
> +		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
>  					&acrtc_state->shaper_lut,
>  					val,
>  					-1, sizeof(struct drm_color_lut),
> @@ -397,7 +364,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
>  		acrtc_state->base.color_mgmt_changed |= replaced;
>  		return ret;
>  	} else if (property == adev->mode_info.lut3d_property) {
> -		ret = atomic_replace_property_blob_from_id(crtc->dev,
> +		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
>  					&acrtc_state->lut3d,
>  					val,
>  					-1, sizeof(struct drm_color_lut),
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> index 322668973747..4e5498153be2 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> @@ -1411,6 +1411,41 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
>  	drm_atomic_helper_plane_destroy_state(plane, state);
>  }
>  
> +#ifdef CONFIG_STEAM_DECK
> +int
> +amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> +					       struct drm_property_blob **blob,
> +					       uint64_t blob_id,
> +					       ssize_t expected_size,
> +					       ssize_t expected_elem_size,
> +					       bool *replaced)
> +{
> +	struct drm_property_blob *new_blob = NULL;
> +
> +	if (blob_id != 0) {
> +		new_blob = drm_property_lookup_blob(dev, blob_id);
> +		if (new_blob == NULL)
> +			return -EINVAL;
> +
> +		if (expected_size > 0 &&
> +		    new_blob->length != expected_size) {
> +			drm_property_blob_put(new_blob);
> +			return -EINVAL;
> +		}
> +		if (expected_elem_size > 0 &&
> +		    new_blob->length % expected_elem_size != 0) {
> +			drm_property_blob_put(new_blob);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	*replaced |= drm_property_replace_blob(blob, new_blob);
> +	drm_property_blob_put(new_blob);
> +
> +	return 0;
> +}

amdgpu_dm_plane doesn't seem the right place for it either. Maybe a new
amdgpu_dm_helper.c/h?

Alternatively would this make sense to live in DRM core as a helper?

Harry

> +#endif
> +
>  static const struct drm_plane_funcs dm_plane_funcs = {
>  	.update_plane	= drm_atomic_helper_update_plane,
>  	.disable_plane	= drm_atomic_helper_disable_plane,
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> index 930f1572f898..1b05ac4c15f6 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> @@ -51,6 +51,13 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev,
>  				 bool tmz_surface,
>  				 bool force_disable_dcc);
>  
> +int amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> +					    struct drm_property_blob **blob,
> +					    uint64_t blob_id,
> +					    ssize_t expected_size,
> +					    ssize_t expected_elem_size,
> +					    bool *replaced);
> +
>  int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
>  			 struct drm_plane *plane,
>  			 unsigned long possible_crtcs,



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

* Re: [RFC PATCH 09/40] drm/amd/display: move replace blob func to dm plane
@ 2023-05-08 21:24     ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel



On 4/23/23 10:10, Melissa Wen wrote:
> From amdgpu_dm_plane we can get it for both CRTC and plane color
> properties. We are adding new plane properties for AMD driver-private
> color mgmt.
> 
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> ---
>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 37 +------------------
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 35 ++++++++++++++++++
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |  7 ++++
>  3 files changed, 44 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> index 79324fbab1f1..27d7a8b18013 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> @@ -344,39 +344,6 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
>  					   DRM_TRANSFER_FUNCTION_DEFAULT);
>  }
>  
> -static int
> -atomic_replace_property_blob_from_id(struct drm_device *dev,
> -					 struct drm_property_blob **blob,
> -					 uint64_t blob_id,
> -					 ssize_t expected_size,
> -					 ssize_t expected_elem_size,
> -					 bool *replaced)
> -{
> -	struct drm_property_blob *new_blob = NULL;
> -
> -	if (blob_id != 0) {
> -		new_blob = drm_property_lookup_blob(dev, blob_id);
> -		if (new_blob == NULL)
> -			return -EINVAL;
> -
> -		if (expected_size > 0 &&
> -		    new_blob->length != expected_size) {
> -			drm_property_blob_put(new_blob);
> -			return -EINVAL;
> -		}
> -		if (expected_elem_size > 0 &&
> -		    new_blob->length % expected_elem_size != 0) {
> -			drm_property_blob_put(new_blob);
> -			return -EINVAL;
> -		}
> -	}
> -
> -	*replaced |= drm_property_replace_blob(blob, new_blob);
> -	drm_property_blob_put(new_blob);
> -
> -	return 0;
> -}
> -
>  static int
>  amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
>  				   struct drm_crtc_state *state,
> @@ -389,7 +356,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
>  	int ret;
>  
>  	if (property == adev->mode_info.shaper_lut_property) {
> -		ret = atomic_replace_property_blob_from_id(crtc->dev,
> +		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
>  					&acrtc_state->shaper_lut,
>  					val,
>  					-1, sizeof(struct drm_color_lut),
> @@ -397,7 +364,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
>  		acrtc_state->base.color_mgmt_changed |= replaced;
>  		return ret;
>  	} else if (property == adev->mode_info.lut3d_property) {
> -		ret = atomic_replace_property_blob_from_id(crtc->dev,
> +		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
>  					&acrtc_state->lut3d,
>  					val,
>  					-1, sizeof(struct drm_color_lut),
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> index 322668973747..4e5498153be2 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> @@ -1411,6 +1411,41 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
>  	drm_atomic_helper_plane_destroy_state(plane, state);
>  }
>  
> +#ifdef CONFIG_STEAM_DECK
> +int
> +amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> +					       struct drm_property_blob **blob,
> +					       uint64_t blob_id,
> +					       ssize_t expected_size,
> +					       ssize_t expected_elem_size,
> +					       bool *replaced)
> +{
> +	struct drm_property_blob *new_blob = NULL;
> +
> +	if (blob_id != 0) {
> +		new_blob = drm_property_lookup_blob(dev, blob_id);
> +		if (new_blob == NULL)
> +			return -EINVAL;
> +
> +		if (expected_size > 0 &&
> +		    new_blob->length != expected_size) {
> +			drm_property_blob_put(new_blob);
> +			return -EINVAL;
> +		}
> +		if (expected_elem_size > 0 &&
> +		    new_blob->length % expected_elem_size != 0) {
> +			drm_property_blob_put(new_blob);
> +			return -EINVAL;
> +		}
> +	}
> +
> +	*replaced |= drm_property_replace_blob(blob, new_blob);
> +	drm_property_blob_put(new_blob);
> +
> +	return 0;
> +}

amdgpu_dm_plane doesn't seem the right place for it either. Maybe a new
amdgpu_dm_helper.c/h?

Alternatively would this make sense to live in DRM core as a helper?

Harry

> +#endif
> +
>  static const struct drm_plane_funcs dm_plane_funcs = {
>  	.update_plane	= drm_atomic_helper_update_plane,
>  	.disable_plane	= drm_atomic_helper_disable_plane,
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> index 930f1572f898..1b05ac4c15f6 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> @@ -51,6 +51,13 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev,
>  				 bool tmz_surface,
>  				 bool force_disable_dcc);
>  
> +int amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> +					    struct drm_property_blob **blob,
> +					    uint64_t blob_id,
> +					    ssize_t expected_size,
> +					    ssize_t expected_elem_size,
> +					    bool *replaced);
> +
>  int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
>  			 struct drm_plane *plane,
>  			 unsigned long possible_crtcs,



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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
  2023-04-23 14:10   ` Melissa Wen
@ 2023-05-08 21:24     ` Harry Wentland
  -1 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel
  Cc: Sebastian Wick, Shashank Sharma, Alex Hung, Xaver Hugl,
	linux-kernel, Nicholas Kazlauskas, Joshua Ashton, sungjoon.kim



On 4/23/23 10:10, Melissa Wen wrote:
> From: Joshua Ashton <joshua@froggi.es>
> 
> Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
> transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
> least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
> nits for SDR content. So if you want, 203 nits for SDR content, pass in
> (203.0 / 80.0).
> 

Is gamescope intending to use this?

Harry

> Co-developed-by: Melissa Wen <mwen@igalia.com>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> Signed-off-by: Joshua Ashton <joshua@froggi.es>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
>  4 files changed, 41 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index 24595906dab1..dd658f162f6f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>  		return -ENOMEM;
>  	adev->mode_info.plane_degamma_tf_property = prop;
>  
> +	prop = drm_property_create_range(adev_to_drm(adev),
> +					 0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
> +	if (!prop)
> +		return -ENOMEM;
> +	adev->mode_info.plane_hdr_mult_property = prop;
> +
>  	return 0;
>  }
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> index ab9ce6f26c90..65a9d62ffbe4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
>  	 * linearize content with or without LUT.
>  	 */
>  	struct drm_property *plane_degamma_tf_property;
> +	/**
> +	 * @plane_hdr_mult_property:
> +	 */
> +	struct drm_property *plane_hdr_mult_property;
>  #endif
>  };
>  
> 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 005632c1c9ec..bb7307b9cfd5 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -51,6 +51,7 @@
>  
>  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
>  
> +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
>  /*
>  #include "include/amdgpu_dal_power_if.h"
>  #include "amdgpu_dm_irq.h"
> @@ -736,6 +737,17 @@ struct dm_plane_state {
>  	 * linearize.
>  	 */
>  	enum drm_transfer_function degamma_tf;
> +	/**
> +	 * @hdr_mult:
> +	 *
> +	 * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
> +	 * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
> +	 * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
> +	 * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
> +	 * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
> +	 * S31.32 sign-magnitude.
> +	 */
> +	__u64 hdr_mult;
>  #endif
>  };
>  
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> index 5b458cc0781c..57169dae8b3d 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
>  		__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
>  
>  #ifdef CONFIG_STEAM_DECK
> -	if (amdgpu_state)
> +	if (amdgpu_state) {
>  		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
> +		amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> +	}
>  #endif
>  }
>  
> @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
>  #ifdef CONFIG_STEAM_DECK
>  int
>  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> -					       struct drm_property_blob **blob,
> -					       uint64_t blob_id,
> -					       ssize_t expected_size,
> -					       ssize_t expected_elem_size,
> -					       bool *replaced)
> +					struct drm_property_blob **blob,
> +					uint64_t blob_id,
> +					ssize_t expected_size,
> +					ssize_t expected_elem_size,
> +					bool *replaced)
>  {
>  	struct drm_property_blob *new_blob = NULL;
>  
> @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
>  					   dm->adev->mode_info.plane_degamma_tf_property,
>  					   DRM_TRANSFER_FUNCTION_DEFAULT);
>  	}
> +	/* HDR MULT is always available */
> +	drm_object_attach_property(&plane->base,
> +				   dm->adev->mode_info.plane_hdr_mult_property,
> +				   AMDGPU_HDR_MULT_DEFAULT);
>  }
>  
>  static int
> @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
>  			dm_plane_state->degamma_tf = val;
>  			dm_plane_state->base.color_mgmt_changed = 1;
>  		}
> +	} else if (property == adev->mode_info.plane_hdr_mult_property) {
> +		if (dm_plane_state->hdr_mult != val) {
> +			dm_plane_state->hdr_mult = val;
> +			dm_plane_state->base.color_mgmt_changed = 1;
> +		}
>  	} else {
>  		drm_dbg_atomic(plane->dev,
>  			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
> @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
>  			dm_plane_state->degamma_lut->base.id : 0;
>  	} else if (property == adev->mode_info.plane_degamma_tf_property) {
>  		*val = dm_plane_state->degamma_tf;
> +	} else if (property == adev->mode_info.plane_hdr_mult_property) {
> +		*val = dm_plane_state->hdr_mult;
>  	} else {
>  		return -EINVAL;
>  	}



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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-05-08 21:24     ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-08 21:24 UTC (permalink / raw)
  To: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel
  Cc: Joshua Ashton, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel



On 4/23/23 10:10, Melissa Wen wrote:
> From: Joshua Ashton <joshua@froggi.es>
> 
> Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
> transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
> least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
> nits for SDR content. So if you want, 203 nits for SDR content, pass in
> (203.0 / 80.0).
> 

Is gamescope intending to use this?

Harry

> Co-developed-by: Melissa Wen <mwen@igalia.com>
> Signed-off-by: Melissa Wen <mwen@igalia.com>
> Signed-off-by: Joshua Ashton <joshua@froggi.es>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
>  4 files changed, 41 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index 24595906dab1..dd658f162f6f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>  		return -ENOMEM;
>  	adev->mode_info.plane_degamma_tf_property = prop;
>  
> +	prop = drm_property_create_range(adev_to_drm(adev),
> +					 0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
> +	if (!prop)
> +		return -ENOMEM;
> +	adev->mode_info.plane_hdr_mult_property = prop;
> +
>  	return 0;
>  }
>  #endif
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> index ab9ce6f26c90..65a9d62ffbe4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
>  	 * linearize content with or without LUT.
>  	 */
>  	struct drm_property *plane_degamma_tf_property;
> +	/**
> +	 * @plane_hdr_mult_property:
> +	 */
> +	struct drm_property *plane_hdr_mult_property;
>  #endif
>  };
>  
> 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 005632c1c9ec..bb7307b9cfd5 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> @@ -51,6 +51,7 @@
>  
>  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
>  
> +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
>  /*
>  #include "include/amdgpu_dal_power_if.h"
>  #include "amdgpu_dm_irq.h"
> @@ -736,6 +737,17 @@ struct dm_plane_state {
>  	 * linearize.
>  	 */
>  	enum drm_transfer_function degamma_tf;
> +	/**
> +	 * @hdr_mult:
> +	 *
> +	 * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
> +	 * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
> +	 * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
> +	 * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
> +	 * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
> +	 * S31.32 sign-magnitude.
> +	 */
> +	__u64 hdr_mult;
>  #endif
>  };
>  
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> index 5b458cc0781c..57169dae8b3d 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
>  		__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
>  
>  #ifdef CONFIG_STEAM_DECK
> -	if (amdgpu_state)
> +	if (amdgpu_state) {
>  		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
> +		amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> +	}
>  #endif
>  }
>  
> @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
>  #ifdef CONFIG_STEAM_DECK
>  int
>  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> -					       struct drm_property_blob **blob,
> -					       uint64_t blob_id,
> -					       ssize_t expected_size,
> -					       ssize_t expected_elem_size,
> -					       bool *replaced)
> +					struct drm_property_blob **blob,
> +					uint64_t blob_id,
> +					ssize_t expected_size,
> +					ssize_t expected_elem_size,
> +					bool *replaced)
>  {
>  	struct drm_property_blob *new_blob = NULL;
>  
> @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
>  					   dm->adev->mode_info.plane_degamma_tf_property,
>  					   DRM_TRANSFER_FUNCTION_DEFAULT);
>  	}
> +	/* HDR MULT is always available */
> +	drm_object_attach_property(&plane->base,
> +				   dm->adev->mode_info.plane_hdr_mult_property,
> +				   AMDGPU_HDR_MULT_DEFAULT);
>  }
>  
>  static int
> @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
>  			dm_plane_state->degamma_tf = val;
>  			dm_plane_state->base.color_mgmt_changed = 1;
>  		}
> +	} else if (property == adev->mode_info.plane_hdr_mult_property) {
> +		if (dm_plane_state->hdr_mult != val) {
> +			dm_plane_state->hdr_mult = val;
> +			dm_plane_state->base.color_mgmt_changed = 1;
> +		}
>  	} else {
>  		drm_dbg_atomic(plane->dev,
>  			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
> @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
>  			dm_plane_state->degamma_lut->base.id : 0;
>  	} else if (property == adev->mode_info.plane_degamma_tf_property) {
>  		*val = dm_plane_state->degamma_tf;
> +	} else if (property == adev->mode_info.plane_hdr_mult_property) {
> +		*val = dm_plane_state->hdr_mult;
>  	} else {
>  		return -EINVAL;
>  	}



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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
  2023-05-08 21:24     ` Harry Wentland
  (?)
@ 2023-05-09 16:23       ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:23 UTC (permalink / raw)
  To: Harry Wentland
  Cc: amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher, dri-devel,
	christian.koenig, Xinhui.Pan, airlied, daniel, Joshua Ashton,
	Sebastian Wick, Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas,
	sungjoon.kim, Alex Hung, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1742 bytes --]

On 05/08, Harry Wentland wrote:
> On 4/23/23 10:10, Melissa Wen wrote:
> > We are enabling a large set of color calibration features to enhance KMS
> > color mgmt but these properties are specific of AMD display HW, and
> > cannot be provided by other vendors. Therefore, set a config option to
> > enable AMD driver-private properties used on Steam Deck color mgmt
> > pipeline.
> > 
> > Co-developed-by: Joshua Ashton <joshua@froggi.es>
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > ---
> >  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
> > index 06b438217c61..c45a8deb1098 100644
> > --- a/drivers/gpu/drm/amd/display/Kconfig
> > +++ b/drivers/gpu/drm/amd/display/Kconfig
> > @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
> >              of crc of specific region via debugfs.
> >              Cooperate with specific DMCU FW.
> >  
> > +config STEAM_DECK
> > +	bool "Enable color calibration features for Steam Deck"
> > +	depends on DRM_AMD_DC
> > +	help
> > +	  Choose this option if you want to use AMDGPU features for broader
> > +	  color management support on Steam Deck.
> >  
> 
> If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
> the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
> us from requiring to support this forever.

I see, I'll follow this path. Still on that, I've changed
CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.
Does it sound better?

Thanks,

Melissa

> 
> Harry
> 
> >  endmenu
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
@ 2023-05-09 16:23       ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:23 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, Alex Deucher,
	christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 1742 bytes --]

On 05/08, Harry Wentland wrote:
> On 4/23/23 10:10, Melissa Wen wrote:
> > We are enabling a large set of color calibration features to enhance KMS
> > color mgmt but these properties are specific of AMD display HW, and
> > cannot be provided by other vendors. Therefore, set a config option to
> > enable AMD driver-private properties used on Steam Deck color mgmt
> > pipeline.
> > 
> > Co-developed-by: Joshua Ashton <joshua@froggi.es>
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > ---
> >  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
> > index 06b438217c61..c45a8deb1098 100644
> > --- a/drivers/gpu/drm/amd/display/Kconfig
> > +++ b/drivers/gpu/drm/amd/display/Kconfig
> > @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
> >              of crc of specific region via debugfs.
> >              Cooperate with specific DMCU FW.
> >  
> > +config STEAM_DECK
> > +	bool "Enable color calibration features for Steam Deck"
> > +	depends on DRM_AMD_DC
> > +	help
> > +	  Choose this option if you want to use AMDGPU features for broader
> > +	  color management support on Steam Deck.
> >  
> 
> If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
> the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
> us from requiring to support this forever.

I see, I'll follow this path. Still on that, I've changed
CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.
Does it sound better?

Thanks,

Melissa

> 
> Harry
> 
> >  endmenu
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
@ 2023-05-09 16:23       ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:23 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, daniel, Alex Deucher,
	airlied, christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 1742 bytes --]

On 05/08, Harry Wentland wrote:
> On 4/23/23 10:10, Melissa Wen wrote:
> > We are enabling a large set of color calibration features to enhance KMS
> > color mgmt but these properties are specific of AMD display HW, and
> > cannot be provided by other vendors. Therefore, set a config option to
> > enable AMD driver-private properties used on Steam Deck color mgmt
> > pipeline.
> > 
> > Co-developed-by: Joshua Ashton <joshua@froggi.es>
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > ---
> >  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
> > index 06b438217c61..c45a8deb1098 100644
> > --- a/drivers/gpu/drm/amd/display/Kconfig
> > +++ b/drivers/gpu/drm/amd/display/Kconfig
> > @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
> >              of crc of specific region via debugfs.
> >              Cooperate with specific DMCU FW.
> >  
> > +config STEAM_DECK
> > +	bool "Enable color calibration features for Steam Deck"
> > +	depends on DRM_AMD_DC
> > +	help
> > +	  Choose this option if you want to use AMDGPU features for broader
> > +	  color management support on Steam Deck.
> >  
> 
> If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
> the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
> us from requiring to support this forever.

I see, I'll follow this path. Still on that, I've changed
CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.
Does it sound better?

Thanks,

Melissa

> 
> Harry
> 
> >  endmenu
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 05/40] drm/amd/display: add shaper LUT driver-private props
  2023-05-08 21:24     ` Harry Wentland
  (?)
@ 2023-05-09 16:30       ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:30 UTC (permalink / raw)
  To: Harry Wentland
  Cc: amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher, dri-devel,
	christian.koenig, Xinhui.Pan, airlied, daniel, Joshua Ashton,
	Sebastian Wick, Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas,
	sungjoon.kim, Alex Hung, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 10830 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > CRTC shaper LUT shapes the content after blending, i.e., de-linearizes
> > or normalizes space before applying a 3D LUT color correction. In the
> > next patch, we add CRTC 3D LUT property to DRM color management after
> > this shaper LUT and before the current CRTC gamma LUT.
> > 
> 
> It might be good to describe the motivation behind the "de-linearization"
> of pixels. Since a 3DLUT has a limited number of entries in each dimension
> we want to use them in an optimal fashion. This means using the 3DLUT in
> a colorspace that is optimized for human vision, such as sRGB, PQ, or
> another non-linear space.

ack.

> 
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  28 ++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  14 ++
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  17 +++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 122 +++++++++++++++++-
> >  4 files changed, 179 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index 8632ab695a6c..44c22cb87dde 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -1247,6 +1247,30 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
> >  	return &amdgpu_fb->base;
> >  }
> >  
> > +#ifdef CONFIG_STEAM_DECK
> 
> Something like AMD_PRIVATE_COLOR would be better.

Oh, I see your suggestion for my previous question here, so nvm.

> 
> It might also be enough to guard only the bits that make the uAPI
> appear, such as drm_property_create, etc.

Makes sense. Joshie also suggested me this path.

Thanks!

> 
> Harry
> 
> > +static int
> > +amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > +{
> > +	struct drm_property *prop;
> > +
> > +	prop = drm_property_create(adev_to_drm(adev),
> > +				   DRM_MODE_PROP_BLOB,
> > +				   "AMD_SHAPER_LUT", 0);
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.shaper_lut_property = prop;
> > +
> > +	prop = drm_property_create_range(adev_to_drm(adev),
> > +					 DRM_MODE_PROP_IMMUTABLE,
> > +					 "AMD_SHAPER_LUT_SIZE", 0, UINT_MAX);
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.shaper_lut_size_property = prop;
> > +
> > +	return 0;
> > +}
> > +#endif
> > +
> >  const struct drm_mode_config_funcs amdgpu_mode_funcs = {
> >  	.fb_create = amdgpu_display_user_framebuffer_create,
> >  };
> > @@ -1323,6 +1347,10 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
> >  			return -ENOMEM;
> >  	}
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +	if (amdgpu_display_create_color_properties(adev))
> > +		return -ENOMEM;
> > +#endif
> >  	return 0;
> >  }
> >  
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > index b8633df418d4..1fd3497af3b5 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > @@ -344,6 +344,20 @@ struct amdgpu_mode_info {
> >  	int			disp_priority;
> >  	const struct amdgpu_display_funcs *funcs;
> >  	const enum drm_plane_type *plane_type;
> > +
> > +	/* Driver-private color mgmt props */
> > +#ifdef CONFIG_STEAM_DECK
> > +	/**
> > +	 * @shaper_lut_property: CRTC property to set post-blending shaper LUT
> > +	 * that converts content before 3D LUT gamma correction.
> > +	 */
> > +	struct drm_property *shaper_lut_property;
> > +	/**
> > +	 * @shaper_lut_size_property: CRTC property for the size of
> > +	 * post-blending shaper LUT as supported by the driver (read-only).
> > +	 */
> > +	struct drm_property *shaper_lut_size_property;
> > +#endif
> >  };
> >  
> >  #define AMDGPU_MAX_BL_LEVEL 0xFF
> > 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 2e2413fd73a4..de63455896cc 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > @@ -726,6 +726,23 @@ struct dm_crtc_state {
> >  	struct dc_info_packet vrr_infopacket;
> >  
> >  	int abm_level;
> > +
> > +#ifdef CONFIG_STEAM_DECK
> > +	/* AMD driver-private color mgmt pipeline
> > +	 *
> > +	 * DRM provides CRTC degamma/ctm/gamma color mgmt features, but AMD HW
> > +	 * has a larger set of post-blending color calibration features, as
> > +	 * below:
> > +	 */
> > +	/**
> > +	 * @shaper_lut:
> > +	 *
> > +	 * Lookup table used to de-linearize pixel data for gamma correction.
> > +	 * See drm_crtc_enable_color_mgmt(). The blob (if not NULL) is an array
> > +	 * of &struct drm_color_lut.
> > +	 */
> > +	struct drm_property_blob *shaper_lut;
> > +#endif
> >  };
> >  
> >  #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > index e3762e806617..503433e5cb38 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > @@ -229,7 +229,9 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
> >  	if (cur->stream)
> >  		dc_stream_release(cur->stream);
> >  
> > -
> > +#ifdef CONFIG_STEAM_DECK
> > +	drm_property_blob_put(cur->shaper_lut);
> > +#endif
> >  	__drm_atomic_helper_crtc_destroy_state(state);
> >  
> >  
> > @@ -266,7 +268,12 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
> >  	state->crc_skip_count = cur->crc_skip_count;
> >  	state->mpo_requested = cur->mpo_requested;
> >  	/* TODO Duplicate dc_stream after objects are stream object is flattened */
> > +#ifdef CONFIG_STEAM_DECK
> > +	state->shaper_lut = cur->shaper_lut;
> >  
> > +	if (state->shaper_lut)
> > +		drm_property_blob_get(state->shaper_lut);
> > +#endif
> >  	return &state->base;
> >  }
> >  
> > @@ -299,6 +306,111 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc)
> >  }
> >  #endif
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +/**
> > + * drm_crtc_additional_color_mgmt - enable additional color properties
> > + * @crtc: DRM CRTC
> > + *
> > + * This function lets the driver enable the 3D LUT color correction property
> > + * on a CRTC. This includes shaper LUT, 3D LUT and regamma TF. The shaper
> > + * LUT and 3D LUT property is only attached if its size is not 0.
> > + */
> > +static void
> > +dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> > +{
> > +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> > +
> > +	if (adev->dm.dc->caps.color.mpc.num_3dluts) {
> > +		drm_object_attach_property(&crtc->base,
> > +					   adev->mode_info.shaper_lut_property, 0);
> > +		drm_object_attach_property(&crtc->base,
> > +					   adev->mode_info.shaper_lut_size_property,
> > +					   MAX_COLOR_LUT_ENTRIES);
> > +	}
> > +}
> > +
> > +static int
> > +atomic_replace_property_blob_from_id(struct drm_device *dev,
> > +					 struct drm_property_blob **blob,
> > +					 uint64_t blob_id,
> > +					 ssize_t expected_size,
> > +					 ssize_t expected_elem_size,
> > +					 bool *replaced)
> > +{
> > +	struct drm_property_blob *new_blob = NULL;
> > +
> > +	if (blob_id != 0) {
> > +		new_blob = drm_property_lookup_blob(dev, blob_id);
> > +		if (new_blob == NULL)
> > +			return -EINVAL;
> > +
> > +		if (expected_size > 0 &&
> > +		    new_blob->length != expected_size) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +		if (expected_elem_size > 0 &&
> > +		    new_blob->length % expected_elem_size != 0) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> > +	*replaced |= drm_property_replace_blob(blob, new_blob);
> > +	drm_property_blob_put(new_blob);
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> > +				   struct drm_crtc_state *state,
> > +				   struct drm_property *property,
> > +				   uint64_t val)
> > +{
> > +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> > +	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> > +	bool replaced = false;
> > +	int ret;
> > +
> > +	if (property == adev->mode_info.shaper_lut_property) {
> > +		ret = atomic_replace_property_blob_from_id(crtc->dev,
> > +					&acrtc_state->shaper_lut,
> > +					val,
> > +					-1, sizeof(struct drm_color_lut),
> > +					&replaced);
> > +		acrtc_state->base.color_mgmt_changed |= replaced;
> > +		return ret;
> > +	} else {
> > +		drm_dbg_atomic(crtc->dev,
> > +			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> > +			       crtc->base.id, crtc->name,
> > +			       property->base.id, property->name);
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> > +				   const struct drm_crtc_state *state,
> > +				   struct drm_property *property,
> > +				   uint64_t *val)
> > +{
> > +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> > +	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> > +
> > +	if (property == adev->mode_info.shaper_lut_property)
> > +		*val = (acrtc_state->shaper_lut) ?
> > +			acrtc_state->shaper_lut->base.id : 0;
> > +	else
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
> > +#endif
> > +
> >  /* Implemented only the options currently available for the driver */
> >  static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
> >  	.reset = dm_crtc_reset_state,
> > @@ -317,6 +429,10 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
> >  #if defined(CONFIG_DEBUG_FS)
> >  	.late_register = amdgpu_dm_crtc_late_register,
> >  #endif
> > +#ifdef CONFIG_STEAM_DECK
> > +	.atomic_set_property = amdgpu_dm_atomic_crtc_set_property,
> > +	.atomic_get_property = amdgpu_dm_atomic_crtc_get_property,
> > +#endif
> >  };
> >  
> >  static void dm_crtc_helper_disable(struct drm_crtc *crtc)
> > @@ -477,9 +593,11 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
> >  	is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch;
> >  	drm_crtc_enable_color_mgmt(&acrtc->base, is_dcn ? MAX_COLOR_LUT_ENTRIES : 0,
> >  				   true, MAX_COLOR_LUT_ENTRIES);
> > -
> >  	drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES);
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +	dm_crtc_additional_color_mgmt(&acrtc->base);
> > +#endif
> >  	return 0;
> >  
> >  fail:
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 05/40] drm/amd/display: add shaper LUT driver-private props
@ 2023-05-09 16:30       ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:30 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, Alex Deucher,
	christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 10830 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > CRTC shaper LUT shapes the content after blending, i.e., de-linearizes
> > or normalizes space before applying a 3D LUT color correction. In the
> > next patch, we add CRTC 3D LUT property to DRM color management after
> > this shaper LUT and before the current CRTC gamma LUT.
> > 
> 
> It might be good to describe the motivation behind the "de-linearization"
> of pixels. Since a 3DLUT has a limited number of entries in each dimension
> we want to use them in an optimal fashion. This means using the 3DLUT in
> a colorspace that is optimized for human vision, such as sRGB, PQ, or
> another non-linear space.

ack.

> 
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  28 ++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  14 ++
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  17 +++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 122 +++++++++++++++++-
> >  4 files changed, 179 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index 8632ab695a6c..44c22cb87dde 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -1247,6 +1247,30 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
> >  	return &amdgpu_fb->base;
> >  }
> >  
> > +#ifdef CONFIG_STEAM_DECK
> 
> Something like AMD_PRIVATE_COLOR would be better.

Oh, I see your suggestion for my previous question here, so nvm.

> 
> It might also be enough to guard only the bits that make the uAPI
> appear, such as drm_property_create, etc.

Makes sense. Joshie also suggested me this path.

Thanks!

> 
> Harry
> 
> > +static int
> > +amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > +{
> > +	struct drm_property *prop;
> > +
> > +	prop = drm_property_create(adev_to_drm(adev),
> > +				   DRM_MODE_PROP_BLOB,
> > +				   "AMD_SHAPER_LUT", 0);
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.shaper_lut_property = prop;
> > +
> > +	prop = drm_property_create_range(adev_to_drm(adev),
> > +					 DRM_MODE_PROP_IMMUTABLE,
> > +					 "AMD_SHAPER_LUT_SIZE", 0, UINT_MAX);
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.shaper_lut_size_property = prop;
> > +
> > +	return 0;
> > +}
> > +#endif
> > +
> >  const struct drm_mode_config_funcs amdgpu_mode_funcs = {
> >  	.fb_create = amdgpu_display_user_framebuffer_create,
> >  };
> > @@ -1323,6 +1347,10 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
> >  			return -ENOMEM;
> >  	}
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +	if (amdgpu_display_create_color_properties(adev))
> > +		return -ENOMEM;
> > +#endif
> >  	return 0;
> >  }
> >  
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > index b8633df418d4..1fd3497af3b5 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > @@ -344,6 +344,20 @@ struct amdgpu_mode_info {
> >  	int			disp_priority;
> >  	const struct amdgpu_display_funcs *funcs;
> >  	const enum drm_plane_type *plane_type;
> > +
> > +	/* Driver-private color mgmt props */
> > +#ifdef CONFIG_STEAM_DECK
> > +	/**
> > +	 * @shaper_lut_property: CRTC property to set post-blending shaper LUT
> > +	 * that converts content before 3D LUT gamma correction.
> > +	 */
> > +	struct drm_property *shaper_lut_property;
> > +	/**
> > +	 * @shaper_lut_size_property: CRTC property for the size of
> > +	 * post-blending shaper LUT as supported by the driver (read-only).
> > +	 */
> > +	struct drm_property *shaper_lut_size_property;
> > +#endif
> >  };
> >  
> >  #define AMDGPU_MAX_BL_LEVEL 0xFF
> > 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 2e2413fd73a4..de63455896cc 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > @@ -726,6 +726,23 @@ struct dm_crtc_state {
> >  	struct dc_info_packet vrr_infopacket;
> >  
> >  	int abm_level;
> > +
> > +#ifdef CONFIG_STEAM_DECK
> > +	/* AMD driver-private color mgmt pipeline
> > +	 *
> > +	 * DRM provides CRTC degamma/ctm/gamma color mgmt features, but AMD HW
> > +	 * has a larger set of post-blending color calibration features, as
> > +	 * below:
> > +	 */
> > +	/**
> > +	 * @shaper_lut:
> > +	 *
> > +	 * Lookup table used to de-linearize pixel data for gamma correction.
> > +	 * See drm_crtc_enable_color_mgmt(). The blob (if not NULL) is an array
> > +	 * of &struct drm_color_lut.
> > +	 */
> > +	struct drm_property_blob *shaper_lut;
> > +#endif
> >  };
> >  
> >  #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > index e3762e806617..503433e5cb38 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > @@ -229,7 +229,9 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
> >  	if (cur->stream)
> >  		dc_stream_release(cur->stream);
> >  
> > -
> > +#ifdef CONFIG_STEAM_DECK
> > +	drm_property_blob_put(cur->shaper_lut);
> > +#endif
> >  	__drm_atomic_helper_crtc_destroy_state(state);
> >  
> >  
> > @@ -266,7 +268,12 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
> >  	state->crc_skip_count = cur->crc_skip_count;
> >  	state->mpo_requested = cur->mpo_requested;
> >  	/* TODO Duplicate dc_stream after objects are stream object is flattened */
> > +#ifdef CONFIG_STEAM_DECK
> > +	state->shaper_lut = cur->shaper_lut;
> >  
> > +	if (state->shaper_lut)
> > +		drm_property_blob_get(state->shaper_lut);
> > +#endif
> >  	return &state->base;
> >  }
> >  
> > @@ -299,6 +306,111 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc)
> >  }
> >  #endif
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +/**
> > + * drm_crtc_additional_color_mgmt - enable additional color properties
> > + * @crtc: DRM CRTC
> > + *
> > + * This function lets the driver enable the 3D LUT color correction property
> > + * on a CRTC. This includes shaper LUT, 3D LUT and regamma TF. The shaper
> > + * LUT and 3D LUT property is only attached if its size is not 0.
> > + */
> > +static void
> > +dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> > +{
> > +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> > +
> > +	if (adev->dm.dc->caps.color.mpc.num_3dluts) {
> > +		drm_object_attach_property(&crtc->base,
> > +					   adev->mode_info.shaper_lut_property, 0);
> > +		drm_object_attach_property(&crtc->base,
> > +					   adev->mode_info.shaper_lut_size_property,
> > +					   MAX_COLOR_LUT_ENTRIES);
> > +	}
> > +}
> > +
> > +static int
> > +atomic_replace_property_blob_from_id(struct drm_device *dev,
> > +					 struct drm_property_blob **blob,
> > +					 uint64_t blob_id,
> > +					 ssize_t expected_size,
> > +					 ssize_t expected_elem_size,
> > +					 bool *replaced)
> > +{
> > +	struct drm_property_blob *new_blob = NULL;
> > +
> > +	if (blob_id != 0) {
> > +		new_blob = drm_property_lookup_blob(dev, blob_id);
> > +		if (new_blob == NULL)
> > +			return -EINVAL;
> > +
> > +		if (expected_size > 0 &&
> > +		    new_blob->length != expected_size) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +		if (expected_elem_size > 0 &&
> > +		    new_blob->length % expected_elem_size != 0) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> > +	*replaced |= drm_property_replace_blob(blob, new_blob);
> > +	drm_property_blob_put(new_blob);
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> > +				   struct drm_crtc_state *state,
> > +				   struct drm_property *property,
> > +				   uint64_t val)
> > +{
> > +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> > +	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> > +	bool replaced = false;
> > +	int ret;
> > +
> > +	if (property == adev->mode_info.shaper_lut_property) {
> > +		ret = atomic_replace_property_blob_from_id(crtc->dev,
> > +					&acrtc_state->shaper_lut,
> > +					val,
> > +					-1, sizeof(struct drm_color_lut),
> > +					&replaced);
> > +		acrtc_state->base.color_mgmt_changed |= replaced;
> > +		return ret;
> > +	} else {
> > +		drm_dbg_atomic(crtc->dev,
> > +			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> > +			       crtc->base.id, crtc->name,
> > +			       property->base.id, property->name);
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> > +				   const struct drm_crtc_state *state,
> > +				   struct drm_property *property,
> > +				   uint64_t *val)
> > +{
> > +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> > +	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> > +
> > +	if (property == adev->mode_info.shaper_lut_property)
> > +		*val = (acrtc_state->shaper_lut) ?
> > +			acrtc_state->shaper_lut->base.id : 0;
> > +	else
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
> > +#endif
> > +
> >  /* Implemented only the options currently available for the driver */
> >  static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
> >  	.reset = dm_crtc_reset_state,
> > @@ -317,6 +429,10 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
> >  #if defined(CONFIG_DEBUG_FS)
> >  	.late_register = amdgpu_dm_crtc_late_register,
> >  #endif
> > +#ifdef CONFIG_STEAM_DECK
> > +	.atomic_set_property = amdgpu_dm_atomic_crtc_set_property,
> > +	.atomic_get_property = amdgpu_dm_atomic_crtc_get_property,
> > +#endif
> >  };
> >  
> >  static void dm_crtc_helper_disable(struct drm_crtc *crtc)
> > @@ -477,9 +593,11 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
> >  	is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch;
> >  	drm_crtc_enable_color_mgmt(&acrtc->base, is_dcn ? MAX_COLOR_LUT_ENTRIES : 0,
> >  				   true, MAX_COLOR_LUT_ENTRIES);
> > -
> >  	drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES);
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +	dm_crtc_additional_color_mgmt(&acrtc->base);
> > +#endif
> >  	return 0;
> >  
> >  fail:
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 05/40] drm/amd/display: add shaper LUT driver-private props
@ 2023-05-09 16:30       ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:30 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, daniel, Alex Deucher,
	airlied, christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 10830 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > CRTC shaper LUT shapes the content after blending, i.e., de-linearizes
> > or normalizes space before applying a 3D LUT color correction. In the
> > next patch, we add CRTC 3D LUT property to DRM color management after
> > this shaper LUT and before the current CRTC gamma LUT.
> > 
> 
> It might be good to describe the motivation behind the "de-linearization"
> of pixels. Since a 3DLUT has a limited number of entries in each dimension
> we want to use them in an optimal fashion. This means using the 3DLUT in
> a colorspace that is optimized for human vision, such as sRGB, PQ, or
> another non-linear space.

ack.

> 
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  28 ++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  14 ++
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  17 +++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 122 +++++++++++++++++-
> >  4 files changed, 179 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index 8632ab695a6c..44c22cb87dde 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -1247,6 +1247,30 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
> >  	return &amdgpu_fb->base;
> >  }
> >  
> > +#ifdef CONFIG_STEAM_DECK
> 
> Something like AMD_PRIVATE_COLOR would be better.

Oh, I see your suggestion for my previous question here, so nvm.

> 
> It might also be enough to guard only the bits that make the uAPI
> appear, such as drm_property_create, etc.

Makes sense. Joshie also suggested me this path.

Thanks!

> 
> Harry
> 
> > +static int
> > +amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > +{
> > +	struct drm_property *prop;
> > +
> > +	prop = drm_property_create(adev_to_drm(adev),
> > +				   DRM_MODE_PROP_BLOB,
> > +				   "AMD_SHAPER_LUT", 0);
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.shaper_lut_property = prop;
> > +
> > +	prop = drm_property_create_range(adev_to_drm(adev),
> > +					 DRM_MODE_PROP_IMMUTABLE,
> > +					 "AMD_SHAPER_LUT_SIZE", 0, UINT_MAX);
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.shaper_lut_size_property = prop;
> > +
> > +	return 0;
> > +}
> > +#endif
> > +
> >  const struct drm_mode_config_funcs amdgpu_mode_funcs = {
> >  	.fb_create = amdgpu_display_user_framebuffer_create,
> >  };
> > @@ -1323,6 +1347,10 @@ int amdgpu_display_modeset_create_props(struct amdgpu_device *adev)
> >  			return -ENOMEM;
> >  	}
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +	if (amdgpu_display_create_color_properties(adev))
> > +		return -ENOMEM;
> > +#endif
> >  	return 0;
> >  }
> >  
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > index b8633df418d4..1fd3497af3b5 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > @@ -344,6 +344,20 @@ struct amdgpu_mode_info {
> >  	int			disp_priority;
> >  	const struct amdgpu_display_funcs *funcs;
> >  	const enum drm_plane_type *plane_type;
> > +
> > +	/* Driver-private color mgmt props */
> > +#ifdef CONFIG_STEAM_DECK
> > +	/**
> > +	 * @shaper_lut_property: CRTC property to set post-blending shaper LUT
> > +	 * that converts content before 3D LUT gamma correction.
> > +	 */
> > +	struct drm_property *shaper_lut_property;
> > +	/**
> > +	 * @shaper_lut_size_property: CRTC property for the size of
> > +	 * post-blending shaper LUT as supported by the driver (read-only).
> > +	 */
> > +	struct drm_property *shaper_lut_size_property;
> > +#endif
> >  };
> >  
> >  #define AMDGPU_MAX_BL_LEVEL 0xFF
> > 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 2e2413fd73a4..de63455896cc 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > @@ -726,6 +726,23 @@ struct dm_crtc_state {
> >  	struct dc_info_packet vrr_infopacket;
> >  
> >  	int abm_level;
> > +
> > +#ifdef CONFIG_STEAM_DECK
> > +	/* AMD driver-private color mgmt pipeline
> > +	 *
> > +	 * DRM provides CRTC degamma/ctm/gamma color mgmt features, but AMD HW
> > +	 * has a larger set of post-blending color calibration features, as
> > +	 * below:
> > +	 */
> > +	/**
> > +	 * @shaper_lut:
> > +	 *
> > +	 * Lookup table used to de-linearize pixel data for gamma correction.
> > +	 * See drm_crtc_enable_color_mgmt(). The blob (if not NULL) is an array
> > +	 * of &struct drm_color_lut.
> > +	 */
> > +	struct drm_property_blob *shaper_lut;
> > +#endif
> >  };
> >  
> >  #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base)
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > index e3762e806617..503433e5cb38 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > @@ -229,7 +229,9 @@ static void dm_crtc_destroy_state(struct drm_crtc *crtc,
> >  	if (cur->stream)
> >  		dc_stream_release(cur->stream);
> >  
> > -
> > +#ifdef CONFIG_STEAM_DECK
> > +	drm_property_blob_put(cur->shaper_lut);
> > +#endif
> >  	__drm_atomic_helper_crtc_destroy_state(state);
> >  
> >  
> > @@ -266,7 +268,12 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
> >  	state->crc_skip_count = cur->crc_skip_count;
> >  	state->mpo_requested = cur->mpo_requested;
> >  	/* TODO Duplicate dc_stream after objects are stream object is flattened */
> > +#ifdef CONFIG_STEAM_DECK
> > +	state->shaper_lut = cur->shaper_lut;
> >  
> > +	if (state->shaper_lut)
> > +		drm_property_blob_get(state->shaper_lut);
> > +#endif
> >  	return &state->base;
> >  }
> >  
> > @@ -299,6 +306,111 @@ static int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc)
> >  }
> >  #endif
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +/**
> > + * drm_crtc_additional_color_mgmt - enable additional color properties
> > + * @crtc: DRM CRTC
> > + *
> > + * This function lets the driver enable the 3D LUT color correction property
> > + * on a CRTC. This includes shaper LUT, 3D LUT and regamma TF. The shaper
> > + * LUT and 3D LUT property is only attached if its size is not 0.
> > + */
> > +static void
> > +dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> > +{
> > +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> > +
> > +	if (adev->dm.dc->caps.color.mpc.num_3dluts) {
> > +		drm_object_attach_property(&crtc->base,
> > +					   adev->mode_info.shaper_lut_property, 0);
> > +		drm_object_attach_property(&crtc->base,
> > +					   adev->mode_info.shaper_lut_size_property,
> > +					   MAX_COLOR_LUT_ENTRIES);
> > +	}
> > +}
> > +
> > +static int
> > +atomic_replace_property_blob_from_id(struct drm_device *dev,
> > +					 struct drm_property_blob **blob,
> > +					 uint64_t blob_id,
> > +					 ssize_t expected_size,
> > +					 ssize_t expected_elem_size,
> > +					 bool *replaced)
> > +{
> > +	struct drm_property_blob *new_blob = NULL;
> > +
> > +	if (blob_id != 0) {
> > +		new_blob = drm_property_lookup_blob(dev, blob_id);
> > +		if (new_blob == NULL)
> > +			return -EINVAL;
> > +
> > +		if (expected_size > 0 &&
> > +		    new_blob->length != expected_size) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +		if (expected_elem_size > 0 &&
> > +		    new_blob->length % expected_elem_size != 0) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> > +	*replaced |= drm_property_replace_blob(blob, new_blob);
> > +	drm_property_blob_put(new_blob);
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> > +				   struct drm_crtc_state *state,
> > +				   struct drm_property *property,
> > +				   uint64_t val)
> > +{
> > +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> > +	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> > +	bool replaced = false;
> > +	int ret;
> > +
> > +	if (property == adev->mode_info.shaper_lut_property) {
> > +		ret = atomic_replace_property_blob_from_id(crtc->dev,
> > +					&acrtc_state->shaper_lut,
> > +					val,
> > +					-1, sizeof(struct drm_color_lut),
> > +					&replaced);
> > +		acrtc_state->base.color_mgmt_changed |= replaced;
> > +		return ret;
> > +	} else {
> > +		drm_dbg_atomic(crtc->dev,
> > +			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> > +			       crtc->base.id, crtc->name,
> > +			       property->base.id, property->name);
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> > +				   const struct drm_crtc_state *state,
> > +				   struct drm_property *property,
> > +				   uint64_t *val)
> > +{
> > +	struct amdgpu_device *adev = drm_to_adev(crtc->dev);
> > +	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(state);
> > +
> > +	if (property == adev->mode_info.shaper_lut_property)
> > +		*val = (acrtc_state->shaper_lut) ?
> > +			acrtc_state->shaper_lut->base.id : 0;
> > +	else
> > +		return -EINVAL;
> > +
> > +	return 0;
> > +}
> > +#endif
> > +
> >  /* Implemented only the options currently available for the driver */
> >  static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
> >  	.reset = dm_crtc_reset_state,
> > @@ -317,6 +429,10 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = {
> >  #if defined(CONFIG_DEBUG_FS)
> >  	.late_register = amdgpu_dm_crtc_late_register,
> >  #endif
> > +#ifdef CONFIG_STEAM_DECK
> > +	.atomic_set_property = amdgpu_dm_atomic_crtc_set_property,
> > +	.atomic_get_property = amdgpu_dm_atomic_crtc_get_property,
> > +#endif
> >  };
> >  
> >  static void dm_crtc_helper_disable(struct drm_crtc *crtc)
> > @@ -477,9 +593,11 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
> >  	is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch;
> >  	drm_crtc_enable_color_mgmt(&acrtc->base, is_dcn ? MAX_COLOR_LUT_ENTRIES : 0,
> >  				   true, MAX_COLOR_LUT_ENTRIES);
> > -
> >  	drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES);
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +	dm_crtc_additional_color_mgmt(&acrtc->base);
> > +#endif
> >  	return 0;
> >  
> >  fail:
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to driver-private props
  2023-05-08 21:24     ` Harry Wentland
  (?)
@ 2023-05-09 16:34       ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:34 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, Alex Deucher,
	christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 6851 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > From: Joshua Ashton <joshua@froggi.es>
> > 
> > Add predefined transfer function property to DRM CRTC gamma to convert
> > to wire encoding with or without gamma LUT.
> > 
> 
> Are all these new CRTC properties used by gamescope? I would be reluctant
> to merge them if they're currently not needed.

The regamma TF yes. The shaper and 3D LUT not yet.

I'll double check with Joshie and drop from the series what we don't
have a short-term perspective of usage.

> 
> > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 22 ++++++++++++++++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 ++++
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 23 +++++++++++++++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 13 +++++++++++
> >  4 files changed, 62 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index 2abe5fe87c10..1913903cab88 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -1248,6 +1248,19 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
> >  }
> >  
> >  #ifdef CONFIG_STEAM_DECK
> > +static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
> > +	{ DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
> > +	{ DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
> > +	{ DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
> > +	{ DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
> > +	{ DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
> > +	{ DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
> > +	{ DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
> > +	{ DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
> > +	{ DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
> > +	{ DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
> > +};
> > +
> 
> Would it be better to prefix things with AMD_/amd_ to avoid confusion? On the other
> hand, these will likely just move into DRM core once we get the generic color uAPI.
> 
> Harry
> 
> >  static int
> >  amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >  {
> > @@ -1281,6 +1294,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >  		return -ENOMEM;
> >  	adev->mode_info.lut3d_size_property = prop;
> >  
> > +	prop = drm_property_create_enum(adev_to_drm(adev),
> > +					DRM_MODE_PROP_ENUM,
> > +					"GAMMA_TF",
> > +					drm_transfer_function_enum_list,
> > +					ARRAY_SIZE(drm_transfer_function_enum_list));
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.gamma_tf_property = prop;
> > +
> >  	return 0;
> >  }
> >  #endif
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > index 205fa4f5bea7..76337e18c728 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > @@ -368,6 +368,10 @@ struct amdgpu_mode_info {
> >  	 * LUT as supported by the driver (read-only).
> >  	 */
> >  	struct drm_property *lut3d_size_property;
> > +	/**
> > +	 * @gamma_tf_property: Transfer function for CRTC regamma.
> > +	 */
> > +	struct drm_property *gamma_tf_property;
> >  #endif
> >  };
> >  
> > 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 09c3e1858b56..1e90a2dd445e 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > @@ -699,6 +699,23 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
> >  
> >  extern const struct amdgpu_ip_block_version dm_ip_block;
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +enum drm_transfer_function {
> > +	DRM_TRANSFER_FUNCTION_DEFAULT,
> > +
> > +	DRM_TRANSFER_FUNCTION_SRGB,
> > +	DRM_TRANSFER_FUNCTION_BT709,
> > +	DRM_TRANSFER_FUNCTION_PQ,
> > +	DRM_TRANSFER_FUNCTION_LINEAR,
> > +	DRM_TRANSFER_FUNCTION_UNITY,
> > +	DRM_TRANSFER_FUNCTION_HLG,
> > +	DRM_TRANSFER_FUNCTION_GAMMA22,
> > +	DRM_TRANSFER_FUNCTION_GAMMA24,
> > +	DRM_TRANSFER_FUNCTION_GAMMA26,
> > +	DRM_TRANSFER_FUNCTION_MAX,
> > +};
> > +#endif
> > +
> >  struct dm_plane_state {
> >  	struct drm_plane_state base;
> >  	struct dc_plane_state *dc_state;
> > @@ -751,6 +768,12 @@ struct dm_crtc_state {
> >  	 * &struct drm_color_lut.
> >  	 */
> >  	struct drm_property_blob *lut3d;
> > +        /**
> > +	 * @gamma_tf:
> > +	 *
> > +	 * Pre-defined transfer function for converting internal FB -> wire encoding.
> > +	 */
> > +	enum drm_transfer_function gamma_tf;
> >  #endif
> >  };
> >  
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > index 0e1280228e6e..79324fbab1f1 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > @@ -272,6 +272,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
> >  #ifdef CONFIG_STEAM_DECK
> >  	state->shaper_lut = cur->shaper_lut;
> >  	state->lut3d = cur->lut3d;
> > +	state->gamma_tf = cur->gamma_tf;
> >  
> >  	if (state->shaper_lut)
> >  		drm_property_blob_get(state->shaper_lut);
> > @@ -336,6 +337,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> >  					   adev->mode_info.lut3d_size_property,
> >  					   MAX_COLOR_3DLUT_ENTRIES);
> >  	}
> > +
> > +	if(adev->dm.dc->caps.color.mpc.ogam_ram)
> > +		drm_object_attach_property(&crtc->base,
> > +					   adev->mode_info.gamma_tf_property,
> > +					   DRM_TRANSFER_FUNCTION_DEFAULT);
> >  }
> >  
> >  static int
> > @@ -398,6 +404,11 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  					&replaced);
> >  		acrtc_state->base.color_mgmt_changed |= replaced;
> >  		return ret;
> > +	} else if (property == adev->mode_info.gamma_tf_property) {
> > +		if (acrtc_state->gamma_tf != val) {
> > +			acrtc_state->gamma_tf = val;
> > +			acrtc_state->base.color_mgmt_changed |= 1;
> > +		}
> >  	} else {
> >  		drm_dbg_atomic(crtc->dev,
> >  			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> > @@ -424,6 +435,8 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> >  	else if (property == adev->mode_info.lut3d_property)
> >  		*val = (acrtc_state->lut3d) ?
> >  			acrtc_state->lut3d->base.id : 0;
> > +	else if (property == adev->mode_info.gamma_tf_property)
> > +		*val = acrtc_state->gamma_tf;
> >  	else
> >  		return -EINVAL;
> >  
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to driver-private props
@ 2023-05-09 16:34       ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:34 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, daniel, Alex Deucher,
	airlied, christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 6851 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > From: Joshua Ashton <joshua@froggi.es>
> > 
> > Add predefined transfer function property to DRM CRTC gamma to convert
> > to wire encoding with or without gamma LUT.
> > 
> 
> Are all these new CRTC properties used by gamescope? I would be reluctant
> to merge them if they're currently not needed.

The regamma TF yes. The shaper and 3D LUT not yet.

I'll double check with Joshie and drop from the series what we don't
have a short-term perspective of usage.

> 
> > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 22 ++++++++++++++++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 ++++
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 23 +++++++++++++++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 13 +++++++++++
> >  4 files changed, 62 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index 2abe5fe87c10..1913903cab88 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -1248,6 +1248,19 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
> >  }
> >  
> >  #ifdef CONFIG_STEAM_DECK
> > +static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
> > +	{ DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
> > +	{ DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
> > +	{ DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
> > +	{ DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
> > +	{ DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
> > +	{ DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
> > +	{ DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
> > +	{ DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
> > +	{ DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
> > +	{ DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
> > +};
> > +
> 
> Would it be better to prefix things with AMD_/amd_ to avoid confusion? On the other
> hand, these will likely just move into DRM core once we get the generic color uAPI.
> 
> Harry
> 
> >  static int
> >  amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >  {
> > @@ -1281,6 +1294,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >  		return -ENOMEM;
> >  	adev->mode_info.lut3d_size_property = prop;
> >  
> > +	prop = drm_property_create_enum(adev_to_drm(adev),
> > +					DRM_MODE_PROP_ENUM,
> > +					"GAMMA_TF",
> > +					drm_transfer_function_enum_list,
> > +					ARRAY_SIZE(drm_transfer_function_enum_list));
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.gamma_tf_property = prop;
> > +
> >  	return 0;
> >  }
> >  #endif
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > index 205fa4f5bea7..76337e18c728 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > @@ -368,6 +368,10 @@ struct amdgpu_mode_info {
> >  	 * LUT as supported by the driver (read-only).
> >  	 */
> >  	struct drm_property *lut3d_size_property;
> > +	/**
> > +	 * @gamma_tf_property: Transfer function for CRTC regamma.
> > +	 */
> > +	struct drm_property *gamma_tf_property;
> >  #endif
> >  };
> >  
> > 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 09c3e1858b56..1e90a2dd445e 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > @@ -699,6 +699,23 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
> >  
> >  extern const struct amdgpu_ip_block_version dm_ip_block;
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +enum drm_transfer_function {
> > +	DRM_TRANSFER_FUNCTION_DEFAULT,
> > +
> > +	DRM_TRANSFER_FUNCTION_SRGB,
> > +	DRM_TRANSFER_FUNCTION_BT709,
> > +	DRM_TRANSFER_FUNCTION_PQ,
> > +	DRM_TRANSFER_FUNCTION_LINEAR,
> > +	DRM_TRANSFER_FUNCTION_UNITY,
> > +	DRM_TRANSFER_FUNCTION_HLG,
> > +	DRM_TRANSFER_FUNCTION_GAMMA22,
> > +	DRM_TRANSFER_FUNCTION_GAMMA24,
> > +	DRM_TRANSFER_FUNCTION_GAMMA26,
> > +	DRM_TRANSFER_FUNCTION_MAX,
> > +};
> > +#endif
> > +
> >  struct dm_plane_state {
> >  	struct drm_plane_state base;
> >  	struct dc_plane_state *dc_state;
> > @@ -751,6 +768,12 @@ struct dm_crtc_state {
> >  	 * &struct drm_color_lut.
> >  	 */
> >  	struct drm_property_blob *lut3d;
> > +        /**
> > +	 * @gamma_tf:
> > +	 *
> > +	 * Pre-defined transfer function for converting internal FB -> wire encoding.
> > +	 */
> > +	enum drm_transfer_function gamma_tf;
> >  #endif
> >  };
> >  
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > index 0e1280228e6e..79324fbab1f1 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > @@ -272,6 +272,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
> >  #ifdef CONFIG_STEAM_DECK
> >  	state->shaper_lut = cur->shaper_lut;
> >  	state->lut3d = cur->lut3d;
> > +	state->gamma_tf = cur->gamma_tf;
> >  
> >  	if (state->shaper_lut)
> >  		drm_property_blob_get(state->shaper_lut);
> > @@ -336,6 +337,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> >  					   adev->mode_info.lut3d_size_property,
> >  					   MAX_COLOR_3DLUT_ENTRIES);
> >  	}
> > +
> > +	if(adev->dm.dc->caps.color.mpc.ogam_ram)
> > +		drm_object_attach_property(&crtc->base,
> > +					   adev->mode_info.gamma_tf_property,
> > +					   DRM_TRANSFER_FUNCTION_DEFAULT);
> >  }
> >  
> >  static int
> > @@ -398,6 +404,11 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  					&replaced);
> >  		acrtc_state->base.color_mgmt_changed |= replaced;
> >  		return ret;
> > +	} else if (property == adev->mode_info.gamma_tf_property) {
> > +		if (acrtc_state->gamma_tf != val) {
> > +			acrtc_state->gamma_tf = val;
> > +			acrtc_state->base.color_mgmt_changed |= 1;
> > +		}
> >  	} else {
> >  		drm_dbg_atomic(crtc->dev,
> >  			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> > @@ -424,6 +435,8 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> >  	else if (property == adev->mode_info.lut3d_property)
> >  		*val = (acrtc_state->lut3d) ?
> >  			acrtc_state->lut3d->base.id : 0;
> > +	else if (property == adev->mode_info.gamma_tf_property)
> > +		*val = acrtc_state->gamma_tf;
> >  	else
> >  		return -EINVAL;
> >  
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to driver-private props
@ 2023-05-09 16:34       ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:34 UTC (permalink / raw)
  To: Harry Wentland
  Cc: amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher, dri-devel,
	christian.koenig, Xinhui.Pan, airlied, daniel, Joshua Ashton,
	Sebastian Wick, Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas,
	sungjoon.kim, Alex Hung, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 6851 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > From: Joshua Ashton <joshua@froggi.es>
> > 
> > Add predefined transfer function property to DRM CRTC gamma to convert
> > to wire encoding with or without gamma LUT.
> > 
> 
> Are all these new CRTC properties used by gamescope? I would be reluctant
> to merge them if they're currently not needed.

The regamma TF yes. The shaper and 3D LUT not yet.

I'll double check with Joshie and drop from the series what we don't
have a short-term perspective of usage.

> 
> > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 22 ++++++++++++++++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 ++++
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 23 +++++++++++++++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 13 +++++++++++
> >  4 files changed, 62 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index 2abe5fe87c10..1913903cab88 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -1248,6 +1248,19 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
> >  }
> >  
> >  #ifdef CONFIG_STEAM_DECK
> > +static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
> > +	{ DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
> > +	{ DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
> > +	{ DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
> > +	{ DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
> > +	{ DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
> > +	{ DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
> > +	{ DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
> > +	{ DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
> > +	{ DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
> > +	{ DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
> > +};
> > +
> 
> Would it be better to prefix things with AMD_/amd_ to avoid confusion? On the other
> hand, these will likely just move into DRM core once we get the generic color uAPI.
> 
> Harry
> 
> >  static int
> >  amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >  {
> > @@ -1281,6 +1294,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >  		return -ENOMEM;
> >  	adev->mode_info.lut3d_size_property = prop;
> >  
> > +	prop = drm_property_create_enum(adev_to_drm(adev),
> > +					DRM_MODE_PROP_ENUM,
> > +					"GAMMA_TF",
> > +					drm_transfer_function_enum_list,
> > +					ARRAY_SIZE(drm_transfer_function_enum_list));
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.gamma_tf_property = prop;
> > +
> >  	return 0;
> >  }
> >  #endif
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > index 205fa4f5bea7..76337e18c728 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > @@ -368,6 +368,10 @@ struct amdgpu_mode_info {
> >  	 * LUT as supported by the driver (read-only).
> >  	 */
> >  	struct drm_property *lut3d_size_property;
> > +	/**
> > +	 * @gamma_tf_property: Transfer function for CRTC regamma.
> > +	 */
> > +	struct drm_property *gamma_tf_property;
> >  #endif
> >  };
> >  
> > 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 09c3e1858b56..1e90a2dd445e 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > @@ -699,6 +699,23 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
> >  
> >  extern const struct amdgpu_ip_block_version dm_ip_block;
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +enum drm_transfer_function {
> > +	DRM_TRANSFER_FUNCTION_DEFAULT,
> > +
> > +	DRM_TRANSFER_FUNCTION_SRGB,
> > +	DRM_TRANSFER_FUNCTION_BT709,
> > +	DRM_TRANSFER_FUNCTION_PQ,
> > +	DRM_TRANSFER_FUNCTION_LINEAR,
> > +	DRM_TRANSFER_FUNCTION_UNITY,
> > +	DRM_TRANSFER_FUNCTION_HLG,
> > +	DRM_TRANSFER_FUNCTION_GAMMA22,
> > +	DRM_TRANSFER_FUNCTION_GAMMA24,
> > +	DRM_TRANSFER_FUNCTION_GAMMA26,
> > +	DRM_TRANSFER_FUNCTION_MAX,
> > +};
> > +#endif
> > +
> >  struct dm_plane_state {
> >  	struct drm_plane_state base;
> >  	struct dc_plane_state *dc_state;
> > @@ -751,6 +768,12 @@ struct dm_crtc_state {
> >  	 * &struct drm_color_lut.
> >  	 */
> >  	struct drm_property_blob *lut3d;
> > +        /**
> > +	 * @gamma_tf:
> > +	 *
> > +	 * Pre-defined transfer function for converting internal FB -> wire encoding.
> > +	 */
> > +	enum drm_transfer_function gamma_tf;
> >  #endif
> >  };
> >  
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > index 0e1280228e6e..79324fbab1f1 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > @@ -272,6 +272,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
> >  #ifdef CONFIG_STEAM_DECK
> >  	state->shaper_lut = cur->shaper_lut;
> >  	state->lut3d = cur->lut3d;
> > +	state->gamma_tf = cur->gamma_tf;
> >  
> >  	if (state->shaper_lut)
> >  		drm_property_blob_get(state->shaper_lut);
> > @@ -336,6 +337,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> >  					   adev->mode_info.lut3d_size_property,
> >  					   MAX_COLOR_3DLUT_ENTRIES);
> >  	}
> > +
> > +	if(adev->dm.dc->caps.color.mpc.ogam_ram)
> > +		drm_object_attach_property(&crtc->base,
> > +					   adev->mode_info.gamma_tf_property,
> > +					   DRM_TRANSFER_FUNCTION_DEFAULT);
> >  }
> >  
> >  static int
> > @@ -398,6 +404,11 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  					&replaced);
> >  		acrtc_state->base.color_mgmt_changed |= replaced;
> >  		return ret;
> > +	} else if (property == adev->mode_info.gamma_tf_property) {
> > +		if (acrtc_state->gamma_tf != val) {
> > +			acrtc_state->gamma_tf = val;
> > +			acrtc_state->base.color_mgmt_changed |= 1;
> > +		}
> >  	} else {
> >  		drm_dbg_atomic(crtc->dev,
> >  			       "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> > @@ -424,6 +435,8 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> >  	else if (property == adev->mode_info.lut3d_property)
> >  		*val = (acrtc_state->lut3d) ?
> >  			acrtc_state->lut3d->base.id : 0;
> > +	else if (property == adev->mode_info.gamma_tf_property)
> > +		*val = acrtc_state->gamma_tf;
> >  	else
> >  		return -EINVAL;
> >  
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 09/40] drm/amd/display: move replace blob func to dm plane
  2023-05-08 21:24     ` Harry Wentland
  (?)
@ 2023-05-09 16:35       ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:35 UTC (permalink / raw)
  To: Harry Wentland
  Cc: amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher, dri-devel,
	christian.koenig, Xinhui.Pan, airlied, daniel, Joshua Ashton,
	Sebastian Wick, Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas,
	sungjoon.kim, Alex Hung, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 5825 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > From amdgpu_dm_plane we can get it for both CRTC and plane color
> > properties. We are adding new plane properties for AMD driver-private
> > color mgmt.
> > 
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > ---
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 37 +------------------
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 35 ++++++++++++++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |  7 ++++
> >  3 files changed, 44 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > index 79324fbab1f1..27d7a8b18013 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > @@ -344,39 +344,6 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> >  					   DRM_TRANSFER_FUNCTION_DEFAULT);
> >  }
> >  
> > -static int
> > -atomic_replace_property_blob_from_id(struct drm_device *dev,
> > -					 struct drm_property_blob **blob,
> > -					 uint64_t blob_id,
> > -					 ssize_t expected_size,
> > -					 ssize_t expected_elem_size,
> > -					 bool *replaced)
> > -{
> > -	struct drm_property_blob *new_blob = NULL;
> > -
> > -	if (blob_id != 0) {
> > -		new_blob = drm_property_lookup_blob(dev, blob_id);
> > -		if (new_blob == NULL)
> > -			return -EINVAL;
> > -
> > -		if (expected_size > 0 &&
> > -		    new_blob->length != expected_size) {
> > -			drm_property_blob_put(new_blob);
> > -			return -EINVAL;
> > -		}
> > -		if (expected_elem_size > 0 &&
> > -		    new_blob->length % expected_elem_size != 0) {
> > -			drm_property_blob_put(new_blob);
> > -			return -EINVAL;
> > -		}
> > -	}
> > -
> > -	*replaced |= drm_property_replace_blob(blob, new_blob);
> > -	drm_property_blob_put(new_blob);
> > -
> > -	return 0;
> > -}
> > -
> >  static int
> >  amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  				   struct drm_crtc_state *state,
> > @@ -389,7 +356,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  	int ret;
> >  
> >  	if (property == adev->mode_info.shaper_lut_property) {
> > -		ret = atomic_replace_property_blob_from_id(crtc->dev,
> > +		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
> >  					&acrtc_state->shaper_lut,
> >  					val,
> >  					-1, sizeof(struct drm_color_lut),
> > @@ -397,7 +364,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  		acrtc_state->base.color_mgmt_changed |= replaced;
> >  		return ret;
> >  	} else if (property == adev->mode_info.lut3d_property) {
> > -		ret = atomic_replace_property_blob_from_id(crtc->dev,
> > +		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
> >  					&acrtc_state->lut3d,
> >  					val,
> >  					-1, sizeof(struct drm_color_lut),
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > index 322668973747..4e5498153be2 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > @@ -1411,6 +1411,41 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> >  	drm_atomic_helper_plane_destroy_state(plane, state);
> >  }
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +int
> > +amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > +					       struct drm_property_blob **blob,
> > +					       uint64_t blob_id,
> > +					       ssize_t expected_size,
> > +					       ssize_t expected_elem_size,
> > +					       bool *replaced)
> > +{
> > +	struct drm_property_blob *new_blob = NULL;
> > +
> > +	if (blob_id != 0) {
> > +		new_blob = drm_property_lookup_blob(dev, blob_id);
> > +		if (new_blob == NULL)
> > +			return -EINVAL;
> > +
> > +		if (expected_size > 0 &&
> > +		    new_blob->length != expected_size) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +		if (expected_elem_size > 0 &&
> > +		    new_blob->length % expected_elem_size != 0) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> > +	*replaced |= drm_property_replace_blob(blob, new_blob);
> > +	drm_property_blob_put(new_blob);
> > +
> > +	return 0;
> > +}
> 
> amdgpu_dm_plane doesn't seem the right place for it either. Maybe a new
> amdgpu_dm_helper.c/h?
> 
> Alternatively would this make sense to live in DRM core as a helper?

A DRM helper sounds better for me. I'll follow this path.

Melissa

> 
> Harry
> 
> > +#endif
> > +
> >  static const struct drm_plane_funcs dm_plane_funcs = {
> >  	.update_plane	= drm_atomic_helper_update_plane,
> >  	.disable_plane	= drm_atomic_helper_disable_plane,
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> > index 930f1572f898..1b05ac4c15f6 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> > @@ -51,6 +51,13 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev,
> >  				 bool tmz_surface,
> >  				 bool force_disable_dcc);
> >  
> > +int amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > +					    struct drm_property_blob **blob,
> > +					    uint64_t blob_id,
> > +					    ssize_t expected_size,
> > +					    ssize_t expected_elem_size,
> > +					    bool *replaced);
> > +
> >  int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
> >  			 struct drm_plane *plane,
> >  			 unsigned long possible_crtcs,
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 09/40] drm/amd/display: move replace blob func to dm plane
@ 2023-05-09 16:35       ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:35 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, Alex Deucher,
	christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 5825 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > From amdgpu_dm_plane we can get it for both CRTC and plane color
> > properties. We are adding new plane properties for AMD driver-private
> > color mgmt.
> > 
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > ---
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 37 +------------------
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 35 ++++++++++++++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |  7 ++++
> >  3 files changed, 44 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > index 79324fbab1f1..27d7a8b18013 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > @@ -344,39 +344,6 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> >  					   DRM_TRANSFER_FUNCTION_DEFAULT);
> >  }
> >  
> > -static int
> > -atomic_replace_property_blob_from_id(struct drm_device *dev,
> > -					 struct drm_property_blob **blob,
> > -					 uint64_t blob_id,
> > -					 ssize_t expected_size,
> > -					 ssize_t expected_elem_size,
> > -					 bool *replaced)
> > -{
> > -	struct drm_property_blob *new_blob = NULL;
> > -
> > -	if (blob_id != 0) {
> > -		new_blob = drm_property_lookup_blob(dev, blob_id);
> > -		if (new_blob == NULL)
> > -			return -EINVAL;
> > -
> > -		if (expected_size > 0 &&
> > -		    new_blob->length != expected_size) {
> > -			drm_property_blob_put(new_blob);
> > -			return -EINVAL;
> > -		}
> > -		if (expected_elem_size > 0 &&
> > -		    new_blob->length % expected_elem_size != 0) {
> > -			drm_property_blob_put(new_blob);
> > -			return -EINVAL;
> > -		}
> > -	}
> > -
> > -	*replaced |= drm_property_replace_blob(blob, new_blob);
> > -	drm_property_blob_put(new_blob);
> > -
> > -	return 0;
> > -}
> > -
> >  static int
> >  amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  				   struct drm_crtc_state *state,
> > @@ -389,7 +356,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  	int ret;
> >  
> >  	if (property == adev->mode_info.shaper_lut_property) {
> > -		ret = atomic_replace_property_blob_from_id(crtc->dev,
> > +		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
> >  					&acrtc_state->shaper_lut,
> >  					val,
> >  					-1, sizeof(struct drm_color_lut),
> > @@ -397,7 +364,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  		acrtc_state->base.color_mgmt_changed |= replaced;
> >  		return ret;
> >  	} else if (property == adev->mode_info.lut3d_property) {
> > -		ret = atomic_replace_property_blob_from_id(crtc->dev,
> > +		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
> >  					&acrtc_state->lut3d,
> >  					val,
> >  					-1, sizeof(struct drm_color_lut),
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > index 322668973747..4e5498153be2 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > @@ -1411,6 +1411,41 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> >  	drm_atomic_helper_plane_destroy_state(plane, state);
> >  }
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +int
> > +amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > +					       struct drm_property_blob **blob,
> > +					       uint64_t blob_id,
> > +					       ssize_t expected_size,
> > +					       ssize_t expected_elem_size,
> > +					       bool *replaced)
> > +{
> > +	struct drm_property_blob *new_blob = NULL;
> > +
> > +	if (blob_id != 0) {
> > +		new_blob = drm_property_lookup_blob(dev, blob_id);
> > +		if (new_blob == NULL)
> > +			return -EINVAL;
> > +
> > +		if (expected_size > 0 &&
> > +		    new_blob->length != expected_size) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +		if (expected_elem_size > 0 &&
> > +		    new_blob->length % expected_elem_size != 0) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> > +	*replaced |= drm_property_replace_blob(blob, new_blob);
> > +	drm_property_blob_put(new_blob);
> > +
> > +	return 0;
> > +}
> 
> amdgpu_dm_plane doesn't seem the right place for it either. Maybe a new
> amdgpu_dm_helper.c/h?
> 
> Alternatively would this make sense to live in DRM core as a helper?

A DRM helper sounds better for me. I'll follow this path.

Melissa

> 
> Harry
> 
> > +#endif
> > +
> >  static const struct drm_plane_funcs dm_plane_funcs = {
> >  	.update_plane	= drm_atomic_helper_update_plane,
> >  	.disable_plane	= drm_atomic_helper_disable_plane,
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> > index 930f1572f898..1b05ac4c15f6 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> > @@ -51,6 +51,13 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev,
> >  				 bool tmz_surface,
> >  				 bool force_disable_dcc);
> >  
> > +int amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > +					    struct drm_property_blob **blob,
> > +					    uint64_t blob_id,
> > +					    ssize_t expected_size,
> > +					    ssize_t expected_elem_size,
> > +					    bool *replaced);
> > +
> >  int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
> >  			 struct drm_plane *plane,
> >  			 unsigned long possible_crtcs,
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 09/40] drm/amd/display: move replace blob func to dm plane
@ 2023-05-09 16:35       ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:35 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, daniel, Alex Deucher,
	airlied, christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 5825 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > From amdgpu_dm_plane we can get it for both CRTC and plane color
> > properties. We are adding new plane properties for AMD driver-private
> > color mgmt.
> > 
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > ---
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 37 +------------------
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 35 ++++++++++++++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |  7 ++++
> >  3 files changed, 44 insertions(+), 35 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > index 79324fbab1f1..27d7a8b18013 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > @@ -344,39 +344,6 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> >  					   DRM_TRANSFER_FUNCTION_DEFAULT);
> >  }
> >  
> > -static int
> > -atomic_replace_property_blob_from_id(struct drm_device *dev,
> > -					 struct drm_property_blob **blob,
> > -					 uint64_t blob_id,
> > -					 ssize_t expected_size,
> > -					 ssize_t expected_elem_size,
> > -					 bool *replaced)
> > -{
> > -	struct drm_property_blob *new_blob = NULL;
> > -
> > -	if (blob_id != 0) {
> > -		new_blob = drm_property_lookup_blob(dev, blob_id);
> > -		if (new_blob == NULL)
> > -			return -EINVAL;
> > -
> > -		if (expected_size > 0 &&
> > -		    new_blob->length != expected_size) {
> > -			drm_property_blob_put(new_blob);
> > -			return -EINVAL;
> > -		}
> > -		if (expected_elem_size > 0 &&
> > -		    new_blob->length % expected_elem_size != 0) {
> > -			drm_property_blob_put(new_blob);
> > -			return -EINVAL;
> > -		}
> > -	}
> > -
> > -	*replaced |= drm_property_replace_blob(blob, new_blob);
> > -	drm_property_blob_put(new_blob);
> > -
> > -	return 0;
> > -}
> > -
> >  static int
> >  amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  				   struct drm_crtc_state *state,
> > @@ -389,7 +356,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  	int ret;
> >  
> >  	if (property == adev->mode_info.shaper_lut_property) {
> > -		ret = atomic_replace_property_blob_from_id(crtc->dev,
> > +		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
> >  					&acrtc_state->shaper_lut,
> >  					val,
> >  					-1, sizeof(struct drm_color_lut),
> > @@ -397,7 +364,7 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> >  		acrtc_state->base.color_mgmt_changed |= replaced;
> >  		return ret;
> >  	} else if (property == adev->mode_info.lut3d_property) {
> > -		ret = atomic_replace_property_blob_from_id(crtc->dev,
> > +		ret = amdgpu_dm_replace_property_blob_from_id(crtc->dev,
> >  					&acrtc_state->lut3d,
> >  					val,
> >  					-1, sizeof(struct drm_color_lut),
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > index 322668973747..4e5498153be2 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > @@ -1411,6 +1411,41 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> >  	drm_atomic_helper_plane_destroy_state(plane, state);
> >  }
> >  
> > +#ifdef CONFIG_STEAM_DECK
> > +int
> > +amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > +					       struct drm_property_blob **blob,
> > +					       uint64_t blob_id,
> > +					       ssize_t expected_size,
> > +					       ssize_t expected_elem_size,
> > +					       bool *replaced)
> > +{
> > +	struct drm_property_blob *new_blob = NULL;
> > +
> > +	if (blob_id != 0) {
> > +		new_blob = drm_property_lookup_blob(dev, blob_id);
> > +		if (new_blob == NULL)
> > +			return -EINVAL;
> > +
> > +		if (expected_size > 0 &&
> > +		    new_blob->length != expected_size) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +		if (expected_elem_size > 0 &&
> > +		    new_blob->length % expected_elem_size != 0) {
> > +			drm_property_blob_put(new_blob);
> > +			return -EINVAL;
> > +		}
> > +	}
> > +
> > +	*replaced |= drm_property_replace_blob(blob, new_blob);
> > +	drm_property_blob_put(new_blob);
> > +
> > +	return 0;
> > +}
> 
> amdgpu_dm_plane doesn't seem the right place for it either. Maybe a new
> amdgpu_dm_helper.c/h?
> 
> Alternatively would this make sense to live in DRM core as a helper?

A DRM helper sounds better for me. I'll follow this path.

Melissa

> 
> Harry
> 
> > +#endif
> > +
> >  static const struct drm_plane_funcs dm_plane_funcs = {
> >  	.update_plane	= drm_atomic_helper_update_plane,
> >  	.disable_plane	= drm_atomic_helper_disable_plane,
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> > index 930f1572f898..1b05ac4c15f6 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
> > @@ -51,6 +51,13 @@ int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev,
> >  				 bool tmz_surface,
> >  				 bool force_disable_dcc);
> >  
> > +int amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > +					    struct drm_property_blob **blob,
> > +					    uint64_t blob_id,
> > +					    ssize_t expected_size,
> > +					    ssize_t expected_elem_size,
> > +					    bool *replaced);
> > +
> >  int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
> >  			 struct drm_plane *plane,
> >  			 unsigned long possible_crtcs,
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
  2023-05-08 21:24     ` Harry Wentland
  (?)
@ 2023-05-09 16:37       ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:37 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, Alex Deucher,
	christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 6265 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > From: Joshua Ashton <joshua@froggi.es>
> > 
> > Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
> > transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
> > least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
> > nits for SDR content. So if you want, 203 nits for SDR content, pass in
> > (203.0 / 80.0).
> > 
> 
> Is gamescope intending to use this?

I don't think so. Again, I'll double check and drop it accordingly.

Melissa

> 
> Harry
> 
> > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
> >  4 files changed, 41 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index 24595906dab1..dd658f162f6f 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >  		return -ENOMEM;
> >  	adev->mode_info.plane_degamma_tf_property = prop;
> >  
> > +	prop = drm_property_create_range(adev_to_drm(adev),
> > +					 0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.plane_hdr_mult_property = prop;
> > +
> >  	return 0;
> >  }
> >  #endif
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > index ab9ce6f26c90..65a9d62ffbe4 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
> >  	 * linearize content with or without LUT.
> >  	 */
> >  	struct drm_property *plane_degamma_tf_property;
> > +	/**
> > +	 * @plane_hdr_mult_property:
> > +	 */
> > +	struct drm_property *plane_hdr_mult_property;
> >  #endif
> >  };
> >  
> > 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 005632c1c9ec..bb7307b9cfd5 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > @@ -51,6 +51,7 @@
> >  
> >  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
> >  
> > +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
> >  /*
> >  #include "include/amdgpu_dal_power_if.h"
> >  #include "amdgpu_dm_irq.h"
> > @@ -736,6 +737,17 @@ struct dm_plane_state {
> >  	 * linearize.
> >  	 */
> >  	enum drm_transfer_function degamma_tf;
> > +	/**
> > +	 * @hdr_mult:
> > +	 *
> > +	 * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
> > +	 * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
> > +	 * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
> > +	 * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
> > +	 * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
> > +	 * S31.32 sign-magnitude.
> > +	 */
> > +	__u64 hdr_mult;
> >  #endif
> >  };
> >  
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > index 5b458cc0781c..57169dae8b3d 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
> >  		__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
> >  
> >  #ifdef CONFIG_STEAM_DECK
> > -	if (amdgpu_state)
> > +	if (amdgpu_state) {
> >  		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
> > +		amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> > +	}
> >  #endif
> >  }
> >  
> > @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> >  #ifdef CONFIG_STEAM_DECK
> >  int
> >  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > -					       struct drm_property_blob **blob,
> > -					       uint64_t blob_id,
> > -					       ssize_t expected_size,
> > -					       ssize_t expected_elem_size,
> > -					       bool *replaced)
> > +					struct drm_property_blob **blob,
> > +					uint64_t blob_id,
> > +					ssize_t expected_size,
> > +					ssize_t expected_elem_size,
> > +					bool *replaced)
> >  {
> >  	struct drm_property_blob *new_blob = NULL;
> >  
> > @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
> >  					   dm->adev->mode_info.plane_degamma_tf_property,
> >  					   DRM_TRANSFER_FUNCTION_DEFAULT);
> >  	}
> > +	/* HDR MULT is always available */
> > +	drm_object_attach_property(&plane->base,
> > +				   dm->adev->mode_info.plane_hdr_mult_property,
> > +				   AMDGPU_HDR_MULT_DEFAULT);
> >  }
> >  
> >  static int
> > @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
> >  			dm_plane_state->degamma_tf = val;
> >  			dm_plane_state->base.color_mgmt_changed = 1;
> >  		}
> > +	} else if (property == adev->mode_info.plane_hdr_mult_property) {
> > +		if (dm_plane_state->hdr_mult != val) {
> > +			dm_plane_state->hdr_mult = val;
> > +			dm_plane_state->base.color_mgmt_changed = 1;
> > +		}
> >  	} else {
> >  		drm_dbg_atomic(plane->dev,
> >  			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
> > @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
> >  			dm_plane_state->degamma_lut->base.id : 0;
> >  	} else if (property == adev->mode_info.plane_degamma_tf_property) {
> >  		*val = dm_plane_state->degamma_tf;
> > +	} else if (property == adev->mode_info.plane_hdr_mult_property) {
> > +		*val = dm_plane_state->hdr_mult;
> >  	} else {
> >  		return -EINVAL;
> >  	}
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-05-09 16:37       ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:37 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, daniel, Alex Deucher,
	airlied, christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 6265 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > From: Joshua Ashton <joshua@froggi.es>
> > 
> > Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
> > transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
> > least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
> > nits for SDR content. So if you want, 203 nits for SDR content, pass in
> > (203.0 / 80.0).
> > 
> 
> Is gamescope intending to use this?

I don't think so. Again, I'll double check and drop it accordingly.

Melissa

> 
> Harry
> 
> > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
> >  4 files changed, 41 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index 24595906dab1..dd658f162f6f 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >  		return -ENOMEM;
> >  	adev->mode_info.plane_degamma_tf_property = prop;
> >  
> > +	prop = drm_property_create_range(adev_to_drm(adev),
> > +					 0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.plane_hdr_mult_property = prop;
> > +
> >  	return 0;
> >  }
> >  #endif
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > index ab9ce6f26c90..65a9d62ffbe4 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
> >  	 * linearize content with or without LUT.
> >  	 */
> >  	struct drm_property *plane_degamma_tf_property;
> > +	/**
> > +	 * @plane_hdr_mult_property:
> > +	 */
> > +	struct drm_property *plane_hdr_mult_property;
> >  #endif
> >  };
> >  
> > 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 005632c1c9ec..bb7307b9cfd5 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > @@ -51,6 +51,7 @@
> >  
> >  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
> >  
> > +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
> >  /*
> >  #include "include/amdgpu_dal_power_if.h"
> >  #include "amdgpu_dm_irq.h"
> > @@ -736,6 +737,17 @@ struct dm_plane_state {
> >  	 * linearize.
> >  	 */
> >  	enum drm_transfer_function degamma_tf;
> > +	/**
> > +	 * @hdr_mult:
> > +	 *
> > +	 * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
> > +	 * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
> > +	 * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
> > +	 * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
> > +	 * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
> > +	 * S31.32 sign-magnitude.
> > +	 */
> > +	__u64 hdr_mult;
> >  #endif
> >  };
> >  
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > index 5b458cc0781c..57169dae8b3d 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
> >  		__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
> >  
> >  #ifdef CONFIG_STEAM_DECK
> > -	if (amdgpu_state)
> > +	if (amdgpu_state) {
> >  		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
> > +		amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> > +	}
> >  #endif
> >  }
> >  
> > @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> >  #ifdef CONFIG_STEAM_DECK
> >  int
> >  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > -					       struct drm_property_blob **blob,
> > -					       uint64_t blob_id,
> > -					       ssize_t expected_size,
> > -					       ssize_t expected_elem_size,
> > -					       bool *replaced)
> > +					struct drm_property_blob **blob,
> > +					uint64_t blob_id,
> > +					ssize_t expected_size,
> > +					ssize_t expected_elem_size,
> > +					bool *replaced)
> >  {
> >  	struct drm_property_blob *new_blob = NULL;
> >  
> > @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
> >  					   dm->adev->mode_info.plane_degamma_tf_property,
> >  					   DRM_TRANSFER_FUNCTION_DEFAULT);
> >  	}
> > +	/* HDR MULT is always available */
> > +	drm_object_attach_property(&plane->base,
> > +				   dm->adev->mode_info.plane_hdr_mult_property,
> > +				   AMDGPU_HDR_MULT_DEFAULT);
> >  }
> >  
> >  static int
> > @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
> >  			dm_plane_state->degamma_tf = val;
> >  			dm_plane_state->base.color_mgmt_changed = 1;
> >  		}
> > +	} else if (property == adev->mode_info.plane_hdr_mult_property) {
> > +		if (dm_plane_state->hdr_mult != val) {
> > +			dm_plane_state->hdr_mult = val;
> > +			dm_plane_state->base.color_mgmt_changed = 1;
> > +		}
> >  	} else {
> >  		drm_dbg_atomic(plane->dev,
> >  			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
> > @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
> >  			dm_plane_state->degamma_lut->base.id : 0;
> >  	} else if (property == adev->mode_info.plane_degamma_tf_property) {
> >  		*val = dm_plane_state->degamma_tf;
> > +	} else if (property == adev->mode_info.plane_hdr_mult_property) {
> > +		*val = dm_plane_state->hdr_mult;
> >  	} else {
> >  		return -EINVAL;
> >  	}
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-05-09 16:37       ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:37 UTC (permalink / raw)
  To: Harry Wentland
  Cc: amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher, dri-devel,
	christian.koenig, Xinhui.Pan, airlied, daniel, Joshua Ashton,
	Sebastian Wick, Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas,
	sungjoon.kim, Alex Hung, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 6265 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > From: Joshua Ashton <joshua@froggi.es>
> > 
> > Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
> > transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
> > least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
> > nits for SDR content. So if you want, 203 nits for SDR content, pass in
> > (203.0 / 80.0).
> > 
> 
> Is gamescope intending to use this?

I don't think so. Again, I'll double check and drop it accordingly.

Melissa

> 
> Harry
> 
> > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > ---
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
> >  4 files changed, 41 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > index 24595906dab1..dd658f162f6f 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >  		return -ENOMEM;
> >  	adev->mode_info.plane_degamma_tf_property = prop;
> >  
> > +	prop = drm_property_create_range(adev_to_drm(adev),
> > +					 0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
> > +	if (!prop)
> > +		return -ENOMEM;
> > +	adev->mode_info.plane_hdr_mult_property = prop;
> > +
> >  	return 0;
> >  }
> >  #endif
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > index ab9ce6f26c90..65a9d62ffbe4 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
> >  	 * linearize content with or without LUT.
> >  	 */
> >  	struct drm_property *plane_degamma_tf_property;
> > +	/**
> > +	 * @plane_hdr_mult_property:
> > +	 */
> > +	struct drm_property *plane_hdr_mult_property;
> >  #endif
> >  };
> >  
> > 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 005632c1c9ec..bb7307b9cfd5 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > @@ -51,6 +51,7 @@
> >  
> >  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
> >  
> > +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
> >  /*
> >  #include "include/amdgpu_dal_power_if.h"
> >  #include "amdgpu_dm_irq.h"
> > @@ -736,6 +737,17 @@ struct dm_plane_state {
> >  	 * linearize.
> >  	 */
> >  	enum drm_transfer_function degamma_tf;
> > +	/**
> > +	 * @hdr_mult:
> > +	 *
> > +	 * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
> > +	 * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
> > +	 * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
> > +	 * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
> > +	 * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
> > +	 * S31.32 sign-magnitude.
> > +	 */
> > +	__u64 hdr_mult;
> >  #endif
> >  };
> >  
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > index 5b458cc0781c..57169dae8b3d 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
> >  		__drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
> >  
> >  #ifdef CONFIG_STEAM_DECK
> > -	if (amdgpu_state)
> > +	if (amdgpu_state) {
> >  		amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
> > +		amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> > +	}
> >  #endif
> >  }
> >  
> > @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> >  #ifdef CONFIG_STEAM_DECK
> >  int
> >  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > -					       struct drm_property_blob **blob,
> > -					       uint64_t blob_id,
> > -					       ssize_t expected_size,
> > -					       ssize_t expected_elem_size,
> > -					       bool *replaced)
> > +					struct drm_property_blob **blob,
> > +					uint64_t blob_id,
> > +					ssize_t expected_size,
> > +					ssize_t expected_elem_size,
> > +					bool *replaced)
> >  {
> >  	struct drm_property_blob *new_blob = NULL;
> >  
> > @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
> >  					   dm->adev->mode_info.plane_degamma_tf_property,
> >  					   DRM_TRANSFER_FUNCTION_DEFAULT);
> >  	}
> > +	/* HDR MULT is always available */
> > +	drm_object_attach_property(&plane->base,
> > +				   dm->adev->mode_info.plane_hdr_mult_property,
> > +				   AMDGPU_HDR_MULT_DEFAULT);
> >  }
> >  
> >  static int
> > @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
> >  			dm_plane_state->degamma_tf = val;
> >  			dm_plane_state->base.color_mgmt_changed = 1;
> >  		}
> > +	} else if (property == adev->mode_info.plane_hdr_mult_property) {
> > +		if (dm_plane_state->hdr_mult != val) {
> > +			dm_plane_state->hdr_mult = val;
> > +			dm_plane_state->base.color_mgmt_changed = 1;
> > +		}
> >  	} else {
> >  		drm_dbg_atomic(plane->dev,
> >  			       "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
> > @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
> >  			dm_plane_state->degamma_lut->base.id : 0;
> >  	} else if (property == adev->mode_info.plane_degamma_tf_property) {
> >  		*val = dm_plane_state->degamma_tf;
> > +	} else if (property == adev->mode_info.plane_hdr_mult_property) {
> > +		*val = dm_plane_state->hdr_mult;
> >  	} else {
> >  		return -EINVAL;
> >  	}
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt
  2023-05-08 21:24   ` Harry Wentland
  (?)
@ 2023-05-09 16:52     ` Melissa Wen
  -1 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:52 UTC (permalink / raw)
  To: Harry Wentland
  Cc: amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher, dri-devel,
	airlied, christian.koenig, daniel, maarten.lankhorst, mripard,
	tzimmermann, Xinhui.Pan, Joshua Ashton, Sebastian Wick,
	Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas, sungjoon.kim,
	Alex Hung, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 10753 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > Hi all,
> > 
> > Joshua Ashton and I (with the great collaboration of Harry Wentland -
> > thanks) have been working on KMS color pipeline enhancement for Steam
> > Deck/SteamOS by exposing the large set of color caps available in AMD
> > display HW.
> > 
> 
> Thank you for your work on this.
> 
> > This patchset results from this full-stack work, including pre-blending
> > and post-blending new color properties. The first two patches fix
> > quantization issues on shaper LUT programming. Just after, we have one
> > patch that adds a config option to restrict AMD colo feature usage. The
> > following 13 patches implement AMD driver-private color properties
> > (pending detachment of property counter and plane color_mgmt_changed
> > from DRM). Finally, the last 24 patches rework the AMD display manager
> > and color management to support the properties exposed.
> > 
> > In short, for pre-blending, we added the following:
> > - plane degamma LUT and predefined transfer function;
> > - plane HDR multiplier
> > - plane shaper LUT/transfer function;
> > - plane 3D LUT; and finally,
> > - plane blend LUT/transfer function, just before blending.
> > 
> > After blending, we already have DRM CRTC degamma/gamma LUTs and CTM,
> > therefore, we extend CRTC color pipeline with the following:
> > - CRTC shaper LUT/transfer function;
> > - CRTC 3D LUT; and
> > - CRTC gamma transfer function.
> > 
> > You can already find the AMD color capabilities and color management
> > pipeline documented here:
> > https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties
> > 
> > In previous iterations, we tried to provide a generic solution for
> > post-blending shaper and 3D LUT [1][2][3], and also Alex Hung worked on
> > a pre-blending 3D LUT solution[4] extending plane color mgmt proposal
> > from Uma Shankar [5]. However, we identified during our work [6] that
> > AMD provides many other valuable capabilities that we don't find in
> > other vendors, so we started to work on AMD driver-private color
> > properties that better describe its color pipeline, enabling us to
> > expose full AMD color capabilities on Deck HW.
> > 
> > Our primary purpose is to avoid usage limitations of color calibration
> > features provided by HW just because we don't have an interface for
> > that. At the same time, a generic solution doesn't fit well since some
> > of these capabilities seem AMD HW specific, such as hardcoded
> > curve/predefined transfer function and shaper 1D LUTs sandwiching 3D
> > LUT.
> > 
> > So far, we keep these properties' usage under an AMD display config
> > option (STEAM_DECK). However, we are fine with having them fully
> > available to other DCN HW generations. In the current proposal, we are
> > already checking ASICs before exposing a color feature. We can work on
> > 3D LUT resource acquisition details to fit them to DCN 3+ families that
> > support them. Indeed, before moving to these config boundaries, we
> > started working on an open solution for any AMD HW [7].
> > 
> 
> The problem with a CONFIG_XYZ option is that it becomes uAPI and can't be
> removed. I feel we have a good proposal going for the generic solution.
> Would it work for you if we don't make this a CONFIG_ option? What I mean
> is using
> 
> #define AMD_PRIVATE_COLOR
> 
> around the interface bits, which are only compiled when building with
> -DAMD_PRIVATE_COLOR

I think we can go with this approach for the properties already in use
by Gamescope/SteamOS.
> 
> That way we have the option to rip the driver-private stuff out later
> while still allowing for experimentation now.
> 
> Or, alternatively, we can merge everything but the stuff currently
> guarded by CONFIG_STEAM_DECK, so that custom kernels can enable this
> functionality by simply merging one patch that includes all the
> CONFIG_STEAM_DECK stuff.

An then we can drop the interface of things that Gamescope is not
managing, but keep those things already programmed on DM color for any
future usage. What do you think?

Melissa

> 
> This will allow us to merge the vast majority of the code without
> having to maintain it in downstream repo.
> 
> > The userspace case here is Gamescope which is the compositor for
> > SteamOS. It's already using all of this functionality (although with a
> > VALVE1_ prefix instead of AMD) to implement its color management
> > pipeline right now:
> > https://github.com/ValveSoftware/gamescope
> > 
> > We are planning on shipping our color management support with gamut
> > mapping, HDR, SDR on HDR, HDR on SDR, and much more in Steam OS 3.5. A
> > brief overview of our color pipeline can be found here:
> > https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png
> > 
> > We have also had some other userspace interests from Xaver Hugl (KDE) in
> > experimenting with these properties for their HDR/color bring-up before
> > a generic interface is settled on also.
> > 
> > It still needs AMD-specific IGT tests; we are working on documentation
> > and adding plane CTM support too. 
> > 
> > We decided first to share our work to collect thoughts and open for
> > discussion, even with missing refinements, since driver-private
> > properties are not the usual DMR/KMS color management approach.
> > 
> > Please, let us know your thoughts.
> > 
> 
> As discussed at the hackfest I think it's a good idea to have something
> that's easy to enable for the purposes of experimentation (and to
> help downstream users that help us figure out how this all fits
> together, i.e. SteamOS).
> 
> Harry
> 
> > Best Regards,
> > 
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > Signed-off-by: Melissa Wen<mwen@igalia.com>
> > 
> > [1] https://lore.kernel.org/dri-devel/20220619223104.667413-1-mwen@igalia.com/
> > [2] https://lore.kernel.org/amd-gfx/20220906164628.2361811-1-mwen@igalia.com/
> > [3] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-mwen@igalia.com/
> > [4] https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.hung@amd.com/
> > [5] https://lore.kernel.org/dri-devel/20210906213904.27918-1-uma.shankar@intel.com/
> > [6] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-color-mgmt
> > [7] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-private-color-mgmt
> > 
> > Harry Wentland (2):
> >   drm/amd/display: fix segment distribution for linear LUTs
> >   drm/amd/display: fix the delta clamping for shaper LUT
> > 
> > Joshua Ashton (15):
> >   drm/amd/display: add CRTC gamma TF to driver-private props
> >   drm/amd/display: add plane degamma LUT driver-private props
> >   drm/amd/display: add plane degamma TF driver-private property
> >   drm/amd/display: add plane HDR multiplier driver-private property
> >   drm/amd/display: add plane blend LUT and TF driver-private properties
> >   drm/amd/display: copy 3D LUT settings from crtc state to stream_update
> >   drm/amd/display: dynamically acquire 3DLUT resources for color changes
> >   drm/amd/display: add CRTC regamma TF support
> >   drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
> >   drm/amd/display: add support for plane degamma TF and LUT properties
> >   drm/amd/display: add dc_fixpt_from_s3132 helper
> >   drm/adm/display: add HDR multiplier support
> >   drm/amd/display: handle empty LUTs in __set_input_tf
> >   drm/amd/display: add DRM plane blend LUT and TF support
> >   drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG
> > 
> > Melissa Wen (23):
> >   drm/amd/display: introduce Steam Deck color features to AMD display
> >     driver
> >   drm/drm_mode_object: increase max objects to accommodate new color
> >     props
> >   drm/amd/display: add shaper LUT driver-private props
> >   drm/amd/display: add 3D LUT driver-private props
> >   drm/drm_plane: track color mgmt changes per plane
> >   drm/amd/display: move replace blob func to dm plane
> >   drm/amd/display: add plane 3D LUT driver-private properties
> >   drm/amd/display: add plane shaper LUT driver-private properties
> >   drm/amd/display: add plane shaper TF driver-private property
> >   drm/amd/display: add comments to describe DM crtc color mgmt behavior
> >   drm/amd/display: encapsulate atomic regamma operation
> >   drm/amd/display: update lut3d and shaper lut to stream
> >   drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
> >   drm/amd/display: handle MPC 3D LUT resources for a given context
> >   drm/amd/display: add CRTC 3D LUT support to amd color pipeline
> >   drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
> >   drm/amd/display: add CRTC shaper LUT support to amd color pipeline
> >   drm/amd/display: add CRTC shaper TF support
> >   drm/amd/display: mark plane as needing reset if plane color mgmt
> >     changes
> >   drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
> >   drm/amd/display: reject atomic commit if setting both plane and CRTC
> >     degamma
> >   drm/amd/display: add plane shaper/3D LUT and shaper TF support
> >   drm/amd/display: copy dc_plane color settings to surface_updates
> > 
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 153 +++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  92 +++
> >  drivers/gpu/drm/amd/display/Kconfig           |   6 +
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  31 +-
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 120 +++-
> >  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 613 ++++++++++++++++--
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 124 +++-
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 238 +++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |   7 +
> >  drivers/gpu/drm/amd/display/dc/core/dc.c      |  49 +-
> >  drivers/gpu/drm/amd/display/dc/dc.h           |   8 +
> >  .../amd/display/dc/dcn10/dcn10_cm_common.c    | 109 +++-
> >  .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   5 +-
> >  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   9 +-
> >  .../amd/display/dc/dcn301/dcn301_resource.c   |  26 +-
> >  .../gpu/drm/amd/display/include/fixed31_32.h  |  12 +
> >  drivers/gpu/drm/drm_atomic.c                  |   1 +
> >  drivers/gpu/drm/drm_atomic_state_helper.c     |   1 +
> >  include/drm/drm_mode_object.h                 |   2 +-
> >  include/drm/drm_plane.h                       |   7 +
> >  20 files changed, 1509 insertions(+), 104 deletions(-)
> > 
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt
@ 2023-05-09 16:52     ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:52 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, linux-kernel, tzimmermann, Shashank Sharma,
	sunpeng.li, Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, Alex Deucher,
	christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 10753 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > Hi all,
> > 
> > Joshua Ashton and I (with the great collaboration of Harry Wentland -
> > thanks) have been working on KMS color pipeline enhancement for Steam
> > Deck/SteamOS by exposing the large set of color caps available in AMD
> > display HW.
> > 
> 
> Thank you for your work on this.
> 
> > This patchset results from this full-stack work, including pre-blending
> > and post-blending new color properties. The first two patches fix
> > quantization issues on shaper LUT programming. Just after, we have one
> > patch that adds a config option to restrict AMD colo feature usage. The
> > following 13 patches implement AMD driver-private color properties
> > (pending detachment of property counter and plane color_mgmt_changed
> > from DRM). Finally, the last 24 patches rework the AMD display manager
> > and color management to support the properties exposed.
> > 
> > In short, for pre-blending, we added the following:
> > - plane degamma LUT and predefined transfer function;
> > - plane HDR multiplier
> > - plane shaper LUT/transfer function;
> > - plane 3D LUT; and finally,
> > - plane blend LUT/transfer function, just before blending.
> > 
> > After blending, we already have DRM CRTC degamma/gamma LUTs and CTM,
> > therefore, we extend CRTC color pipeline with the following:
> > - CRTC shaper LUT/transfer function;
> > - CRTC 3D LUT; and
> > - CRTC gamma transfer function.
> > 
> > You can already find the AMD color capabilities and color management
> > pipeline documented here:
> > https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties
> > 
> > In previous iterations, we tried to provide a generic solution for
> > post-blending shaper and 3D LUT [1][2][3], and also Alex Hung worked on
> > a pre-blending 3D LUT solution[4] extending plane color mgmt proposal
> > from Uma Shankar [5]. However, we identified during our work [6] that
> > AMD provides many other valuable capabilities that we don't find in
> > other vendors, so we started to work on AMD driver-private color
> > properties that better describe its color pipeline, enabling us to
> > expose full AMD color capabilities on Deck HW.
> > 
> > Our primary purpose is to avoid usage limitations of color calibration
> > features provided by HW just because we don't have an interface for
> > that. At the same time, a generic solution doesn't fit well since some
> > of these capabilities seem AMD HW specific, such as hardcoded
> > curve/predefined transfer function and shaper 1D LUTs sandwiching 3D
> > LUT.
> > 
> > So far, we keep these properties' usage under an AMD display config
> > option (STEAM_DECK). However, we are fine with having them fully
> > available to other DCN HW generations. In the current proposal, we are
> > already checking ASICs before exposing a color feature. We can work on
> > 3D LUT resource acquisition details to fit them to DCN 3+ families that
> > support them. Indeed, before moving to these config boundaries, we
> > started working on an open solution for any AMD HW [7].
> > 
> 
> The problem with a CONFIG_XYZ option is that it becomes uAPI and can't be
> removed. I feel we have a good proposal going for the generic solution.
> Would it work for you if we don't make this a CONFIG_ option? What I mean
> is using
> 
> #define AMD_PRIVATE_COLOR
> 
> around the interface bits, which are only compiled when building with
> -DAMD_PRIVATE_COLOR

I think we can go with this approach for the properties already in use
by Gamescope/SteamOS.
> 
> That way we have the option to rip the driver-private stuff out later
> while still allowing for experimentation now.
> 
> Or, alternatively, we can merge everything but the stuff currently
> guarded by CONFIG_STEAM_DECK, so that custom kernels can enable this
> functionality by simply merging one patch that includes all the
> CONFIG_STEAM_DECK stuff.

An then we can drop the interface of things that Gamescope is not
managing, but keep those things already programmed on DM color for any
future usage. What do you think?

Melissa

> 
> This will allow us to merge the vast majority of the code without
> having to maintain it in downstream repo.
> 
> > The userspace case here is Gamescope which is the compositor for
> > SteamOS. It's already using all of this functionality (although with a
> > VALVE1_ prefix instead of AMD) to implement its color management
> > pipeline right now:
> > https://github.com/ValveSoftware/gamescope
> > 
> > We are planning on shipping our color management support with gamut
> > mapping, HDR, SDR on HDR, HDR on SDR, and much more in Steam OS 3.5. A
> > brief overview of our color pipeline can be found here:
> > https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png
> > 
> > We have also had some other userspace interests from Xaver Hugl (KDE) in
> > experimenting with these properties for their HDR/color bring-up before
> > a generic interface is settled on also.
> > 
> > It still needs AMD-specific IGT tests; we are working on documentation
> > and adding plane CTM support too. 
> > 
> > We decided first to share our work to collect thoughts and open for
> > discussion, even with missing refinements, since driver-private
> > properties are not the usual DMR/KMS color management approach.
> > 
> > Please, let us know your thoughts.
> > 
> 
> As discussed at the hackfest I think it's a good idea to have something
> that's easy to enable for the purposes of experimentation (and to
> help downstream users that help us figure out how this all fits
> together, i.e. SteamOS).
> 
> Harry
> 
> > Best Regards,
> > 
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > Signed-off-by: Melissa Wen<mwen@igalia.com>
> > 
> > [1] https://lore.kernel.org/dri-devel/20220619223104.667413-1-mwen@igalia.com/
> > [2] https://lore.kernel.org/amd-gfx/20220906164628.2361811-1-mwen@igalia.com/
> > [3] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-mwen@igalia.com/
> > [4] https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.hung@amd.com/
> > [5] https://lore.kernel.org/dri-devel/20210906213904.27918-1-uma.shankar@intel.com/
> > [6] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-color-mgmt
> > [7] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-private-color-mgmt
> > 
> > Harry Wentland (2):
> >   drm/amd/display: fix segment distribution for linear LUTs
> >   drm/amd/display: fix the delta clamping for shaper LUT
> > 
> > Joshua Ashton (15):
> >   drm/amd/display: add CRTC gamma TF to driver-private props
> >   drm/amd/display: add plane degamma LUT driver-private props
> >   drm/amd/display: add plane degamma TF driver-private property
> >   drm/amd/display: add plane HDR multiplier driver-private property
> >   drm/amd/display: add plane blend LUT and TF driver-private properties
> >   drm/amd/display: copy 3D LUT settings from crtc state to stream_update
> >   drm/amd/display: dynamically acquire 3DLUT resources for color changes
> >   drm/amd/display: add CRTC regamma TF support
> >   drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
> >   drm/amd/display: add support for plane degamma TF and LUT properties
> >   drm/amd/display: add dc_fixpt_from_s3132 helper
> >   drm/adm/display: add HDR multiplier support
> >   drm/amd/display: handle empty LUTs in __set_input_tf
> >   drm/amd/display: add DRM plane blend LUT and TF support
> >   drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG
> > 
> > Melissa Wen (23):
> >   drm/amd/display: introduce Steam Deck color features to AMD display
> >     driver
> >   drm/drm_mode_object: increase max objects to accommodate new color
> >     props
> >   drm/amd/display: add shaper LUT driver-private props
> >   drm/amd/display: add 3D LUT driver-private props
> >   drm/drm_plane: track color mgmt changes per plane
> >   drm/amd/display: move replace blob func to dm plane
> >   drm/amd/display: add plane 3D LUT driver-private properties
> >   drm/amd/display: add plane shaper LUT driver-private properties
> >   drm/amd/display: add plane shaper TF driver-private property
> >   drm/amd/display: add comments to describe DM crtc color mgmt behavior
> >   drm/amd/display: encapsulate atomic regamma operation
> >   drm/amd/display: update lut3d and shaper lut to stream
> >   drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
> >   drm/amd/display: handle MPC 3D LUT resources for a given context
> >   drm/amd/display: add CRTC 3D LUT support to amd color pipeline
> >   drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
> >   drm/amd/display: add CRTC shaper LUT support to amd color pipeline
> >   drm/amd/display: add CRTC shaper TF support
> >   drm/amd/display: mark plane as needing reset if plane color mgmt
> >     changes
> >   drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
> >   drm/amd/display: reject atomic commit if setting both plane and CRTC
> >     degamma
> >   drm/amd/display: add plane shaper/3D LUT and shaper TF support
> >   drm/amd/display: copy dc_plane color settings to surface_updates
> > 
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 153 +++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  92 +++
> >  drivers/gpu/drm/amd/display/Kconfig           |   6 +
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  31 +-
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 120 +++-
> >  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 613 ++++++++++++++++--
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 124 +++-
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 238 +++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |   7 +
> >  drivers/gpu/drm/amd/display/dc/core/dc.c      |  49 +-
> >  drivers/gpu/drm/amd/display/dc/dc.h           |   8 +
> >  .../amd/display/dc/dcn10/dcn10_cm_common.c    | 109 +++-
> >  .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   5 +-
> >  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   9 +-
> >  .../amd/display/dc/dcn301/dcn301_resource.c   |  26 +-
> >  .../gpu/drm/amd/display/include/fixed31_32.h  |  12 +
> >  drivers/gpu/drm/drm_atomic.c                  |   1 +
> >  drivers/gpu/drm/drm_atomic_state_helper.c     |   1 +
> >  include/drm/drm_mode_object.h                 |   2 +-
> >  include/drm/drm_plane.h                       |   7 +
> >  20 files changed, 1509 insertions(+), 104 deletions(-)
> > 
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt
@ 2023-05-09 16:52     ` Melissa Wen
  0 siblings, 0 replies; 141+ messages in thread
From: Melissa Wen @ 2023-05-09 16:52 UTC (permalink / raw)
  To: Harry Wentland
  Cc: mripard, Sebastian Wick, linux-kernel, tzimmermann,
	Shashank Sharma, sunpeng.li, maarten.lankhorst, Xinhui.Pan,
	Rodrigo Siqueira, Xaver Hugl, dri-devel, Nicholas Kazlauskas,
	Alex Hung, amd-gfx, daniel, Alex Deucher, airlied,
	christian.koenig, Joshua Ashton, sungjoon.kim

[-- Attachment #1: Type: text/plain, Size: 10753 bytes --]

On 05/08, Harry Wentland wrote:
> 
> 
> On 4/23/23 10:10, Melissa Wen wrote:
> > Hi all,
> > 
> > Joshua Ashton and I (with the great collaboration of Harry Wentland -
> > thanks) have been working on KMS color pipeline enhancement for Steam
> > Deck/SteamOS by exposing the large set of color caps available in AMD
> > display HW.
> > 
> 
> Thank you for your work on this.
> 
> > This patchset results from this full-stack work, including pre-blending
> > and post-blending new color properties. The first two patches fix
> > quantization issues on shaper LUT programming. Just after, we have one
> > patch that adds a config option to restrict AMD colo feature usage. The
> > following 13 patches implement AMD driver-private color properties
> > (pending detachment of property counter and plane color_mgmt_changed
> > from DRM). Finally, the last 24 patches rework the AMD display manager
> > and color management to support the properties exposed.
> > 
> > In short, for pre-blending, we added the following:
> > - plane degamma LUT and predefined transfer function;
> > - plane HDR multiplier
> > - plane shaper LUT/transfer function;
> > - plane 3D LUT; and finally,
> > - plane blend LUT/transfer function, just before blending.
> > 
> > After blending, we already have DRM CRTC degamma/gamma LUTs and CTM,
> > therefore, we extend CRTC color pipeline with the following:
> > - CRTC shaper LUT/transfer function;
> > - CRTC 3D LUT; and
> > - CRTC gamma transfer function.
> > 
> > You can already find the AMD color capabilities and color management
> > pipeline documented here:
> > https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties
> > 
> > In previous iterations, we tried to provide a generic solution for
> > post-blending shaper and 3D LUT [1][2][3], and also Alex Hung worked on
> > a pre-blending 3D LUT solution[4] extending plane color mgmt proposal
> > from Uma Shankar [5]. However, we identified during our work [6] that
> > AMD provides many other valuable capabilities that we don't find in
> > other vendors, so we started to work on AMD driver-private color
> > properties that better describe its color pipeline, enabling us to
> > expose full AMD color capabilities on Deck HW.
> > 
> > Our primary purpose is to avoid usage limitations of color calibration
> > features provided by HW just because we don't have an interface for
> > that. At the same time, a generic solution doesn't fit well since some
> > of these capabilities seem AMD HW specific, such as hardcoded
> > curve/predefined transfer function and shaper 1D LUTs sandwiching 3D
> > LUT.
> > 
> > So far, we keep these properties' usage under an AMD display config
> > option (STEAM_DECK). However, we are fine with having them fully
> > available to other DCN HW generations. In the current proposal, we are
> > already checking ASICs before exposing a color feature. We can work on
> > 3D LUT resource acquisition details to fit them to DCN 3+ families that
> > support them. Indeed, before moving to these config boundaries, we
> > started working on an open solution for any AMD HW [7].
> > 
> 
> The problem with a CONFIG_XYZ option is that it becomes uAPI and can't be
> removed. I feel we have a good proposal going for the generic solution.
> Would it work for you if we don't make this a CONFIG_ option? What I mean
> is using
> 
> #define AMD_PRIVATE_COLOR
> 
> around the interface bits, which are only compiled when building with
> -DAMD_PRIVATE_COLOR

I think we can go with this approach for the properties already in use
by Gamescope/SteamOS.
> 
> That way we have the option to rip the driver-private stuff out later
> while still allowing for experimentation now.
> 
> Or, alternatively, we can merge everything but the stuff currently
> guarded by CONFIG_STEAM_DECK, so that custom kernels can enable this
> functionality by simply merging one patch that includes all the
> CONFIG_STEAM_DECK stuff.

An then we can drop the interface of things that Gamescope is not
managing, but keep those things already programmed on DM color for any
future usage. What do you think?

Melissa

> 
> This will allow us to merge the vast majority of the code without
> having to maintain it in downstream repo.
> 
> > The userspace case here is Gamescope which is the compositor for
> > SteamOS. It's already using all of this functionality (although with a
> > VALVE1_ prefix instead of AMD) to implement its color management
> > pipeline right now:
> > https://github.com/ValveSoftware/gamescope
> > 
> > We are planning on shipping our color management support with gamut
> > mapping, HDR, SDR on HDR, HDR on SDR, and much more in Steam OS 3.5. A
> > brief overview of our color pipeline can be found here:
> > https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png
> > 
> > We have also had some other userspace interests from Xaver Hugl (KDE) in
> > experimenting with these properties for their HDR/color bring-up before
> > a generic interface is settled on also.
> > 
> > It still needs AMD-specific IGT tests; we are working on documentation
> > and adding plane CTM support too. 
> > 
> > We decided first to share our work to collect thoughts and open for
> > discussion, even with missing refinements, since driver-private
> > properties are not the usual DMR/KMS color management approach.
> > 
> > Please, let us know your thoughts.
> > 
> 
> As discussed at the hackfest I think it's a good idea to have something
> that's easy to enable for the purposes of experimentation (and to
> help downstream users that help us figure out how this all fits
> together, i.e. SteamOS).
> 
> Harry
> 
> > Best Regards,
> > 
> > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > Signed-off-by: Melissa Wen<mwen@igalia.com>
> > 
> > [1] https://lore.kernel.org/dri-devel/20220619223104.667413-1-mwen@igalia.com/
> > [2] https://lore.kernel.org/amd-gfx/20220906164628.2361811-1-mwen@igalia.com/
> > [3] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-mwen@igalia.com/
> > [4] https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.hung@amd.com/
> > [5] https://lore.kernel.org/dri-devel/20210906213904.27918-1-uma.shankar@intel.com/
> > [6] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-color-mgmt
> > [7] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-private-color-mgmt
> > 
> > Harry Wentland (2):
> >   drm/amd/display: fix segment distribution for linear LUTs
> >   drm/amd/display: fix the delta clamping for shaper LUT
> > 
> > Joshua Ashton (15):
> >   drm/amd/display: add CRTC gamma TF to driver-private props
> >   drm/amd/display: add plane degamma LUT driver-private props
> >   drm/amd/display: add plane degamma TF driver-private property
> >   drm/amd/display: add plane HDR multiplier driver-private property
> >   drm/amd/display: add plane blend LUT and TF driver-private properties
> >   drm/amd/display: copy 3D LUT settings from crtc state to stream_update
> >   drm/amd/display: dynamically acquire 3DLUT resources for color changes
> >   drm/amd/display: add CRTC regamma TF support
> >   drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
> >   drm/amd/display: add support for plane degamma TF and LUT properties
> >   drm/amd/display: add dc_fixpt_from_s3132 helper
> >   drm/adm/display: add HDR multiplier support
> >   drm/amd/display: handle empty LUTs in __set_input_tf
> >   drm/amd/display: add DRM plane blend LUT and TF support
> >   drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG
> > 
> > Melissa Wen (23):
> >   drm/amd/display: introduce Steam Deck color features to AMD display
> >     driver
> >   drm/drm_mode_object: increase max objects to accommodate new color
> >     props
> >   drm/amd/display: add shaper LUT driver-private props
> >   drm/amd/display: add 3D LUT driver-private props
> >   drm/drm_plane: track color mgmt changes per plane
> >   drm/amd/display: move replace blob func to dm plane
> >   drm/amd/display: add plane 3D LUT driver-private properties
> >   drm/amd/display: add plane shaper LUT driver-private properties
> >   drm/amd/display: add plane shaper TF driver-private property
> >   drm/amd/display: add comments to describe DM crtc color mgmt behavior
> >   drm/amd/display: encapsulate atomic regamma operation
> >   drm/amd/display: update lut3d and shaper lut to stream
> >   drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
> >   drm/amd/display: handle MPC 3D LUT resources for a given context
> >   drm/amd/display: add CRTC 3D LUT support to amd color pipeline
> >   drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
> >   drm/amd/display: add CRTC shaper LUT support to amd color pipeline
> >   drm/amd/display: add CRTC shaper TF support
> >   drm/amd/display: mark plane as needing reset if plane color mgmt
> >     changes
> >   drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
> >   drm/amd/display: reject atomic commit if setting both plane and CRTC
> >     degamma
> >   drm/amd/display: add plane shaper/3D LUT and shaper TF support
> >   drm/amd/display: copy dc_plane color settings to surface_updates
> > 
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 153 +++++
> >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  92 +++
> >  drivers/gpu/drm/amd/display/Kconfig           |   6 +
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  31 +-
> >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 120 +++-
> >  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 613 ++++++++++++++++--
> >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 124 +++-
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 238 +++++++
> >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |   7 +
> >  drivers/gpu/drm/amd/display/dc/core/dc.c      |  49 +-
> >  drivers/gpu/drm/amd/display/dc/dc.h           |   8 +
> >  .../amd/display/dc/dcn10/dcn10_cm_common.c    | 109 +++-
> >  .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   5 +-
> >  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   9 +-
> >  .../amd/display/dc/dcn301/dcn301_resource.c   |  26 +-
> >  .../gpu/drm/amd/display/include/fixed31_32.h  |  12 +
> >  drivers/gpu/drm/drm_atomic.c                  |   1 +
> >  drivers/gpu/drm/drm_atomic_state_helper.c     |   1 +
> >  include/drm/drm_mode_object.h                 |   2 +-
> >  include/drm/drm_plane.h                       |   7 +
> >  20 files changed, 1509 insertions(+), 104 deletions(-)
> > 
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
  2023-05-09 16:23       ` Melissa Wen
  (?)
@ 2023-05-09 16:52         ` Joshua Ashton
  -1 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 16:52 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, Xinhui.Pan,
	Rodrigo Siqueira, Xaver Hugl, dri-devel, Nicholas Kazlauskas,
	Alex Hung, amd-gfx, Alex Deucher, christian.koenig, linux-kernel,
	sungjoon.kim

I think the idea is that we wouldn't have a config option so it
doesn't inherently become linux kernel uAPI?

Then we can just build our SteamOS kernels with that definiton set.

On Tue, 9 May 2023 at 16:26, Melissa Wen <mwen@igalia.com> wrote:
>
> On 05/08, Harry Wentland wrote:
> > On 4/23/23 10:10, Melissa Wen wrote:
> > > We are enabling a large set of color calibration features to enhance KMS
> > > color mgmt but these properties are specific of AMD display HW, and
> > > cannot be provided by other vendors. Therefore, set a config option to
> > > enable AMD driver-private properties used on Steam Deck color mgmt
> > > pipeline.
> > >
> > > Co-developed-by: Joshua Ashton <joshua@froggi.es>
> > > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > > ---
> > >  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
> > >  1 file changed, 6 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
> > > index 06b438217c61..c45a8deb1098 100644
> > > --- a/drivers/gpu/drm/amd/display/Kconfig
> > > +++ b/drivers/gpu/drm/amd/display/Kconfig
> > > @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
> > >              of crc of specific region via debugfs.
> > >              Cooperate with specific DMCU FW.
> > >
> > > +config STEAM_DECK
> > > +   bool "Enable color calibration features for Steam Deck"
> > > +   depends on DRM_AMD_DC
> > > +   help
> > > +     Choose this option if you want to use AMDGPU features for broader
> > > +     color management support on Steam Deck.
> > >
> >
> > If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
> > the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
> > us from requiring to support this forever.
>
> I see, I'll follow this path. Still on that, I've changed
> CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.
> Does it sound better?
>
> Thanks,
>
> Melissa
>
> >
> > Harry
> >
> > >  endmenu
> >
> >

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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
@ 2023-05-09 16:52         ` Joshua Ashton
  0 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 16:52 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, airlied, Xinhui.Pan,
	Rodrigo Siqueira, Xaver Hugl, dri-devel, Nicholas Kazlauskas,
	Alex Hung, amd-gfx, daniel, Alex Deucher, Harry Wentland,
	christian.koenig, linux-kernel, sungjoon.kim

I think the idea is that we wouldn't have a config option so it
doesn't inherently become linux kernel uAPI?

Then we can just build our SteamOS kernels with that definiton set.

On Tue, 9 May 2023 at 16:26, Melissa Wen <mwen@igalia.com> wrote:
>
> On 05/08, Harry Wentland wrote:
> > On 4/23/23 10:10, Melissa Wen wrote:
> > > We are enabling a large set of color calibration features to enhance KMS
> > > color mgmt but these properties are specific of AMD display HW, and
> > > cannot be provided by other vendors. Therefore, set a config option to
> > > enable AMD driver-private properties used on Steam Deck color mgmt
> > > pipeline.
> > >
> > > Co-developed-by: Joshua Ashton <joshua@froggi.es>
> > > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > > ---
> > >  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
> > >  1 file changed, 6 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
> > > index 06b438217c61..c45a8deb1098 100644
> > > --- a/drivers/gpu/drm/amd/display/Kconfig
> > > +++ b/drivers/gpu/drm/amd/display/Kconfig
> > > @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
> > >              of crc of specific region via debugfs.
> > >              Cooperate with specific DMCU FW.
> > >
> > > +config STEAM_DECK
> > > +   bool "Enable color calibration features for Steam Deck"
> > > +   depends on DRM_AMD_DC
> > > +   help
> > > +     Choose this option if you want to use AMDGPU features for broader
> > > +     color management support on Steam Deck.
> > >
> >
> > If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
> > the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
> > us from requiring to support this forever.
>
> I see, I'll follow this path. Still on that, I've changed
> CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.
> Does it sound better?
>
> Thanks,
>
> Melissa
>
> >
> > Harry
> >
> > >  endmenu
> >
> >

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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
@ 2023-05-09 16:52         ` Joshua Ashton
  0 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 16:52 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Harry Wentland, amd-gfx, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

I think the idea is that we wouldn't have a config option so it
doesn't inherently become linux kernel uAPI?

Then we can just build our SteamOS kernels with that definiton set.

On Tue, 9 May 2023 at 16:26, Melissa Wen <mwen@igalia.com> wrote:
>
> On 05/08, Harry Wentland wrote:
> > On 4/23/23 10:10, Melissa Wen wrote:
> > > We are enabling a large set of color calibration features to enhance KMS
> > > color mgmt but these properties are specific of AMD display HW, and
> > > cannot be provided by other vendors. Therefore, set a config option to
> > > enable AMD driver-private properties used on Steam Deck color mgmt
> > > pipeline.
> > >
> > > Co-developed-by: Joshua Ashton <joshua@froggi.es>
> > > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > > ---
> > >  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
> > >  1 file changed, 6 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
> > > index 06b438217c61..c45a8deb1098 100644
> > > --- a/drivers/gpu/drm/amd/display/Kconfig
> > > +++ b/drivers/gpu/drm/amd/display/Kconfig
> > > @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
> > >              of crc of specific region via debugfs.
> > >              Cooperate with specific DMCU FW.
> > >
> > > +config STEAM_DECK
> > > +   bool "Enable color calibration features for Steam Deck"
> > > +   depends on DRM_AMD_DC
> > > +   help
> > > +     Choose this option if you want to use AMDGPU features for broader
> > > +     color management support on Steam Deck.
> > >
> >
> > If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
> > the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
> > us from requiring to support this forever.
>
> I see, I'll follow this path. Still on that, I've changed
> CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.
> Does it sound better?
>
> Thanks,
>
> Melissa
>
> >
> > Harry
> >
> > >  endmenu
> >
> >

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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
  2023-05-09 16:37       ` Melissa Wen
  (?)
@ 2023-05-09 16:54         ` Joshua Ashton
  -1 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 16:54 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Harry Wentland, amd-gfx, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

We currently do not have a use for this as we settled on per-plane 3D
LUT + Shaper, but we might end up wanting to use in our scRGB stack
someday so I would like to keep it.

On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
>
> On 05/08, Harry Wentland wrote:
> >
> >
> > On 4/23/23 10:10, Melissa Wen wrote:
> > > From: Joshua Ashton <joshua@froggi.es>
> > >
> > > Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
> > > transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
> > > least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
> > > nits for SDR content. So if you want, 203 nits for SDR content, pass in
> > > (203.0 / 80.0).
> > >
> >
> > Is gamescope intending to use this?
>
> I don't think so. Again, I'll double check and drop it accordingly.
>
> Melissa
>
> >
> > Harry
> >
> > > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > > ---
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
> > >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
> > >  4 files changed, 41 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > index 24595906dab1..dd658f162f6f 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > >             return -ENOMEM;
> > >     adev->mode_info.plane_degamma_tf_property = prop;
> > >
> > > +   prop = drm_property_create_range(adev_to_drm(adev),
> > > +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
> > > +   if (!prop)
> > > +           return -ENOMEM;
> > > +   adev->mode_info.plane_hdr_mult_property = prop;
> > > +
> > >     return 0;
> > >  }
> > >  #endif
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > index ab9ce6f26c90..65a9d62ffbe4 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
> > >      * linearize content with or without LUT.
> > >      */
> > >     struct drm_property *plane_degamma_tf_property;
> > > +   /**
> > > +    * @plane_hdr_mult_property:
> > > +    */
> > > +   struct drm_property *plane_hdr_mult_property;
> > >  #endif
> > >  };
> > >
> > > 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 005632c1c9ec..bb7307b9cfd5 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > @@ -51,6 +51,7 @@
> > >
> > >  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
> > >
> > > +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
> > >  /*
> > >  #include "include/amdgpu_dal_power_if.h"
> > >  #include "amdgpu_dm_irq.h"
> > > @@ -736,6 +737,17 @@ struct dm_plane_state {
> > >      * linearize.
> > >      */
> > >     enum drm_transfer_function degamma_tf;
> > > +   /**
> > > +    * @hdr_mult:
> > > +    *
> > > +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
> > > +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
> > > +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
> > > +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
> > > +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
> > > +    * S31.32 sign-magnitude.
> > > +    */
> > > +   __u64 hdr_mult;
> > >  #endif
> > >  };
> > >
> > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > > index 5b458cc0781c..57169dae8b3d 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > > @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
> > >             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
> > >
> > >  #ifdef CONFIG_STEAM_DECK
> > > -   if (amdgpu_state)
> > > +   if (amdgpu_state) {
> > >             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
> > > +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> > > +   }
> > >  #endif
> > >  }
> > >
> > > @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> > >  #ifdef CONFIG_STEAM_DECK
> > >  int
> > >  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > > -                                          struct drm_property_blob **blob,
> > > -                                          uint64_t blob_id,
> > > -                                          ssize_t expected_size,
> > > -                                          ssize_t expected_elem_size,
> > > -                                          bool *replaced)
> > > +                                   struct drm_property_blob **blob,
> > > +                                   uint64_t blob_id,
> > > +                                   ssize_t expected_size,
> > > +                                   ssize_t expected_elem_size,
> > > +                                   bool *replaced)
> > >  {
> > >     struct drm_property_blob *new_blob = NULL;
> > >
> > > @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
> > >                                        dm->adev->mode_info.plane_degamma_tf_property,
> > >                                        DRM_TRANSFER_FUNCTION_DEFAULT);
> > >     }
> > > +   /* HDR MULT is always available */
> > > +   drm_object_attach_property(&plane->base,
> > > +                              dm->adev->mode_info.plane_hdr_mult_property,
> > > +                              AMDGPU_HDR_MULT_DEFAULT);
> > >  }
> > >
> > >  static int
> > > @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
> > >                     dm_plane_state->degamma_tf = val;
> > >                     dm_plane_state->base.color_mgmt_changed = 1;
> > >             }
> > > +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> > > +           if (dm_plane_state->hdr_mult != val) {
> > > +                   dm_plane_state->hdr_mult = val;
> > > +                   dm_plane_state->base.color_mgmt_changed = 1;
> > > +           }
> > >     } else {
> > >             drm_dbg_atomic(plane->dev,
> > >                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
> > > @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
> > >                     dm_plane_state->degamma_lut->base.id : 0;
> > >     } else if (property == adev->mode_info.plane_degamma_tf_property) {
> > >             *val = dm_plane_state->degamma_tf;
> > > +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> > > +           *val = dm_plane_state->hdr_mult;
> > >     } else {
> > >             return -EINVAL;
> > >     }
> >
> >

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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-05-09 16:54         ` Joshua Ashton
  0 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 16:54 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, Xinhui.Pan,
	Rodrigo Siqueira, Xaver Hugl, dri-devel, Nicholas Kazlauskas,
	Alex Hung, amd-gfx, Alex Deucher, christian.koenig, linux-kernel,
	sungjoon.kim

We currently do not have a use for this as we settled on per-plane 3D
LUT + Shaper, but we might end up wanting to use in our scRGB stack
someday so I would like to keep it.

On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
>
> On 05/08, Harry Wentland wrote:
> >
> >
> > On 4/23/23 10:10, Melissa Wen wrote:
> > > From: Joshua Ashton <joshua@froggi.es>
> > >
> > > Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
> > > transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
> > > least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
> > > nits for SDR content. So if you want, 203 nits for SDR content, pass in
> > > (203.0 / 80.0).
> > >
> >
> > Is gamescope intending to use this?
>
> I don't think so. Again, I'll double check and drop it accordingly.
>
> Melissa
>
> >
> > Harry
> >
> > > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > > ---
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
> > >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
> > >  4 files changed, 41 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > index 24595906dab1..dd658f162f6f 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > >             return -ENOMEM;
> > >     adev->mode_info.plane_degamma_tf_property = prop;
> > >
> > > +   prop = drm_property_create_range(adev_to_drm(adev),
> > > +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
> > > +   if (!prop)
> > > +           return -ENOMEM;
> > > +   adev->mode_info.plane_hdr_mult_property = prop;
> > > +
> > >     return 0;
> > >  }
> > >  #endif
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > index ab9ce6f26c90..65a9d62ffbe4 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
> > >      * linearize content with or without LUT.
> > >      */
> > >     struct drm_property *plane_degamma_tf_property;
> > > +   /**
> > > +    * @plane_hdr_mult_property:
> > > +    */
> > > +   struct drm_property *plane_hdr_mult_property;
> > >  #endif
> > >  };
> > >
> > > 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 005632c1c9ec..bb7307b9cfd5 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > @@ -51,6 +51,7 @@
> > >
> > >  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
> > >
> > > +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
> > >  /*
> > >  #include "include/amdgpu_dal_power_if.h"
> > >  #include "amdgpu_dm_irq.h"
> > > @@ -736,6 +737,17 @@ struct dm_plane_state {
> > >      * linearize.
> > >      */
> > >     enum drm_transfer_function degamma_tf;
> > > +   /**
> > > +    * @hdr_mult:
> > > +    *
> > > +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
> > > +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
> > > +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
> > > +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
> > > +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
> > > +    * S31.32 sign-magnitude.
> > > +    */
> > > +   __u64 hdr_mult;
> > >  #endif
> > >  };
> > >
> > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > > index 5b458cc0781c..57169dae8b3d 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > > @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
> > >             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
> > >
> > >  #ifdef CONFIG_STEAM_DECK
> > > -   if (amdgpu_state)
> > > +   if (amdgpu_state) {
> > >             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
> > > +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> > > +   }
> > >  #endif
> > >  }
> > >
> > > @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> > >  #ifdef CONFIG_STEAM_DECK
> > >  int
> > >  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > > -                                          struct drm_property_blob **blob,
> > > -                                          uint64_t blob_id,
> > > -                                          ssize_t expected_size,
> > > -                                          ssize_t expected_elem_size,
> > > -                                          bool *replaced)
> > > +                                   struct drm_property_blob **blob,
> > > +                                   uint64_t blob_id,
> > > +                                   ssize_t expected_size,
> > > +                                   ssize_t expected_elem_size,
> > > +                                   bool *replaced)
> > >  {
> > >     struct drm_property_blob *new_blob = NULL;
> > >
> > > @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
> > >                                        dm->adev->mode_info.plane_degamma_tf_property,
> > >                                        DRM_TRANSFER_FUNCTION_DEFAULT);
> > >     }
> > > +   /* HDR MULT is always available */
> > > +   drm_object_attach_property(&plane->base,
> > > +                              dm->adev->mode_info.plane_hdr_mult_property,
> > > +                              AMDGPU_HDR_MULT_DEFAULT);
> > >  }
> > >
> > >  static int
> > > @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
> > >                     dm_plane_state->degamma_tf = val;
> > >                     dm_plane_state->base.color_mgmt_changed = 1;
> > >             }
> > > +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> > > +           if (dm_plane_state->hdr_mult != val) {
> > > +                   dm_plane_state->hdr_mult = val;
> > > +                   dm_plane_state->base.color_mgmt_changed = 1;
> > > +           }
> > >     } else {
> > >             drm_dbg_atomic(plane->dev,
> > >                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
> > > @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
> > >                     dm_plane_state->degamma_lut->base.id : 0;
> > >     } else if (property == adev->mode_info.plane_degamma_tf_property) {
> > >             *val = dm_plane_state->degamma_tf;
> > > +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> > > +           *val = dm_plane_state->hdr_mult;
> > >     } else {
> > >             return -EINVAL;
> > >     }
> >
> >

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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-05-09 16:54         ` Joshua Ashton
  0 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 16:54 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, airlied, Xinhui.Pan,
	Rodrigo Siqueira, Xaver Hugl, dri-devel, Nicholas Kazlauskas,
	Alex Hung, amd-gfx, daniel, Alex Deucher, Harry Wentland,
	christian.koenig, linux-kernel, sungjoon.kim

We currently do not have a use for this as we settled on per-plane 3D
LUT + Shaper, but we might end up wanting to use in our scRGB stack
someday so I would like to keep it.

On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
>
> On 05/08, Harry Wentland wrote:
> >
> >
> > On 4/23/23 10:10, Melissa Wen wrote:
> > > From: Joshua Ashton <joshua@froggi.es>
> > >
> > > Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
> > > transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
> > > least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
> > > nits for SDR content. So if you want, 203 nits for SDR content, pass in
> > > (203.0 / 80.0).
> > >
> >
> > Is gamescope intending to use this?
>
> I don't think so. Again, I'll double check and drop it accordingly.
>
> Melissa
>
> >
> > Harry
> >
> > > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > > ---
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
> > >  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
> > >  4 files changed, 41 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > index 24595906dab1..dd658f162f6f 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > >             return -ENOMEM;
> > >     adev->mode_info.plane_degamma_tf_property = prop;
> > >
> > > +   prop = drm_property_create_range(adev_to_drm(adev),
> > > +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
> > > +   if (!prop)
> > > +           return -ENOMEM;
> > > +   adev->mode_info.plane_hdr_mult_property = prop;
> > > +
> > >     return 0;
> > >  }
> > >  #endif
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > index ab9ce6f26c90..65a9d62ffbe4 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
> > >      * linearize content with or without LUT.
> > >      */
> > >     struct drm_property *plane_degamma_tf_property;
> > > +   /**
> > > +    * @plane_hdr_mult_property:
> > > +    */
> > > +   struct drm_property *plane_hdr_mult_property;
> > >  #endif
> > >  };
> > >
> > > 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 005632c1c9ec..bb7307b9cfd5 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > @@ -51,6 +51,7 @@
> > >
> > >  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
> > >
> > > +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
> > >  /*
> > >  #include "include/amdgpu_dal_power_if.h"
> > >  #include "amdgpu_dm_irq.h"
> > > @@ -736,6 +737,17 @@ struct dm_plane_state {
> > >      * linearize.
> > >      */
> > >     enum drm_transfer_function degamma_tf;
> > > +   /**
> > > +    * @hdr_mult:
> > > +    *
> > > +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
> > > +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
> > > +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
> > > +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
> > > +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
> > > +    * S31.32 sign-magnitude.
> > > +    */
> > > +   __u64 hdr_mult;
> > >  #endif
> > >  };
> > >
> > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > > index 5b458cc0781c..57169dae8b3d 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> > > @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
> > >             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
> > >
> > >  #ifdef CONFIG_STEAM_DECK
> > > -   if (amdgpu_state)
> > > +   if (amdgpu_state) {
> > >             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
> > > +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> > > +   }
> > >  #endif
> > >  }
> > >
> > > @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> > >  #ifdef CONFIG_STEAM_DECK
> > >  int
> > >  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> > > -                                          struct drm_property_blob **blob,
> > > -                                          uint64_t blob_id,
> > > -                                          ssize_t expected_size,
> > > -                                          ssize_t expected_elem_size,
> > > -                                          bool *replaced)
> > > +                                   struct drm_property_blob **blob,
> > > +                                   uint64_t blob_id,
> > > +                                   ssize_t expected_size,
> > > +                                   ssize_t expected_elem_size,
> > > +                                   bool *replaced)
> > >  {
> > >     struct drm_property_blob *new_blob = NULL;
> > >
> > > @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
> > >                                        dm->adev->mode_info.plane_degamma_tf_property,
> > >                                        DRM_TRANSFER_FUNCTION_DEFAULT);
> > >     }
> > > +   /* HDR MULT is always available */
> > > +   drm_object_attach_property(&plane->base,
> > > +                              dm->adev->mode_info.plane_hdr_mult_property,
> > > +                              AMDGPU_HDR_MULT_DEFAULT);
> > >  }
> > >
> > >  static int
> > > @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
> > >                     dm_plane_state->degamma_tf = val;
> > >                     dm_plane_state->base.color_mgmt_changed = 1;
> > >             }
> > > +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> > > +           if (dm_plane_state->hdr_mult != val) {
> > > +                   dm_plane_state->hdr_mult = val;
> > > +                   dm_plane_state->base.color_mgmt_changed = 1;
> > > +           }
> > >     } else {
> > >             drm_dbg_atomic(plane->dev,
> > >                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
> > > @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
> > >                     dm_plane_state->degamma_lut->base.id : 0;
> > >     } else if (property == adev->mode_info.plane_degamma_tf_property) {
> > >             *val = dm_plane_state->degamma_tf;
> > > +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> > > +           *val = dm_plane_state->hdr_mult;
> > >     } else {
> > >             return -EINVAL;
> > >     }
> >
> >

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

* Re: [RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to driver-private props
  2023-05-09 16:34       ` Melissa Wen
  (?)
@ 2023-05-09 16:55         ` Joshua Ashton
  -1 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 16:55 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Harry Wentland, amd-gfx, Rodrigo Siqueira, sunpeng.li,
	Alex Deucher, dri-devel, christian.koenig, Xinhui.Pan, airlied,
	daniel, Sebastian Wick, Xaver Hugl, Shashank Sharma,
	Nicholas Kazlauskas, sungjoon.kim, Alex Hung, linux-kernel

I am okay with us dropping the shaper + 3D LUT from crtc. It has
problems anyway wrt. atomicity.

On Tue, 9 May 2023 at 16:34, Melissa Wen <mwen@igalia.com> wrote:
>
> On 05/08, Harry Wentland wrote:
> >
> >
> > On 4/23/23 10:10, Melissa Wen wrote:
> > > From: Joshua Ashton <joshua@froggi.es>
> > >
> > > Add predefined transfer function property to DRM CRTC gamma to convert
> > > to wire encoding with or without gamma LUT.
> > >
> >
> > Are all these new CRTC properties used by gamescope? I would be reluctant
> > to merge them if they're currently not needed.
>
> The regamma TF yes. The shaper and 3D LUT not yet.
>
> I'll double check with Joshie and drop from the series what we don't
> have a short-term perspective of usage.
>
> >
> > > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > > ---
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 22 ++++++++++++++++++
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 ++++
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 23 +++++++++++++++++++
> > >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 13 +++++++++++
> > >  4 files changed, 62 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > index 2abe5fe87c10..1913903cab88 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > @@ -1248,6 +1248,19 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
> > >  }
> > >
> > >  #ifdef CONFIG_STEAM_DECK
> > > +static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
> > > +   { DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
> > > +   { DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
> > > +   { DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
> > > +   { DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
> > > +   { DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
> > > +   { DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
> > > +   { DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
> > > +   { DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
> > > +   { DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
> > > +   { DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
> > > +};
> > > +
> >
> > Would it be better to prefix things with AMD_/amd_ to avoid confusion? On the other
> > hand, these will likely just move into DRM core once we get the generic color uAPI.
> >
> > Harry
> >
> > >  static int
> > >  amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > >  {
> > > @@ -1281,6 +1294,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > >             return -ENOMEM;
> > >     adev->mode_info.lut3d_size_property = prop;
> > >
> > > +   prop = drm_property_create_enum(adev_to_drm(adev),
> > > +                                   DRM_MODE_PROP_ENUM,
> > > +                                   "GAMMA_TF",
> > > +                                   drm_transfer_function_enum_list,
> > > +                                   ARRAY_SIZE(drm_transfer_function_enum_list));
> > > +   if (!prop)
> > > +           return -ENOMEM;
> > > +   adev->mode_info.gamma_tf_property = prop;
> > > +
> > >     return 0;
> > >  }
> > >  #endif
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > index 205fa4f5bea7..76337e18c728 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > @@ -368,6 +368,10 @@ struct amdgpu_mode_info {
> > >      * LUT as supported by the driver (read-only).
> > >      */
> > >     struct drm_property *lut3d_size_property;
> > > +   /**
> > > +    * @gamma_tf_property: Transfer function for CRTC regamma.
> > > +    */
> > > +   struct drm_property *gamma_tf_property;
> > >  #endif
> > >  };
> > >
> > > 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 09c3e1858b56..1e90a2dd445e 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > @@ -699,6 +699,23 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
> > >
> > >  extern const struct amdgpu_ip_block_version dm_ip_block;
> > >
> > > +#ifdef CONFIG_STEAM_DECK
> > > +enum drm_transfer_function {
> > > +   DRM_TRANSFER_FUNCTION_DEFAULT,
> > > +
> > > +   DRM_TRANSFER_FUNCTION_SRGB,
> > > +   DRM_TRANSFER_FUNCTION_BT709,
> > > +   DRM_TRANSFER_FUNCTION_PQ,
> > > +   DRM_TRANSFER_FUNCTION_LINEAR,
> > > +   DRM_TRANSFER_FUNCTION_UNITY,
> > > +   DRM_TRANSFER_FUNCTION_HLG,
> > > +   DRM_TRANSFER_FUNCTION_GAMMA22,
> > > +   DRM_TRANSFER_FUNCTION_GAMMA24,
> > > +   DRM_TRANSFER_FUNCTION_GAMMA26,
> > > +   DRM_TRANSFER_FUNCTION_MAX,
> > > +};
> > > +#endif
> > > +
> > >  struct dm_plane_state {
> > >     struct drm_plane_state base;
> > >     struct dc_plane_state *dc_state;
> > > @@ -751,6 +768,12 @@ struct dm_crtc_state {
> > >      * &struct drm_color_lut.
> > >      */
> > >     struct drm_property_blob *lut3d;
> > > +        /**
> > > +    * @gamma_tf:
> > > +    *
> > > +    * Pre-defined transfer function for converting internal FB -> wire encoding.
> > > +    */
> > > +   enum drm_transfer_function gamma_tf;
> > >  #endif
> > >  };
> > >
> > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > > index 0e1280228e6e..79324fbab1f1 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > > @@ -272,6 +272,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
> > >  #ifdef CONFIG_STEAM_DECK
> > >     state->shaper_lut = cur->shaper_lut;
> > >     state->lut3d = cur->lut3d;
> > > +   state->gamma_tf = cur->gamma_tf;
> > >
> > >     if (state->shaper_lut)
> > >             drm_property_blob_get(state->shaper_lut);
> > > @@ -336,6 +337,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> > >                                        adev->mode_info.lut3d_size_property,
> > >                                        MAX_COLOR_3DLUT_ENTRIES);
> > >     }
> > > +
> > > +   if(adev->dm.dc->caps.color.mpc.ogam_ram)
> > > +           drm_object_attach_property(&crtc->base,
> > > +                                      adev->mode_info.gamma_tf_property,
> > > +                                      DRM_TRANSFER_FUNCTION_DEFAULT);
> > >  }
> > >
> > >  static int
> > > @@ -398,6 +404,11 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> > >                                     &replaced);
> > >             acrtc_state->base.color_mgmt_changed |= replaced;
> > >             return ret;
> > > +   } else if (property == adev->mode_info.gamma_tf_property) {
> > > +           if (acrtc_state->gamma_tf != val) {
> > > +                   acrtc_state->gamma_tf = val;
> > > +                   acrtc_state->base.color_mgmt_changed |= 1;
> > > +           }
> > >     } else {
> > >             drm_dbg_atomic(crtc->dev,
> > >                            "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> > > @@ -424,6 +435,8 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> > >     else if (property == adev->mode_info.lut3d_property)
> > >             *val = (acrtc_state->lut3d) ?
> > >                     acrtc_state->lut3d->base.id : 0;
> > > +   else if (property == adev->mode_info.gamma_tf_property)
> > > +           *val = acrtc_state->gamma_tf;
> > >     else
> > >             return -EINVAL;
> > >
> >
> >

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

* Re: [RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to driver-private props
@ 2023-05-09 16:55         ` Joshua Ashton
  0 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 16:55 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, Xinhui.Pan,
	Rodrigo Siqueira, Xaver Hugl, dri-devel, Nicholas Kazlauskas,
	Alex Hung, amd-gfx, Alex Deucher, christian.koenig, linux-kernel,
	sungjoon.kim

I am okay with us dropping the shaper + 3D LUT from crtc. It has
problems anyway wrt. atomicity.

On Tue, 9 May 2023 at 16:34, Melissa Wen <mwen@igalia.com> wrote:
>
> On 05/08, Harry Wentland wrote:
> >
> >
> > On 4/23/23 10:10, Melissa Wen wrote:
> > > From: Joshua Ashton <joshua@froggi.es>
> > >
> > > Add predefined transfer function property to DRM CRTC gamma to convert
> > > to wire encoding with or without gamma LUT.
> > >
> >
> > Are all these new CRTC properties used by gamescope? I would be reluctant
> > to merge them if they're currently not needed.
>
> The regamma TF yes. The shaper and 3D LUT not yet.
>
> I'll double check with Joshie and drop from the series what we don't
> have a short-term perspective of usage.
>
> >
> > > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > > ---
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 22 ++++++++++++++++++
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 ++++
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 23 +++++++++++++++++++
> > >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 13 +++++++++++
> > >  4 files changed, 62 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > index 2abe5fe87c10..1913903cab88 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > @@ -1248,6 +1248,19 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
> > >  }
> > >
> > >  #ifdef CONFIG_STEAM_DECK
> > > +static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
> > > +   { DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
> > > +   { DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
> > > +   { DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
> > > +   { DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
> > > +   { DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
> > > +   { DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
> > > +   { DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
> > > +   { DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
> > > +   { DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
> > > +   { DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
> > > +};
> > > +
> >
> > Would it be better to prefix things with AMD_/amd_ to avoid confusion? On the other
> > hand, these will likely just move into DRM core once we get the generic color uAPI.
> >
> > Harry
> >
> > >  static int
> > >  amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > >  {
> > > @@ -1281,6 +1294,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > >             return -ENOMEM;
> > >     adev->mode_info.lut3d_size_property = prop;
> > >
> > > +   prop = drm_property_create_enum(adev_to_drm(adev),
> > > +                                   DRM_MODE_PROP_ENUM,
> > > +                                   "GAMMA_TF",
> > > +                                   drm_transfer_function_enum_list,
> > > +                                   ARRAY_SIZE(drm_transfer_function_enum_list));
> > > +   if (!prop)
> > > +           return -ENOMEM;
> > > +   adev->mode_info.gamma_tf_property = prop;
> > > +
> > >     return 0;
> > >  }
> > >  #endif
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > index 205fa4f5bea7..76337e18c728 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > @@ -368,6 +368,10 @@ struct amdgpu_mode_info {
> > >      * LUT as supported by the driver (read-only).
> > >      */
> > >     struct drm_property *lut3d_size_property;
> > > +   /**
> > > +    * @gamma_tf_property: Transfer function for CRTC regamma.
> > > +    */
> > > +   struct drm_property *gamma_tf_property;
> > >  #endif
> > >  };
> > >
> > > 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 09c3e1858b56..1e90a2dd445e 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > @@ -699,6 +699,23 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
> > >
> > >  extern const struct amdgpu_ip_block_version dm_ip_block;
> > >
> > > +#ifdef CONFIG_STEAM_DECK
> > > +enum drm_transfer_function {
> > > +   DRM_TRANSFER_FUNCTION_DEFAULT,
> > > +
> > > +   DRM_TRANSFER_FUNCTION_SRGB,
> > > +   DRM_TRANSFER_FUNCTION_BT709,
> > > +   DRM_TRANSFER_FUNCTION_PQ,
> > > +   DRM_TRANSFER_FUNCTION_LINEAR,
> > > +   DRM_TRANSFER_FUNCTION_UNITY,
> > > +   DRM_TRANSFER_FUNCTION_HLG,
> > > +   DRM_TRANSFER_FUNCTION_GAMMA22,
> > > +   DRM_TRANSFER_FUNCTION_GAMMA24,
> > > +   DRM_TRANSFER_FUNCTION_GAMMA26,
> > > +   DRM_TRANSFER_FUNCTION_MAX,
> > > +};
> > > +#endif
> > > +
> > >  struct dm_plane_state {
> > >     struct drm_plane_state base;
> > >     struct dc_plane_state *dc_state;
> > > @@ -751,6 +768,12 @@ struct dm_crtc_state {
> > >      * &struct drm_color_lut.
> > >      */
> > >     struct drm_property_blob *lut3d;
> > > +        /**
> > > +    * @gamma_tf:
> > > +    *
> > > +    * Pre-defined transfer function for converting internal FB -> wire encoding.
> > > +    */
> > > +   enum drm_transfer_function gamma_tf;
> > >  #endif
> > >  };
> > >
> > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > > index 0e1280228e6e..79324fbab1f1 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > > @@ -272,6 +272,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
> > >  #ifdef CONFIG_STEAM_DECK
> > >     state->shaper_lut = cur->shaper_lut;
> > >     state->lut3d = cur->lut3d;
> > > +   state->gamma_tf = cur->gamma_tf;
> > >
> > >     if (state->shaper_lut)
> > >             drm_property_blob_get(state->shaper_lut);
> > > @@ -336,6 +337,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> > >                                        adev->mode_info.lut3d_size_property,
> > >                                        MAX_COLOR_3DLUT_ENTRIES);
> > >     }
> > > +
> > > +   if(adev->dm.dc->caps.color.mpc.ogam_ram)
> > > +           drm_object_attach_property(&crtc->base,
> > > +                                      adev->mode_info.gamma_tf_property,
> > > +                                      DRM_TRANSFER_FUNCTION_DEFAULT);
> > >  }
> > >
> > >  static int
> > > @@ -398,6 +404,11 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> > >                                     &replaced);
> > >             acrtc_state->base.color_mgmt_changed |= replaced;
> > >             return ret;
> > > +   } else if (property == adev->mode_info.gamma_tf_property) {
> > > +           if (acrtc_state->gamma_tf != val) {
> > > +                   acrtc_state->gamma_tf = val;
> > > +                   acrtc_state->base.color_mgmt_changed |= 1;
> > > +           }
> > >     } else {
> > >             drm_dbg_atomic(crtc->dev,
> > >                            "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> > > @@ -424,6 +435,8 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> > >     else if (property == adev->mode_info.lut3d_property)
> > >             *val = (acrtc_state->lut3d) ?
> > >                     acrtc_state->lut3d->base.id : 0;
> > > +   else if (property == adev->mode_info.gamma_tf_property)
> > > +           *val = acrtc_state->gamma_tf;
> > >     else
> > >             return -EINVAL;
> > >
> >
> >

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

* Re: [RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to driver-private props
@ 2023-05-09 16:55         ` Joshua Ashton
  0 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 16:55 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, airlied, Xinhui.Pan,
	Rodrigo Siqueira, Xaver Hugl, dri-devel, Nicholas Kazlauskas,
	Alex Hung, amd-gfx, daniel, Alex Deucher, Harry Wentland,
	christian.koenig, linux-kernel, sungjoon.kim

I am okay with us dropping the shaper + 3D LUT from crtc. It has
problems anyway wrt. atomicity.

On Tue, 9 May 2023 at 16:34, Melissa Wen <mwen@igalia.com> wrote:
>
> On 05/08, Harry Wentland wrote:
> >
> >
> > On 4/23/23 10:10, Melissa Wen wrote:
> > > From: Joshua Ashton <joshua@froggi.es>
> > >
> > > Add predefined transfer function property to DRM CRTC gamma to convert
> > > to wire encoding with or without gamma LUT.
> > >
> >
> > Are all these new CRTC properties used by gamescope? I would be reluctant
> > to merge them if they're currently not needed.
>
> The regamma TF yes. The shaper and 3D LUT not yet.
>
> I'll double check with Joshie and drop from the series what we don't
> have a short-term perspective of usage.
>
> >
> > > Co-developed-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Melissa Wen <mwen@igalia.com>
> > > Signed-off-by: Joshua Ashton <joshua@froggi.es>
> > > ---
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 22 ++++++++++++++++++
> > >  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 ++++
> > >  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 23 +++++++++++++++++++
> > >  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 13 +++++++++++
> > >  4 files changed, 62 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > index 2abe5fe87c10..1913903cab88 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> > > @@ -1248,6 +1248,19 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
> > >  }
> > >
> > >  #ifdef CONFIG_STEAM_DECK
> > > +static const struct drm_prop_enum_list drm_transfer_function_enum_list[] = {
> > > +   { DRM_TRANSFER_FUNCTION_DEFAULT, "Default" },
> > > +   { DRM_TRANSFER_FUNCTION_SRGB, "sRGB" },
> > > +   { DRM_TRANSFER_FUNCTION_BT709, "BT.709" },
> > > +   { DRM_TRANSFER_FUNCTION_PQ, "PQ (Perceptual Quantizer)" },
> > > +   { DRM_TRANSFER_FUNCTION_LINEAR, "Linear" },
> > > +   { DRM_TRANSFER_FUNCTION_UNITY, "Unity" },
> > > +   { DRM_TRANSFER_FUNCTION_HLG, "HLG (Hybrid Log Gamma)" },
> > > +   { DRM_TRANSFER_FUNCTION_GAMMA22, "Gamma 2.2" },
> > > +   { DRM_TRANSFER_FUNCTION_GAMMA24, "Gamma 2.4" },
> > > +   { DRM_TRANSFER_FUNCTION_GAMMA26, "Gamma 2.6" },
> > > +};
> > > +
> >
> > Would it be better to prefix things with AMD_/amd_ to avoid confusion? On the other
> > hand, these will likely just move into DRM core once we get the generic color uAPI.
> >
> > Harry
> >
> > >  static int
> > >  amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > >  {
> > > @@ -1281,6 +1294,15 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> > >             return -ENOMEM;
> > >     adev->mode_info.lut3d_size_property = prop;
> > >
> > > +   prop = drm_property_create_enum(adev_to_drm(adev),
> > > +                                   DRM_MODE_PROP_ENUM,
> > > +                                   "GAMMA_TF",
> > > +                                   drm_transfer_function_enum_list,
> > > +                                   ARRAY_SIZE(drm_transfer_function_enum_list));
> > > +   if (!prop)
> > > +           return -ENOMEM;
> > > +   adev->mode_info.gamma_tf_property = prop;
> > > +
> > >     return 0;
> > >  }
> > >  #endif
> > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > index 205fa4f5bea7..76337e18c728 100644
> > > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> > > @@ -368,6 +368,10 @@ struct amdgpu_mode_info {
> > >      * LUT as supported by the driver (read-only).
> > >      */
> > >     struct drm_property *lut3d_size_property;
> > > +   /**
> > > +    * @gamma_tf_property: Transfer function for CRTC regamma.
> > > +    */
> > > +   struct drm_property *gamma_tf_property;
> > >  #endif
> > >  };
> > >
> > > 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 09c3e1858b56..1e90a2dd445e 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> > > @@ -699,6 +699,23 @@ static inline void amdgpu_dm_set_mst_status(uint8_t *status,
> > >
> > >  extern const struct amdgpu_ip_block_version dm_ip_block;
> > >
> > > +#ifdef CONFIG_STEAM_DECK
> > > +enum drm_transfer_function {
> > > +   DRM_TRANSFER_FUNCTION_DEFAULT,
> > > +
> > > +   DRM_TRANSFER_FUNCTION_SRGB,
> > > +   DRM_TRANSFER_FUNCTION_BT709,
> > > +   DRM_TRANSFER_FUNCTION_PQ,
> > > +   DRM_TRANSFER_FUNCTION_LINEAR,
> > > +   DRM_TRANSFER_FUNCTION_UNITY,
> > > +   DRM_TRANSFER_FUNCTION_HLG,
> > > +   DRM_TRANSFER_FUNCTION_GAMMA22,
> > > +   DRM_TRANSFER_FUNCTION_GAMMA24,
> > > +   DRM_TRANSFER_FUNCTION_GAMMA26,
> > > +   DRM_TRANSFER_FUNCTION_MAX,
> > > +};
> > > +#endif
> > > +
> > >  struct dm_plane_state {
> > >     struct drm_plane_state base;
> > >     struct dc_plane_state *dc_state;
> > > @@ -751,6 +768,12 @@ struct dm_crtc_state {
> > >      * &struct drm_color_lut.
> > >      */
> > >     struct drm_property_blob *lut3d;
> > > +        /**
> > > +    * @gamma_tf:
> > > +    *
> > > +    * Pre-defined transfer function for converting internal FB -> wire encoding.
> > > +    */
> > > +   enum drm_transfer_function gamma_tf;
> > >  #endif
> > >  };
> > >
> > > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > > index 0e1280228e6e..79324fbab1f1 100644
> > > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
> > > @@ -272,6 +272,7 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc)
> > >  #ifdef CONFIG_STEAM_DECK
> > >     state->shaper_lut = cur->shaper_lut;
> > >     state->lut3d = cur->lut3d;
> > > +   state->gamma_tf = cur->gamma_tf;
> > >
> > >     if (state->shaper_lut)
> > >             drm_property_blob_get(state->shaper_lut);
> > > @@ -336,6 +337,11 @@ dm_crtc_additional_color_mgmt(struct drm_crtc *crtc)
> > >                                        adev->mode_info.lut3d_size_property,
> > >                                        MAX_COLOR_3DLUT_ENTRIES);
> > >     }
> > > +
> > > +   if(adev->dm.dc->caps.color.mpc.ogam_ram)
> > > +           drm_object_attach_property(&crtc->base,
> > > +                                      adev->mode_info.gamma_tf_property,
> > > +                                      DRM_TRANSFER_FUNCTION_DEFAULT);
> > >  }
> > >
> > >  static int
> > > @@ -398,6 +404,11 @@ amdgpu_dm_atomic_crtc_set_property(struct drm_crtc *crtc,
> > >                                     &replaced);
> > >             acrtc_state->base.color_mgmt_changed |= replaced;
> > >             return ret;
> > > +   } else if (property == adev->mode_info.gamma_tf_property) {
> > > +           if (acrtc_state->gamma_tf != val) {
> > > +                   acrtc_state->gamma_tf = val;
> > > +                   acrtc_state->base.color_mgmt_changed |= 1;
> > > +           }
> > >     } else {
> > >             drm_dbg_atomic(crtc->dev,
> > >                            "[CRTC:%d:%s] unknown property [PROP:%d:%s]]\n",
> > > @@ -424,6 +435,8 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc,
> > >     else if (property == adev->mode_info.lut3d_property)
> > >             *val = (acrtc_state->lut3d) ?
> > >                     acrtc_state->lut3d->base.id : 0;
> > > +   else if (property == adev->mode_info.gamma_tf_property)
> > > +           *val = acrtc_state->gamma_tf;
> > >     else
> > >             return -EINVAL;
> > >
> >
> >

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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
  2023-05-09 16:52         ` Joshua Ashton
  (?)
@ 2023-05-09 17:19           ` Harry Wentland
  -1 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 17:19 UTC (permalink / raw)
  To: Joshua Ashton, Melissa Wen
  Cc: amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher, dri-devel,
	christian.koenig, Xinhui.Pan, airlied, daniel, Sebastian Wick,
	Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas, sungjoon.kim,
	Alex Hung, linux-kernel



On 5/9/23 12:52, Joshua Ashton wrote:
> I think the idea is that we wouldn't have a config option so it
> doesn't inherently become linux kernel uAPI?
> 
> Then we can just build our SteamOS kernels with that definiton set.
> 

That's the idea. Would that work for you?

Harry

> On Tue, 9 May 2023 at 16:26, Melissa Wen <mwen@igalia.com> wrote:
>>
>> On 05/08, Harry Wentland wrote:
>>> On 4/23/23 10:10, Melissa Wen wrote:
>>>> We are enabling a large set of color calibration features to enhance KMS
>>>> color mgmt but these properties are specific of AMD display HW, and
>>>> cannot be provided by other vendors. Therefore, set a config option to
>>>> enable AMD driver-private properties used on Steam Deck color mgmt
>>>> pipeline.
>>>>
>>>> Co-developed-by: Joshua Ashton <joshua@froggi.es>
>>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>>> ---
>>>>  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
>>>>  1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
>>>> index 06b438217c61..c45a8deb1098 100644
>>>> --- a/drivers/gpu/drm/amd/display/Kconfig
>>>> +++ b/drivers/gpu/drm/amd/display/Kconfig
>>>> @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
>>>>              of crc of specific region via debugfs.
>>>>              Cooperate with specific DMCU FW.
>>>>
>>>> +config STEAM_DECK
>>>> +   bool "Enable color calibration features for Steam Deck"
>>>> +   depends on DRM_AMD_DC
>>>> +   help
>>>> +     Choose this option if you want to use AMDGPU features for broader
>>>> +     color management support on Steam Deck.
>>>>
>>>
>>> If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
>>> the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
>>> us from requiring to support this forever.
>>
>> I see, I'll follow this path. Still on that, I've changed
>> CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.
>> Does it sound better?
>>
>> Thanks,
>>
>> Melissa
>>
>>>
>>> Harry
>>>
>>>>  endmenu
>>>
>>>


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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
@ 2023-05-09 17:19           ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 17:19 UTC (permalink / raw)
  To: Joshua Ashton, Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, Alex Deucher,
	christian.koenig, sungjoon.kim



On 5/9/23 12:52, Joshua Ashton wrote:
> I think the idea is that we wouldn't have a config option so it
> doesn't inherently become linux kernel uAPI?
> 
> Then we can just build our SteamOS kernels with that definiton set.
> 

That's the idea. Would that work for you?

Harry

> On Tue, 9 May 2023 at 16:26, Melissa Wen <mwen@igalia.com> wrote:
>>
>> On 05/08, Harry Wentland wrote:
>>> On 4/23/23 10:10, Melissa Wen wrote:
>>>> We are enabling a large set of color calibration features to enhance KMS
>>>> color mgmt but these properties are specific of AMD display HW, and
>>>> cannot be provided by other vendors. Therefore, set a config option to
>>>> enable AMD driver-private properties used on Steam Deck color mgmt
>>>> pipeline.
>>>>
>>>> Co-developed-by: Joshua Ashton <joshua@froggi.es>
>>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>>> ---
>>>>  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
>>>>  1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
>>>> index 06b438217c61..c45a8deb1098 100644
>>>> --- a/drivers/gpu/drm/amd/display/Kconfig
>>>> +++ b/drivers/gpu/drm/amd/display/Kconfig
>>>> @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
>>>>              of crc of specific region via debugfs.
>>>>              Cooperate with specific DMCU FW.
>>>>
>>>> +config STEAM_DECK
>>>> +   bool "Enable color calibration features for Steam Deck"
>>>> +   depends on DRM_AMD_DC
>>>> +   help
>>>> +     Choose this option if you want to use AMDGPU features for broader
>>>> +     color management support on Steam Deck.
>>>>
>>>
>>> If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
>>> the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
>>> us from requiring to support this forever.
>>
>> I see, I'll follow this path. Still on that, I've changed
>> CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.
>> Does it sound better?
>>
>> Thanks,
>>
>> Melissa
>>
>>>
>>> Harry
>>>
>>>>  endmenu
>>>
>>>


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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
@ 2023-05-09 17:19           ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 17:19 UTC (permalink / raw)
  To: Joshua Ashton, Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, daniel, Alex Deucher,
	airlied, christian.koenig, sungjoon.kim



On 5/9/23 12:52, Joshua Ashton wrote:
> I think the idea is that we wouldn't have a config option so it
> doesn't inherently become linux kernel uAPI?
> 
> Then we can just build our SteamOS kernels with that definiton set.
> 

That's the idea. Would that work for you?

Harry

> On Tue, 9 May 2023 at 16:26, Melissa Wen <mwen@igalia.com> wrote:
>>
>> On 05/08, Harry Wentland wrote:
>>> On 4/23/23 10:10, Melissa Wen wrote:
>>>> We are enabling a large set of color calibration features to enhance KMS
>>>> color mgmt but these properties are specific of AMD display HW, and
>>>> cannot be provided by other vendors. Therefore, set a config option to
>>>> enable AMD driver-private properties used on Steam Deck color mgmt
>>>> pipeline.
>>>>
>>>> Co-developed-by: Joshua Ashton <joshua@froggi.es>
>>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>>> ---
>>>>  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
>>>>  1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
>>>> index 06b438217c61..c45a8deb1098 100644
>>>> --- a/drivers/gpu/drm/amd/display/Kconfig
>>>> +++ b/drivers/gpu/drm/amd/display/Kconfig
>>>> @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
>>>>              of crc of specific region via debugfs.
>>>>              Cooperate with specific DMCU FW.
>>>>
>>>> +config STEAM_DECK
>>>> +   bool "Enable color calibration features for Steam Deck"
>>>> +   depends on DRM_AMD_DC
>>>> +   help
>>>> +     Choose this option if you want to use AMDGPU features for broader
>>>> +     color management support on Steam Deck.
>>>>
>>>
>>> If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
>>> the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
>>> us from requiring to support this forever.
>>
>> I see, I'll follow this path. Still on that, I've changed
>> CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.
>> Does it sound better?
>>
>> Thanks,
>>
>> Melissa
>>
>>>
>>> Harry
>>>
>>>>  endmenu
>>>
>>>


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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
  2023-05-09 16:23       ` Melissa Wen
  (?)
@ 2023-05-09 17:20         ` Harry Wentland
  -1 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 17:20 UTC (permalink / raw)
  To: Melissa Wen
  Cc: amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher, dri-devel,
	christian.koenig, Xinhui.Pan, airlied, daniel, Joshua Ashton,
	Sebastian Wick, Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas,
	sungjoon.kim, Alex Hung, linux-kernel



On 5/9/23 12:23, Melissa Wen wrote:
> On 05/08, Harry Wentland wrote:
>> On 4/23/23 10:10, Melissa Wen wrote:
>>> We are enabling a large set of color calibration features to enhance KMS
>>> color mgmt but these properties are specific of AMD display HW, and
>>> cannot be provided by other vendors. Therefore, set a config option to
>>> enable AMD driver-private properties used on Steam Deck color mgmt
>>> pipeline.
>>>
>>> Co-developed-by: Joshua Ashton <joshua@froggi.es>
>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>> ---
>>>  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
>>>  1 file changed, 6 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
>>> index 06b438217c61..c45a8deb1098 100644
>>> --- a/drivers/gpu/drm/amd/display/Kconfig
>>> +++ b/drivers/gpu/drm/amd/display/Kconfig
>>> @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
>>>              of crc of specific region via debugfs.
>>>              Cooperate with specific DMCU FW.
>>>  
>>> +config STEAM_DECK
>>> +	bool "Enable color calibration features for Steam Deck"
>>> +	depends on DRM_AMD_DC
>>> +	help
>>> +	  Choose this option if you want to use AMDGPU features for broader
>>> +	  color management support on Steam Deck.
>>>  
>>
>> If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
>> the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
>> us from requiring to support this forever.
> 
> I see, I'll follow this path. Still on that, I've changed
> CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.

I'm not sure I like the steamdeck name in there. There's nothing
inherently in this API that's only for the steamdeck.

Harry

> Does it sound better?
> 
> Thanks,
> 
> Melissa
> 
>>
>> Harry
>>
>>>  endmenu
>>
>>


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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
@ 2023-05-09 17:20         ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 17:20 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, Alex Deucher,
	christian.koenig, Joshua Ashton, sungjoon.kim



On 5/9/23 12:23, Melissa Wen wrote:
> On 05/08, Harry Wentland wrote:
>> On 4/23/23 10:10, Melissa Wen wrote:
>>> We are enabling a large set of color calibration features to enhance KMS
>>> color mgmt but these properties are specific of AMD display HW, and
>>> cannot be provided by other vendors. Therefore, set a config option to
>>> enable AMD driver-private properties used on Steam Deck color mgmt
>>> pipeline.
>>>
>>> Co-developed-by: Joshua Ashton <joshua@froggi.es>
>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>> ---
>>>  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
>>>  1 file changed, 6 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
>>> index 06b438217c61..c45a8deb1098 100644
>>> --- a/drivers/gpu/drm/amd/display/Kconfig
>>> +++ b/drivers/gpu/drm/amd/display/Kconfig
>>> @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
>>>              of crc of specific region via debugfs.
>>>              Cooperate with specific DMCU FW.
>>>  
>>> +config STEAM_DECK
>>> +	bool "Enable color calibration features for Steam Deck"
>>> +	depends on DRM_AMD_DC
>>> +	help
>>> +	  Choose this option if you want to use AMDGPU features for broader
>>> +	  color management support on Steam Deck.
>>>  
>>
>> If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
>> the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
>> us from requiring to support this forever.
> 
> I see, I'll follow this path. Still on that, I've changed
> CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.

I'm not sure I like the steamdeck name in there. There's nothing
inherently in this API that's only for the steamdeck.

Harry

> Does it sound better?
> 
> Thanks,
> 
> Melissa
> 
>>
>> Harry
>>
>>>  endmenu
>>
>>


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

* Re: [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver
@ 2023-05-09 17:20         ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 17:20 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, daniel, Alex Deucher,
	airlied, christian.koenig, Joshua Ashton, sungjoon.kim



On 5/9/23 12:23, Melissa Wen wrote:
> On 05/08, Harry Wentland wrote:
>> On 4/23/23 10:10, Melissa Wen wrote:
>>> We are enabling a large set of color calibration features to enhance KMS
>>> color mgmt but these properties are specific of AMD display HW, and
>>> cannot be provided by other vendors. Therefore, set a config option to
>>> enable AMD driver-private properties used on Steam Deck color mgmt
>>> pipeline.
>>>
>>> Co-developed-by: Joshua Ashton <joshua@froggi.es>
>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>> ---
>>>  drivers/gpu/drm/amd/display/Kconfig | 6 ++++++
>>>  1 file changed, 6 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
>>> index 06b438217c61..c45a8deb1098 100644
>>> --- a/drivers/gpu/drm/amd/display/Kconfig
>>> +++ b/drivers/gpu/drm/amd/display/Kconfig
>>> @@ -53,5 +53,11 @@ config DRM_AMD_SECURE_DISPLAY
>>>              of crc of specific region via debugfs.
>>>              Cooperate with specific DMCU FW.
>>>  
>>> +config STEAM_DECK
>>> +	bool "Enable color calibration features for Steam Deck"
>>> +	depends on DRM_AMD_DC
>>> +	help
>>> +	  Choose this option if you want to use AMDGPU features for broader
>>> +	  color management support on Steam Deck.
>>>  
>>
>> If we can drop this (i.e. don't offer a CONFIG_ option to allow enablement of
>> the uAPI, but build with -DCONFIG_STEAM_DECK) it would go a long way to keep
>> us from requiring to support this forever.
> 
> I see, I'll follow this path. Still on that, I've changed
> CONFIG_STEAM_DECK (too generic) to CONFIG_DRM_AMD_COLOR_STEAMDECK.

I'm not sure I like the steamdeck name in there. There's nothing
inherently in this API that's only for the steamdeck.

Harry

> Does it sound better?
> 
> Thanks,
> 
> Melissa
> 
>>
>> Harry
>>
>>>  endmenu
>>
>>


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

* Re: [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt
  2023-05-09 16:52     ` Melissa Wen
  (?)
@ 2023-05-09 17:25       ` Harry Wentland
  -1 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 17:25 UTC (permalink / raw)
  To: Melissa Wen
  Cc: amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher, dri-devel,
	airlied, christian.koenig, daniel, maarten.lankhorst, mripard,
	tzimmermann, Xinhui.Pan, Joshua Ashton, Sebastian Wick,
	Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas, sungjoon.kim,
	Alex Hung, linux-kernel



On 5/9/23 12:52, Melissa Wen wrote:
> On 05/08, Harry Wentland wrote:
>>
>>
>> On 4/23/23 10:10, Melissa Wen wrote:
>>> Hi all,
>>>
>>> Joshua Ashton and I (with the great collaboration of Harry Wentland -
>>> thanks) have been working on KMS color pipeline enhancement for Steam
>>> Deck/SteamOS by exposing the large set of color caps available in AMD
>>> display HW.
>>>
>>
>> Thank you for your work on this.
>>
>>> This patchset results from this full-stack work, including pre-blending
>>> and post-blending new color properties. The first two patches fix
>>> quantization issues on shaper LUT programming. Just after, we have one
>>> patch that adds a config option to restrict AMD colo feature usage. The
>>> following 13 patches implement AMD driver-private color properties
>>> (pending detachment of property counter and plane color_mgmt_changed
>>> from DRM). Finally, the last 24 patches rework the AMD display manager
>>> and color management to support the properties exposed.
>>>
>>> In short, for pre-blending, we added the following:
>>> - plane degamma LUT and predefined transfer function;
>>> - plane HDR multiplier
>>> - plane shaper LUT/transfer function;
>>> - plane 3D LUT; and finally,
>>> - plane blend LUT/transfer function, just before blending.
>>>
>>> After blending, we already have DRM CRTC degamma/gamma LUTs and CTM,
>>> therefore, we extend CRTC color pipeline with the following:
>>> - CRTC shaper LUT/transfer function;
>>> - CRTC 3D LUT; and
>>> - CRTC gamma transfer function.
>>>
>>> You can already find the AMD color capabilities and color management
>>> pipeline documented here:
>>> https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties
>>>
>>> In previous iterations, we tried to provide a generic solution for
>>> post-blending shaper and 3D LUT [1][2][3], and also Alex Hung worked on
>>> a pre-blending 3D LUT solution[4] extending plane color mgmt proposal
>>> from Uma Shankar [5]. However, we identified during our work [6] that
>>> AMD provides many other valuable capabilities that we don't find in
>>> other vendors, so we started to work on AMD driver-private color
>>> properties that better describe its color pipeline, enabling us to
>>> expose full AMD color capabilities on Deck HW.
>>>
>>> Our primary purpose is to avoid usage limitations of color calibration
>>> features provided by HW just because we don't have an interface for
>>> that. At the same time, a generic solution doesn't fit well since some
>>> of these capabilities seem AMD HW specific, such as hardcoded
>>> curve/predefined transfer function and shaper 1D LUTs sandwiching 3D
>>> LUT.
>>>
>>> So far, we keep these properties' usage under an AMD display config
>>> option (STEAM_DECK). However, we are fine with having them fully
>>> available to other DCN HW generations. In the current proposal, we are
>>> already checking ASICs before exposing a color feature. We can work on
>>> 3D LUT resource acquisition details to fit them to DCN 3+ families that
>>> support them. Indeed, before moving to these config boundaries, we
>>> started working on an open solution for any AMD HW [7].
>>>
>>
>> The problem with a CONFIG_XYZ option is that it becomes uAPI and can't be
>> removed. I feel we have a good proposal going for the generic solution.
>> Would it work for you if we don't make this a CONFIG_ option? What I mean
>> is using
>>
>> #define AMD_PRIVATE_COLOR
>>
>> around the interface bits, which are only compiled when building with
>> -DAMD_PRIVATE_COLOR
> 
> I think we can go with this approach for the properties already in use
> by Gamescope/SteamOS.
>>
>> That way we have the option to rip the driver-private stuff out later
>> while still allowing for experimentation now.
>>
>> Or, alternatively, we can merge everything but the stuff currently
>> guarded by CONFIG_STEAM_DECK, so that custom kernels can enable this
>> functionality by simply merging one patch that includes all the
>> CONFIG_STEAM_DECK stuff.
> 
> An then we can drop the interface of things that Gamescope is not
> managing, but keep those things already programmed on DM color for any
> future usage. What do you think?
> 

Sure.

Harry

> Melissa
> 
>>
>> This will allow us to merge the vast majority of the code without
>> having to maintain it in downstream repo.
>>
>>> The userspace case here is Gamescope which is the compositor for
>>> SteamOS. It's already using all of this functionality (although with a
>>> VALVE1_ prefix instead of AMD) to implement its color management
>>> pipeline right now:
>>> https://github.com/ValveSoftware/gamescope
>>>
>>> We are planning on shipping our color management support with gamut
>>> mapping, HDR, SDR on HDR, HDR on SDR, and much more in Steam OS 3.5. A
>>> brief overview of our color pipeline can be found here:
>>> https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png
>>>
>>> We have also had some other userspace interests from Xaver Hugl (KDE) in
>>> experimenting with these properties for their HDR/color bring-up before
>>> a generic interface is settled on also.
>>>
>>> It still needs AMD-specific IGT tests; we are working on documentation
>>> and adding plane CTM support too. 
>>>
>>> We decided first to share our work to collect thoughts and open for
>>> discussion, even with missing refinements, since driver-private
>>> properties are not the usual DMR/KMS color management approach.
>>>
>>> Please, let us know your thoughts.
>>>
>>
>> As discussed at the hackfest I think it's a good idea to have something
>> that's easy to enable for the purposes of experimentation (and to
>> help downstream users that help us figure out how this all fits
>> together, i.e. SteamOS).
>>
>> Harry
>>
>>> Best Regards,
>>>
>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>> Signed-off-by: Melissa Wen<mwen@igalia.com>
>>>
>>> [1] https://lore.kernel.org/dri-devel/20220619223104.667413-1-mwen@igalia.com/
>>> [2] https://lore.kernel.org/amd-gfx/20220906164628.2361811-1-mwen@igalia.com/
>>> [3] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-mwen@igalia.com/
>>> [4] https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.hung@amd.com/
>>> [5] https://lore.kernel.org/dri-devel/20210906213904.27918-1-uma.shankar@intel.com/
>>> [6] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-color-mgmt
>>> [7] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-private-color-mgmt
>>>
>>> Harry Wentland (2):
>>>   drm/amd/display: fix segment distribution for linear LUTs
>>>   drm/amd/display: fix the delta clamping for shaper LUT
>>>
>>> Joshua Ashton (15):
>>>   drm/amd/display: add CRTC gamma TF to driver-private props
>>>   drm/amd/display: add plane degamma LUT driver-private props
>>>   drm/amd/display: add plane degamma TF driver-private property
>>>   drm/amd/display: add plane HDR multiplier driver-private property
>>>   drm/amd/display: add plane blend LUT and TF driver-private properties
>>>   drm/amd/display: copy 3D LUT settings from crtc state to stream_update
>>>   drm/amd/display: dynamically acquire 3DLUT resources for color changes
>>>   drm/amd/display: add CRTC regamma TF support
>>>   drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
>>>   drm/amd/display: add support for plane degamma TF and LUT properties
>>>   drm/amd/display: add dc_fixpt_from_s3132 helper
>>>   drm/adm/display: add HDR multiplier support
>>>   drm/amd/display: handle empty LUTs in __set_input_tf
>>>   drm/amd/display: add DRM plane blend LUT and TF support
>>>   drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG
>>>
>>> Melissa Wen (23):
>>>   drm/amd/display: introduce Steam Deck color features to AMD display
>>>     driver
>>>   drm/drm_mode_object: increase max objects to accommodate new color
>>>     props
>>>   drm/amd/display: add shaper LUT driver-private props
>>>   drm/amd/display: add 3D LUT driver-private props
>>>   drm/drm_plane: track color mgmt changes per plane
>>>   drm/amd/display: move replace blob func to dm plane
>>>   drm/amd/display: add plane 3D LUT driver-private properties
>>>   drm/amd/display: add plane shaper LUT driver-private properties
>>>   drm/amd/display: add plane shaper TF driver-private property
>>>   drm/amd/display: add comments to describe DM crtc color mgmt behavior
>>>   drm/amd/display: encapsulate atomic regamma operation
>>>   drm/amd/display: update lut3d and shaper lut to stream
>>>   drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
>>>   drm/amd/display: handle MPC 3D LUT resources for a given context
>>>   drm/amd/display: add CRTC 3D LUT support to amd color pipeline
>>>   drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
>>>   drm/amd/display: add CRTC shaper LUT support to amd color pipeline
>>>   drm/amd/display: add CRTC shaper TF support
>>>   drm/amd/display: mark plane as needing reset if plane color mgmt
>>>     changes
>>>   drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
>>>   drm/amd/display: reject atomic commit if setting both plane and CRTC
>>>     degamma
>>>   drm/amd/display: add plane shaper/3D LUT and shaper TF support
>>>   drm/amd/display: copy dc_plane color settings to surface_updates
>>>
>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 153 +++++
>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  92 +++
>>>  drivers/gpu/drm/amd/display/Kconfig           |   6 +
>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  31 +-
>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 120 +++-
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 613 ++++++++++++++++--
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 124 +++-
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 238 +++++++
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |   7 +
>>>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  49 +-
>>>  drivers/gpu/drm/amd/display/dc/dc.h           |   8 +
>>>  .../amd/display/dc/dcn10/dcn10_cm_common.c    | 109 +++-
>>>  .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   5 +-
>>>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   9 +-
>>>  .../amd/display/dc/dcn301/dcn301_resource.c   |  26 +-
>>>  .../gpu/drm/amd/display/include/fixed31_32.h  |  12 +
>>>  drivers/gpu/drm/drm_atomic.c                  |   1 +
>>>  drivers/gpu/drm/drm_atomic_state_helper.c     |   1 +
>>>  include/drm/drm_mode_object.h                 |   2 +-
>>>  include/drm/drm_plane.h                       |   7 +
>>>  20 files changed, 1509 insertions(+), 104 deletions(-)
>>>
>>
>>


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

* Re: [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt
@ 2023-05-09 17:25       ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 17:25 UTC (permalink / raw)
  To: Melissa Wen
  Cc: Sebastian Wick, linux-kernel, tzimmermann, Shashank Sharma,
	sunpeng.li, Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, Alex Deucher,
	christian.koenig, Joshua Ashton, sungjoon.kim



On 5/9/23 12:52, Melissa Wen wrote:
> On 05/08, Harry Wentland wrote:
>>
>>
>> On 4/23/23 10:10, Melissa Wen wrote:
>>> Hi all,
>>>
>>> Joshua Ashton and I (with the great collaboration of Harry Wentland -
>>> thanks) have been working on KMS color pipeline enhancement for Steam
>>> Deck/SteamOS by exposing the large set of color caps available in AMD
>>> display HW.
>>>
>>
>> Thank you for your work on this.
>>
>>> This patchset results from this full-stack work, including pre-blending
>>> and post-blending new color properties. The first two patches fix
>>> quantization issues on shaper LUT programming. Just after, we have one
>>> patch that adds a config option to restrict AMD colo feature usage. The
>>> following 13 patches implement AMD driver-private color properties
>>> (pending detachment of property counter and plane color_mgmt_changed
>>> from DRM). Finally, the last 24 patches rework the AMD display manager
>>> and color management to support the properties exposed.
>>>
>>> In short, for pre-blending, we added the following:
>>> - plane degamma LUT and predefined transfer function;
>>> - plane HDR multiplier
>>> - plane shaper LUT/transfer function;
>>> - plane 3D LUT; and finally,
>>> - plane blend LUT/transfer function, just before blending.
>>>
>>> After blending, we already have DRM CRTC degamma/gamma LUTs and CTM,
>>> therefore, we extend CRTC color pipeline with the following:
>>> - CRTC shaper LUT/transfer function;
>>> - CRTC 3D LUT; and
>>> - CRTC gamma transfer function.
>>>
>>> You can already find the AMD color capabilities and color management
>>> pipeline documented here:
>>> https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties
>>>
>>> In previous iterations, we tried to provide a generic solution for
>>> post-blending shaper and 3D LUT [1][2][3], and also Alex Hung worked on
>>> a pre-blending 3D LUT solution[4] extending plane color mgmt proposal
>>> from Uma Shankar [5]. However, we identified during our work [6] that
>>> AMD provides many other valuable capabilities that we don't find in
>>> other vendors, so we started to work on AMD driver-private color
>>> properties that better describe its color pipeline, enabling us to
>>> expose full AMD color capabilities on Deck HW.
>>>
>>> Our primary purpose is to avoid usage limitations of color calibration
>>> features provided by HW just because we don't have an interface for
>>> that. At the same time, a generic solution doesn't fit well since some
>>> of these capabilities seem AMD HW specific, such as hardcoded
>>> curve/predefined transfer function and shaper 1D LUTs sandwiching 3D
>>> LUT.
>>>
>>> So far, we keep these properties' usage under an AMD display config
>>> option (STEAM_DECK). However, we are fine with having them fully
>>> available to other DCN HW generations. In the current proposal, we are
>>> already checking ASICs before exposing a color feature. We can work on
>>> 3D LUT resource acquisition details to fit them to DCN 3+ families that
>>> support them. Indeed, before moving to these config boundaries, we
>>> started working on an open solution for any AMD HW [7].
>>>
>>
>> The problem with a CONFIG_XYZ option is that it becomes uAPI and can't be
>> removed. I feel we have a good proposal going for the generic solution.
>> Would it work for you if we don't make this a CONFIG_ option? What I mean
>> is using
>>
>> #define AMD_PRIVATE_COLOR
>>
>> around the interface bits, which are only compiled when building with
>> -DAMD_PRIVATE_COLOR
> 
> I think we can go with this approach for the properties already in use
> by Gamescope/SteamOS.
>>
>> That way we have the option to rip the driver-private stuff out later
>> while still allowing for experimentation now.
>>
>> Or, alternatively, we can merge everything but the stuff currently
>> guarded by CONFIG_STEAM_DECK, so that custom kernels can enable this
>> functionality by simply merging one patch that includes all the
>> CONFIG_STEAM_DECK stuff.
> 
> An then we can drop the interface of things that Gamescope is not
> managing, but keep those things already programmed on DM color for any
> future usage. What do you think?
> 

Sure.

Harry

> Melissa
> 
>>
>> This will allow us to merge the vast majority of the code without
>> having to maintain it in downstream repo.
>>
>>> The userspace case here is Gamescope which is the compositor for
>>> SteamOS. It's already using all of this functionality (although with a
>>> VALVE1_ prefix instead of AMD) to implement its color management
>>> pipeline right now:
>>> https://github.com/ValveSoftware/gamescope
>>>
>>> We are planning on shipping our color management support with gamut
>>> mapping, HDR, SDR on HDR, HDR on SDR, and much more in Steam OS 3.5. A
>>> brief overview of our color pipeline can be found here:
>>> https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png
>>>
>>> We have also had some other userspace interests from Xaver Hugl (KDE) in
>>> experimenting with these properties for their HDR/color bring-up before
>>> a generic interface is settled on also.
>>>
>>> It still needs AMD-specific IGT tests; we are working on documentation
>>> and adding plane CTM support too. 
>>>
>>> We decided first to share our work to collect thoughts and open for
>>> discussion, even with missing refinements, since driver-private
>>> properties are not the usual DMR/KMS color management approach.
>>>
>>> Please, let us know your thoughts.
>>>
>>
>> As discussed at the hackfest I think it's a good idea to have something
>> that's easy to enable for the purposes of experimentation (and to
>> help downstream users that help us figure out how this all fits
>> together, i.e. SteamOS).
>>
>> Harry
>>
>>> Best Regards,
>>>
>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>> Signed-off-by: Melissa Wen<mwen@igalia.com>
>>>
>>> [1] https://lore.kernel.org/dri-devel/20220619223104.667413-1-mwen@igalia.com/
>>> [2] https://lore.kernel.org/amd-gfx/20220906164628.2361811-1-mwen@igalia.com/
>>> [3] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-mwen@igalia.com/
>>> [4] https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.hung@amd.com/
>>> [5] https://lore.kernel.org/dri-devel/20210906213904.27918-1-uma.shankar@intel.com/
>>> [6] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-color-mgmt
>>> [7] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-private-color-mgmt
>>>
>>> Harry Wentland (2):
>>>   drm/amd/display: fix segment distribution for linear LUTs
>>>   drm/amd/display: fix the delta clamping for shaper LUT
>>>
>>> Joshua Ashton (15):
>>>   drm/amd/display: add CRTC gamma TF to driver-private props
>>>   drm/amd/display: add plane degamma LUT driver-private props
>>>   drm/amd/display: add plane degamma TF driver-private property
>>>   drm/amd/display: add plane HDR multiplier driver-private property
>>>   drm/amd/display: add plane blend LUT and TF driver-private properties
>>>   drm/amd/display: copy 3D LUT settings from crtc state to stream_update
>>>   drm/amd/display: dynamically acquire 3DLUT resources for color changes
>>>   drm/amd/display: add CRTC regamma TF support
>>>   drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
>>>   drm/amd/display: add support for plane degamma TF and LUT properties
>>>   drm/amd/display: add dc_fixpt_from_s3132 helper
>>>   drm/adm/display: add HDR multiplier support
>>>   drm/amd/display: handle empty LUTs in __set_input_tf
>>>   drm/amd/display: add DRM plane blend LUT and TF support
>>>   drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG
>>>
>>> Melissa Wen (23):
>>>   drm/amd/display: introduce Steam Deck color features to AMD display
>>>     driver
>>>   drm/drm_mode_object: increase max objects to accommodate new color
>>>     props
>>>   drm/amd/display: add shaper LUT driver-private props
>>>   drm/amd/display: add 3D LUT driver-private props
>>>   drm/drm_plane: track color mgmt changes per plane
>>>   drm/amd/display: move replace blob func to dm plane
>>>   drm/amd/display: add plane 3D LUT driver-private properties
>>>   drm/amd/display: add plane shaper LUT driver-private properties
>>>   drm/amd/display: add plane shaper TF driver-private property
>>>   drm/amd/display: add comments to describe DM crtc color mgmt behavior
>>>   drm/amd/display: encapsulate atomic regamma operation
>>>   drm/amd/display: update lut3d and shaper lut to stream
>>>   drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
>>>   drm/amd/display: handle MPC 3D LUT resources for a given context
>>>   drm/amd/display: add CRTC 3D LUT support to amd color pipeline
>>>   drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
>>>   drm/amd/display: add CRTC shaper LUT support to amd color pipeline
>>>   drm/amd/display: add CRTC shaper TF support
>>>   drm/amd/display: mark plane as needing reset if plane color mgmt
>>>     changes
>>>   drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
>>>   drm/amd/display: reject atomic commit if setting both plane and CRTC
>>>     degamma
>>>   drm/amd/display: add plane shaper/3D LUT and shaper TF support
>>>   drm/amd/display: copy dc_plane color settings to surface_updates
>>>
>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 153 +++++
>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  92 +++
>>>  drivers/gpu/drm/amd/display/Kconfig           |   6 +
>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  31 +-
>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 120 +++-
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 613 ++++++++++++++++--
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 124 +++-
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 238 +++++++
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |   7 +
>>>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  49 +-
>>>  drivers/gpu/drm/amd/display/dc/dc.h           |   8 +
>>>  .../amd/display/dc/dcn10/dcn10_cm_common.c    | 109 +++-
>>>  .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   5 +-
>>>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   9 +-
>>>  .../amd/display/dc/dcn301/dcn301_resource.c   |  26 +-
>>>  .../gpu/drm/amd/display/include/fixed31_32.h  |  12 +
>>>  drivers/gpu/drm/drm_atomic.c                  |   1 +
>>>  drivers/gpu/drm/drm_atomic_state_helper.c     |   1 +
>>>  include/drm/drm_mode_object.h                 |   2 +-
>>>  include/drm/drm_plane.h                       |   7 +
>>>  20 files changed, 1509 insertions(+), 104 deletions(-)
>>>
>>
>>


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

* Re: [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt
@ 2023-05-09 17:25       ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 17:25 UTC (permalink / raw)
  To: Melissa Wen
  Cc: mripard, Sebastian Wick, linux-kernel, tzimmermann,
	Shashank Sharma, sunpeng.li, maarten.lankhorst, Xinhui.Pan,
	Rodrigo Siqueira, Xaver Hugl, dri-devel, Nicholas Kazlauskas,
	Alex Hung, amd-gfx, daniel, Alex Deucher, airlied,
	christian.koenig, Joshua Ashton, sungjoon.kim



On 5/9/23 12:52, Melissa Wen wrote:
> On 05/08, Harry Wentland wrote:
>>
>>
>> On 4/23/23 10:10, Melissa Wen wrote:
>>> Hi all,
>>>
>>> Joshua Ashton and I (with the great collaboration of Harry Wentland -
>>> thanks) have been working on KMS color pipeline enhancement for Steam
>>> Deck/SteamOS by exposing the large set of color caps available in AMD
>>> display HW.
>>>
>>
>> Thank you for your work on this.
>>
>>> This patchset results from this full-stack work, including pre-blending
>>> and post-blending new color properties. The first two patches fix
>>> quantization issues on shaper LUT programming. Just after, we have one
>>> patch that adds a config option to restrict AMD colo feature usage. The
>>> following 13 patches implement AMD driver-private color properties
>>> (pending detachment of property counter and plane color_mgmt_changed
>>> from DRM). Finally, the last 24 patches rework the AMD display manager
>>> and color management to support the properties exposed.
>>>
>>> In short, for pre-blending, we added the following:
>>> - plane degamma LUT and predefined transfer function;
>>> - plane HDR multiplier
>>> - plane shaper LUT/transfer function;
>>> - plane 3D LUT; and finally,
>>> - plane blend LUT/transfer function, just before blending.
>>>
>>> After blending, we already have DRM CRTC degamma/gamma LUTs and CTM,
>>> therefore, we extend CRTC color pipeline with the following:
>>> - CRTC shaper LUT/transfer function;
>>> - CRTC 3D LUT; and
>>> - CRTC gamma transfer function.
>>>
>>> You can already find the AMD color capabilities and color management
>>> pipeline documented here:
>>> https://dri.freedesktop.org/docs/drm/gpu/amdgpu/display/display-manager.html#color-management-properties
>>>
>>> In previous iterations, we tried to provide a generic solution for
>>> post-blending shaper and 3D LUT [1][2][3], and also Alex Hung worked on
>>> a pre-blending 3D LUT solution[4] extending plane color mgmt proposal
>>> from Uma Shankar [5]. However, we identified during our work [6] that
>>> AMD provides many other valuable capabilities that we don't find in
>>> other vendors, so we started to work on AMD driver-private color
>>> properties that better describe its color pipeline, enabling us to
>>> expose full AMD color capabilities on Deck HW.
>>>
>>> Our primary purpose is to avoid usage limitations of color calibration
>>> features provided by HW just because we don't have an interface for
>>> that. At the same time, a generic solution doesn't fit well since some
>>> of these capabilities seem AMD HW specific, such as hardcoded
>>> curve/predefined transfer function and shaper 1D LUTs sandwiching 3D
>>> LUT.
>>>
>>> So far, we keep these properties' usage under an AMD display config
>>> option (STEAM_DECK). However, we are fine with having them fully
>>> available to other DCN HW generations. In the current proposal, we are
>>> already checking ASICs before exposing a color feature. We can work on
>>> 3D LUT resource acquisition details to fit them to DCN 3+ families that
>>> support them. Indeed, before moving to these config boundaries, we
>>> started working on an open solution for any AMD HW [7].
>>>
>>
>> The problem with a CONFIG_XYZ option is that it becomes uAPI and can't be
>> removed. I feel we have a good proposal going for the generic solution.
>> Would it work for you if we don't make this a CONFIG_ option? What I mean
>> is using
>>
>> #define AMD_PRIVATE_COLOR
>>
>> around the interface bits, which are only compiled when building with
>> -DAMD_PRIVATE_COLOR
> 
> I think we can go with this approach for the properties already in use
> by Gamescope/SteamOS.
>>
>> That way we have the option to rip the driver-private stuff out later
>> while still allowing for experimentation now.
>>
>> Or, alternatively, we can merge everything but the stuff currently
>> guarded by CONFIG_STEAM_DECK, so that custom kernels can enable this
>> functionality by simply merging one patch that includes all the
>> CONFIG_STEAM_DECK stuff.
> 
> An then we can drop the interface of things that Gamescope is not
> managing, but keep those things already programmed on DM color for any
> future usage. What do you think?
> 

Sure.

Harry

> Melissa
> 
>>
>> This will allow us to merge the vast majority of the code without
>> having to maintain it in downstream repo.
>>
>>> The userspace case here is Gamescope which is the compositor for
>>> SteamOS. It's already using all of this functionality (although with a
>>> VALVE1_ prefix instead of AMD) to implement its color management
>>> pipeline right now:
>>> https://github.com/ValveSoftware/gamescope
>>>
>>> We are planning on shipping our color management support with gamut
>>> mapping, HDR, SDR on HDR, HDR on SDR, and much more in Steam OS 3.5. A
>>> brief overview of our color pipeline can be found here:
>>> https://github.com/ValveSoftware/gamescope/blob/master/src/docs/Steam%20Deck%20Display%20Pipeline.png
>>>
>>> We have also had some other userspace interests from Xaver Hugl (KDE) in
>>> experimenting with these properties for their HDR/color bring-up before
>>> a generic interface is settled on also.
>>>
>>> It still needs AMD-specific IGT tests; we are working on documentation
>>> and adding plane CTM support too. 
>>>
>>> We decided first to share our work to collect thoughts and open for
>>> discussion, even with missing refinements, since driver-private
>>> properties are not the usual DMR/KMS color management approach.
>>>
>>> Please, let us know your thoughts.
>>>
>>
>> As discussed at the hackfest I think it's a good idea to have something
>> that's easy to enable for the purposes of experimentation (and to
>> help downstream users that help us figure out how this all fits
>> together, i.e. SteamOS).
>>
>> Harry
>>
>>> Best Regards,
>>>
>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>> Signed-off-by: Melissa Wen<mwen@igalia.com>
>>>
>>> [1] https://lore.kernel.org/dri-devel/20220619223104.667413-1-mwen@igalia.com/
>>> [2] https://lore.kernel.org/amd-gfx/20220906164628.2361811-1-mwen@igalia.com/
>>> [3] https://lore.kernel.org/dri-devel/20230109143846.1966301-1-mwen@igalia.com/
>>> [4] https://lore.kernel.org/dri-devel/20221004211451.1475215-1-alex.hung@amd.com/
>>> [5] https://lore.kernel.org/dri-devel/20210906213904.27918-1-uma.shankar@intel.com/
>>> [6] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-color-mgmt
>>> [7] https://gitlab.freedesktop.org/mwen/linux-amd/-/commits/amd-private-color-mgmt
>>>
>>> Harry Wentland (2):
>>>   drm/amd/display: fix segment distribution for linear LUTs
>>>   drm/amd/display: fix the delta clamping for shaper LUT
>>>
>>> Joshua Ashton (15):
>>>   drm/amd/display: add CRTC gamma TF to driver-private props
>>>   drm/amd/display: add plane degamma LUT driver-private props
>>>   drm/amd/display: add plane degamma TF driver-private property
>>>   drm/amd/display: add plane HDR multiplier driver-private property
>>>   drm/amd/display: add plane blend LUT and TF driver-private properties
>>>   drm/amd/display: copy 3D LUT settings from crtc state to stream_update
>>>   drm/amd/display: dynamically acquire 3DLUT resources for color changes
>>>   drm/amd/display: add CRTC regamma TF support
>>>   drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func
>>>   drm/amd/display: add support for plane degamma TF and LUT properties
>>>   drm/amd/display: add dc_fixpt_from_s3132 helper
>>>   drm/adm/display: add HDR multiplier support
>>>   drm/amd/display: handle empty LUTs in __set_input_tf
>>>   drm/amd/display: add DRM plane blend LUT and TF support
>>>   drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG
>>>
>>> Melissa Wen (23):
>>>   drm/amd/display: introduce Steam Deck color features to AMD display
>>>     driver
>>>   drm/drm_mode_object: increase max objects to accommodate new color
>>>     props
>>>   drm/amd/display: add shaper LUT driver-private props
>>>   drm/amd/display: add 3D LUT driver-private props
>>>   drm/drm_plane: track color mgmt changes per plane
>>>   drm/amd/display: move replace blob func to dm plane
>>>   drm/amd/display: add plane 3D LUT driver-private properties
>>>   drm/amd/display: add plane shaper LUT driver-private properties
>>>   drm/amd/display: add plane shaper TF driver-private property
>>>   drm/amd/display: add comments to describe DM crtc color mgmt behavior
>>>   drm/amd/display: encapsulate atomic regamma operation
>>>   drm/amd/display: update lut3d and shaper lut to stream
>>>   drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings
>>>   drm/amd/display: handle MPC 3D LUT resources for a given context
>>>   drm/amd/display: add CRTC 3D LUT support to amd color pipeline
>>>   drm/amd/display: decouple steps to reuse in CRTC shaper LUT support
>>>   drm/amd/display: add CRTC shaper LUT support to amd color pipeline
>>>   drm/amd/display: add CRTC shaper TF support
>>>   drm/amd/display: mark plane as needing reset if plane color mgmt
>>>     changes
>>>   drm/amd/display: decouple steps for mapping CRTC degamma to DC plane
>>>   drm/amd/display: reject atomic commit if setting both plane and CRTC
>>>     degamma
>>>   drm/amd/display: add plane shaper/3D LUT and shaper TF support
>>>   drm/amd/display: copy dc_plane color settings to surface_updates
>>>
>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 153 +++++
>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  92 +++
>>>  drivers/gpu/drm/amd/display/Kconfig           |   6 +
>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  31 +-
>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 120 +++-
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 613 ++++++++++++++++--
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 124 +++-
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 238 +++++++
>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.h   |   7 +
>>>  drivers/gpu/drm/amd/display/dc/core/dc.c      |  49 +-
>>>  drivers/gpu/drm/amd/display/dc/dc.h           |   8 +
>>>  .../amd/display/dc/dcn10/dcn10_cm_common.c    | 109 +++-
>>>  .../drm/amd/display/dc/dcn20/dcn20_hwseq.c    |   5 +-
>>>  .../drm/amd/display/dc/dcn30/dcn30_hwseq.c    |   9 +-
>>>  .../amd/display/dc/dcn301/dcn301_resource.c   |  26 +-
>>>  .../gpu/drm/amd/display/include/fixed31_32.h  |  12 +
>>>  drivers/gpu/drm/drm_atomic.c                  |   1 +
>>>  drivers/gpu/drm/drm_atomic_state_helper.c     |   1 +
>>>  include/drm/drm_mode_object.h                 |   2 +-
>>>  include/drm/drm_plane.h                       |   7 +
>>>  20 files changed, 1509 insertions(+), 104 deletions(-)
>>>
>>
>>


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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
  2023-05-09 16:54         ` Joshua Ashton
  (?)
@ 2023-05-09 20:00           ` Harry Wentland
  -1 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 20:00 UTC (permalink / raw)
  To: Joshua Ashton, Melissa Wen
  Cc: amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher, dri-devel,
	christian.koenig, Xinhui.Pan, airlied, daniel, Sebastian Wick,
	Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas, sungjoon.kim,
	Alex Hung, linux-kernel

On 5/9/23 12:54, Joshua Ashton wrote:
> We currently do not have a use for this as we settled on per-plane 3D
> LUT + Shaper, but we might end up wanting to use in our scRGB stack
> someday so I would like to keep it.
> 

uAPI should always have a userspace that uses it. But if we go
and put it behind an #ifdef anyways I don't mind taking this
if we foresee use for it in the near future. A gamescope experiment
showing how this can be used to scale sRGB planes would be great.
I assume that's sort of how you intend to use it.

Harry

> On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
>>
>> On 05/08, Harry Wentland wrote:
>>>
>>>
>>> On 4/23/23 10:10, Melissa Wen wrote:
>>>> From: Joshua Ashton <joshua@froggi.es>
>>>>
>>>> Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
>>>> transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
>>>> least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
>>>> nits for SDR content. So if you want, 203 nits for SDR content, pass in
>>>> (203.0 / 80.0).
>>>>
>>>
>>> Is gamescope intending to use this?
>>
>> I don't think so. Again, I'll double check and drop it accordingly.
>>
>> Melissa
>>
>>>
>>> Harry
>>>
>>>> Co-developed-by: Melissa Wen <mwen@igalia.com>
>>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>>> ---
>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
>>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
>>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
>>>>  4 files changed, 41 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>> index 24595906dab1..dd658f162f6f 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>> @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>>>>             return -ENOMEM;
>>>>     adev->mode_info.plane_degamma_tf_property = prop;
>>>>
>>>> +   prop = drm_property_create_range(adev_to_drm(adev),
>>>> +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
>>>> +   if (!prop)
>>>> +           return -ENOMEM;
>>>> +   adev->mode_info.plane_hdr_mult_property = prop;
>>>> +
>>>>     return 0;
>>>>  }
>>>>  #endif
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>> index ab9ce6f26c90..65a9d62ffbe4 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>> @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
>>>>      * linearize content with or without LUT.
>>>>      */
>>>>     struct drm_property *plane_degamma_tf_property;
>>>> +   /**
>>>> +    * @plane_hdr_mult_property:
>>>> +    */
>>>> +   struct drm_property *plane_hdr_mult_property;
>>>>  #endif
>>>>  };
>>>>
>>>> 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 005632c1c9ec..bb7307b9cfd5 100644
>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>> @@ -51,6 +51,7 @@
>>>>
>>>>  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
>>>>
>>>> +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
>>>>  /*
>>>>  #include "include/amdgpu_dal_power_if.h"
>>>>  #include "amdgpu_dm_irq.h"
>>>> @@ -736,6 +737,17 @@ struct dm_plane_state {
>>>>      * linearize.
>>>>      */
>>>>     enum drm_transfer_function degamma_tf;
>>>> +   /**
>>>> +    * @hdr_mult:
>>>> +    *
>>>> +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
>>>> +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
>>>> +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
>>>> +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
>>>> +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
>>>> +    * S31.32 sign-magnitude.
>>>> +    */
>>>> +   __u64 hdr_mult;
>>>>  #endif
>>>>  };
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>> index 5b458cc0781c..57169dae8b3d 100644
>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>> @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
>>>>             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
>>>>
>>>>  #ifdef CONFIG_STEAM_DECK
>>>> -   if (amdgpu_state)
>>>> +   if (amdgpu_state) {
>>>>             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
>>>> +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
>>>> +   }
>>>>  #endif
>>>>  }
>>>>
>>>> @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
>>>>  #ifdef CONFIG_STEAM_DECK
>>>>  int
>>>>  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
>>>> -                                          struct drm_property_blob **blob,
>>>> -                                          uint64_t blob_id,
>>>> -                                          ssize_t expected_size,
>>>> -                                          ssize_t expected_elem_size,
>>>> -                                          bool *replaced)
>>>> +                                   struct drm_property_blob **blob,
>>>> +                                   uint64_t blob_id,
>>>> +                                   ssize_t expected_size,
>>>> +                                   ssize_t expected_elem_size,
>>>> +                                   bool *replaced)
>>>>  {
>>>>     struct drm_property_blob *new_blob = NULL;
>>>>
>>>> @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
>>>>                                        dm->adev->mode_info.plane_degamma_tf_property,
>>>>                                        DRM_TRANSFER_FUNCTION_DEFAULT);
>>>>     }
>>>> +   /* HDR MULT is always available */
>>>> +   drm_object_attach_property(&plane->base,
>>>> +                              dm->adev->mode_info.plane_hdr_mult_property,
>>>> +                              AMDGPU_HDR_MULT_DEFAULT);
>>>>  }
>>>>
>>>>  static int
>>>> @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
>>>>                     dm_plane_state->degamma_tf = val;
>>>>                     dm_plane_state->base.color_mgmt_changed = 1;
>>>>             }
>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>> +           if (dm_plane_state->hdr_mult != val) {
>>>> +                   dm_plane_state->hdr_mult = val;
>>>> +                   dm_plane_state->base.color_mgmt_changed = 1;
>>>> +           }
>>>>     } else {
>>>>             drm_dbg_atomic(plane->dev,
>>>>                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
>>>> @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
>>>>                     dm_plane_state->degamma_lut->base.id : 0;
>>>>     } else if (property == adev->mode_info.plane_degamma_tf_property) {
>>>>             *val = dm_plane_state->degamma_tf;
>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>> +           *val = dm_plane_state->hdr_mult;
>>>>     } else {
>>>>             return -EINVAL;
>>>>     }
>>>
>>>


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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-05-09 20:00           ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 20:00 UTC (permalink / raw)
  To: Joshua Ashton, Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, Alex Deucher,
	christian.koenig, sungjoon.kim

On 5/9/23 12:54, Joshua Ashton wrote:
> We currently do not have a use for this as we settled on per-plane 3D
> LUT + Shaper, but we might end up wanting to use in our scRGB stack
> someday so I would like to keep it.
> 

uAPI should always have a userspace that uses it. But if we go
and put it behind an #ifdef anyways I don't mind taking this
if we foresee use for it in the near future. A gamescope experiment
showing how this can be used to scale sRGB planes would be great.
I assume that's sort of how you intend to use it.

Harry

> On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
>>
>> On 05/08, Harry Wentland wrote:
>>>
>>>
>>> On 4/23/23 10:10, Melissa Wen wrote:
>>>> From: Joshua Ashton <joshua@froggi.es>
>>>>
>>>> Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
>>>> transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
>>>> least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
>>>> nits for SDR content. So if you want, 203 nits for SDR content, pass in
>>>> (203.0 / 80.0).
>>>>
>>>
>>> Is gamescope intending to use this?
>>
>> I don't think so. Again, I'll double check and drop it accordingly.
>>
>> Melissa
>>
>>>
>>> Harry
>>>
>>>> Co-developed-by: Melissa Wen <mwen@igalia.com>
>>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>>> ---
>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
>>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
>>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
>>>>  4 files changed, 41 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>> index 24595906dab1..dd658f162f6f 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>> @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>>>>             return -ENOMEM;
>>>>     adev->mode_info.plane_degamma_tf_property = prop;
>>>>
>>>> +   prop = drm_property_create_range(adev_to_drm(adev),
>>>> +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
>>>> +   if (!prop)
>>>> +           return -ENOMEM;
>>>> +   adev->mode_info.plane_hdr_mult_property = prop;
>>>> +
>>>>     return 0;
>>>>  }
>>>>  #endif
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>> index ab9ce6f26c90..65a9d62ffbe4 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>> @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
>>>>      * linearize content with or without LUT.
>>>>      */
>>>>     struct drm_property *plane_degamma_tf_property;
>>>> +   /**
>>>> +    * @plane_hdr_mult_property:
>>>> +    */
>>>> +   struct drm_property *plane_hdr_mult_property;
>>>>  #endif
>>>>  };
>>>>
>>>> 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 005632c1c9ec..bb7307b9cfd5 100644
>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>> @@ -51,6 +51,7 @@
>>>>
>>>>  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
>>>>
>>>> +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
>>>>  /*
>>>>  #include "include/amdgpu_dal_power_if.h"
>>>>  #include "amdgpu_dm_irq.h"
>>>> @@ -736,6 +737,17 @@ struct dm_plane_state {
>>>>      * linearize.
>>>>      */
>>>>     enum drm_transfer_function degamma_tf;
>>>> +   /**
>>>> +    * @hdr_mult:
>>>> +    *
>>>> +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
>>>> +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
>>>> +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
>>>> +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
>>>> +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
>>>> +    * S31.32 sign-magnitude.
>>>> +    */
>>>> +   __u64 hdr_mult;
>>>>  #endif
>>>>  };
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>> index 5b458cc0781c..57169dae8b3d 100644
>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>> @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
>>>>             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
>>>>
>>>>  #ifdef CONFIG_STEAM_DECK
>>>> -   if (amdgpu_state)
>>>> +   if (amdgpu_state) {
>>>>             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
>>>> +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
>>>> +   }
>>>>  #endif
>>>>  }
>>>>
>>>> @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
>>>>  #ifdef CONFIG_STEAM_DECK
>>>>  int
>>>>  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
>>>> -                                          struct drm_property_blob **blob,
>>>> -                                          uint64_t blob_id,
>>>> -                                          ssize_t expected_size,
>>>> -                                          ssize_t expected_elem_size,
>>>> -                                          bool *replaced)
>>>> +                                   struct drm_property_blob **blob,
>>>> +                                   uint64_t blob_id,
>>>> +                                   ssize_t expected_size,
>>>> +                                   ssize_t expected_elem_size,
>>>> +                                   bool *replaced)
>>>>  {
>>>>     struct drm_property_blob *new_blob = NULL;
>>>>
>>>> @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
>>>>                                        dm->adev->mode_info.plane_degamma_tf_property,
>>>>                                        DRM_TRANSFER_FUNCTION_DEFAULT);
>>>>     }
>>>> +   /* HDR MULT is always available */
>>>> +   drm_object_attach_property(&plane->base,
>>>> +                              dm->adev->mode_info.plane_hdr_mult_property,
>>>> +                              AMDGPU_HDR_MULT_DEFAULT);
>>>>  }
>>>>
>>>>  static int
>>>> @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
>>>>                     dm_plane_state->degamma_tf = val;
>>>>                     dm_plane_state->base.color_mgmt_changed = 1;
>>>>             }
>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>> +           if (dm_plane_state->hdr_mult != val) {
>>>> +                   dm_plane_state->hdr_mult = val;
>>>> +                   dm_plane_state->base.color_mgmt_changed = 1;
>>>> +           }
>>>>     } else {
>>>>             drm_dbg_atomic(plane->dev,
>>>>                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
>>>> @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
>>>>                     dm_plane_state->degamma_lut->base.id : 0;
>>>>     } else if (property == adev->mode_info.plane_degamma_tf_property) {
>>>>             *val = dm_plane_state->degamma_tf;
>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>> +           *val = dm_plane_state->hdr_mult;
>>>>     } else {
>>>>             return -EINVAL;
>>>>     }
>>>
>>>


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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-05-09 20:00           ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 20:00 UTC (permalink / raw)
  To: Joshua Ashton, Melissa Wen
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Alex Hung, amd-gfx, daniel, Alex Deucher,
	airlied, christian.koenig, sungjoon.kim

On 5/9/23 12:54, Joshua Ashton wrote:
> We currently do not have a use for this as we settled on per-plane 3D
> LUT + Shaper, but we might end up wanting to use in our scRGB stack
> someday so I would like to keep it.
> 

uAPI should always have a userspace that uses it. But if we go
and put it behind an #ifdef anyways I don't mind taking this
if we foresee use for it in the near future. A gamescope experiment
showing how this can be used to scale sRGB planes would be great.
I assume that's sort of how you intend to use it.

Harry

> On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
>>
>> On 05/08, Harry Wentland wrote:
>>>
>>>
>>> On 4/23/23 10:10, Melissa Wen wrote:
>>>> From: Joshua Ashton <joshua@froggi.es>
>>>>
>>>> Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
>>>> transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
>>>> least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
>>>> nits for SDR content. So if you want, 203 nits for SDR content, pass in
>>>> (203.0 / 80.0).
>>>>
>>>
>>> Is gamescope intending to use this?
>>
>> I don't think so. Again, I'll double check and drop it accordingly.
>>
>> Melissa
>>
>>>
>>> Harry
>>>
>>>> Co-developed-by: Melissa Wen <mwen@igalia.com>
>>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>>> ---
>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
>>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
>>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
>>>>  4 files changed, 41 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>> index 24595906dab1..dd658f162f6f 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>> @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>>>>             return -ENOMEM;
>>>>     adev->mode_info.plane_degamma_tf_property = prop;
>>>>
>>>> +   prop = drm_property_create_range(adev_to_drm(adev),
>>>> +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
>>>> +   if (!prop)
>>>> +           return -ENOMEM;
>>>> +   adev->mode_info.plane_hdr_mult_property = prop;
>>>> +
>>>>     return 0;
>>>>  }
>>>>  #endif
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>> index ab9ce6f26c90..65a9d62ffbe4 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>> @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
>>>>      * linearize content with or without LUT.
>>>>      */
>>>>     struct drm_property *plane_degamma_tf_property;
>>>> +   /**
>>>> +    * @plane_hdr_mult_property:
>>>> +    */
>>>> +   struct drm_property *plane_hdr_mult_property;
>>>>  #endif
>>>>  };
>>>>
>>>> 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 005632c1c9ec..bb7307b9cfd5 100644
>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>> @@ -51,6 +51,7 @@
>>>>
>>>>  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
>>>>
>>>> +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
>>>>  /*
>>>>  #include "include/amdgpu_dal_power_if.h"
>>>>  #include "amdgpu_dm_irq.h"
>>>> @@ -736,6 +737,17 @@ struct dm_plane_state {
>>>>      * linearize.
>>>>      */
>>>>     enum drm_transfer_function degamma_tf;
>>>> +   /**
>>>> +    * @hdr_mult:
>>>> +    *
>>>> +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
>>>> +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
>>>> +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
>>>> +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
>>>> +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
>>>> +    * S31.32 sign-magnitude.
>>>> +    */
>>>> +   __u64 hdr_mult;
>>>>  #endif
>>>>  };
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>> index 5b458cc0781c..57169dae8b3d 100644
>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>> @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
>>>>             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
>>>>
>>>>  #ifdef CONFIG_STEAM_DECK
>>>> -   if (amdgpu_state)
>>>> +   if (amdgpu_state) {
>>>>             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
>>>> +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
>>>> +   }
>>>>  #endif
>>>>  }
>>>>
>>>> @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
>>>>  #ifdef CONFIG_STEAM_DECK
>>>>  int
>>>>  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
>>>> -                                          struct drm_property_blob **blob,
>>>> -                                          uint64_t blob_id,
>>>> -                                          ssize_t expected_size,
>>>> -                                          ssize_t expected_elem_size,
>>>> -                                          bool *replaced)
>>>> +                                   struct drm_property_blob **blob,
>>>> +                                   uint64_t blob_id,
>>>> +                                   ssize_t expected_size,
>>>> +                                   ssize_t expected_elem_size,
>>>> +                                   bool *replaced)
>>>>  {
>>>>     struct drm_property_blob *new_blob = NULL;
>>>>
>>>> @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
>>>>                                        dm->adev->mode_info.plane_degamma_tf_property,
>>>>                                        DRM_TRANSFER_FUNCTION_DEFAULT);
>>>>     }
>>>> +   /* HDR MULT is always available */
>>>> +   drm_object_attach_property(&plane->base,
>>>> +                              dm->adev->mode_info.plane_hdr_mult_property,
>>>> +                              AMDGPU_HDR_MULT_DEFAULT);
>>>>  }
>>>>
>>>>  static int
>>>> @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
>>>>                     dm_plane_state->degamma_tf = val;
>>>>                     dm_plane_state->base.color_mgmt_changed = 1;
>>>>             }
>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>> +           if (dm_plane_state->hdr_mult != val) {
>>>> +                   dm_plane_state->hdr_mult = val;
>>>> +                   dm_plane_state->base.color_mgmt_changed = 1;
>>>> +           }
>>>>     } else {
>>>>             drm_dbg_atomic(plane->dev,
>>>>                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
>>>> @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
>>>>                     dm_plane_state->degamma_lut->base.id : 0;
>>>>     } else if (property == adev->mode_info.plane_degamma_tf_property) {
>>>>             *val = dm_plane_state->degamma_tf;
>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>> +           *val = dm_plane_state->hdr_mult;
>>>>     } else {
>>>>             return -EINVAL;
>>>>     }
>>>
>>>


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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
  2023-05-09 20:00           ` Harry Wentland
  (?)
@ 2023-05-09 20:35             ` Joshua Ashton
  -1 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 20:35 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel,
	Sebastian Wick, Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas,
	sungjoon.kim, Alex Hung, linux-kernel

FWIW, we technically do use it right now, but it is always set to 1 in S.31.32.

Before we used shaper + 3D LUT we did use it for scaling SDR content,
but given we always have a shaper + 3D LUT it made sense for us to
roll that into there.

On Tue, 9 May 2023 at 20:00, Harry Wentland <harry.wentland@amd.com> wrote:
>
> On 5/9/23 12:54, Joshua Ashton wrote:
> > We currently do not have a use for this as we settled on per-plane 3D
> > LUT + Shaper, but we might end up wanting to use in our scRGB stack
> > someday so I would like to keep it.
> >
>
> uAPI should always have a userspace that uses it. But if we go
> and put it behind an #ifdef anyways I don't mind taking this
> if we foresee use for it in the near future. A gamescope experiment
> showing how this can be used to scale sRGB planes would be great.
> I assume that's sort of how you intend to use it.
>
> Harry
>
> > On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
> >>
> >> On 05/08, Harry Wentland wrote:
> >>>
> >>>
> >>> On 4/23/23 10:10, Melissa Wen wrote:
> >>>> From: Joshua Ashton <joshua@froggi.es>
> >>>>
> >>>> Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
> >>>> transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
> >>>> least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
> >>>> nits for SDR content. So if you want, 203 nits for SDR content, pass in
> >>>> (203.0 / 80.0).
> >>>>
> >>>
> >>> Is gamescope intending to use this?
> >>
> >> I don't think so. Again, I'll double check and drop it accordingly.
> >>
> >> Melissa
> >>
> >>>
> >>> Harry
> >>>
> >>>> Co-developed-by: Melissa Wen <mwen@igalia.com>
> >>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
> >>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
> >>>> ---
> >>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
> >>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
> >>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
> >>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
> >>>>  4 files changed, 41 insertions(+), 6 deletions(-)
> >>>>
> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> >>>> index 24595906dab1..dd658f162f6f 100644
> >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> >>>> @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >>>>             return -ENOMEM;
> >>>>     adev->mode_info.plane_degamma_tf_property = prop;
> >>>>
> >>>> +   prop = drm_property_create_range(adev_to_drm(adev),
> >>>> +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
> >>>> +   if (!prop)
> >>>> +           return -ENOMEM;
> >>>> +   adev->mode_info.plane_hdr_mult_property = prop;
> >>>> +
> >>>>     return 0;
> >>>>  }
> >>>>  #endif
> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> >>>> index ab9ce6f26c90..65a9d62ffbe4 100644
> >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> >>>> @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
> >>>>      * linearize content with or without LUT.
> >>>>      */
> >>>>     struct drm_property *plane_degamma_tf_property;
> >>>> +   /**
> >>>> +    * @plane_hdr_mult_property:
> >>>> +    */
> >>>> +   struct drm_property *plane_hdr_mult_property;
> >>>>  #endif
> >>>>  };
> >>>>
> >>>> 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 005632c1c9ec..bb7307b9cfd5 100644
> >>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> >>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> >>>> @@ -51,6 +51,7 @@
> >>>>
> >>>>  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
> >>>>
> >>>> +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
> >>>>  /*
> >>>>  #include "include/amdgpu_dal_power_if.h"
> >>>>  #include "amdgpu_dm_irq.h"
> >>>> @@ -736,6 +737,17 @@ struct dm_plane_state {
> >>>>      * linearize.
> >>>>      */
> >>>>     enum drm_transfer_function degamma_tf;
> >>>> +   /**
> >>>> +    * @hdr_mult:
> >>>> +    *
> >>>> +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
> >>>> +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
> >>>> +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
> >>>> +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
> >>>> +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
> >>>> +    * S31.32 sign-magnitude.
> >>>> +    */
> >>>> +   __u64 hdr_mult;
> >>>>  #endif
> >>>>  };
> >>>>
> >>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> >>>> index 5b458cc0781c..57169dae8b3d 100644
> >>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> >>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> >>>> @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
> >>>>             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
> >>>>
> >>>>  #ifdef CONFIG_STEAM_DECK
> >>>> -   if (amdgpu_state)
> >>>> +   if (amdgpu_state) {
> >>>>             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
> >>>> +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> >>>> +   }
> >>>>  #endif
> >>>>  }
> >>>>
> >>>> @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> >>>>  #ifdef CONFIG_STEAM_DECK
> >>>>  int
> >>>>  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> >>>> -                                          struct drm_property_blob **blob,
> >>>> -                                          uint64_t blob_id,
> >>>> -                                          ssize_t expected_size,
> >>>> -                                          ssize_t expected_elem_size,
> >>>> -                                          bool *replaced)
> >>>> +                                   struct drm_property_blob **blob,
> >>>> +                                   uint64_t blob_id,
> >>>> +                                   ssize_t expected_size,
> >>>> +                                   ssize_t expected_elem_size,
> >>>> +                                   bool *replaced)
> >>>>  {
> >>>>     struct drm_property_blob *new_blob = NULL;
> >>>>
> >>>> @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
> >>>>                                        dm->adev->mode_info.plane_degamma_tf_property,
> >>>>                                        DRM_TRANSFER_FUNCTION_DEFAULT);
> >>>>     }
> >>>> +   /* HDR MULT is always available */
> >>>> +   drm_object_attach_property(&plane->base,
> >>>> +                              dm->adev->mode_info.plane_hdr_mult_property,
> >>>> +                              AMDGPU_HDR_MULT_DEFAULT);
> >>>>  }
> >>>>
> >>>>  static int
> >>>> @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
> >>>>                     dm_plane_state->degamma_tf = val;
> >>>>                     dm_plane_state->base.color_mgmt_changed = 1;
> >>>>             }
> >>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> >>>> +           if (dm_plane_state->hdr_mult != val) {
> >>>> +                   dm_plane_state->hdr_mult = val;
> >>>> +                   dm_plane_state->base.color_mgmt_changed = 1;
> >>>> +           }
> >>>>     } else {
> >>>>             drm_dbg_atomic(plane->dev,
> >>>>                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
> >>>> @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
> >>>>                     dm_plane_state->degamma_lut->base.id : 0;
> >>>>     } else if (property == adev->mode_info.plane_degamma_tf_property) {
> >>>>             *val = dm_plane_state->degamma_tf;
> >>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> >>>> +           *val = dm_plane_state->hdr_mult;
> >>>>     } else {
> >>>>             return -EINVAL;
> >>>>     }
> >>>
> >>>
>

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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-05-09 20:35             ` Joshua Ashton
  0 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 20:35 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Melissa Wen, Alex Hung, amd-gfx,
	Alex Deucher, christian.koenig, sungjoon.kim

FWIW, we technically do use it right now, but it is always set to 1 in S.31.32.

Before we used shaper + 3D LUT we did use it for scaling SDR content,
but given we always have a shaper + 3D LUT it made sense for us to
roll that into there.

On Tue, 9 May 2023 at 20:00, Harry Wentland <harry.wentland@amd.com> wrote:
>
> On 5/9/23 12:54, Joshua Ashton wrote:
> > We currently do not have a use for this as we settled on per-plane 3D
> > LUT + Shaper, but we might end up wanting to use in our scRGB stack
> > someday so I would like to keep it.
> >
>
> uAPI should always have a userspace that uses it. But if we go
> and put it behind an #ifdef anyways I don't mind taking this
> if we foresee use for it in the near future. A gamescope experiment
> showing how this can be used to scale sRGB planes would be great.
> I assume that's sort of how you intend to use it.
>
> Harry
>
> > On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
> >>
> >> On 05/08, Harry Wentland wrote:
> >>>
> >>>
> >>> On 4/23/23 10:10, Melissa Wen wrote:
> >>>> From: Joshua Ashton <joshua@froggi.es>
> >>>>
> >>>> Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
> >>>> transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
> >>>> least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
> >>>> nits for SDR content. So if you want, 203 nits for SDR content, pass in
> >>>> (203.0 / 80.0).
> >>>>
> >>>
> >>> Is gamescope intending to use this?
> >>
> >> I don't think so. Again, I'll double check and drop it accordingly.
> >>
> >> Melissa
> >>
> >>>
> >>> Harry
> >>>
> >>>> Co-developed-by: Melissa Wen <mwen@igalia.com>
> >>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
> >>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
> >>>> ---
> >>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
> >>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
> >>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
> >>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
> >>>>  4 files changed, 41 insertions(+), 6 deletions(-)
> >>>>
> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> >>>> index 24595906dab1..dd658f162f6f 100644
> >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> >>>> @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >>>>             return -ENOMEM;
> >>>>     adev->mode_info.plane_degamma_tf_property = prop;
> >>>>
> >>>> +   prop = drm_property_create_range(adev_to_drm(adev),
> >>>> +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
> >>>> +   if (!prop)
> >>>> +           return -ENOMEM;
> >>>> +   adev->mode_info.plane_hdr_mult_property = prop;
> >>>> +
> >>>>     return 0;
> >>>>  }
> >>>>  #endif
> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> >>>> index ab9ce6f26c90..65a9d62ffbe4 100644
> >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> >>>> @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
> >>>>      * linearize content with or without LUT.
> >>>>      */
> >>>>     struct drm_property *plane_degamma_tf_property;
> >>>> +   /**
> >>>> +    * @plane_hdr_mult_property:
> >>>> +    */
> >>>> +   struct drm_property *plane_hdr_mult_property;
> >>>>  #endif
> >>>>  };
> >>>>
> >>>> 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 005632c1c9ec..bb7307b9cfd5 100644
> >>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> >>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> >>>> @@ -51,6 +51,7 @@
> >>>>
> >>>>  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
> >>>>
> >>>> +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
> >>>>  /*
> >>>>  #include "include/amdgpu_dal_power_if.h"
> >>>>  #include "amdgpu_dm_irq.h"
> >>>> @@ -736,6 +737,17 @@ struct dm_plane_state {
> >>>>      * linearize.
> >>>>      */
> >>>>     enum drm_transfer_function degamma_tf;
> >>>> +   /**
> >>>> +    * @hdr_mult:
> >>>> +    *
> >>>> +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
> >>>> +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
> >>>> +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
> >>>> +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
> >>>> +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
> >>>> +    * S31.32 sign-magnitude.
> >>>> +    */
> >>>> +   __u64 hdr_mult;
> >>>>  #endif
> >>>>  };
> >>>>
> >>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> >>>> index 5b458cc0781c..57169dae8b3d 100644
> >>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> >>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> >>>> @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
> >>>>             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
> >>>>
> >>>>  #ifdef CONFIG_STEAM_DECK
> >>>> -   if (amdgpu_state)
> >>>> +   if (amdgpu_state) {
> >>>>             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
> >>>> +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> >>>> +   }
> >>>>  #endif
> >>>>  }
> >>>>
> >>>> @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> >>>>  #ifdef CONFIG_STEAM_DECK
> >>>>  int
> >>>>  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> >>>> -                                          struct drm_property_blob **blob,
> >>>> -                                          uint64_t blob_id,
> >>>> -                                          ssize_t expected_size,
> >>>> -                                          ssize_t expected_elem_size,
> >>>> -                                          bool *replaced)
> >>>> +                                   struct drm_property_blob **blob,
> >>>> +                                   uint64_t blob_id,
> >>>> +                                   ssize_t expected_size,
> >>>> +                                   ssize_t expected_elem_size,
> >>>> +                                   bool *replaced)
> >>>>  {
> >>>>     struct drm_property_blob *new_blob = NULL;
> >>>>
> >>>> @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
> >>>>                                        dm->adev->mode_info.plane_degamma_tf_property,
> >>>>                                        DRM_TRANSFER_FUNCTION_DEFAULT);
> >>>>     }
> >>>> +   /* HDR MULT is always available */
> >>>> +   drm_object_attach_property(&plane->base,
> >>>> +                              dm->adev->mode_info.plane_hdr_mult_property,
> >>>> +                              AMDGPU_HDR_MULT_DEFAULT);
> >>>>  }
> >>>>
> >>>>  static int
> >>>> @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
> >>>>                     dm_plane_state->degamma_tf = val;
> >>>>                     dm_plane_state->base.color_mgmt_changed = 1;
> >>>>             }
> >>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> >>>> +           if (dm_plane_state->hdr_mult != val) {
> >>>> +                   dm_plane_state->hdr_mult = val;
> >>>> +                   dm_plane_state->base.color_mgmt_changed = 1;
> >>>> +           }
> >>>>     } else {
> >>>>             drm_dbg_atomic(plane->dev,
> >>>>                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
> >>>> @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
> >>>>                     dm_plane_state->degamma_lut->base.id : 0;
> >>>>     } else if (property == adev->mode_info.plane_degamma_tf_property) {
> >>>>             *val = dm_plane_state->degamma_tf;
> >>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> >>>> +           *val = dm_plane_state->hdr_mult;
> >>>>     } else {
> >>>>             return -EINVAL;
> >>>>     }
> >>>
> >>>
>

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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-05-09 20:35             ` Joshua Ashton
  0 siblings, 0 replies; 141+ messages in thread
From: Joshua Ashton @ 2023-05-09 20:35 UTC (permalink / raw)
  To: Harry Wentland
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Melissa Wen, Alex Hung, amd-gfx, daniel,
	Alex Deucher, airlied, christian.koenig, sungjoon.kim

FWIW, we technically do use it right now, but it is always set to 1 in S.31.32.

Before we used shaper + 3D LUT we did use it for scaling SDR content,
but given we always have a shaper + 3D LUT it made sense for us to
roll that into there.

On Tue, 9 May 2023 at 20:00, Harry Wentland <harry.wentland@amd.com> wrote:
>
> On 5/9/23 12:54, Joshua Ashton wrote:
> > We currently do not have a use for this as we settled on per-plane 3D
> > LUT + Shaper, but we might end up wanting to use in our scRGB stack
> > someday so I would like to keep it.
> >
>
> uAPI should always have a userspace that uses it. But if we go
> and put it behind an #ifdef anyways I don't mind taking this
> if we foresee use for it in the near future. A gamescope experiment
> showing how this can be used to scale sRGB planes would be great.
> I assume that's sort of how you intend to use it.
>
> Harry
>
> > On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
> >>
> >> On 05/08, Harry Wentland wrote:
> >>>
> >>>
> >>> On 4/23/23 10:10, Melissa Wen wrote:
> >>>> From: Joshua Ashton <joshua@froggi.es>
> >>>>
> >>>> Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
> >>>> transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
> >>>> least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
> >>>> nits for SDR content. So if you want, 203 nits for SDR content, pass in
> >>>> (203.0 / 80.0).
> >>>>
> >>>
> >>> Is gamescope intending to use this?
> >>
> >> I don't think so. Again, I'll double check and drop it accordingly.
> >>
> >> Melissa
> >>
> >>>
> >>> Harry
> >>>
> >>>> Co-developed-by: Melissa Wen <mwen@igalia.com>
> >>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
> >>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
> >>>> ---
> >>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
> >>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
> >>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
> >>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
> >>>>  4 files changed, 41 insertions(+), 6 deletions(-)
> >>>>
> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> >>>> index 24595906dab1..dd658f162f6f 100644
> >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> >>>> @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
> >>>>             return -ENOMEM;
> >>>>     adev->mode_info.plane_degamma_tf_property = prop;
> >>>>
> >>>> +   prop = drm_property_create_range(adev_to_drm(adev),
> >>>> +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
> >>>> +   if (!prop)
> >>>> +           return -ENOMEM;
> >>>> +   adev->mode_info.plane_hdr_mult_property = prop;
> >>>> +
> >>>>     return 0;
> >>>>  }
> >>>>  #endif
> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> >>>> index ab9ce6f26c90..65a9d62ffbe4 100644
> >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
> >>>> @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
> >>>>      * linearize content with or without LUT.
> >>>>      */
> >>>>     struct drm_property *plane_degamma_tf_property;
> >>>> +   /**
> >>>> +    * @plane_hdr_mult_property:
> >>>> +    */
> >>>> +   struct drm_property *plane_hdr_mult_property;
> >>>>  #endif
> >>>>  };
> >>>>
> >>>> 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 005632c1c9ec..bb7307b9cfd5 100644
> >>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> >>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
> >>>> @@ -51,6 +51,7 @@
> >>>>
> >>>>  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
> >>>>
> >>>> +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
> >>>>  /*
> >>>>  #include "include/amdgpu_dal_power_if.h"
> >>>>  #include "amdgpu_dm_irq.h"
> >>>> @@ -736,6 +737,17 @@ struct dm_plane_state {
> >>>>      * linearize.
> >>>>      */
> >>>>     enum drm_transfer_function degamma_tf;
> >>>> +   /**
> >>>> +    * @hdr_mult:
> >>>> +    *
> >>>> +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
> >>>> +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
> >>>> +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
> >>>> +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
> >>>> +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
> >>>> +    * S31.32 sign-magnitude.
> >>>> +    */
> >>>> +   __u64 hdr_mult;
> >>>>  #endif
> >>>>  };
> >>>>
> >>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> >>>> index 5b458cc0781c..57169dae8b3d 100644
> >>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> >>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
> >>>> @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
> >>>>             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
> >>>>
> >>>>  #ifdef CONFIG_STEAM_DECK
> >>>> -   if (amdgpu_state)
> >>>> +   if (amdgpu_state) {
> >>>>             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
> >>>> +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
> >>>> +   }
> >>>>  #endif
> >>>>  }
> >>>>
> >>>> @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
> >>>>  #ifdef CONFIG_STEAM_DECK
> >>>>  int
> >>>>  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
> >>>> -                                          struct drm_property_blob **blob,
> >>>> -                                          uint64_t blob_id,
> >>>> -                                          ssize_t expected_size,
> >>>> -                                          ssize_t expected_elem_size,
> >>>> -                                          bool *replaced)
> >>>> +                                   struct drm_property_blob **blob,
> >>>> +                                   uint64_t blob_id,
> >>>> +                                   ssize_t expected_size,
> >>>> +                                   ssize_t expected_elem_size,
> >>>> +                                   bool *replaced)
> >>>>  {
> >>>>     struct drm_property_blob *new_blob = NULL;
> >>>>
> >>>> @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
> >>>>                                        dm->adev->mode_info.plane_degamma_tf_property,
> >>>>                                        DRM_TRANSFER_FUNCTION_DEFAULT);
> >>>>     }
> >>>> +   /* HDR MULT is always available */
> >>>> +   drm_object_attach_property(&plane->base,
> >>>> +                              dm->adev->mode_info.plane_hdr_mult_property,
> >>>> +                              AMDGPU_HDR_MULT_DEFAULT);
> >>>>  }
> >>>>
> >>>>  static int
> >>>> @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
> >>>>                     dm_plane_state->degamma_tf = val;
> >>>>                     dm_plane_state->base.color_mgmt_changed = 1;
> >>>>             }
> >>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> >>>> +           if (dm_plane_state->hdr_mult != val) {
> >>>> +                   dm_plane_state->hdr_mult = val;
> >>>> +                   dm_plane_state->base.color_mgmt_changed = 1;
> >>>> +           }
> >>>>     } else {
> >>>>             drm_dbg_atomic(plane->dev,
> >>>>                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
> >>>> @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
> >>>>                     dm_plane_state->degamma_lut->base.id : 0;
> >>>>     } else if (property == adev->mode_info.plane_degamma_tf_property) {
> >>>>             *val = dm_plane_state->degamma_tf;
> >>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
> >>>> +           *val = dm_plane_state->hdr_mult;
> >>>>     } else {
> >>>>             return -EINVAL;
> >>>>     }
> >>>
> >>>
>

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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
  2023-05-09 20:35             ` Joshua Ashton
  (?)
@ 2023-05-09 22:55               ` Harry Wentland
  -1 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 22:55 UTC (permalink / raw)
  To: Joshua Ashton
  Cc: Melissa Wen, amd-gfx, Rodrigo Siqueira, sunpeng.li, Alex Deucher,
	dri-devel, christian.koenig, Xinhui.Pan, airlied, daniel,
	Sebastian Wick, Xaver Hugl, Shashank Sharma, Nicholas Kazlauskas,
	sungjoon.kim, Alex Hung, linux-kernel



On 5/9/23 16:35, Joshua Ashton wrote:
> FWIW, we technically do use it right now, but it is always set to 1 in S.31.32.
> 
> Before we used shaper + 3D LUT we did use it for scaling SDR content,
> but given we always have a shaper + 3D LUT it made sense for us to
> roll that into there.
> 

Ah, that's good. No problem then.

Harry

> On Tue, 9 May 2023 at 20:00, Harry Wentland <harry.wentland@amd.com> wrote:
>>
>> On 5/9/23 12:54, Joshua Ashton wrote:
>>> We currently do not have a use for this as we settled on per-plane 3D
>>> LUT + Shaper, but we might end up wanting to use in our scRGB stack
>>> someday so I would like to keep it.
>>>
>>
>> uAPI should always have a userspace that uses it. But if we go
>> and put it behind an #ifdef anyways I don't mind taking this
>> if we foresee use for it in the near future. A gamescope experiment
>> showing how this can be used to scale sRGB planes would be great.
>> I assume that's sort of how you intend to use it.
>>
>> Harry
>>
>>> On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
>>>>
>>>> On 05/08, Harry Wentland wrote:
>>>>>
>>>>>
>>>>> On 4/23/23 10:10, Melissa Wen wrote:
>>>>>> From: Joshua Ashton <joshua@froggi.es>
>>>>>>
>>>>>> Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
>>>>>> transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
>>>>>> least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
>>>>>> nits for SDR content. So if you want, 203 nits for SDR content, pass in
>>>>>> (203.0 / 80.0).
>>>>>>
>>>>>
>>>>> Is gamescope intending to use this?
>>>>
>>>> I don't think so. Again, I'll double check and drop it accordingly.
>>>>
>>>> Melissa
>>>>
>>>>>
>>>>> Harry
>>>>>
>>>>>> Co-developed-by: Melissa Wen <mwen@igalia.com>
>>>>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>>>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>>>>> ---
>>>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
>>>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
>>>>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
>>>>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
>>>>>>  4 files changed, 41 insertions(+), 6 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>>>> index 24595906dab1..dd658f162f6f 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>>>> @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>>>>>>             return -ENOMEM;
>>>>>>     adev->mode_info.plane_degamma_tf_property = prop;
>>>>>>
>>>>>> +   prop = drm_property_create_range(adev_to_drm(adev),
>>>>>> +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
>>>>>> +   if (!prop)
>>>>>> +           return -ENOMEM;
>>>>>> +   adev->mode_info.plane_hdr_mult_property = prop;
>>>>>> +
>>>>>>     return 0;
>>>>>>  }
>>>>>>  #endif
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>>>> index ab9ce6f26c90..65a9d62ffbe4 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>>>> @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
>>>>>>      * linearize content with or without LUT.
>>>>>>      */
>>>>>>     struct drm_property *plane_degamma_tf_property;
>>>>>> +   /**
>>>>>> +    * @plane_hdr_mult_property:
>>>>>> +    */
>>>>>> +   struct drm_property *plane_hdr_mult_property;
>>>>>>  #endif
>>>>>>  };
>>>>>>
>>>>>> 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 005632c1c9ec..bb7307b9cfd5 100644
>>>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>>>> @@ -51,6 +51,7 @@
>>>>>>
>>>>>>  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
>>>>>>
>>>>>> +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
>>>>>>  /*
>>>>>>  #include "include/amdgpu_dal_power_if.h"
>>>>>>  #include "amdgpu_dm_irq.h"
>>>>>> @@ -736,6 +737,17 @@ struct dm_plane_state {
>>>>>>      * linearize.
>>>>>>      */
>>>>>>     enum drm_transfer_function degamma_tf;
>>>>>> +   /**
>>>>>> +    * @hdr_mult:
>>>>>> +    *
>>>>>> +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
>>>>>> +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
>>>>>> +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
>>>>>> +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
>>>>>> +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
>>>>>> +    * S31.32 sign-magnitude.
>>>>>> +    */
>>>>>> +   __u64 hdr_mult;
>>>>>>  #endif
>>>>>>  };
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>>>> index 5b458cc0781c..57169dae8b3d 100644
>>>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>>>> @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
>>>>>>             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
>>>>>>
>>>>>>  #ifdef CONFIG_STEAM_DECK
>>>>>> -   if (amdgpu_state)
>>>>>> +   if (amdgpu_state) {
>>>>>>             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
>>>>>> +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
>>>>>> +   }
>>>>>>  #endif
>>>>>>  }
>>>>>>
>>>>>> @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
>>>>>>  #ifdef CONFIG_STEAM_DECK
>>>>>>  int
>>>>>>  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
>>>>>> -                                          struct drm_property_blob **blob,
>>>>>> -                                          uint64_t blob_id,
>>>>>> -                                          ssize_t expected_size,
>>>>>> -                                          ssize_t expected_elem_size,
>>>>>> -                                          bool *replaced)
>>>>>> +                                   struct drm_property_blob **blob,
>>>>>> +                                   uint64_t blob_id,
>>>>>> +                                   ssize_t expected_size,
>>>>>> +                                   ssize_t expected_elem_size,
>>>>>> +                                   bool *replaced)
>>>>>>  {
>>>>>>     struct drm_property_blob *new_blob = NULL;
>>>>>>
>>>>>> @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
>>>>>>                                        dm->adev->mode_info.plane_degamma_tf_property,
>>>>>>                                        DRM_TRANSFER_FUNCTION_DEFAULT);
>>>>>>     }
>>>>>> +   /* HDR MULT is always available */
>>>>>> +   drm_object_attach_property(&plane->base,
>>>>>> +                              dm->adev->mode_info.plane_hdr_mult_property,
>>>>>> +                              AMDGPU_HDR_MULT_DEFAULT);
>>>>>>  }
>>>>>>
>>>>>>  static int
>>>>>> @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
>>>>>>                     dm_plane_state->degamma_tf = val;
>>>>>>                     dm_plane_state->base.color_mgmt_changed = 1;
>>>>>>             }
>>>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>>>> +           if (dm_plane_state->hdr_mult != val) {
>>>>>> +                   dm_plane_state->hdr_mult = val;
>>>>>> +                   dm_plane_state->base.color_mgmt_changed = 1;
>>>>>> +           }
>>>>>>     } else {
>>>>>>             drm_dbg_atomic(plane->dev,
>>>>>>                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
>>>>>> @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
>>>>>>                     dm_plane_state->degamma_lut->base.id : 0;
>>>>>>     } else if (property == adev->mode_info.plane_degamma_tf_property) {
>>>>>>             *val = dm_plane_state->degamma_tf;
>>>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>>>> +           *val = dm_plane_state->hdr_mult;
>>>>>>     } else {
>>>>>>             return -EINVAL;
>>>>>>     }
>>>>>
>>>>>
>>


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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-05-09 22:55               ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 22:55 UTC (permalink / raw)
  To: Joshua Ashton
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Melissa Wen, Alex Hung, amd-gfx,
	Alex Deucher, christian.koenig, sungjoon.kim



On 5/9/23 16:35, Joshua Ashton wrote:
> FWIW, we technically do use it right now, but it is always set to 1 in S.31.32.
> 
> Before we used shaper + 3D LUT we did use it for scaling SDR content,
> but given we always have a shaper + 3D LUT it made sense for us to
> roll that into there.
> 

Ah, that's good. No problem then.

Harry

> On Tue, 9 May 2023 at 20:00, Harry Wentland <harry.wentland@amd.com> wrote:
>>
>> On 5/9/23 12:54, Joshua Ashton wrote:
>>> We currently do not have a use for this as we settled on per-plane 3D
>>> LUT + Shaper, but we might end up wanting to use in our scRGB stack
>>> someday so I would like to keep it.
>>>
>>
>> uAPI should always have a userspace that uses it. But if we go
>> and put it behind an #ifdef anyways I don't mind taking this
>> if we foresee use for it in the near future. A gamescope experiment
>> showing how this can be used to scale sRGB planes would be great.
>> I assume that's sort of how you intend to use it.
>>
>> Harry
>>
>>> On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
>>>>
>>>> On 05/08, Harry Wentland wrote:
>>>>>
>>>>>
>>>>> On 4/23/23 10:10, Melissa Wen wrote:
>>>>>> From: Joshua Ashton <joshua@froggi.es>
>>>>>>
>>>>>> Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
>>>>>> transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
>>>>>> least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
>>>>>> nits for SDR content. So if you want, 203 nits for SDR content, pass in
>>>>>> (203.0 / 80.0).
>>>>>>
>>>>>
>>>>> Is gamescope intending to use this?
>>>>
>>>> I don't think so. Again, I'll double check and drop it accordingly.
>>>>
>>>> Melissa
>>>>
>>>>>
>>>>> Harry
>>>>>
>>>>>> Co-developed-by: Melissa Wen <mwen@igalia.com>
>>>>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>>>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>>>>> ---
>>>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
>>>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
>>>>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
>>>>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
>>>>>>  4 files changed, 41 insertions(+), 6 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>>>> index 24595906dab1..dd658f162f6f 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>>>> @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>>>>>>             return -ENOMEM;
>>>>>>     adev->mode_info.plane_degamma_tf_property = prop;
>>>>>>
>>>>>> +   prop = drm_property_create_range(adev_to_drm(adev),
>>>>>> +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
>>>>>> +   if (!prop)
>>>>>> +           return -ENOMEM;
>>>>>> +   adev->mode_info.plane_hdr_mult_property = prop;
>>>>>> +
>>>>>>     return 0;
>>>>>>  }
>>>>>>  #endif
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>>>> index ab9ce6f26c90..65a9d62ffbe4 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>>>> @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
>>>>>>      * linearize content with or without LUT.
>>>>>>      */
>>>>>>     struct drm_property *plane_degamma_tf_property;
>>>>>> +   /**
>>>>>> +    * @plane_hdr_mult_property:
>>>>>> +    */
>>>>>> +   struct drm_property *plane_hdr_mult_property;
>>>>>>  #endif
>>>>>>  };
>>>>>>
>>>>>> 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 005632c1c9ec..bb7307b9cfd5 100644
>>>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>>>> @@ -51,6 +51,7 @@
>>>>>>
>>>>>>  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
>>>>>>
>>>>>> +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
>>>>>>  /*
>>>>>>  #include "include/amdgpu_dal_power_if.h"
>>>>>>  #include "amdgpu_dm_irq.h"
>>>>>> @@ -736,6 +737,17 @@ struct dm_plane_state {
>>>>>>      * linearize.
>>>>>>      */
>>>>>>     enum drm_transfer_function degamma_tf;
>>>>>> +   /**
>>>>>> +    * @hdr_mult:
>>>>>> +    *
>>>>>> +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
>>>>>> +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
>>>>>> +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
>>>>>> +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
>>>>>> +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
>>>>>> +    * S31.32 sign-magnitude.
>>>>>> +    */
>>>>>> +   __u64 hdr_mult;
>>>>>>  #endif
>>>>>>  };
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>>>> index 5b458cc0781c..57169dae8b3d 100644
>>>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>>>> @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
>>>>>>             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
>>>>>>
>>>>>>  #ifdef CONFIG_STEAM_DECK
>>>>>> -   if (amdgpu_state)
>>>>>> +   if (amdgpu_state) {
>>>>>>             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
>>>>>> +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
>>>>>> +   }
>>>>>>  #endif
>>>>>>  }
>>>>>>
>>>>>> @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
>>>>>>  #ifdef CONFIG_STEAM_DECK
>>>>>>  int
>>>>>>  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
>>>>>> -                                          struct drm_property_blob **blob,
>>>>>> -                                          uint64_t blob_id,
>>>>>> -                                          ssize_t expected_size,
>>>>>> -                                          ssize_t expected_elem_size,
>>>>>> -                                          bool *replaced)
>>>>>> +                                   struct drm_property_blob **blob,
>>>>>> +                                   uint64_t blob_id,
>>>>>> +                                   ssize_t expected_size,
>>>>>> +                                   ssize_t expected_elem_size,
>>>>>> +                                   bool *replaced)
>>>>>>  {
>>>>>>     struct drm_property_blob *new_blob = NULL;
>>>>>>
>>>>>> @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
>>>>>>                                        dm->adev->mode_info.plane_degamma_tf_property,
>>>>>>                                        DRM_TRANSFER_FUNCTION_DEFAULT);
>>>>>>     }
>>>>>> +   /* HDR MULT is always available */
>>>>>> +   drm_object_attach_property(&plane->base,
>>>>>> +                              dm->adev->mode_info.plane_hdr_mult_property,
>>>>>> +                              AMDGPU_HDR_MULT_DEFAULT);
>>>>>>  }
>>>>>>
>>>>>>  static int
>>>>>> @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
>>>>>>                     dm_plane_state->degamma_tf = val;
>>>>>>                     dm_plane_state->base.color_mgmt_changed = 1;
>>>>>>             }
>>>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>>>> +           if (dm_plane_state->hdr_mult != val) {
>>>>>> +                   dm_plane_state->hdr_mult = val;
>>>>>> +                   dm_plane_state->base.color_mgmt_changed = 1;
>>>>>> +           }
>>>>>>     } else {
>>>>>>             drm_dbg_atomic(plane->dev,
>>>>>>                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
>>>>>> @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
>>>>>>                     dm_plane_state->degamma_lut->base.id : 0;
>>>>>>     } else if (property == adev->mode_info.plane_degamma_tf_property) {
>>>>>>             *val = dm_plane_state->degamma_tf;
>>>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>>>> +           *val = dm_plane_state->hdr_mult;
>>>>>>     } else {
>>>>>>             return -EINVAL;
>>>>>>     }
>>>>>
>>>>>
>>


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

* Re: [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier driver-private property
@ 2023-05-09 22:55               ` Harry Wentland
  0 siblings, 0 replies; 141+ messages in thread
From: Harry Wentland @ 2023-05-09 22:55 UTC (permalink / raw)
  To: Joshua Ashton
  Cc: Sebastian Wick, Shashank Sharma, sunpeng.li, linux-kernel,
	Xinhui.Pan, Rodrigo Siqueira, Xaver Hugl, dri-devel,
	Nicholas Kazlauskas, Melissa Wen, Alex Hung, amd-gfx, daniel,
	Alex Deucher, airlied, christian.koenig, sungjoon.kim



On 5/9/23 16:35, Joshua Ashton wrote:
> FWIW, we technically do use it right now, but it is always set to 1 in S.31.32.
> 
> Before we used shaper + 3D LUT we did use it for scaling SDR content,
> but given we always have a shaper + 3D LUT it made sense for us to
> roll that into there.
> 

Ah, that's good. No problem then.

Harry

> On Tue, 9 May 2023 at 20:00, Harry Wentland <harry.wentland@amd.com> wrote:
>>
>> On 5/9/23 12:54, Joshua Ashton wrote:
>>> We currently do not have a use for this as we settled on per-plane 3D
>>> LUT + Shaper, but we might end up wanting to use in our scRGB stack
>>> someday so I would like to keep it.
>>>
>>
>> uAPI should always have a userspace that uses it. But if we go
>> and put it behind an #ifdef anyways I don't mind taking this
>> if we foresee use for it in the near future. A gamescope experiment
>> showing how this can be used to scale sRGB planes would be great.
>> I assume that's sort of how you intend to use it.
>>
>> Harry
>>
>>> On Tue, 9 May 2023 at 16:37, Melissa Wen <mwen@igalia.com> wrote:
>>>>
>>>> On 05/08, Harry Wentland wrote:
>>>>>
>>>>>
>>>>> On 4/23/23 10:10, Melissa Wen wrote:
>>>>>> From: Joshua Ashton <joshua@froggi.es>
>>>>>>
>>>>>> Multiplier to 'gain' the plane. When PQ is decoded using the fixed func
>>>>>> transfer function to the internal FP16 fb, 1.0 -> 80 nits (on AMD at
>>>>>> least) When sRGB is decoded, 1.0 -> 1.0.  Therefore, 1.0 multiplier = 80
>>>>>> nits for SDR content. So if you want, 203 nits for SDR content, pass in
>>>>>> (203.0 / 80.0).
>>>>>>
>>>>>
>>>>> Is gamescope intending to use this?
>>>>
>>>> I don't think so. Again, I'll double check and drop it accordingly.
>>>>
>>>> Melissa
>>>>
>>>>>
>>>>> Harry
>>>>>
>>>>>> Co-developed-by: Melissa Wen <mwen@igalia.com>
>>>>>> Signed-off-by: Melissa Wen <mwen@igalia.com>
>>>>>> Signed-off-by: Joshua Ashton <joshua@froggi.es>
>>>>>> ---
>>>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   |  6 +++++
>>>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h      |  4 +++
>>>>>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 12 +++++++++
>>>>>>  .../amd/display/amdgpu_dm/amdgpu_dm_plane.c   | 25 ++++++++++++++-----
>>>>>>  4 files changed, 41 insertions(+), 6 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>>>> index 24595906dab1..dd658f162f6f 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
>>>>>> @@ -1326,6 +1326,12 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev)
>>>>>>             return -ENOMEM;
>>>>>>     adev->mode_info.plane_degamma_tf_property = prop;
>>>>>>
>>>>>> +   prop = drm_property_create_range(adev_to_drm(adev),
>>>>>> +                                    0, "AMD_PLANE_HDR_MULT", 0, UINT_MAX);
>>>>>> +   if (!prop)
>>>>>> +           return -ENOMEM;
>>>>>> +   adev->mode_info.plane_hdr_mult_property = prop;
>>>>>> +
>>>>>>     return 0;
>>>>>>  }
>>>>>>  #endif
>>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>>>> index ab9ce6f26c90..65a9d62ffbe4 100644
>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h
>>>>>> @@ -387,6 +387,10 @@ struct amdgpu_mode_info {
>>>>>>      * linearize content with or without LUT.
>>>>>>      */
>>>>>>     struct drm_property *plane_degamma_tf_property;
>>>>>> +   /**
>>>>>> +    * @plane_hdr_mult_property:
>>>>>> +    */
>>>>>> +   struct drm_property *plane_hdr_mult_property;
>>>>>>  #endif
>>>>>>  };
>>>>>>
>>>>>> 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 005632c1c9ec..bb7307b9cfd5 100644
>>>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
>>>>>> @@ -51,6 +51,7 @@
>>>>>>
>>>>>>  #define AMDGPU_DMUB_NOTIFICATION_MAX 5
>>>>>>
>>>>>> +#define AMDGPU_HDR_MULT_DEFAULT (0x100000000LL)
>>>>>>  /*
>>>>>>  #include "include/amdgpu_dal_power_if.h"
>>>>>>  #include "amdgpu_dm_irq.h"
>>>>>> @@ -736,6 +737,17 @@ struct dm_plane_state {
>>>>>>      * linearize.
>>>>>>      */
>>>>>>     enum drm_transfer_function degamma_tf;
>>>>>> +   /**
>>>>>> +    * @hdr_mult:
>>>>>> +    *
>>>>>> +    * Multiplier to 'gain' the plane.  When PQ is decoded using the fixed
>>>>>> +    * func transfer function to the internal FP16 fb, 1.0 -> 80 nits (on
>>>>>> +    * AMD at least). When sRGB is decoded, 1.0 -> 1.0, obviously.
>>>>>> +    * Therefore, 1.0 multiplier = 80 nits for SDR content.  So if you
>>>>>> +    * want, 203 nits for SDR content, pass in (203.0 / 80.0).  Format is
>>>>>> +    * S31.32 sign-magnitude.
>>>>>> +    */
>>>>>> +   __u64 hdr_mult;
>>>>>>  #endif
>>>>>>  };
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>>>> index 5b458cc0781c..57169dae8b3d 100644
>>>>>> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>>>> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
>>>>>> @@ -1321,8 +1321,10 @@ static void dm_drm_plane_reset(struct drm_plane *plane)
>>>>>>             __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
>>>>>>
>>>>>>  #ifdef CONFIG_STEAM_DECK
>>>>>> -   if (amdgpu_state)
>>>>>> +   if (amdgpu_state) {
>>>>>>             amdgpu_state->degamma_tf = DRM_TRANSFER_FUNCTION_DEFAULT;
>>>>>> +           amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
>>>>>> +   }
>>>>>>  #endif
>>>>>>  }
>>>>>>
>>>>>> @@ -1424,11 +1426,11 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane,
>>>>>>  #ifdef CONFIG_STEAM_DECK
>>>>>>  int
>>>>>>  amdgpu_dm_replace_property_blob_from_id(struct drm_device *dev,
>>>>>> -                                          struct drm_property_blob **blob,
>>>>>> -                                          uint64_t blob_id,
>>>>>> -                                          ssize_t expected_size,
>>>>>> -                                          ssize_t expected_elem_size,
>>>>>> -                                          bool *replaced)
>>>>>> +                                   struct drm_property_blob **blob,
>>>>>> +                                   uint64_t blob_id,
>>>>>> +                                   ssize_t expected_size,
>>>>>> +                                   ssize_t expected_elem_size,
>>>>>> +                                   bool *replaced)
>>>>>>  {
>>>>>>     struct drm_property_blob *new_blob = NULL;
>>>>>>
>>>>>> @@ -1482,6 +1484,10 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
>>>>>>                                        dm->adev->mode_info.plane_degamma_tf_property,
>>>>>>                                        DRM_TRANSFER_FUNCTION_DEFAULT);
>>>>>>     }
>>>>>> +   /* HDR MULT is always available */
>>>>>> +   drm_object_attach_property(&plane->base,
>>>>>> +                              dm->adev->mode_info.plane_hdr_mult_property,
>>>>>> +                              AMDGPU_HDR_MULT_DEFAULT);
>>>>>>  }
>>>>>>
>>>>>>  static int
>>>>>> @@ -1507,6 +1513,11 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
>>>>>>                     dm_plane_state->degamma_tf = val;
>>>>>>                     dm_plane_state->base.color_mgmt_changed = 1;
>>>>>>             }
>>>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>>>> +           if (dm_plane_state->hdr_mult != val) {
>>>>>> +                   dm_plane_state->hdr_mult = val;
>>>>>> +                   dm_plane_state->base.color_mgmt_changed = 1;
>>>>>> +           }
>>>>>>     } else {
>>>>>>             drm_dbg_atomic(plane->dev,
>>>>>>                            "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
>>>>>> @@ -1533,6 +1544,8 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
>>>>>>                     dm_plane_state->degamma_lut->base.id : 0;
>>>>>>     } else if (property == adev->mode_info.plane_degamma_tf_property) {
>>>>>>             *val = dm_plane_state->degamma_tf;
>>>>>> +   } else if (property == adev->mode_info.plane_hdr_mult_property) {
>>>>>> +           *val = dm_plane_state->hdr_mult;
>>>>>>     } else {
>>>>>>             return -EINVAL;
>>>>>>     }
>>>>>
>>>>>
>>


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

end of thread, other threads:[~2023-05-09 22:56 UTC | newest]

Thread overview: 141+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-23 14:10 [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt Melissa Wen
2023-04-23 14:10 ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 01/40] drm/amd/display: fix segment distribution for linear LUTs Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 02/40] drm/amd/display: fix the delta clamping for shaper LUT Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 03/40] drm/amd/display: introduce Steam Deck color features to AMD display driver Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-05-08 21:24   ` Harry Wentland
2023-05-08 21:24     ` Harry Wentland
2023-05-09 16:23     ` Melissa Wen
2023-05-09 16:23       ` Melissa Wen
2023-05-09 16:23       ` Melissa Wen
2023-05-09 16:52       ` Joshua Ashton
2023-05-09 16:52         ` Joshua Ashton
2023-05-09 16:52         ` Joshua Ashton
2023-05-09 17:19         ` Harry Wentland
2023-05-09 17:19           ` Harry Wentland
2023-05-09 17:19           ` Harry Wentland
2023-05-09 17:20       ` Harry Wentland
2023-05-09 17:20         ` Harry Wentland
2023-05-09 17:20         ` Harry Wentland
2023-04-23 14:10 ` [RFC PATCH 04/40] drm/drm_mode_object: increase max objects to accommodate new color props Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 05/40] drm/amd/display: add shaper LUT driver-private props Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 17:26   ` kernel test robot
2023-05-08 21:24   ` Harry Wentland
2023-05-08 21:24     ` Harry Wentland
2023-05-09 16:30     ` Melissa Wen
2023-05-09 16:30       ` Melissa Wen
2023-05-09 16:30       ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 06/40] drm/amd/display: add 3D " Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 07/40] drm/amd/display: add CRTC gamma TF to " Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-05-08 21:24   ` Harry Wentland
2023-05-08 21:24     ` Harry Wentland
2023-05-09 16:34     ` Melissa Wen
2023-05-09 16:34       ` Melissa Wen
2023-05-09 16:34       ` Melissa Wen
2023-05-09 16:55       ` Joshua Ashton
2023-05-09 16:55         ` Joshua Ashton
2023-05-09 16:55         ` Joshua Ashton
2023-04-23 14:10 ` [RFC PATCH 08/40] drm/drm_plane: track color mgmt changes per plane Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 09/40] drm/amd/display: move replace blob func to dm plane Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-05-08 21:24   ` Harry Wentland
2023-05-08 21:24     ` Harry Wentland
2023-05-09 16:35     ` Melissa Wen
2023-05-09 16:35       ` Melissa Wen
2023-05-09 16:35       ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 10/40] drm/amd/display: add plane degamma LUT driver-private props Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 11/40] drm/amd/display: add plane degamma TF driver-private property Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 12/40] drm/amd/display: add plane HDR multiplier " Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-05-08 21:24   ` Harry Wentland
2023-05-08 21:24     ` Harry Wentland
2023-05-09 16:37     ` Melissa Wen
2023-05-09 16:37       ` Melissa Wen
2023-05-09 16:37       ` Melissa Wen
2023-05-09 16:54       ` Joshua Ashton
2023-05-09 16:54         ` Joshua Ashton
2023-05-09 16:54         ` Joshua Ashton
2023-05-09 20:00         ` Harry Wentland
2023-05-09 20:00           ` Harry Wentland
2023-05-09 20:00           ` Harry Wentland
2023-05-09 20:35           ` Joshua Ashton
2023-05-09 20:35             ` Joshua Ashton
2023-05-09 20:35             ` Joshua Ashton
2023-05-09 22:55             ` Harry Wentland
2023-05-09 22:55               ` Harry Wentland
2023-05-09 22:55               ` Harry Wentland
2023-04-23 14:10 ` [RFC PATCH 13/40] drm/amd/display: add plane 3D LUT driver-private properties Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 14/40] drm/amd/display: add plane shaper " Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 15/40] drm/amd/display: add plane shaper TF driver-private property Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 16/40] drm/amd/display: add plane blend LUT and TF driver-private properties Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 17/40] drm/amd/display: add comments to describe DM crtc color mgmt behavior Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 18/40] drm/amd/display: encapsulate atomic regamma operation Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 19/40] drm/amd/display: update lut3d and shaper lut to stream Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 20/40] drm/amd/display: copy 3D LUT settings from crtc state to stream_update Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 21/40] drm/amd/display: allow BYPASS 3D LUT but keep shaper LUT settings Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 22/40] drm/amd/display: handle MPC 3D LUT resources for a given context Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 23/40] drm/amd/display: dynamically acquire 3DLUT resources for color changes Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 24/40] drm/amd/display: add CRTC 3D LUT support to amd color pipeline Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 25/40] drm/amd/display: decouple steps to reuse in CRTC shaper LUT support Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 26/40] drm/amd/display: add CRTC shaper LUT support to amd color pipeline Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 18:48   ` kernel test robot
2023-04-23 14:10 ` [RFC PATCH 27/40] drm/amd/display: add CRTC regamma TF support Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 28/40] drm/amd/display: set sdr_ref_white_level to 80 for out_transfer_func Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 29/40] drm/amd/display: add CRTC shaper TF support Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 30/40] drm/amd/display: mark plane as needing reset if plane color mgmt changes Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 31/40] drm/amd/display: decouple steps for mapping CRTC degamma to DC plane Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 32/40] drm/amd/display: add support for plane degamma TF and LUT properties Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 33/40] drm/amd/display: reject atomic commit if setting both plane and CRTC degamma Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 34/40] drm/amd/display: add dc_fixpt_from_s3132 helper Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 35/40] drm/adm/display: add HDR multiplier support Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 36/40] drm/amd/display: add plane shaper/3D LUT and shaper TF support Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 37/40] drm/amd/display: handle empty LUTs in __set_input_tf Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 38/40] drm/amd/display: add DRM plane blend LUT and TF support Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 39/40] drm/amd/display: copy dc_plane color settings to surface_updates Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-04-23 14:10 ` [RFC PATCH 40/40] drm/amd/display: allow newer DC hardware to use degamma ROM for PQ/HLG Melissa Wen
2023-04-23 14:10   ` Melissa Wen
2023-05-08 21:24 ` [RFC PATCH 00/40] drm/amd/display: add AMD driver-specific properties for color mgmt Harry Wentland
2023-05-08 21:24   ` Harry Wentland
2023-05-09 16:52   ` Melissa Wen
2023-05-09 16:52     ` Melissa Wen
2023-05-09 16:52     ` Melissa Wen
2023-05-09 17:25     ` Harry Wentland
2023-05-09 17:25       ` Harry Wentland
2023-05-09 17:25       ` Harry Wentland

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.