All of lore.kernel.org
 help / color / mirror / Atom feed
From: Melissa Wen <mwen@igalia.com>
To: harry.wentland@amd.com, sunpeng.li@amd.com,
	Rodrigo.Siqueira@amd.com, alexander.deucher@amd.com,
	christian.koenig@amd.com, Xinhui.Pan@amd.com, airlied@gmail.com,
	daniel@ffwll.ch
Cc: laurent.pinchart+renesas@ideasonboard.com, kernel-dev@igalia.com,
	Shashank Sharma <shashank.sharma@amd.com>,
	alex.hung@amd.com, dri-devel@lists.freedesktop.org,
	linux-kernel@vger.kernel.org, Melissa Wen <mwen@igalia.com>,
	seanpaul@chromium.org, tzimmermann@suse.de,
	amd-gfx@lists.freedesktop.org, bhawanpreet.lakha@amd.com,
	nicholas.kazlauskas@amd.com, Joshua Ashton <joshua@froggi.es>,
	sungjoon.kim@amd.com
Subject: [RFC PATCH v2 18/18] drm/amd/display: add user shaper LUT support to amdgpu_dm color pipeline
Date: Mon,  9 Jan 2023 13:38:46 -0100	[thread overview]
Message-ID: <20230109143846.1966301-19-mwen@igalia.com> (raw)
In-Reply-To: <20230109143846.1966301-1-mwen@igalia.com>

Now, we can use 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.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 95 ++++++++++++++++---
 1 file changed, 83 insertions(+), 12 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 8a930f9bce60..81b20ac9ff19 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
@@ -497,14 +497,62 @@ static void amdgpu_dm_atomic_lut3d(struct dc_stream_state *stream,
 	stream->lut3d_func = lut;
 }
 
+static int __set_func_shaper(struct dc_transfer_func *shaper_func,
+			     const struct drm_color_lut *lut, uint32_t lut_size)
+{
+	struct dc_gamma *gamma = NULL;
+	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;
+
+	gamma->num_entries = lut_size;
+	__drm_lut_to_dc_gamma(lut, gamma, false);
+
+	/*
+	 * Color module doesn't like calculating gamma params
+	 * on top of a linear input. But degamma params can be used
+	 * instead to simulate this.
+	 */
+	gamma->type = GAMMA_CUSTOM;
+	res = mod_color_calculate_degamma_params(NULL, shaper_func, gamma, true);
+
+	dc_gamma_release(&gamma);
+
+	return res ? 0 : -ENOMEM;
+}
+
 static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
+				       const struct drm_color_lut *shaper_lut,
+				       uint32_t shaper_size,
 				       struct dc_transfer_func *func_shaper_new)
 {
-	/* We don't get DRM shaper LUT yet. We assume the input color space is already
+	/* If no DRM shaper LUT, we assume the input color space is already
 	 * delinearized, so we don't need a shaper LUT and we can just BYPASS
 	 */
-	func_shaper_new->type = TF_TYPE_BYPASS;
-	func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+	if (!shaper_size) {
+		func_shaper_new->type = TF_TYPE_BYPASS;
+		func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+	} else {
+		int r;
+
+		/* If DRM shaper LUT is set, we assume a linear color space
+		 * (linearized by DRM degamma 1D LUT or not)
+		 */
+		func_shaper_new->type = TF_TYPE_DISTRIBUTED_POINTS;
+		func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+
+		r = __set_func_shaper(func_shaper_new, shaper_lut, shaper_size);
+		if (r)
+			return r;
+	}
+
 	stream->func_shaper = func_shaper_new;
 
 	return 0;
@@ -514,6 +562,8 @@ static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
  * interface
  * @dc: Display Core control structure
  * @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
  *
@@ -522,6 +572,8 @@ static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
  */
 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,
 					 const struct drm_color_lut *drm_lut3d,
 					 uint32_t drm_lut3d_size,
 					 const struct drm_mode_lut3d_mode *mode)
@@ -532,11 +584,11 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 	lut3d_func_new = (struct dc_3dlut *) stream->lut3d_func;
 	func_shaper_new = (struct dc_transfer_func *) stream->func_shaper;
 
-
 	amdgpu_dm_atomic_lut3d(stream, drm_lut3d, drm_lut3d_size,
 			       mode, lut3d_func_new);
 
-	return amdgpu_dm_atomic_shaper_lut(stream, func_shaper_new);
+	return amdgpu_dm_atomic_shaper_lut(stream, drm_shaper_lut,
+					   drm_shaper_size, func_shaper_new);
 }
 
 static const struct drm_mode_lut3d_mode *
@@ -569,13 +621,23 @@ get_lut3d_mode(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;
+	const struct drm_color_lut *shaper = NULL, *lut3d = NULL;
 	const struct drm_mode_lut3d_mode *mode;
 	uint32_t exp_size, size;
 
+	/* shaper LUT is only available if 3D LUT color caps*/
+	exp_size = has_mpc_lut3d_caps(&adev->dm) ? MAX_COLOR_LUT_ENTRIES : 0;
+	shaper = __extract_blob_lut(crtc_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;
+	}
+
 	mode = get_lut3d_mode(adev, crtc_state);
 	exp_size = mode ? mode->lut_size * mode->lut_size * mode->lut_size : 0;
-
 	lut3d = __extract_blob_lut(crtc_state->lut3d, &size);
 
 	if (lut3d && size != exp_size) {
@@ -617,11 +679,11 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 	bool has_rom = adev->asic_type <= CHIP_RAVEN;
 	struct drm_color_ctm *ctm = NULL;
 	const struct drm_color_lut *degamma_lut, *regamma_lut;
-	const struct drm_color_lut *lut3d;
+	const struct drm_color_lut *shaper_lut, *lut3d;
 	uint32_t degamma_size, regamma_size;
-	uint32_t lut3d_size;
+	uint32_t lut3d_size, shaper_size;
 	bool has_regamma, has_degamma;
-	bool has_lut3d;
+	bool has_lut3d, has_shaper_lut;
 	bool is_legacy;
 	int r;
 
@@ -634,12 +696,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 		return r;
 
 	degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, &degamma_size);
+	shaper_lut = __extract_blob_lut(crtc->base.shaper_lut, &shaper_size);
 	lut3d = __extract_blob_lut(crtc->base.lut3d, &lut3d_size);
 	regamma_lut = __extract_blob_lut(crtc->base.gamma_lut, &regamma_size);
 
 	has_degamma =
 		degamma_lut && !__is_lut_linear(degamma_lut, degamma_size);
 
+	has_shaper_lut = shaper_lut != NULL;
 	has_lut3d = lut3d != NULL;
 
 	has_regamma =
@@ -680,10 +744,17 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 			return r;
 	} else {
 		if (has_lut3d) {
-			r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, stream, lut3d, lut3d_size,
+			/* enable 3D LUT only for DRM atomic color mgmt */
+			shaper_size = has_shaper_lut ? shaper_size : 0;
+
+			r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, stream,
+							  shaper_lut, shaper_size,
+							  lut3d, lut3d_size,
 							  get_lut3d_mode(adev, &crtc->base));
-			if (r)
+			if (r) {
+				DRM_DEBUG_DRIVER("Failed to set shaper and 3D LUT\n");
 				return r;
+			}
 		}
 		/* Note: OGAM is disabled if 3D LUT is successfully programmed.
 		 * See params and set_output_gamma in
-- 
2.35.1


WARNING: multiple messages have this Message-ID (diff)
From: Melissa Wen <mwen@igalia.com>
To: harry.wentland@amd.com, sunpeng.li@amd.com,
	Rodrigo.Siqueira@amd.com, alexander.deucher@amd.com,
	christian.koenig@amd.com, Xinhui.Pan@amd.com, airlied@gmail.com,
	daniel@ffwll.ch
Cc: laurent.pinchart+renesas@ideasonboard.com, kernel-dev@igalia.com,
	Shashank Sharma <shashank.sharma@amd.com>,
	alex.hung@amd.com, dri-devel@lists.freedesktop.org,
	maarten.lankhorst@linux.intel.com, linux-kernel@vger.kernel.org,
	mripard@kernel.org, Melissa Wen <mwen@igalia.com>,
	seanpaul@chromium.org, ville.syrjala@linux.intel.com,
	tzimmermann@suse.de, amd-gfx@lists.freedesktop.org,
	bhawanpreet.lakha@amd.com, nicholas.kazlauskas@amd.com,
	Joshua Ashton <joshua@froggi.es>,
	sungjoon.kim@amd.com
Subject: [RFC PATCH v2 18/18] drm/amd/display: add user shaper LUT support to amdgpu_dm color pipeline
Date: Mon,  9 Jan 2023 13:38:46 -0100	[thread overview]
Message-ID: <20230109143846.1966301-19-mwen@igalia.com> (raw)
In-Reply-To: <20230109143846.1966301-1-mwen@igalia.com>

Now, we can use 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.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 95 ++++++++++++++++---
 1 file changed, 83 insertions(+), 12 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 8a930f9bce60..81b20ac9ff19 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
@@ -497,14 +497,62 @@ static void amdgpu_dm_atomic_lut3d(struct dc_stream_state *stream,
 	stream->lut3d_func = lut;
 }
 
+static int __set_func_shaper(struct dc_transfer_func *shaper_func,
+			     const struct drm_color_lut *lut, uint32_t lut_size)
+{
+	struct dc_gamma *gamma = NULL;
+	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;
+
+	gamma->num_entries = lut_size;
+	__drm_lut_to_dc_gamma(lut, gamma, false);
+
+	/*
+	 * Color module doesn't like calculating gamma params
+	 * on top of a linear input. But degamma params can be used
+	 * instead to simulate this.
+	 */
+	gamma->type = GAMMA_CUSTOM;
+	res = mod_color_calculate_degamma_params(NULL, shaper_func, gamma, true);
+
+	dc_gamma_release(&gamma);
+
+	return res ? 0 : -ENOMEM;
+}
+
 static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
+				       const struct drm_color_lut *shaper_lut,
+				       uint32_t shaper_size,
 				       struct dc_transfer_func *func_shaper_new)
 {
-	/* We don't get DRM shaper LUT yet. We assume the input color space is already
+	/* If no DRM shaper LUT, we assume the input color space is already
 	 * delinearized, so we don't need a shaper LUT and we can just BYPASS
 	 */
-	func_shaper_new->type = TF_TYPE_BYPASS;
-	func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+	if (!shaper_size) {
+		func_shaper_new->type = TF_TYPE_BYPASS;
+		func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+	} else {
+		int r;
+
+		/* If DRM shaper LUT is set, we assume a linear color space
+		 * (linearized by DRM degamma 1D LUT or not)
+		 */
+		func_shaper_new->type = TF_TYPE_DISTRIBUTED_POINTS;
+		func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+
+		r = __set_func_shaper(func_shaper_new, shaper_lut, shaper_size);
+		if (r)
+			return r;
+	}
+
 	stream->func_shaper = func_shaper_new;
 
 	return 0;
@@ -514,6 +562,8 @@ static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
  * interface
  * @dc: Display Core control structure
  * @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
  *
@@ -522,6 +572,8 @@ static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
  */
 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,
 					 const struct drm_color_lut *drm_lut3d,
 					 uint32_t drm_lut3d_size,
 					 const struct drm_mode_lut3d_mode *mode)
@@ -532,11 +584,11 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 	lut3d_func_new = (struct dc_3dlut *) stream->lut3d_func;
 	func_shaper_new = (struct dc_transfer_func *) stream->func_shaper;
 
-
 	amdgpu_dm_atomic_lut3d(stream, drm_lut3d, drm_lut3d_size,
 			       mode, lut3d_func_new);
 
-	return amdgpu_dm_atomic_shaper_lut(stream, func_shaper_new);
+	return amdgpu_dm_atomic_shaper_lut(stream, drm_shaper_lut,
+					   drm_shaper_size, func_shaper_new);
 }
 
 static const struct drm_mode_lut3d_mode *
@@ -569,13 +621,23 @@ get_lut3d_mode(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;
+	const struct drm_color_lut *shaper = NULL, *lut3d = NULL;
 	const struct drm_mode_lut3d_mode *mode;
 	uint32_t exp_size, size;
 
+	/* shaper LUT is only available if 3D LUT color caps*/
+	exp_size = has_mpc_lut3d_caps(&adev->dm) ? MAX_COLOR_LUT_ENTRIES : 0;
+	shaper = __extract_blob_lut(crtc_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;
+	}
+
 	mode = get_lut3d_mode(adev, crtc_state);
 	exp_size = mode ? mode->lut_size * mode->lut_size * mode->lut_size : 0;
-
 	lut3d = __extract_blob_lut(crtc_state->lut3d, &size);
 
 	if (lut3d && size != exp_size) {
@@ -617,11 +679,11 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 	bool has_rom = adev->asic_type <= CHIP_RAVEN;
 	struct drm_color_ctm *ctm = NULL;
 	const struct drm_color_lut *degamma_lut, *regamma_lut;
-	const struct drm_color_lut *lut3d;
+	const struct drm_color_lut *shaper_lut, *lut3d;
 	uint32_t degamma_size, regamma_size;
-	uint32_t lut3d_size;
+	uint32_t lut3d_size, shaper_size;
 	bool has_regamma, has_degamma;
-	bool has_lut3d;
+	bool has_lut3d, has_shaper_lut;
 	bool is_legacy;
 	int r;
 
@@ -634,12 +696,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 		return r;
 
 	degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, &degamma_size);
+	shaper_lut = __extract_blob_lut(crtc->base.shaper_lut, &shaper_size);
 	lut3d = __extract_blob_lut(crtc->base.lut3d, &lut3d_size);
 	regamma_lut = __extract_blob_lut(crtc->base.gamma_lut, &regamma_size);
 
 	has_degamma =
 		degamma_lut && !__is_lut_linear(degamma_lut, degamma_size);
 
+	has_shaper_lut = shaper_lut != NULL;
 	has_lut3d = lut3d != NULL;
 
 	has_regamma =
@@ -680,10 +744,17 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 			return r;
 	} else {
 		if (has_lut3d) {
-			r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, stream, lut3d, lut3d_size,
+			/* enable 3D LUT only for DRM atomic color mgmt */
+			shaper_size = has_shaper_lut ? shaper_size : 0;
+
+			r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, stream,
+							  shaper_lut, shaper_size,
+							  lut3d, lut3d_size,
 							  get_lut3d_mode(adev, &crtc->base));
-			if (r)
+			if (r) {
+				DRM_DEBUG_DRIVER("Failed to set shaper and 3D LUT\n");
 				return r;
+			}
 		}
 		/* Note: OGAM is disabled if 3D LUT is successfully programmed.
 		 * See params and set_output_gamma in
-- 
2.35.1


WARNING: multiple messages have this Message-ID (diff)
From: Melissa Wen <mwen@igalia.com>
To: harry.wentland@amd.com, sunpeng.li@amd.com,
	Rodrigo.Siqueira@amd.com, alexander.deucher@amd.com,
	christian.koenig@amd.com, Xinhui.Pan@amd.com, airlied@gmail.com,
	daniel@ffwll.ch
Cc: Joshua Ashton <joshua@froggi.es>,
	alex.hung@amd.com, nicholas.kazlauskas@amd.com,
	sungjoon.kim@amd.com, seanpaul@chromium.org,
	bhawanpreet.lakha@amd.com,
	Shashank Sharma <shashank.sharma@amd.com>,
	ville.syrjala@linux.intel.com, maarten.lankhorst@linux.intel.com,
	mripard@kernel.org, tzimmermann@suse.de, kernel-dev@igalia.com,
	laurent.pinchart+renesas@ideasonboard.com,
	Melissa Wen <mwen@igalia.com>,
	amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH v2 18/18] drm/amd/display: add user shaper LUT support to amdgpu_dm color pipeline
Date: Mon,  9 Jan 2023 13:38:46 -0100	[thread overview]
Message-ID: <20230109143846.1966301-19-mwen@igalia.com> (raw)
In-Reply-To: <20230109143846.1966301-1-mwen@igalia.com>

Now, we can use 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.

Signed-off-by: Melissa Wen <mwen@igalia.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 95 ++++++++++++++++---
 1 file changed, 83 insertions(+), 12 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 8a930f9bce60..81b20ac9ff19 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
@@ -497,14 +497,62 @@ static void amdgpu_dm_atomic_lut3d(struct dc_stream_state *stream,
 	stream->lut3d_func = lut;
 }
 
+static int __set_func_shaper(struct dc_transfer_func *shaper_func,
+			     const struct drm_color_lut *lut, uint32_t lut_size)
+{
+	struct dc_gamma *gamma = NULL;
+	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;
+
+	gamma->num_entries = lut_size;
+	__drm_lut_to_dc_gamma(lut, gamma, false);
+
+	/*
+	 * Color module doesn't like calculating gamma params
+	 * on top of a linear input. But degamma params can be used
+	 * instead to simulate this.
+	 */
+	gamma->type = GAMMA_CUSTOM;
+	res = mod_color_calculate_degamma_params(NULL, shaper_func, gamma, true);
+
+	dc_gamma_release(&gamma);
+
+	return res ? 0 : -ENOMEM;
+}
+
 static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
+				       const struct drm_color_lut *shaper_lut,
+				       uint32_t shaper_size,
 				       struct dc_transfer_func *func_shaper_new)
 {
-	/* We don't get DRM shaper LUT yet. We assume the input color space is already
+	/* If no DRM shaper LUT, we assume the input color space is already
 	 * delinearized, so we don't need a shaper LUT and we can just BYPASS
 	 */
-	func_shaper_new->type = TF_TYPE_BYPASS;
-	func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+	if (!shaper_size) {
+		func_shaper_new->type = TF_TYPE_BYPASS;
+		func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+	} else {
+		int r;
+
+		/* If DRM shaper LUT is set, we assume a linear color space
+		 * (linearized by DRM degamma 1D LUT or not)
+		 */
+		func_shaper_new->type = TF_TYPE_DISTRIBUTED_POINTS;
+		func_shaper_new->tf = TRANSFER_FUNCTION_LINEAR;
+
+		r = __set_func_shaper(func_shaper_new, shaper_lut, shaper_size);
+		if (r)
+			return r;
+	}
+
 	stream->func_shaper = func_shaper_new;
 
 	return 0;
@@ -514,6 +562,8 @@ static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
  * interface
  * @dc: Display Core control structure
  * @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
  *
@@ -522,6 +572,8 @@ static int amdgpu_dm_atomic_shaper_lut(struct dc_stream_state *stream,
  */
 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,
 					 const struct drm_color_lut *drm_lut3d,
 					 uint32_t drm_lut3d_size,
 					 const struct drm_mode_lut3d_mode *mode)
@@ -532,11 +584,11 @@ static int amdgpu_dm_atomic_shaper_lut3d(struct dc *dc,
 	lut3d_func_new = (struct dc_3dlut *) stream->lut3d_func;
 	func_shaper_new = (struct dc_transfer_func *) stream->func_shaper;
 
-
 	amdgpu_dm_atomic_lut3d(stream, drm_lut3d, drm_lut3d_size,
 			       mode, lut3d_func_new);
 
-	return amdgpu_dm_atomic_shaper_lut(stream, func_shaper_new);
+	return amdgpu_dm_atomic_shaper_lut(stream, drm_shaper_lut,
+					   drm_shaper_size, func_shaper_new);
 }
 
 static const struct drm_mode_lut3d_mode *
@@ -569,13 +621,23 @@ get_lut3d_mode(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;
+	const struct drm_color_lut *shaper = NULL, *lut3d = NULL;
 	const struct drm_mode_lut3d_mode *mode;
 	uint32_t exp_size, size;
 
+	/* shaper LUT is only available if 3D LUT color caps*/
+	exp_size = has_mpc_lut3d_caps(&adev->dm) ? MAX_COLOR_LUT_ENTRIES : 0;
+	shaper = __extract_blob_lut(crtc_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;
+	}
+
 	mode = get_lut3d_mode(adev, crtc_state);
 	exp_size = mode ? mode->lut_size * mode->lut_size * mode->lut_size : 0;
-
 	lut3d = __extract_blob_lut(crtc_state->lut3d, &size);
 
 	if (lut3d && size != exp_size) {
@@ -617,11 +679,11 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 	bool has_rom = adev->asic_type <= CHIP_RAVEN;
 	struct drm_color_ctm *ctm = NULL;
 	const struct drm_color_lut *degamma_lut, *regamma_lut;
-	const struct drm_color_lut *lut3d;
+	const struct drm_color_lut *shaper_lut, *lut3d;
 	uint32_t degamma_size, regamma_size;
-	uint32_t lut3d_size;
+	uint32_t lut3d_size, shaper_size;
 	bool has_regamma, has_degamma;
-	bool has_lut3d;
+	bool has_lut3d, has_shaper_lut;
 	bool is_legacy;
 	int r;
 
@@ -634,12 +696,14 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 		return r;
 
 	degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, &degamma_size);
+	shaper_lut = __extract_blob_lut(crtc->base.shaper_lut, &shaper_size);
 	lut3d = __extract_blob_lut(crtc->base.lut3d, &lut3d_size);
 	regamma_lut = __extract_blob_lut(crtc->base.gamma_lut, &regamma_size);
 
 	has_degamma =
 		degamma_lut && !__is_lut_linear(degamma_lut, degamma_size);
 
+	has_shaper_lut = shaper_lut != NULL;
 	has_lut3d = lut3d != NULL;
 
 	has_regamma =
@@ -680,10 +744,17 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
 			return r;
 	} else {
 		if (has_lut3d) {
-			r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, stream, lut3d, lut3d_size,
+			/* enable 3D LUT only for DRM atomic color mgmt */
+			shaper_size = has_shaper_lut ? shaper_size : 0;
+
+			r = amdgpu_dm_atomic_shaper_lut3d(adev->dm.dc, stream,
+							  shaper_lut, shaper_size,
+							  lut3d, lut3d_size,
 							  get_lut3d_mode(adev, &crtc->base));
-			if (r)
+			if (r) {
+				DRM_DEBUG_DRIVER("Failed to set shaper and 3D LUT\n");
 				return r;
+			}
 		}
 		/* Note: OGAM is disabled if 3D LUT is successfully programmed.
 		 * See params and set_output_gamma in
-- 
2.35.1


  parent reply	other threads:[~2023-01-09 14:45 UTC|newest]

Thread overview: 94+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-09 14:38 [RFC PATCH v2 00/18] Add DRM CRTC 3D LUT interface Melissa Wen
2023-01-09 14:38 ` Melissa Wen
2023-01-09 14:38 ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 01/18] drm: Add 3D LUT mode and its attributes Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 02/18] drm/drm_color_mgmt: add shaper LUT to color mgmt properties Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 03/18] drm/drm_color_mgmt: add 3D LUT props to DRM color mgmt Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 04/18] drm/drm_color_mgmt: add function to create 3D LUT modes supported Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 05/18] drm/drm_color_mgmt: add function to attach 3D LUT props Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 06/18] drm/drm_color_mgmt: set first lut3d mode as default Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 07/18] drm/amd/display: remove unused regamma condition Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 22:43   ` kernel test robot
2023-01-09 14:38 ` [RFC PATCH v2 08/18] drm/amd/display: add comments to describe DM crtc color mgmt behavior Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 09/18] drm/amd/display: encapsulate atomic regamma operation Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 10/18] drm/amd/display: update lut3d and shaper lut to stream Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 11/18] drm/amd/display: handle MPC 3D LUT resources for a given context Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 12/18] drm/amd/display: acquire/release 3D LUT resources for ctx on DCN301 Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 13/18] drm/amd/display: Define 3D LUT struct for HDR planes Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 23:43   ` kernel test robot
2023-01-09 14:38 ` [RFC PATCH v2 14/18] drm/amd/display: expand array of supported 3D LUT modes Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-10  5:17   ` kernel test robot
2023-01-09 14:38 ` [RFC PATCH v2 15/18] drm/amd/display: enable 3D-LUT DRM properties if supported Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 16/18] drm/amd/display: add user 3D LUT support to the amdgpu_dm color pipeline Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` [RFC PATCH v2 17/18] drm/amd/display: decouple steps to reuse in shaper LUT support Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 14:38 ` Melissa Wen [this message]
2023-01-09 14:38   ` [RFC PATCH v2 18/18] drm/amd/display: add user shaper LUT support to amdgpu_dm color pipeline Melissa Wen
2023-01-09 14:38   ` Melissa Wen
2023-01-09 15:38 ` [RFC PATCH v2 00/18] Add DRM CRTC 3D LUT interface Melissa Wen
2023-01-09 15:38   ` Melissa Wen
2023-01-31  9:07   ` Pekka Paalanen
2023-01-31  9:07     ` Pekka Paalanen
2023-02-09 14:27     ` Melissa Wen
2023-02-09 14:27       ` Melissa Wen
2023-02-10  9:28       ` Pekka Paalanen
2023-02-10  9:28         ` Pekka Paalanen
2023-02-10 19:47         ` Harry Wentland
2023-02-10 19:47           ` Harry Wentland
2023-02-13  9:01           ` Pekka Paalanen
2023-02-13  9:01             ` Pekka Paalanen
2023-02-13 13:02             ` Ville Syrjälä
2023-02-13 13:02               ` Ville Syrjälä
2023-02-13 19:45               ` Melissa Wen
2023-02-13 19:45                 ` Melissa Wen
2023-02-14  9:28                 ` Pekka Paalanen
2023-02-14  9:28                   ` Pekka Paalanen
2023-02-14 10:40                   ` Sharma, Shashank
2023-02-14 10:40                     ` Sharma, Shashank
2023-02-13 19:26         ` Melissa Wen
2023-02-13 19:26           ` Melissa Wen
2023-02-14  9:19           ` Pekka Paalanen
2023-02-14  9:19             ` Pekka Paalanen
2023-02-15  8:34             ` Pekka Paalanen
2023-02-15  8:34               ` Pekka Paalanen
2023-06-13 15:43 ` Jacopo Mondi
2023-06-13 15:43   ` Jacopo Mondi
2023-06-13 15:43   ` Jacopo Mondi
2023-06-15  7:14   ` Pekka Paalanen
2023-06-15  7:14     ` Pekka Paalanen
2023-06-15  7:14     ` Pekka Paalanen
2023-06-15  8:07     ` Jacopo Mondi
2023-06-15  8:07       ` Jacopo Mondi
2023-06-15  8:07       ` Jacopo Mondi
2023-06-15 10:29       ` Pekka Paalanen
2023-06-15 10:29         ` Pekka Paalanen
2023-06-15 10:29         ` Pekka Paalanen
2023-01-10  0:44 [RFC PATCH v2 06/18] drm/drm_color_mgmt: set first lut3d mode as default kernel test robot
2023-01-10  5:13 ` Dan Carpenter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230109143846.1966301-19-mwen@igalia.com \
    --to=mwen@igalia.com \
    --cc=Rodrigo.Siqueira@amd.com \
    --cc=Xinhui.Pan@amd.com \
    --cc=airlied@gmail.com \
    --cc=alex.hung@amd.com \
    --cc=alexander.deucher@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=bhawanpreet.lakha@amd.com \
    --cc=christian.koenig@amd.com \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=harry.wentland@amd.com \
    --cc=joshua@froggi.es \
    --cc=kernel-dev@igalia.com \
    --cc=laurent.pinchart+renesas@ideasonboard.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nicholas.kazlauskas@amd.com \
    --cc=seanpaul@chromium.org \
    --cc=shashank.sharma@amd.com \
    --cc=sungjoon.kim@amd.com \
    --cc=sunpeng.li@amd.com \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.