[V7 35/45] drm/amd/display: add 3x4 matrix colorop

Leo Li sunpeng.li at amd.com
Thu Feb 13 17:16:15 UTC 2025



On 2024-12-19 23:33, Alex Hung wrote:
> This adds support for a 3x4 color transformation matrix.
> 
> With this change the following IGT tests pass:
> kms_colorop --run plane-XR30-XR30-ctm_3x4_50_desat
> kms_colorop --run plane-XR30-XR30-ctm_3x4_overdrive
> kms_colorop --run plane-XR30-XR30-ctm_3x4_oversaturate
> kms_colorop --run plane-XR30-XR30-ctm_3x4_bt709_enc
> kms_colorop --run plane-XR30-XR30-ctm_3x4_bt709_dec
> 
> The color pipeline now consists of the following colorops:
> 1. 1D curve colorop
> 2. 3x4 CTM
> 3. 1D curve colorop
> 4. 1D LUT
> 5. 1D curve colorop
> 6. 1D LUT
> 
> Signed-off-by: Alex Hung <alex.hung at amd.com>
> Signed-off-by: Harry Wentland <harry.wentland at amd.com>
> ---
> v7:
>   - Change %lu to %zu for sizeof() when In drm_warn
> 
> v6:
>   - fix warnings in dbg prints
> 
>   .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 50 +++++++++++++++++++
>   .../amd/display/amdgpu_dm/amdgpu_dm_colorop.c | 16 ++++++
>   2 files changed, 66 insertions(+)
> 
> 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 0bea52eede39..5d6effe6f90e 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
> @@ -1211,6 +1211,45 @@ __set_dm_plane_colorop_degamma(struct drm_plane_state *plane_state,
>   	return __set_colorop_in_tf_1d_curve(dc_plane_state, colorop_state);
>   }
>   
> +static int
> +__set_dm_plane_colorop_3x4_matrix(struct drm_plane_state *plane_state,
> +				  struct dc_plane_state *dc_plane_state,
> +				  struct drm_colorop *colorop)
> +{
> +	struct drm_colorop *old_colorop;
> +	struct drm_colorop_state *colorop_state = NULL, *new_colorop_state;
> +	struct drm_atomic_state *state = plane_state->state;
> +	const struct drm_device *dev = colorop->dev;
> +	const struct drm_property_blob *blob;
> +	struct drm_color_ctm_3x4 *ctm = NULL;
> +	int i = 0;
> +
> +	/* 3x4 matrix */
> +	old_colorop = colorop;
> +	for_each_new_colorop_in_state(state, colorop, new_colorop_state, i) {
> +		if (new_colorop_state->colorop == old_colorop &&
> +		    new_colorop_state->colorop->type == DRM_COLOROP_CTM_3X4) {
> +			colorop_state = new_colorop_state;
> +			break;
> +		}
> +	}
> +
> +	if (colorop_state && !colorop_state->bypass && colorop->type == DRM_COLOROP_CTM_3X4) {
> +		drm_dbg(dev, "3x4 matrix colorop with ID: %d\n", colorop->base.id);
> +		blob = colorop_state->data;
> +		if (blob->length == sizeof(struct drm_color_ctm_3x4)) {
> +			ctm = blob ? (struct drm_color_ctm_3x4 *) blob->data : NULL;
> +			__drm_ctm_3x4_to_dc_matrix(ctm, dc_plane_state->gamut_remap_matrix.matrix);
> +			dc_plane_state->gamut_remap_matrix.enable_remap = true;
> +			dc_plane_state->input_csc_color_matrix.enable_adjustment = false;
> +		} else
> +			drm_warn(dev, "blob->length (%lu) isn't equal to drm_color_ctm_3x4 (%zu)\n",
> +				 blob->length, sizeof(struct drm_color_ctm_3x4));

Should -EINVAL be returned here?
- Leo

> +	}
> +
> +	return 0;
> +}
> +
>   static int
>   __set_dm_plane_colorop_shaper(struct drm_plane_state *plane_state,
>   			      struct dc_plane_state *dc_plane_state,
> @@ -1409,6 +1448,17 @@ amdgpu_dm_plane_set_colorop_properties(struct drm_plane_state *plane_state,
>   	if (ret)
>   		return ret;
>   
> +	/* 3x4 matrix */
> +	colorop = colorop->next;
> +	if (!colorop) {
> +		drm_dbg(dev, "no 3x4 matrix colorop found\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = __set_dm_plane_colorop_3x4_matrix(plane_state, dc_plane_state, colorop);
> +	if (ret)
> +		return ret;
> +
>   	/* 1D Curve & LUT - SHAPER TF & LUT */
>   	colorop = colorop->next;
>   	if (!colorop) {
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
> index 8a5e15083f11..9a9386bf85ec 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c
> @@ -75,6 +75,22 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr
>   
>   	i++;
>   
> +	/* 3x4 matrix */
> +	ops[i] = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL);
> +	if (!ops[i]) {
> +		DRM_ERROR("KMS: Failed to allocate colorop\n");
> +		ret = -ENOMEM;
> +		goto cleanup;
> +	}
> +
> +	ret = drm_colorop_ctm_3x4_init(dev, ops[i], plane);
> +	if (ret)
> +		goto cleanup;
> +
> +	drm_colorop_set_next_property(ops[i-1], ops[i]);
> +
> +	i++;
> +
>   	/* 1D curve - SHAPER TF */
>   	ops[i] = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL);
>   	if (!ops[i]) {



More information about the wayland-devel mailing list