gallium/vl: Implement rendering to 3-plane YUV formats

Acked-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32252>
This commit is contained in:
David Rosca 2024-11-20 14:32:29 +01:00 committed by Marge Bot
parent 7d1ce3d802
commit 0f533b387c
3 changed files with 111 additions and 43 deletions

View File

@ -330,11 +330,13 @@ static void
set_yuv_layer(struct vl_compositor_state *s, struct vl_compositor *c,
unsigned layer, struct pipe_video_buffer *buffer,
struct u_rect *src_rect, struct u_rect *dst_rect,
bool y, enum vl_compositor_deinterlace deinterlace)
enum vl_compositor_plane plane,
enum vl_compositor_deinterlace deinterlace)
{
struct pipe_sampler_view **sampler_views;
float half_a_line;
unsigned i;
bool y = plane == VL_COMPOSITOR_PLANE_Y;
assert(s && c && buffer);
@ -379,8 +381,15 @@ set_yuv_layer(struct vl_compositor_state *s, struct vl_compositor *c,
case VL_COMPOSITOR_NONE:
if (c->pipe_cs_composit_supported) {
s->layers[layer].cs = (y) ? c->cs_yuv.progressive.y : c->cs_yuv.progressive.uv;
break;
if (plane == VL_COMPOSITOR_PLANE_Y)
s->layers[layer].cs = c->cs_yuv.progressive.y;
else if (plane == VL_COMPOSITOR_PLANE_U)
s->layers[layer].cs = c->cs_yuv.progressive.u;
else if (plane == VL_COMPOSITOR_PLANE_V)
s->layers[layer].cs = c->cs_yuv.progressive.v;
else if (plane == VL_COMPOSITOR_PLANE_UV)
s->layers[layer].cs = c->cs_yuv.progressive.uv;
break;
}
FALLTHROUGH;
@ -396,10 +405,12 @@ set_yuv_layer(struct vl_compositor_state *s, struct vl_compositor *c,
static void
set_rgb_to_yuv_layer(struct vl_compositor_state *s, struct vl_compositor *c,
unsigned layer, struct pipe_sampler_view *v,
struct u_rect *src_rect, struct u_rect *dst_rect, bool y)
struct u_rect *src_rect, struct u_rect *dst_rect,
enum vl_compositor_plane plane)
{
assert(s && c && v);
bool y = plane == VL_COMPOSITOR_PLANE_Y;
assert(s && c && v);
assert(layer < VL_COMPOSITOR_MAX_LAYERS);
if (!init_shaders(c))
@ -407,9 +418,16 @@ set_rgb_to_yuv_layer(struct vl_compositor_state *s, struct vl_compositor *c,
s->used_layers |= 1 << layer;
if (c->pipe_cs_composit_supported)
s->layers[layer].cs = y ? c->cs_rgb_yuv.y : c->cs_rgb_yuv.uv;
else if (c->pipe_gfx_supported)
if (c->pipe_cs_composit_supported) {
if (plane == VL_COMPOSITOR_PLANE_Y)
s->layers[layer].cs = c->cs_rgb_yuv.y;
else if (plane == VL_COMPOSITOR_PLANE_U)
s->layers[layer].cs = c->cs_rgb_yuv.u;
else if (plane == VL_COMPOSITOR_PLANE_V)
s->layers[layer].cs = c->cs_rgb_yuv.v;
else if (plane == VL_COMPOSITOR_PLANE_UV)
s->layers[layer].cs = c->cs_rgb_yuv.uv;
} else if (c->pipe_gfx_supported)
s->layers[layer].fs = y ? c->fs_rgb_yuv.y : c->fs_rgb_yuv.uv;
s->layers[layer].samplers[0] = c->sampler_linear;
@ -711,20 +729,26 @@ vl_compositor_yuv_deint_full(struct vl_compositor_state *s,
dst_surfaces = dst->get_surfaces(dst);
vl_compositor_clear_layers(s);
set_yuv_layer(s, c, 0, src, src_rect, NULL, true, deinterlace);
set_yuv_layer(s, c, 0, src, src_rect, NULL, VL_COMPOSITOR_PLANE_Y, deinterlace);
vl_compositor_set_layer_dst_area(s, 0, dst_rect);
vl_compositor_render(s, c, dst_surfaces[0], NULL, false);
if (dst_rect) {
dst_rect->x0 /= 2;
dst_rect->y0 /= 2;
dst_rect->x1 /= 2;
dst_rect->y1 /= 2;
}
if (dst_surfaces[1]) {
dst_rect->x0 = util_format_get_plane_width(dst->buffer_format, 1, dst_rect->x0);
dst_rect->x1 = util_format_get_plane_width(dst->buffer_format, 1, dst_rect->x1);
dst_rect->y0 = util_format_get_plane_height(dst->buffer_format, 1, dst_rect->y0);
dst_rect->y1 = util_format_get_plane_height(dst->buffer_format, 1, dst_rect->y1);
set_yuv_layer(s, c, 0, src, src_rect, NULL, dst_surfaces[2] ? VL_COMPOSITOR_PLANE_U :
VL_COMPOSITOR_PLANE_UV, deinterlace);
vl_compositor_set_layer_dst_area(s, 0, dst_rect);
vl_compositor_render(s, c, dst_surfaces[1], NULL, false);
set_yuv_layer(s, c, 0, src, src_rect, NULL, false, deinterlace);
vl_compositor_set_layer_dst_area(s, 0, dst_rect);
vl_compositor_render(s, c, dst_surfaces[1], NULL, false);
if (dst_surfaces[2]) {
set_yuv_layer(s, c, 0, src, src_rect, NULL, VL_COMPOSITOR_PLANE_V, deinterlace);
vl_compositor_set_layer_dst_area(s, 0, dst_rect);
vl_compositor_render(s, c, dst_surfaces[2], NULL, false);
}
}
s->pipe->flush(s->pipe, NULL, 0);
}
@ -749,20 +773,27 @@ vl_compositor_convert_rgb_to_yuv(struct vl_compositor_state *s,
vl_compositor_clear_layers(s);
set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, true);
set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, VL_COMPOSITOR_PLANE_Y);
vl_compositor_set_layer_dst_area(s, 0, dst_rect);
vl_compositor_render(s, c, dst_surfaces[0], NULL, false);
if (dst_rect) {
dst_rect->x0 /= 2;
dst_rect->y0 /= 2;
dst_rect->x1 /= 2;
dst_rect->y1 /= 2;
if (dst_surfaces[1]) {
dst_rect->x0 = util_format_get_plane_width(dst->buffer_format, 1, dst_rect->x0);
dst_rect->x1 = util_format_get_plane_width(dst->buffer_format, 1, dst_rect->x1);
dst_rect->y0 = util_format_get_plane_height(dst->buffer_format, 1, dst_rect->y0);
dst_rect->y1 = util_format_get_plane_height(dst->buffer_format, 1, dst_rect->y1);
set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, dst_surfaces[2] ? VL_COMPOSITOR_PLANE_U :
VL_COMPOSITOR_PLANE_UV);
vl_compositor_set_layer_dst_area(s, 0, dst_rect);
vl_compositor_render(s, c, dst_surfaces[1], NULL, false);
if (dst_surfaces[2]) {
set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, VL_COMPOSITOR_PLANE_V);
vl_compositor_set_layer_dst_area(s, 0, dst_rect);
vl_compositor_render(s, c, dst_surfaces[2], NULL, false);
}
}
set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, false);
vl_compositor_set_layer_dst_area(s, 0, dst_rect);
vl_compositor_render(s, c, dst_surfaces[1], NULL, false);
pipe_sampler_view_reference(&sv, NULL);
s->pipe->flush(s->pipe, NULL, 0);

View File

@ -79,6 +79,15 @@ enum vl_compositor_chroma_location
VL_COMPOSITOR_LOCATION_HORIZONTAL_CENTER = (1 << 4)
};
enum vl_compositor_plane
{
VL_COMPOSITOR_PLANE_NONE = 0,
VL_COMPOSITOR_PLANE_Y = (1 << 0),
VL_COMPOSITOR_PLANE_U = (1 << 1),
VL_COMPOSITOR_PLANE_V = (1 << 2),
VL_COMPOSITOR_PLANE_UV = VL_COMPOSITOR_PLANE_U | VL_COMPOSITOR_PLANE_V
};
struct vl_compositor_layer
{
bool clearing;
@ -165,6 +174,8 @@ struct vl_compositor
struct {
void *y;
void *uv;
void *u;
void *v;
} progressive;
} cs_yuv;
@ -181,6 +192,8 @@ struct vl_compositor
struct {
void *y;
void *uv;
void *u;
void *v;
} cs_rgb_yuv;
bool shaders_initialized;

View File

@ -339,20 +339,25 @@ static void *create_video_buffer_shader(struct vl_compositor *c)
return cs_create_shader_state(c, &s);
}
static void *create_yuv_progressive_shader(struct vl_compositor *c, bool y)
static void *create_yuv_progressive_shader(struct vl_compositor *c, enum vl_compositor_plane plane)
{
struct cs_shader s = {
.name = y ? "yuv_progressive_y" : "yuv_progressive_uv",
.name = "yuv_progressive",
.num_samplers = 3,
};
nir_builder *b = &s.b;
nir_def *ipos = cs_create_shader(c, &s);
nir_def *pos = cs_tex_coords(&s, ipos, y ? COORDS_LUMA : COORDS_CHROMA);
nir_def *pos = cs_tex_coords(&s, ipos, plane == VL_COMPOSITOR_PLANE_Y ? COORDS_LUMA : COORDS_CHROMA);
nir_def *color;
if (y) {
color = nir_channel(b, cs_fetch_texel(&s, pos, 0), 0);
if (plane != VL_COMPOSITOR_PLANE_UV) {
unsigned c = 0;
if (plane == VL_COMPOSITOR_PLANE_U)
c = 1;
else if (plane == VL_COMPOSITOR_PLANE_V)
c = 2;
color = nir_channel(b, cs_fetch_texel(&s, pos, c), c);
} else {
nir_def *col1 = cs_fetch_texel(&s, pos, 1);
nir_def *col2 = cs_fetch_texel(&s, pos, 2);
@ -364,10 +369,10 @@ static void *create_yuv_progressive_shader(struct vl_compositor *c, bool y)
return cs_create_shader_state(c, &s);
}
static void *create_rgb_yuv_shader(struct vl_compositor *c, bool y)
static void *create_rgb_yuv_shader(struct vl_compositor *c, enum vl_compositor_plane plane)
{
struct cs_shader s = {
.name = y ? "rgb_yuv_y" : "rgb_yuv_uv",
.name = "rgb_yuv",
.num_samplers = 1,
};
nir_builder *b = &s.b;
@ -375,7 +380,7 @@ static void *create_rgb_yuv_shader(struct vl_compositor *c, bool y)
nir_def *ipos = cs_create_shader(c, &s);
nir_def *color = NULL;
if (y) {
if (plane == VL_COMPOSITOR_PLANE_Y) {
nir_def *pos = cs_tex_coords(&s, ipos, COORDS_LUMA);
color = cs_fetch_texel(&s, pos, 0);
} else {
@ -426,8 +431,13 @@ static void *create_rgb_yuv_shader(struct vl_compositor *c, bool y)
color = nir_vector_insert_imm(b, color, s.fone, 3);
if (y) {
color = cs_color_space_conversion(&s, color, 0);
if (plane != VL_COMPOSITOR_PLANE_UV) {
unsigned c = 0;
if (plane == VL_COMPOSITOR_PLANE_U)
c = 1;
else if (plane == VL_COMPOSITOR_PLANE_V)
c = 2;
color = cs_color_space_conversion(&s, color, c);
} else {
nir_def *col1 = cs_color_space_conversion(&s, color, 1);
nir_def *col2 = cs_color_space_conversion(&s, color, 2);
@ -832,20 +842,26 @@ bool vl_compositor_cs_init_shaders(struct vl_compositor *c)
c->cs_yuv.weave.y = create_weave_shader(c, false, true);
c->cs_yuv.weave.uv = create_weave_shader(c, false, false);
c->cs_yuv.progressive.y = create_yuv_progressive_shader(c, true);
c->cs_yuv.progressive.uv = create_yuv_progressive_shader(c, false);
c->cs_yuv.progressive.y = create_yuv_progressive_shader(c, VL_COMPOSITOR_PLANE_Y);
c->cs_yuv.progressive.uv = create_yuv_progressive_shader(c, VL_COMPOSITOR_PLANE_UV);
c->cs_yuv.progressive.u = create_yuv_progressive_shader(c, VL_COMPOSITOR_PLANE_U);
c->cs_yuv.progressive.v = create_yuv_progressive_shader(c, VL_COMPOSITOR_PLANE_V);
if (!c->cs_yuv.weave.y || !c->cs_yuv.weave.uv) {
debug_printf("Unable to create YCbCr i-to-YCbCr p deint compute shader.\n");
return false;
}
if (!c->cs_yuv.progressive.y || !c->cs_yuv.progressive.uv) {
if (!c->cs_yuv.progressive.y || !c->cs_yuv.progressive.uv ||
!c->cs_yuv.progressive.u || !c->cs_yuv.progressive.v) {
debug_printf("Unable to create YCbCr p-to-NV12 compute shader.\n");
return false;
}
c->cs_rgb_yuv.y = create_rgb_yuv_shader(c, true);
c->cs_rgb_yuv.uv = create_rgb_yuv_shader(c, false);
if (!c->cs_rgb_yuv.y || !c->cs_rgb_yuv.uv) {
c->cs_rgb_yuv.y = create_rgb_yuv_shader(c, VL_COMPOSITOR_PLANE_Y);
c->cs_rgb_yuv.uv = create_rgb_yuv_shader(c, VL_COMPOSITOR_PLANE_UV);
c->cs_rgb_yuv.u = create_rgb_yuv_shader(c, VL_COMPOSITOR_PLANE_U);
c->cs_rgb_yuv.v = create_rgb_yuv_shader(c, VL_COMPOSITOR_PLANE_V);
if (!c->cs_rgb_yuv.y || !c->cs_rgb_yuv.uv ||
!c->cs_rgb_yuv.u || !c->cs_rgb_yuv.v) {
debug_printf("Unable to create RGB-to-NV12 compute shader.\n");
return false;
}
@ -869,8 +885,16 @@ void vl_compositor_cs_cleanup_shaders(struct vl_compositor *c)
c->pipe->delete_compute_state(c->pipe, c->cs_yuv.progressive.y);
if (c->cs_yuv.progressive.uv)
c->pipe->delete_compute_state(c->pipe, c->cs_yuv.progressive.uv);
if (c->cs_yuv.progressive.u)
c->pipe->delete_compute_state(c->pipe, c->cs_yuv.progressive.u);
if (c->cs_yuv.progressive.v)
c->pipe->delete_compute_state(c->pipe, c->cs_yuv.progressive.v);
if (c->cs_rgb_yuv.y)
c->pipe->delete_compute_state(c->pipe, c->cs_rgb_yuv.y);
if (c->cs_rgb_yuv.uv)
c->pipe->delete_compute_state(c->pipe, c->cs_rgb_yuv.uv);
if (c->cs_rgb_yuv.u)
c->pipe->delete_compute_state(c->pipe, c->cs_rgb_yuv.u);
if (c->cs_rgb_yuv.v)
c->pipe->delete_compute_state(c->pipe, c->cs_rgb_yuv.v);
}