From patchwork Thu Aug 10 16:02:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Melissa Wen X-Patchwork-Id: 134069 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b824:0:b0:3f2:4152:657d with SMTP id z4csp523040vqi; Thu, 10 Aug 2023 09:07:01 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHy10nmLUObh7+UYXIcSCJqV60kBfH83ten0TddTycv9xO9PKolNFj9MgjIc9Cx0Blc4LPc X-Received: by 2002:a17:907:760d:b0:992:13c7:563 with SMTP id jx13-20020a170907760d00b0099213c70563mr2363877ejc.75.1691683620976; Thu, 10 Aug 2023 09:07:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691683620; cv=none; d=google.com; s=arc-20160816; b=VvJyhRulDlU8nmIQJaAS9c1Yaz/7uQZgKJ+V5T86VClFeKKWi0pwfAJMMbLSgpGQ3d J1ED6Qpj9EChQPo/Omf0FsYAoOE9L9hDCPAjsjtXwJGJL6LKJGFEUsWE9AjMsUFh9+m2 TnxNMA3st7mK9r2vXhqx4BtxAVYPgFL4K+lT+lPq6Lb5Uhc3zo443hAnImnA6O4jBbZH rLVMfmhMOVVNwQEQYBWowSd757uIVcdqvOZicl/YEX2tBpLIR1rgJqjprcoE2nuG2qNr XEnrzxPJfC8wxXeWJ2y/ACCK1k1JcgOhHwsvRjAeC04xfxxn7WJWolN8rRKfC2UVz1kg pAdg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=3AVBAr082q4rBxH/YVFTkGB+6GGW8BMoNEmTi8POMDI=; fh=K4g2hpcHeis9i+u86e9V+yTBU0PZFkfdrKenkMdV+qw=; b=AGcBBe2f0bm/sXNTSEfxpBjejne+AXnbedcScWy/aVTTJkbTDxQsrXAN8Du0Ud+fbS uykh+4Gr3z5G1tBAQOqC+HrDKucSWnlCjg4LddhDLulawhLI/jOX4+TXoYCbGZL3eEhG bD8a08R4zxg9aLHtqysdJc12QrNtVle0B6zOUC90qFXgT0NqQkkdR3poKBF+p3/qVrVl GcEkpWzuCXujmYbWqG9jt8edTN4fZgzfoL2xjSndG9dv3ZGXH0Q6DF8k3JtFDVM2hQxc 8D9V5Y9jP1qkuwRZmpHju+pjR1IDlBkDKs7qi1P/QFYirJssobvkmIgWueXxTfT+GAlf PJOQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@igalia.com header.s=20170329 header.b=emCa+ELd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id v8-20020a170906858800b00997e8ac3332si1814017ejx.340.2023.08.10.09.06.24; Thu, 10 Aug 2023 09:07:00 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=fail header.i=@igalia.com header.s=20170329 header.b=emCa+ELd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236511AbjHJQET (ORCPT + 99 others); Thu, 10 Aug 2023 12:04:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54810 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236336AbjHJQDy (ORCPT ); Thu, 10 Aug 2023 12:03:54 -0400 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5AEDA2738 for ; Thu, 10 Aug 2023 09:03:50 -0700 (PDT) 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=3AVBAr082q4rBxH/YVFTkGB+6GGW8BMoNEmTi8POMDI=; b=emCa+ELd7sUevg0Gt2NRd1TfVo eyYtxXAdfc88eLJfj7Ad5Clgjf5Of358FE2opYeAHju30p+zI2pUqzytLs9tEZT0dEzkLyz6RaVbo PZU4EYZN+kcCxAy/4/Xu03w/2NtRH3+klTNg3QUE/Ps5+oIZS0EghK4sT2wOK8Y0haA5jL8DILb9j C3D0+gQPdTow6xqOQ+UAEHGcoQRJQm+aQCWDPVCFc2Pg/6NHmnMl7Q1ox1KYP57zApuEJDsPDj4EE P0ryqs0zqX1GoQB9qPis+97qsLLve3QR3sje+L2s8jflGmKOyPaWU6q8W49DH4q7QjKuWkM93GH7d KcNhvIqA==; Received: from [38.44.68.151] (helo=killbill.home) by fanzine2.igalia.com with esmtpsa (Cipher TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim) id 1qU88U-00GjYD-00; Thu, 10 Aug 2023 18:03:42 +0200 From: Melissa Wen To: amd-gfx@lists.freedesktop.org, Harry Wentland , Rodrigo Siqueira , sunpeng.li@amd.com, Alex Deucher , dri-devel@lists.freedesktop.org, christian.koenig@amd.com, Xinhui.Pan@amd.com, airlied@gmail.com, daniel@ffwll.ch Cc: Joshua Ashton , Sebastian Wick , Xaver Hugl , Shashank Sharma , Nicholas Kazlauskas , sungjoon.kim@amd.com, Alex Hung , Pekka Paalanen , Simon Ser , kernel-dev@igalia.com, linux-kernel@vger.kernel.org Subject: [PATCH v2 11/34] drm/amd/display: add plane shaper LUT and TF driver-specific properties Date: Thu, 10 Aug 2023 15:02:51 -0100 Message-Id: <20230810160314.48225-12-mwen@igalia.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230810160314.48225-1-mwen@igalia.com> References: <20230810160314.48225-1-mwen@igalia.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773858844689626630 X-GMAIL-MSGID: 1773858844689626630 On AMD HW, 3D LUT always assumes a preceding shaper 1D LUT used for delinearizing and/or normalizing the color space before applying a 3D LUT. Add pre-defined transfer function to enable delinearizing content with or without shaper LUT, where AMD color module calculates the resulted shaper curve. We apply an inverse EOTF to go from linear values to encoded values. If we are already in a non-linear space and/or don't need to normalize values, we can bypass shaper LUT with a linear transfer function that is also the default TF value. v2: - squash commits for shaper LUT and shaper TF - define inverse EOTF as supported shaper TFs Signed-off-by: Melissa Wen --- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 16 ++++++++++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 11 +++++++ .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 29 +++++++++++++++++ .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 32 +++++++++++++++++++ 4 files changed, 88 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 730a88236501..4fb164204ee6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -363,6 +363,22 @@ struct amdgpu_mode_info { * @plane_hdr_mult_property: */ struct drm_property *plane_hdr_mult_property; + /** + * @shaper_lut_property: Plane property to set pre-blending shaper LUT + * that converts color content before 3D LUT. + */ + struct drm_property *plane_shaper_lut_property; + /** + * @shaper_lut_size_property: Plane property for the size of + * pre-blending shaper LUT as supported by the driver (read-only). + */ + struct drm_property *plane_shaper_lut_size_property; + /** + * @plane_shaper_tf_property: Plane property to set a predefined + * transfer function for pre-blending shaper (before applying 3D LUT) + * with or without LUT. + */ + struct drm_property *plane_shaper_tf_property; /** * @plane_lut3d_property: Plane property for gamma correction using a * 3D LUT (pre-blending). diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index deea90212e31..6b6c2980f0af 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -769,6 +769,17 @@ struct dm_plane_state { * S31.32 sign-magnitude. */ __u64 hdr_mult; + /** + * @shaper_lut: shaper lookup table blob. The blob (if not NULL) is an + * array of &struct drm_color_lut. + */ + struct drm_property_blob *shaper_lut; + /** + * @shaper_tf: + * + * Predefined transfer function to delinearize color space. + */ + enum amdgpu_transfer_function shaper_tf; /** * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of * &struct drm_color_lut. diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c index 7e6d4df99a0c..fbcee717bf0a 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 @@ -151,6 +151,14 @@ static const u32 amdgpu_eotf = BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA24_EOTF) | BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA26_EOTF); +static const u32 amdgpu_inv_eotf = + BIT(AMDGPU_TRANSFER_FUNCTION_SRGB_INV_EOTF) | + BIT(AMDGPU_TRANSFER_FUNCTION_BT709_INV_EOTF) | + BIT(AMDGPU_TRANSFER_FUNCTION_PQ_INV_EOTF) | + BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA22_INV_EOTF) | + BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA24_INV_EOTF) | + BIT(AMDGPU_TRANSFER_FUNCTION_GAMMA26_INV_EOTF); + static struct drm_property * amdgpu_create_tf_property(struct drm_device *dev, const char *name, @@ -209,6 +217,27 @@ amdgpu_dm_create_color_properties(struct amdgpu_device *adev) return -ENOMEM; adev->mode_info.plane_hdr_mult_property = prop; + prop = drm_property_create(adev_to_drm(adev), + DRM_MODE_PROP_BLOB, + "AMD_PLANE_SHAPER_LUT", 0); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_shaper_lut_property = prop; + + prop = drm_property_create_range(adev_to_drm(adev), + DRM_MODE_PROP_IMMUTABLE, + "AMD_PLANE_SHAPER_LUT_SIZE", 0, UINT_MAX); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_shaper_lut_size_property = prop; + + prop = amdgpu_create_tf_property(adev_to_drm(adev), + "AMD_PLANE_SHAPER_TF", + amdgpu_inv_eotf); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_shaper_tf_property = prop; + prop = drm_property_create(adev_to_drm(adev), DRM_MODE_PROP_BLOB, "AMD_PLANE_LUT3D", 0); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c index 882391f7add6..8d6ddf19bb87 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -1332,6 +1332,7 @@ static void dm_drm_plane_reset(struct drm_plane *plane) __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base); amdgpu_state->degamma_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT; amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT; + amdgpu_state->shaper_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT; } static struct drm_plane_state * @@ -1353,11 +1354,14 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) if (dm_plane_state->degamma_lut) drm_property_blob_get(dm_plane_state->degamma_lut); + if (dm_plane_state->shaper_lut) + drm_property_blob_get(dm_plane_state->shaper_lut); if (dm_plane_state->lut3d) drm_property_blob_get(dm_plane_state->lut3d); dm_plane_state->degamma_tf = old_dm_plane_state->degamma_tf; dm_plane_state->hdr_mult = old_dm_plane_state->hdr_mult; + dm_plane_state->shaper_tf = old_dm_plane_state->shaper_tf; return &dm_plane_state->base; } @@ -1430,6 +1434,8 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane, drm_property_blob_put(dm_plane_state->degamma_lut); if (dm_plane_state->lut3d) drm_property_blob_put(dm_plane_state->lut3d); + if (dm_plane_state->shaper_lut) + drm_property_blob_put(dm_plane_state->shaper_lut); if (dm_plane_state->dc_state) dc_plane_state_release(dm_plane_state->dc_state); @@ -1462,6 +1468,14 @@ dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, AMDGPU_HDR_MULT_DEFAULT); if (dpp_color_caps.hw_3d_lut) { + drm_object_attach_property(&plane->base, + mode_info.plane_shaper_lut_property, 0); + drm_object_attach_property(&plane->base, + mode_info.plane_shaper_lut_size_property, + MAX_COLOR_LUT_ENTRIES); + drm_object_attach_property(&plane->base, + mode_info.plane_shaper_tf_property, + AMDGPU_TRANSFER_FUNCTION_DEFAULT); drm_object_attach_property(&plane->base, mode_info.plane_lut3d_property, 0); drm_object_attach_property(&plane->base, @@ -1499,6 +1513,19 @@ dm_atomic_plane_set_property(struct drm_plane *plane, dm_plane_state->hdr_mult = val; dm_plane_state->base.color_mgmt_changed = 1; } + } else if (property == adev->mode_info.plane_shaper_lut_property) { + ret = drm_property_replace_blob_from_id(plane->dev, + &dm_plane_state->shaper_lut, + val, -1, + sizeof(struct drm_color_lut), + &replaced); + dm_plane_state->base.color_mgmt_changed |= replaced; + return ret; + } else if (property == adev->mode_info.plane_shaper_tf_property) { + if (dm_plane_state->shaper_tf != val) { + dm_plane_state->shaper_tf = val; + dm_plane_state->base.color_mgmt_changed = 1; + } } else if (property == adev->mode_info.plane_lut3d_property) { ret = drm_property_replace_blob_from_id(plane->dev, &dm_plane_state->lut3d, @@ -1534,6 +1561,11 @@ dm_atomic_plane_get_property(struct drm_plane *plane, *val = dm_plane_state->degamma_tf; } else if (property == adev->mode_info.plane_hdr_mult_property) { *val = dm_plane_state->hdr_mult; + } else if (property == adev->mode_info.plane_shaper_lut_property) { + *val = (dm_plane_state->shaper_lut) ? + dm_plane_state->shaper_lut->base.id : 0; + } else if (property == adev->mode_info.plane_shaper_tf_property) { + *val = dm_plane_state->shaper_tf; } else if (property == adev->mode_info.plane_lut3d_property) { *val = (dm_plane_state->lut3d) ? dm_plane_state->lut3d->base.id : 0;