From ca79aeb91e914ac1a4774d51ca49911406377407 Mon Sep 17 00:00:00 2001 From: Christian König Date: Sun, 17 Apr 2011 12:15:14 +0200 Subject: [g3dvl] rename vl_mpeg12_mc_renderer into vl_mc It's still not 100% free from mpeg12 specific stuff, but should now be a good start for other codecs. --- src/gallium/auxiliary/Makefile | 2 +- src/gallium/auxiliary/vl/vl_mc.c | 668 +++++++++++++++++++++++ src/gallium/auxiliary/vl/vl_mc.h | 85 +++ src/gallium/auxiliary/vl/vl_mpeg12_decoder.h | 6 +- src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c | 668 ----------------------- src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h | 85 --- 6 files changed, 757 insertions(+), 757 deletions(-) create mode 100644 src/gallium/auxiliary/vl/vl_mc.c create mode 100644 src/gallium/auxiliary/vl/vl_mc.h delete mode 100644 src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c delete mode 100644 src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index 425ae78138b..d210a25510b 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -149,11 +149,11 @@ C_SOURCES = \ util/u_vbuf_mgr.c \ vl/vl_context.c \ vl/vl_bitstream_parser.c \ - vl/vl_mpeg12_mc_renderer.c \ vl/vl_mpeg12_decoder.c \ vl/vl_compositor.c \ vl/vl_csc.c \ vl/vl_idct.c \ + vl/vl_mc.c \ vl/vl_vertex_buffers.c \ vl/vl_video_buffer.c diff --git a/src/gallium/auxiliary/vl/vl_mc.c b/src/gallium/auxiliary/vl/vl_mc.c new file mode 100644 index 00000000000..707a4a27077 --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_mc.c @@ -0,0 +1,668 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include + +#include +#include + +#include + +#include "vl_defines.h" +#include "vl_vertex_buffers.h" +#include "vl_mc.h" + +enum VS_OUTPUT +{ + VS_O_VPOS, + VS_O_LINE, + VS_O_VTOP, + VS_O_VBOTTOM +}; + +static struct ureg_dst +calc_position(struct vl_mc *r, struct ureg_program *shader) +{ + struct ureg_src block_scale; + struct ureg_src vrect, vpos; + struct ureg_dst t_vpos; + struct ureg_dst o_vpos; + + vrect = ureg_DECL_vs_input(shader, VS_I_RECT); + vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); + + t_vpos = ureg_DECL_temporary(shader); + + o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); + + /* + * block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height) + * + * t_vpos = (vpos + vrect) * block_scale + * o_vpos.xy = t_vpos + * o_vpos.zw = vpos + */ + block_scale = ureg_imm2f(shader, + (float)MACROBLOCK_WIDTH / r->buffer_width, + (float)MACROBLOCK_HEIGHT / r->buffer_height); + + ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect); + ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), block_scale); + ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos)); + ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), vpos); + + return t_vpos; +} + +static void * +create_ycbcr_vert_shader(struct vl_mc *r) +{ + struct ureg_program *shader; + struct ureg_src block_scale; + struct ureg_src vrect, vpos, eb, flags; + struct ureg_dst t_vpos, t_vtex; + struct ureg_dst o_line, o_vtex[2]; + unsigned label; + + shader = ureg_create(TGSI_PROCESSOR_VERTEX); + if (!shader) + return NULL; + + vrect = ureg_DECL_vs_input(shader, VS_I_RECT); + vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); + eb = ureg_DECL_vs_input(shader, VS_I_EB); + flags = ureg_DECL_vs_input(shader, VS_I_FLAGS); + + t_vpos = calc_position(r, shader); + t_vtex = ureg_DECL_temporary(shader); + + o_line = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE); + o_vtex[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP); + o_vtex[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM); + + /* + * block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height) + * + * o_line.x = interlaced + * o_line.y = vrect + * + * o_vtex[0].z = vrect.x ? eb.y : eb.x + * o_vtex[1].z = vrect.x ? eb.w : eb.z + * + * if(interlaced) { + * t_vtex.x = vrect.x + * t_vtex.y = vrect.y * 0.5 + * t_vtex += vpos + * + * o_vtex[0].xy = t_vtex * block_scale + * + * t_vtex.y += 0.5 + * o_vtex[1].xy = t_vtex * block_scale + * } else { + * o_vtex[0..1].xy = t_vpos + * } + * o_vtex[2].xy = t_vpos + * + */ + block_scale = ureg_imm2f(shader, + (float)MACROBLOCK_WIDTH / r->buffer_width, + (float)MACROBLOCK_HEIGHT / r->buffer_height); + + ureg_MUL(shader, ureg_writemask(o_line, TGSI_WRITEMASK_X), flags, ureg_imm1f(shader, 0.5f)); + ureg_MOV(shader, ureg_writemask(o_line, TGSI_WRITEMASK_Y), vrect); + + ureg_MOV(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_XY), ureg_src(t_vpos)); + ureg_CMP(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_Z), + ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_X)), + ureg_scalar(eb, TGSI_SWIZZLE_Y), + ureg_scalar(eb, TGSI_SWIZZLE_X)); + + ureg_MOV(shader, ureg_writemask(o_vtex[1], TGSI_WRITEMASK_XY), ureg_src(t_vpos)); + ureg_CMP(shader, ureg_writemask(o_vtex[1], TGSI_WRITEMASK_Z), + ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_X)), + ureg_scalar(eb, TGSI_SWIZZLE_W), + ureg_scalar(eb, TGSI_SWIZZLE_Z)); + + if (r->macroblock_size == MACROBLOCK_HEIGHT) { //TODO + ureg_IF(shader, ureg_scalar(flags, TGSI_SWIZZLE_Y), &label); + + ureg_MOV(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_X), vrect); + ureg_MUL(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y), vrect, ureg_imm1f(shader, 0.5f)); + ureg_ADD(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_XY), vpos, ureg_src(t_vtex)); + ureg_MUL(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_XY), ureg_src(t_vtex), block_scale); + ureg_ADD(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y), ureg_src(t_vtex), ureg_imm1f(shader, 0.5f)); + ureg_MUL(shader, ureg_writemask(o_vtex[1], TGSI_WRITEMASK_XY), ureg_src(t_vtex), block_scale); + + ureg_MUL(shader, ureg_writemask(o_line, TGSI_WRITEMASK_Y), + ureg_scalar(vrect, TGSI_SWIZZLE_Y), + ureg_imm1f(shader, MACROBLOCK_HEIGHT / 2)); + + ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); + ureg_ENDIF(shader); + } + + ureg_release_temporary(shader, t_vtex); + ureg_release_temporary(shader, t_vpos); + + ureg_END(shader); + + return ureg_create_shader_and_destroy(shader, r->pipe); +} + +static void * +create_ref_vert_shader(struct vl_mc *r) +{ + struct ureg_program *shader; + struct ureg_src mv_scale; + struct ureg_src vrect, vmv[2]; + struct ureg_dst t_vpos; + struct ureg_dst o_vpos, o_line, o_vmv[2]; + unsigned i; + + shader = ureg_create(TGSI_PROCESSOR_VERTEX); + if (!shader) + return NULL; + + vrect = ureg_DECL_vs_input(shader, VS_I_RECT); + ureg_DECL_vs_input(shader, VS_I_EB); + ureg_DECL_vs_input(shader, VS_I_FLAGS); + vmv[0] = ureg_DECL_vs_input(shader, VS_I_MV_TOP); + vmv[1] = ureg_DECL_vs_input(shader, VS_I_MV_BOTTOM); + + t_vpos = calc_position(r, shader); + + o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); + o_line = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE); + o_vmv[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP); + o_vmv[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM); + + /* + * mv_scale = 0.5 / (dst.width, dst.height); + * + * // Apply motion vectors + * o_vmv[0..3] = t_vpos + vmv[0..3] * mv_scale + * + * o_line.y = vrect + * + */ + + ureg_MUL(shader, ureg_writemask(o_line, TGSI_WRITEMASK_Y), + vrect, ureg_imm1f(shader, r->macroblock_size / 2)); + + mv_scale = ureg_imm4f(shader, + 0.5f / r->buffer_width, + 0.5f / r->buffer_height, + 1.0f / 4.0f, + 1.0f / 255.0f); + + for (i = 0; i < 2; ++i) { + ureg_MAD(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_XY), mv_scale, vmv[i], ureg_src(t_vpos)); + ureg_MUL(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_ZW), mv_scale, vmv[i]); + } + + ureg_release_temporary(shader, t_vpos); + + ureg_END(shader); + + return ureg_create_shader_and_destroy(shader, r->pipe); +} + +static struct ureg_dst +calc_field(struct ureg_program *shader) +{ + struct ureg_dst tmp; + struct ureg_src line; + + tmp = ureg_DECL_temporary(shader); + + line = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE, TGSI_INTERPOLATE_LINEAR); + + /* + * line.x is flag for intra frames + * line.y going from 0 to 1 if not interlaced + * line.y going from 0 to 8 in steps of 0.5 if interlaced + * + * tmp.xy = fraction(line) + * tmp.xy = tmp.xy >= 0.5 ? 1 : 0 + */ + ureg_MOV(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), line); + ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), line); + ureg_SGE(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(tmp), ureg_imm1f(shader, 0.5f)); + + return tmp; +} + +static void * +create_ycbcr_frag_shader(struct vl_mc *r, float scale) +{ + struct ureg_program *shader; + struct ureg_src tc[2], sampler; + struct ureg_dst texel, t_tc, field; + struct ureg_dst fragment; + unsigned label; + + shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); + if (!shader) + return NULL; + + tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR); + tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR); + + sampler = ureg_DECL_sampler(shader, 0); + + t_tc = ureg_DECL_temporary(shader); + texel = ureg_DECL_temporary(shader); + + fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); + + field = calc_field(shader); + + /* + * texel.y = tex(field.y ? tc[1] : tc[0], sampler[0]) + * texel.cb = tex(tc[2], sampler[1]) + * texel.cr = tex(tc[2], sampler[2]) + */ + + ureg_CMP(shader, ureg_writemask(t_tc, TGSI_WRITEMASK_XYZ), + ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), + tc[1], tc[0]); + + ureg_SLT(shader, ureg_writemask(t_tc, TGSI_WRITEMASK_Z), ureg_src(t_tc), ureg_imm1f(shader, 0.5f)); + + ureg_MOV(shader, fragment, ureg_imm4f(shader, 0.0f, 0.0f, 0.0f, 1.0f)); + ureg_IF(shader, ureg_scalar(ureg_src(t_tc), TGSI_SWIZZLE_Z), &label); + + ureg_TEX(shader, texel, TGSI_TEXTURE_3D, ureg_src(t_tc), sampler); + + if (scale != 1.0f) + ureg_MAD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), + ureg_src(texel), ureg_imm1f(shader, scale), + ureg_scalar(ureg_src(field), TGSI_SWIZZLE_X)); + else + ureg_ADD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), + ureg_src(texel), ureg_scalar(ureg_src(field), TGSI_SWIZZLE_X)); + + ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); + ureg_ENDIF(shader); + + ureg_release_temporary(shader, t_tc); + ureg_release_temporary(shader, texel); + + return ureg_create_shader_and_destroy(shader, r->pipe); +} + +static void * +create_ref_frag_shader(struct vl_mc *r) +{ + const float y_scale = + r->buffer_height / 2 * + r->macroblock_size / MACROBLOCK_HEIGHT; + + struct ureg_program *shader; + struct ureg_src tc[2], sampler; + struct ureg_dst ref, field; + struct ureg_dst fragment; + unsigned label; + + shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); + if (!shader) + return NULL; + + tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR); + tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR); + + sampler = ureg_DECL_sampler(shader, 0); + ref = ureg_DECL_temporary(shader); + + fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); + + field = calc_field(shader); + + /* + * ref = field.z ? tc[1] : tc[0] + * + * // Adjust tc acording to top/bottom field selection + * if (|ref.z|) { + * ref.y *= y_scale + * ref.y = floor(ref.y) + * ref.y += ref.z + * ref.y /= y_scale + * } + * fragment.xyz = tex(ref, sampler[0]) + */ + ureg_CMP(shader, ureg_writemask(ref, TGSI_WRITEMASK_XYZ), + ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), + tc[1], tc[0]); + ureg_CMP(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), + ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), + tc[1], tc[0]); + + ureg_IF(shader, ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z), &label); + + ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), + ureg_src(ref), ureg_imm1f(shader, y_scale)); + ureg_FLR(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), ureg_src(ref)); + ureg_ADD(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), + ureg_src(ref), ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z)); + ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), + ureg_src(ref), ureg_imm1f(shader, 1.0f / y_scale)); + + ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); + ureg_ENDIF(shader); + + ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), TGSI_TEXTURE_2D, ureg_src(ref), sampler); + + ureg_release_temporary(shader, ref); + + ureg_release_temporary(shader, field); + ureg_END(shader); + + return ureg_create_shader_and_destroy(shader, r->pipe); +} + +static bool +init_pipe_state(struct vl_mc *r) +{ + struct pipe_sampler_state sampler; + struct pipe_blend_state blend; + struct pipe_rasterizer_state rs_state; + + assert(r); + + memset(&sampler, 0, sizeof(sampler)); + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER; + sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + sampler.compare_mode = PIPE_TEX_COMPARE_NONE; + sampler.compare_func = PIPE_FUNC_ALWAYS; + sampler.normalized_coords = 1; + r->sampler_ref = r->pipe->create_sampler_state(r->pipe, &sampler); + if (!r->sampler_ref) + goto error_sampler_ref; + + sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + r->sampler_ycbcr = r->pipe->create_sampler_state(r->pipe, &sampler); + if (!r->sampler_ycbcr) + goto error_sampler_ycbcr; + + memset(&blend, 0, sizeof blend); + blend.independent_blend_enable = 0; + blend.rt[0].blend_enable = 1; + blend.rt[0].rgb_func = PIPE_BLEND_ADD; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.rt[0].alpha_func = PIPE_BLEND_ADD; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + blend.logicop_enable = 0; + blend.logicop_func = PIPE_LOGICOP_CLEAR; + blend.rt[0].colormask = PIPE_MASK_RGBA; + blend.dither = 0; + r->blend_clear = r->pipe->create_blend_state(r->pipe, &blend); + if (!r->blend_clear) + goto error_blend_clear; + + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + r->blend_add = r->pipe->create_blend_state(r->pipe, &blend); + if (!r->blend_add) + goto error_blend_add; + + memset(&rs_state, 0, sizeof(rs_state)); + /*rs_state.sprite_coord_enable */ + rs_state.sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT; + rs_state.point_quad_rasterization = true; + rs_state.point_size = BLOCK_WIDTH; + rs_state.gl_rasterization_rules = true; + r->rs_state = r->pipe->create_rasterizer_state(r->pipe, &rs_state); + if (!r->rs_state) + goto error_rs_state; + + return true; + +error_rs_state: + r->pipe->delete_blend_state(r->pipe, r->blend_add); + +error_blend_add: + r->pipe->delete_blend_state(r->pipe, r->blend_clear); + +error_blend_clear: + r->pipe->delete_sampler_state(r->pipe, r->sampler_ref); + +error_sampler_ref: + r->pipe->delete_sampler_state(r->pipe, r->sampler_ycbcr); + +error_sampler_ycbcr: + return false; +} + +static void +cleanup_pipe_state(struct vl_mc *r) +{ + assert(r); + + r->pipe->delete_sampler_state(r->pipe, r->sampler_ref); + r->pipe->delete_sampler_state(r->pipe, r->sampler_ycbcr); + r->pipe->delete_blend_state(r->pipe, r->blend_clear); + r->pipe->delete_blend_state(r->pipe, r->blend_add); + r->pipe->delete_rasterizer_state(r->pipe, r->rs_state); +} + +bool +vl_mc_init(struct vl_mc *renderer, struct pipe_context *pipe, + unsigned buffer_width, unsigned buffer_height, + unsigned macroblock_size, float scale) +{ + assert(renderer); + assert(pipe); + + memset(renderer, 0, sizeof(struct vl_mc)); + + renderer->pipe = pipe; + renderer->buffer_width = buffer_width; + renderer->buffer_height = buffer_height; + renderer->macroblock_size = macroblock_size; + + if (!init_pipe_state(renderer)) + goto error_pipe_state; + + renderer->vs_ref = create_ref_vert_shader(renderer); + if (!renderer->vs_ref) + goto error_vs_ref; + + renderer->vs_ycbcr = create_ycbcr_vert_shader(renderer); + if (!renderer->vs_ycbcr) + goto error_vs_ycbcr; + + renderer->fs_ref = create_ref_frag_shader(renderer); + if (!renderer->fs_ref) + goto error_fs_ref; + + renderer->fs_ycbcr = create_ycbcr_frag_shader(renderer, scale); + if (!renderer->fs_ycbcr) + goto error_fs_ycbcr; + + return true; + +error_fs_ycbcr: + renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref); + +error_fs_ref: + renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr); + +error_vs_ycbcr: + renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ref); + +error_vs_ref: + cleanup_pipe_state(renderer); + +error_pipe_state: + return false; +} + +void +vl_mc_cleanup(struct vl_mc *renderer) +{ + assert(renderer); + + cleanup_pipe_state(renderer); + + renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ref); + renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr); + renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref); + renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr); +} + +bool +vl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer, + struct pipe_sampler_view *source) +{ + assert(renderer && buffer); + assert(source); + + buffer->renderer = renderer; + + buffer->viewport.scale[2] = 1; + buffer->viewport.scale[3] = 1; + buffer->viewport.translate[0] = 0; + buffer->viewport.translate[1] = 0; + buffer->viewport.translate[2] = 0; + buffer->viewport.translate[3] = 0; + + buffer->fb_state.nr_cbufs = 1; + buffer->fb_state.zsbuf = NULL; + + pipe_sampler_view_reference(&buffer->source, source); + + return true; +} + +void +vl_mc_cleanup_buffer(struct vl_mc_buffer *buffer) +{ + assert(buffer); + + pipe_sampler_view_reference(&buffer->source, NULL); +} + +void +vl_mc_set_surface(struct vl_mc_buffer *buffer, struct pipe_surface *surface) +{ + assert(buffer && surface); + + buffer->surface_cleared = false; + + buffer->viewport.scale[0] = surface->width; + buffer->viewport.scale[1] = surface->height; + + buffer->fb_state.width = surface->width; + buffer->fb_state.height = surface->height; + buffer->fb_state.cbufs[0] = surface; +} + +static void +prepare_pipe_4_rendering(struct vl_mc_buffer *buffer) +{ + struct vl_mc *renderer; + + assert(buffer); + + renderer = buffer->renderer; + renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state); + + if (buffer->surface_cleared) + renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_add); + else { + renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_clear); + buffer->surface_cleared = true; + } + + renderer->pipe->set_framebuffer_state(renderer->pipe, &buffer->fb_state); + renderer->pipe->set_viewport_state(renderer->pipe, &buffer->viewport); +} + +void +vl_mc_render_ref(struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref, + unsigned not_empty_start_instance, unsigned not_empty_num_instances, + unsigned empty_start_instance, unsigned empty_num_instances) +{ + struct vl_mc *renderer; + + assert(buffer && ref); + + if (not_empty_num_instances == 0 && empty_num_instances == 0) + return; + + prepare_pipe_4_rendering(buffer); + + renderer = buffer->renderer; + + renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ref); + renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ref); + + renderer->pipe->set_fragment_sampler_views(renderer->pipe, 1, &ref); + renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ref); + + if (not_empty_num_instances > 0) + util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, + not_empty_start_instance, not_empty_num_instances); + + if (empty_num_instances > 0) + util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, + empty_start_instance, empty_num_instances); +} + +void +vl_mc_render_ycbcr(struct vl_mc_buffer *buffer, + unsigned not_empty_start_instance, unsigned not_empty_num_instances) +{ + struct vl_mc *renderer; + + assert(buffer); + + if (not_empty_num_instances == 0) + return; + + prepare_pipe_4_rendering(buffer); + + renderer = buffer->renderer; + + renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ycbcr); + renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr); + + renderer->pipe->set_fragment_sampler_views(renderer->pipe, 1, &buffer->source); + renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ycbcr); + + util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, + not_empty_start_instance, not_empty_num_instances); +} diff --git a/src/gallium/auxiliary/vl/vl_mc.h b/src/gallium/auxiliary/vl/vl_mc.h new file mode 100644 index 00000000000..e5b16b5b9da --- /dev/null +++ b/src/gallium/auxiliary/vl/vl_mc.h @@ -0,0 +1,85 @@ +/************************************************************************** + * + * Copyright 2009 Younes Manton. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef vl_mc_h +#define vl_mc_h + +#include +#include + +#include "vl_types.h" + +struct pipe_context; + +struct vl_mc +{ + struct pipe_context *pipe; + unsigned buffer_width; + unsigned buffer_height; + unsigned macroblock_size; + + void *rs_state; + + void *blend_clear, *blend_add; + void *vs_ref, *vs_ycbcr; + void *fs_ref, *fs_ycbcr; + void *sampler_ref, *sampler_ycbcr; +}; + +struct vl_mc_buffer +{ + struct vl_mc *renderer; + + bool surface_cleared; + + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state fb_state; + + struct pipe_sampler_view *source; +}; + +bool vl_mc_init(struct vl_mc *renderer, struct pipe_context *pipe, + unsigned picture_width, unsigned picture_height, + unsigned macroblock_size, float scale); + +void vl_mc_cleanup(struct vl_mc *renderer); + +bool vl_mc_init_buffer(struct vl_mc *renderer, struct vl_mc_buffer *buffer, + struct pipe_sampler_view *source); + +void vl_mc_cleanup_buffer(struct vl_mc_buffer *buffer); + +void vl_mc_set_surface(struct vl_mc_buffer *buffer, struct pipe_surface *surface); + +void vl_mc_render_ref(struct vl_mc_buffer *buffer, struct pipe_sampler_view *ref, + unsigned not_empty_start_instance, unsigned not_empty_num_instances, + unsigned empty_start_instance, unsigned empty_num_instances); + +void vl_mc_render_ycbcr(struct vl_mc_buffer *buffer, + unsigned not_empty_start_instance, unsigned not_empty_num_instances); + +#endif /* vl_mc_h */ diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h index 6f93c5a01ab..4d494b0bd2a 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h +++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.h @@ -31,7 +31,7 @@ #include #include "vl_idct.h" -#include "vl_mpeg12_mc_renderer.h" +#include "vl_mc.h" #include "vl_vertex_buffers.h" #include "vl_video_buffer.h" @@ -56,7 +56,7 @@ struct vl_mpeg12_decoder void *ves_mv[2]; struct vl_idct idct_y, idct_c; - struct vl_mpeg12_mc_renderer mc_y, mc_c; + struct vl_mc mc_y, mc_c; void *dsa; void *blend; @@ -81,7 +81,7 @@ struct vl_mpeg12_buffer } vertex_bufs; struct vl_idct_buffer idct[VL_MAX_PLANES]; - struct vl_mpeg12_mc_buffer mc[VL_MAX_PLANES]; + struct vl_mc_buffer mc[VL_MAX_PLANES]; struct pipe_transfer *tex_transfer[VL_MAX_PLANES]; short *texels[VL_MAX_PLANES]; diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c deleted file mode 100644 index eae546aefcc..00000000000 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c +++ /dev/null @@ -1,668 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 Younes Manton. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include - -#include - -#include -#include - -#include - -#include "vl_defines.h" -#include "vl_vertex_buffers.h" -#include "vl_mpeg12_mc_renderer.h" - -enum VS_OUTPUT -{ - VS_O_VPOS, - VS_O_LINE, - VS_O_VTOP, - VS_O_VBOTTOM -}; - -static struct ureg_dst -calc_position(struct vl_mpeg12_mc_renderer *r, struct ureg_program *shader) -{ - struct ureg_src block_scale; - struct ureg_src vrect, vpos; - struct ureg_dst t_vpos; - struct ureg_dst o_vpos; - - vrect = ureg_DECL_vs_input(shader, VS_I_RECT); - vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); - - t_vpos = ureg_DECL_temporary(shader); - - o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); - - /* - * block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height) - * - * t_vpos = (vpos + vrect) * block_scale - * o_vpos.xy = t_vpos - * o_vpos.zw = vpos - */ - block_scale = ureg_imm2f(shader, - (float)MACROBLOCK_WIDTH / r->buffer_width, - (float)MACROBLOCK_HEIGHT / r->buffer_height); - - ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect); - ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), block_scale); - ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos)); - ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), vpos); - - return t_vpos; -} - -static void * -create_ycbcr_vert_shader(struct vl_mpeg12_mc_renderer *r) -{ - struct ureg_program *shader; - struct ureg_src block_scale; - struct ureg_src vrect, vpos, eb, flags; - struct ureg_dst t_vpos, t_vtex; - struct ureg_dst o_line, o_vtex[2]; - unsigned label; - - shader = ureg_create(TGSI_PROCESSOR_VERTEX); - if (!shader) - return NULL; - - vrect = ureg_DECL_vs_input(shader, VS_I_RECT); - vpos = ureg_DECL_vs_input(shader, VS_I_VPOS); - eb = ureg_DECL_vs_input(shader, VS_I_EB); - flags = ureg_DECL_vs_input(shader, VS_I_FLAGS); - - t_vpos = calc_position(r, shader); - t_vtex = ureg_DECL_temporary(shader); - - o_line = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE); - o_vtex[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP); - o_vtex[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM); - - /* - * block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height) - * - * o_line.x = interlaced - * o_line.y = vrect - * - * o_vtex[0].z = vrect.x ? eb.y : eb.x - * o_vtex[1].z = vrect.x ? eb.w : eb.z - * - * if(interlaced) { - * t_vtex.x = vrect.x - * t_vtex.y = vrect.y * 0.5 - * t_vtex += vpos - * - * o_vtex[0].xy = t_vtex * block_scale - * - * t_vtex.y += 0.5 - * o_vtex[1].xy = t_vtex * block_scale - * } else { - * o_vtex[0..1].xy = t_vpos - * } - * o_vtex[2].xy = t_vpos - * - */ - block_scale = ureg_imm2f(shader, - (float)MACROBLOCK_WIDTH / r->buffer_width, - (float)MACROBLOCK_HEIGHT / r->buffer_height); - - ureg_MUL(shader, ureg_writemask(o_line, TGSI_WRITEMASK_X), flags, ureg_imm1f(shader, 0.5f)); - ureg_MOV(shader, ureg_writemask(o_line, TGSI_WRITEMASK_Y), vrect); - - ureg_MOV(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_XY), ureg_src(t_vpos)); - ureg_CMP(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_Z), - ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_X)), - ureg_scalar(eb, TGSI_SWIZZLE_Y), - ureg_scalar(eb, TGSI_SWIZZLE_X)); - - ureg_MOV(shader, ureg_writemask(o_vtex[1], TGSI_WRITEMASK_XY), ureg_src(t_vpos)); - ureg_CMP(shader, ureg_writemask(o_vtex[1], TGSI_WRITEMASK_Z), - ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_X)), - ureg_scalar(eb, TGSI_SWIZZLE_W), - ureg_scalar(eb, TGSI_SWIZZLE_Z)); - - if (r->macroblock_size == MACROBLOCK_HEIGHT) { //TODO - ureg_IF(shader, ureg_scalar(flags, TGSI_SWIZZLE_Y), &label); - - ureg_MOV(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_X), vrect); - ureg_MUL(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y), vrect, ureg_imm1f(shader, 0.5f)); - ureg_ADD(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_XY), vpos, ureg_src(t_vtex)); - ureg_MUL(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_XY), ureg_src(t_vtex), block_scale); - ureg_ADD(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y), ureg_src(t_vtex), ureg_imm1f(shader, 0.5f)); - ureg_MUL(shader, ureg_writemask(o_vtex[1], TGSI_WRITEMASK_XY), ureg_src(t_vtex), block_scale); - - ureg_MUL(shader, ureg_writemask(o_line, TGSI_WRITEMASK_Y), - ureg_scalar(vrect, TGSI_SWIZZLE_Y), - ureg_imm1f(shader, MACROBLOCK_HEIGHT / 2)); - - ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); - ureg_ENDIF(shader); - } - - ureg_release_temporary(shader, t_vtex); - ureg_release_temporary(shader, t_vpos); - - ureg_END(shader); - - return ureg_create_shader_and_destroy(shader, r->pipe); -} - -static void * -create_ref_vert_shader(struct vl_mpeg12_mc_renderer *r) -{ - struct ureg_program *shader; - struct ureg_src mv_scale; - struct ureg_src vrect, vmv[2]; - struct ureg_dst t_vpos; - struct ureg_dst o_vpos, o_line, o_vmv[2]; - unsigned i; - - shader = ureg_create(TGSI_PROCESSOR_VERTEX); - if (!shader) - return NULL; - - vrect = ureg_DECL_vs_input(shader, VS_I_RECT); - ureg_DECL_vs_input(shader, VS_I_EB); - ureg_DECL_vs_input(shader, VS_I_FLAGS); - vmv[0] = ureg_DECL_vs_input(shader, VS_I_MV_TOP); - vmv[1] = ureg_DECL_vs_input(shader, VS_I_MV_BOTTOM); - - t_vpos = calc_position(r, shader); - - o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS); - o_line = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE); - o_vmv[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP); - o_vmv[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM); - - /* - * mv_scale = 0.5 / (dst.width, dst.height); - * - * // Apply motion vectors - * o_vmv[0..3] = t_vpos + vmv[0..3] * mv_scale - * - * o_line.y = vrect - * - */ - - ureg_MUL(shader, ureg_writemask(o_line, TGSI_WRITEMASK_Y), - vrect, ureg_imm1f(shader, r->macroblock_size / 2)); - - mv_scale = ureg_imm4f(shader, - 0.5f / r->buffer_width, - 0.5f / r->buffer_height, - 1.0f / 4.0f, - 1.0f / 255.0f); - - for (i = 0; i < 2; ++i) { - ureg_MAD(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_XY), mv_scale, vmv[i], ureg_src(t_vpos)); - ureg_MUL(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_ZW), mv_scale, vmv[i]); - } - - ureg_release_temporary(shader, t_vpos); - - ureg_END(shader); - - return ureg_create_shader_and_destroy(shader, r->pipe); -} - -static struct ureg_dst -calc_field(struct ureg_program *shader) -{ - struct ureg_dst tmp; - struct ureg_src line; - - tmp = ureg_DECL_temporary(shader); - - line = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE, TGSI_INTERPOLATE_LINEAR); - - /* - * line.x is flag for intra frames - * line.y going from 0 to 1 if not interlaced - * line.y going from 0 to 8 in steps of 0.5 if interlaced - * - * tmp.xy = fraction(line) - * tmp.xy = tmp.xy >= 0.5 ? 1 : 0 - */ - ureg_MOV(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), line); - ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), line); - ureg_SGE(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(tmp), ureg_imm1f(shader, 0.5f)); - - return tmp; -} - -static void * -create_ycbcr_frag_shader(struct vl_mpeg12_mc_renderer *r, float scale) -{ - struct ureg_program *shader; - struct ureg_src tc[2], sampler; - struct ureg_dst texel, t_tc, field; - struct ureg_dst fragment; - unsigned label; - - shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); - if (!shader) - return NULL; - - tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR); - tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR); - - sampler = ureg_DECL_sampler(shader, 0); - - t_tc = ureg_DECL_temporary(shader); - texel = ureg_DECL_temporary(shader); - - fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); - - field = calc_field(shader); - - /* - * texel.y = tex(field.y ? tc[1] : tc[0], sampler[0]) - * texel.cb = tex(tc[2], sampler[1]) - * texel.cr = tex(tc[2], sampler[2]) - */ - - ureg_CMP(shader, ureg_writemask(t_tc, TGSI_WRITEMASK_XYZ), - ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), - tc[1], tc[0]); - - ureg_SLT(shader, ureg_writemask(t_tc, TGSI_WRITEMASK_Z), ureg_src(t_tc), ureg_imm1f(shader, 0.5f)); - - ureg_MOV(shader, fragment, ureg_imm4f(shader, 0.0f, 0.0f, 0.0f, 1.0f)); - ureg_IF(shader, ureg_scalar(ureg_src(t_tc), TGSI_SWIZZLE_Z), &label); - - ureg_TEX(shader, texel, TGSI_TEXTURE_3D, ureg_src(t_tc), sampler); - - if (scale != 1.0f) - ureg_MAD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), - ureg_src(texel), ureg_imm1f(shader, scale), - ureg_scalar(ureg_src(field), TGSI_SWIZZLE_X)); - else - ureg_ADD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), - ureg_src(texel), ureg_scalar(ureg_src(field), TGSI_SWIZZLE_X)); - - ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); - ureg_ENDIF(shader); - - ureg_release_temporary(shader, t_tc); - ureg_release_temporary(shader, texel); - - return ureg_create_shader_and_destroy(shader, r->pipe); -} - -static void * -create_ref_frag_shader(struct vl_mpeg12_mc_renderer *r) -{ - const float y_scale = - r->buffer_height / 2 * - r->macroblock_size / MACROBLOCK_HEIGHT; - - struct ureg_program *shader; - struct ureg_src tc[2], sampler; - struct ureg_dst ref, field; - struct ureg_dst fragment; - unsigned label; - - shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); - if (!shader) - return NULL; - - tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP, TGSI_INTERPOLATE_LINEAR); - tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM, TGSI_INTERPOLATE_LINEAR); - - sampler = ureg_DECL_sampler(shader, 0); - ref = ureg_DECL_temporary(shader); - - fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); - - field = calc_field(shader); - - /* - * ref = field.z ? tc[1] : tc[0] - * - * // Adjust tc acording to top/bottom field selection - * if (|ref.z|) { - * ref.y *= y_scale - * ref.y = floor(ref.y) - * ref.y += ref.z - * ref.y /= y_scale - * } - * fragment.xyz = tex(ref, sampler[0]) - */ - ureg_CMP(shader, ureg_writemask(ref, TGSI_WRITEMASK_XYZ), - ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), - tc[1], tc[0]); - ureg_CMP(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), - ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), - tc[1], tc[0]); - - ureg_IF(shader, ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z), &label); - - ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), - ureg_src(ref), ureg_imm1f(shader, y_scale)); - ureg_FLR(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), ureg_src(ref)); - ureg_ADD(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), - ureg_src(ref), ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_Z)); - ureg_MUL(shader, ureg_writemask(ref, TGSI_WRITEMASK_Y), - ureg_src(ref), ureg_imm1f(shader, 1.0f / y_scale)); - - ureg_fixup_label(shader, label, ureg_get_instruction_number(shader)); - ureg_ENDIF(shader); - - ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), TGSI_TEXTURE_2D, ureg_src(ref), sampler); - - ureg_release_temporary(shader, ref); - - ureg_release_temporary(shader, field); - ureg_END(shader); - - return ureg_create_shader_and_destroy(shader, r->pipe); -} - -static bool -init_pipe_state(struct vl_mpeg12_mc_renderer *r) -{ - struct pipe_sampler_state sampler; - struct pipe_blend_state blend; - struct pipe_rasterizer_state rs_state; - - assert(r); - - memset(&sampler, 0, sizeof(sampler)); - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; - sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER; - sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; - sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; - sampler.compare_mode = PIPE_TEX_COMPARE_NONE; - sampler.compare_func = PIPE_FUNC_ALWAYS; - sampler.normalized_coords = 1; - r->sampler_ref = r->pipe->create_sampler_state(r->pipe, &sampler); - if (!r->sampler_ref) - goto error_sampler_ref; - - sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; - sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; - r->sampler_ycbcr = r->pipe->create_sampler_state(r->pipe, &sampler); - if (!r->sampler_ycbcr) - goto error_sampler_ycbcr; - - memset(&blend, 0, sizeof blend); - blend.independent_blend_enable = 0; - blend.rt[0].blend_enable = 1; - blend.rt[0].rgb_func = PIPE_BLEND_ADD; - blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.rt[0].alpha_func = PIPE_BLEND_ADD; - blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; - blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.logicop_enable = 0; - blend.logicop_func = PIPE_LOGICOP_CLEAR; - blend.rt[0].colormask = PIPE_MASK_RGBA; - blend.dither = 0; - r->blend_clear = r->pipe->create_blend_state(r->pipe, &blend); - if (!r->blend_clear) - goto error_blend_clear; - - blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; - r->blend_add = r->pipe->create_blend_state(r->pipe, &blend); - if (!r->blend_add) - goto error_blend_add; - - memset(&rs_state, 0, sizeof(rs_state)); - /*rs_state.sprite_coord_enable */ - rs_state.sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT; - rs_state.point_quad_rasterization = true; - rs_state.point_size = BLOCK_WIDTH; - rs_state.gl_rasterization_rules = true; - r->rs_state = r->pipe->create_rasterizer_state(r->pipe, &rs_state); - if (!r->rs_state) - goto error_rs_state; - - return true; - -error_rs_state: - r->pipe->delete_blend_state(r->pipe, r->blend_add); - -error_blend_add: - r->pipe->delete_blend_state(r->pipe, r->blend_clear); - -error_blend_clear: - r->pipe->delete_sampler_state(r->pipe, r->sampler_ref); - -error_sampler_ref: - r->pipe->delete_sampler_state(r->pipe, r->sampler_ycbcr); - -error_sampler_ycbcr: - return false; -} - -static void -cleanup_pipe_state(struct vl_mpeg12_mc_renderer *r) -{ - assert(r); - - r->pipe->delete_sampler_state(r->pipe, r->sampler_ref); - r->pipe->delete_sampler_state(r->pipe, r->sampler_ycbcr); - r->pipe->delete_blend_state(r->pipe, r->blend_clear); - r->pipe->delete_blend_state(r->pipe, r->blend_add); - r->pipe->delete_rasterizer_state(r->pipe, r->rs_state); -} - -bool -vl_mc_init(struct vl_mpeg12_mc_renderer *renderer, struct pipe_context *pipe, - unsigned buffer_width, unsigned buffer_height, - unsigned macroblock_size, float scale) -{ - assert(renderer); - assert(pipe); - - memset(renderer, 0, sizeof(struct vl_mpeg12_mc_renderer)); - - renderer->pipe = pipe; - renderer->buffer_width = buffer_width; - renderer->buffer_height = buffer_height; - renderer->macroblock_size = macroblock_size; - - if (!init_pipe_state(renderer)) - goto error_pipe_state; - - renderer->vs_ref = create_ref_vert_shader(renderer); - if (!renderer->vs_ref) - goto error_vs_ref; - - renderer->vs_ycbcr = create_ycbcr_vert_shader(renderer); - if (!renderer->vs_ycbcr) - goto error_vs_ycbcr; - - renderer->fs_ref = create_ref_frag_shader(renderer); - if (!renderer->fs_ref) - goto error_fs_ref; - - renderer->fs_ycbcr = create_ycbcr_frag_shader(renderer, scale); - if (!renderer->fs_ycbcr) - goto error_fs_ycbcr; - - return true; - -error_fs_ycbcr: - renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref); - -error_fs_ref: - renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr); - -error_vs_ycbcr: - renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ref); - -error_vs_ref: - cleanup_pipe_state(renderer); - -error_pipe_state: - return false; -} - -void -vl_mc_cleanup(struct vl_mpeg12_mc_renderer *renderer) -{ - assert(renderer); - - cleanup_pipe_state(renderer); - - renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ref); - renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs_ycbcr); - renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ref); - renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs_ycbcr); -} - -bool -vl_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer, - struct pipe_sampler_view *source) -{ - assert(renderer && buffer); - assert(source); - - buffer->renderer = renderer; - - buffer->viewport.scale[2] = 1; - buffer->viewport.scale[3] = 1; - buffer->viewport.translate[0] = 0; - buffer->viewport.translate[1] = 0; - buffer->viewport.translate[2] = 0; - buffer->viewport.translate[3] = 0; - - buffer->fb_state.nr_cbufs = 1; - buffer->fb_state.zsbuf = NULL; - - pipe_sampler_view_reference(&buffer->source, source); - - return true; -} - -void -vl_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer) -{ - assert(buffer); - - pipe_sampler_view_reference(&buffer->source, NULL); -} - -void -vl_mc_set_surface(struct vl_mpeg12_mc_buffer *buffer, struct pipe_surface *surface) -{ - assert(buffer && surface); - - buffer->surface_cleared = false; - - buffer->viewport.scale[0] = surface->width; - buffer->viewport.scale[1] = surface->height; - - buffer->fb_state.width = surface->width; - buffer->fb_state.height = surface->height; - buffer->fb_state.cbufs[0] = surface; -} - -static void -prepare_pipe_4_rendering(struct vl_mpeg12_mc_buffer *buffer) -{ - struct vl_mpeg12_mc_renderer *renderer; - - assert(buffer); - - renderer = buffer->renderer; - renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state); - - if (buffer->surface_cleared) - renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_add); - else { - renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_clear); - buffer->surface_cleared = true; - } - - renderer->pipe->set_framebuffer_state(renderer->pipe, &buffer->fb_state); - renderer->pipe->set_viewport_state(renderer->pipe, &buffer->viewport); -} - -void -vl_mc_render_ref(struct vl_mpeg12_mc_buffer *buffer, struct pipe_sampler_view *ref, - unsigned not_empty_start_instance, unsigned not_empty_num_instances, - unsigned empty_start_instance, unsigned empty_num_instances) -{ - struct vl_mpeg12_mc_renderer *renderer; - - assert(buffer && ref); - - if (not_empty_num_instances == 0 && empty_num_instances == 0) - return; - - prepare_pipe_4_rendering(buffer); - - renderer = buffer->renderer; - - renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ref); - renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ref); - - renderer->pipe->set_fragment_sampler_views(renderer->pipe, 1, &ref); - renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ref); - - if (not_empty_num_instances > 0) - util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, - not_empty_start_instance, not_empty_num_instances); - - if (empty_num_instances > 0) - util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, - empty_start_instance, empty_num_instances); -} - -void -vl_mc_render_ycbcr(struct vl_mpeg12_mc_buffer *buffer, - unsigned not_empty_start_instance, unsigned not_empty_num_instances) -{ - struct vl_mpeg12_mc_renderer *renderer; - - assert(buffer); - - if (not_empty_num_instances == 0) - return; - - prepare_pipe_4_rendering(buffer); - - renderer = buffer->renderer; - - renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs_ycbcr); - renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr); - - renderer->pipe->set_fragment_sampler_views(renderer->pipe, 1, &buffer->source); - renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ycbcr); - - util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, - not_empty_start_instance, not_empty_num_instances); -} diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h deleted file mode 100644 index 4137ac407d2..00000000000 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 Younes Manton. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef vl_mpeg12_mc_renderer_h -#define vl_mpeg12_mc_renderer_h - -#include -#include - -#include "vl_types.h" - -struct pipe_context; - -struct vl_mpeg12_mc_renderer -{ - struct pipe_context *pipe; - unsigned buffer_width; - unsigned buffer_height; - unsigned macroblock_size; - - void *rs_state; - - void *blend_clear, *blend_add; - void *vs_ref, *vs_ycbcr; - void *fs_ref, *fs_ycbcr; - void *sampler_ref, *sampler_ycbcr; -}; - -struct vl_mpeg12_mc_buffer -{ - struct vl_mpeg12_mc_renderer *renderer; - - bool surface_cleared; - - struct pipe_viewport_state viewport; - struct pipe_framebuffer_state fb_state; - - struct pipe_sampler_view *source; -}; - -bool vl_mc_init(struct vl_mpeg12_mc_renderer *renderer, struct pipe_context *pipe, - unsigned picture_width, unsigned picture_height, - unsigned macroblock_size, float scale); - -void vl_mc_cleanup(struct vl_mpeg12_mc_renderer *renderer); - -bool vl_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer, - struct pipe_sampler_view *source); - -void vl_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer); - -void vl_mc_set_surface(struct vl_mpeg12_mc_buffer *buffer, struct pipe_surface *surface); - -void vl_mc_render_ref(struct vl_mpeg12_mc_buffer *buffer, struct pipe_sampler_view *ref, - unsigned not_empty_start_instance, unsigned not_empty_num_instances, - unsigned empty_start_instance, unsigned empty_num_instances); - -void vl_mc_render_ycbcr(struct vl_mpeg12_mc_buffer *buffer, - unsigned not_empty_start_instance, unsigned not_empty_num_instances); - -#endif /* vl_mpeg12_mc_renderer_h */ -- cgit v1.2.3