Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / gallium / state_trackers / g3dvl / vl_r16snorm_mc_buf.c
index 08aed4542e72c449da739baa18c5febe70474804..e7a070ef4df28a1c4f395cc6c097360ac0b5e3ce 100644 (file)
@@ -6,10 +6,10 @@
 #include <pipe/p_winsys.h>
 #include <pipe/p_screen.h>
 #include <pipe/p_state.h>
-#include <pipe/p_util.h>
 #include <pipe/p_inlines.h>
 #include <tgsi/tgsi_parse.h>
 #include <tgsi/tgsi_build.h>
+#include <util/u_math.h>
 #include "vl_render.h"
 #include "vl_shader_build.h"
 #include "vl_surface.h"
 #include "vl_types.h"
 #include "vl_defs.h"
 
+/*
+ * TODO: Dynamically determine number of buf sets to use, based on
+ * video size and available mem, since we can easily run out of memory
+ * for high res videos.
+ * Note: Destroying previous frame's buffers and creating new ones
+ * doesn't work, since the buffer are not actually destroyed until their
+ * fence is signalled, and if we render fast enough we will create faster
+ * than we destroy.
+ */
 #define NUM_BUF_SETS 4 /* Number of rotating buffer sets to use */
 
 enum vlMacroBlockTypeEx
@@ -47,15 +56,16 @@ struct vlR16SnormBufferedMC
 {
        struct vlRender                         base;
 
-       unsigned int                            video_width, video_height;
-       enum vlFormat                           video_format;
+       unsigned int                            picture_width, picture_height;
+       enum vlFormat                           picture_format;
 
        unsigned int                            cur_buf;
        struct vlSurface                        *buffered_surface;
        struct vlSurface                        *past_surface, *future_surface;
        struct vlVertex2f                       surface_tex_inv_size;
-       unsigned int                            num_macroblocks[vlNumMacroBlockExTypes];
-       unsigned int                            total_num_macroblocks;
+       struct vlVertex2f                       zero_block[3];
+       unsigned int                            num_macroblocks;
+       struct vlMpeg2MacroBlock                *macroblocks;
 
        struct pipe_context                     *pipe;
        struct pipe_viewport_state              viewport;
@@ -64,8 +74,8 @@ struct vlR16SnormBufferedMC
        struct pipe_texture                     *textures[NUM_BUF_SETS][5];
        void                                    *i_vs, *p_vs[2], *b_vs[2];
        void                                    *i_fs, *p_fs[2], *b_fs[2];
-       struct pipe_vertex_buffer               vertex_bufs[NUM_BUF_SETS][vlNumMacroBlockExTypes][3];
-       struct pipe_vertex_element              vertex_elems[5];
+       struct pipe_vertex_buffer               vertex_bufs[NUM_BUF_SETS][3];
+       struct pipe_vertex_element              vertex_elems[8];
        struct pipe_constant_buffer             vs_const_buf, fs_const_buf;
 };
 
@@ -98,17 +108,7 @@ static inline int vlGrabFieldCodedBlock(short *src, short *dst, unsigned int dst
 {
        unsigned int y;
 
-       for (y = 0; y < VL_BLOCK_HEIGHT / 2; ++y)
-               memcpy
-               (
-                       dst + y * dst_pitch * 2,
-                       src + y * VL_BLOCK_WIDTH,
-                       VL_BLOCK_WIDTH * 2
-               );
-
-       dst += VL_BLOCK_HEIGHT * dst_pitch;
-
-       for (; y < VL_BLOCK_HEIGHT; ++y)
+       for (y = 0; y < VL_BLOCK_HEIGHT; ++y)
                memcpy
                (
                        dst + y * dst_pitch * 2,
@@ -130,7 +130,7 @@ static inline int vlGrabNoBlock(short *dst, unsigned int dst_pitch)
                        0,
                        VL_BLOCK_WIDTH * 2
                );
-       
+
        return 0;
 }
 
@@ -164,7 +164,7 @@ static inline int vlGrabBlocks
        tex_pitch = tex_surface->stride / tex_surface->block.size;
 
        texels += mbpy * tex_pitch + mbpx;
-       
+
        for (y = 0; y < 2; ++y)
        {
                for (x = 0; x < 2; ++x, ++tb)
@@ -194,8 +194,13 @@ static inline int vlGrabBlocks
 
                                ++sb;
                        }
-                       else
+                       else if (mc->zero_block[0].x < 0.0f)
+                       {
                                vlGrabNoBlock(texels + y * tex_pitch * VL_BLOCK_HEIGHT + x * VL_BLOCK_WIDTH, tex_pitch);
+
+                               mc->zero_block[0].x = (mbpx + x * 8) * mc->surface_tex_inv_size.x;
+                               mc->zero_block[0].y = (mbpy + y * 8) * mc->surface_tex_inv_size.y;
+                       }
                }
        }
 
@@ -232,79 +237,175 @@ static inline int vlGrabBlocks
 
                        ++sb;
                }
-               else
+               else if (mc->zero_block[tb + 1].x < 0.0f)
+               {
                        vlGrabNoBlock(texels, tex_pitch);
 
+                       mc->zero_block[tb + 1].x = (mbpx << 1) * mc->surface_tex_inv_size.x;
+                       mc->zero_block[tb + 1].y = (mbpy << 1) * mc->surface_tex_inv_size.y;
+               }
+
                pipe_surface_unmap(tex_surface);
        }
 
        return 0;
 }
 
-static inline int vlGrabMacroBlock
-(
-       struct vlR16SnormBufferedMC *mc,
-       struct vlMpeg2MacroBlock *macroblock
-)
+static inline enum vlMacroBlockTypeEx vlGetMacroBlockTypeEx(struct vlMpeg2MacroBlock *mb)
 {
-       const struct vlVertex2f unit =
-       {
-               mc->surface_tex_inv_size.x * VL_MACROBLOCK_WIDTH,
-               mc->surface_tex_inv_size.y * VL_MACROBLOCK_HEIGHT
-       };
-       const struct vlVertex2f half =
-       {
-               mc->surface_tex_inv_size.x * (VL_MACROBLOCK_WIDTH / 2),
-               mc->surface_tex_inv_size.y * (VL_MACROBLOCK_HEIGHT / 2)
-       };
+       assert(mb);
 
-       struct vlVertex2f       *vb;
-       enum vlMacroBlockTypeEx mb_type_ex;
-       struct vlVertex2f       mo_vec[2];
-       unsigned int            i;
-
-       assert(mc);
-       assert(macroblock);
-
-       switch (macroblock->mb_type)
+       switch (mb->mb_type)
        {
                case vlMacroBlockTypeIntra:
-               {
-                       mb_type_ex = vlMacroBlockExTypeIntra;
-                       break;
-               }
+                       return vlMacroBlockExTypeIntra;
                case vlMacroBlockTypeFwdPredicted:
-               {
-                       mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ?
+                       return mb->mo_type == vlMotionTypeFrame ?
                                vlMacroBlockExTypeFwdPredictedFrame : vlMacroBlockExTypeFwdPredictedField;
-                       break;
-               }
                case vlMacroBlockTypeBkwdPredicted:
-               {
-                       mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ?
+                       return mb->mo_type == vlMotionTypeFrame ?
                                vlMacroBlockExTypeBkwdPredictedFrame : vlMacroBlockExTypeBkwdPredictedField;
-                       break;
-               }
                case vlMacroBlockTypeBiPredicted:
-               {
-                       mb_type_ex = macroblock->mo_type == vlMotionTypeFrame ?
+                       return mb->mo_type == vlMotionTypeFrame ?
                                vlMacroBlockExTypeBiPredictedFrame : vlMacroBlockExTypeBiPredictedField;
-                       break;
-               }
                default:
                        assert(0);
        }
 
+       /* Unreachable */
+       return -1;
+}
+
+static inline int vlGrabMacroBlock
+(
+       struct vlR16SnormBufferedMC *mc,
+       struct vlMpeg2MacroBlock *macroblock
+)
+{
+       assert(mc);
+       assert(macroblock);
+
+       mc->macroblocks[mc->num_macroblocks].mbx = macroblock->mbx;
+       mc->macroblocks[mc->num_macroblocks].mby = macroblock->mby;
+       mc->macroblocks[mc->num_macroblocks].mb_type = macroblock->mb_type;
+       mc->macroblocks[mc->num_macroblocks].mo_type = macroblock->mo_type;
+       mc->macroblocks[mc->num_macroblocks].dct_type = macroblock->dct_type;
+       mc->macroblocks[mc->num_macroblocks].PMV[0][0][0] = macroblock->PMV[0][0][0];
+       mc->macroblocks[mc->num_macroblocks].PMV[0][0][1] = macroblock->PMV[0][0][1];
+       mc->macroblocks[mc->num_macroblocks].PMV[0][1][0] = macroblock->PMV[0][1][0];
+       mc->macroblocks[mc->num_macroblocks].PMV[0][1][1] = macroblock->PMV[0][1][1];
+       mc->macroblocks[mc->num_macroblocks].PMV[1][0][0] = macroblock->PMV[1][0][0];
+       mc->macroblocks[mc->num_macroblocks].PMV[1][0][1] = macroblock->PMV[1][0][1];
+       mc->macroblocks[mc->num_macroblocks].PMV[1][1][0] = macroblock->PMV[1][1][0];
+       mc->macroblocks[mc->num_macroblocks].PMV[1][1][1] = macroblock->PMV[1][1][1];
+       mc->macroblocks[mc->num_macroblocks].cbp = macroblock->cbp;
+       mc->macroblocks[mc->num_macroblocks].blocks = macroblock->blocks;
+
+       vlGrabBlocks
+       (
+               mc,
+               macroblock->mbx,
+               macroblock->mby,
+               macroblock->dct_type,
+               macroblock->cbp,
+               macroblock->blocks
+       );
+
+       mc->num_macroblocks++;
+
+       return 0;
+}
+
+#define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, zb)                                       \
+       (vb)[0].pos.x = (mbx) * (unitx) + (ofsx);               (vb)[0].pos.y = (mby) * (unity) + (ofsy);                       \
+       (vb)[1].pos.x = (mbx) * (unitx) + (ofsx);               (vb)[1].pos.y = (mby) * (unity) + (ofsy) + (hy);                \
+       (vb)[2].pos.x = (mbx) * (unitx) + (ofsx) + (hx);        (vb)[2].pos.y = (mby) * (unity) + (ofsy);                       \
+       (vb)[3].pos.x = (mbx) * (unitx) + (ofsx) + (hx);        (vb)[3].pos.y = (mby) * (unity) + (ofsy);                       \
+       (vb)[4].pos.x = (mbx) * (unitx) + (ofsx);               (vb)[4].pos.y = (mby) * (unity) + (ofsy) + (hy);                \
+       (vb)[5].pos.x = (mbx) * (unitx) + (ofsx) + (hx);        (vb)[5].pos.y = (mby) * (unity) + (ofsy) + (hy);                \
+                                                                                                                               \
+       if ((cbp) & (lm))                                                                                                       \
+       {                                                                                                                       \
+               (vb)[0].luma_tc.x = (mbx) * (unitx) + (ofsx);           (vb)[0].luma_tc.y = (mby) * (unity) + (ofsy);           \
+               (vb)[1].luma_tc.x = (mbx) * (unitx) + (ofsx);           (vb)[1].luma_tc.y = (mby) * (unity) + (ofsy) + (hy);    \
+               (vb)[2].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx);    (vb)[2].luma_tc.y = (mby) * (unity) + (ofsy);           \
+               (vb)[3].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx);    (vb)[3].luma_tc.y = (mby) * (unity) + (ofsy);           \
+               (vb)[4].luma_tc.x = (mbx) * (unitx) + (ofsx);           (vb)[4].luma_tc.y = (mby) * (unity) + (ofsy) + (hy);    \
+               (vb)[5].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx);    (vb)[5].luma_tc.y = (mby) * (unity) + (ofsy) + (hy);    \
+       }                                                                                                                       \
+       else                                                                                                                    \
+       {                                                                                                                       \
+               (vb)[0].luma_tc.x = (zb)[0].x;          (vb)[0].luma_tc.y = (zb)[0].y;                                          \
+               (vb)[1].luma_tc.x = (zb)[0].x;          (vb)[1].luma_tc.y = (zb)[0].y + (hy);                                   \
+               (vb)[2].luma_tc.x = (zb)[0].x + (hx);   (vb)[2].luma_tc.y = (zb)[0].y;                                          \
+               (vb)[3].luma_tc.x = (zb)[0].x + (hx);   (vb)[3].luma_tc.y = (zb)[0].y;                                          \
+               (vb)[4].luma_tc.x = (zb)[0].x;          (vb)[4].luma_tc.y = (zb)[0].y + (hy);                                   \
+               (vb)[5].luma_tc.x = (zb)[0].x + (hx);   (vb)[5].luma_tc.y = (zb)[0].y + (hy);                                   \
+       }                                                                                                                       \
+                                                                                                                               \
+       if ((cbp) & (cbm))                                                                                                      \
+       {                                                                                                                       \
+               (vb)[0].cb_tc.x = (mbx) * (unitx) + (ofsx);             (vb)[0].cb_tc.y = (mby) * (unity) + (ofsy);             \
+               (vb)[1].cb_tc.x = (mbx) * (unitx) + (ofsx);             (vb)[1].cb_tc.y = (mby) * (unity) + (ofsy) + (hy);      \
+               (vb)[2].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx);      (vb)[2].cb_tc.y = (mby) * (unity) + (ofsy);             \
+               (vb)[3].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx);      (vb)[3].cb_tc.y = (mby) * (unity) + (ofsy);             \
+               (vb)[4].cb_tc.x = (mbx) * (unitx) + (ofsx);             (vb)[4].cb_tc.y = (mby) * (unity) + (ofsy) + (hy);      \
+               (vb)[5].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx);      (vb)[5].cb_tc.y = (mby) * (unity) + (ofsy) + (hy);      \
+       }                                                                                                                       \
+       else                                                                                                                    \
+       {                                                                                                                       \
+               (vb)[0].cb_tc.x = (zb)[1].x;            (vb)[0].cb_tc.y = (zb)[1].y;                                            \
+               (vb)[1].cb_tc.x = (zb)[1].x;            (vb)[1].cb_tc.y = (zb)[1].y + (hy);                                     \
+               (vb)[2].cb_tc.x = (zb)[1].x + (hx);     (vb)[2].cb_tc.y = (zb)[1].y;                                            \
+               (vb)[3].cb_tc.x = (zb)[1].x + (hx);     (vb)[3].cb_tc.y = (zb)[1].y;                                            \
+               (vb)[4].cb_tc.x = (zb)[1].x;            (vb)[4].cb_tc.y = (zb)[1].y + (hy);                                     \
+               (vb)[5].cb_tc.x = (zb)[1].x + (hx);     (vb)[5].cb_tc.y = (zb)[1].y + (hy);                                     \
+       }                                                                                                                       \
+                                                                                                                               \
+       if ((cbp) & (crm))                                                                                                      \
+       {                                                                                                                       \
+               (vb)[0].cr_tc.x = (mbx) * (unitx) + (ofsx);             (vb)[0].cr_tc.y = (mby) * (unity) + (ofsy);             \
+               (vb)[1].cr_tc.x = (mbx) * (unitx) + (ofsx);             (vb)[1].cr_tc.y = (mby) * (unity) + (ofsy) + (hy);      \
+               (vb)[2].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx);      (vb)[2].cr_tc.y = (mby) * (unity) + (ofsy);             \
+               (vb)[3].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx);      (vb)[3].cr_tc.y = (mby) * (unity) + (ofsy);             \
+               (vb)[4].cr_tc.x = (mbx) * (unitx) + (ofsx);             (vb)[4].cr_tc.y = (mby) * (unity) + (ofsy) + (hy);      \
+               (vb)[5].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx);      (vb)[5].cr_tc.y = (mby) * (unity) + (ofsy) + (hy);      \
+       }                                                                                                                       \
+       else                                                                                                                    \
+       {                                                                                                                       \
+               (vb)[0].cr_tc.x = (zb)[2].x;            (vb)[0].cr_tc.y = (zb)[2].y;                                            \
+               (vb)[1].cr_tc.x = (zb)[2].x;            (vb)[1].cr_tc.y = (zb)[2].y + (hy);                                     \
+               (vb)[2].cr_tc.x = (zb)[2].x + (hx);     (vb)[2].cr_tc.y = (zb)[2].y;                                            \
+               (vb)[3].cr_tc.x = (zb)[2].x + (hx);     (vb)[3].cr_tc.y = (zb)[2].y;                                            \
+               (vb)[4].cr_tc.x = (zb)[2].x;            (vb)[4].cr_tc.y = (zb)[2].y + (hy);                                     \
+               (vb)[5].cr_tc.x = (zb)[2].x + (hx);     (vb)[5].cr_tc.y = (zb)[2].y + (hy);                                     \
+       }
+
+static inline int vlGrabMacroBlockVB
+(
+       struct vlR16SnormBufferedMC *mc,
+       struct vlMpeg2MacroBlock *macroblock,
+       unsigned int pos
+)
+{
+       struct vlVertex2f       mo_vec[2];
+       unsigned int            i;
+
+       assert(mc);
+       assert(macroblock);
+
        switch (macroblock->mb_type)
        {
                case vlMacroBlockTypeBiPredicted:
                {
+                       struct vlVertex2f *vb;
+
                        vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
                        (
                                mc->pipe->winsys,
-                               mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][2].buffer,
+                               mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer,
                                PIPE_BUFFER_USAGE_CPU_WRITE
-                       ) + mc->num_macroblocks[mb_type_ex] * 2 * 24;
+                       ) + pos * 2 * 24;
 
                        mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x;
                        mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y;
@@ -331,19 +432,21 @@ static inline int vlGrabMacroBlock
                                }
                        }
 
-                       mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][2].buffer);
+                       mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer);
 
                        /* fall-through */
                }
                case vlMacroBlockTypeFwdPredicted:
                case vlMacroBlockTypeBkwdPredicted:
                {
+                       struct vlVertex2f *vb;
+
                        vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
                        (
                                mc->pipe->winsys,
-                               mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][1].buffer,
+                               mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer,
                                PIPE_BUFFER_USAGE_CPU_WRITE
-                       ) + mc->num_macroblocks[mb_type_ex] * 2 * 24;
+                       ) + pos * 2 * 24;
 
                        if (macroblock->mb_type == vlMacroBlockTypeBkwdPredicted)
                        {
@@ -387,52 +490,71 @@ static inline int vlGrabMacroBlock
                                }
                        }
 
-                       mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][1].buffer);
+                       mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer);
 
                        /* fall-through */
                }
                case vlMacroBlockTypeIntra:
                {
-                       vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
+                       const struct vlVertex2f unit =
+                       {
+                               mc->surface_tex_inv_size.x * VL_MACROBLOCK_WIDTH,
+                               mc->surface_tex_inv_size.y * VL_MACROBLOCK_HEIGHT
+                       };
+                       const struct vlVertex2f half =
+                       {
+                               mc->surface_tex_inv_size.x * (VL_MACROBLOCK_WIDTH / 2),
+                               mc->surface_tex_inv_size.y * (VL_MACROBLOCK_HEIGHT / 2)
+                       };
+
+                       struct vlMacroBlockVertexStream0
+                       {
+                               struct vlVertex2f pos;
+                               struct vlVertex2f luma_tc;
+                               struct vlVertex2f cb_tc;
+                               struct vlVertex2f cr_tc;
+                       } *vb;
+
+                       vb = (struct vlMacroBlockVertexStream0*)mc->pipe->winsys->buffer_map
                        (
                                mc->pipe->winsys,
-                               mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][0].buffer,
+                               mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer,
                                PIPE_BUFFER_USAGE_CPU_WRITE
-                       ) + mc->num_macroblocks[mb_type_ex] * 24;
-
-                       vb[0].x = macroblock->mbx * unit.x;             vb[0].y = macroblock->mby * unit.y;
-                       vb[1].x = macroblock->mbx * unit.x;             vb[1].y = macroblock->mby * unit.y + half.y;
-                       vb[2].x = macroblock->mbx * unit.x + half.x;    vb[2].y = macroblock->mby * unit.y;
-
-                       vb[3].x = macroblock->mbx * unit.x + half.x;    vb[3].y = macroblock->mby * unit.y;
-                       vb[4].x = macroblock->mbx * unit.x;             vb[4].y = macroblock->mby * unit.y + half.y;
-                       vb[5].x = macroblock->mbx * unit.x + half.x;    vb[5].y = macroblock->mby * unit.y + half.y;
-
-                       vb[6].x = macroblock->mbx * unit.x + half.x;    vb[6].y = macroblock->mby * unit.y;
-                       vb[7].x = macroblock->mbx * unit.x + half.x;    vb[7].y = macroblock->mby * unit.y + half.y;
-                       vb[8].x = macroblock->mbx * unit.x + unit.x;    vb[8].y = macroblock->mby * unit.y;
-
-                       vb[9].x = macroblock->mbx * unit.x + unit.x;    vb[9].y = macroblock->mby * unit.y;
-                       vb[10].x = macroblock->mbx * unit.x + half.x;   vb[10].y = macroblock->mby * unit.y + half.y;
-                       vb[11].x = macroblock->mbx * unit.x + unit.x;   vb[11].y = macroblock->mby * unit.y + half.y;
+                       ) + pos * 24;
 
-                       vb[12].x = macroblock->mbx * unit.x;            vb[12].y = macroblock->mby * unit.y + half.y;
-                       vb[13].x = macroblock->mbx * unit.x;            vb[13].y = macroblock->mby * unit.y + unit.y;
-                       vb[14].x = macroblock->mbx * unit.x + half.x;   vb[14].y = macroblock->mby * unit.y + half.y;
+                       SET_BLOCK
+                       (
+                               vb,
+                               macroblock->cbp, macroblock->mbx, macroblock->mby,
+                               unit.x, unit.y, 0, 0, half.x, half.y,
+                               32, 2, 1, mc->zero_block
+                       );
 
-                       vb[15].x = macroblock->mbx * unit.x + half.x;   vb[15].y = macroblock->mby * unit.y + half.y;
-                       vb[16].x = macroblock->mbx * unit.x;            vb[16].y = macroblock->mby * unit.y + unit.y;
-                       vb[17].x = macroblock->mbx * unit.x + half.x;   vb[17].y = macroblock->mby * unit.y + unit.y;
+                       SET_BLOCK
+                       (
+                               vb + 6,
+                               macroblock->cbp, macroblock->mbx, macroblock->mby,
+                               unit.x, unit.y, half.x, 0, half.x, half.y,
+                               16, 2, 1, mc->zero_block
+                       );
 
-                       vb[18].x = macroblock->mbx * unit.x + half.x;   vb[18].y = macroblock->mby * unit.y + half.y;
-                       vb[19].x = macroblock->mbx * unit.x + half.x;   vb[19].y = macroblock->mby * unit.y + unit.y;
-                       vb[20].x = macroblock->mbx * unit.x + unit.x;   vb[20].y = macroblock->mby * unit.y + half.y;
+                       SET_BLOCK
+                       (
+                               vb + 12,
+                               macroblock->cbp, macroblock->mbx, macroblock->mby,
+                               unit.x, unit.y, 0, half.y, half.x, half.y,
+                               8, 2, 1, mc->zero_block
+                       );
 
-                       vb[21].x = macroblock->mbx * unit.x + unit.x;   vb[21].y = macroblock->mby * unit.y + half.y;
-                       vb[22].x = macroblock->mbx * unit.x + half.x;   vb[22].y = macroblock->mby * unit.y + unit.y;
-                       vb[23].x = macroblock->mbx * unit.x + unit.x;   vb[23].y = macroblock->mby * unit.y + unit.y;
+                       SET_BLOCK
+                       (
+                               vb + 18,
+                               macroblock->cbp, macroblock->mbx, macroblock->mby,
+                               unit.x, unit.y, half.x, half.y, half.x, half.y,
+                               4, 2, 1, mc->zero_block
+                       );
 
-                       mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][mb_type_ex][0].buffer);
+                       mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer);
 
                        break;
                }
@@ -440,19 +562,6 @@ static inline int vlGrabMacroBlock
                        assert(0);
        }
 
-       vlGrabBlocks
-       (
-               mc,
-               macroblock->mbx,
-               macroblock->mby,
-               macroblock->dct_type,
-               macroblock->cbp,
-               macroblock->blocks
-       );
-
-       mc->num_macroblocks[mb_type_ex]++;
-       mc->total_num_macroblocks++;
-
        return 0;
 }
 
@@ -464,12 +573,51 @@ static int vlFlush
        struct vlR16SnormBufferedMC     *mc;
        struct pipe_context             *pipe;
        struct vlVertexShaderConsts     *vs_consts;
+       unsigned int                    num_macroblocks[vlNumMacroBlockExTypes] = {0};
+       unsigned int                    offset[vlNumMacroBlockExTypes];
+       unsigned int                    vb_start = 0;
+       unsigned int                    mbw;
+       unsigned int                    mbh;
+       unsigned int                    num_mb_per_frame;
+       unsigned int                    i;
 
-       assert(mc);
+       assert(render);
 
        mc = (struct vlR16SnormBufferedMC*)render;
+
+       if (!mc->buffered_surface)
+               return 0;
+
+       mbw = align(mc->picture_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH;
+       mbh = align(mc->picture_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT;
+       num_mb_per_frame = mbw * mbh;
+
+       if (mc->num_macroblocks < num_mb_per_frame)
+               return 0;
+
        pipe = mc->pipe;
 
+       for (i = 0; i < mc->num_macroblocks; ++i)
+       {
+               enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]);
+
+               num_macroblocks[mb_type_ex]++;
+       }
+
+       offset[0] = 0;
+
+       for (i = 1; i < vlNumMacroBlockExTypes; ++i)
+               offset[i] = offset[i - 1] + num_macroblocks[i - 1];
+
+       for (i = 0; i < mc->num_macroblocks; ++i)
+       {
+               enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]);
+
+               vlGrabMacroBlockVB(mc, &mc->macroblocks[i], offset[mb_type_ex]);
+
+               offset[mb_type_ex]++;
+       }
+
        mc->render_target.cbufs[0] = pipe->screen->get_tex_surface
        (
                pipe->screen,
@@ -490,76 +638,82 @@ static int vlFlush
        vs_consts->denorm.y = mc->buffered_surface->texture->height[0];
 
        pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer);
+       pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &mc->vs_const_buf);
        pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &mc->fs_const_buf);
 
-       if (mc->num_macroblocks[vlMacroBlockExTypeIntra] > 0)
+       if (num_macroblocks[vlMacroBlockExTypeIntra] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeIntra]);
-               pipe->set_vertex_elements(pipe, 1, mc->vertex_elems);
+               pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_elements(pipe, 4, mc->vertex_elems);
                pipe->set_sampler_textures(pipe, 3, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
                pipe->bind_sampler_states(pipe, 3, (void**)mc->samplers);
                pipe->bind_vs_state(pipe, mc->i_vs);
                pipe->bind_fs_state(pipe, mc->i_fs);
 
-               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeIntra] * 24);
+               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeIntra] * 24);
+               vb_start += num_macroblocks[vlMacroBlockExTypeIntra] * 24;
        }
 
-       if (mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0)
+       if (num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeFwdPredictedFrame]);
-               pipe->set_vertex_elements(pipe, 3, mc->vertex_elems);
+               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
                mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
                pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
                pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
                pipe->bind_vs_state(pipe, mc->p_vs[0]);
                pipe->bind_fs_state(pipe, mc->p_fs[0]);
 
-               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24);
+               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24);
+               vb_start += num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24;
        }
 
-       if (mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0)
+       if (num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeFwdPredictedField]);
-               pipe->set_vertex_elements(pipe, 3, mc->vertex_elems);
+               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
                mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
                pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
                pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
                pipe->bind_vs_state(pipe, mc->p_vs[1]);
                pipe->bind_fs_state(pipe, mc->p_fs[1]);
 
-               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24);
+               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24);
+               vb_start += num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24;
        }
 
-       if (mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0)
+       if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBkwdPredictedFrame]);
-               pipe->set_vertex_elements(pipe, 3, mc->vertex_elems);
+               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
                mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture;
                pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
                pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
                pipe->bind_vs_state(pipe, mc->p_vs[0]);
                pipe->bind_fs_state(pipe, mc->p_fs[0]);
 
-               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24);
+               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24);
+               vb_start += num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24;
        }
 
-       if (mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0)
+       if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBkwdPredictedField]);
-               pipe->set_vertex_elements(pipe, 3, mc->vertex_elems);
+               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
                mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture;
                pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
                pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
                pipe->bind_vs_state(pipe, mc->p_vs[1]);
                pipe->bind_fs_state(pipe, mc->p_fs[1]);
 
-               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24);
+               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24);
+               vb_start += num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24;
        }
 
-       if (mc->num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0)
+       if (num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBiPredictedFrame]);
-               pipe->set_vertex_elements(pipe, 5, mc->vertex_elems);
+               pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_elements(pipe, 8, mc->vertex_elems);
                mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
                mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture;
                pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
@@ -567,13 +721,14 @@ static int vlFlush
                pipe->bind_vs_state(pipe, mc->b_vs[0]);
                pipe->bind_fs_state(pipe, mc->b_fs[0]);
 
-               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24);
+               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24);
+               vb_start += num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24;
        }
 
-       if (mc->num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0)
+       if (num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][vlMacroBlockExTypeBiPredictedField]);
-               pipe->set_vertex_elements(pipe, 5, mc->vertex_elems);
+               pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_elements(pipe, 8, mc->vertex_elems);
                mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
                mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture;
                pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
@@ -581,11 +736,17 @@ static int vlFlush
                pipe->bind_vs_state(pipe, mc->b_vs[1]);
                pipe->bind_fs_state(pipe, mc->b_fs[1]);
 
-               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, mc->num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24);
+               pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24);
+               vb_start += num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24;
        }
 
-       memset(mc->num_macroblocks, 0, sizeof(unsigned int) * 7);
-       mc->total_num_macroblocks = 0;
+       pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &mc->buffered_surface->render_fence);
+
+       for (i = 0; i < 3; ++i)
+               mc->zero_block[i].x = -1.0f;
+
+       mc->buffered_surface = NULL;
+       mc->num_macroblocks = 0;
        mc->cur_buf++;
 
        return 0;
@@ -607,12 +768,7 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
 
        if (mc->buffered_surface)
        {
-               if
-               (
-                       mc->buffered_surface != surface /*||
-                       mc->past_surface != batch->past_surface ||
-                       mc->future_surface != batch->future_surface*/
-               )
+               if (mc->buffered_surface != surface)
                {
                        vlFlush(&mc->base);
                        mc->buffered_surface = surface;
@@ -654,7 +810,7 @@ static int vlDestroy
 {
        struct vlR16SnormBufferedMC     *mc;
        struct pipe_context             *pipe;
-       unsigned int                    g, h, i;
+       unsigned int                    h, i;
 
        assert(render);
 
@@ -664,10 +820,9 @@ static int vlDestroy
        for (i = 0; i < 5; ++i)
                pipe->delete_sampler_state(pipe, mc->samplers[i]);
 
-       for (g = 0; g < NUM_BUF_SETS; ++g)
-               for (h = 0; h < 7; ++h)
+       for (h = 0; h < NUM_BUF_SETS; ++h)
                        for (i = 0; i < 3; ++i)
-                               pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[g][h][i].buffer);
+                               pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[h][i].buffer);
 
        /* Textures 3 & 4 are not created directly, no need to release them here */
        for (i = 0; i < NUM_BUF_SETS; ++i)
@@ -691,6 +846,7 @@ static int vlDestroy
        pipe->winsys->buffer_destroy(pipe->winsys, mc->vs_const_buf.buffer);
        pipe->winsys->buffer_destroy(pipe->winsys, mc->fs_const_buf.buffer);
 
+       free(mc->macroblocks);
        free(mc);
 
        return 0;
@@ -742,9 +898,12 @@ static int vlCreateVertexShaderIMB
        ti = 3;
 
        /*
-        * decl i0              ; Vertex pos, luma & chroma texcoords
+        * decl i0              ; Vertex pos
+        * decl i1              ; Luma texcoords
+        * decl i2              ; Chroma Cb texcoords
+        * decl i3              ; Chroma Cr texcoords
         */
-       for (i = 0; i < 3; i++)
+       for (i = 0; i < 4; i++)
        {
                decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
@@ -752,9 +911,11 @@ static int vlCreateVertexShaderIMB
 
        /*
         * decl o0              ; Vertex pos
-        * decl o1              ; Luma/chroma texcoords
+        * decl o1              ; Luma texcoords
+        * decl o2              ; Chroma Cb texcoords
+        * decl o3              ; Chroma Cr texcoords
         */
-       for (i = 0; i < 2; i++)
+       for (i = 0; i < 4; i++)
        {
                decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
@@ -762,11 +923,13 @@ static int vlCreateVertexShaderIMB
 
        /*
         * mov o0, i0           ; Move input vertex pos to output
-        * mov o1, i0           ; Move input luma/chroma texcoords to output
+        * mov o1, i1           ; Move input luma texcoords to output
+        * mov o2, i2           ; Move input chroma Cb texcoords to output
+        * mov o3, i3           ; Move input chroma Cr texcoords to output
         */
-       for (i = 0; i < 2; ++i)
+       for (i = 0; i < 4; ++i)
        {
-               inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0);
+               inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
@@ -814,9 +977,16 @@ static int vlCreateFragmentShaderIMB
 
        ti = 3;
 
-       /* decl i0                      ; Luma/chroma texcoords */
-       decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, 1, 0, 0, TGSI_INTERPOLATE_LINEAR);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
+       /*
+        * decl i0                      ; Luma texcoords
+        * decl i1                      ; Chroma Cb texcoords
+        * decl i2                      ; Chroma Cr texcoords
+        */
+       for (i = 0; i < 3; ++i)
+       {
+               decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR);
+               ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
+       }
 
        /* decl c0                      ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */
        decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0);
@@ -844,14 +1014,14 @@ static int vlCreateFragmentShaderIMB
        /*
         * tex2d t1, i0, s0             ; Read texel from luma texture
         * mov t0.x, t1.x               ; Move luma sample into .x component
-        * tex2d t1, i0, s1             ; Read texel from chroma Cb texture
+        * tex2d t1, i1, s1             ; Read texel from chroma Cb texture
         * mov t0.y, t1.x               ; Move Cb sample into .y component
-        * tex2d t1, i0, s2             ; Read texel from chroma Cr texture
+        * tex2d t1, i2, s2             ; Read texel from chroma Cr texture
         * mov t0.z, t1.x               ; Move Cr sample into .z component
         */
        for (i = 0; i < 3; ++i)
        {
-               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i);
+               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
                inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
@@ -860,7 +1030,6 @@ static int vlCreateFragmentShaderIMB
                inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
                inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
        }
 
        /* mul o0, t0, c0               ; Rescale texel to correct range */
@@ -912,11 +1081,14 @@ static int vlCreateVertexShaderFramePMB
        ti = 3;
 
        /*
-        * decl i0              ; Vertex pos, luma/chroma texcoords
-        * decl i1              ; Ref surface top field texcoords
-        * decl i2              ; Ref surface bottom field texcoords (unused, packed in the same stream)
+        * decl i0              ; Vertex pos
+        * decl i1              ; Luma texcoords
+        * decl i2              ; Chroma Cb texcoords
+        * decl i3              ; Chroma Cr texcoords
+        * decl i4              ; Ref surface top field texcoords
+        * decl i5              ; Ref surface bottom field texcoords (unused, packed in the same stream)
         */
-       for (i = 0; i < 3; i++)
+       for (i = 0; i < 6; i++)
        {
                decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
@@ -924,10 +1096,12 @@ static int vlCreateVertexShaderFramePMB
 
        /*
         * decl o0              ; Vertex pos
-        * decl o1              ; Luma/chroma texcoords
-        * decl o2              ; Ref macroblock texcoords
+        * decl o1              ; Luma texcoords
+        * decl o2              ; Chroma Cb texcoords
+        * decl o3              ; Chroma Cr texcoords
+        * decl o4              ; Ref macroblock texcoords
         */
-       for (i = 0; i < 3; i++)
+       for (i = 0; i < 5; i++)
        {
                decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
@@ -935,16 +1109,18 @@ static int vlCreateVertexShaderFramePMB
 
        /*
         * mov o0, i0           ; Move input vertex pos to output
-        * mov o1, i0           ; Move input luma/chroma texcoords to output
+        * mov o1, i1           ; Move input luma texcoords to output
+        * mov o2, i2           ; Move input chroma Cb texcoords to output
+        * mov o3, i3           ; Move input chroma Cr texcoords to output
         */
-       for (i = 0; i < 2; ++i)
+       for (i = 0; i < 4; ++i)
        {
-               inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0);
+               inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
-       /* add o2, i0, i1       ; Translate vertex pos by motion vec to form ref macroblock texcoords */
-       inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, 1);
+       /* add o4, i0, i4       ; Translate vertex pos by motion vec to form ref macroblock texcoords */
+       inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, 4);
        ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
        /* end */
@@ -992,55 +1168,62 @@ static int vlCreateVertexShaderFieldPMB
        ti = 3;
 
        /*
-        * decl i0              ; Vertex pos, luma/chroma texcoords
-        * decl i1              ; Ref surface top field texcoords
-        * decl i2              ; Ref surface bottom field texcoords
+        * decl i0              ; Vertex pos
+        * decl i1              ; Luma texcoords
+        * decl i2              ; Chroma Cb texcoords
+        * decl i3              ; Chroma Cr texcoords
+        * decl i4              ; Ref macroblock top field texcoords
+        * decl i5              ; Ref macroblock bottom field texcoords
         */
-       for (i = 0; i < 3; i++)
+       for (i = 0; i < 6; i++)
        {
                decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
        }
 
-       /* decl c0              ; Texcoord denorm coefficients */
+       /* decl c0              ; Render target dimensions */
        decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0);
        ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
 
        /*
         * decl o0              ; Vertex pos
-        * decl o1              ; Luma/chroma texcoords
-        * decl o2              ; Top field ref macroblock texcoords
-        * decl o3              ; Bottom field ref macroblock texcoords
-        * decl o4              ; Denormalized vertex pos
+        * decl o1              ; Luma texcoords
+        * decl o2              ; Chroma Cb texcoords
+        * decl o3              ; Chroma Cr texcoords
+        * decl o4              ; Ref macroblock top field texcoords
+        * decl o5              ; Ref macroblock bottom field texcoords
+        * decl o6              ; Denormalized vertex pos
         */
-       for (i = 0; i < 5; i++)
+       for (i = 0; i < 7; i++)
        {
-               decl = vl_decl_output((i == 0 || i == 5) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
+               decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
        }
 
        /*
         * mov o0, i0           ; Move input vertex pos to output
-        * mov o1, i0           ; Move input luma/chroma texcoords to output
+        * mov o1, i1           ; Move input luma texcoords to output
+        * mov o2, i2           ; Move input chroma Cb texcoords to output
+        * mov o3, i3           ; Move input chroma Cr texcoords to output
         */
-       for (i = 0; i < 3; ++i)
+       for (i = 0; i < 4; ++i)
        {
-               inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i == 0 ? 0 : i - 1);
+               inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
        /*
-        * add o2, i0, i1       ; Translate vertex pos by motion vec to form top field macroblock texcoords
-        * add o3, i0, i2       ; Translate vertex pos by motion vec to form bottom field macroblock texcoords
+        * add o4, i0, i4       ; Translate vertex pos by motion vec to form top field macroblock texcoords
+        * add o5, i0, i5       ; Translate vertex pos by motion vec to form bottom field macroblock texcoords
         */
        for (i = 0; i < 2; ++i)
        {
-               inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 1);
+               inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 4);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
-       /* mul o4, i0, c0       ; Denorm vertex pos */
-       inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 5, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0);
+       /* mul o6, i0, c0       ; Denorm vertex pos */
+       inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 6, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0);
        ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
        /* end */
@@ -1088,10 +1271,12 @@ static int vlCreateFragmentShaderFramePMB
        ti = 3;
 
        /*
-        * decl i0                      ; Texcoords for s0, s1, s2
-        * decl i1                      ; Texcoords for s3
+        * decl i0                      ; Luma texcoords
+        * decl i1                      ; Chroma Cb texcoords
+        * decl i2                      ; Chroma Cr texcoords
+        * decl i3                      ; Ref macroblock texcoords
         */
-       for (i = 0; i < 2; ++i)
+       for (i = 0; i < 4; ++i)
        {
                decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
@@ -1124,14 +1309,14 @@ static int vlCreateFragmentShaderFramePMB
        /*
         * tex2d t1, i0, s0             ; Read texel from luma texture
         * mov t0.x, t1.x               ; Move luma sample into .x component
-        * tex2d t1, i0, s1             ; Read texel from chroma Cb texture
+        * tex2d t1, i1, s1             ; Read texel from chroma Cb texture
         * mov t0.y, t1.x               ; Move Cb sample into .y component
-        * tex2d t1, i0, s2             ; Read texel from chroma Cr texture
+        * tex2d t1, i2, s2             ; Read texel from chroma Cr texture
         * mov t0.z, t1.x               ; Move Cr sample into .z component
         */
        for (i = 0; i < 3; ++i)
        {
-               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i);
+               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
                inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
@@ -1140,15 +1325,14 @@ static int vlCreateFragmentShaderFramePMB
                inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
                inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
        }
 
        /* mul t0, t0, c0               ; Rescale texel to correct range */
        inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0);
        ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
-       /* tex2d t1, i1, s3             ; Read texel from ref macroblock */
-       inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 1, TGSI_FILE_SAMPLER, 3);
+       /* tex2d t1, i3, s3             ; Read texel from ref macroblock */
+       inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 3, TGSI_FILE_SAMPLER, 3);
        ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
        /* add o0, t0, t1               ; Add ref and differential to form final output */
@@ -1200,12 +1384,14 @@ static int vlCreateFragmentShaderFieldPMB
        ti = 3;
 
        /*
-        * decl i0                      ; Texcoords for s0, s1, s2
-        * decl i1                      ; Texcoords for s3
-        * decl i2                      ; Texcoords for s3
-        * decl i3                      ; Denormalized vertex pos
+        * decl i0                      ; Luma texcoords
+        * decl i1                      ; Chroma Cb texcoords
+        * decl i2                      ; Chroma Cr texcoords
+        * decl i3                      ; Ref macroblock top field texcoords
+        * decl i4                      ; Ref macroblock bottom field texcoords
+        * decl i5                      ; Denormalized vertex pos
         */
-       for (i = 0; i < 4; ++i)
+       for (i = 0; i < 6; ++i)
        {
                decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
@@ -1241,14 +1427,14 @@ static int vlCreateFragmentShaderFieldPMB
        /*
         * tex2d t1, i0, s0             ; Read texel from luma texture
         * mov t0.x, t1.x               ; Move luma sample into .x component
-        * tex2d t1, i0, s1             ; Read texel from chroma Cb texture
+        * tex2d t1, i1, s1             ; Read texel from chroma Cb texture
         * mov t0.y, t1.x               ; Move Cb sample into .y component
-        * tex2d t1, i0, s2             ; Read texel from chroma Cr texture
+        * tex2d t1, i2, s2             ; Read texel from chroma Cr texture
         * mov t0.z, t1.x               ; Move Cr sample into .z component
         */
        for (i = 0; i < 3; ++i)
        {
-               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i);
+               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
                inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
@@ -1257,7 +1443,6 @@ static int vlCreateFragmentShaderFieldPMB
                inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
                inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
        }
 
        /* mul t0, t0, c0               ; Rescale texel to correct range */
@@ -1265,18 +1450,18 @@ static int vlCreateFragmentShaderFieldPMB
        ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
        /*
-        * tex2d t1, i1, s3             ; Read texel from ref macroblock top field
-        * tex2d t2, i2, s3             ; Read texel from ref macroblock bottom field
+        * tex2d t1, i3, s3             ; Read texel from ref macroblock top field
+        * tex2d t2, i4, s3             ; Read texel from ref macroblock bottom field
         */
        for (i = 0; i < 2; ++i)
        {
-               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 1, TGSI_FILE_SAMPLER, 3);
+               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, 3);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
        /* XXX: Pos values off by 0.5? */
-       /* sub t4, i3.y, c1.x           ; Sub 0.5 from denormalized pos */
-       inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 3, TGSI_FILE_CONSTANT, 1);
+       /* sub t4, i5.y, c1.x           ; Sub 0.5 from denormalized pos */
+       inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 5, TGSI_FILE_CONSTANT, 1);
        inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
        inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
        inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
@@ -1365,13 +1550,16 @@ static int vlCreateVertexShaderFrameBMB
        ti = 3;
 
        /*
-        * decl i0              ; Vertex pos, luma/chroma texcoords
-        * decl i1              ; First ref surface top field texcoords
-        * decl i2              ; First ref surface bottom field texcoords (unused, packed in the same stream)
-        * decl i3              ; Second ref surface top field texcoords
-        * decl i4              ; Second ref surface bottom field texcoords (unused, packed in the same stream)
+        * decl i0              ; Vertex pos
+        * decl i1              ; Luma texcoords
+        * decl i2              ; Chroma Cb texcoords
+        * decl i3              ; Chroma Cr texcoords
+        * decl i4              ; First ref macroblock top field texcoords
+        * decl i5              ; First ref macroblock bottom field texcoords (unused, packed in the same stream)
+        * decl i6              ; Second ref macroblock top field texcoords
+        * decl i7              ; Second ref macroblock bottom field texcoords (unused, packed in the same stream)
         */
-       for (i = 0; i < 5; i++)
+       for (i = 0; i < 8; i++)
        {
                decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
@@ -1379,11 +1567,13 @@ static int vlCreateVertexShaderFrameBMB
 
        /*
         * decl o0              ; Vertex pos
-        * decl o1              ; Luma/chroma texcoords
-        * decl o2              ; First ref macroblock texcoords
-        * decl o3              ; Second ref macroblock texcoords
+        * decl o1              ; Luma texcoords
+        * decl o2              ; Chroma Cb texcoords
+        * decl o3              ; Chroma Cr texcoords
+        * decl o4              ; First ref macroblock texcoords
+        * decl o5              ; Second ref macroblock texcoords
         */
-       for (i = 0; i < 4; i++)
+       for (i = 0; i < 6; i++)
        {
                decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
@@ -1391,21 +1581,23 @@ static int vlCreateVertexShaderFrameBMB
 
        /*
         * mov o0, i0           ; Move input vertex pos to output
-        * mov o1, i0           ; Move input luma/chroma texcoords to output
+        * mov o1, i1           ; Move input luma texcoords to output
+        * mov o2, i2           ; Move input chroma Cb texcoords to output
+        * mov o3, i3           ; Move input chroma Cr texcoords to output
         */
-       for (i = 0; i < 2; ++i)
+       for (i = 0; i < 4; ++i)
        {
-               inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0);
+               inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
        /*
-        * add o2, i0, i1       ; Translate vertex pos by motion vec to form first ref macroblock texcoords
-        * add o3, i0, i3       ; Translate vertex pos by motion vec to form second ref macroblock texcoords
+        * add o4, i0, i4       ; Translate vertex pos by motion vec to form first ref macroblock texcoords
+        * add o5, i0, i6       ; Translate vertex pos by motion vec to form second ref macroblock texcoords
         */
        for (i = 0; i < 2; ++i)
        {
-               inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i * 2 + 1);
+               inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, (i + 2) * 2);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
@@ -1454,34 +1646,39 @@ static int vlCreateVertexShaderFieldBMB
        ti = 3;
 
        /*
-        * decl i0              ; Vertex pos, Luma/chroma texcoords
-        * decl i1              ; First ref surface top field texcoords
-        * decl i2              ; First ref surface bottom field texcoords
-        * decl i3              ; Second ref surface top field texcoords
-        * decl i4              ; Second ref surface bottom field texcoords
+        * decl i0              ; Vertex pos
+        * decl i1              ; Luma texcoords
+        * decl i2              ; Chroma Cb texcoords
+        * decl i3              ; Chroma Cr texcoords
+        * decl i4              ; First ref macroblock top field texcoords
+        * decl i5              ; First ref macroblock bottom field texcoords
+        * decl i6              ; Second ref macroblock top field texcoords
+        * decl i7              ; Second ref macroblock bottom field texcoords
         */
-       for (i = 0; i < 5; i++)
+       for (i = 0; i < 8; i++)
        {
                decl = vl_decl_input(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
        }
 
-       /* decl c0              ; Denorm coefficients */
-       decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 6);
+       /* decl c0              ; Render target dimensions */
+       decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0);
        ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
 
        /*
         * decl o0              ; Vertex pos
-        * decl o1              ; Luma/chroma texcoords
-        * decl o2              ; Top field past ref macroblock texcoords
-        * decl o3              ; Bottom field past ref macroblock texcoords
-        * decl o4              ; Top field future ref macroblock texcoords
-        * decl o5              ; Bottom field future ref macroblock texcoords
-        * decl o6              ; Denormalized vertex pos
+        * decl o1              ; Luma texcoords
+        * decl o2              ; Chroma Cb texcoords
+        * decl o3              ; Chroma Cr texcoords
+        * decl o4              ; First ref macroblock top field texcoords
+        * decl o5              ; First ref macroblock Bottom field texcoords
+        * decl o6              ; Second ref macroblock top field texcoords
+        * decl o7              ; Second ref macroblock Bottom field texcoords
+        * decl o8              ; Denormalized vertex pos
         */
-       for (i = 0; i < 7; i++)
+       for (i = 0; i < 9; i++)
        {
-               decl = vl_decl_output((i == 0 || i == 7) ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
+               decl = vl_decl_output(i == 0 ? TGSI_SEMANTIC_POSITION : TGSI_SEMANTIC_GENERIC, i, i, i);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
        }
 
@@ -1491,32 +1688,30 @@ static int vlCreateVertexShaderFieldBMB
 
        /*
         * mov o0, i0           ; Move input vertex pos to output
-        * mov o1, i0           ; Move input luma/chroma texcoords to output
-        * mov o2, i1           ; Move past top field texcoords to output
-        * mov o3, i2           ; Move past bottom field texcoords to output
-        * mov o4, i3           ; Move future top field texcoords to output
-        * mov o5, i4           ; Move future bottom field texcoords to output
+        * mov o1, i1           ; Move input luma texcoords to output
+        * mov o2, i2           ; Move input chroma Cb texcoords to output
+        * mov o3, i3           ; Move input chroma Cr texcoords to output
         */
-       for (i = 0; i < 6; ++i)
+       for (i = 0; i < 4; ++i)
        {
-               inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, 0);
+               inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
        /*
-        * add o2, i0, i1       ; Translate vertex pos by motion vec to form first top field macroblock texcoords
-        * add o3, i0, i2       ; Translate vertex pos by motion vec to form first bottom field macroblock texcoords
-        * add o4, i0, i3       ; Translate vertex pos by motion vec to form second top field macroblock texcoords
-        * add o5, i0, i4       ; Translate vertex pos by motion vec to form second bottom field macroblock texcoords
+        * add o4, i0, i4       ; Translate vertex pos by motion vec to form first top field macroblock texcoords
+        * add o5, i0, i5       ; Translate vertex pos by motion vec to form first bottom field macroblock texcoords
+        * add o6, i0, i6       ; Translate vertex pos by motion vec to form second top field macroblock texcoords
+        * add o7, i0, i7       ; Translate vertex pos by motion vec to form second bottom field macroblock texcoords
         */
        for (i = 0; i < 4; ++i)
        {
-               inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 2, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 1);
+               inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, i + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 4);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
-       /* mul o6, i0, c0       ; Denorm vertex pos */
-       inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 6, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0);
+       /* mul o8, i0, c0       ; Denorm vertex pos */
+       inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 8, TGSI_FILE_INPUT, 0, TGSI_FILE_CONSTANT, 0);
        ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
        /* end */
@@ -1564,11 +1759,13 @@ static int vlCreateFragmentShaderFrameBMB
        ti = 3;
 
        /*
-        * decl i0                      ; Texcoords for s0, s1, s2
-        * decl i1                      ; Texcoords for s3
-        * decl i2                      ; Texcoords for s4
+        * decl i0                      ; Luma texcoords
+        * decl i1                      ; Chroma Cb texcoords
+        * decl i2                      ; Chroma Cr texcoords
+        * decl i3                      ; First ref macroblock texcoords
+        * decl i4                      ; Second ref macroblock texcoords
         */
-       for (i = 0; i < 3; ++i)
+       for (i = 0; i < 5; ++i)
        {
                decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
@@ -1593,8 +1790,8 @@ static int vlCreateFragmentShaderFrameBMB
         * decl s0                      ; Sampler for luma texture
         * decl s1                      ; Sampler for chroma Cb texture
         * decl s2                      ; Sampler for chroma Cr texture
-        * decl s3                      ; Sampler for past ref surface texture
-        * decl s4                      ; Sampler for future ref surface texture
+        * decl s3                      ; Sampler for first ref surface texture
+        * decl s4                      ; Sampler for second ref surface texture
         */
        for (i = 0; i < 5; ++i)
        {
@@ -1605,14 +1802,14 @@ static int vlCreateFragmentShaderFrameBMB
        /*
         * tex2d t1, i0, s0             ; Read texel from luma texture
         * mov t0.x, t1.x               ; Move luma sample into .x component
-        * tex2d t1, i0, s1             ; Read texel from chroma Cb texture
+        * tex2d t1, i1, s1             ; Read texel from chroma Cb texture
         * mov t0.y, t1.x               ; Move Cb sample into .y component
-        * tex2d t1, i0, s2             ; Read texel from chroma Cr texture
+        * tex2d t1, i2, s2             ; Read texel from chroma Cr texture
         * mov t0.z, t1.x               ; Move Cr sample into .z component
         */
        for (i = 0; i < 3; ++i)
        {
-               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i);
+               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
                inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
@@ -1621,7 +1818,6 @@ static int vlCreateFragmentShaderFrameBMB
                inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
                inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
        }
 
        /* mul t0, t0, c0               ; Rescale texel to correct range */
@@ -1629,12 +1825,12 @@ static int vlCreateFragmentShaderFrameBMB
        ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
        /*
-        * tex2d t1, i1, s3             ; Read texel from past ref macroblock
-        * tex2d t2, i2, s4             ; Read texel from future ref macroblock
+        * tex2d t1, i3, s3             ; Read texel from first ref macroblock
+        * tex2d t2, i4, s4             ; Read texel from second ref macroblock
         */
        for (i = 0; i < 2; ++i)
        {
-               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 1, TGSI_FILE_SAMPLER, i + 3);
+               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, i + 3);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
@@ -1695,14 +1891,16 @@ static int vlCreateFragmentShaderFieldBMB
        ti = 3;
 
        /*
-        * decl i0                      ; Texcoords for s0, s1, s2
-        * decl i1                      ; Texcoords for s3
-        * decl i2                      ; Texcoords for s3
-        * decl i3                      ; Texcoords for s4
-        * decl i4                      ; Texcoords for s4
-        * decl i5                      ; Denormalized vertex pos
+        * decl i0                      ; Luma texcoords
+        * decl i1                      ; Chroma Cb texcoords
+        * decl i2                      ; Chroma Cr texcoords
+        * decl i3                      ; First ref macroblock top field texcoords
+        * decl i4                      ; First ref macroblock bottom field texcoords
+        * decl i5                      ; Second ref macroblock top field texcoords
+        * decl i6                      ; Second ref macroblock bottom field texcoords
+        * decl i7                      ; Denormalized vertex pos
         */
-       for (i = 0; i < 6; ++i)
+       for (i = 0; i < 8; ++i)
        {
                decl = vl_decl_interpolated_input(TGSI_SEMANTIC_GENERIC, i + 1, i, i, TGSI_INTERPOLATE_LINEAR);
                ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
@@ -1728,8 +1926,8 @@ static int vlCreateFragmentShaderFieldBMB
         * decl s0                      ; Sampler for luma texture
         * decl s1                      ; Sampler for chroma Cb texture
         * decl s2                      ; Sampler for chroma Cr texture
-        * decl s3                      ; Sampler for past ref surface texture
-        * decl s4                      ; Sampler for future ref surface texture
+        * decl s3                      ; Sampler for first ref surface texture
+        * decl s4                      ; Sampler for second ref surface texture
         */
        for (i = 0; i < 5; ++i)
        {
@@ -1740,14 +1938,14 @@ static int vlCreateFragmentShaderFieldBMB
        /*
         * tex2d t1, i0, s0             ; Read texel from luma texture
         * mov t0.x, t1.x               ; Move luma sample into .x component
-        * tex2d t1, i0, s1             ; Read texel from chroma Cb texture
+        * tex2d t1, i1, s1             ; Read texel from chroma Cb texture
         * mov t0.y, t1.x               ; Move Cb sample into .y component
-        * tex2d t1, i0, s2             ; Read texel from chroma Cr texture
+        * tex2d t1, i2, s2             ; Read texel from chroma Cr texture
         * mov t0.z, t1.x               ; Move Cr sample into .z component
         */
        for (i = 0; i < 3; ++i)
        {
-               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, 0, TGSI_FILE_SAMPLER, i);
+               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_INPUT, i, TGSI_FILE_SAMPLER, i);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
                inst = vl_inst2(TGSI_OPCODE_MOV, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
@@ -1756,7 +1954,6 @@ static int vlCreateFragmentShaderFieldBMB
                inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
                inst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X << i;
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
        }
 
        /* mul t0, t0, c0               ; Rescale texel to correct range */
@@ -1764,8 +1961,8 @@ static int vlCreateFragmentShaderFieldBMB
        ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
        /* XXX: Pos values off by 0.5? */
-       /* sub t4, i5.y, c1.x           ; Sub 0.5 from denormalized pos */
-       inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 5, TGSI_FILE_CONSTANT, 1);
+       /* sub t4, i7.y, c1.x           ; Sub 0.5 from denormalized pos */
+       inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_INPUT, 7, TGSI_FILE_CONSTANT, 1);
        inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
        inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
        inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
@@ -1801,12 +1998,12 @@ static int vlCreateFragmentShaderFieldBMB
        ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
        /*
-        * tex2d t1, i1, s3             ; Read texel from past ref macroblock top field
-        * tex2d t2, i2, s3             ; Read texel from past ref macroblock bottom field
+        * tex2d t1, i3, s3             ; Read texel from past ref macroblock top field
+        * tex2d t2, i4, s3             ; Read texel from past ref macroblock bottom field
         */
        for (i = 0; i < 2; ++i)
        {
-               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 1, TGSI_FILE_SAMPLER, 3);
+               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 1, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, 3);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
@@ -1816,12 +2013,12 @@ static int vlCreateFragmentShaderFieldBMB
        ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
 
        /*
-        * tex2d t4, i3, s4             ; Read texel from future ref macroblock top field
-        * tex2d t5, i4, s4             ; Read texel from future ref macroblock bottom field
+        * tex2d t4, i5, s4             ; Read texel from future ref macroblock top field
+        * tex2d t5, i6, s4             ; Read texel from future ref macroblock bottom field
         */
        for (i = 0; i < 2; ++i)
        {
-               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 4, TGSI_FILE_INPUT, i + 3, TGSI_FILE_SAMPLER, 4);
+               inst = vl_tex(TGSI_TEXTURE_2D, TGSI_FILE_TEMPORARY, i + 4, TGSI_FILE_INPUT, i + 5, TGSI_FILE_SAMPLER, 4);
                ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
        }
 
@@ -1858,85 +2055,94 @@ static int vlCreateDataBufs
        struct vlR16SnormBufferedMC *mc
 )
 {
-       const unsigned int      mbw = align(mc->video_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH;
-       const unsigned int      mbh = align(mc->video_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT;
+       const unsigned int      mbw = align(mc->picture_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH;
+       const unsigned int      mbh = align(mc->picture_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT;
        const unsigned int      num_mb_per_frame = mbw * mbh;
 
        struct pipe_context     *pipe;
-       unsigned int            g, h, i;
+       unsigned int            h, i;
 
        assert(mc);
 
        pipe = mc->pipe;
 
-       for (g = 0; g < NUM_BUF_SETS; ++g)
+       /* Create our vertex buffers */
+       for (h = 0; h < NUM_BUF_SETS; ++h)
        {
-               for (h = 0; h < 7; ++h)
+               mc->vertex_bufs[h][0].pitch = sizeof(struct vlVertex2f) * 4;
+               mc->vertex_bufs[h][0].max_index = 24 * num_mb_per_frame - 1;
+               mc->vertex_bufs[h][0].buffer_offset = 0;
+               mc->vertex_bufs[h][0].buffer = pipe->winsys->buffer_create
+               (
+                       pipe->winsys,
+                       1,
+                       PIPE_BUFFER_USAGE_VERTEX,
+                       sizeof(struct vlVertex2f) * 4 * 24 * num_mb_per_frame
+               );
+
+               for (i = 1; i < 3; ++i)
                {
-                       /* Create our vertex buffer and vertex buffer element */
-                       mc->vertex_bufs[g][h][0].pitch = sizeof(struct vlVertex2f);
-                       mc->vertex_bufs[g][h][0].max_index = 24 * num_mb_per_frame - 1;
-                       mc->vertex_bufs[g][h][0].buffer_offset = 0;
-                       mc->vertex_bufs[g][h][0].buffer = pipe->winsys->buffer_create
+                       mc->vertex_bufs[h][i].pitch = sizeof(struct vlVertex2f) * 2;
+                       mc->vertex_bufs[h][i].max_index = 24 * num_mb_per_frame - 1;
+                       mc->vertex_bufs[h][i].buffer_offset = 0;
+                       mc->vertex_bufs[h][i].buffer = pipe->winsys->buffer_create
                        (
                                pipe->winsys,
                                1,
                                PIPE_BUFFER_USAGE_VERTEX,
-                               sizeof(struct vlVertex2f) * 24 * num_mb_per_frame
+                               sizeof(struct vlVertex2f) * 2 * 24 * num_mb_per_frame
                        );
                }
        }
 
-       /* Position & block luma, block chroma texcoord element */
+       /* Position element */
        mc->vertex_elems[0].src_offset = 0;
        mc->vertex_elems[0].vertex_buffer_index = 0;
        mc->vertex_elems[0].nr_components = 2;
        mc->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
 
-       for (g = 0; g < NUM_BUF_SETS; ++g)
-       {
-               for (h = 0; h < 7; ++h)
-               {
-                       for (i = 1; i < 3; ++i)
-                       {
-                               mc->vertex_bufs[g][h][i].pitch = sizeof(struct vlVertex2f) * 2;
-                               mc->vertex_bufs[g][h][i].max_index = 24 * num_mb_per_frame - 1;
-                               mc->vertex_bufs[g][h][i].buffer_offset = 0;
-                               mc->vertex_bufs[g][h][i].buffer = pipe->winsys->buffer_create
-                               (
-                                       pipe->winsys,
-                                       1,
-                                       PIPE_BUFFER_USAGE_VERTEX,
-                                       sizeof(struct vlVertex2f) * 2 * 24 * num_mb_per_frame
-                               );
-                       }
-               }
-       }
-
-       /* First ref surface top field texcoord element */
-       mc->vertex_elems[1].src_offset = 0;
-       mc->vertex_elems[1].vertex_buffer_index = 1;
+       /* Luma, texcoord element */
+       mc->vertex_elems[1].src_offset = sizeof(struct vlVertex2f);
+       mc->vertex_elems[1].vertex_buffer_index = 0;
        mc->vertex_elems[1].nr_components = 2;
        mc->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
 
-       /* First ref surface bottom field texcoord element */
-       mc->vertex_elems[2].src_offset = sizeof(struct vlVertex2f);
-       mc->vertex_elems[2].vertex_buffer_index = 1;
+       /* Chroma Cr texcoord element */
+       mc->vertex_elems[2].src_offset = sizeof(struct vlVertex2f) * 2;
+       mc->vertex_elems[2].vertex_buffer_index = 0;
        mc->vertex_elems[2].nr_components = 2;
        mc->vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
 
-       /* Second ref surface top field texcoord element */
-       mc->vertex_elems[3].src_offset = 0;
-       mc->vertex_elems[3].vertex_buffer_index = 2;
+       /* Chroma Cb texcoord element */
+       mc->vertex_elems[3].src_offset = sizeof(struct vlVertex2f) * 3;
+       mc->vertex_elems[3].vertex_buffer_index = 0;
        mc->vertex_elems[3].nr_components = 2;
        mc->vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT;
 
-       /* Second ref surface bottom field texcoord element */
-       mc->vertex_elems[4].src_offset = sizeof(struct vlVertex2f);
-       mc->vertex_elems[4].vertex_buffer_index = 2;
+       /* First ref surface top field texcoord element */
+       mc->vertex_elems[4].src_offset = 0;
+       mc->vertex_elems[4].vertex_buffer_index = 1;
        mc->vertex_elems[4].nr_components = 2;
        mc->vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT;
 
+       /* First ref surface bottom field texcoord element */
+       mc->vertex_elems[5].src_offset = sizeof(struct vlVertex2f);
+       mc->vertex_elems[5].vertex_buffer_index = 1;
+       mc->vertex_elems[5].nr_components = 2;
+       mc->vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+       /* Second ref surface top field texcoord element */
+       mc->vertex_elems[6].src_offset = 0;
+       mc->vertex_elems[6].vertex_buffer_index = 2;
+       mc->vertex_elems[6].nr_components = 2;
+       mc->vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+       /* Second ref surface bottom field texcoord element */
+       mc->vertex_elems[7].src_offset = sizeof(struct vlVertex2f);
+       mc->vertex_elems[7].vertex_buffer_index = 2;
+       mc->vertex_elems[7].nr_components = 2;
+       mc->vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
        /* Create our constant buffer */
        mc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts);
        mc->vs_const_buf.buffer = pipe->winsys->buffer_create
@@ -1965,6 +2171,8 @@ static int vlCreateDataBufs
 
        pipe->winsys->buffer_unmap(pipe->winsys, mc->fs_const_buf.buffer);
 
+       mc->macroblocks = malloc(sizeof(struct vlMpeg2MacroBlock) * num_mb_per_frame);
+
        return 0;
 }
 
@@ -1984,8 +2192,8 @@ static int vlInit
        pipe = mc->pipe;
 
        /* For MC we render to textures, which are rounded up to nearest POT */
-       mc->viewport.scale[0] = vlRoundUpPOT(mc->video_width);
-       mc->viewport.scale[1] = vlRoundUpPOT(mc->video_height);
+       mc->viewport.scale[0] = vlRoundUpPOT(mc->picture_width);
+       mc->viewport.scale[1] = vlRoundUpPOT(mc->picture_height);
        mc->viewport.scale[2] = 1;
        mc->viewport.scale[3] = 1;
        mc->viewport.translate[0] = 0;
@@ -1993,16 +2201,16 @@ static int vlInit
        mc->viewport.translate[2] = 0;
        mc->viewport.translate[3] = 0;
 
-       mc->render_target.width = vlRoundUpPOT(mc->video_width);
-       mc->render_target.height = vlRoundUpPOT(mc->video_height);
+       mc->render_target.width = vlRoundUpPOT(mc->picture_width);
+       mc->render_target.height = vlRoundUpPOT(mc->picture_height);
        mc->render_target.num_cbufs = 1;
        /* FB for MC stage is a vlSurface created by the user, set at render time */
        mc->render_target.zsbuf = NULL;
 
        filters[0] = PIPE_TEX_FILTER_NEAREST;
        /* FIXME: Linear causes discoloration around block edges */
-       filters[1] = /*mc->video_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/;
-       filters[2] = /*mc->video_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/;
+       filters[1] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/;
+       filters[2] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/;
        filters[3] = PIPE_TEX_FILTER_LINEAR;
        filters[4] = PIPE_TEX_FILTER_LINEAR;
 
@@ -2031,8 +2239,8 @@ static int vlInit
        template.target = PIPE_TEXTURE_2D;
        template.format = PIPE_FORMAT_R16_SNORM;
        template.last_level = 0;
-       template.width[0] = vlRoundUpPOT(mc->video_width);
-       template.height[0] = vlRoundUpPOT(mc->video_height);
+       template.width[0] = vlRoundUpPOT(mc->picture_width);
+       template.height[0] = vlRoundUpPOT(mc->picture_height);
        template.depth[0] = 1;
        template.compressed = 0;
        pf_get_block(template.format, &template.block);
@@ -2040,13 +2248,13 @@ static int vlInit
        for (i = 0; i < NUM_BUF_SETS; ++i)
                mc->textures[i][0] = pipe->screen->texture_create(pipe->screen, &template);
 
-       if (mc->video_format == vlFormatYCbCr420)
+       if (mc->picture_format == vlFormatYCbCr420)
        {
-               template.width[0] = vlRoundUpPOT(mc->video_width / 2);
-               template.height[0] = vlRoundUpPOT(mc->video_height / 2);
+               template.width[0] = vlRoundUpPOT(mc->picture_width / 2);
+               template.height[0] = vlRoundUpPOT(mc->picture_height / 2);
        }
-       else if (mc->video_format == vlFormatYCbCr422)
-               template.height[0] = vlRoundUpPOT(mc->video_height / 2);
+       else if (mc->picture_format == vlFormatYCbCr422)
+               template.height[0] = vlRoundUpPOT(mc->picture_height / 2);
 
        for (i = 0; i < NUM_BUF_SETS; ++i)
        {
@@ -2074,13 +2282,14 @@ static int vlInit
 int vlCreateR16SNormBufferedMC
 (
        struct pipe_context *pipe,
-       unsigned int video_width,
-       unsigned int video_height,
-       enum vlFormat video_format,
+       unsigned int picture_width,
+       unsigned int picture_height,
+       enum vlFormat picture_format,
        struct vlRender **render
 )
 {
-       struct vlR16SnormBufferedMC *mc;
+       struct vlR16SnormBufferedMC     *mc;
+       unsigned int                    i;
 
        assert(pipe);
        assert(render);
@@ -2093,15 +2302,16 @@ int vlCreateR16SNormBufferedMC
        mc->base.vlFlush = &vlFlush;
        mc->base.vlDestroy = &vlDestroy;
        mc->pipe = pipe;
-       mc->video_width = video_width;
-       mc->video_height = video_height;
+       mc->picture_width = picture_width;
+       mc->picture_height = picture_height;
 
        mc->cur_buf = 0;
        mc->buffered_surface = NULL;
        mc->past_surface = NULL;
        mc->future_surface = NULL;
-       memset(mc->num_macroblocks, 0, sizeof(unsigned int) * 7);
-       mc->total_num_macroblocks = 0;
+       for (i = 0; i < 3; ++i)
+               mc->zero_block[i].x = -1.0f;
+       mc->num_macroblocks = 0;
 
        vlInit(mc);