mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-21 21:08:23 +02:00
vl,frontends/va: Implement YUV->YUV matrix coeff conversion
Use separate matrix for YUV->RGB and RGB->YUV conversions. Acked-by: Ruijing Dong <ruijing.dong@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37058>
This commit is contained in:
parent
6e8a8d8ee7
commit
5bc0df5aad
5 changed files with 77 additions and 26 deletions
|
|
@ -888,7 +888,7 @@ vl_compositor_init_state(struct vl_compositor_state *s, struct pipe_context *pip
|
||||||
pipe->screen,
|
pipe->screen,
|
||||||
PIPE_BIND_CONSTANT_BUFFER,
|
PIPE_BIND_CONSTANT_BUFFER,
|
||||||
PIPE_USAGE_DEFAULT,
|
PIPE_USAGE_DEFAULT,
|
||||||
sizeof(vl_csc_matrix) + 32 * sizeof(float) + 2 * sizeof(int)
|
sizeof(vl_csc_matrix) * 2 + 32 * sizeof(float) + 2 * sizeof(int)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!s->shader_params)
|
if (!s->shader_params)
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,8 @@ struct vl_compositor_state
|
||||||
struct vl_compositor_layer layers[VL_COMPOSITOR_MAX_LAYERS];
|
struct vl_compositor_layer layers[VL_COMPOSITOR_MAX_LAYERS];
|
||||||
bool interlaced;
|
bool interlaced;
|
||||||
unsigned chroma_location;
|
unsigned chroma_location;
|
||||||
|
vl_csc_matrix yuv2rgb;
|
||||||
|
vl_csc_matrix rgb2yuv;
|
||||||
|
|
||||||
vl_csc_matrix csc_matrix;
|
vl_csc_matrix csc_matrix;
|
||||||
float luma_min, luma_max;
|
float luma_min, luma_max;
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ struct cs_shader {
|
||||||
unsigned num_samplers;
|
unsigned num_samplers;
|
||||||
nir_variable *samplers[3];
|
nir_variable *samplers[3];
|
||||||
nir_variable *image;
|
nir_variable *image;
|
||||||
nir_def *params[11];
|
nir_def *params[14];
|
||||||
nir_def *fone;
|
nir_def *fone;
|
||||||
nir_def *fzero;
|
nir_def *fzero;
|
||||||
};
|
};
|
||||||
|
|
@ -66,6 +66,11 @@ enum coords_flags {
|
||||||
COORDS_CHROMA_OFFSET = 0x2,
|
COORDS_CHROMA_OFFSET = 0x2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum color_conversion {
|
||||||
|
YUV2RGB,
|
||||||
|
RGB2YUV,
|
||||||
|
};
|
||||||
|
|
||||||
static nir_def *cs_create_shader(struct vl_compositor *c, struct cs_shader *s)
|
static nir_def *cs_create_shader(struct vl_compositor *c, struct cs_shader *s)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
@ -77,7 +82,7 @@ static nir_def *cs_create_shader(struct vl_compositor *c, struct cs_shader *s)
|
||||||
|
|
||||||
layout (std140, binding = 0) uniform ubo
|
layout (std140, binding = 0) uniform ubo
|
||||||
{
|
{
|
||||||
vec4 csc_mat[3]; // params[0-2]
|
vec4 yuv2rgb[3]; // params[0-2]
|
||||||
float luma_min; // params[3].x
|
float luma_min; // params[3].x
|
||||||
float luma_max; // params[3].y
|
float luma_max; // params[3].y
|
||||||
vec2 chroma_offset; // params[3].zw
|
vec2 chroma_offset; // params[3].zw
|
||||||
|
|
@ -88,6 +93,7 @@ static nir_def *cs_create_shader(struct vl_compositor *c, struct cs_shader *s)
|
||||||
vec2 chroma_clamp; // params[6].zw
|
vec2 chroma_clamp; // params[6].zw
|
||||||
vec4 proj[3]; // params[7-8]
|
vec4 proj[3]; // params[7-8]
|
||||||
vec4 chroma_proj[3]; // params[9-10]
|
vec4 chroma_proj[3]; // params[9-10]
|
||||||
|
vec4 rgb2yuv[3]; // params[11-13]
|
||||||
};
|
};
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
|
@ -246,13 +252,14 @@ static inline nir_def *cs_normalize(struct cs_shader *s, nir_def *src, unsigned
|
||||||
return nir_fdiv(b, src, div);
|
return nir_fdiv(b, src, div);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline nir_def *cs_color_space_conversion(struct cs_shader *s, nir_def *src, unsigned comp)
|
static inline nir_def *cs_color_space_conversion(struct cs_shader *s, nir_def *src,
|
||||||
|
unsigned comp, enum color_conversion conversion)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
return dot(src, params[comp]);
|
return dot(src, params[(conversion == RGB2YUV ? 11 : 0) + comp]);
|
||||||
*/
|
*/
|
||||||
nir_builder *b = &s->b;
|
nir_builder *b = &s->b;
|
||||||
return nir_fdot4(b, src, s->params[comp]);
|
return nir_fdot4(b, src, s->params[(conversion == RGB2YUV ? 11 : 0) + comp]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline nir_def *cs_fetch_texel(struct cs_shader *s, nir_def *coords, unsigned sampler)
|
static inline nir_def *cs_fetch_texel(struct cs_shader *s, nir_def *coords, unsigned sampler)
|
||||||
|
|
@ -335,7 +342,7 @@ static void *create_video_buffer_shader(struct vl_compositor *c)
|
||||||
|
|
||||||
nir_def *color = nir_vec4(b, col[0], col[1], col[2], s.fone);
|
nir_def *color = nir_vec4(b, col[0], col[1], col[2], s.fone);
|
||||||
for (unsigned i = 0; i < 3; ++i)
|
for (unsigned i = 0; i < 3; ++i)
|
||||||
col[i] = cs_color_space_conversion(&s, color, i);
|
col[i] = cs_color_space_conversion(&s, color, i, YUV2RGB);
|
||||||
|
|
||||||
color = nir_vec4(b, col[0], col[1], col[2], alpha);
|
color = nir_vec4(b, col[0], col[1], col[2], alpha);
|
||||||
cs_image_store(&s, cs_translate(&s, ipos), color);
|
cs_image_store(&s, cs_translate(&s, ipos), color);
|
||||||
|
|
@ -352,19 +359,36 @@ static void *create_yuv_progressive_shader(struct vl_compositor *c, enum vl_comp
|
||||||
nir_builder *b = &s.b;
|
nir_builder *b = &s.b;
|
||||||
|
|
||||||
nir_def *ipos = cs_create_shader(c, &s);
|
nir_def *ipos = cs_create_shader(c, &s);
|
||||||
nir_def *pos = cs_tex_coords(&s, ipos, plane == VL_COMPOSITOR_PLANE_Y ? COORDS_LUMA : COORDS_CHROMA);
|
nir_def *pos_luma = cs_tex_coords(&s, ipos, COORDS_LUMA);
|
||||||
|
nir_def *pos_chroma = cs_tex_coords(&s, ipos, COORDS_CHROMA |
|
||||||
|
(plane == VL_COMPOSITOR_PLANE_Y ? COORDS_CHROMA_OFFSET : 0));
|
||||||
|
|
||||||
|
nir_def *col[3];
|
||||||
|
for (unsigned i = 0; i < 3; i++)
|
||||||
|
col[i] = cs_fetch_texel(&s, i == 0 ? pos_luma : pos_chroma, i);
|
||||||
|
|
||||||
|
nir_def *color = nir_vec4(b, col[0], col[1], col[2], s.fone);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 3; i++)
|
||||||
|
col[i] = cs_color_space_conversion(&s, color, i, YUV2RGB);
|
||||||
|
|
||||||
|
color = nir_vec4(b, col[0], col[1], col[2], s.fone);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < 3; i++)
|
||||||
|
col[i] = cs_color_space_conversion(&s, color, i, RGB2YUV);
|
||||||
|
|
||||||
|
color = nir_vec4(b, col[0], col[1], col[2], s.fone);
|
||||||
|
|
||||||
nir_def *color;
|
|
||||||
if (plane != VL_COMPOSITOR_PLANE_UV) {
|
if (plane != VL_COMPOSITOR_PLANE_UV) {
|
||||||
unsigned c = 0;
|
unsigned c = 0;
|
||||||
if (plane == VL_COMPOSITOR_PLANE_U)
|
if (plane == VL_COMPOSITOR_PLANE_U)
|
||||||
c = 1;
|
c = 1;
|
||||||
else if (plane == VL_COMPOSITOR_PLANE_V)
|
else if (plane == VL_COMPOSITOR_PLANE_V)
|
||||||
c = 2;
|
c = 2;
|
||||||
color = nir_channel(b, cs_fetch_texel(&s, pos, c), c);
|
color = nir_channel(b, color, c);
|
||||||
} else {
|
} else {
|
||||||
nir_def *col1 = cs_fetch_texel(&s, pos, 1);
|
nir_def *col1 = nir_channel(b, color, 1);
|
||||||
nir_def *col2 = cs_fetch_texel(&s, pos, 2);
|
nir_def *col2 = nir_channel(b, color, 2);
|
||||||
color = nir_vec2(b, col1, col2);
|
color = nir_vec2(b, col1, col2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -439,10 +463,10 @@ static void *create_rgb_yuv_shader(struct vl_compositor *c, enum vl_compositor_p
|
||||||
c = 1;
|
c = 1;
|
||||||
else if (plane == VL_COMPOSITOR_PLANE_V)
|
else if (plane == VL_COMPOSITOR_PLANE_V)
|
||||||
c = 2;
|
c = 2;
|
||||||
color = cs_color_space_conversion(&s, color, c);
|
color = cs_color_space_conversion(&s, color, c, RGB2YUV);
|
||||||
} else {
|
} else {
|
||||||
nir_def *col1 = cs_color_space_conversion(&s, color, 1);
|
nir_def *col1 = cs_color_space_conversion(&s, color, 1, RGB2YUV);
|
||||||
nir_def *col2 = cs_color_space_conversion(&s, color, 2);
|
nir_def *col2 = cs_color_space_conversion(&s, color, 2, RGB2YUV);
|
||||||
color = nir_vec2(b, col1, col2);
|
color = nir_vec2(b, col1, col2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -560,7 +584,7 @@ static nir_def *create_weave_shader(struct vl_compositor *c, bool rgb, bool y)
|
||||||
if (rgb) {
|
if (rgb) {
|
||||||
nir_def *alpha = cs_luma_key(&s, nir_channel(b, color, 2));
|
nir_def *alpha = cs_luma_key(&s, nir_channel(b, color, 2));
|
||||||
for (unsigned i = 0; i < 3; ++i)
|
for (unsigned i = 0; i < 3; ++i)
|
||||||
col[i] = cs_color_space_conversion(&s, color, i);
|
col[i] = cs_color_space_conversion(&s, color, i, YUV2RGB);
|
||||||
color = nir_vec4(b, col[0], col[1], col[2], alpha);
|
color = nir_vec4(b, col[0], col[1], col[2], alpha);
|
||||||
} else if (y) {
|
} else if (y) {
|
||||||
color = nir_channel(b, color, 0);
|
color = nir_channel(b, color, 0);
|
||||||
|
|
@ -774,7 +798,7 @@ set_viewport(struct vl_compositor_state *s,
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
memcpy(ptr, &s->csc_matrix, sizeof(vl_csc_matrix));
|
memcpy(ptr, &s->yuv2rgb, sizeof(vl_csc_matrix));
|
||||||
|
|
||||||
float *ptr_float = (float *)ptr;
|
float *ptr_float = (float *)ptr;
|
||||||
ptr_float += sizeof(vl_csc_matrix) / sizeof(float);
|
ptr_float += sizeof(vl_csc_matrix) / sizeof(float);
|
||||||
|
|
@ -816,6 +840,9 @@ set_viewport(struct vl_compositor_state *s,
|
||||||
memcpy(ptr_float, drawn->proj, sizeof(drawn->proj));
|
memcpy(ptr_float, drawn->proj, sizeof(drawn->proj));
|
||||||
ptr_float += sizeof(drawn->proj) / sizeof(float);
|
ptr_float += sizeof(drawn->proj) / sizeof(float);
|
||||||
memcpy(ptr_float, drawn->chroma_proj, sizeof(drawn->chroma_proj));
|
memcpy(ptr_float, drawn->chroma_proj, sizeof(drawn->chroma_proj));
|
||||||
|
ptr_float += sizeof(drawn->chroma_proj) / sizeof(float);
|
||||||
|
|
||||||
|
memcpy(ptr_float, &s->rgb2yuv, sizeof(vl_csc_matrix));
|
||||||
|
|
||||||
pipe_buffer_unmap(s->pipe, buf_transfer);
|
pipe_buffer_unmap(s->pipe, buf_transfer);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@ vlVaPostProcCompositor(vlVaDriver *drv,
|
||||||
struct pipe_vpp_desc *param)
|
struct pipe_vpp_desc *param)
|
||||||
{
|
{
|
||||||
struct pipe_surface *surfaces;
|
struct pipe_surface *surfaces;
|
||||||
enum pipe_video_vpp_matrix_coefficients coeffs;
|
|
||||||
enum vl_compositor_rotation rotation;
|
enum vl_compositor_rotation rotation;
|
||||||
enum vl_compositor_mirror mirror;
|
enum vl_compositor_mirror mirror;
|
||||||
bool src_yuv = util_format_is_yuv(src->buffer_format);
|
bool src_yuv = util_format_is_yuv(src->buffer_format);
|
||||||
|
|
@ -75,14 +74,37 @@ vlVaPostProcCompositor(vlVaDriver *drv,
|
||||||
if (!surfaces[0].texture)
|
if (!surfaces[0].texture)
|
||||||
return VA_STATUS_ERROR_INVALID_SURFACE;
|
return VA_STATUS_ERROR_INVALID_SURFACE;
|
||||||
|
|
||||||
if (src_yuv == dst_yuv || util_format_get_nr_components(src->buffer_format) == 1)
|
if (util_format_get_nr_components(src->buffer_format) == 1) {
|
||||||
coeffs = PIPE_VIDEO_VPP_MCF_RGB; /* identity */
|
/* Identity */
|
||||||
else
|
vl_csc_get_rgbyuv_matrix(PIPE_VIDEO_VPP_MCF_RGB, src->buffer_format, dst->buffer_format,
|
||||||
coeffs = src_yuv ? param->in_matrix_coefficients : param->out_matrix_coefficients;
|
param->in_color_range, param->out_color_range, &drv->cstate.yuv2rgb);
|
||||||
|
vl_csc_get_rgbyuv_matrix(PIPE_VIDEO_VPP_MCF_RGB, src->buffer_format, dst->buffer_format,
|
||||||
|
param->in_color_range, param->out_color_range, &drv->cstate.rgb2yuv);
|
||||||
|
} else if (src_yuv == dst_yuv) {
|
||||||
|
if (!src_yuv) {
|
||||||
|
/* RGB to RGB */
|
||||||
|
vl_csc_get_rgbyuv_matrix(PIPE_VIDEO_VPP_MCF_RGB, src->buffer_format, dst->buffer_format,
|
||||||
|
param->in_color_range, param->out_color_range, &drv->cstate.yuv2rgb);
|
||||||
|
} else {
|
||||||
|
/* YUV to YUV (convert to RGB for transfer function and primaries) */
|
||||||
|
enum pipe_format rgb_format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
vl_csc_get_rgbyuv_matrix(param->in_matrix_coefficients, src->buffer_format, rgb_format,
|
||||||
|
param->in_color_range, PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_FULL,
|
||||||
|
&drv->cstate.yuv2rgb);
|
||||||
|
vl_csc_get_rgbyuv_matrix(param->out_matrix_coefficients, rgb_format, dst->buffer_format,
|
||||||
|
PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_FULL, param->out_color_range,
|
||||||
|
&drv->cstate.rgb2yuv);
|
||||||
|
}
|
||||||
|
} else if (src_yuv) {
|
||||||
|
/* YUV to RGB */
|
||||||
|
vl_csc_get_rgbyuv_matrix(param->in_matrix_coefficients, src->buffer_format, dst->buffer_format,
|
||||||
|
param->in_color_range, param->out_color_range, &drv->cstate.yuv2rgb);
|
||||||
|
} else {
|
||||||
|
/* RGB to YUV */
|
||||||
|
vl_csc_get_rgbyuv_matrix(param->out_matrix_coefficients, src->buffer_format, dst->buffer_format,
|
||||||
|
param->in_color_range, param->out_color_range, &drv->cstate.rgb2yuv);
|
||||||
|
}
|
||||||
|
|
||||||
vl_csc_get_rgbyuv_matrix(coeffs, src->buffer_format, dst->buffer_format,
|
|
||||||
param->in_color_range, param->out_color_range, &drv->csc);
|
|
||||||
vl_compositor_set_csc_matrix(&drv->cstate, &drv->csc, 1.0f, 0.0f);
|
|
||||||
|
|
||||||
if (src_yuv || dst_yuv) {
|
if (src_yuv || dst_yuv) {
|
||||||
enum pipe_format format = src_yuv ? src->buffer_format : dst->buffer_format;
|
enum pipe_format format = src_yuv ? src->buffer_format : dst->buffer_format;
|
||||||
|
|
|
||||||
|
|
@ -402,7 +402,7 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s
|
||||||
|
|
||||||
vl_csc_get_rgbyuv_matrix(coeffs, format, surf_templ.format,
|
vl_csc_get_rgbyuv_matrix(coeffs, format, surf_templ.format,
|
||||||
PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_REDUCED,
|
PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_REDUCED,
|
||||||
PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_FULL, &drv->cstate.csc_matrix);
|
PIPE_VIDEO_VPP_CHROMA_COLOR_RANGE_FULL, &drv->cstate.yuv2rgb);
|
||||||
|
|
||||||
vl_compositor_clear_layers(&drv->cstate);
|
vl_compositor_clear_layers(&drv->cstate);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue