Skip to content

Commit bff4d3c

Browse files
Harry Wentlandemersion
authored andcommitted
drm/vkms: Use s32 for internal color pipeline precision
Certain operations require us to preserve values below 0.0 and above 1.0 (0x0 and 0xffff respectively in 16 bpc unorm). One such operation is a BT709 encoding operation followed by its decoding operation, or the reverse. We'll use s32 values as intermediate in and outputs of our color operations, for the operations where it matters. For now this won't apply to LUT operations. We might want to update those to work on s32 as well, but it's unclear how that should work for unorm LUT definitions. We'll revisit that once we add LUT + CTM tests. 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-20-alex.hung@amd.com
1 parent e5719e7 commit bff4d3c

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

drivers/gpu/drm/vkms/vkms_composer.c

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

131-
static void apply_colorop(struct pixel_argb_u16 *pixel, struct drm_colorop *colorop)
131+
static void apply_colorop(struct pixel_argb_s32 *pixel, struct drm_colorop *colorop)
132132
{
133133
struct drm_colorop_state *colorop_state = colorop->state;
134134
struct drm_device *dev = colorop->dev;
@@ -157,9 +157,26 @@ static void apply_colorop(struct pixel_argb_u16 *pixel, struct drm_colorop *colo
157157
static void pre_blend_color_transform(const struct vkms_plane_state *plane_state,
158158
struct line_buffer *output_buffer)
159159
{
160+
struct pixel_argb_s32 pixel;
161+
160162
for (size_t x = 0; x < output_buffer->n_pixels; x++) {
161163
struct drm_colorop *colorop = plane_state->base.base.color_pipeline;
162164

165+
/*
166+
* Some operations, such as applying a BT709 encoding matrix,
167+
* followed by a decoding matrix, require that we preserve
168+
* values above 1.0 and below 0.0 until the end of the pipeline.
169+
*
170+
* Pack the 16-bit UNORM values into s32 to give us head-room to
171+
* avoid clipping until we're at the end of the pipeline. Clip
172+
* intentionally at the end of the pipeline before packing
173+
* UNORM values back into u16.
174+
*/
175+
pixel.a = output_buffer->pixels[x].a;
176+
pixel.r = output_buffer->pixels[x].r;
177+
pixel.g = output_buffer->pixels[x].g;
178+
pixel.b = output_buffer->pixels[x].b;
179+
163180
while (colorop) {
164181
struct drm_colorop_state *colorop_state;
165182

@@ -169,10 +186,16 @@ static void pre_blend_color_transform(const struct vkms_plane_state *plane_state
169186
return;
170187

171188
if (!colorop_state->bypass)
172-
apply_colorop(&output_buffer->pixels[x], colorop);
189+
apply_colorop(&pixel, colorop);
173190

174191
colorop = colorop->next;
175192
}
193+
194+
/* clamp values */
195+
output_buffer->pixels[x].a = clamp_val(pixel.a, 0, 0xffff);
196+
output_buffer->pixels[x].r = clamp_val(pixel.r, 0, 0xffff);
197+
output_buffer->pixels[x].g = clamp_val(pixel.g, 0, 0xffff);
198+
output_buffer->pixels[x].b = clamp_val(pixel.b, 0, 0xffff);
176199
}
177200
}
178201

drivers/gpu/drm/vkms/vkms_drv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ struct vkms_frame_info {
4545
unsigned int rotation;
4646
};
4747

48+
struct pixel_argb_s32 {
49+
s32 a, r, g, b;
50+
};
51+
4852
/**
4953
* struct pixel_argb_u16 - Internal representation of a pixel color.
5054
* @a: Alpha component value, stored in 16 bits, without padding, using

0 commit comments

Comments
 (0)