[g3dvl] rework pot buffer handling and flushing
authorChristian König <deathsimple@vodafone.de>
Mon, 6 Dec 2010 23:29:02 +0000 (00:29 +0100)
committerChristian König <deathsimple@vodafone.de>
Mon, 6 Dec 2010 23:29:02 +0000 (00:29 +0100)
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

index f97bc47a70ab380ec3fe577cdee98595e6d5e7ee..9983b47692d27282524ec763de1ff1b79b7af127 100644 (file)
@@ -519,10 +519,8 @@ init_pipe_state(struct vl_mpeg12_mc_renderer *r)
 
    assert(r);
 
-   r->viewport.scale[0] = r->pot_buffers ?
-      util_next_power_of_two(r->picture_width) : r->picture_width;
-   r->viewport.scale[1] = r->pot_buffers ?
-      util_next_power_of_two(r->picture_height) : r->picture_height;
+   r->viewport.scale[0] = r->buffer_width;
+   r->viewport.scale[1] = r->buffer_height;
    r->viewport.scale[2] = 1;
    r->viewport.scale[3] = 1;
    r->viewport.translate[0] = 0;
@@ -530,10 +528,8 @@ init_pipe_state(struct vl_mpeg12_mc_renderer *r)
    r->viewport.translate[2] = 0;
    r->viewport.translate[3] = 0;
 
-   r->fb_state.width = r->pot_buffers ?
-      util_next_power_of_two(r->picture_width) : r->picture_width;
-   r->fb_state.height = r->pot_buffers ?
-      util_next_power_of_two(r->picture_height) : r->picture_height;
+   r->fb_state.width = r->buffer_width;
+   r->fb_state.height = r->buffer_height;
    r->fb_state.nr_cbufs = 1;
    r->fb_state.zsbuf = NULL;
 
@@ -607,9 +603,9 @@ init_buffers(struct vl_mpeg12_mc_renderer *r)
    struct pipe_sampler_view sampler_view;
 
    const unsigned mbw =
-      align(r->picture_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH;
+      align(r->buffer_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH;
    const unsigned mbh =
-      align(r->picture_height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT;
+      align(r->buffer_height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT;
 
    unsigned i;
 
@@ -624,10 +620,8 @@ init_buffers(struct vl_mpeg12_mc_renderer *r)
    /* 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 = r->pot_buffers ?
-      util_next_power_of_two(r->picture_width) : r->picture_width;
-   template.height0 = r->pot_buffers ?
-      util_next_power_of_two(r->picture_height) : r->picture_height;
+   template.width0 = r->buffer_width;
+   template.height0 = r->buffer_height;
    template.depth0 = 1;
    template.usage = PIPE_USAGE_DYNAMIC;
    template.bind = PIPE_BIND_SAMPLER_VIEW;
@@ -636,17 +630,11 @@ init_buffers(struct vl_mpeg12_mc_renderer *r)
    r->textures.individual.y = r->pipe->screen->resource_create(r->pipe->screen, &template);
 
    if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
-      template.width0 = r->pot_buffers ?
-         util_next_power_of_two(r->picture_width / 2) :
-         r->picture_width / 2;
-      template.height0 = r->pot_buffers ?
-         util_next_power_of_two(r->picture_height / 2) :
-         r->picture_height / 2;
+      template.width0 = r->buffer_width / 2;
+      template.height0 = r->buffer_height / 2;
    }
    else if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422)
-      template.height0 = r->pot_buffers ?
-         util_next_power_of_two(r->picture_height / 2) :
-         r->picture_height / 2;
+      template.height0 = r->buffer_height / 2;
 
    r->textures.individual.cb =
       r->pipe->screen->resource_create(r->pipe->screen, &template);
@@ -941,44 +929,6 @@ flush_mbtype_handler(struct vl_mpeg12_mc_renderer *r, enum VL_MACROBLOCK_TYPE ty
    return num_macroblocks;
 }
 
-static void
-flush(struct vl_mpeg12_mc_renderer *r)
-{
-   unsigned num_verts[VL_NUM_MACROBLOCK_TYPES] = { 0 };
-   unsigned vb_start = 0, i;
-
-   assert(r);
-   assert(r->num_macroblocks == r->macroblocks_per_batch);
-
-   vl_idct_unmap_buffers(&r->idct_y);
-   vl_idct_unmap_buffers(&r->idct_cr);
-   vl_idct_unmap_buffers(&r->idct_cb);
-
-   vl_idct_flush(&r->idct_y);
-   vl_idct_flush(&r->idct_cr);
-   vl_idct_flush(&r->idct_cb);
-
-   upload_vertex_stream(r, num_verts);
-
-   r->pipe->bind_rasterizer_state(r->pipe, r->rs_state);
-   r->pipe->set_framebuffer_state(r->pipe, &r->fb_state);
-   r->pipe->set_viewport_state(r->pipe, &r->viewport);
-
-   for (i = 0; i < VL_NUM_MACROBLOCK_TYPES; ++i) {
-      if (num_verts[i] > 0)
-         vb_start += flush_mbtype_handler(r, i, vb_start, num_verts[i]);
-   }
-
-
-   r->pipe->flush(r->pipe, PIPE_FLUSH_RENDER_CACHE, r->fence);
-
-   vl_idct_map_buffers(&r->idct_y);
-   vl_idct_map_buffers(&r->idct_cr);
-   vl_idct_map_buffers(&r->idct_cb);
-
-   r->num_macroblocks = 0;
-}
-
 static void
 update_render_target(struct vl_mpeg12_mc_renderer *r)
 {
@@ -1190,11 +1140,10 @@ texview_map_delete(const struct keymap *map,
 bool
 vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
                            struct pipe_context *pipe,
-                           unsigned picture_width,
-                           unsigned picture_height,
+                           unsigned buffer_width,
+                           unsigned buffer_height,
                            enum pipe_video_chroma_format chroma_format,
-                           enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
-                           bool pot_buffers)
+                           enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode)
 {
    struct pipe_resource *idct_matrix;
 
@@ -1203,17 +1152,14 @@ vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
 
    /* TODO: Implement other policies */
    assert(bufmode == VL_MPEG12_MC_RENDERER_BUFFER_PICTURE);
-   /* TODO: Non-pot buffers untested, probably doesn't work without changes to texcoord generation, vert shader, etc */
-   assert(pot_buffers);
 
    memset(renderer, 0, sizeof(struct vl_mpeg12_mc_renderer));
 
    renderer->pipe = pipe;
-   renderer->picture_width = picture_width;
-   renderer->picture_height = picture_height;
+   renderer->buffer_width = buffer_width;
+   renderer->buffer_height = buffer_height;
    renderer->chroma_format = chroma_format;
    renderer->bufmode = bufmode;
-   renderer->pot_buffers = pot_buffers;
 
    renderer->texview_map = util_new_keymap(sizeof(struct pipe_surface*), -1,
                                            texview_map_delete);
@@ -1301,16 +1247,13 @@ vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer
 
    if (renderer->surface) {
       if (surface != renderer->surface) {
-         if (renderer->num_macroblocks > 0) {
-            flush(renderer);
-         }
-
          new_surface = true;
-      }
+      } else {
 
-      /* If the surface we're rendering hasn't changed the ref frames shouldn't change. */
-      assert(surface != renderer->surface || renderer->past == past);
-      assert(surface != renderer->surface || renderer->future == future);
+         /* If the surface we're rendering hasn't changed the ref frames shouldn't change. */
+         assert(renderer->past == past);
+         assert(renderer->future == future);
+      }
    }
    else
       new_surface = true;
@@ -1336,7 +1279,8 @@ vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer
       num_macroblocks -= num_to_submit;
 
       if (renderer->num_macroblocks == renderer->macroblocks_per_batch) {
-         flush(renderer);
+         vl_mpeg12_mc_renderer_flush(renderer);
+
          /* Next time we get this surface it may have new ref frames */
          pipe_surface_reference(&renderer->surface, NULL);
          pipe_surface_reference(&renderer->past, NULL);
@@ -1344,3 +1288,43 @@ vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer
       }
    }
 }
+
+void
+vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer)
+{
+   unsigned num_verts[VL_NUM_MACROBLOCK_TYPES] = { 0 };
+   unsigned vb_start = 0, i;
+
+   assert(renderer);
+   assert(renderer->num_macroblocks <= renderer->macroblocks_per_batch);
+
+   if (renderer->num_macroblocks == 0)
+      return;
+
+   vl_idct_unmap_buffers(&renderer->idct_y);
+   vl_idct_unmap_buffers(&renderer->idct_cr);
+   vl_idct_unmap_buffers(&renderer->idct_cb);
+
+   vl_idct_flush(&renderer->idct_y);
+   vl_idct_flush(&renderer->idct_cr);
+   vl_idct_flush(&renderer->idct_cb);
+
+   upload_vertex_stream(renderer, num_verts);
+
+   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);
+
+   for (i = 0; i < VL_NUM_MACROBLOCK_TYPES; ++i) {
+      if (num_verts[i] > 0)
+         vb_start += flush_mbtype_handler(renderer, i, vb_start, num_verts[i]);
+   }
+
+   renderer->pipe->flush(renderer->pipe, PIPE_FLUSH_RENDER_CACHE, renderer->fence);
+
+   vl_idct_map_buffers(&renderer->idct_y);
+   vl_idct_map_buffers(&renderer->idct_cr);
+   vl_idct_map_buffers(&renderer->idct_cb);
+
+   renderer->num_macroblocks = 0;
+}
index fb169c7421e4e39451cd5acd5d7f883550a6fece..0f110c0df356db79a896aec9eab41c720b222594 100644 (file)
@@ -71,11 +71,10 @@ struct vl_mc_mbtype_handler
 struct vl_mpeg12_mc_renderer
 {
    struct pipe_context *pipe;
-   unsigned picture_width;
-   unsigned picture_height;
+   unsigned buffer_width;
+   unsigned buffer_height;
    enum pipe_video_chroma_format chroma_format;
    enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode;
-   bool pot_buffers;
    unsigned macroblocks_per_batch;
 
    struct pipe_viewport_state viewport;
@@ -126,8 +125,7 @@ bool vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
                                 unsigned picture_width,
                                 unsigned picture_height,
                                 enum pipe_video_chroma_format chroma_format,
-                                enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
-                                bool pot_buffers);
+                                enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode);
 
 void vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer);
 
@@ -139,4 +137,6 @@ void vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer *rend
                                               struct pipe_mpeg12_macroblock *mpeg12_macroblocks,
                                               struct pipe_fence_handle **fence);
 
+void vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer);
+
 #endif /* vl_mpeg12_mc_renderer_h */
index 3edab82367715af1035352e91c45d835a7e1b773..35636d8475c366556d1aec21ac05aaf605e5d39c 100644 (file)
@@ -282,6 +282,8 @@ sp_mpeg12_render_picture(struct pipe_video_context     *vpipe,
    assert(dst_surface);
    assert(dst_area);
 
+   vl_mpeg12_mc_renderer_flush(&ctx->mc_renderer);
+
    vl_compositor_render(&ctx->compositor, src_surface,
                         picture_type, src_area, dst_surface, dst_area, fence);
 }
@@ -325,7 +327,10 @@ sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe,
    assert(vpipe);
    assert(dt);
 
-   pipe_surface_reference(&ctx->decode_target, dt);
+   if (ctx->decode_target != dt) {
+      vl_mpeg12_mc_renderer_flush(&ctx->mc_renderer);
+      pipe_surface_reference(&ctx->decode_target, dt);
+   }
 }
 
 static void
@@ -426,6 +431,7 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
                  bool pot_buffers,
                  enum pipe_format decode_format)
 {
+   unsigned buffer_width, buffer_height;
    struct sp_mpeg12_context *ctx;
 
    assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
@@ -435,6 +441,12 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
    if (!ctx)
       return NULL;
 
+   /* TODO: Non-pot buffers untested, probably doesn't work without changes to texcoord generation, vert shader, etc */
+   assert(pot_buffers);
+
+   buffer_width = pot_buffers ? util_next_power_of_two(width) : width; 
+   buffer_height = pot_buffers ? util_next_power_of_two(height) : height; 
+
    ctx->base.profile = profile;
    ctx->base.chroma_format = chroma_format;
    ctx->base.width = width;
@@ -464,8 +476,8 @@ sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
    ctx->decode_format = decode_format;
 
    if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
-                                   width, height, chroma_format,
-                                   bufmode, pot_buffers)) {
+                                   buffer_width, buffer_height, chroma_format,
+                                   bufmode)) {
       ctx->pipe->destroy(ctx->pipe);
       FREE(ctx);
       return NULL;