From 9c8bb28ca128dca9f279c78857da1b39223e30f7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20K=C3=B6nig?= Date: Sun, 17 Apr 2011 12:04:18 +0200 Subject: [PATCH] [g3dvl] move top/bottom field selection into mc code Removes the workaround and get interlaced videos to work 100% correctly. --- src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c | 45 +++++++++++++++++++----- src/gallium/auxiliary/vl/vl_vertex_buffers.c | 26 ++++++-------- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c index b87bd6b..eae546a 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c @@ -218,12 +218,12 @@ create_ref_vert_shader(struct vl_mpeg12_mc_renderer *r) mv_scale = ureg_imm4f(shader, 0.5f / r->buffer_width, 0.5f / r->buffer_height, - 1.0f, + 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_W), mv_scale, vmv[i]); + ureg_MUL(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_ZW), mv_scale, vmv[i]); } ureg_release_temporary(shader, t_vpos); @@ -320,10 +320,15 @@ create_ycbcr_frag_shader(struct vl_mpeg12_mc_renderer *r, float scale) 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) @@ -340,15 +345,37 @@ create_ref_frag_shader(struct vl_mpeg12_mc_renderer *r) field = calc_field(shader); /* - * if (field.z) - * ref[0..1] = tex(tc[0..1], sampler[0..1]) - * else - * ref[0..1] = tex(tc[2..3], sampler[0..1]) - * result = LRP(info.y, ref[0..1]) + * 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, ref, ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), tc[1], tc[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_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_src(ref)); ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), TGSI_TEXTURE_2D, ureg_src(ref), sampler); ureg_release_temporary(shader, ref); diff --git a/src/gallium/auxiliary/vl/vl_vertex_buffers.c b/src/gallium/auxiliary/vl/vl_vertex_buffers.c index fc30e85..84dfc9e 100644 --- a/src/gallium/auxiliary/vl/vl_vertex_buffers.c +++ b/src/gallium/auxiliary/vl/vl_vertex_buffers.c @@ -228,34 +228,28 @@ get_motion_vectors(struct pipe_mpeg12_macroblock *mb, struct vertex4s mv[4]) if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) { mv[0].x = mv[1].x = mb->mv[0].top.x; mv[0].y = mv[1].y = mb->mv[0].top.y; - mv[0].z = 0; mv[1].z = 1; + mv[0].z = mv[1].z = 0; mv[2].x = mv[3].x = mb->mv[1].top.x; mv[2].y = mv[3].y = mb->mv[1].top.y; - mv[2].z = 0; mv[3].z = 1; + mv[2].z = mv[3].z = 0; } else { mv[0].x = mb->mv[0].top.x; - mv[0].y = mb->mv[0].top.y - (mb->mv[0].top.y % 4); - mv[0].z = mb->mv[0].top.field_select; + mv[0].y = mb->mv[0].top.y; + mv[0].z = mb->mv[0].top.field_select ? 3 : 1; mv[1].x = mb->mv[0].bottom.x; - mv[1].y = mb->mv[0].bottom.y - (mb->mv[0].bottom.y % 4); - mv[1].z = mb->mv[0].bottom.field_select; - - if (mb->mv[0].top.field_select) mv[0].y += 2; - if (!mb->mv[0].bottom.field_select) mv[1].y -= 2; + mv[1].y = mb->mv[0].bottom.y; + mv[1].z = mb->mv[0].bottom.field_select ? 3 : 1; mv[2].x = mb->mv[1].top.x; - mv[2].y = mb->mv[1].top.y - (mb->mv[1].top.y % 4); - mv[2].z = mb->mv[1].top.field_select; + mv[2].y = mb->mv[1].top.y; + mv[2].z = mb->mv[1].top.field_select ? 3 : 1; mv[3].x = mb->mv[1].bottom.x; - mv[3].y = mb->mv[1].bottom.y - (mb->mv[1].bottom.y % 4); - mv[3].z = mb->mv[1].bottom.field_select; - - if (mb->mv[1].top.field_select) mv[2].y += 2; - if (!mb->mv[1].bottom.field_select) mv[3].y -= 2; + mv[3].y = mb->mv[1].bottom.y; + mv[3].z = mb->mv[1].bottom.field_select ? 3 : 1; } mv[0].w = mv[1].w = mb->mv[0].wheight; -- 2.7.4