[g3dvl] use blending for mc of ref frames
authorChristian König <deathsimple@vodafone.de>
Thu, 14 Apr 2011 20:31:40 +0000 (22:31 +0200)
committerChristian König <deathsimple@vodafone.de>
Thu, 14 Apr 2011 21:39:27 +0000 (23:39 +0200)
src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
src/gallium/auxiliary/vl/vl_mpeg12_decoder.h
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
src/gallium/auxiliary/vl/vl_types.h
src/gallium/auxiliary/vl/vl_vertex_buffers.c
src/gallium/auxiliary/vl/vl_vertex_buffers.h

index 669d082f873bf103329227b04068fb1701f1fb76..906be3775c4458a7286532e7690d5876f992fbb2 100644 (file)
@@ -193,6 +193,8 @@ vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer *buffer)
 {
    struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
    struct vl_mpeg12_decoder *dec;
+   unsigned i;
+
    assert(buf);
 
    dec = (struct vl_mpeg12_decoder*)buf->base.decoder;
@@ -203,9 +205,8 @@ vl_mpeg12_buffer_destroy(struct pipe_video_decode_buffer *buffer)
 
    buf->mc_source->destroy(buf->mc_source);
    vl_vb_cleanup(&buf->vertex_stream);
-   vl_mpeg12_mc_cleanup_buffer(&buf->mc[0]);
-   vl_mpeg12_mc_cleanup_buffer(&buf->mc[1]);
-   vl_mpeg12_mc_cleanup_buffer(&buf->mc[2]);
+   for (i = 0; i < VL_MAX_PLANES; ++i)
+      vl_mc_cleanup_buffer(&buf->mc[i]);
 
    FREE(buf);
 }
@@ -267,6 +268,7 @@ static void
 vl_mpeg12_destroy(struct pipe_video_decoder *decoder)
 {
    struct vl_mpeg12_decoder *dec = (struct vl_mpeg12_decoder*)decoder;
+   unsigned i;
 
    assert(decoder);
 
@@ -277,14 +279,17 @@ vl_mpeg12_destroy(struct pipe_video_decoder *decoder)
    dec->pipe->delete_blend_state(dec->pipe, dec->blend);
    dec->pipe->delete_depth_stencil_alpha_state(dec->pipe, dec->dsa);
 
-   vl_mpeg12_mc_renderer_cleanup(&dec->mc);
+   vl_mc_cleanup(&dec->mc);
    if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
       vl_idct_cleanup(&dec->idct_y);
       vl_idct_cleanup(&dec->idct_c);
    }
-   dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves[0]);
-   dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves[1]);
-   dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves[2]);
+   for (i = 0; i < VL_MAX_PLANES; ++i)
+      dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_eb[i]);
+
+   for (i = 0; i < 2; ++i)
+      dec->pipe->delete_vertex_elements_state(dec->pipe, dec->ves_mv[i]);
+
    pipe_resource_reference(&dec->quads.buffer, NULL);
 
    FREE(dec);
@@ -409,22 +414,22 @@ vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder)
    if (!mc_source_sv)
       goto error_mc_source_sv;
 
-   if(!vl_mpeg12_mc_init_buffer(&dec->mc, &buffer->mc[0], mc_source_sv[0]))
+   if(!vl_mc_init_buffer(&dec->mc, &buffer->mc[0], mc_source_sv[0]))
       goto error_mc_y;
 
-   if(!vl_mpeg12_mc_init_buffer(&dec->mc, &buffer->mc[1], mc_source_sv[1]))
+   if(!vl_mc_init_buffer(&dec->mc, &buffer->mc[1], mc_source_sv[1]))
       goto error_mc_cb;
 
-   if(!vl_mpeg12_mc_init_buffer(&dec->mc, &buffer->mc[2], mc_source_sv[2]))
+   if(!vl_mc_init_buffer(&dec->mc, &buffer->mc[2], mc_source_sv[2]))
       goto error_mc_cr;
 
    return &buffer->base;
 
 error_mc_cr:
-   vl_mpeg12_mc_cleanup_buffer(&buffer->mc[1]);
+   vl_mc_cleanup_buffer(&buffer->mc[1]);
 
 error_mc_cb:
-   vl_mpeg12_mc_cleanup_buffer(&buffer->mc[0]);
+   vl_mc_cleanup_buffer(&buffer->mc[0]);
 
 error_mc_y:
 error_mc_source_sv:
@@ -451,20 +456,19 @@ vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
    struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer;
    struct vl_mpeg12_decoder *dec;
 
-   struct pipe_sampler_view **sv_past;
-   struct pipe_sampler_view **sv_future;
+   struct pipe_sampler_view **sv[2];
    struct pipe_surface **surfaces;
 
    unsigned ne_start, ne_num, e_start, e_num;
-   unsigned i;
+   unsigned i, j;
 
    assert(buf);
 
    dec = (struct vl_mpeg12_decoder *)buf->base.decoder;
    assert(dec);
 
-   sv_past = refs[0] ? refs[0]->get_sampler_views(refs[0]) : NULL;
-   sv_future = refs[1] ? refs[1]->get_sampler_views(refs[1]) : NULL;
+   for (i = 0; i < 2; ++i)
+      sv[i] = refs[i] ? refs[i]->get_sampler_views(refs[i]) : NULL;
 
    surfaces = dst->get_surfaces(dst);
 
@@ -473,20 +477,28 @@ vl_mpeg12_decoder_flush_buffer(struct pipe_video_decode_buffer *buffer,
    dec->pipe->set_vertex_buffers(dec->pipe, 2, buf->vertex_bufs.all);
 
    for (i = 0; i < VL_MAX_PLANES; ++i) {
-      struct pipe_sampler_view *sv_refs[2];
+      bool first = true;
+
+      vl_mc_set_surface(&dec->mc, surfaces[i]);
+
+      for (j = 0; j < 2; ++j) {
+         if (sv[j] == NULL) continue;
+
+         dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_mv[j]);
+         vl_mc_render_ref(&buf->mc[i], sv[j][i], first, ne_start, ne_num, e_start, e_num);
+         first = false;
+      }
 
       dec->pipe->bind_blend_state(dec->pipe, dec->blend);
-      dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves[i]);
+      dec->pipe->bind_vertex_elements_state(dec->pipe, dec->ves_eb[i]);
 
       if (dec->base.entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT)
          vl_idct_flush(i == 0 ? &dec->idct_y : &dec->idct_c, &buf->idct[i], ne_num);
 
-      sv_refs[0] = sv_past ? sv_past[i] : NULL;
-      sv_refs[1] = sv_future ? sv_future[i] : NULL;
+      vl_mc_render_ycbcr(&buf->mc[i], first, ne_start, ne_num);
 
-      vl_mpeg12_mc_renderer_flush(&dec->mc, &buf->mc[i], surfaces[i], sv_refs,
-                                  ne_start, ne_num, e_start, e_num, fence);
    }
+   dec->pipe->flush(dec->pipe, fence);
 }
 
 static void
@@ -703,7 +715,10 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
 
    dec->quads = vl_vb_upload_quads(dec->pipe, 2, 2);
    for (i = 0; i < VL_MAX_PLANES; ++i)
-      dec->ves[i] = vl_vb_get_elems_state(dec->pipe, i);
+      dec->ves_eb[i] = vl_vb_get_elems_state(dec->pipe, i, 0);
+
+   for (i = 0; i < 2; ++i)
+      dec->ves_mv[i] = vl_vb_get_elems_state(dec->pipe, 0, i);
 
    dec->base.width = align(width, MACROBLOCK_WIDTH);
    dec->base.height = align(height, MACROBLOCK_HEIGHT);
@@ -741,7 +756,7 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
       }
    }
 
-   if (!vl_mpeg12_mc_renderer_init(&dec->mc, dec->pipe, dec->base.width, dec->base.height, mc_scale))
+   if (!vl_mc_init(&dec->mc, dec->pipe, dec->base.width, dec->base.height, mc_scale))
       goto error_mc;
 
    if (!init_pipe_state(dec))
@@ -750,7 +765,7 @@ vl_create_mpeg12_decoder(struct pipe_video_context *context,
    return &dec->base;
 
 error_pipe_state:
-   vl_mpeg12_mc_renderer_cleanup(&dec->mc);
+   vl_mc_cleanup(&dec->mc);
 
 error_mc:
    if (entrypoint <= PIPE_VIDEO_ENTRYPOINT_IDCT) {
index 25048e8543ca75b263d35cbdda24452221bd3ec0..c27197f666481a704190cbc9b51d41b023012993 100644 (file)
@@ -52,7 +52,8 @@ struct vl_mpeg12_decoder
    enum pipe_format mc_source_format;
 
    struct pipe_vertex_buffer quads;
-   void *ves[VL_MAX_PLANES];
+   void *ves_eb[VL_MAX_PLANES];
+   void *ves_mv[2];
 
    struct vl_idct idct_y, idct_c;
    struct vl_mpeg12_mc_renderer mc;
index 0ffb76c6b1cc6d6f006537b71d216f131f48b8dd..dde7846ffb226e82d5c0ef71d53251464122c6cb 100644 (file)
@@ -44,10 +44,8 @@ enum VS_OUTPUT
    VS_O_LINE,
    VS_O_TEX_TOP,
    VS_O_TEX_BOTTOM,
-   VS_O_MV0_TOP,
-   VS_O_MV0_BOTTOM,
-   VS_O_MV1_TOP,
-   VS_O_MV1_BOTTOM
+   VS_O_MV_TOP,
+   VS_O_MV_BOTTOM
 };
 
 static void *
@@ -55,10 +53,10 @@ create_vert_shader(struct vl_mpeg12_mc_renderer *r)
 {
    struct ureg_program *shader;
    struct ureg_src block_scale, mv_scale;
-   struct ureg_src vrect, vpos, eb, flags, vmv[2][2];
+   struct ureg_src vrect, vpos, eb, flags, vmv[2];
    struct ureg_dst t_vpos, t_vtex, t_vmv;
-   struct ureg_dst o_vpos, o_line, o_vtex[2], o_vmv[2][2];
-   unsigned i, j, label;
+   struct ureg_dst o_vpos, o_line, o_vtex[2], o_vmv[2];
+   unsigned i, label;
 
    shader = ureg_create(TGSI_PROCESSOR_VERTEX);
    if (!shader)
@@ -72,19 +70,15 @@ create_vert_shader(struct vl_mpeg12_mc_renderer *r)
    vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);
    eb = ureg_DECL_vs_input(shader, VS_I_EB);
    flags = ureg_DECL_vs_input(shader, VS_I_FLAGS);
-   vmv[0][0] = ureg_DECL_vs_input(shader, VS_I_MV0_TOP);
-   vmv[0][1] = ureg_DECL_vs_input(shader, VS_I_MV0_BOTTOM);
-   vmv[1][0] = ureg_DECL_vs_input(shader, VS_I_MV1_TOP);
-   vmv[1][1] = ureg_DECL_vs_input(shader, VS_I_MV1_BOTTOM);
+   vmv[0] = ureg_DECL_vs_input(shader, VS_I_MV_TOP);
+   vmv[1] = ureg_DECL_vs_input(shader, VS_I_MV_BOTTOM);
 
    o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
    o_line = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE);
    o_vtex[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX_TOP);
    o_vtex[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX_BOTTOM);
-   o_vmv[0][0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0_TOP);
-   o_vmv[0][1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0_BOTTOM);
-   o_vmv[1][0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV1_TOP);
-   o_vmv[1][1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV1_BOTTOM);
+   o_vmv[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV_TOP);
+   o_vmv[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV_BOTTOM);
 
    /*
     * block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height)
@@ -125,20 +119,21 @@ create_vert_shader(struct vl_mpeg12_mc_renderer *r)
       (float)MACROBLOCK_WIDTH / r->buffer_width,
       (float)MACROBLOCK_HEIGHT / r->buffer_height);
 
-   mv_scale = ureg_imm2f(shader,
+   mv_scale = ureg_imm4f(shader,
       0.5f / r->buffer_width,
-      0.5f / r->buffer_height);
+      0.5f / r->buffer_height,
+      1.0f,
+      1.0f / 255.0f);
 
    ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect);
    ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), block_scale);
    ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos));
    ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), vpos);
 
-   for (i = 0; i < 2; ++i)
-      for (j = 0; j < 2; ++j) {
-         ureg_MAD(shader, ureg_writemask(o_vmv[i][j], TGSI_WRITEMASK_XY), mv_scale, vmv[i][j], ureg_src(t_vpos));
-         ureg_MOV(shader, ureg_writemask(o_vmv[i][j], TGSI_WRITEMASK_Z), ureg_scalar(flags, TGSI_SWIZZLE_Z + i));
-      }
+   for (i = 0; i < 2; ++i) {
+      ureg_MAD(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_XY), mv_scale, vmv[i], ureg_src(t_vpos));
+      ureg_MUL(shader, ureg_writemask(o_vmv[i], TGSI_WRITEMASK_W), mv_scale, vmv[i]);
+   }
 
    ureg_MOV(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_XY), ureg_src(t_vpos));
    ureg_CMP(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_Z),
@@ -274,24 +269,19 @@ static void *
 create_ref_frag_shader(struct vl_mpeg12_mc_renderer *r)
 {
    struct ureg_program *shader;
-   struct ureg_src tc[2][2], sampler[2];
-   struct ureg_dst ref[2], field;
+   struct ureg_src tc[2], sampler;
+   struct ureg_dst ref, field;
    struct ureg_dst fragment;
-   unsigned i;
 
    shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
    if (!shader)
       return NULL;
 
-   tc[0][0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0_TOP, TGSI_INTERPOLATE_LINEAR);
-   tc[0][1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0_BOTTOM, TGSI_INTERPOLATE_LINEAR);
-   tc[1][0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV1_TOP, TGSI_INTERPOLATE_LINEAR);
-   tc[1][1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV1_BOTTOM, TGSI_INTERPOLATE_LINEAR);
+   tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV_TOP, TGSI_INTERPOLATE_LINEAR);
+   tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV_BOTTOM, TGSI_INTERPOLATE_LINEAR);
 
-   for (i = 0; i < 2; ++i) {
-      sampler[i] = ureg_DECL_sampler(shader, i);
-      ref[i] = ureg_DECL_temporary(shader);
-   }
+   sampler = ureg_DECL_sampler(shader, 0);
+   ref = ureg_DECL_temporary(shader);
 
    fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
 
@@ -304,29 +294,12 @@ create_ref_frag_shader(struct vl_mpeg12_mc_renderer *r)
     *    ref[0..1] = tex(tc[2..3], sampler[0..1])
     * result = LRP(info.y, ref[0..1])
     */
-   ureg_CMP(shader, ureg_writemask(ref[0], TGSI_WRITEMASK_XY),
-            ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)),
-            tc[0][1], tc[0][0]);
-   ureg_CMP(shader, ureg_writemask(ref[1], TGSI_WRITEMASK_XY),
-            ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)),
-            tc[1][1], tc[1][0]);
+   ureg_CMP(shader, ref, ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)), tc[1], tc[0]);
 
-   ureg_TEX(shader, ref[0], TGSI_TEXTURE_2D, ureg_src(ref[0]), sampler[0]);
-   ureg_TEX(shader, ref[1], TGSI_TEXTURE_2D, ureg_src(ref[1]), sampler[1]);
+   ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_src(ref));
+   ureg_TEX(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), TGSI_TEXTURE_2D, ureg_src(ref), sampler);
 
-   ureg_LRP(shader, ref[0],
-            ureg_scalar(tc[0][0], TGSI_SWIZZLE_Z),
-            ureg_src(ref[0]), ureg_imm1f(shader, 0.0f));
-
-   ureg_LRP(shader, ref[1],
-            ureg_scalar(tc[1][0], TGSI_SWIZZLE_Z),
-            ureg_src(ref[1]), ureg_imm1f(shader, 0.0f));
-
-   ureg_ADD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), ureg_src(ref[0]), ureg_src(ref[1]));
-   ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f));
-
-   for (i = 0; i < 2; ++i)
-      ureg_release_temporary(shader, ref[i]);
+   ureg_release_temporary(shader, ref);
 
    ureg_release_temporary(shader, field);
    ureg_END(shader);
@@ -435,11 +408,8 @@ cleanup_pipe_state(struct vl_mpeg12_mc_renderer *r)
 }
 
 bool
-vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
-                           struct pipe_context *pipe,
-                           unsigned buffer_width,
-                           unsigned buffer_height,
-                           float scale)
+vl_mc_init(struct vl_mpeg12_mc_renderer *renderer, struct pipe_context *pipe,
+           unsigned buffer_width, unsigned buffer_height, float scale)
 {
    struct pipe_resource tex_templ, *tex_dummy;
    struct pipe_sampler_view sampler_view;
@@ -511,7 +481,7 @@ error_pipe_state:
 }
 
 void
-vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer)
+vl_mc_cleanup(struct vl_mpeg12_mc_renderer *renderer)
 {
    assert(renderer);
 
@@ -525,19 +495,21 @@ 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,
-                         struct pipe_sampler_view *source)
+vl_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
+                  struct pipe_sampler_view *source)
 {
    assert(renderer && buffer);
    assert(source);
 
+   buffer->renderer = renderer;
+
    pipe_sampler_view_reference(&buffer->source, source);
 
    return true;
 }
 
 void
-vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer)
+vl_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer)
 {
    assert(buffer);
 
@@ -545,17 +517,9 @@ vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer)
 }
 
 void
-vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
-                            struct pipe_surface *surface, struct pipe_sampler_view *ref[2],
-                            unsigned not_empty_start_instance, unsigned not_empty_num_instances,
-                            unsigned empty_start_instance, unsigned empty_num_instances,
-                            struct pipe_fence_handle **fence)
+vl_mc_set_surface(struct vl_mpeg12_mc_renderer *renderer, struct pipe_surface *surface)
 {
-   assert(renderer && buffer);
-   assert(surface && ref);
-
-   if (not_empty_num_instances == 0 && empty_num_instances == 0)
-      return;
+   assert(renderer && surface);
 
    renderer->viewport.scale[0] = surface->width;
    renderer->viewport.scale[1] = surface->height;
@@ -563,46 +527,65 @@ vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mp
    renderer->fb_state.width = surface->width;
    renderer->fb_state.height = surface->height;
    renderer->fb_state.cbufs[0] = surface;
+}
+
+void
+vl_mc_render_ref(struct vl_mpeg12_mc_buffer *buffer,
+                 struct pipe_sampler_view *ref, bool first,
+                 unsigned not_empty_start_instance, unsigned not_empty_num_instances,
+                 unsigned empty_start_instance, unsigned empty_num_instances)
+{
+   struct vl_mpeg12_mc_renderer *renderer;
+
+   assert(buffer && ref);
+
+   if (not_empty_num_instances == 0 && empty_num_instances == 0)
+      return;
 
+   renderer = buffer->renderer;
    renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state);
    renderer->pipe->set_framebuffer_state(renderer->pipe, &renderer->fb_state);
    renderer->pipe->set_viewport_state(renderer->pipe, &renderer->viewport);
+   renderer->pipe->bind_blend_state(renderer->pipe, first ? renderer->blend_clear : renderer->blend_add);
 
    renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs);
+   renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ref);
 
-   renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_clear);
-   if (ref[0] || ref[1]) {
-      void *samplers[2];
+   renderer->pipe->set_fragment_sampler_views(renderer->pipe, 1, &ref);
+   renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ref);
 
-      renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ref);
+   if (not_empty_num_instances > 0)
+      util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
+                                 not_empty_start_instance, not_empty_num_instances);
 
-      /* if no reference frame provided use a dummy sampler instead */
-      if (!ref[0]) ref[0] = renderer->dummy;
-      if (!ref[1]) ref[1] = renderer->dummy;
+   if (empty_num_instances > 0)
+      util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
+                                 empty_start_instance, empty_num_instances);
+}
 
-      renderer->pipe->set_fragment_sampler_views(renderer->pipe, 2, ref);
+void
+vl_mc_render_ycbcr(struct vl_mpeg12_mc_buffer *buffer, bool first,
+                   unsigned not_empty_start_instance, unsigned not_empty_num_instances)
+{
+   struct vl_mpeg12_mc_renderer *renderer;
 
-      samplers[0] = samplers[1] = renderer->sampler_ref;
-      renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 2, samplers);
+   assert(buffer);
 
-      if (not_empty_num_instances > 0)
-         util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
-                                    not_empty_start_instance, not_empty_num_instances);
+   if (not_empty_num_instances == 0)
+      return;
 
-      if (empty_num_instances > 0)
-         util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
-                                    empty_start_instance, empty_num_instances);
+   renderer = buffer->renderer;
+   renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state);
+   renderer->pipe->set_framebuffer_state(renderer->pipe, &renderer->fb_state);
+   renderer->pipe->set_viewport_state(renderer->pipe, &renderer->viewport);
+   renderer->pipe->bind_blend_state(renderer->pipe, first ? renderer->blend_clear : renderer->blend_add);
 
-      renderer->pipe->bind_blend_state(renderer->pipe, renderer->blend_add);
-   }
+   renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs);
+   renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr);
 
    renderer->pipe->set_fragment_sampler_views(renderer->pipe, 1, &buffer->source);
    renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 1, &renderer->sampler_ycbcr);
-   renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs_ycbcr);
-
-   if (not_empty_num_instances > 0)
-      util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
-                                 not_empty_start_instance, not_empty_num_instances);
 
-   renderer->pipe->flush(renderer->pipe, fence);
+   util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4,
+                              not_empty_start_instance, not_empty_num_instances);
 }
index f71bca5e821b63c5d6acc75552ef09401fb7e0d3..3b5e61df02c8dc2147f61462b18e443072eb96f9 100644 (file)
@@ -55,26 +55,28 @@ struct vl_mpeg12_mc_renderer
 
 struct vl_mpeg12_mc_buffer
 {
+   struct vl_mpeg12_mc_renderer *renderer;
    struct pipe_sampler_view *source;
 };
 
-bool vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
-                                struct pipe_context *pipe,
-                                unsigned picture_width,
-                                unsigned picture_height,
-                                float scale);
+bool vl_mc_init(struct vl_mpeg12_mc_renderer *renderer, struct pipe_context *pipe,
+                unsigned picture_width, unsigned picture_height, float scale);
 
-void vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer);
+void vl_mc_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,
-                              struct pipe_sampler_view *source);
+bool vl_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
+                       struct pipe_sampler_view *source);
 
-void vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer);
+void vl_mc_cleanup_buffer(struct vl_mpeg12_mc_buffer *buffer);
 
-void vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer,
-                                 struct pipe_surface *surface, struct pipe_sampler_view *ref[2],
-                                 unsigned not_empty_start_instance, unsigned not_empty_num_instances,
-                                 unsigned empty_start_instance, unsigned empty_num_instances,
-                                 struct pipe_fence_handle **fence);
+void vl_mc_set_surface(struct vl_mpeg12_mc_renderer *renderer, struct pipe_surface *surface);
+
+void vl_mc_render_ref(struct vl_mpeg12_mc_buffer *buffer,
+                      struct pipe_sampler_view *ref, bool first,
+                      unsigned not_empty_start_instance, unsigned not_empty_num_instances,
+                      unsigned empty_start_instance, unsigned empty_num_instances);
+
+void vl_mc_render_ycbcr(struct vl_mpeg12_mc_buffer *buffer, bool first,
+                        unsigned not_empty_start_instance, unsigned not_empty_num_instances);
 
 #endif /* vl_mpeg12_mc_renderer_h */
index a927e8293493ae64c3ecdd76937e21906a182a5a..27bb69d67bceb17b697970122553ba2f4e10c5ac 100644 (file)
@@ -43,4 +43,9 @@ struct vertex4f
    float x, y, z, w;
 };
 
+struct vertex4s
+{
+   short x, y, z, w;
+};
+
 #endif /* vl_types_h */
index c834042e8ae3fea6d14d8b92792b80ce0c648187..4ec1905af207fb38055bc682ed7810dcc2f668e4 100644 (file)
 struct vl_vertex_stream
 {
    struct vertex2s pos;
-   uint8_t eb[3][2][2];
    uint8_t dct_type_field;
    uint8_t mb_type_intra;
-   uint8_t mv_wheights[2];
-   struct vertex2s mv[4];
+   uint8_t dummy[2];
+   uint8_t eb[3][2][2];
+   struct vertex4s mv[4];
 };
 
 /* vertices for a quad covering a block */
@@ -130,7 +130,7 @@ vl_vb_element_helper(struct pipe_vertex_element* elements, unsigned num_elements
 }
 
 void *
-vl_vb_get_elems_state(struct pipe_context *pipe, int component)
+vl_vb_get_elems_state(struct pipe_context *pipe, int component, int motionvector)
 {
    struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS];
 
@@ -140,25 +140,19 @@ vl_vb_get_elems_state(struct pipe_context *pipe, int component)
    /* Position element */
    vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R16G16_SSCALED;
 
-   /* empty block element of selected component */
-   vertex_elems[VS_I_EB].src_offset = 4 + component * 4;
-   vertex_elems[VS_I_EB].src_format = PIPE_FORMAT_R8G8B8A8_USCALED;
-
    /* flags */
-   vertex_elems[VS_I_FLAGS].src_offset = 16;
    vertex_elems[VS_I_FLAGS].src_format = PIPE_FORMAT_R8G8B8A8_UNORM;
 
-   /* motion vector 0 TOP element */
-   vertex_elems[VS_I_MV0_TOP].src_format = PIPE_FORMAT_R16G16_SSCALED;
-
-   /* motion vector 0 BOTTOM element */
-   vertex_elems[VS_I_MV0_BOTTOM].src_format = PIPE_FORMAT_R16G16_SSCALED;
+   /* empty block element of selected component */
+   vertex_elems[VS_I_EB].src_offset = 8 + component * 4;
+   vertex_elems[VS_I_EB].src_format = PIPE_FORMAT_R8G8B8A8_USCALED;
 
-   /* motion vector 1 TOP element */
-   vertex_elems[VS_I_MV1_TOP].src_format = PIPE_FORMAT_R16G16_SSCALED;
+   /* motion vector TOP element */
+   vertex_elems[VS_I_MV_TOP].src_offset = 20 + motionvector * 16;
+   vertex_elems[VS_I_MV_TOP].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED;
 
-   /* motion vector BOTTOM element */
-   vertex_elems[VS_I_MV1_BOTTOM].src_format = PIPE_FORMAT_R16G16_SSCALED;
+   /* motion vector BOTTOM element */
+   vertex_elems[VS_I_MV_BOTTOM].src_format = PIPE_FORMAT_R16G16B16A16_SSCALED;
 
    vl_vb_element_helper(&vertex_elems[VS_I_VPOS], NUM_VS_INPUTS - 1, 1);
 
@@ -209,33 +203,43 @@ vl_vb_map(struct vl_vertex_buffer *buffer, struct pipe_context *pipe)
 }
 
 static void
-get_motion_vectors(struct pipe_mpeg12_macroblock *mb, struct vertex2s mv[4])
+get_motion_vectors(struct pipe_mpeg12_macroblock *mb, struct vertex4s mv[4])
 {
    if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
       mv[0].x = mv[1].x = mb->mv[0].top.x;
       mv[0].y = mv[1].y = mb->mv[0].top.y;
+      mv[0].z = 0; mv[1].z = 1;
+
       mv[2].x = mv[3].x = mb->mv[1].top.x;
       mv[2].y = mv[3].y = mb->mv[1].top.y;
+      mv[2].z = 0; mv[3].z = 1;
 
    } else {
       mv[0].x = mb->mv[0].top.x;
       mv[0].y = mb->mv[0].top.y - (mb->mv[0].top.y % 4);
+      mv[0].z = mb->mv[0].top.field_select;
 
       mv[1].x = mb->mv[0].bottom.x;
       mv[1].y = mb->mv[0].bottom.y - (mb->mv[0].bottom.y % 4);
+      mv[1].z = mb->mv[0].bottom.field_select;
 
       if (mb->mv[0].top.field_select) mv[0].y += 2;
       if (!mb->mv[0].bottom.field_select) mv[1].y -= 2;
 
       mv[2].x = mb->mv[1].top.x;
       mv[2].y = mb->mv[1].top.y - (mb->mv[1].top.y % 4);
+      mv[2].z = mb->mv[1].top.field_select;
 
       mv[3].x = mb->mv[1].bottom.x;
       mv[3].y = mb->mv[1].bottom.y - (mb->mv[1].bottom.y % 4);
+      mv[3].z = mb->mv[1].bottom.field_select;
 
       if (mb->mv[1].top.field_select) mv[2].y += 2;
       if (!mb->mv[1].bottom.field_select) mv[3].y -= 2;
    }
+
+   mv[0].w = mv[1].w = mb->mv[0].wheight;
+   mv[2].w = mv[3].w = mb->mv[1].wheight;
 }
 
 void
@@ -265,8 +269,6 @@ vl_vb_add_block(struct vl_vertex_buffer *buffer, struct pipe_mpeg12_macroblock *
    stream->dct_type_field = mb->dct_type == PIPE_MPEG12_DCT_TYPE_FIELD;
    stream->mb_type_intra = !mb->dct_intra;
 
-   stream->mv_wheights[0] = mb->mv[0].wheight;
-   stream->mv_wheights[1] = mb->mv[1].wheight;
    get_motion_vectors(mb, stream->mv);
 }
 
index 58b841836d093fde215d047b6fc37350fc179dc9..6cbda7cc9b1dad5a6b1a73c236f4f12539220bda 100644 (file)
@@ -42,12 +42,10 @@ enum VS_INPUT
 {
    VS_I_RECT,
    VS_I_VPOS,
-   VS_I_EB,
    VS_I_FLAGS,
-   VS_I_MV0_TOP,
-   VS_I_MV0_BOTTOM,
-   VS_I_MV1_TOP,
-   VS_I_MV1_BOTTOM,
+   VS_I_EB,
+   VS_I_MV_TOP,
+   VS_I_MV_BOTTOM,
 
    NUM_VS_INPUTS
 };
@@ -66,7 +64,7 @@ struct vl_vertex_buffer
 struct pipe_vertex_buffer vl_vb_upload_quads(struct pipe_context *pipe,
                                              unsigned blocks_x, unsigned blocks_y);
 
-void *vl_vb_get_elems_state(struct pipe_context *pipe, int component);
+void *vl_vb_get_elems_state(struct pipe_context *pipe, int component, int motionvector);
 
 struct pipe_vertex_buffer vl_vb_init(struct vl_vertex_buffer *buffer,
                                      struct pipe_context *pipe,