mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 06:57:30 -04:00
drm/amd/display: Add KUnit test for color helpers
Add KUnit tests for six pure-logic functions in amdgpu_dm_color.c: amdgpu_dm_fixpt_from_s3132, __is_lut_linear, __drm_ctm_to_dc_matrix, __drm_ctm_3x4_to_dc_matrix, amdgpu_tf_to_dc_tf, and amdgpu_colorop_tf_to_dc_tf. Expose these static functions under CONFIG_DRM_AMD_DC_KUNIT_TEST and add a new amdgpu_dm_color.h header with the KUnit-only prototypes. The test file re-declares the dc and amdgpu transfer function enums locally to avoid pulling in the full DC/amdgpu include chain that fails under UML. 26 test cases cover signed-magnitude to two's complement conversion, LUT linearity detection, CTM-to-DC matrix conversion, and transfer function enum mapping. Assisted-by: Copilot:Claude-Opus-4.6 Reviewed-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Ivan Lipski <ivan.lipski@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -29,9 +29,12 @@
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_mode.h"
|
||||
#include "amdgpu_dm.h"
|
||||
#include "amdgpu_dm_color.h"
|
||||
#include "amdgpu_dm_colorop.h"
|
||||
#include "dc.h"
|
||||
#include "modules/color/color_gamma.h"
|
||||
#include "amdgpu_dm_kunit_helpers.h"
|
||||
|
||||
|
||||
/**
|
||||
* DOC: overview
|
||||
@@ -157,8 +160,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#define MAX_DRM_LUT_VALUE 0xFFFF
|
||||
#define MAX_DRM_LUT32_VALUE 0xFFFFFFFF
|
||||
#define SDR_WHITE_LEVEL_INIT_VALUE 80
|
||||
|
||||
/**
|
||||
@@ -172,7 +173,8 @@ void amdgpu_dm_init_color_mod(void)
|
||||
setup_x_points_distribution();
|
||||
}
|
||||
|
||||
static inline struct fixed31_32 amdgpu_dm_fixpt_from_s3132(__u64 x)
|
||||
STATIC_IFN_KUNIT INLINE_IFN_KUNIT
|
||||
struct fixed31_32 amdgpu_dm_fixpt_from_s3132(__u64 x)
|
||||
{
|
||||
struct fixed31_32 val;
|
||||
|
||||
@@ -183,6 +185,7 @@ static inline struct fixed31_32 amdgpu_dm_fixpt_from_s3132(__u64 x)
|
||||
val.value = x;
|
||||
return val;
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_fixpt_from_s3132);
|
||||
|
||||
#ifdef AMD_PRIVATE_COLOR
|
||||
/* Pre-defined Transfer Functions (TF)
|
||||
@@ -421,12 +424,14 @@ amdgpu_dm_create_color_properties(struct amdgpu_device *adev)
|
||||
* Returns:
|
||||
* DRM LUT or NULL
|
||||
*/
|
||||
static const struct drm_color_lut *
|
||||
STATIC_IFN_KUNIT
|
||||
const struct drm_color_lut *
|
||||
__extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size)
|
||||
{
|
||||
*size = blob ? drm_color_lut_size(blob) : 0;
|
||||
return blob ? (struct drm_color_lut *)blob->data : NULL;
|
||||
}
|
||||
EXPORT_IF_KUNIT(__extract_blob_lut);
|
||||
|
||||
/**
|
||||
* __extract_blob_lut32 - Extracts the DRM lut and lut size from a blob.
|
||||
@@ -436,12 +441,14 @@ __extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size)
|
||||
* Returns:
|
||||
* DRM LUT or NULL
|
||||
*/
|
||||
static const struct drm_color_lut32 *
|
||||
STATIC_IFN_KUNIT
|
||||
const struct drm_color_lut32 *
|
||||
__extract_blob_lut32(const struct drm_property_blob *blob, uint32_t *size)
|
||||
{
|
||||
*size = blob ? drm_color_lut32_size(blob) : 0;
|
||||
return blob ? (struct drm_color_lut32 *)blob->data : NULL;
|
||||
}
|
||||
EXPORT_IF_KUNIT(__extract_blob_lut32);
|
||||
|
||||
/**
|
||||
* __is_lut_linear - check if the given lut is a linear mapping of values
|
||||
@@ -456,7 +463,8 @@ __extract_blob_lut32(const struct drm_property_blob *blob, uint32_t *size)
|
||||
* 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)
|
||||
STATIC_IFN_KUNIT
|
||||
bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size)
|
||||
{
|
||||
int i;
|
||||
uint32_t expected;
|
||||
@@ -476,6 +484,7 @@ static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
EXPORT_IF_KUNIT(__is_lut_linear);
|
||||
|
||||
/**
|
||||
* __drm_lut_to_dc_gamma - convert the drm_color_lut to dc_gamma.
|
||||
@@ -485,7 +494,8 @@ static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size)
|
||||
*
|
||||
* 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,
|
||||
STATIC_IFN_KUNIT
|
||||
void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
|
||||
struct dc_gamma *gamma, bool is_legacy)
|
||||
{
|
||||
uint32_t r, g, b;
|
||||
@@ -515,6 +525,7 @@ static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
|
||||
gamma->entries.blue[i] = dc_fixpt_from_fraction(b, MAX_DRM_LUT_VALUE);
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(__drm_lut_to_dc_gamma);
|
||||
|
||||
/**
|
||||
* __drm_lut32_to_dc_gamma - convert the drm_color_lut to dc_gamma.
|
||||
@@ -523,7 +534,8 @@ static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
|
||||
*
|
||||
* The conversion depends on the size of the lut - whether or not it's legacy.
|
||||
*/
|
||||
static void __drm_lut32_to_dc_gamma(const struct drm_color_lut32 *lut, struct dc_gamma *gamma)
|
||||
STATIC_IFN_KUNIT
|
||||
void __drm_lut32_to_dc_gamma(const struct drm_color_lut32 *lut, struct dc_gamma *gamma)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -533,6 +545,7 @@ static void __drm_lut32_to_dc_gamma(const struct drm_color_lut32 *lut, struct dc
|
||||
gamma->entries.blue[i] = dc_fixpt_from_fraction(lut[i].blue, MAX_DRM_LUT32_VALUE);
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(__drm_lut32_to_dc_gamma);
|
||||
|
||||
/**
|
||||
* __drm_ctm_to_dc_matrix - converts a DRM CTM to a DC CSC float matrix
|
||||
@@ -541,8 +554,9 @@ static void __drm_lut32_to_dc_gamma(const struct drm_color_lut32 *lut, struct dc
|
||||
*
|
||||
* The matrix needs to be a 3x4 (12 entry) matrix.
|
||||
*/
|
||||
static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
|
||||
struct fixed31_32 *matrix)
|
||||
STATIC_IFN_KUNIT
|
||||
void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
|
||||
struct fixed31_32 *matrix)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -565,6 +579,7 @@ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
|
||||
matrix[i] = amdgpu_dm_fixpt_from_s3132(ctm->matrix[i - (i / 4)]);
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(__drm_ctm_to_dc_matrix);
|
||||
|
||||
/**
|
||||
* __drm_ctm_3x4_to_dc_matrix - converts a DRM CTM 3x4 to a DC CSC float matrix
|
||||
@@ -573,8 +588,9 @@ static void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
|
||||
*
|
||||
* The matrix needs to be a 3x4 (12 entry) matrix.
|
||||
*/
|
||||
static void __drm_ctm_3x4_to_dc_matrix(const struct drm_color_ctm_3x4 *ctm,
|
||||
struct fixed31_32 *matrix)
|
||||
STATIC_IFN_KUNIT
|
||||
void __drm_ctm_3x4_to_dc_matrix(const struct drm_color_ctm_3x4 *ctm,
|
||||
struct fixed31_32 *matrix)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -587,6 +603,7 @@ static void __drm_ctm_3x4_to_dc_matrix(const struct drm_color_ctm_3x4 *ctm,
|
||||
matrix[i] = amdgpu_dm_fixpt_from_s3132(ctm->matrix[i]);
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(__drm_ctm_3x4_to_dc_matrix);
|
||||
|
||||
/**
|
||||
* __set_legacy_tf - Calculates the legacy transfer function
|
||||
@@ -851,7 +868,8 @@ static int __set_input_tf_32(struct dc_color_caps *caps, struct dc_transfer_func
|
||||
return res ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
static enum dc_transfer_func_predefined
|
||||
STATIC_IFN_KUNIT
|
||||
enum dc_transfer_func_predefined
|
||||
amdgpu_tf_to_dc_tf(enum amdgpu_transfer_function tf)
|
||||
{
|
||||
switch (tf) {
|
||||
@@ -879,8 +897,10 @@ amdgpu_tf_to_dc_tf(enum amdgpu_transfer_function tf)
|
||||
return TRANSFER_FUNCTION_GAMMA26;
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_tf_to_dc_tf);
|
||||
|
||||
static enum dc_transfer_func_predefined
|
||||
STATIC_IFN_KUNIT
|
||||
enum dc_transfer_func_predefined
|
||||
amdgpu_colorop_tf_to_dc_tf(enum drm_colorop_curve_1d_type tf)
|
||||
{
|
||||
switch (tf) {
|
||||
@@ -900,8 +920,10 @@ amdgpu_colorop_tf_to_dc_tf(enum drm_colorop_curve_1d_type tf)
|
||||
return TRANSFER_FUNCTION_LINEAR;
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_colorop_tf_to_dc_tf);
|
||||
|
||||
static void __to_dc_lut3d_color(struct dc_rgb *rgb,
|
||||
STATIC_IFN_KUNIT
|
||||
void __to_dc_lut3d_color(struct dc_rgb *rgb,
|
||||
const struct drm_color_lut lut,
|
||||
int bit_precision)
|
||||
{
|
||||
@@ -909,8 +931,10 @@ static void __to_dc_lut3d_color(struct dc_rgb *rgb,
|
||||
rgb->green = drm_color_lut_extract(lut.green, bit_precision);
|
||||
rgb->blue = drm_color_lut_extract(lut.blue, bit_precision);
|
||||
}
|
||||
EXPORT_IF_KUNIT(__to_dc_lut3d_color);
|
||||
|
||||
static void __drm_3dlut_to_dc_3dlut(const struct drm_color_lut *lut,
|
||||
STATIC_IFN_KUNIT
|
||||
void __drm_3dlut_to_dc_3dlut(const struct drm_color_lut *lut,
|
||||
uint32_t lut3d_size,
|
||||
struct tetrahedral_params *params,
|
||||
bool use_tetrahedral_9,
|
||||
@@ -953,8 +977,10 @@ static void __drm_3dlut_to_dc_3dlut(const struct drm_color_lut *lut,
|
||||
/* lut0 has 1229 points (lut_size/4 + 1) */
|
||||
__to_dc_lut3d_color(&lut0[lut_i], lut[i], bit_depth);
|
||||
}
|
||||
EXPORT_IF_KUNIT(__drm_3dlut_to_dc_3dlut);
|
||||
|
||||
static void __to_dc_lut3d_32_color(struct dc_rgb *rgb,
|
||||
STATIC_IFN_KUNIT
|
||||
void __to_dc_lut3d_32_color(struct dc_rgb *rgb,
|
||||
const struct drm_color_lut32 lut,
|
||||
int bit_precision)
|
||||
{
|
||||
@@ -962,8 +988,10 @@ static void __to_dc_lut3d_32_color(struct dc_rgb *rgb,
|
||||
rgb->green = drm_color_lut32_extract(lut.green, bit_precision);
|
||||
rgb->blue = drm_color_lut32_extract(lut.blue, bit_precision);
|
||||
}
|
||||
EXPORT_IF_KUNIT(__to_dc_lut3d_32_color);
|
||||
|
||||
static void __drm_3dlut32_to_dc_3dlut(const struct drm_color_lut32 *lut,
|
||||
STATIC_IFN_KUNIT
|
||||
void __drm_3dlut32_to_dc_3dlut(const struct drm_color_lut32 *lut,
|
||||
uint32_t lut3d_size,
|
||||
struct tetrahedral_params *params,
|
||||
bool use_tetrahedral_9,
|
||||
@@ -1006,6 +1034,7 @@ static void __drm_3dlut32_to_dc_3dlut(const struct drm_color_lut32 *lut,
|
||||
/* lut0 has 1229 points (lut_size/4 + 1) */
|
||||
__to_dc_lut3d_32_color(&lut0[lut_i], lut[i], bit_depth);
|
||||
}
|
||||
EXPORT_IF_KUNIT(__drm_3dlut32_to_dc_3dlut);
|
||||
|
||||
/* amdgpu_dm_atomic_lut3d - set DRM 3D LUT to DC stream
|
||||
* @drm_lut3d: user 3D LUT
|
||||
|
||||
89
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.h
Normal file
89
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* Copyright 2026 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: AMD
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __AMDGPU_DM_COLOR_H__
|
||||
#define __AMDGPU_DM_COLOR_H__
|
||||
|
||||
#define MAX_DRM_LUT_VALUE 0xFFFF
|
||||
#define MAX_DRM_LUT32_VALUE 0xFFFFFFFF
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct drm_color_lut;
|
||||
struct drm_color_lut32;
|
||||
struct drm_color_ctm;
|
||||
struct drm_color_ctm_3x4;
|
||||
struct drm_property_blob;
|
||||
struct dc_gamma;
|
||||
struct dc_rgb;
|
||||
struct fixed31_32;
|
||||
struct tetrahedral_params;
|
||||
|
||||
#ifdef CONFIG_DRM_AMD_DC_KUNIT_TEST
|
||||
/*
|
||||
* Prototypes for functions exposed to KUnit tests. The enum types
|
||||
* used below (dc_transfer_func_predefined, amdgpu_transfer_function,
|
||||
* drm_colorop_curve_1d_type) must be defined before this header is
|
||||
* included — the source file (amdgpu_dm_color.c) ensures this via
|
||||
* its own includes of dc.h, amdgpu_dm.h, and drm/drm_colorop.h.
|
||||
*/
|
||||
struct fixed31_32 amdgpu_dm_fixpt_from_s3132(__u64 x);
|
||||
bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t size);
|
||||
void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
|
||||
struct dc_gamma *gamma, bool is_legacy);
|
||||
void __drm_lut32_to_dc_gamma(const struct drm_color_lut32 *lut,
|
||||
struct dc_gamma *gamma);
|
||||
void __drm_ctm_to_dc_matrix(const struct drm_color_ctm *ctm,
|
||||
struct fixed31_32 *matrix);
|
||||
void __drm_ctm_3x4_to_dc_matrix(const struct drm_color_ctm_3x4 *ctm,
|
||||
struct fixed31_32 *matrix);
|
||||
enum dc_transfer_func_predefined
|
||||
amdgpu_tf_to_dc_tf(enum amdgpu_transfer_function tf);
|
||||
enum dc_transfer_func_predefined
|
||||
amdgpu_colorop_tf_to_dc_tf(enum drm_colorop_curve_1d_type tf);
|
||||
const struct drm_color_lut *
|
||||
__extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size);
|
||||
const struct drm_color_lut32 *
|
||||
__extract_blob_lut32(const struct drm_property_blob *blob, uint32_t *size);
|
||||
void __to_dc_lut3d_color(struct dc_rgb *rgb,
|
||||
const struct drm_color_lut lut,
|
||||
int bit_precision);
|
||||
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);
|
||||
void __to_dc_lut3d_32_color(struct dc_rgb *rgb,
|
||||
const struct drm_color_lut32 lut,
|
||||
int bit_precision);
|
||||
void __drm_3dlut32_to_dc_3dlut(const struct drm_color_lut32 *lut,
|
||||
uint32_t lut3d_size,
|
||||
struct tetrahedral_params *params,
|
||||
bool use_tetrahedral_9,
|
||||
int bit_depth);
|
||||
#endif
|
||||
|
||||
#endif /* __AMDGPU_DM_COLOR_H__ */
|
||||
@@ -7,7 +7,9 @@ ccflags-y += -I$(src)/../..
|
||||
ccflags-y += -I$(src)/../../include
|
||||
ccflags-y += -I$(src)/../../modules/inc
|
||||
ccflags-y += -I$(src)/../../dc
|
||||
ccflags-y += -I$(src)/../../../amdgpu
|
||||
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_crc_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_hdcp_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_color_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_colorop_test.o
|
||||
|
||||
1071
drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_color_test.c
Normal file
1071
drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_color_test.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user