[g3dvl] move idct out of mc code
authorChristian König <deathsimple@vodafone.de>
Wed, 9 Mar 2011 22:40:08 +0000 (23:40 +0100)
committerChristian König <deathsimple@vodafone.de>
Wed, 9 Mar 2011 22:40:08 +0000 (23:40 +0100)
iDCT and MC now look good, but sp_video_context is a total mess

src/gallium/auxiliary/vl/vl_idct.c
src/gallium/auxiliary/vl/vl_idct.h
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
src/gallium/drivers/softpipe/sp_video_context.c
src/gallium/drivers/softpipe/sp_video_context.h

index f191a89..e030737 100644 (file)
@@ -476,6 +476,15 @@ init_textures(struct vl_idct *idct, struct vl_idct_buffer *buffer)
       buffer->sampler_views.all[i] = idct->pipe->create_sampler_view(idct->pipe, buffer->textures.all[i], &sampler_view);
    }
 
+   template.target = PIPE_TEXTURE_2D;
+   /* TODO: Accomodate HW that can't do this and also for cases when this isn't precise enough */
+   template.format = PIPE_FORMAT_R16_SNORM;
+   template.width0 = idct->buffer_width;
+   template.height0 = idct->buffer_height;
+   template.depth0 = 1;
+
+   buffer->destination = idct->pipe->screen->resource_create(idct->pipe->screen, &template);
+
    return true;
 }
 
@@ -577,9 +586,8 @@ vl_idct_cleanup(struct vl_idct *idct)
    pipe_resource_reference(&idct->matrix, NULL);
 }
 
-bool
-vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer,
-                    struct pipe_resource *dst)
+struct pipe_resource *
+vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer)
 {
    struct pipe_surface template;
 
@@ -587,14 +595,12 @@ vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer,
 
    assert(buffer);
    assert(idct);
-   assert(dst);
 
    pipe_resource_reference(&buffer->textures.individual.matrix, idct->matrix);
    pipe_resource_reference(&buffer->textures.individual.transpose, idct->matrix);
-   pipe_resource_reference(&buffer->destination, dst);
 
    if (!init_textures(idct, buffer))
-      return false;
+      return NULL;
 
    /* init state */
    buffer->viewport[0].scale[0] = buffer->textures.individual.intermediate->width0;
@@ -640,7 +646,7 @@ vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer,
       buffer->fb_state[i].zsbuf = NULL;
    }
 
-   return true;
+   return buffer->destination;
 }
 
 void
@@ -685,7 +691,6 @@ vl_idct_map_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
 void
 vl_idct_add_block(struct vl_idct_buffer *buffer, unsigned x, unsigned y, short *block)
 {
-   //struct vertex2s v;
    unsigned tex_pitch;
    short *texels;
 
index 0ff12cf..264ad2b 100644 (file)
@@ -97,8 +97,7 @@ bool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe,
 
 void vl_idct_cleanup(struct vl_idct *idct);
 
-bool vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer,
-                         struct pipe_resource *dst);
+struct pipe_resource *vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer);
 
 void vl_idct_cleanup_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer);
 
index 160388a..5b67534 100644 (file)
@@ -481,68 +481,6 @@ cleanup_pipe_state(struct vl_mpeg12_mc_renderer *r)
    r->pipe->delete_rasterizer_state(r->pipe, r->rs_state);
 }
 
-static bool
-init_buffers(struct vl_mpeg12_mc_renderer *r)
-{
-   struct pipe_resource *idct_matrix;
-   unsigned chroma_width, chroma_height, chroma_blocks_x, chroma_blocks_y;
-
-   assert(r);
-
-   if (!(idct_matrix = vl_idct_upload_matrix(r->pipe)))
-      return false;
-
-   if (!vl_idct_init(&r->idct_y, r->pipe, r->buffer_width, r->buffer_height,
-                     2, 2, TGSI_SWIZZLE_X, idct_matrix))
-      return false;
-
-   if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
-      chroma_width = r->buffer_width / 2;
-      chroma_height = r->buffer_height / 2;
-      chroma_blocks_x = 1;
-      chroma_blocks_y = 1;
-   } else if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
-      chroma_width = r->buffer_width;
-      chroma_height = r->buffer_height / 2;
-      chroma_blocks_x = 2;
-      chroma_blocks_y = 1;
-   } else {
-      chroma_width = r->buffer_width;
-      chroma_height = r->buffer_height;
-      chroma_blocks_x = 2;
-      chroma_blocks_y = 2;
-   }
-
-   if(!vl_idct_init(&r->idct_cr, r->pipe, chroma_width, chroma_height,
-                    chroma_blocks_x, chroma_blocks_y, TGSI_SWIZZLE_Y, idct_matrix))
-      return false;
-
-   if(!vl_idct_init(&r->idct_cb, r->pipe, chroma_width, chroma_height,
-                    chroma_blocks_x, chroma_blocks_y, TGSI_SWIZZLE_Z, idct_matrix))
-      return false;
-
-   r->vs = create_vert_shader(r);
-   r->fs = create_frag_shader(r);
-
-   if (r->vs == NULL || r->fs == NULL)
-      return false;
-
-   return true;
-}
-
-static void
-cleanup_buffers(struct vl_mpeg12_mc_renderer *r)
-{
-   assert(r);
-
-   r->pipe->delete_vs_state(r->pipe, r->vs);
-   r->pipe->delete_fs_state(r->pipe, r->fs);
-
-   vl_idct_cleanup(&r->idct_y);
-   vl_idct_cleanup(&r->idct_cr);
-   vl_idct_cleanup(&r->idct_cb);
-}
-
 static struct pipe_sampler_view
 *find_or_create_sampler_view(struct vl_mpeg12_mc_renderer *r, struct pipe_surface *surface)
 {
@@ -571,41 +509,6 @@ static struct pipe_sampler_view
 }
 
 static void
-grab_blocks(struct vl_mpeg12_mc_renderer *r,
-            struct vl_mpeg12_mc_buffer *buffer,
-            unsigned mbx, unsigned mby,
-            unsigned cbp, short *blocks)
-{
-   unsigned tb = 0;
-   unsigned x, y;
-
-   assert(r);
-   assert(blocks);
-
-   for (y = 0; y < 2; ++y) {
-      for (x = 0; x < 2; ++x, ++tb) {
-         if (cbp & (*r->empty_block_mask)[0][y][x]) {
-            vl_idct_add_block(&buffer->idct_y, mbx * 2 + x, mby * 2 + y, blocks);
-            blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
-         }
-      }
-   }
-
-   /* TODO: Implement 422, 444 */
-   assert(r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
-
-   for (tb = 1; tb < 3; ++tb) {
-      if (cbp & (*r->empty_block_mask)[tb][0][0]) {
-         if(tb == 1)
-            vl_idct_add_block(&buffer->idct_cb, mbx, mby, blocks);
-         else
-            vl_idct_add_block(&buffer->idct_cr, mbx, mby, blocks);
-         blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
-      }
-   }
-}
-
-static void
 texview_map_delete(const struct keymap *map,
                    const void *key, void *data,
                    void *user)
@@ -649,12 +552,15 @@ vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
    if (!init_pipe_state(renderer))
       goto error_pipe_state;
 
-   if (!init_buffers(renderer))
-      goto error_buffers;
+   renderer->vs = create_vert_shader(renderer);
+   renderer->fs = create_frag_shader(renderer);
+
+   if (renderer->vs == NULL || renderer->fs == NULL)
+      goto error_shaders;
 
    return true;
 
-error_buffers:
+error_shaders:
    cleanup_pipe_state(renderer);
 
 error_pipe_state:
@@ -669,13 +575,15 @@ vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer)
 
    util_delete_keymap(renderer->texview_map, renderer->pipe);
    cleanup_pipe_state(renderer);
-   cleanup_buffers(renderer);
+
+   renderer->pipe->delete_vs_state(renderer->pipe, renderer->vs);
+   renderer->pipe->delete_fs_state(renderer->pipe, renderer->fs);
 }
 
 bool
-vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
+vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
+                         struct pipe_resource *y, struct pipe_resource *cr, struct pipe_resource *cb)
 {
-   struct pipe_resource template;
    struct pipe_sampler_view sampler_view;
 
    unsigned i;
@@ -686,41 +594,9 @@ vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg1
    buffer->past = NULL;
    buffer->future = NULL;
 
-   memset(&template, 0, sizeof(struct pipe_resource));
-   template.target = PIPE_TEXTURE_2D;
-   /* TODO: Accomodate HW that can't do this and also for cases when this isn't precise enough */
-   template.format = PIPE_FORMAT_R16_SNORM;
-   template.last_level = 0;
-   template.width0 = renderer->buffer_width;
-   template.height0 = renderer->buffer_height;
-   template.depth0 = 1;
-   template.array_size = 1;
-   template.usage = PIPE_USAGE_STATIC;
-   template.bind = PIPE_BIND_SAMPLER_VIEW;
-   template.flags = 0;
-
-   buffer->textures.individual.y = renderer->pipe->screen->resource_create(renderer->pipe->screen, &template);
-
-   if (!vl_idct_init_buffer(&renderer->idct_y, &buffer->idct_y, buffer->textures.individual.y))
-      return false;
-
-   if (renderer->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
-      template.width0 = renderer->buffer_width / 2;
-      template.height0 = renderer->buffer_height / 2;
-   }
-   else if (renderer->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422)
-      template.height0 = renderer->buffer_height / 2;
-
-   buffer->textures.individual.cb =
-      renderer->pipe->screen->resource_create(renderer->pipe->screen, &template);
-   buffer->textures.individual.cr =
-      renderer->pipe->screen->resource_create(renderer->pipe->screen, &template);
-
-   if (!vl_idct_init_buffer(&renderer->idct_cb, &buffer->idct_cb, buffer->textures.individual.cb))
-      return false;
-
-   if (!vl_idct_init_buffer(&renderer->idct_cr, &buffer->idct_cr, buffer->textures.individual.cr))
-      return false;
+   pipe_resource_reference(&buffer->textures.individual.y, y);
+   pipe_resource_reference(&buffer->textures.individual.cr, cr);
+   pipe_resource_reference(&buffer->textures.individual.cb, cb);
 
    for (i = 0; i < 3; ++i) {
       u_sampler_view_default_template(&sampler_view,
@@ -749,41 +625,21 @@ vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mp
       pipe_resource_reference(&buffer->textures.all[i], NULL);
    }
 
-   vl_idct_cleanup_buffer(&renderer->idct_y, &buffer->idct_y);
-   vl_idct_cleanup_buffer(&renderer->idct_cb, &buffer->idct_cb);
-   vl_idct_cleanup_buffer(&renderer->idct_cr, &buffer->idct_cr);
-
    pipe_surface_reference(&buffer->surface, NULL);
    pipe_surface_reference(&buffer->past, NULL);
    pipe_surface_reference(&buffer->future, NULL);
 }
 
 void
-vl_mpeg12_mc_map_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
+vl_mpeg12_mc_set_surfaces(struct vl_mpeg12_mc_renderer *renderer,
+                          struct vl_mpeg12_mc_buffer *buffer,
+                          struct pipe_surface *surface,
+                          struct pipe_surface *past,
+                          struct pipe_surface *future,
+                          struct pipe_fence_handle **fence)
 {
    assert(renderer && buffer);
-
-   vl_idct_map_buffers(&renderer->idct_y, &buffer->idct_y);
-   vl_idct_map_buffers(&renderer->idct_cr, &buffer->idct_cr);
-   vl_idct_map_buffers(&renderer->idct_cb, &buffer->idct_cb);
-}
-
-void
-vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer *renderer,
-                                         struct vl_mpeg12_mc_buffer *buffer,
-                                         struct pipe_surface *surface,
-                                         struct pipe_surface *past,
-                                         struct pipe_surface *future,
-                                         unsigned num_macroblocks,
-                                         struct pipe_mpeg12_macroblock *mpeg12_macroblocks,
-                                         struct pipe_fence_handle **fence)
-{
-   unsigned i;
-
-   assert(renderer && buffer);
    assert(surface);
-   assert(num_macroblocks);
-   assert(mpeg12_macroblocks);
 
    if (surface != buffer->surface) {
       pipe_surface_reference(&buffer->surface, surface);
@@ -795,23 +651,6 @@ vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer *renderer,
       assert(buffer->past == past);
       assert(buffer->future == future);
    }
-
-   for (i = 0; i < num_macroblocks; ++i) {
-      struct pipe_mpeg12_macroblock *mb = &mpeg12_macroblocks[i];
-
-      assert(mb->base.codec == PIPE_VIDEO_CODEC_MPEG12);
-      grab_blocks(renderer, buffer, mb->mbx, mb->mby, mb->cbp, mb->blocks);
-   }
-}
-
-void
-vl_mpeg12_mc_unmap_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
-{
-   assert(renderer && buffer);
-
-   vl_idct_unmap_buffers(&renderer->idct_y, &buffer->idct_y);
-   vl_idct_unmap_buffers(&renderer->idct_cr, &buffer->idct_cr);
-   vl_idct_unmap_buffers(&renderer->idct_cb, &buffer->idct_cb);
 }
 
 void
@@ -824,10 +663,6 @@ vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mp
    if (not_empty_num_instances == 0 && empty_num_instances == 0)
       return;
 
-   vl_idct_flush(&renderer->idct_y, &buffer->idct_y, not_empty_num_instances);
-   vl_idct_flush(&renderer->idct_cr, &buffer->idct_cr, not_empty_num_instances);
-   vl_idct_flush(&renderer->idct_cb, &buffer->idct_cb, not_empty_num_instances);
-
    renderer->fb_state.cbufs[0] = buffer->surface;
    renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state);
    renderer->pipe->set_framebuffer_state(renderer->pipe, &renderer->fb_state);
index 86a6518..db8f2ff 100644 (file)
@@ -50,8 +50,6 @@ struct vl_mpeg12_mc_renderer
    struct pipe_viewport_state viewport;
    struct pipe_framebuffer_state fb_state;
 
-   struct vl_idct idct_y, idct_cr, idct_cb;
-
    void *rs_state;
 
    void *vs, *fs;
@@ -67,8 +65,6 @@ struct vl_mpeg12_mc_renderer
 
 struct vl_mpeg12_mc_buffer
 {
-   struct vl_idct_buffer idct_y, idct_cb, idct_cr;
-
    union
    {
       struct pipe_sampler_view *all[5];
@@ -93,22 +89,17 @@ bool vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
 
 void vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer);
 
-bool vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer);
+bool vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
+                              struct pipe_resource *y, struct pipe_resource *cr, struct pipe_resource *cb);
 
 void vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer);
 
-void vl_mpeg12_mc_map_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer);
-
-void vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer *renderer,
-                                              struct vl_mpeg12_mc_buffer *buffer,
-                                              struct pipe_surface *surface,
-                                              struct pipe_surface *past,
-                                              struct pipe_surface *future,
-                                              unsigned num_macroblocks,
-                                              struct pipe_mpeg12_macroblock *mpeg12_macroblocks,
-                                              struct pipe_fence_handle **fence);
-
-void vl_mpeg12_mc_unmap_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer);
+void vl_mpeg12_mc_set_surfaces(struct vl_mpeg12_mc_renderer *renderer,
+                               struct vl_mpeg12_mc_buffer *buffer,
+                               struct pipe_surface *surface,
+                               struct pipe_surface *past,
+                               struct pipe_surface *future,
+                               struct pipe_fence_handle **fence);
 
 void vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
                                  unsigned not_empty_start_instance, unsigned not_empty_num_instances,
index e733399..32398e4 100644 (file)
@@ -29,6 +29,7 @@
 #include "util/u_memory.h"
 
 #include "sp_video_context.h"
+#include <pipe/p_shader_tokens.h>
 #include <util/u_inlines.h>
 #include <util/u_memory.h>
 #include <util/u_keymap.h>
@@ -40,6 +41,8 @@
 
 #define MACROBLOCK_WIDTH 16
 #define MACROBLOCK_HEIGHT 16
+#define BLOCK_WIDTH 8
+#define BLOCK_HEIGHT 8
 
 #define NUM_BUFFERS 2
 
@@ -52,12 +55,19 @@ flush_buffer(struct sp_mpeg12_context *ctx)
    if(ctx->cur_buffer != NULL) {
 
       vl_vb_unmap(&ctx->cur_buffer->vertex_stream, ctx->pipe);
-      vl_mpeg12_mc_unmap_buffer(&ctx->mc_renderer, &ctx->cur_buffer->mc);
-      vl_vb_restart(&ctx->cur_buffer->vertex_stream, &ne_start, &ne_num, &e_start, &e_num);
+      vl_idct_unmap_buffers(&ctx->idct_y, &ctx->cur_buffer->idct_y);
+      vl_idct_unmap_buffers(&ctx->idct_cr, &ctx->cur_buffer->idct_cr);
+      vl_idct_unmap_buffers(&ctx->idct_cb, &ctx->cur_buffer->idct_cb);
+      vl_vb_restart(&ctx->cur_buffer->vertex_stream,
+                   &ne_start, &ne_num, &e_start, &e_num);
 
       ctx->pipe->set_vertex_buffers(ctx->pipe, 2, ctx->cur_buffer->vertex_bufs.all);
       ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->vertex_elems_state);
-      vl_mpeg12_mc_renderer_flush(&ctx->mc_renderer, &ctx->cur_buffer->mc, ne_start, ne_num, e_start, e_num);
+      vl_idct_flush(&ctx->idct_y, &ctx->cur_buffer->idct_y, ne_num);
+      vl_idct_flush(&ctx->idct_cr, &ctx->cur_buffer->idct_cr, ne_num);
+      vl_idct_flush(&ctx->idct_cb, &ctx->cur_buffer->idct_cb, ne_num);
+      vl_mpeg12_mc_renderer_flush(&ctx->mc_renderer, &ctx->cur_buffer->mc,
+                                  ne_start, ne_num, e_start, e_num);
 
       ctx->cur_buffer = NULL;
    }
@@ -66,6 +76,7 @@ flush_buffer(struct sp_mpeg12_context *ctx)
 static void
 rotate_buffer(struct sp_mpeg12_context *ctx)
 {
+   struct pipe_resource *y, *cr, *cb;
    static unsigned key = 0;
    struct sp_mpeg12_buffer *buffer;
 
@@ -87,8 +98,22 @@ rotate_buffer(struct sp_mpeg12_context *ctx)
 
       buffer->vertex_bufs.individual.stream = vl_vb_init(&buffer->vertex_stream, ctx->pipe,
                                                          ctx->vertex_buffer_size);
+      if (!(y = vl_idct_init_buffer(&ctx->idct_y, &buffer->idct_y))) {
+         FREE(buffer);
+         return;
+      }
+
+      if (!(cr = vl_idct_init_buffer(&ctx->idct_cr, &buffer->idct_cr))) {
+         FREE(buffer);
+         return;
+      }
 
-      if(!vl_mpeg12_mc_init_buffer(&ctx->mc_renderer, &buffer->mc)) {
+      if (!(cb = vl_idct_init_buffer(&ctx->idct_cb, &buffer->idct_cb))) {
+         FREE(buffer);
+         return;
+      }
+
+      if(!vl_mpeg12_mc_init_buffer(&ctx->mc_renderer, &buffer->mc, y, cr, cb)) {
          FREE(buffer);
          return;
       }
@@ -101,7 +126,9 @@ rotate_buffer(struct sp_mpeg12_context *ctx)
    ctx->cur_buffer = buffer;
 
    vl_vb_map(&ctx->cur_buffer->vertex_stream, ctx->pipe);
-   vl_mpeg12_mc_map_buffer(&ctx->mc_renderer, &ctx->cur_buffer->mc);
+   vl_idct_map_buffers(&ctx->idct_y, &ctx->cur_buffer->idct_y);
+   vl_idct_map_buffers(&ctx->idct_cr, &ctx->cur_buffer->idct_cr);
+   vl_idct_map_buffers(&ctx->idct_cb, &ctx->cur_buffer->idct_cb);
 }
 
 static void
@@ -118,10 +145,50 @@ delete_buffer(const struct keymap *map,
    assert(user);
 
    vl_vb_cleanup(&buf->vertex_stream);
+   vl_idct_cleanup_buffer(&ctx->idct_y, &buf->idct_y);
+   vl_idct_cleanup_buffer(&ctx->idct_cb, &buf->idct_cb);
+   vl_idct_cleanup_buffer(&ctx->idct_cr, &buf->idct_cr);
    vl_mpeg12_mc_cleanup_buffer(&ctx->mc_renderer, &buf->mc);
 }
 
 static void
+upload_buffer(struct sp_mpeg12_context *ctx,
+              struct sp_mpeg12_buffer *buffer,
+              struct pipe_mpeg12_macroblock *mb)
+{
+   short *blocks;
+   unsigned tb, x, y;
+
+   assert(ctx);
+   assert(buffer);
+   assert(mb);
+
+   blocks = mb->blocks;
+
+   for (y = 0; y < 2; ++y) {
+      for (x = 0; x < 2; ++x, ++tb) {
+         if (mb->cbp & (*ctx->mc_renderer.empty_block_mask)[0][y][x]) {
+            vl_idct_add_block(&buffer->idct_y, mb->mbx * 2 + x, mb->mby * 2 + y, blocks);
+            blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
+         }
+      }
+   }
+
+   /* TODO: Implement 422, 444 */
+   assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
+
+   for (tb = 1; tb < 3; ++tb) {
+      if (mb->cbp & (*ctx->mc_renderer.empty_block_mask)[tb][0][0]) {
+         if(tb == 1)
+            vl_idct_add_block(&buffer->idct_cb, mb->mbx, mb->mby, blocks);
+         else
+            vl_idct_add_block(&buffer->idct_cr, mb->mbx, mb->mby, blocks);
+         blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
+      }
+   }
+}
+
+static void
 sp_mpeg12_destroy(struct pipe_video_context *vpipe)
 {
    struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
@@ -142,6 +209,9 @@ sp_mpeg12_destroy(struct pipe_video_context *vpipe)
    vl_compositor_cleanup(&ctx->compositor);
    util_delete_keymap(ctx->buffer_map, ctx);
    vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
+   vl_idct_cleanup(&ctx->idct_y);
+   vl_idct_cleanup(&ctx->idct_cr);
+   vl_idct_cleanup(&ctx->idct_cb);
    ctx->pipe->delete_vertex_elements_state(ctx->pipe, ctx->vertex_elems_state);
    pipe_resource_reference(&ctx->quads.buffer, NULL);
    ctx->pipe->destroy(ctx->pipe);
@@ -223,14 +293,14 @@ sp_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe,
    assert(ctx->decode_target);
    assert(ctx->cur_buffer);
 
-   for ( i = 0; i < num_macroblocks; ++i )
-      vl_vb_add_block(&ctx->cur_buffer->vertex_stream, &mpeg12_macroblocks[i], ctx->mc_renderer.empty_block_mask);
+   for ( i = 0; i < num_macroblocks; ++i ) {
+      vl_vb_add_block(&ctx->cur_buffer->vertex_stream, &mpeg12_macroblocks[i],
+                      ctx->mc_renderer.empty_block_mask);
+      upload_buffer(ctx, ctx->cur_buffer, &mpeg12_macroblocks[i]);
+   }
 
-   vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer,
-                                            &ctx->cur_buffer->mc,
-                                            ctx->decode_target,
-                                            past, future, num_macroblocks,
-                                            mpeg12_macroblocks, fence);
+   vl_mpeg12_mc_set_surfaces(&ctx->mc_renderer, &ctx->cur_buffer->mc,
+                             ctx->decode_target, past, future, fence);
 }
 
 static void
@@ -541,7 +611,9 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
                  bool pot_buffers,
                  enum pipe_format decode_format)
 {
+   struct pipe_resource *idct_matrix;
    unsigned buffer_width, buffer_height;
+   unsigned chroma_width, chroma_height, chroma_blocks_x, chroma_blocks_y;
    struct sp_mpeg12_context *ctx;
 
    assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
@@ -597,6 +669,38 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
       return NULL;
    }
 
+   if (!(idct_matrix = vl_idct_upload_matrix(ctx->pipe)))
+      return false;
+
+   if (!vl_idct_init(&ctx->idct_y, ctx->pipe, buffer_width, buffer_height,
+                     2, 2, TGSI_SWIZZLE_X, idct_matrix))
+      return false;
+
+   if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
+      chroma_width = buffer_width / 2;
+      chroma_height = buffer_height / 2;
+      chroma_blocks_x = 1;
+      chroma_blocks_y = 1;
+   } else if (chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
+      chroma_width = buffer_width;
+      chroma_height = buffer_height / 2;
+      chroma_blocks_x = 2;
+      chroma_blocks_y = 1;
+   } else {
+      chroma_width = buffer_width;
+      chroma_height = buffer_height;
+      chroma_blocks_x = 2;
+      chroma_blocks_y = 2;
+   }
+
+   if(!vl_idct_init(&ctx->idct_cr, ctx->pipe, chroma_width, chroma_height,
+                    chroma_blocks_x, chroma_blocks_y, TGSI_SWIZZLE_Y, idct_matrix))
+      return false;
+
+   if(!vl_idct_init(&ctx->idct_cb, ctx->pipe, chroma_width, chroma_height,
+                    chroma_blocks_x, chroma_blocks_y, TGSI_SWIZZLE_Z, idct_matrix))
+      return false;
+
    if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
                                    buffer_width, buffer_height, chroma_format)) {
       ctx->pipe->destroy(ctx->pipe);
index 7e04a6d..2e3e4ec 100644 (file)
@@ -47,6 +47,8 @@ struct sp_mpeg12_buffer
       } individual;
    } vertex_bufs;
 
+   struct vl_idct_buffer idct_y, idct_cb, idct_cr;
+
    struct vl_mpeg12_mc_buffer mc;
 };
 
@@ -60,6 +62,7 @@ struct sp_mpeg12_context
    unsigned vertex_buffer_size;
    void *vertex_elems_state;
 
+   struct vl_idct idct_y, idct_cr, idct_cb;
    struct vl_mpeg12_mc_renderer mc_renderer;
 
    struct keymap *buffer_map;