X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Fvl%2Fvl_compositor.c;h=159a2952af4090a84fa1d4624bdbf2df877a7b42;hb=daa19363def83c025ccf16106b3402268bf1f56f;hp=794c8b5b17c801ef85ec2ff7985139af053adaa7;hpb=78ec7400c512b5d1d4a56ed32714c9ad555af003;p=mesa.git diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index 794c8b5b17c..159a2952af4 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -34,6 +34,7 @@ #include "util/u_draw.h" #include "util/u_surface.h" #include "util/u_upload_mgr.h" +#include "util/u_sampler.h" #include "tgsi/tgsi_ureg.h" @@ -239,20 +240,13 @@ create_frag_shader_csc(struct ureg_program *shader, struct ureg_dst texel, ureg_release_temporary(shader, temp[i]); } -static void * -create_frag_shader_video_buffer(struct vl_compositor *c) +static void +create_frag_shader_yuv(struct ureg_program *shader, struct ureg_dst texel) { - struct ureg_program *shader; struct ureg_src tc; struct ureg_src sampler[3]; - struct ureg_dst texel; - struct ureg_dst fragment; unsigned i; - shader = ureg_create(PIPE_SHADER_FRAGMENT); - if (!shader) - return false; - tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR); for (i = 0; i < 3; ++i) { sampler[i] = ureg_DECL_sampler(shader, i); @@ -262,17 +256,29 @@ create_frag_shader_video_buffer(struct vl_compositor *c) TGSI_RETURN_TYPE_FLOAT, TGSI_RETURN_TYPE_FLOAT); } - - texel = ureg_DECL_temporary(shader); - fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); /* * texel.xyz = tex(tc, sampler[i]) - * fragment = csc * texel */ for (i = 0; i < 3; ++i) ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D_ARRAY, tc, sampler[i]); +} +static void * +create_frag_shader_video_buffer(struct vl_compositor *c) +{ + struct ureg_program *shader; + struct ureg_dst texel; + struct ureg_dst fragment; + + shader = ureg_create(PIPE_SHADER_FRAGMENT); + if (!shader) + return false; + + texel = ureg_DECL_temporary(shader); + fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); + + create_frag_shader_yuv(shader, texel); create_frag_shader_csc(shader, texel, fragment); ureg_release_temporary(shader, texel); @@ -305,7 +311,7 @@ create_frag_shader_weave_rgb(struct vl_compositor *c) } static void * -create_frag_shader_weave_yuv(struct vl_compositor *c, bool y) +create_frag_shader_deint_yuv(struct vl_compositor *c, bool y, bool w) { struct ureg_program *shader; struct ureg_dst texel, fragment; @@ -317,7 +323,10 @@ create_frag_shader_weave_yuv(struct vl_compositor *c, bool y) texel = ureg_DECL_temporary(shader); fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); - create_frag_shader_weave(shader, texel); + if (w) + create_frag_shader_weave(shader, texel); + else + create_frag_shader_yuv(shader, texel); if (y) ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X), ureg_src(texel)); @@ -424,6 +433,43 @@ create_frag_shader_rgba(struct vl_compositor *c) return ureg_create_shader_and_destroy(shader, c->pipe); } +static void * +create_frag_shader_rgb_yuv(struct vl_compositor *c, bool y) +{ + struct ureg_program *shader; + struct ureg_src tc, sampler; + struct ureg_dst texel, fragment; + + struct ureg_src csc[3]; + unsigned i; + + shader = ureg_create(PIPE_SHADER_FRAGMENT); + if (!shader) + return false; + + for (i = 0; i < 3; ++i) + csc[i] = ureg_DECL_constant(shader, i); + + sampler = ureg_DECL_sampler(shader, 0); + tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR); + texel = ureg_DECL_temporary(shader); + fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); + + ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler); + + if (y) { + ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X), csc[0], ureg_src(texel)); + } else { + for (i = 0; i < 2; ++i) + ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i + 1], ureg_src(texel)); + } + + ureg_release_temporary(shader, texel); + ureg_END(shader); + + return ureg_create_shader_and_destroy(shader, c->pipe); +} + static bool init_shaders(struct vl_compositor *c) { @@ -447,10 +493,13 @@ init_shaders(struct vl_compositor *c) return false; } - c->fs_weave_yuv.y = create_frag_shader_weave_yuv(c, true); - c->fs_weave_yuv.uv = create_frag_shader_weave_yuv(c, false); - if (!c->fs_weave_yuv.y || !c->fs_weave_yuv.uv) { - debug_printf("Unable to create YCbCr i-to-YCbCr p weave fragment shader.\n"); + c->fs_yuv.weave.y = create_frag_shader_deint_yuv(c, true, true); + c->fs_yuv.weave.uv = create_frag_shader_deint_yuv(c, false, true); + c->fs_yuv.bob.y = create_frag_shader_deint_yuv(c, true, false); + c->fs_yuv.bob.uv = create_frag_shader_deint_yuv(c, false, false); + if (!c->fs_yuv.weave.y || !c->fs_yuv.weave.uv || + !c->fs_yuv.bob.y || !c->fs_yuv.bob.uv) { + debug_printf("Unable to create YCbCr i-to-YCbCr p deint fragment shader.\n"); return false; } @@ -472,6 +521,13 @@ init_shaders(struct vl_compositor *c) return false; } + c->fs_rgb_yuv.y = create_frag_shader_rgb_yuv(c, true); + c->fs_rgb_yuv.uv = create_frag_shader_rgb_yuv(c, false); + if (!c->fs_rgb_yuv.y || !c->fs_rgb_yuv.uv) { + debug_printf("Unable to create RGB-to-YUV fragment shader.\n"); + return false; + } + return true; } @@ -482,11 +538,15 @@ static void cleanup_shaders(struct vl_compositor *c) c->pipe->delete_vs_state(c->pipe, c->vs); c->pipe->delete_fs_state(c->pipe, c->fs_video_buffer); c->pipe->delete_fs_state(c->pipe, c->fs_weave_rgb); - c->pipe->delete_fs_state(c->pipe, c->fs_weave_yuv.y); - c->pipe->delete_fs_state(c->pipe, c->fs_weave_yuv.uv); + c->pipe->delete_fs_state(c->pipe, c->fs_yuv.weave.y); + c->pipe->delete_fs_state(c->pipe, c->fs_yuv.weave.uv); + c->pipe->delete_fs_state(c->pipe, c->fs_yuv.bob.y); + c->pipe->delete_fs_state(c->pipe, c->fs_yuv.bob.uv); c->pipe->delete_fs_state(c->pipe, c->fs_palette.yuv); c->pipe->delete_fs_state(c->pipe, c->fs_palette.rgb); c->pipe->delete_fs_state(c->pipe, c->fs_rgba); + c->pipe->delete_fs_state(c->pipe, c->fs_rgb_yuv.y); + c->pipe->delete_fs_state(c->pipe, c->fs_rgb_yuv.uv); } static bool @@ -551,7 +611,8 @@ init_pipe_state(struct vl_compositor *c) rast.offset_scale = 1; rast.half_pixel_center = 1; rast.bottom_edge_rule = 1; - rast.depth_clip = 1; + rast.depth_clip_near = 1; + rast.depth_clip_far = 1; c->rast = c->pipe->create_rasterizer_state(c->pipe, &rast); @@ -886,11 +947,13 @@ draw_layers(struct vl_compositor *c, struct vl_compositor_state *s, struct u_rec } 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) +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) { struct pipe_sampler_view **sampler_views; + float half_a_line; unsigned i; assert(s && c && buffer); @@ -908,7 +971,58 @@ set_yuv_layer(struct vl_compositor_state *s, struct vl_compositor *c, unsigned l src_rect ? *src_rect : default_rect(&s->layers[layer]), dst_rect ? *dst_rect : default_rect(&s->layers[layer])); - s->layers[layer].fs = (y) ? c->fs_weave_yuv.y : c->fs_weave_yuv.uv; + half_a_line = 0.5f / s->layers[layer].zw.y; + + switch(deinterlace) { + case VL_COMPOSITOR_BOB_TOP: + s->layers[layer].zw.x = 0.0f; + s->layers[layer].src.tl.y += half_a_line; + s->layers[layer].src.br.y += half_a_line; + s->layers[layer].fs = (y) ? c->fs_yuv.bob.y : c->fs_yuv.bob.uv; + break; + + case VL_COMPOSITOR_BOB_BOTTOM: + s->layers[layer].zw.x = 1.0f; + s->layers[layer].src.tl.y -= half_a_line; + s->layers[layer].src.br.y -= half_a_line; + s->layers[layer].fs = (y) ? c->fs_yuv.bob.y : c->fs_yuv.bob.uv; + break; + + default: + s->layers[layer].fs = (y) ? c->fs_yuv.weave.y : c->fs_yuv.weave.uv; + break; + } +} + +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) +{ + vl_csc_matrix csc_matrix; + + assert(s && c && v); + + assert(layer < VL_COMPOSITOR_MAX_LAYERS); + + s->used_layers |= 1 << layer; + + s->layers[layer].fs = y? c->fs_rgb_yuv.y : c->fs_rgb_yuv.uv; + + vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_709_REV, NULL, false, &csc_matrix); + vl_compositor_set_csc_matrix(s, (const vl_csc_matrix *)&csc_matrix, 1.0f, 0.0f); + + s->layers[layer].samplers[0] = c->sampler_linear; + s->layers[layer].samplers[1] = NULL; + s->layers[layer].samplers[2] = NULL; + + pipe_sampler_view_reference(&s->layers[layer].sampler_views[0], v); + pipe_sampler_view_reference(&s->layers[layer].sampler_views[1], NULL); + pipe_sampler_view_reference(&s->layers[layer].sampler_views[2], NULL); + + calc_src_and_dst(&s->layers[layer], v->texture->width0, v->texture->height0, + src_rect ? *src_rect : default_rect(&s->layers[layer]), + dst_rect ? *dst_rect : default_rect(&s->layers[layer])); } void @@ -1168,6 +1282,73 @@ vl_compositor_set_layer_rotation(struct vl_compositor_state *s, s->layers[layer].rotate = rotate; } +void +vl_compositor_yuv_deint_full(struct vl_compositor_state *s, + struct vl_compositor *c, + struct pipe_video_buffer *src, + struct pipe_video_buffer *dst, + struct u_rect *src_rect, + struct u_rect *dst_rect, + enum vl_compositor_deinterlace deinterlace) +{ + struct pipe_surface **dst_surfaces; + + dst_surfaces = dst->get_surfaces(dst); + vl_compositor_clear_layers(s); + + set_yuv_layer(s, c, 0, src, src_rect, NULL, true, 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->x1 /= 2; + dst_rect->y1 /= 2; + } + + 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); + + s->pipe->flush(s->pipe, NULL, 0); +} + +void +vl_compositor_convert_rgb_to_yuv(struct vl_compositor_state *s, + struct vl_compositor *c, + unsigned layer, + struct pipe_resource *src_res, + struct pipe_video_buffer *dst, + struct u_rect *src_rect, + struct u_rect *dst_rect) +{ + struct pipe_sampler_view *sv, sv_templ; + struct pipe_surface **dst_surfaces; + + dst_surfaces = dst->get_surfaces(dst); + + memset(&sv_templ, 0, sizeof(sv_templ)); + u_sampler_view_default_template(&sv_templ, src_res, src_res->format); + sv = s->pipe->create_sampler_view(s->pipe, src_res, &sv_templ); + + vl_compositor_clear_layers(s); + + set_rgb_to_yuv_layer(s, c, 0, sv, src_rect, NULL, true); + 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->x1 /= 2; + dst_rect->y1 /= 2; + } + + 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); +} + void vl_compositor_render(struct vl_compositor_state *s, struct vl_compositor *c, @@ -1211,37 +1392,6 @@ vl_compositor_render(struct vl_compositor_state *s, draw_layers(c, s, dirty_area); } -void -vl_compositor_yuv_deint(struct vl_compositor_state *s, - struct vl_compositor *c, - struct pipe_video_buffer *src, - struct pipe_video_buffer *dst) -{ - struct pipe_surface **dst_surfaces; - struct u_rect dst_rect; - - dst_surfaces = dst->get_surfaces(dst); - vl_compositor_clear_layers(s); - - dst_rect.x0 = 0; - dst_rect.x1 = src->width; - dst_rect.y0 = 0; - dst_rect.y1 = src->height; - - set_yuv_layer(s, c, 0, src, NULL, NULL, true); - vl_compositor_set_layer_dst_area(s, 0, &dst_rect); - vl_compositor_render(s, c, dst_surfaces[0], NULL, false); - - dst_rect.x1 /= 2; - dst_rect.y1 /= 2; - - set_yuv_layer(s, c, 0, src, NULL, NULL, false); - vl_compositor_set_layer_dst_area(s, 0, &dst_rect); - vl_compositor_render(s, c, dst_surfaces[1], NULL, false); - - s->pipe->flush(s->pipe, NULL, 0); -} - bool vl_compositor_init(struct vl_compositor *c, struct pipe_context *pipe) { @@ -1288,7 +1438,7 @@ vl_compositor_init_state(struct vl_compositor_state *s, struct pipe_context *pip * Const buffer contains the color conversion matrix and bias vectors */ /* XXX: Create with IMMUTABLE/STATIC... although it does change every once in a long while... */ - s->csc_matrix = pipe_buffer_create + s->csc_matrix = pipe_buffer_create_const0 ( pipe->screen, PIPE_BIND_CONSTANT_BUFFER,