Received: by 2002:a05:6358:51dd:b0:131:369:b2a3 with SMTP id 29csp1334867rwl; Thu, 10 Aug 2023 09:36:57 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFiG6aJ/DCF5Re6RhxNODOPmOSbZiisCVOWkVxY6oOJ9frxc/1D16uawo3MJerIt7wygwKq X-Received: by 2002:a05:6a20:4421:b0:13f:7ffe:855e with SMTP id ce33-20020a056a20442100b0013f7ffe855emr3561002pzb.45.1691685416399; Thu, 10 Aug 2023 09:36:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691685416; cv=none; d=google.com; s=arc-20160816; b=aWTpoqffRepybMoNidYyJbCCafHRQnGuQHIoCDzks46yrSFSY/G1TYaK/rkWi7LecS mzeTo1fJw2OW+mDYMkYZAh3NTOhUWt7mprJxIDqJd3rWnxs2KWtSoTRxJBijXFnw05Jt 7QI/M3cJIeW/YJS8ygtiw1sewTEa6cSck2aU/ZVppFuGkQkGshqv2ZrrFzwyFqtx3oTz +ED2aJX3PtyEK3WQjLRsQN2OxEPtGZ1BFZ09+o6Sj+2adyuy6N8ZDA8mE7//gYBMmIZD W7O2sP0krLvn57GidTcU2aRMiuep5iqbz24GthoBjUxxiVg+eVHaykf0EXchLCSb1LvK 7dJg== 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=9D+sOG90D4swtOov18+zIz0GOUaWYMvws/wo1WCwL5I=; fh=K4g2hpcHeis9i+u86e9V+yTBU0PZFkfdrKenkMdV+qw=; b=LlE2JLGwcXWvZgpDi1bagfUKiYJqdAGCIyjr9+sLGyo1Rj1WXyMvmh6fCFPcjYf/bR qNskWBoDHapETzA4xSntHRcXg20IGSx0jAIdxt62/l0KVM9R9DiEiO0lgSmWK51GiX40 w2Pn0pnTeQfno7Bg4le44x2s0aZuQqBSVr5sX/kIkxK5jIQTYDTJMoQGWtcT10TC5yuT mHcm5iaD8tzVAfNp8M5SpieY7bNb00zBMRoaJhyAp6HyF/JPopEJo1UR+6n6BYsD4GzY ICHYnF0+wOL+bKZkHWgGAoqJStHiD7KtR1tD2DujNuNVCoEMUS+yQ3R+edV7ZUeIvYtl 6/0w== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@igalia.com header.s=20170329 header.b="DxdrX/dL"; 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 Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id a19-20020a63d413000000b0055c8fd5fe00si1763157pgh.886.2023.08.10.09.36.44; Thu, 10 Aug 2023 09:36:56 -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="DxdrX/dL"; 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 S236653AbjHJQGJ (ORCPT + 99 others); Thu, 10 Aug 2023 12:06:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33556 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236553AbjHJQFT (ORCPT ); Thu, 10 Aug 2023 12:05:19 -0400 Received: from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CEB3A3AAF for ; Thu, 10 Aug 2023 09:04:26 -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=9D+sOG90D4swtOov18+zIz0GOUaWYMvws/wo1WCwL5I=; b=DxdrX/dLbfzG23bLvw11clvFMg DO3hen4LLZDo8qfjYm61Wb4vBEbPqwPLNOxgMrMqw/f3K7lo7jiEl4dkoPPiL1W05s60Zk8nJiQ9/ WYAgHH+9nTKDyD62CB30jgevAPymqvJTTTPuIout/CVr9WBgkOotBE8ule0ljmGa0jKlzMOGOim3s CpiaTBmpbzuou5wKLHK3wegBFQjlzAcOJDgE70JQmT5K723f4oGCIMBngMiRFnGGIAL9uHilGSBX1 tpET4LuB4Mp+tegxHIE4sqA0OwCZXE/pfx0xIkILE8K7erIHwlIfO+cHyDI5W6YRo/HsojaR0cfO0 exXAiIxw==; 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 1qU890-00GjYD-Cs; Thu, 10 Aug 2023 18:04:14 +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 26/34] drm/amd/display: add plane 3D LUT support Date: Thu, 10 Aug 2023 15:03:06 -0100 Message-Id: <20230810160314.48225-27-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 Content-Transfer-Encoding: 8bit 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 Wire up DC 3D LUT to DM plane color management (pre-blending). On AMD display HW, 3D LUT comes after a shaper curve and we always have to program a shaper curve to delinearize or normalize the color space before applying a 3D LUT (since we have a reduced number of LUT entries). In this version, the default values of 3D LUT for size and bit_depth are 17x17x17 and 12-bit, but we already provide here a more generic mechanisms to program other supported values (9x9x9 size and 10-bit). v2: - started with plane 3D LUT instead of CRTC 3D LUT support Reviewed-by: Harry Wentland (v1) Signed-off-by: Melissa Wen --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + .../amd/display/amdgpu_dm/amdgpu_dm_color.c | 96 ++++++++++++++++++- 2 files changed, 94 insertions(+), 3 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 347ecff2c920..025a7eb5c8aa 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8062,6 +8062,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix; bundle->surface_updates[planes_count].hdr_mult = dc_plane->hdr_mult; bundle->surface_updates[planes_count].func_shaper = dc_plane->in_shaper_func; + bundle->surface_updates[planes_count].lut3d_func = dc_plane->lut3d_func; } amdgpu_dm_plane_fill_dc_scaling_info(dm->adev, new_plane_state, 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 90ec09ca4118..58c4797f506e 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 @@ -598,6 +598,85 @@ amdgpu_tf_to_dc_tf(enum amdgpu_transfer_function tf) } } +static void __to_dc_lut3d_color(struct dc_rgb *rgb, + const struct drm_color_lut lut, + int bit_precision) +{ + rgb->red = drm_color_lut_extract(lut.red, bit_precision); + rgb->green = drm_color_lut_extract(lut.green, bit_precision); + rgb->blue = drm_color_lut_extract(lut.blue, bit_precision); +} + +static void __drm_3dlut_to_dc_3dlut(const struct drm_color_lut *lut, + uint32_t lut3d_size, + struct tetrahedral_params *params, + bool use_tetrahedral_9, + int bit_depth) +{ + struct dc_rgb *lut0; + struct dc_rgb *lut1; + struct dc_rgb *lut2; + struct dc_rgb *lut3; + int lut_i, i; + + + if (use_tetrahedral_9) { + lut0 = params->tetrahedral_9.lut0; + lut1 = params->tetrahedral_9.lut1; + lut2 = params->tetrahedral_9.lut2; + lut3 = params->tetrahedral_9.lut3; + } else { + lut0 = params->tetrahedral_17.lut0; + lut1 = params->tetrahedral_17.lut1; + lut2 = params->tetrahedral_17.lut2; + lut3 = params->tetrahedral_17.lut3; + } + + for (lut_i = 0, i = 0; i < lut3d_size - 4; lut_i++, i += 4) { + /* We should consider the 3dlut RGB values are distributed + * along four arrays lut0-3 where the first sizes 1229 and the + * other 1228. The bit depth supported for 3dlut channel is + * 12-bit, but DC also supports 10-bit. + * + * TODO: improve color pipeline API to enable the userspace set + * bit depth and 3D LUT size/stride, as specified by VA-API. + */ + __to_dc_lut3d_color(&lut0[lut_i], lut[i], bit_depth); + __to_dc_lut3d_color(&lut1[lut_i], lut[i + 1], bit_depth); + __to_dc_lut3d_color(&lut2[lut_i], lut[i + 2], bit_depth); + __to_dc_lut3d_color(&lut3[lut_i], lut[i + 3], bit_depth); + } + /* lut0 has 1229 points (lut_size/4 + 1) */ + __to_dc_lut3d_color(&lut0[lut_i], lut[i], bit_depth); +} + +/* amdgpu_dm_atomic_lut3d - set DRM 3D LUT to DC stream + * @drm_lut3d: DRM CRTC (user) 3D LUT + * @drm_lut3d_size: size of 3D LUT + * @lut3d: DC 3D LUT + * + * Map DRM CRTC 3D LUT to DC 3D LUT and all necessary bits to program it + * on DCN MPC accordingly. + */ +static void amdgpu_dm_atomic_lut3d(const struct drm_color_lut *drm_lut, + uint32_t drm_lut3d_size, + struct dc_3dlut *lut) +{ + if (!drm_lut3d_size) { + lut->state.bits.initialized = 0; + } else { + /* Stride and bit depth are not programmable by API yet. + * Therefore, only supports 17x17x17 3D LUT (12-bit). + */ + lut->lut_3d.use_tetrahedral_9 = false; + lut->lut_3d.use_12bits = true; + lut->state.bits.initialized = 1; + __drm_3dlut_to_dc_3dlut(drm_lut, drm_lut3d_size, &lut->lut_3d, + lut->lut_3d.use_tetrahedral_9, + MAX_COLOR_3DLUT_BITDEPTH); + } +} + static int amdgpu_dm_atomic_shaper_lut(const struct drm_color_lut *shaper_lut, bool has_rom, enum dc_transfer_func_predefined tf, @@ -652,7 +731,7 @@ int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev, struct drm_plane_state *plane_state) { struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); - const struct drm_color_lut *shaper = NULL; + const struct drm_color_lut *shaper = NULL, *lut3d = NULL; uint32_t exp_size, size; /* shaper LUT is only available if 3D LUT color caps*/ @@ -663,6 +742,14 @@ int amdgpu_dm_verify_lut3d_size(struct amdgpu_device *adev, drm_dbg(&adev->ddev, "Invalid Shaper LUT size. Should be %u but got %u.\n", exp_size, size); + } + + exp_size = amdgpu_dm_get_lut3d_size(adev, MAX_COLOR_3DLUT_ENTRIES); + lut3d = __extract_blob_lut(dm_plane_state->lut3d, &size); + + if (lut3d && size != exp_size) { + drm_dbg(&adev->ddev, "Invalid 3D LUT size. Should be %u but got %u.\n", + exp_size, size); return -EINVAL; } @@ -962,8 +1049,8 @@ amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state, { struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane_state); enum amdgpu_transfer_function shaper_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT; - const struct drm_color_lut *shaper_lut; - uint32_t shaper_size; + const struct drm_color_lut *shaper_lut, *lut3d; + uint32_t shaper_size, lut3d_size; int ret; /* We have nothing to do here, return */ @@ -975,7 +1062,10 @@ amdgpu_dm_plane_set_color_properties(struct drm_plane_state *plane_state, shaper_lut = __extract_blob_lut(dm_plane_state->shaper_lut, &shaper_size); shaper_size = shaper_lut != NULL ? shaper_size : 0; shaper_tf = dm_plane_state->shaper_tf; + lut3d = __extract_blob_lut(dm_plane_state->lut3d, &lut3d_size); + lut3d_size = lut3d != NULL ? lut3d_size : 0; + amdgpu_dm_atomic_lut3d(lut3d, lut3d_size, dc_plane_state->lut3d_func); ret = amdgpu_dm_atomic_shaper_lut(shaper_lut, false, amdgpu_tf_to_dc_tf(shaper_tf), shaper_size, -- 2.40.1