mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-11-23 02:04:41 +08:00
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:
parent
7d1ce3d802
commit
0f533b387c
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user