On 03/10/24 - 16:01, Harry Wentland wrote: > 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. > > Signed-off-by: Harry Wentland <harry.wentland@xxxxxxx> > --- > > v6: > - pre-compute colors (Louis Chauvet) > - round matrix output (Louis Chauvet) > > drivers/gpu/drm/vkms/vkms_colorop.c | 34 +++++++++++++++++++++++++++- > drivers/gpu/drm/vkms/vkms_composer.c | 32 ++++++++++++++++++++++++++ > 2 files changed, 65 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/vkms/vkms_colorop.c b/drivers/gpu/drm/vkms/vkms_colorop.c > index aebd467c4e61..f0c264820a81 100644 > --- a/drivers/gpu/drm/vkms/vkms_colorop.c > +++ b/drivers/gpu/drm/vkms/vkms_colorop.c > @@ -12,7 +12,7 @@ static const u64 supported_tfs = > BIT(DRM_COLOROP_1D_CURVE_SRGB_EOTF) | > BIT(DRM_COLOROP_1D_CURVE_SRGB_INV_EOTF); > > -#define MAX_COLOR_PIPELINE_OPS 2 > +#define MAX_COLOR_PIPELINE_OPS 4 > > static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_prop_enum_list *list) > { > @@ -48,6 +48,38 @@ static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_pr > 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]); checkpatch: spaces preferred around that '-' (ctx:VxV) > + > + i++; > + > + /* 3rd op: 3x4 matrix */ > + ops[i] = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); checkpatch: Prefer kzalloc(sizeof(*ops[i])...) over kzalloc(sizeof(struct drm_colorop)...) > + 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]); checkpatch: preferred around that '-' (ctx:VxV) > + > + i++; > + > + /* 4th op: 1d curve */ > + ops[i] = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); checkpatch: Prefer kzalloc(sizeof(*ops[i])...) over kzalloc(sizeof(struct drm_colorop)...) > + if (!ops[i]) { > + DRM_ERROR("KMS: Failed to allocate colorop\n"); > + ret = -ENOMEM; > + goto cleanup; > + } > + > ret = drm_colorop_curve_1d_init(dev, ops[i], plane, supported_tfs); > if (ret) > goto cleanup; > diff --git a/drivers/gpu/drm/vkms/vkms_composer.c b/drivers/gpu/drm/vkms/vkms_composer.c > index 01fa81ebc93b..c8b9b9d7f78f 100644 > --- a/drivers/gpu/drm/vkms/vkms_composer.c > +++ b/drivers/gpu/drm/vkms/vkms_composer.c > @@ -159,6 +159,35 @@ static void apply_lut(const struct vkms_crtc_state *crtc_state, struct line_buff > } > } > > +static void apply_3x4_matrix(struct pixel_argb_s32 *pixel, const struct drm_color_ctm_3x4 *matrix) > +{ > + s64 rf, gf, bf; > + s64 r, g, b; > + > + r = drm_int2fixp(pixel->r); > + g = drm_int2fixp(pixel->g); > + b = drm_int2fixp(pixel->b); > + > + rf = drm_fixp_mul(drm_sm2fixp(matrix->matrix[0]), r) + > + drm_fixp_mul(drm_sm2fixp(matrix->matrix[1]), g) + > + drm_fixp_mul(drm_sm2fixp(matrix->matrix[2]), b) + > + drm_sm2fixp(matrix->matrix[3]); > + > + gf = drm_fixp_mul(drm_sm2fixp(matrix->matrix[4]), r) + > + drm_fixp_mul(drm_sm2fixp(matrix->matrix[5]), g) + > + drm_fixp_mul(drm_sm2fixp(matrix->matrix[6]), b) + > + drm_sm2fixp(matrix->matrix[7]); > + > + bf = drm_fixp_mul(drm_sm2fixp(matrix->matrix[8]), r) + > + drm_fixp_mul(drm_sm2fixp(matrix->matrix[9]), g) + > + drm_fixp_mul(drm_sm2fixp(matrix->matrix[10]), b) + > + drm_sm2fixp(matrix->matrix[11]); > + > + pixel->r = drm_fixp2int_round(rf); > + pixel->g = drm_fixp2int_round(gf); > + pixel->b = drm_fixp2int_round(bf); > +} > + > static void apply_colorop(struct pixel_argb_s32 *pixel, struct drm_colorop *colorop) > { > struct drm_colorop_state *colorop_state = colorop->state; > @@ -179,6 +208,9 @@ static void apply_colorop(struct pixel_argb_s32 *pixel, struct drm_colorop *colo > DRM_DEBUG_DRIVER("unkown colorop 1D curve type %d\n", colorop_state->curve_1d_type); > break; > } > + } else if (colorop->type == DRM_COLOROP_CTM_3X4) { > + if (colorop_state->data) > + apply_3x4_matrix(pixel, (struct drm_color_ctm_3x4 *) colorop_state->data->data); checkpatch: line length of 104 exceeds 100 columns > } > > } > -- > 2.46.2 >