python: Fix method renaming.
[mesa.git] / src / gallium / state_trackers / g3dvl / vl_r16snorm_mc_buf.c
index e7a070ef4df28a1c4f395cc6c097360ac0b5e3ce..eb8270ecad3fdf44cd006b4c285755d19658f790 100644 (file)
@@ -1,15 +1,14 @@
 #define VL_INTERNAL
 #include "vl_r16snorm_mc_buf.h"
 #include <assert.h>
-#include <stdlib.h>
 #include <pipe/p_context.h>
-#include <pipe/p_winsys.h>
 #include <pipe/p_screen.h>
 #include <pipe/p_state.h>
 #include <pipe/p_inlines.h>
 #include <tgsi/tgsi_parse.h>
 #include <tgsi/tgsi_build.h>
 #include <util/u_math.h>
+#include <util/u_memory.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 */
+const unsigned int DEFAULT_BUF_ALIGNMENT = 1;
 
 enum vlMacroBlockTypeEx
 {
@@ -52,34 +42,79 @@ struct vlFragmentShaderConsts
        struct vlVertex4f div;
 };
 
+struct vlMacroBlockVertexStream0
+{
+       struct vlVertex2f pos;
+       struct vlVertex2f luma_tc;
+       struct vlVertex2f cb_tc;
+       struct vlVertex2f cr_tc;
+};
+
 struct vlR16SnormBufferedMC
 {
        struct vlRender                         base;
 
-       unsigned int                            picture_width, picture_height;
+       unsigned int                            picture_width;
+       unsigned int                            picture_height;
        enum vlFormat                           picture_format;
+       unsigned int                            macroblocks_per_picture;
 
-       unsigned int                            cur_buf;
        struct vlSurface                        *buffered_surface;
-       struct vlSurface                        *past_surface, *future_surface;
+       struct vlSurface                        *past_surface;
+       struct vlSurface                        *future_surface;
        struct vlVertex2f                       surface_tex_inv_size;
        struct vlVertex2f                       zero_block[3];
        unsigned int                            num_macroblocks;
        struct vlMpeg2MacroBlock                *macroblocks;
+       struct pipe_transfer                    *tex_transfer[3];
+       short                                   *texels[3];
 
        struct pipe_context                     *pipe;
        struct pipe_viewport_state              viewport;
        struct pipe_framebuffer_state           render_target;
-       struct pipe_sampler_state               *samplers[5];
-       struct pipe_texture                     *textures[NUM_BUF_SETS][5];
+
+       union
+       {
+               void                                    *all[5];
+               struct
+               {
+                       void                            *y;
+                       void                            *cb;
+                       void                            *cr;
+                       void                            *ref[2];
+               };
+       } samplers;
+
+       union
+       {
+               struct pipe_texture                     *all[5];
+               struct
+               {
+                       struct pipe_texture             *y;
+                       struct pipe_texture             *cb;
+                       struct pipe_texture             *cr;
+                       struct pipe_texture             *ref[2];
+               };
+       } textures;
+
+       union
+       {
+               struct pipe_vertex_buffer               all[3];
+               struct
+               {
+                       struct pipe_vertex_buffer       ycbcr;
+                       struct pipe_vertex_buffer       ref[2];
+               };
+       } vertex_bufs;
+
        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][3];
        struct pipe_vertex_element              vertex_elems[8];
-       struct pipe_constant_buffer             vs_const_buf, fs_const_buf;
+       struct pipe_constant_buffer             vs_const_buf;
+       struct pipe_constant_buffer             fs_const_buf;
 };
 
-static int vlBegin
+static inline int vlBegin
 (
        struct vlRender *render
 )
@@ -144,7 +179,6 @@ static inline int vlGrabBlocks
        short *blocks
 )
 {
-       struct pipe_surface     *tex_surface;
        short                   *texels;
        unsigned int            tex_pitch;
        unsigned int            x, y, tb = 0, sb = 0;
@@ -153,17 +187,8 @@ static inline int vlGrabBlocks
        assert(mc);
        assert(blocks);
 
-       tex_surface = mc->pipe->screen->get_tex_surface
-       (
-               mc->pipe->screen,
-               mc->textures[mc->cur_buf % NUM_BUF_SETS][0],
-               0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
-       );
-
-       texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE);
-       tex_pitch = tex_surface->stride / tex_surface->block.size;
-
-       texels += mbpy * tex_pitch + mbpx;
+       tex_pitch = mc->tex_transfer[0]->stride / mc->tex_transfer[0]->block.size;
+       texels = mc->texels[0] + mbpy * tex_pitch + mbpx;
 
        for (y = 0; y < 2; ++y)
        {
@@ -204,25 +229,14 @@ static inline int vlGrabBlocks
                }
        }
 
-       pipe_surface_unmap(tex_surface);
-
        /* TODO: Implement 422, 444 */
        mbpx >>= 1;
        mbpy >>= 1;
 
        for (tb = 0; tb < 2; ++tb)
        {
-               tex_surface = mc->pipe->screen->get_tex_surface
-               (
-                       mc->pipe->screen,
-                       mc->textures[mc->cur_buf % NUM_BUF_SETS][tb + 1],
-                       0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
-               );
-
-               texels = pipe_surface_map(tex_surface, PIPE_BUFFER_USAGE_CPU_WRITE);
-               tex_pitch = tex_surface->stride / tex_surface->block.size;
-
-               texels += mbpy * tex_pitch + mbpx;
+               tex_pitch = mc->tex_transfer[tb + 1]->stride / mc->tex_transfer[tb + 1]->block.size;
+               texels = mc->texels[tb + 1] + mbpy * tex_pitch + mbpx;
 
                if ((coded_block_pattern >> (1 - tb)) & 1)
                {
@@ -244,8 +258,6 @@ static inline int vlGrabBlocks
                        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;
@@ -284,6 +296,7 @@ static inline int vlGrabMacroBlock
 {
        assert(mc);
        assert(macroblock);
+       assert(mc->num_macroblocks < mc->macroblocks_per_picture);
 
        mc->macroblocks[mc->num_macroblocks].mbx = macroblock->mbx;
        mc->macroblocks[mc->num_macroblocks].mby = macroblock->mby;
@@ -317,6 +330,7 @@ static inline int vlGrabMacroBlock
 }
 
 #define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, zb)                                       \
+       do {                                                                                                                    \
        (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);                       \
@@ -379,13 +393,16 @@ static inline int vlGrabMacroBlock
                (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);                                     \
-       }
+       }                                                                                                                       \
+       } while (0)
 
-static inline int vlGrabMacroBlockVB
+static inline int vlGenMacroblockVerts
 (
        struct vlR16SnormBufferedMC *mc,
        struct vlMpeg2MacroBlock *macroblock,
-       unsigned int pos
+       unsigned int pos,
+       struct vlMacroBlockVertexStream0 *ycbcr_vb,
+       struct vlVertex2f **ref_vb
 )
 {
        struct vlVertex2f       mo_vec[2];
@@ -393,6 +410,8 @@ static inline int vlGrabMacroBlockVB
 
        assert(mc);
        assert(macroblock);
+       assert(ycbcr_vb);
+       assert(pos < mc->macroblocks_per_picture);
 
        switch (macroblock->mb_type)
        {
@@ -400,12 +419,9 @@ static inline int vlGrabMacroBlockVB
                {
                        struct vlVertex2f *vb;
 
-                       vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
-                       (
-                               mc->pipe->winsys,
-                               mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer,
-                               PIPE_BUFFER_USAGE_CPU_WRITE
-                       ) + pos * 2 * 24;
+                       assert(ref_vb && ref_vb[1]);
+
+                       vb = ref_vb[1] + 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;
@@ -432,8 +448,6 @@ static inline int vlGrabMacroBlockVB
                                }
                        }
 
-                       mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer);
-
                        /* fall-through */
                }
                case vlMacroBlockTypeFwdPredicted:
@@ -441,12 +455,9 @@ static inline int vlGrabMacroBlockVB
                {
                        struct vlVertex2f *vb;
 
-                       vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
-                       (
-                               mc->pipe->winsys,
-                               mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer,
-                               PIPE_BUFFER_USAGE_CPU_WRITE
-                       ) + pos * 2 * 24;
+                       assert(ref_vb && ref_vb[0]);
+
+                       vb = ref_vb[0] + pos * 2 * 24;
 
                        if (macroblock->mb_type == vlMacroBlockTypeBkwdPredicted)
                        {
@@ -490,8 +501,6 @@ static inline int vlGrabMacroBlockVB
                                }
                        }
 
-                       mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer);
-
                        /* fall-through */
                }
                case vlMacroBlockTypeIntra:
@@ -507,20 +516,9 @@ static inline int vlGrabMacroBlockVB
                                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;
+                       struct vlMacroBlockVertexStream0 *vb;
 
-                       vb = (struct vlMacroBlockVertexStream0*)mc->pipe->winsys->buffer_map
-                       (
-                               mc->pipe->winsys,
-                               mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer,
-                               PIPE_BUFFER_USAGE_CPU_WRITE
-                       ) + pos * 24;
+                       vb = ycbcr_vb + pos * 24;
 
                        SET_BLOCK
                        (
@@ -554,8 +552,6 @@ static inline int vlGrabMacroBlockVB
                                4, 2, 1, mc->zero_block
                        );
 
-                       mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer);
-
                        break;
                }
                default:
@@ -576,9 +572,6 @@ static int vlFlush
        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(render);
@@ -588,13 +581,11 @@ static int vlFlush
        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)
+       if (mc->num_macroblocks < mc->macroblocks_per_picture)
                return 0;
 
+       assert(mc->num_macroblocks <= mc->macroblocks_per_picture);
+
        pipe = mc->pipe;
 
        for (i = 0; i < mc->num_macroblocks; ++i)
@@ -609,13 +600,43 @@ static int vlFlush
        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]);
+               struct vlMacroBlockVertexStream0        *ycbcr_vb;
+               struct vlVertex2f                       *ref_vb[2];
+
+               ycbcr_vb = (struct vlMacroBlockVertexStream0*)pipe_buffer_map
+               (
+                       pipe->screen,
+                       mc->vertex_bufs.ycbcr.buffer,
+                       PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
+               );
 
-               vlGrabMacroBlockVB(mc, &mc->macroblocks[i], offset[mb_type_ex]);
+               for (i = 0; i < 2; ++i)
+                       ref_vb[i] = (struct vlVertex2f*)pipe_buffer_map
+                       (
+                               pipe->screen,
+                               mc->vertex_bufs.ref[i].buffer,
+                               PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
+                       );
 
-               offset[mb_type_ex]++;
+               for (i = 0; i < mc->num_macroblocks; ++i)
+               {
+                       enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]);
+
+                       vlGenMacroblockVerts(mc, &mc->macroblocks[i], offset[mb_type_ex], ycbcr_vb, ref_vb);
+
+                       offset[mb_type_ex]++;
+               }
+
+               pipe_buffer_unmap(pipe->screen, mc->vertex_bufs.ycbcr.buffer);
+               for (i = 0; i < 2; ++i)
+                       pipe_buffer_unmap(pipe->screen, mc->vertex_bufs.ref[i].buffer);
+       }
+
+       for (i = 0; i < 3; ++i)
+       {
+               pipe->screen->transfer_unmap(pipe->screen, mc->tex_transfer[i]);
+               pipe->screen->tex_transfer_destroy(mc->tex_transfer[i]);
        }
 
        mc->render_target.cbufs[0] = pipe->screen->get_tex_surface
@@ -627,26 +648,26 @@ static int vlFlush
 
        pipe->set_framebuffer_state(pipe, &mc->render_target);
        pipe->set_viewport_state(pipe, &mc->viewport);
-       vs_consts = pipe->winsys->buffer_map
+       vs_consts = pipe_buffer_map
        (
-               pipe->winsys,
+               pipe->screen,
                mc->vs_const_buf.buffer,
-               PIPE_BUFFER_USAGE_CPU_WRITE
+               PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
        );
 
        vs_consts->denorm.x = mc->buffered_surface->texture->width[0];
        vs_consts->denorm.y = mc->buffered_surface->texture->height[0];
 
-       pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer);
+       pipe_buffer_unmap(pipe->screen, 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 (num_macroblocks[vlMacroBlockExTypeIntra] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs.all);
                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->set_sampler_textures(pipe, 3, mc->textures.all);
+               pipe->bind_sampler_states(pipe, 3, mc->samplers.all);
                pipe->bind_vs_state(pipe, mc->i_vs);
                pipe->bind_fs_state(pipe, mc->i_fs);
 
@@ -656,11 +677,11 @@ static int vlFlush
 
        if (num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
                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);
+               mc->textures.ref[0] = mc->past_surface->texture;
+               pipe->set_sampler_textures(pipe, 4, mc->textures.all);
+               pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
                pipe->bind_vs_state(pipe, mc->p_vs[0]);
                pipe->bind_fs_state(pipe, mc->p_fs[0]);
 
@@ -670,11 +691,11 @@ static int vlFlush
 
        if (num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
                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);
+               mc->textures.ref[0] = mc->past_surface->texture;
+               pipe->set_sampler_textures(pipe, 4, mc->textures.all);
+               pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
                pipe->bind_vs_state(pipe, mc->p_vs[1]);
                pipe->bind_fs_state(pipe, mc->p_fs[1]);
 
@@ -684,11 +705,11 @@ static int vlFlush
 
        if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
                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);
+               mc->textures.ref[0] = mc->future_surface->texture;
+               pipe->set_sampler_textures(pipe, 4, mc->textures.all);
+               pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
                pipe->bind_vs_state(pipe, mc->p_vs[0]);
                pipe->bind_fs_state(pipe, mc->p_fs[0]);
 
@@ -698,11 +719,11 @@ static int vlFlush
 
        if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs.all);
                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);
+               mc->textures.ref[0] = mc->future_surface->texture;
+               pipe->set_sampler_textures(pipe, 4, mc->textures.all);
+               pipe->bind_sampler_states(pipe, 4, mc->samplers.all);
                pipe->bind_vs_state(pipe, mc->p_vs[1]);
                pipe->bind_fs_state(pipe, mc->p_fs[1]);
 
@@ -712,12 +733,12 @@ static int vlFlush
 
        if (num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs.all);
                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]);
-               pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers);
+               mc->textures.ref[0] = mc->past_surface->texture;
+               mc->textures.ref[1] = mc->future_surface->texture;
+               pipe->set_sampler_textures(pipe, 5, mc->textures.all);
+               pipe->bind_sampler_states(pipe, 5, mc->samplers.all);
                pipe->bind_vs_state(pipe, mc->b_vs[0]);
                pipe->bind_fs_state(pipe, mc->b_fs[0]);
 
@@ -727,12 +748,12 @@ static int vlFlush
 
        if (num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0)
        {
-               pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
+               pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs.all);
                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]);
-               pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers);
+               mc->textures.ref[0] = mc->past_surface->texture;
+               mc->textures.ref[1] = mc->future_surface->texture;
+               pipe->set_sampler_textures(pipe, 5, mc->textures.all);
+               pipe->bind_sampler_states(pipe, 5, mc->samplers.all);
                pipe->bind_vs_state(pipe, mc->b_vs[1]);
                pipe->bind_fs_state(pipe, mc->b_fs[1]);
 
@@ -741,13 +762,13 @@ static int vlFlush
        }
 
        pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &mc->buffered_surface->render_fence);
+       pipe_surface_reference(&mc->render_target.cbufs[0], NULL);
 
        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;
 }
@@ -760,6 +781,7 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
 )
 {
        struct vlR16SnormBufferedMC     *mc;
+       bool                            new_surface = false;
        unsigned int                    i;
 
        assert(render);
@@ -771,20 +793,33 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
                if (mc->buffered_surface != surface)
                {
                        vlFlush(&mc->base);
-                       mc->buffered_surface = surface;
-                       mc->past_surface = batch->past_surface;
-                       mc->future_surface = batch->future_surface;
-                       mc->surface_tex_inv_size.x = 1.0f / surface->texture->width[0];
-                       mc->surface_tex_inv_size.y = 1.0f / surface->texture->height[0];
+                       new_surface = true;
                }
        }
        else
+               new_surface = true;
+
+       if (new_surface)
        {
                mc->buffered_surface = surface;
                mc->past_surface = batch->past_surface;
                mc->future_surface = batch->future_surface;
                mc->surface_tex_inv_size.x = 1.0f / surface->texture->width[0];
                mc->surface_tex_inv_size.y = 1.0f / surface->texture->height[0];
+
+               for (i = 0; i < 3; ++i)
+               {
+                       mc->tex_transfer[i] = mc->pipe->screen->get_tex_transfer
+                       (
+                               mc->pipe->screen,
+                               mc->textures.all[i],
+                               0, 0, 0, PIPE_TRANSFER_WRITE, 0, 0,
+                               surface->texture->width[0],
+                               surface->texture->height[0]
+                       );
+
+                       mc->texels[i] = mc->pipe->screen->transfer_map(mc->pipe->screen, mc->tex_transfer[i]);
+               }
        }
 
        for (i = 0; i < batch->num_macroblocks; ++i)
@@ -793,7 +828,7 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
        return 0;
 }
 
-static int vlEnd
+static inline int vlEnd
 (
        struct vlRender *render
 )
@@ -810,7 +845,7 @@ static int vlDestroy
 {
        struct vlR16SnormBufferedMC     *mc;
        struct pipe_context             *pipe;
-       unsigned int                    h, i;
+       unsigned int                    i;
 
        assert(render);
 
@@ -818,19 +853,14 @@ static int vlDestroy
        pipe = mc->pipe;
 
        for (i = 0; i < 5; ++i)
-               pipe->delete_sampler_state(pipe, mc->samplers[i]);
+               pipe->delete_sampler_state(pipe, mc->samplers.all[i]);
 
-       for (h = 0; h < NUM_BUF_SETS; ++h)
-                       for (i = 0; i < 3; ++i)
-                               pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[h][i].buffer);
+       for (i = 0; i < 3; ++i)
+               pipe_buffer_reference(&mc->vertex_bufs.all[i].buffer, NULL);
 
        /* Textures 3 & 4 are not created directly, no need to release them here */
-       for (i = 0; i < NUM_BUF_SETS; ++i)
-       {
-               pipe_texture_release(&mc->textures[i][0]);
-               pipe_texture_release(&mc->textures[i][1]);
-               pipe_texture_release(&mc->textures[i][2]);
-       }
+       for (i = 0; i < 3; ++i)
+               pipe_texture_reference(&mc->textures.all[i], NULL);
 
        pipe->delete_vs_state(pipe, mc->i_vs);
        pipe->delete_fs_state(pipe, mc->i_fs);
@@ -843,11 +873,11 @@ static int vlDestroy
                pipe->delete_fs_state(pipe, mc->b_fs[i]);
        }
 
-       pipe->winsys->buffer_destroy(pipe->winsys, mc->vs_const_buf.buffer);
-       pipe->winsys->buffer_destroy(pipe->winsys, mc->fs_const_buf.buffer);
+       pipe_buffer_reference(&mc->vs_const_buf.buffer, NULL);
+       pipe_buffer_reference(&mc->fs_const_buf.buffer, NULL);
 
-       free(mc->macroblocks);
-       free(mc);
+       FREE(mc->macroblocks);
+       FREE(mc);
 
        return 0;
 }
@@ -864,1191 +894,7 @@ static const struct vlFragmentShaderConsts fs_consts =
        {0.5f, 2.0f, 0.0f, 0.0f}
 };
 
-static int vlCreateVertexShaderIMB
-(
-       struct vlR16SnormBufferedMC *mc
-)
-{
-       const unsigned int              max_tokens = 50;
-
-       struct pipe_context             *pipe;
-       struct pipe_shader_state        vs;
-       struct tgsi_token               *tokens;
-       struct tgsi_header              *header;
-
-       struct tgsi_full_declaration    decl;
-       struct tgsi_full_instruction    inst;
-
-       unsigned int                    ti;
-       unsigned int                    i;
-
-       assert(mc);
-
-       pipe = mc->pipe;
-       tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
-       /* Version */
-       *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-       /* Header */
-       header = (struct tgsi_header*)&tokens[1];
-       *header = tgsi_build_header();
-       /* Processor */
-       *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
-       ti = 3;
-
-       /*
-        * decl i0              ; Vertex pos
-        * decl i1              ; Luma texcoords
-        * decl i2              ; Chroma Cb texcoords
-        * decl i3              ; Chroma Cr texcoords
-        */
-       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);
-       }
-
-       /*
-        * decl o0              ; Vertex pos
-        * decl o1              ; Luma texcoords
-        * decl o2              ; Chroma Cb texcoords
-        * decl o3              ; Chroma Cr texcoords
-        */
-       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);
-       }
-
-       /*
-        * mov o0, i0           ; Move input vertex pos 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 < 4; ++i)
-       {
-               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);
-       }
-
-       /* end */
-       inst = vl_end();
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       vs.tokens = tokens;
-       mc->i_vs = pipe->create_vs_state(pipe, &vs);
-       free(tokens);
-
-       return 0;
-}
-
-static int vlCreateFragmentShaderIMB
-(
-       struct vlR16SnormBufferedMC *mc
-)
-{
-       const unsigned int              max_tokens = 100;
-
-       struct pipe_context             *pipe;
-       struct pipe_shader_state        fs;
-       struct tgsi_token               *tokens;
-       struct tgsi_header              *header;
-
-       struct tgsi_full_declaration    decl;
-       struct tgsi_full_instruction    inst;
-
-       unsigned int                    ti;
-       unsigned int                    i;
-
-       assert(mc);
-
-       pipe = mc->pipe;
-       tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
-       /* Version */
-       *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-       /* Header */
-       header = (struct tgsi_header*)&tokens[1];
-       *header = tgsi_build_header();
-       /* Processor */
-       *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
-       ti = 3;
-
-       /*
-        * 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);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /* decl o0                      ; Fragment color */
-       decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /* decl t0, t1 */
-       decl = vl_decl_temps(0, 1);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /*
-        * decl s0                      ; Sampler for luma texture
-        * decl s1                      ; Sampler for chroma Cb texture
-        * decl s2                      ; Sampler for chroma Cr texture
-        */
-       for (i = 0; i < 3; ++i)
-       {
-               decl = vl_decl_samplers(i, i);
-               ti += tgsi_build_full_declaration(&decl, &tokens[ti], header,max_tokens - ti);
-       }
-
-       /*
-        * tex2d t1, i0, s0             ; Read texel from luma texture
-        * mov t0.x, t1.x               ; Move luma sample into .x component
-        * tex2d t1, i1, s1             ; Read texel from chroma Cb texture
-        * mov t0.y, t1.x               ; Move Cb sample into .y component
-        * 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, 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);
-               inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-               inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-               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 */
-       inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_CONSTANT, 0);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* end */
-       inst = vl_end();
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       fs.tokens = tokens;
-       mc->i_fs = pipe->create_fs_state(pipe, &fs);
-       free(tokens);
-
-       return 0;
-}
-
-static int vlCreateVertexShaderFramePMB
-(
-       struct vlR16SnormBufferedMC *mc
-)
-{
-       const unsigned int              max_tokens = 100;
-
-       struct pipe_context             *pipe;
-       struct pipe_shader_state        vs;
-       struct tgsi_token               *tokens;
-       struct tgsi_header              *header;
-
-       struct tgsi_full_declaration    decl;
-       struct tgsi_full_instruction    inst;
-
-       unsigned int                    ti;
-       unsigned int                    i;
-
-       assert(mc);
-
-       pipe = mc->pipe;
-       tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
-       /* Version */
-       *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-       /* Header */
-       header = (struct tgsi_header*)&tokens[1];
-       *header = tgsi_build_header();
-       /* Processor */
-       *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
-       ti = 3;
-
-       /*
-        * 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 < 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 o0              ; Vertex pos
-        * decl o1              ; Luma texcoords
-        * decl o2              ; Chroma Cb texcoords
-        * decl o3              ; Chroma Cr texcoords
-        * decl o4              ; Ref macroblock texcoords
-        */
-       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);
-       }
-
-       /*
-        * mov o0, i0           ; Move input vertex pos 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 < 4; ++i)
-       {
-               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 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 */
-       inst = vl_end();
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       vs.tokens = tokens;
-       mc->p_vs[0] = pipe->create_vs_state(pipe, &vs);
-       free(tokens);
-
-       return 0;
-}
-
-static int vlCreateVertexShaderFieldPMB
-(
-       struct vlR16SnormBufferedMC *mc
-)
-{
-       const unsigned int              max_tokens = 100;
-
-       struct pipe_context             *pipe;
-       struct pipe_shader_state        vs;
-       struct tgsi_token               *tokens;
-       struct tgsi_header              *header;
-
-       struct tgsi_full_declaration    decl;
-       struct tgsi_full_instruction    inst;
-
-       unsigned int                    ti;
-       unsigned int                    i;
-
-       assert(mc);
-
-       pipe = mc->pipe;
-       tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
-       /* Version */
-       *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-       /* Header */
-       header = (struct tgsi_header*)&tokens[1];
-       *header = tgsi_build_header();
-       /* Processor */
-       *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
-       ti = 3;
-
-       /*
-        * 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 < 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              ; 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 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 < 7; 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, 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 < 4; ++i)
-       {
-               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 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 + 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);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* end */
-       inst = vl_end();
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       vs.tokens = tokens;
-       mc->p_vs[1] = pipe->create_vs_state(pipe, &vs);
-       free(tokens);
-
-       return 0;
-}
-
-static int vlCreateFragmentShaderFramePMB
-(
-       struct vlR16SnormBufferedMC *mc
-)
-{
-       const unsigned int              max_tokens = 100;
-
-       struct pipe_context             *pipe;
-       struct pipe_shader_state        fs;
-       struct tgsi_token               *tokens;
-       struct tgsi_header              *header;
-
-       struct tgsi_full_declaration    decl;
-       struct tgsi_full_instruction    inst;
-
-       unsigned int                    ti;
-       unsigned int                    i;
-
-       assert(mc);
-
-       pipe = mc->pipe;
-       tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
-       /* Version */
-       *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-       /* Header */
-       header = (struct tgsi_header*)&tokens[1];
-       *header = tgsi_build_header();
-       /* Processor */
-       *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
-       ti = 3;
-
-       /*
-        * decl i0                      ; Luma texcoords
-        * decl i1                      ; Chroma Cb texcoords
-        * decl i2                      ; Chroma Cr texcoords
-        * decl i3                      ; Ref macroblock texcoords
-        */
-       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);
-       }
-
-       /* decl c0                      ; Scaling factor, rescales 16-bit snorm to 9-bit snorm */
-       decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 0);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /* decl o0                      ; Fragment color */
-       decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /* decl t0, t1 */
-       decl = vl_decl_temps(0, 1);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /*
-        * decl s0                      ; Sampler for luma texture
-        * decl s1                      ; Sampler for chroma Cb texture
-        * decl s2                      ; Sampler for chroma Cr texture
-        * decl s3                      ; Sampler for ref surface texture
-        */
-       for (i = 0; i < 4; ++i)
-       {
-               decl = vl_decl_samplers(i, i);
-               ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-       }
-
-       /*
-        * tex2d t1, i0, s0             ; Read texel from luma texture
-        * mov t0.x, t1.x               ; Move luma sample into .x component
-        * tex2d t1, i1, s1             ; Read texel from chroma Cb texture
-        * mov t0.y, t1.x               ; Move Cb sample into .y component
-        * 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, 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);
-               inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-               inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-               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, 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 */
-       inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* end */
-       inst = vl_end();
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       fs.tokens = tokens;
-       mc->p_fs[0] = pipe->create_fs_state(pipe, &fs);
-       free(tokens);
-
-       return 0;
-}
-
-static int vlCreateFragmentShaderFieldPMB
-(
-       struct vlR16SnormBufferedMC *mc
-)
-{
-       const unsigned int              max_tokens = 200;
-
-       struct pipe_context             *pipe;
-       struct pipe_shader_state        fs;
-       struct tgsi_token               *tokens;
-       struct tgsi_header              *header;
-
-       struct tgsi_full_declaration    decl;
-       struct tgsi_full_instruction    inst;
-
-       unsigned int                    ti;
-       unsigned int                    i;
-
-       assert(mc);
-
-       pipe = mc->pipe;
-       tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
-       /* Version */
-       *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-       /* Header */
-       header = (struct tgsi_header*)&tokens[1];
-       *header = tgsi_build_header();
-       /* Processor */
-       *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
-       ti = 3;
-
-       /*
-        * 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 < 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);
-       }
-
-       /*
-        * decl c0                      ; Scaling factor, rescales 16-bit snorm to 9-bit snorm
-        * decl c1                      ; Constants 1/2 & 2 in .x, .y channels for Y-mod-2 top/bottom field selection
-        */
-       decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /* decl o0                      ; Fragment color */
-       decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /* decl t0-t4 */
-       decl = vl_decl_temps(0, 4);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /*
-        * decl s0                      ; Sampler for luma texture
-        * decl s1                      ; Sampler for chroma Cb texture
-        * decl s2                      ; Sampler for chroma Cr texture
-        * decl s3                      ; Sampler for ref surface texture
-        */
-       for (i = 0; i < 4; ++i)
-       {
-               decl = vl_decl_samplers(i, i);
-               ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-       }
-
-       /*
-        * tex2d t1, i0, s0             ; Read texel from luma texture
-        * mov t0.x, t1.x               ; Move luma sample into .x component
-        * tex2d t1, i1, s1             ; Read texel from chroma Cb texture
-        * mov t0.y, t1.x               ; Move Cb sample into .y component
-        * 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, 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);
-               inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-               inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-               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, 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 + 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, 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;
-       inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* mul t3, t4, c1.x             ; Multiply pos Y-coord by 1/2 */
-       inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1);
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* floor t3, t3                 ; Get rid of fractional part */
-       inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* mul t3, t3, c1.y             ; Multiply by 2 */
-       inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1);
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* sub t3, t4, t3               ; Subtract from original Y to get Y % 2 */
-       inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* TODO: Move to conditional tex fetch on t3 instead of lerp */
-       /* lerp t1, t3, t1, t2          ; Choose between top and bottom fields based on Y % 2 */
-       inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* add o0, t0, t1               ; Add ref and differential to form final output */
-       inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* end */
-       inst = vl_end();
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       fs.tokens = tokens;
-       mc->p_fs[1] = pipe->create_fs_state(pipe, &fs);
-       free(tokens);
-
-       return 0;
-}
-
-static int vlCreateVertexShaderFrameBMB
-(
-       struct vlR16SnormBufferedMC *mc
-)
-{
-       const unsigned int              max_tokens = 100;
-
-       struct pipe_context             *pipe;
-       struct pipe_shader_state        vs;
-       struct tgsi_token               *tokens;
-       struct tgsi_header              *header;
-
-       struct tgsi_full_declaration    decl;
-       struct tgsi_full_instruction    inst;
-
-       unsigned int                    ti;
-       unsigned int                    i;
-
-       assert(mc);
-
-       pipe = mc->pipe;
-       tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
-       /* Version */
-       *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-       /* Header */
-       header = (struct tgsi_header*)&tokens[1];
-       *header = tgsi_build_header();
-       /* Processor */
-       *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
-       ti = 3;
-
-       /*
-        * 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 < 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 o0              ; Vertex pos
-        * 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 < 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);
-       }
-
-       /*
-        * mov o0, i0           ; Move input vertex pos 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 < 4; ++i)
-       {
-               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 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 + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, (i + 2) * 2);
-               ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-       }
-
-       /* end */
-       inst = vl_end();
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       vs.tokens = tokens;
-       mc->b_vs[0] = pipe->create_vs_state(pipe, &vs);
-       free(tokens);
-
-       return 0;
-}
-
-static int vlCreateVertexShaderFieldBMB
-(
-       struct vlR16SnormBufferedMC *mc
-)
-{
-       const unsigned int              max_tokens = 100;
-
-       struct pipe_context             *pipe;
-       struct pipe_shader_state        vs;
-       struct tgsi_token               *tokens;
-       struct tgsi_header              *header;
-
-       struct tgsi_full_declaration    decl;
-       struct tgsi_full_instruction    inst;
-
-       unsigned int                    ti;
-       unsigned int                    i;
-
-       assert(mc);
-
-       pipe = mc->pipe;
-       tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
-       /* Version */
-       *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-       /* Header */
-       header = (struct tgsi_header*)&tokens[1];
-       *header = tgsi_build_header();
-       /* Processor */
-       *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_VERTEX, header);
-
-       ti = 3;
-
-       /*
-        * 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 < 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              ; 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 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 < 9; 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);
-       }
-
-       /* decl t0, t1 */
-       decl = vl_decl_temps(0, 1);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /*
-        * mov o0, i0           ; Move input vertex pos 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 < 4; ++i)
-       {
-               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 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 + 4, TGSI_FILE_INPUT, 0, TGSI_FILE_INPUT, i + 4);
-               ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-       }
-
-       /* 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 */
-       inst = vl_end();
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       vs.tokens = tokens;
-       mc->b_vs[1] = pipe->create_vs_state(pipe, &vs);
-       free(tokens);
-
-       return 0;
-}
-
-static int vlCreateFragmentShaderFrameBMB
-(
-       struct vlR16SnormBufferedMC *mc
-)
-{
-       const unsigned int              max_tokens = 100;
-
-       struct pipe_context             *pipe;
-       struct pipe_shader_state        fs;
-       struct tgsi_token               *tokens;
-       struct tgsi_header              *header;
-
-       struct tgsi_full_declaration    decl;
-       struct tgsi_full_instruction    inst;
-
-       unsigned int                    ti;
-       unsigned int                    i;
-
-       assert(mc);
-
-       pipe = mc->pipe;
-       tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
-       /* Version */
-       *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-       /* Header */
-       header = (struct tgsi_header*)&tokens[1];
-       *header = tgsi_build_header();
-       /* Processor */
-       *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
-       ti = 3;
-
-       /*
-        * 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 < 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);
-       }
-
-       /*
-        * decl c0                      ; Scaling factor, rescales 16-bit snorm to 9-bit snorm
-        * decl c1                      ; Constant 1/2 in .x channel to use as weight to blend past and future texels
-        */
-       decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /* decl o0                      ; Fragment color */
-       decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /* decl t0-t2 */
-       decl = vl_decl_temps(0, 2);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /*
-        * decl s0                      ; Sampler for luma texture
-        * decl s1                      ; Sampler for chroma Cb texture
-        * decl s2                      ; Sampler for chroma Cr texture
-        * decl s3                      ; Sampler for first ref surface texture
-        * decl s4                      ; Sampler for second ref surface texture
-        */
-       for (i = 0; i < 5; ++i)
-       {
-               decl = vl_decl_samplers(i, i);
-               ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-       }
-
-       /*
-        * tex2d t1, i0, s0             ; Read texel from luma texture
-        * mov t0.x, t1.x               ; Move luma sample into .x component
-        * tex2d t1, i1, s1             ; Read texel from chroma Cb texture
-        * mov t0.y, t1.x               ; Move Cb sample into .y component
-        * 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, 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);
-               inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-               inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-               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, 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 + 3, TGSI_FILE_SAMPLER, i + 3);
-               ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-       }
-
-       /* lerp t1, c1.x, t1, t2        ; Blend past and future texels */
-       inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
-       inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* add o0, t0, t1               ; Add past/future ref and differential to form final output */
-       inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* end */
-       inst = vl_end();
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       fs.tokens = tokens;
-       mc->b_fs[0] = pipe->create_fs_state(pipe, &fs);
-       free(tokens);
-
-       return 0;
-}
-
-static int vlCreateFragmentShaderFieldBMB
-(
-       struct vlR16SnormBufferedMC *mc
-)
-{
-       const unsigned int              max_tokens = 200;
-
-       struct pipe_context             *pipe;
-       struct pipe_shader_state        fs;
-       struct tgsi_token               *tokens;
-       struct tgsi_header              *header;
-
-       struct tgsi_full_declaration    decl;
-       struct tgsi_full_instruction    inst;
-
-       unsigned int                    ti;
-       unsigned int                    i;
-
-       assert(mc);
-
-       pipe = mc->pipe;
-       tokens = (struct tgsi_token*)malloc(max_tokens * sizeof(struct tgsi_token));
-
-       /* Version */
-       *(struct tgsi_version*)&tokens[0] = tgsi_build_version();
-       /* Header */
-       header = (struct tgsi_header*)&tokens[1];
-       *header = tgsi_build_header();
-       /* Processor */
-       *(struct tgsi_processor*)&tokens[2] = tgsi_build_processor(TGSI_PROCESSOR_FRAGMENT, header);
-
-       ti = 3;
-
-       /*
-        * 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 < 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);
-       }
-
-       /*
-        * decl c0                      ; Scaling factor, rescales 16-bit snorm to 9-bit snorm
-        * decl c1                      ; Constants 1/2 & 2 in .x, .y channels to use as weight to blend past and future texels
-        *                              ; and for Y-mod-2 top/bottom field selection
-        */
-       decl = vl_decl_constants(TGSI_SEMANTIC_GENERIC, 0, 0, 1);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /* decl o0                      ; Fragment color */
-       decl = vl_decl_output(TGSI_SEMANTIC_COLOR, 0, 0, 0);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /* decl t0-t5 */
-       decl = vl_decl_temps(0, 5);
-       ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-
-       /*
-        * decl s0                      ; Sampler for luma texture
-        * decl s1                      ; Sampler for chroma Cb texture
-        * decl s2                      ; Sampler for chroma Cr texture
-        * decl s3                      ; Sampler for first ref surface texture
-        * decl s4                      ; Sampler for second ref surface texture
-        */
-       for (i = 0; i < 5; ++i)
-       {
-               decl = vl_decl_samplers(i, i);
-               ti += tgsi_build_full_declaration(&decl, &tokens[ti], header, max_tokens - ti);
-       }
-
-       /*
-        * tex2d t1, i0, s0             ; Read texel from luma texture
-        * mov t0.x, t1.x               ; Move luma sample into .x component
-        * tex2d t1, i1, s1             ; Read texel from chroma Cb texture
-        * mov t0.y, t1.x               ; Move Cb sample into .y component
-        * 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, 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);
-               inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-               inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-               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);
-
-       /* XXX: Pos values off by 0.5? */
-       /* 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;
-       inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* mul t3, t4, c1.x             ; Multiply pos Y-coord by 1/2 */
-       inst = vl_inst3(TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_CONSTANT, 1);
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* floor t3, t3                 ; Get rid of fractional part */
-       inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* mul t3, t3, c1.y             ; Multiply by 2 */
-       inst = vl_inst3( TGSI_OPCODE_MUL, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_CONSTANT, 1);
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
-       inst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* sub t3, t4, t3               ; Subtract from original Y to get Y % 2 */
-       inst = vl_inst3(TGSI_OPCODE_SUB, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 3);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /*
-        * 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 + 3, TGSI_FILE_SAMPLER, 3);
-               ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-       }
-
-       /* TODO: Move to conditional tex fetch on t3 instead of lerp */
-       /* lerp t1, t3, t1, t2          ; Choose between top and bottom fields based on Y % 2 */
-       inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /*
-        * 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 + 5, TGSI_FILE_SAMPLER, 4);
-               ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-       }
-
-       /* TODO: Move to conditional tex fetch on t3 instead of lerp */
-       /* lerp t2, t3, t4, t5          ; Choose between top and bottom fields based on Y % 2 */
-       inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 2, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 5);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* lerp t1, c1.x, t1, t2        ; Blend past and future texels */
-       inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
-       inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
-       inst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_X;
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* add o0, t0, t1               ; Add past/future ref and differential to form final output */
-       inst = vl_inst3(TGSI_OPCODE_ADD, TGSI_FILE_OUTPUT, 0, TGSI_FILE_TEMPORARY, 0, TGSI_FILE_TEMPORARY, 1);
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       /* end */
-       inst = vl_end();
-       ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
-
-       fs.tokens = tokens;
-       mc->b_fs[1] = pipe->create_fs_state(pipe, &fs);
-       free(tokens);
-
-       return 0;
-}
+#include "vl_r16snorm_mc_buf_shaders.inc"
 
 static int vlCreateDataBufs
 (
@@ -2057,42 +903,39 @@ static int vlCreateDataBufs
 {
        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            h, i;
+       unsigned int            i;
 
        assert(mc);
 
        pipe = mc->pipe;
+       mc->macroblocks_per_picture = mbw * mbh;
 
        /* Create our vertex buffers */
-       for (h = 0; h < NUM_BUF_SETS; ++h)
+       mc->vertex_bufs.ycbcr.stride = sizeof(struct vlVertex2f) * 4;
+       mc->vertex_bufs.ycbcr.max_index = 24 * mc->macroblocks_per_picture - 1;
+       mc->vertex_bufs.ycbcr.buffer_offset = 0;
+       mc->vertex_bufs.ycbcr.buffer = pipe_buffer_create
+       (
+               pipe->screen,
+               DEFAULT_BUF_ALIGNMENT,
+               PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD,
+               sizeof(struct vlVertex2f) * 4 * 24 * mc->macroblocks_per_picture
+       );
+
+       for (i = 1; i < 3; ++i)
        {
-               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
+               mc->vertex_bufs.all[i].stride = sizeof(struct vlVertex2f) * 2;
+               mc->vertex_bufs.all[i].max_index = 24 * mc->macroblocks_per_picture - 1;
+               mc->vertex_bufs.all[i].buffer_offset = 0;
+               mc->vertex_bufs.all[i].buffer = pipe_buffer_create
                (
-                       pipe->winsys,
-                       1,
-                       PIPE_BUFFER_USAGE_VERTEX,
-                       sizeof(struct vlVertex2f) * 4 * 24 * num_mb_per_frame
+                       pipe->screen,
+                       DEFAULT_BUF_ALIGNMENT,
+                       PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD,
+                       sizeof(struct vlVertex2f) * 2 * 24 * mc->macroblocks_per_picture
                );
-
-               for (i = 1; i < 3; ++i)
-               {
-                       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) * 2 * 24 * num_mb_per_frame
-                       );
-               }
        }
 
        /* Position element */
@@ -2144,34 +987,32 @@ static int vlCreateDataBufs
        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
+       mc->vs_const_buf.buffer = pipe_buffer_create
        (
-               pipe->winsys,
-               1,
-               PIPE_BUFFER_USAGE_CONSTANT,
-               mc->vs_const_buf.size
+               pipe->screen,
+               DEFAULT_BUF_ALIGNMENT,
+               PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD,
+               sizeof(struct vlVertexShaderConsts)
        );
 
-       mc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts);
-       mc->fs_const_buf.buffer = pipe->winsys->buffer_create
+       mc->fs_const_buf.buffer = pipe_buffer_create
        (
-               pipe->winsys,
-               1,
+               pipe->screen,
+               DEFAULT_BUF_ALIGNMENT,
                PIPE_BUFFER_USAGE_CONSTANT,
-               mc->fs_const_buf.size
+               sizeof(struct vlFragmentShaderConsts)
        );
 
        memcpy
        (
-               pipe->winsys->buffer_map(pipe->winsys, mc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
+               pipe_buffer_map(pipe->screen, mc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
                &fs_consts,
                sizeof(struct vlFragmentShaderConsts)
        );
 
-       pipe->winsys->buffer_unmap(pipe->winsys, mc->fs_const_buf.buffer);
+       pipe_buffer_unmap(pipe->screen, mc->fs_const_buf.buffer);
 
-       mc->macroblocks = malloc(sizeof(struct vlMpeg2MacroBlock) * num_mb_per_frame);
+       mc->macroblocks = MALLOC(sizeof(struct vlMpeg2MacroBlock) * mc->macroblocks_per_picture);
 
        return 0;
 }
@@ -2191,6 +1032,13 @@ static int vlInit
 
        pipe = mc->pipe;
 
+       mc->buffered_surface = NULL;
+       mc->past_surface = NULL;
+       mc->future_surface = NULL;
+       for (i = 0; i < 3; ++i)
+               mc->zero_block[i].x = -1.0f;
+       mc->num_macroblocks = 0;
+
        /* For MC we render to textures, which are rounded up to nearest POT */
        mc->viewport.scale[0] = vlRoundUpPOT(mc->picture_width);
        mc->viewport.scale[1] = vlRoundUpPOT(mc->picture_height);
@@ -2203,7 +1051,7 @@ static int vlInit
 
        mc->render_target.width = vlRoundUpPOT(mc->picture_width);
        mc->render_target.height = vlRoundUpPOT(mc->picture_height);
-       mc->render_target.num_cbufs = 1;
+       mc->render_target.nr_cbufs = 1;
        /* FB for MC stage is a vlSurface created by the user, set at render time */
        mc->render_target.zsbuf = NULL;
 
@@ -2232,7 +1080,7 @@ static int vlInit
                /*sampler.max_lod = ;*/
                /*sampler.border_color[i] = ;*/
                /*sampler.max_anisotropy = ;*/
-               mc->samplers[i] = pipe->create_sampler_state(pipe, &sampler);
+               mc->samplers.all[i] = pipe->create_sampler_state(pipe, &sampler);
        }
 
        memset(&template, 0, sizeof(struct pipe_texture));
@@ -2244,9 +1092,9 @@ static int vlInit
        template.depth[0] = 1;
        template.compressed = 0;
        pf_get_block(template.format, &template.block);
+       template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_DYNAMIC;
 
-       for (i = 0; i < NUM_BUF_SETS; ++i)
-               mc->textures[i][0] = pipe->screen->texture_create(pipe->screen, &template);
+       mc->textures.y = pipe->screen->texture_create(pipe->screen, &template);
 
        if (mc->picture_format == vlFormatYCbCr420)
        {
@@ -2256,13 +1104,10 @@ static int vlInit
        else if (mc->picture_format == vlFormatYCbCr422)
                template.height[0] = vlRoundUpPOT(mc->picture_height / 2);
 
-       for (i = 0; i < NUM_BUF_SETS; ++i)
-       {
-               mc->textures[i][1] = pipe->screen->texture_create(pipe->screen, &template);
-               mc->textures[i][2] = pipe->screen->texture_create(pipe->screen, &template);
-       }
+       mc->textures.cb = pipe->screen->texture_create(pipe->screen, &template);
+       mc->textures.cr = pipe->screen->texture_create(pipe->screen, &template);
 
-       /* textures[3] & textures[4] are assigned from vlSurfaces for P and B macroblocks at render time */
+       /* textures.all[3] & textures.all[4] are assigned from vlSurfaces for P and B macroblocks at render time */
 
        vlCreateVertexShaderIMB(mc);
        vlCreateFragmentShaderIMB(mc);
@@ -2288,13 +1133,12 @@ int vlCreateR16SNormBufferedMC
        struct vlRender **render
 )
 {
-       struct vlR16SnormBufferedMC     *mc;
-       unsigned int                    i;
+       struct vlR16SnormBufferedMC *mc;
 
        assert(pipe);
        assert(render);
 
-       mc = calloc(1, sizeof(struct vlR16SnormBufferedMC));
+       mc = CALLOC_STRUCT(vlR16SnormBufferedMC);
 
        mc->base.vlBegin = &vlBegin;
        mc->base.vlRenderMacroBlocksMpeg2 = &vlRenderMacroBlocksMpeg2R16SnormBuffered;
@@ -2305,14 +1149,6 @@ int vlCreateR16SNormBufferedMC
        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;
-       for (i = 0; i < 3; ++i)
-               mc->zero_block[i].x = -1.0f;
-       mc->num_macroblocks = 0;
-
        vlInit(mc);
 
        *render = &mc->base;