From patchwork Sun Jun 19 22:31:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Melissa Wen X-Patchwork-Id: 12886869 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B51F9CCA47E for ; Sun, 19 Jun 2022 22:32:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6D2AC112EB5; Sun, 19 Jun 2022 22:32:21 +0000 (UTC) Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id B2066112EAF; Sun, 19 Jun 2022 22:32:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=AKCkWR1rJc7yBcTBCZvEPWBlgtap3fgWfhr76qMwAME=; b=Cju2fhs0snvQRc8ACWrsB+GhLJ RDxKHquCSFL1JewgVMS+JXlcnPOJQc4mpqH4hBoBuMEYm8FukF9PeJ8Vvhz1kWtv7KbNZXENyMBE7 dMe4eB3K97o0wG/TU0KylCH7PfYvPh7eBJDKOWp9OctHdm1sD4Qay7yY/2Z15R7Ax5T1tFMvHyTHS 2YwxuDApPOHE0INkc3wOr3IUbbsfApSLQuTjshiEhnZiwqbgoAykfCzmGBBdnt36N5fdN7Slq8/+/ 9IANsqXg5LG4ji1ClE23w2cnPGys43gOS8rxDLzps2rAvxWboBBlwNsVLITdKhDE6OridgEW1m9WR YddoD5Qg==; Received: from [195.77.82.244] (helo=killbill.home) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1o33Sh-005lHy-63; Mon, 20 Jun 2022 00:32:11 +0200 From: Melissa Wen To: alexander.deucher@amd.com, christian.koenig@amd.com, Xinhui.Pan@amd.com, airlied@linux.ie, daniel@ffwll.ch, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, harry.wentland@amd.com, sunpeng.li@amd.com, Rodrigo.Siqueira@amd.com Subject: [RFC PATCH 1/5] Documentation/amdgpu_dm: Add DM color correction documentation Date: Sun, 19 Jun 2022 21:31:00 -0100 Message-Id: <20220619223104.667413-2-mwen@igalia.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220619223104.667413-1-mwen@igalia.com> References: <20220619223104.667413-1-mwen@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.hung@amd.com, amd-gfx@lists.freedesktop.org, nikola.cornij@amd.com, seanpaul@chromium.org, dri-devel@lists.freedesktop.org, bhawanpreet.lakha@amd.com, nicholas.kazlauskas@amd.com, sungjoon.kim@amd.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" AMDGPU DM maps DRM color management properties (degamma, ctm and gamma) to DC color correction entities. Part of this mapping is already documented as code comments and can be converted as kernel docs. Signed-off-by: Melissa Wen Reviewed-by: Harry Wentland --- .../gpu/amdgpu/display/display-manager.rst | 9 ++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 2 + .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 122 +++++++++++++----- 3 files changed, 101 insertions(+), 32 deletions(-) diff --git a/Documentation/gpu/amdgpu/display/display-manager.rst b/Documentation/gpu/amdgpu/display/display-manager.rst index 7ce31f89d9a0..b1b0f11aed83 100644 --- a/Documentation/gpu/amdgpu/display/display-manager.rst +++ b/Documentation/gpu/amdgpu/display/display-manager.rst @@ -40,3 +40,12 @@ Atomic Implementation .. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c :functions: amdgpu_dm_atomic_check amdgpu_dm_atomic_commit_tail + +Color Management Properties +=========================== + +.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c + :doc: overview + +.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c + :internal: 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 3cc5c15303e6..8fd1be7f2583 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -242,6 +242,8 @@ struct hpd_rx_irq_offload_work { * @force_timing_sync: set via debugfs. When set, indicates that all connected * displays will be forced to synchronize. * @dmcub_trace_event_en: enable dmcub trace events + * @num_of_edps: dumber of embedded Display Ports + * @disable_hpd_irq: disable Hot Plug Detect handling */ struct amdgpu_display_manager { 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 a71177305bcd..1f4a7c908587 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 @@ -29,7 +29,9 @@ #include "modules/color/color_gamma.h" #include "basics/conversion.h" -/* +/** + * DOC: overview + * * The DC interface to HW gives us the following color management blocks * per pipe (surface): * @@ -71,8 +73,8 @@ #define MAX_DRM_LUT_VALUE 0xFFFF -/* - * Initialize the color module. +/** + * amdgpu_dm_init_color_mod - Initialize the color module. * * We're not using the full color module, only certain components. * Only call setup functions for components that we need. @@ -82,7 +84,14 @@ void amdgpu_dm_init_color_mod(void) setup_x_points_distribution(); } -/* Extracts the DRM lut and lut size from a blob. */ +/** + * __extract_blob_lut - Extracts the DRM lut and lut size from a blob. + * @blob: DRM color mgmt property blob + * @size: lut size + * + * Returns: + * DRM LUT or NULL + */ static const struct drm_color_lut * __extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size) { @@ -90,13 +99,18 @@ __extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size) return blob ? (struct drm_color_lut *)blob->data : NULL; } -/* - * Return true if the given lut is a linear mapping of values, i.e. it acts - * like a bypass LUT. +/** + * __is_lut_linear - check if the given lut is a linear mapping of values + * @lut: given lut to check values + * @size: lut size * * It is considered linear if the lut represents: - * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in - * [0, MAX_COLOR_LUT_ENTRIES) + * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in [0, + * MAX_COLOR_LUT_ENTRIES) + * + * Returns: + * True if the given lut is a linear mapping of values, i.e. it acts like a + * bypass LUT. Otherwise, false. */ static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size) { @@ -119,9 +133,13 @@ static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size) return true; } -/* - * Convert the drm_color_lut to dc_gamma. The conversion depends on the size - * of the lut - whether or not it's legacy. +/** + * __drm_lut_to_dc_gamma - convert the drm_color_lut to dc_gamma. + * @lut: DRM lookup table for color conversion + * @gamma: DC gamma to set entries + * @is_legacy: legacy or atomic gamma + * + * The conversion depends on the size of the lut - whether or not it's legacy. */ static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut, struct dc_gamma *gamma, bool is_legacy) @@ -154,8 +172,11 @@ static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut, } } -/* - * Converts a DRM CTM to a DC CSC float matrix. +/** + * __drm_ctm_to_dc_matrix - converts a DRM CTM to a DC CSC float matrix + * @ctm: DRM color transformation matrix + * @matrix: DC CSC float matrix + * * The matrix needs to be a 3x4 (12 entry) matrix. */ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm, @@ -189,7 +210,18 @@ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm, } } -/* Calculates the legacy transfer function - only for sRGB input space. */ +/** + * __set_legacy_tf - Calculates the legacy transfer function + * @func: transfer function + * @lut: lookup table that defines the color space + * @lut_size: size of respective lut + * @has_rom: if ROM can be used for hardcoded curve + * + * Only for sRGB input space + * + * Returns: + * 0 in case of sucess, -ENOMEM if fails + */ static int __set_legacy_tf(struct dc_transfer_func *func, const struct drm_color_lut *lut, uint32_t lut_size, bool has_rom) @@ -218,7 +250,16 @@ static int __set_legacy_tf(struct dc_transfer_func *func, return res ? 0 : -ENOMEM; } -/* Calculates the output transfer function based on expected input space. */ +/** + * __set_output_tf - calculates the output transfer function based on expected input space. + * @func: transfer function + * @lut: lookup table that defines the color space + * @lut_size: size of respective lut + * @has_rom: if ROM can be used for hardcoded curve + * + * Returns: + * 0 in case of success. -ENOMEM if fails. + */ static int __set_output_tf(struct dc_transfer_func *func, const struct drm_color_lut *lut, uint32_t lut_size, bool has_rom) @@ -239,7 +280,7 @@ static int __set_output_tf(struct dc_transfer_func *func, __drm_lut_to_dc_gamma(lut, gamma, false); if (func->tf == TRANSFER_FUNCTION_LINEAR) { - /* + /** * Color module doesn't like calculating regamma params * on top of a linear input. But degamma params can be used * instead to simulate this. @@ -262,7 +303,16 @@ static int __set_output_tf(struct dc_transfer_func *func, return res ? 0 : -ENOMEM; } -/* Caculates the input transfer function based on expected input space. */ +/** + * __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) { @@ -285,13 +335,16 @@ static int __set_input_tf(struct dc_transfer_func *func, } /** - * amdgpu_dm_verify_lut_sizes + * amdgpu_dm_verify_lut_sizes - verifies if DRM luts match the hw supported sizes * @crtc_state: the DRM CRTC state + * @adev: amdgpu device * - * Verifies that the Degamma and Gamma LUTs attached to the |crtc_state| are of - * the expected size. + * Verifies that the Degamma and Gamma LUTs attached to the &crtc_state + * are of the expected size. * - * Returns 0 on success. + * Returns: + * 0 on success. + * -EINVAL if any lut sizes are invalid. */ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) { @@ -327,9 +380,9 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) * of the HW blocks as long as the CRTC CTM always comes before the * CRTC RGM and after the CRTC DGM. * - * The CRTC RGM block will be placed in the RGM LUT block if it is non-linear. - * The CRTC DGM block will be placed in the DGM LUT block if it is non-linear. - * The CRTC CTM will be placed in the gamut remap block if it is non-linear. + * * The CRTC RGM block will be placed in the RGM LUT block if it is non-linear. + * * The CRTC DGM block will be placed in the DGM LUT block if it is non-linear. + * * The CRTC CTM will be placed in the gamut remap block if it is non-linear. * * The RGM block is typically more fully featured and accurate across * all ASICs - DCE can't support a custom non-linear CRTC DGM. @@ -338,7 +391,9 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) * management at once we have to either restrict the usage of CRTC properties * or blend adjustments together. * - * Returns 0 on success. + * Returns: + * 0 on success. + * Error code if setup fails. */ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) { @@ -373,7 +428,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) /* Setup regamma and degamma. */ if (is_legacy) { - /* + /** * Legacy regamma forces us to use the sRGB RGM as a base. * This also means we can't use linear DGM since DGM needs * to use sRGB as a base as well, resulting in incorrect CRTC @@ -393,7 +448,8 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) if (r) return r; } else if (has_regamma) { - /* CRTC RGM goes into RGM LUT. */ + /** + * If atomic regamma, CRTC RGM goes into RGM LUT. */ stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; @@ -402,7 +458,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) 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. */ @@ -410,7 +466,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; } - /* + /** * CRTC DGM goes into DGM LUT. It would be nice to place it * into the RGM since it's a more featured block but we'd * have to place the CTM in the OCSC in that case. @@ -421,7 +477,7 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) if (crtc->base.ctm) { ctm = (struct drm_color_ctm *)crtc->base.ctm->data; - /* + /** * Gamut remapping must be used for gamma correction * since it comes before the regamma correction. * @@ -452,7 +508,9 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) * preparation for hardware commit. The transfer function used depends on * the prepartion done on the stream for color management. * - * Returns 0 on success. + * 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) From patchwork Sun Jun 19 22:31:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Melissa Wen X-Patchwork-Id: 12886872 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 883E6CCA47A for ; Sun, 19 Jun 2022 22:32:50 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 04329112ECB; Sun, 19 Jun 2022 22:32:48 +0000 (UTC) Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 323D7112EC1; Sun, 19 Jun 2022 22:32:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=k4T9PmxfWUShlC5HilgodhirfZbF+wehgo/l3DtFmWo=; b=k7AmeWfq7Bvm29kGoDUTPkZLhO 4CltBrqeKMxs7Hiz9gP7MNWIyWkysnDWrCD1+GMI425QwBaHclzuDdPVL+iKl/MzXPjwVadeRYw1x Ojpnu14WSlHCKw3tYs4mFgaZLTUFHGqN8+lbOBima5Pk7yE1KfGkPrw3zQ2+CfBGwCUjl0Nr+X9w3 na0QKnwAm0LDfbt6vfluoRj+toKOFDecUTeK6ui2AdLeIqlTSQeNlen/3FH/x/+DMutgbPYw142rC PK98PwpSGhAkj6+E2quv4LPguGq/L4yZavsf8fiL7UjJ4353dzzjHyi2oQ/QpzTRnO3eCInj7E7Uj brXHL84A==; Received: from [195.77.82.244] (helo=killbill.home) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1o33Sr-005lHy-0d; Mon, 20 Jun 2022 00:32:22 +0200 From: Melissa Wen To: alexander.deucher@amd.com, christian.koenig@amd.com, Xinhui.Pan@amd.com, airlied@linux.ie, daniel@ffwll.ch, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, harry.wentland@amd.com, sunpeng.li@amd.com, Rodrigo.Siqueira@amd.com Subject: [RFC PATCH 2/5] Documentation/amdgpu/display: add DC color caps info Date: Sun, 19 Jun 2022 21:31:01 -0100 Message-Id: <20220619223104.667413-3-mwen@igalia.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220619223104.667413-1-mwen@igalia.com> References: <20220619223104.667413-1-mwen@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.hung@amd.com, amd-gfx@lists.freedesktop.org, nikola.cornij@amd.com, seanpaul@chromium.org, dri-devel@lists.freedesktop.org, bhawanpreet.lakha@amd.com, nicholas.kazlauskas@amd.com, sungjoon.kim@amd.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add details about color correction capabilities and explain a bit about differences between DC hw generations and also how they are mapped between DRM and DC interface. Two schemas for DCN 2.0 and 3.0 (rasterized from the original png) is included to illustrate it. They were obtained from a discussion[1] in the amd-gfx mailing list. [1] https://lore.kernel.org/amd-gfx/20220422142811.dm6vtk6v64jcwydk@mail.igalia.com/ Signed-off-by: Melissa Wen --- .../amdgpu/display/dcn2_cm_drm_current.svg | 1370 +++++++++++++++ .../amdgpu/display/dcn3_cm_drm_current.svg | 1528 +++++++++++++++++ .../gpu/amdgpu/display/display-manager.rst | 35 + drivers/gpu/drm/amd/display/dc/dc.h | 53 +- 4 files changed, 2985 insertions(+), 1 deletion(-) create mode 100644 Documentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg create mode 100644 Documentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg diff --git a/Documentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg b/Documentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg new file mode 100644 index 000000000000..0156f56d4482 --- /dev/null +++ b/Documentation/gpu/amdgpu/display/dcn2_cm_drm_current.svg @@ -0,0 +1,1370 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Matrix + 1D LUT + 3D LUT + Unpacking + Other + drm_framebuffer + format + drm_plane + drm_crtc + Stream + MPC + DPP + + Blender + Degamma + CTM + Gamma + format + bias_and_scale + color space matrix + input_csc_color_matrix + in_transfer_func + hdr_mult + gamut_remap_matrix + in_shaper_func + lut3d_func + blend_tf + Blender + gamut_remap_matrix + func_shaper + lut3d_func + out_transfer_func + csc_color_matrix + bit_depth_param + clamping + output_color_space + Plane + Legend + DCN 2.0 + DC Interface + DRM Interface + + CNVC + Input CSC + DeGammaRAM and ROM(sRGB, BT2020 + HDR Multiply + Gamut Remap + Shaper LUTRAM + 3D LUTRAM + Blend Gamma + Blender + GammaRAM + OCSC + + + color_encoding + + pixel_blend_mode + + color_range + + + + + + + + + + + + + + diff --git a/Documentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg b/Documentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg new file mode 100644 index 000000000000..35f99f6db999 --- /dev/null +++ b/Documentation/gpu/amdgpu/display/dcn3_cm_drm_current.svg @@ -0,0 +1,1528 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Matrix + 1D LUT + 3D LUT + Unpacking + Other + drm_framebuffer + format + drm_plane + drm_crtc + Stream + MPC + DPP + + Blender + Degamma + CTM + Gamma + format + bias_and_scale + color space matrix + input_csc_color_matrix + in_transfer_func + hdr_mult + gamut_remap_matrix + in_shaper_func + lut3d_func + blend_tf + Blender + gamut_remap_matrix + func_shaper + lut3d_func + out_transfer_func + csc_color_matrix + bit_depth_param + clamping + output_color_space + Plane + Legend + DCN 3.0 + DC Interface + DRM Interface + + CNVC + Input CSC + DeGammaROM(sRGB, BT2020, Gamma 2.2,PQ, HLG) + Post CSC + Gamma Correction + HDR Multiply + Gamut Remap + Shaper LUTRAM + 3D LUTRAM + Blend Gamma + Blender + Gamut Remap + Shaper LUTRAM + 3D LUTRAM + GammaRAM + OCSC + + + color_encoding + + pixel_blend_mode + + color_range + + + + + + + + + + + + + + + + + + diff --git a/Documentation/gpu/amdgpu/display/display-manager.rst b/Documentation/gpu/amdgpu/display/display-manager.rst index b1b0f11aed83..8960a5f1fa66 100644 --- a/Documentation/gpu/amdgpu/display/display-manager.rst +++ b/Documentation/gpu/amdgpu/display/display-manager.rst @@ -49,3 +49,38 @@ Color Management Properties .. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c :internal: + + +DC Color Capabilities between DCN generations +--------------------------------------------- + +DRM/KMS framework defines three CRTC color correction properties: degamma, +color transformation matrix (ctm) and gamma, and two properties for degamma and +gamma lut sizes. AMD DC programs some of the color correction features +pre-blending but DRM/KMS has not per-plane color correction properties. + +What's possible to do before and after blending has changed quite a bit between +DCN generations as it depends on hardware color capabilities. DPP and MPC color +correction caps are described below. + +.. kernel-doc:: drivers/gpu/drm/amd/display/dc/dc.h + :doc: color-management-caps + +.. kernel-doc:: drivers/gpu/drm/amd/display/dc/dc.h + :internal: + +In general, the DRM three properties are programed to DC, as follows: CRTC +gamma after blending, and CRTC degamma pre-blending. Although CTM is programmed +after blending, it is mapped to DPP hw blocks (pre-blending). Other color caps +available in the hw is not currently exposed by DRM interface and are by +passed. To illustrate DCN generation capabilities and differences between +them, you can compare the color management schemas for DCN 2.0 and DCN 3.0 +families below. + +**DCN 2.0 family color caps and mapping** + +.. kernel-figure:: dcn2_cm_drm_current.svg + +**DCN 3.0 family color caps and mapping** + +.. kernel-figure:: dcn3_cm_drm_current.svg diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 76db013aac6e..5729de58a356 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -118,7 +118,26 @@ struct dc_plane_cap { uint32_t min_height; }; -// Color management caps (DPP and MPC) +/** + * DOC: color-management-caps + * + * **Color management caps (DPP and MPC)** + * + * Modules/color calculates various colour operations which are translated to + * abstracted HW. DCE 5-12 had almost no important changes, but starting with + * DCN1, every new generation comes with fairly major differences in color + * pipeline. Therefore, we abstract color pipe capabilities so modules/DM can + * decide mapping to HW block based on logical capabilities. + */ + +/** + * struct rom_curve_caps - predefined transfer function caps for degamma and regamma + * @srgb: RGB color space transfer func + * @bt2020: BT.2020 transfer func + * @gamma2_2: standard gamma + * @pq: perceptual quantizer transfer function + * @hlg: hybrid log–gamma transfer function + */ struct rom_curve_caps { uint16_t srgb : 1; uint16_t bt2020 : 1; @@ -127,6 +146,24 @@ struct rom_curve_caps { uint16_t hlg : 1; }; +/** + * struct dpp_color_caps - color pipeline capabilities for display pipe and plane blocks + * + * @dcn_arch: all DCE generations treated the same + * @input_lut_shared: shared with DGAM. Input lut is different than most LUTs, + * just plain 256-entry lookup + * @icsc: input color space convertion + * @post_csc: post color space convertion, before gamut remap + * @gamma_corr: degamma correction + * @hw_3d_lut: 3d lut support. It implies a shaper LUT before, it may be shared + * with MPC by setting mpc:shared_3d_lut flag + * @ogam_ram: blend gamma + * @ocsc: output color space convertion + * @dgam_rom_caps: caps for degamma + * @ogam_rom_caps: caps for regamma 1D lut + * + * Note: hdr_mult and gamut remap (ctm) are always available in DPP (in that order) + */ struct dpp_color_caps { uint16_t dcn_arch : 1; // all DCE generations treated the same // input lut is different than most LUTs, just plain 256-entry lookup @@ -147,6 +184,15 @@ struct dpp_color_caps { struct rom_curve_caps ogam_rom_caps; }; +/** + * struct mpc_color_caps - color pipeline capabilities for multiple pipe and plane combined blocks + * + * @gamut_remap: color transformation matrix + * @ocsc: output color space convertion matrix + * @num_3dluts: 3d lut, always assumes a preceding shaper LUT + * @shared_3d_lut: shared 3d lut flag, can be either DPP or MPC, but single instance + * @ogam_rom_caps: caps for regama 1d lut + */ struct mpc_color_caps { uint16_t gamut_remap : 1; uint16_t ogam_ram : 1; @@ -157,6 +203,11 @@ struct mpc_color_caps { struct rom_curve_caps ogam_rom_caps; }; +/** + * struct dc_color_caps - color pipes capabilities for DPP and MPC hw blocks + * @dpp: color pipes caps for DPP + * @mpc: color pipes caps for MPC + */ struct dc_color_caps { struct dpp_color_caps dpp; struct mpc_color_caps mpc; From patchwork Sun Jun 19 22:31:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Melissa Wen X-Patchwork-Id: 12886870 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 03F71C43334 for ; Sun, 19 Jun 2022 22:32:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C52D1112EC3; Sun, 19 Jun 2022 22:32:40 +0000 (UTC) Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id EFA14112EC1; Sun, 19 Jun 2022 22:32:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=xYy+B0EYyXJqj3PSzsn1daBxOJOCoTCFjWURuGWQBKs=; b=ZNBPH2BoEe81Rkwh9ZzXySFaVd 1Mjy7bZIhLIj+X8rrfkHEsLsCAJLgEvVcr+Jbu6MU9sVRuCZDb2Rmh58c5uTIstrBz7aABuGLGoZY gaasR2QwviAHYVdyL0DklZstYOs6tFh67ubdm9/813933tfUvvdqRSkPiA4RDAp8b543S7paJSsuS Ko8w5rkDkzr2qWGPxafXCMJi90BW0az3z5C6wUH/fq3Z5YgkPmP/AB1xFRf7/vhokeZPxrwThdOn/ oYdr4B/fogTNI25B397ZEAAeSEf+SMaz8a9t2IoR0te9fJtCdvvlozlWw+9T9P+fqkc9g4fYDKlBo qu+3a6eA==; Received: from [195.77.82.244] (helo=killbill.home) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1o33T3-005lHy-PS; Mon, 20 Jun 2022 00:32:31 +0200 From: Melissa Wen To: alexander.deucher@amd.com, christian.koenig@amd.com, Xinhui.Pan@amd.com, airlied@linux.ie, daniel@ffwll.ch, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, harry.wentland@amd.com, sunpeng.li@amd.com, Rodrigo.Siqueira@amd.com Subject: [RFC PATCH 3/5] drm/drm_color_mgmt: add shaper LUT to color mgmt properties Date: Sun, 19 Jun 2022 21:31:02 -0100 Message-Id: <20220619223104.667413-4-mwen@igalia.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220619223104.667413-1-mwen@igalia.com> References: <20220619223104.667413-1-mwen@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.hung@amd.com, amd-gfx@lists.freedesktop.org, nikola.cornij@amd.com, seanpaul@chromium.org, dri-devel@lists.freedesktop.org, bhawanpreet.lakha@amd.com, nicholas.kazlauskas@amd.com, sungjoon.kim@amd.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Shaper LUT is used to shape the contect after blending, i.e., de-linearize space before applying 3D LUT color correction. In the next patch, we are adding 3D LUT property to DRM color mgmt. Signed-off-by: Melissa Wen --- drivers/gpu/drm/drm_atomic_state_helper.c | 4 +++ drivers/gpu/drm/drm_atomic_uapi.c | 10 ++++++++ drivers/gpu/drm/drm_color_mgmt.c | 31 ++++++++++++++++++----- drivers/gpu/drm/drm_fb_helper.c | 3 +++ drivers/gpu/drm/drm_mode_config.c | 14 ++++++++++ include/drm/drm_crtc.h | 14 ++++++++-- include/drm/drm_mode_config.h | 12 +++++++++ 7 files changed, 79 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index ddcf5c2c8e6a..cf0545bb6e00 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -139,8 +139,11 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, drm_property_blob_get(state->degamma_lut); if (state->ctm) drm_property_blob_get(state->ctm); + if (state->shaper_lut) + drm_property_blob_get(state->shaper_lut); if (state->gamma_lut) drm_property_blob_get(state->gamma_lut); + state->mode_changed = false; state->active_changed = false; state->planes_changed = false; @@ -212,6 +215,7 @@ void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) drm_property_blob_put(state->mode_blob); drm_property_blob_put(state->degamma_lut); drm_property_blob_put(state->ctm); + drm_property_blob_put(state->shaper_lut); drm_property_blob_put(state->gamma_lut); } EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state); diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 9781722519c3..6468f2a080bc 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -464,6 +464,14 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, &replaced); state->color_mgmt_changed |= replaced; return ret; + } else if (property == config->shaper_lut_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + &state->shaper_lut, + val, + -1, sizeof(struct drm_color_lut), + &replaced); + state->color_mgmt_changed |= replaced; + return ret; } else if (property == config->gamma_lut_property) { ret = drm_atomic_replace_property_blob_from_id(dev, &state->gamma_lut, @@ -517,6 +525,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, *val = (state->ctm) ? state->ctm->base.id : 0; else if (property == config->gamma_lut_property) *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; + else if (property == config->shaper_lut_property) + *val = (state->shaper_lut) ? state->shaper_lut->base.id : 0; else if (property == config->prop_out_fence_ptr) *val = 0; else if (property == crtc->scaling_filter_property) diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index bb14f488c8f6..4f57dc60fe03 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -69,6 +69,24 @@ * boot-up state too. Drivers can access the blob for the color conversion * matrix through &drm_crtc_state.ctm. * + * “SHAPER_LUT”: + * Blob property to set the shaper lut shaping pixel data after the color + * transformation matrix and before applying 3D Lookup Table (3D LUT). It + * can be used to delinearize content to get an effective 3D LUT mapping. + * The data is interpreted as an array of &struct drm_color_lut elements. + * + * Setting this to NULL (blob property value set to 0) means the output + * color is identical to the input color. This is generally the driver + * boot-up state too. Drivers can access this blob through + * &drm_crtc_state.gamma_lut. + * + * “SHAPER_LUT_SIZE”: + * Unsigned range property to give the size of the shaper lookup table to + * be set on the SHAPER_LUT property (the size depends on the underlying + * hardware). If drivers support multiple LUT sizes then they should + * publish the largest size, and sub-sample smaller sized LUTs + * appropriately. + * * “GAMMA_LUT”: * Blob property to set the gamma lookup table (LUT) mapping pixel data * after the transformation matrix to data sent to the connector. The @@ -149,13 +167,12 @@ EXPORT_SYMBOL(drm_color_ctm_s31_32_to_qm_n); * @has_ctm: whether to attach ctm_property for CSC matrix * @gamma_lut_size: the size of the gamma lut (after CSC) * - * This function lets the driver enable the color correction - * properties on a CRTC. This includes 3 degamma, csc and gamma - * properties that userspace can set and 2 size properties to inform - * the userspace of the lut sizes. Each of the properties are - * optional. The gamma and degamma properties are only attached if - * their size is not 0 and ctm_property is only attached if has_ctm is - * true. + * This function lets the driver enable the color correction properties on a + * CRTC. This includes 3 properties (degamma, csc and gamma) that + * userspace can set and 2 size properties to inform the userspace of the lut + * sizes. Each of the properties are optional. The gamma and degamma + * properties are only attached if their size is not 0 and ctm_property is only + * attached if has_ctm is true. */ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, uint degamma_lut_size, diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index ed43b987d306..bdd33817d968 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1067,8 +1067,11 @@ static int setcmap_atomic(struct fb_cmap *cmap, struct fb_info *info) replaced = drm_property_replace_blob(&crtc_state->degamma_lut, NULL); replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL); + replaced |= drm_property_replace_blob(&crtc_state->shaper_lut, + NULL); replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, gamma_lut); + crtc_state->color_mgmt_changed |= replaced; } diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 37b4b9f0e468..4ba2a95b88e8 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -350,6 +350,20 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.ctm_property = prop; + prop = drm_property_create(dev, + DRM_MODE_PROP_BLOB, + "SHAPER_LUT", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.shaper_lut_property = prop; + + prop = drm_property_create_range(dev, + DRM_MODE_PROP_IMMUTABLE, + "SHAPER_LUT_SIZE", 0, UINT_MAX); + if (!prop) + return -ENOMEM; + dev->mode_config.shaper_lut_size_property = prop; + prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, "GAMMA_LUT", 0); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 13eeba2a750a..a318d5feb44b 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -165,8 +165,9 @@ struct drm_crtc_state { bool zpos_changed : 1; /** * @color_mgmt_changed: Color management properties have changed - * (@gamma_lut, @degamma_lut or @ctm). Used by the atomic helpers and - * drivers to steer the atomic commit control flow. + * (@shaper_lut, @gamma_lut, @degamma_lut or @ctm). Used by + * the atomic helpers and drivers to steer the atomic commit control + * flow. */ bool color_mgmt_changed : 1; @@ -288,6 +289,15 @@ struct drm_crtc_state { */ struct drm_property_blob *gamma_lut; + /** + * @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; + /** * @target_vblank: * diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 91ca575a78de..2df7e171add9 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -800,6 +800,18 @@ struct drm_mode_config { * degamma LUT. */ struct drm_property *ctm_property; + + /** + * @shaper_lut_property: Optional CRTC property to set the shaper LUT used to + * convert colors before 3D LUT conversion. + */ + struct drm_property *shaper_lut_property; + /** + * @shaper_lut_size_property: Optional CRTC property for the size of the + * shaper LUT as supported by the driver (read-only). + */ + struct drm_property *shaper_lut_size_property; + /** * @gamma_lut_property: Optional CRTC property to set the LUT used to * convert the colors, after the CTM matrix, to the gamma space of the From patchwork Sun Jun 19 22:31:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Melissa Wen X-Patchwork-Id: 12886871 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D5988C433EF for ; Sun, 19 Jun 2022 22:32:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CA4C4112EC6; Sun, 19 Jun 2022 22:32:47 +0000 (UTC) Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id A4F3F112EC1; Sun, 19 Jun 2022 22:32:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=VMeVt5GgYN2uaIeRHzX920KYm0jgkAHAMZxXnkIML9g=; b=pgQQkfDDzmwa2hg8Z7zrwiIhkQ wMmfbvfFzlMe66OlOjqFDW79xCsmyWoJyhS82MDkL2zH0CYn8MoO6M8wKt5n+PcIc+nq2bTNkLdcj Zo5bn9/2UywUwjqugOIqMm7bwyDNwJZU+kxpuJWDm0aPyjgyK1ExtHXW08et06pnQgsudJHfChqYn qZvqOHE+ZYE0VU4SWgreeMnuT5rpJsmWbqiKzuH67dtaHsenAE5mRHCAmr8dDyp5bv9krE0e7jbvz G9UqN5M5QSpru5Dl1trqd6rPd5BpkmYQilPUpiVzEr+eX7PopgoAezZYUgUJfe52dn+zK+vCm1uN/ 7WD0ukjQ==; Received: from [195.77.82.244] (helo=killbill.home) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1o33TC-005lHy-8P; Mon, 20 Jun 2022 00:32:39 +0200 From: Melissa Wen To: alexander.deucher@amd.com, christian.koenig@amd.com, Xinhui.Pan@amd.com, airlied@linux.ie, daniel@ffwll.ch, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, harry.wentland@amd.com, sunpeng.li@amd.com, Rodrigo.Siqueira@amd.com Subject: [RFC PATCH 4/5] drm/drm_color_mgmt: add 3D LUT to color mgmt properties Date: Sun, 19 Jun 2022 21:31:03 -0100 Message-Id: <20220619223104.667413-5-mwen@igalia.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220619223104.667413-1-mwen@igalia.com> References: <20220619223104.667413-1-mwen@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.hung@amd.com, amd-gfx@lists.freedesktop.org, nikola.cornij@amd.com, seanpaul@chromium.org, dri-devel@lists.freedesktop.org, bhawanpreet.lakha@amd.com, nicholas.kazlauskas@amd.com, sungjoon.kim@amd.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Add 3D LUT for gammar correction using a 3D lookup table. The position in the color correction pipeline where 3D LUT is applied depends on hw design, being after CTM or gamma. If just after CTM, 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 its color capabilities. Signed-off-by: Melissa Wen --- drivers/gpu/drm/drm_atomic_state_helper.c | 3 ++ drivers/gpu/drm/drm_atomic_uapi.c | 14 +++++- drivers/gpu/drm/drm_color_mgmt.c | 58 +++++++++++++++++++++++ drivers/gpu/drm/drm_fb_helper.c | 2 + drivers/gpu/drm/drm_mode_config.c | 14 ++++++ include/drm/drm_color_mgmt.h | 4 ++ include/drm/drm_crtc.h | 12 ++++- include/drm/drm_mode_config.h | 13 +++++ 8 files changed, 117 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index cf0545bb6e00..64800bc41365 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -141,6 +141,8 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, drm_property_blob_get(state->ctm); if (state->shaper_lut) drm_property_blob_get(state->shaper_lut); + if (state->lut3d) + drm_property_blob_get(state->lut3d); if (state->gamma_lut) drm_property_blob_get(state->gamma_lut); @@ -216,6 +218,7 @@ void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) drm_property_blob_put(state->degamma_lut); drm_property_blob_put(state->ctm); drm_property_blob_put(state->shaper_lut); + drm_property_blob_put(state->lut3d); drm_property_blob_put(state->gamma_lut); } EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state); diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index 6468f2a080bc..1896c0422f73 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -472,6 +472,14 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc, &replaced); state->color_mgmt_changed |= replaced; return ret; + } else if (property == config->lut3d_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + &state->lut3d, + val, + -1, sizeof(struct drm_color_lut), + &replaced); + state->color_mgmt_changed |= replaced; + return ret; } else if (property == config->gamma_lut_property) { ret = drm_atomic_replace_property_blob_from_id(dev, &state->gamma_lut, @@ -523,10 +531,12 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc, *val = (state->degamma_lut) ? state->degamma_lut->base.id : 0; else if (property == config->ctm_property) *val = (state->ctm) ? state->ctm->base.id : 0; - else if (property == config->gamma_lut_property) - *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; else if (property == config->shaper_lut_property) *val = (state->shaper_lut) ? state->shaper_lut->base.id : 0; + else if (property == config->lut3d_property) + *val = (state->lut3d) ? state->lut3d->base.id : 0; + else if (property == config->gamma_lut_property) + *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; else if (property == config->prop_out_fence_ptr) *val = 0; else if (property == crtc->scaling_filter_property) diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index 4f57dc60fe03..696fe1e37801 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -87,6 +87,25 @@ * publish the largest size, and sub-sample smaller sized LUTs * appropriately. * + * “LUT3D”: + * Blob property to set the 3D LUT mapping pixel data after the color + * transformation matrix and before gamma 1D lut correction. The + * data is interpreted as an array of &struct drm_color_lut elements. + * Hardware might choose not to use the full precision of the LUT + * elements. + * + * Setting this to NULL (blob property value set to 0) means a the output + * color is identical to the input color. This is generally the driver + * boot-up state too. Drivers can access this blob through + * &drm_crtc_state.gamma_lut. + * + * “LUT3D_SIZE”: + * Unsigned range property to give the size of the 3D lookup table to be + * set on the LUT3D property (the size depends on the underlying + * hardware). If drivers support multiple LUT sizes then they should + * publish the largest size, and sub-sample smaller sized LUTs + * appropriately. + * * “GAMMA_LUT”: * Blob property to set the gamma lookup table (LUT) mapping pixel data * after the transformation matrix to data sent to the connector. The @@ -204,6 +223,45 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, } EXPORT_SYMBOL(drm_crtc_enable_color_mgmt); +/** + * drm_crtc_enable_lut3d - enable 3D LUT properties + * @crtc: DRM CRTC + * @shaper_lut_size: the size of shaper lut + * @lut3d_size: the size of 3D lut + * + * This function lets the driver enable the 3D LUT color correction property + * on a CRTC. This includes 3D LUT and also a shaper LUT, if set. The shaper + * LUT property is only attached if its size is not 0 and 3D LUT is set, being + * therefore optional. + */ +void drm_crtc_enable_lut3d(struct drm_crtc *crtc, + uint shaper_lut_size, + uint lut3d_size) +{ + struct drm_device *dev = crtc->dev; + struct drm_mode_config *config = &dev->mode_config; + + if (!lut3d_size) + return; + + drm_object_attach_property(&crtc->base, + config->lut3d_property, 0); + drm_object_attach_property(&crtc->base, + config->lut3d_size_property, + lut3d_size); + if (!shaper_lut_size) + return; + + drm_object_attach_property(&crtc->base, + config->shaper_lut_property, 0); + drm_object_attach_property(&crtc->base, + config->shaper_lut_size_property, + lut3d_size); + +} +EXPORT_SYMBOL(drm_crtc_enable_lut3d); + + /** * drm_mode_crtc_set_gamma_size - set the gamma table size * @crtc: CRTC to set the gamma table size for diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index bdd33817d968..358c528c7c80 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1069,6 +1069,8 @@ static int setcmap_atomic(struct fb_cmap *cmap, struct fb_info *info) replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL); replaced |= drm_property_replace_blob(&crtc_state->shaper_lut, NULL); + replaced |= drm_property_replace_blob(&crtc_state->lut3d, + NULL); replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, gamma_lut); diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 4ba2a95b88e8..5458a7dfbe63 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -364,6 +364,20 @@ static int drm_mode_create_standard_properties(struct drm_device *dev) return -ENOMEM; dev->mode_config.shaper_lut_size_property = prop; + prop = drm_property_create(dev, + DRM_MODE_PROP_BLOB, + "LUT3D", 0); + if (!prop) + return -ENOMEM; + dev->mode_config.lut3d_property = prop; + + prop = drm_property_create_range(dev, + DRM_MODE_PROP_IMMUTABLE, + "LUT3D_SIZE", 0, UINT_MAX); + if (!prop) + return -ENOMEM; + dev->mode_config.lut3d_size_property = prop; + prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, "GAMMA_LUT", 0); diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h index 81c298488b0c..a4f054e0108f 100644 --- a/include/drm/drm_color_mgmt.h +++ b/include/drm/drm_color_mgmt.h @@ -59,6 +59,10 @@ void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc, bool has_ctm, uint gamma_lut_size); +void drm_crtc_enable_lut3d(struct drm_crtc *crtc, + uint shaper_lut_size, + uint lut3d_size); + int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index a318d5feb44b..c22ffcc4d7aa 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -165,7 +165,7 @@ struct drm_crtc_state { bool zpos_changed : 1; /** * @color_mgmt_changed: Color management properties have changed - * (@shaper_lut, @gamma_lut, @degamma_lut or @ctm). Used by + * (@shaper_lut, @lut3d, @gamma_lut, @degamma_lut or @ctm). Used by * the atomic helpers and drivers to steer the atomic commit control * flow. */ @@ -298,6 +298,16 @@ struct drm_crtc_state { */ 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; + /** * @target_vblank: * diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 2df7e171add9..87280694e70d 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -812,6 +812,19 @@ struct drm_mode_config { */ struct drm_property *shaper_lut_size_property; + /** + * @lut3d_property: Optional CRTC property to set the 3D LUT used to + * convert colors; before or after gamma conversion depends on hw + * design. A shaper LUT can be used to delinearize content before apply + * 3D LUT correction. + */ + struct drm_property *lut3d_property; + /** + * @lut3d_size_property: Optional CRTC property for the size of the + * 3D LUT as supported by the driver (read-only). + */ + struct drm_property *lut3d_size_property; + /** * @gamma_lut_property: Optional CRTC property to set the LUT used to * convert the colors, after the CTM matrix, to the gamma space of the From patchwork Sun Jun 19 22:31:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Melissa Wen X-Patchwork-Id: 12886873 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9AFD3C433EF for ; Sun, 19 Jun 2022 22:33:58 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D0DDD10E3CD; Sun, 19 Jun 2022 22:33:56 +0000 (UTC) Received: from fanzine2.igalia.com (fanzine.igalia.com [178.60.130.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6462010E3CD; Sun, 19 Jun 2022 22:33:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=SxhspAKE7SzQn5FJuFHB9m9JcLfDn2Aj35mp7jzgkM0=; b=DU/dQCJtGW7lm5B02H3kt4PsAS cMeCaDGoEMyjfdPToEhpjb8RB1O7ZnhvOSE6rdx9La4hjwLAjnagbDTbyU0HA8RyDbmlWGBxHZqYo jDI8xshR+7VOqCNNdOvUzppxu/aM46pmzKfMFrHQbF1Aov0uz1ACRHp11pTQhYme+RK8trKaz7V3m KQ41BvNvOrzMKPFmaq9yfkhJ3HsxnillhToe6p6eloO4A6EwbPt0cMn+sFD1XUKjI9+wqbGbtx3/I zqAq1lG2o5e34V6EW3eH8TuHB3Q3Dj8MBbwF+U/JcMlL0g+Ur4/sSb44neBHe1IE0R2/l9Pj+EksQ Efq7ZEag==; Received: from [195.77.82.244] (helo=killbill.home) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1o33UH-005lHy-G6; Mon, 20 Jun 2022 00:33:47 +0200 From: Melissa Wen To: alexander.deucher@amd.com, christian.koenig@amd.com, Xinhui.Pan@amd.com, airlied@linux.ie, daniel@ffwll.ch, maarten.lankhorst@linux.intel.com, mripard@kernel.org, tzimmermann@suse.de, harry.wentland@amd.com, sunpeng.li@amd.com, Rodrigo.Siqueira@amd.com Subject: [RFC PATCH 5/5] drm/amd/display: mapping new DRM 3D LUT properties to AMD hw blocks Date: Sun, 19 Jun 2022 21:31:04 -0100 Message-Id: <20220619223104.667413-6-mwen@igalia.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220619223104.667413-1-mwen@igalia.com> References: <20220619223104.667413-1-mwen@igalia.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.hung@amd.com, amd-gfx@lists.freedesktop.org, nikola.cornij@amd.com, seanpaul@chromium.org, dri-devel@lists.freedesktop.org, bhawanpreet.lakha@amd.com, nicholas.kazlauskas@amd.com, sungjoon.kim@amd.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" After adding 3D LUT (and shaper LUT) to DRM CRTC color management properties, map shaper lut and 3d lut properties to MPC blocks if DC hw is capable to handle 3dlut after-blending. In this case, the property only applies to DCN 3 family, as DCN 2 only has 3D support pre-blending and should be exposed by a DRM per-plane property in the future. Signed-off-by: Melissa Wen --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 3 +- .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 153 +++++++++++++++--- drivers/gpu/drm/amd/display/dc/dc_stream.h | 4 +- 4 files changed, 137 insertions(+), 25 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 06da4f2ed7ad..02ed3991a803 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -11221,7 +11221,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, dm_old_crtc_state->dsc_force_changed == false) continue; - ret = amdgpu_dm_verify_lut_sizes(new_crtc_state); + ret = amdgpu_dm_verify_lut_sizes(new_crtc_state, adev); if (ret) { DRM_DEBUG_DRIVER("amdgpu_dm_verify_lut_sizes() failed\n"); 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 8fd1be7f2583..205503f12d87 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -721,9 +721,10 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev); #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 +#define COLOR_3DLUT_ENTRIES 17 void amdgpu_dm_init_color_mod(void); -int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state); +int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state, struct amdgpu_device *adev); int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc); 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 1f4a7c908587..d22396976c7a 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 @@ -210,6 +210,45 @@ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm, } } +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, 12); + rgb->green = drm_color_lut_extract(lut.green, 12); + rgb->blue = drm_color_lut_extract(lut.blue, 12); + +} + +static void __drm_lut3d_to_dc_lut3d(const struct drm_color_lut *lut, + struct dc_3dlut *lut3d) +{ + int lut3d_size = COLOR_3DLUT_ENTRIES*COLOR_3DLUT_ENTRIES*COLOR_3DLUT_ENTRIES; + int lutn_size = (lut3d_size - 1)/4 + 1; + int i; + + ASSERT(lut3d && lut3d_size == MAX_COLOR_LUT_ENTRIES); + + /* So far, only supports 17x17x17 3D LUT with 12-bit*/ + lut3d->lut_3d.use_tetrahedral_9 = false; + lut3d->lut_3d.use_12bits = true; + + for (i = 0; i < lutn_size - 1 ; i++) { + /* We should consider the 3dlut RGB values are distributed + * along four arrays lut0-3 where the first sizes 1229 and the + * other 1228. The max bit precision supported for 3dlut + * channel is 12-bit, but can be 10-bit. Still need to verify + * where it is setup */ + __to_dc_lut3d_color(&lut3d->lut_3d.tetrahedral_17.lut0[i], lut[i], 12); + __to_dc_lut3d_color(&lut3d->lut_3d.tetrahedral_17.lut1[i], lut[i+lutn_size], 12); + __to_dc_lut3d_color(&lut3d->lut_3d.tetrahedral_17.lut2[i], lut[i+lutn_size*2], 12); + __to_dc_lut3d_color(&lut3d->lut_3d.tetrahedral_17.lut3[i], lut[i+lutn_size*3], 12); + } + + /* lut0 goes to lutn_size == 1229 */ + __to_dc_lut3d_color(&lut3d->lut_3d.tetrahedral_17.lut0[i], lut[i], 12); +}; + /** * __set_legacy_tf - Calculates the legacy transfer function * @func: transfer function @@ -335,7 +374,20 @@ static int __set_input_tf(struct dc_transfer_func *func, } /** - * amdgpu_dm_verify_lut_sizes - verifies if DRM luts match the hw supported sizes + * amdgpu_dm_3dlut_size - get expected size according to hw color caps + * @lut_size: default size + * @adev: amdgpu device + * + * Return: + * lut_size if 3dlut is supported, zero otherwise + */ +static int amdgpu_dm_3dlut_size(int lut_size, struct amdgpu_device *adev) +{ + return adev->dm.dc->caps.color.mpc.num_3dluts ? lut_size : 0; +} + +/** + * amdgpu_dm_verify_lut_sizes * @crtc_state: the DRM CRTC state * @adev: amdgpu device * @@ -346,10 +398,11 @@ static int __set_input_tf(struct dc_transfer_func *func, * 0 on success. * -EINVAL if any lut sizes are invalid. */ -int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) +int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state, + struct amdgpu_device *adev) { const struct drm_color_lut *lut = NULL; - uint32_t size = 0; + uint32_t size = 0, exp_size; lut = __extract_blob_lut(crtc_state->degamma_lut, &size); if (lut && size != MAX_COLOR_LUT_ENTRIES) { @@ -359,6 +412,24 @@ int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) return -EINVAL; } + lut = __extract_blob_lut(crtc_state->shaper_lut, &size); + exp_size = amdgpu_dm_3dlut_size(MAX_COLOR_LUT_ENTRIES, adev); + if (lut && size != exp_size) { + DRM_DEBUG_DRIVER( + "Invalid Shaper LUT size. Should be %u but got %u.\n", + exp_size, size); + return -EINVAL; + } + + lut = __extract_blob_lut(crtc_state->lut3d, &size); + exp_size = amdgpu_dm_3dlut_size(COLOR_3DLUT_ENTRIES, adev); + if (lut && size != exp_size) { + DRM_DEBUG_DRIVER( + "Invalid Gamma 3D LUT size. Should be %u but got %u.\n", + exp_size, size); + return -EINVAL; + } + lut = __extract_blob_lut(crtc_state->gamma_lut, &size); if (lut && size != MAX_COLOR_LUT_ENTRIES && size != MAX_COLOR_LEGACY_LUT_ENTRIES) { @@ -401,17 +472,19 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) struct amdgpu_device *adev = drm_to_adev(crtc->base.state->dev); bool has_rom = adev->asic_type <= CHIP_RAVEN; struct drm_color_ctm *ctm = NULL; - const struct drm_color_lut *degamma_lut, *regamma_lut; - uint32_t degamma_size, regamma_size; - bool has_regamma, has_degamma; + const struct drm_color_lut *degamma_lut, *shaper_lut, *lut3d, *regamma_lut; + uint32_t degamma_size, regamma_size, shaper_size, lut3d_size; + bool has_regamma, has_degamma, has_lut3d, has_shaper_lut; bool is_legacy; int r; - r = amdgpu_dm_verify_lut_sizes(&crtc->base); + r = amdgpu_dm_verify_lut_sizes(&crtc->base, adev); if (r) return r; degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, °amma_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, ®amma_size); has_degamma = @@ -420,6 +493,12 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) has_regamma = regamma_lut && !__is_lut_linear(regamma_lut, regamma_size); + has_shaper_lut = + shaper_lut && !__is_lut_linear(shaper_lut, shaper_size); + + has_lut3d = shaper_lut && lut3d && + !__is_lut_linear(lut3d, lut3d_size); + is_legacy = regamma_size == MAX_COLOR_LEGACY_LUT_ENTRIES; /* Reset all adjustments. */ @@ -447,23 +526,55 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) regamma_size, has_rom); if (r) return r; - } else if (has_regamma) { - /** - * If atomic regamma, CRTC RGM goes into RGM LUT. */ - 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); - 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. + /* If no 3D LUT, use regamma original settings that means + * linear input space. */ - stream->out_transfer_func->type = TF_TYPE_BYPASS; stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; + + if (has_lut3d && has_shaper_lut) { + /* 3D LUT always implies a shaper 1D LUT to + * de-linearize and shape the content. + * Q: I see func_shaper and lut3d_func is originally + * const, is it expected? If so, where is the point to + * update them? + */ + stream->func_shaper->type = TF_TYPE_DISTRIBUTED_POINTS; + stream->func_shaper->tf = TRANSFER_FUNCTION_LINEAR; + r = __set_output_tf(stream->func_shaper, shaper_lut, + shaper_size, has_rom); + if (r) + return r; + + /* Function to convert DRM 3D LUT to DC 3D LUT*/ + __drm_lut3d_to_dc_lut3d(lut3d, stream->lut3d_func); + + /* Set different input space to gamma lut, since gamma + * 1D LUT will be applied in a non-linear space after + * 3D LUT. But which predefined function to select for + * gamma after 3D LUT? + */ + stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; + } + + if (has_regamma) { + /** + * CRTC RGM goes into RGM LUT. + */ + stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; + + r = __set_output_tf(stream->out_transfer_func, 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; + } } /** diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index f8f66790d09b..a7cc6ace5904 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -246,8 +246,8 @@ struct dc_stream_state { /* writeback */ unsigned int num_wb_info; struct dc_writeback_info writeback_info[MAX_DWB_PIPES]; - const struct dc_transfer_func *func_shaper; - const struct dc_3dlut *lut3d_func; + struct dc_transfer_func *func_shaper; + struct dc_3dlut *lut3d_func; /* Computed state bits */ bool mode_changed : 1;