Skip to content

Commit ea3f6ba

Browse files
Harry Wentlandemersion
authored andcommitted
drm/vkms: add 3x4 matrix in color pipeline
We add two 3x4 matrices into the VKMS color pipeline. The reason we're adding matrices is so that we can test that application of a matrix and its inverse yields an output equal to the input image. One complication with the matrix implementation has to do with the fact that the matrix entries are in signed-magnitude fixed point, whereas the drm_fixed.h implementation uses 2s-complement. The latter one is the one that we want for easy addition and subtraction, so we convert all entries to 2s-complement. Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Harry Wentland <harry.wentland@amd.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Signed-off-by: Simon Ser <contact@emersion.fr> Link: https://patch.msgid.link/20251115000237.3561250-21-alex.hung@amd.com
1 parent bff4d3c commit ea3f6ba

2 files changed

Lines changed: 67 additions & 2 deletions

File tree

drivers/gpu/drm/vkms/vkms_colorop.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ static const u64 supported_tfs =
1212
BIT(DRM_COLOROP_1D_CURVE_SRGB_EOTF) |
1313
BIT(DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF);
1414

15-
#define MAX_COLOR_PIPELINE_OPS 2
15+
#define MAX_COLOR_PIPELINE_OPS 4
1616

1717
static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_prop_enum_list *list)
1818
{
@@ -40,7 +40,39 @@ static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_pr
4040

4141
i++;
4242

43-
/* 2nd op: 1d curve */
43+
/* 2nd op: 3x4 matrix */
44+
ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL);
45+
if (!ops[i]) {
46+
drm_err(dev, "KMS: Failed to allocate colorop\n");
47+
ret = -ENOMEM;
48+
goto cleanup;
49+
}
50+
51+
ret = drm_plane_colorop_ctm_3x4_init(dev, ops[i], plane);
52+
if (ret)
53+
goto cleanup;
54+
55+
drm_colorop_set_next_property(ops[i - 1], ops[i]);
56+
57+
i++;
58+
59+
/* 3rd op: 3x4 matrix */
60+
ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL);
61+
if (!ops[i]) {
62+
drm_err(dev, "KMS: Failed to allocate colorop\n");
63+
ret = -ENOMEM;
64+
goto cleanup;
65+
}
66+
67+
ret = drm_plane_colorop_ctm_3x4_init(dev, ops[i], plane);
68+
if (ret)
69+
goto cleanup;
70+
71+
drm_colorop_set_next_property(ops[i - 1], ops[i]);
72+
73+
i++;
74+
75+
/* 4th op: 1d curve */
4476
ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL);
4577
if (!ops[i]) {
4678
drm_err(dev, "KMS: Failed to allocate colorop\n");

drivers/gpu/drm/vkms/vkms_composer.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,35 @@ static void apply_lut(const struct vkms_crtc_state *crtc_state, struct line_buff
128128
}
129129
}
130130

131+
static void apply_3x4_matrix(struct pixel_argb_s32 *pixel, const struct drm_color_ctm_3x4 *matrix)
132+
{
133+
s64 rf, gf, bf;
134+
s64 r, g, b;
135+
136+
r = drm_int2fixp(pixel->r);
137+
g = drm_int2fixp(pixel->g);
138+
b = drm_int2fixp(pixel->b);
139+
140+
rf = drm_fixp_mul(drm_sm2fixp(matrix->matrix[0]), r) +
141+
drm_fixp_mul(drm_sm2fixp(matrix->matrix[1]), g) +
142+
drm_fixp_mul(drm_sm2fixp(matrix->matrix[2]), b) +
143+
drm_sm2fixp(matrix->matrix[3]);
144+
145+
gf = drm_fixp_mul(drm_sm2fixp(matrix->matrix[4]), r) +
146+
drm_fixp_mul(drm_sm2fixp(matrix->matrix[5]), g) +
147+
drm_fixp_mul(drm_sm2fixp(matrix->matrix[6]), b) +
148+
drm_sm2fixp(matrix->matrix[7]);
149+
150+
bf = drm_fixp_mul(drm_sm2fixp(matrix->matrix[8]), r) +
151+
drm_fixp_mul(drm_sm2fixp(matrix->matrix[9]), g) +
152+
drm_fixp_mul(drm_sm2fixp(matrix->matrix[10]), b) +
153+
drm_sm2fixp(matrix->matrix[11]);
154+
155+
pixel->r = drm_fixp2int_round(rf);
156+
pixel->g = drm_fixp2int_round(gf);
157+
pixel->b = drm_fixp2int_round(bf);
158+
}
159+
131160
static void apply_colorop(struct pixel_argb_s32 *pixel, struct drm_colorop *colorop)
132161
{
133162
struct drm_colorop_state *colorop_state = colorop->state;
@@ -151,6 +180,10 @@ static void apply_colorop(struct pixel_argb_s32 *pixel, struct drm_colorop *colo
151180
colorop_state->curve_1d_type);
152181
break;
153182
}
183+
} else if (colorop->type == DRM_COLOROP_CTM_3X4) {
184+
if (colorop_state->data)
185+
apply_3x4_matrix(pixel,
186+
(struct drm_color_ctm_3x4 *)colorop_state->data->data);
154187
}
155188
}
156189

0 commit comments

Comments
 (0)