[g3dvl] motion type depends on picture structure not dct type
[mesa.git] / src / gallium / state_trackers / xorg / xvmc / surface.c
index a2d71b5c14eb418fad5fe43a63b966cddbe38fcf..9709f2b23737a36d7e62d26d2ca8073ed8423c22 100644 (file)
@@ -72,14 +72,14 @@ static enum pipe_mpeg12_picture_type PictureToPipe(int xvmc_pic)
    return -1;
 }
 
-static enum pipe_mpeg12_motion_type MotionToPipe(int xvmc_motion_type, int xvmc_dct_type)
+static enum pipe_mpeg12_motion_type MotionToPipe(int xvmc_motion_type, unsigned int xvmc_picture_structure)
 {
    switch (xvmc_motion_type) {
       case XVMC_PREDICTION_FRAME:
-         if (xvmc_dct_type == XVMC_DCT_TYPE_FIELD)
-            return PIPE_MPEG12_MOTION_TYPE_16x8;
-         else if (xvmc_dct_type == XVMC_DCT_TYPE_FRAME)
+         if (xvmc_picture_structure == XVMC_FRAME_PICTURE)
             return PIPE_MPEG12_MOTION_TYPE_FRAME;
+         else
+            return PIPE_MPEG12_MOTION_TYPE_16x8;
          break;
       case XVMC_PREDICTION_FIELD:
          return PIPE_MPEG12_MOTION_TYPE_FIELD;
@@ -89,18 +89,19 @@ static enum pipe_mpeg12_motion_type MotionToPipe(int xvmc_motion_type, int xvmc_
          assert(0);
    }
 
-   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized motion type 0x%08X (with DCT type 0x%08X).\n", xvmc_motion_type, xvmc_dct_type);
+   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized motion type 0x%08X (with picture structure 0x%08X).\n", xvmc_motion_type, xvmc_picture_structure);
 
    return -1;
 }
 
+#if 0
 static bool
 CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned int height,
                          struct pipe_surface **backbuffer)
 {
    struct pipe_video_context *vpipe;
-   struct pipe_texture template;
-   struct pipe_texture *tex;
+   struct pipe_resource template;
+   struct pipe_resource *tex;
 
    assert(vctx);
 
@@ -113,23 +114,24 @@ CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned i
          return true;
    }
 
-   memset(&template, 0, sizeof(struct pipe_texture));
+   memset(&template, 0, sizeof(struct pipe_resource));
    template.target = PIPE_TEXTURE_2D;
    template.format = vctx->vscreen->format;
    template.last_level = 0;
    template.width0 = width;
    template.height0 = height;
    template.depth0 = 1;
-   template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+   template.usage = PIPE_USAGE_DEFAULT;
+   template.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_BLIT_SOURCE;
+   template.flags = 0;
 
-   tex = vpipe->screen->texture_create(vpipe->screen, &template);
+   tex = vpipe->screen->resource_create(vpipe->screen, &template);
    if (!tex)
       return false;
 
    *backbuffer = vpipe->screen->get_tex_surface(vpipe->screen, tex, 0, 0, 0,
-                                                PIPE_BUFFER_USAGE_GPU_READ |
-                                                PIPE_BUFFER_USAGE_GPU_WRITE);
-   pipe_texture_reference(&tex, NULL);
+                                                template.bind);
+   pipe_resource_reference(&tex, NULL);
 
    if (!*backbuffer)
       return false;
@@ -140,9 +142,11 @@ CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned i
 
    return true;
 }
+#endif
 
 static void
 MacroBlocksToPipe(struct pipe_screen *screen,
+                  unsigned int xvmc_picture_structure,
                   const XvMCMacroBlockArray *xvmc_macroblocks,
                   const XvMCBlockArray *xvmc_blocks,
                   unsigned int first_macroblock,
@@ -165,7 +169,7 @@ MacroBlocksToPipe(struct pipe_screen *screen,
       pipe_macroblocks->mby = xvmc_mb->y;
       pipe_macroblocks->mb_type = TypeToPipe(xvmc_mb->macroblock_type);
       if (pipe_macroblocks->mb_type != PIPE_MPEG12_MACROBLOCK_TYPE_INTRA)
-         pipe_macroblocks->mo_type = MotionToPipe(xvmc_mb->motion_type, xvmc_mb->dct_type);
+         pipe_macroblocks->mo_type = MotionToPipe(xvmc_mb->motion_type, xvmc_picture_structure);
       /* Get rid of Valgrind 'undefined' warnings */
       else
          pipe_macroblocks->mo_type = -1;
@@ -178,21 +182,21 @@ MacroBlocksToPipe(struct pipe_screen *screen,
                pipe_macroblocks->pmv[j][k][l] = xvmc_mb->PMV[j][k][l];
 
       pipe_macroblocks->cbp = xvmc_mb->coded_block_pattern;
-      pipe_macroblocks->blocks = pipe_user_buffer_create(screen, xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES,
-                                                         BLOCK_SIZE_BYTES);
+      pipe_macroblocks->blocks = xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES;
 
       ++pipe_macroblocks;
       ++xvmc_mb;
    }
 }
 
+PUBLIC
 Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surface)
 {
    XvMCContextPrivate *context_priv;
    struct pipe_video_context *vpipe;
    XvMCSurfacePrivate *surface_priv;
-   struct pipe_texture template;
-   struct pipe_texture *vsfc_tex;
+   struct pipe_resource template;
+   struct pipe_resource *vsfc_tex;
    struct pipe_surface *vsfc;
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Creating surface %p.\n", surface);
@@ -211,25 +215,36 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac
    if (!surface_priv)
       return BadAlloc;
 
-   memset(&template, 0, sizeof(struct pipe_texture));
+   memset(&template, 0, sizeof(struct pipe_resource));
    template.target = PIPE_TEXTURE_2D;
-   /* XXX: Let the pipe_video_context choose whatever format it likes to render to */
-   template.format = PIPE_FORMAT_AYUV;
+   template.format = (enum pipe_format)vpipe->get_param(vpipe, PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT);
    template.last_level = 0;
-   /* XXX: vl_mpeg12_mc_renderer expects this when it's initialized with pot_buffers=true, clean this up */
-   template.width0 = util_next_power_of_two(context->width);
-   template.height0 = util_next_power_of_two(context->height);
+   if (vpipe->is_format_supported(vpipe, template.format,
+                                  PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
+                                  PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)) {
+      template.width0 = context->width;
+      template.height0 = context->height;
+   }
+   else {
+      assert(vpipe->is_format_supported(vpipe, template.format,
+                                       PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
+                                       PIPE_TEXTURE_GEOM_NON_SQUARE));
+      template.width0 = util_next_power_of_two(context->width);
+      template.height0 = util_next_power_of_two(context->height);
+   }
    template.depth0 = 1;
-   template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_RENDER_TARGET;
-   vsfc_tex = vpipe->screen->texture_create(vpipe->screen, &template);
+   template.usage = PIPE_USAGE_DEFAULT;
+   template.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
+   template.flags = 0;
+   vsfc_tex = vpipe->screen->resource_create(vpipe->screen, &template);
    if (!vsfc_tex) {
       FREE(surface_priv);
       return BadAlloc;
    }
 
    vsfc = vpipe->screen->get_tex_surface(vpipe->screen, vsfc_tex, 0, 0, 0,
-                                         PIPE_BUFFER_USAGE_GPU_READ_WRITE);
-   pipe_texture_reference(&vsfc_tex, NULL);
+                                         PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET);
+   pipe_resource_reference(&vsfc_tex, NULL);
    if (!vsfc) {
       FREE(surface_priv);
       return BadAlloc;
@@ -252,6 +267,7 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac
    return Success;
 }
 
+PUBLIC
 Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int picture_structure,
                          XvMCSurface *target_surface, XvMCSurface *past_surface, XvMCSurface *future_surface,
                          unsigned int flags, unsigned int num_macroblocks, unsigned int first_macroblock,
@@ -267,7 +283,6 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
    XvMCSurfacePrivate *past_surface_priv;
    XvMCSurfacePrivate *future_surface_priv;
    struct pipe_mpeg12_macroblock pipe_macroblocks[num_macroblocks];
-   unsigned int i;
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Rendering to surface %p.\n", target_surface);
 
@@ -313,21 +328,19 @@ Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int pictur
    p_vsfc = past_surface ? past_surface_priv->pipe_vsfc : NULL;
    f_vsfc = future_surface ? future_surface_priv->pipe_vsfc : NULL;
 
-   MacroBlocksToPipe(vpipe->screen, macroblocks, blocks, first_macroblock,
+   MacroBlocksToPipe(vpipe->screen, picture_structure, macroblocks, blocks, first_macroblock,
                      num_macroblocks, pipe_macroblocks);
 
    vpipe->set_decode_target(vpipe, t_vsfc);
    vpipe->decode_macroblocks(vpipe, p_vsfc, f_vsfc, num_macroblocks,
-                             &pipe_macroblocks->base, target_surface_priv->render_fence);
-
-   for (i = 0; i < num_macroblocks; ++i)
-      vpipe->screen->buffer_destroy(pipe_macroblocks[i].blocks);
+                             &pipe_macroblocks->base, &target_surface_priv->render_fence);
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface);
 
    return Success;
 }
 
+PUBLIC
 Status XvMCFlushSurface(Display *dpy, XvMCSurface *surface)
 {
    assert(dpy);
@@ -338,6 +351,7 @@ Status XvMCFlushSurface(Display *dpy, XvMCSurface *surface)
    return Success;
 }
 
+PUBLIC
 Status XvMCSyncSurface(Display *dpy, XvMCSurface *surface)
 {
    assert(dpy);
@@ -348,16 +362,12 @@ Status XvMCSyncSurface(Display *dpy, XvMCSurface *surface)
    return Success;
 }
 
+PUBLIC
 Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
                       short srcx, short srcy, unsigned short srcw, unsigned short srch,
                       short destx, short desty, unsigned short destw, unsigned short desth,
                       int flags)
 {
-   Window root;
-   int x, y;
-   unsigned int width, height;
-   unsigned int border_width;
-   unsigned int depth;
    struct pipe_video_context *vpipe;
    XvMCSurfacePrivate *surface_priv;
    XvMCContextPrivate *context_priv;
@@ -365,6 +375,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
    XvMCContext *context;
    struct pipe_video_rect src_rect = {srcx, srcy, srcw, srch};
    struct pipe_video_rect dst_rect = {destx, desty, destw, desth};
+   struct pipe_surface *drawable_surface;
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Displaying surface %p.\n", surface);
 
@@ -373,7 +384,12 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
    if (!surface || !surface->privData)
       return XvMCBadSurface;
 
-   if (XGetGeometry(dpy, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
+   surface_priv = surface->privData;
+   context = surface_priv->context;
+   context_priv = context->privData;
+
+   drawable_surface = vl_drawable_surface_get(context_priv->vctx->vscreen, drawable);
+   if (!drawable_surface)
       return BadDrawable;
 
    assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE);
@@ -387,18 +403,17 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
     * until the app updates destw and desth.
     */
    /*
-   assert(destx + destw - 1 < width);
-   assert(desty + desth - 1 < height);
+   assert(destx + destw - 1 < drawable_surface->width);
+   assert(desty + desth - 1 < drawable_surface->height);
     */
 
-   surface_priv = surface->privData;
-   context = surface_priv->context;
-   context_priv = context->privData;
    subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL;
    vpipe = context_priv->vctx->vpipe;
 
+#if 0
    if (!CreateOrResizeBackBuffer(context_priv->vctx, width, height, &context_priv->backbuffer))
       return BadAlloc;
+#endif
 
    if (subpicture_priv) {
       struct pipe_video_rect src_rect = {surface_priv->subx, surface_priv->suby, surface_priv->subw, surface_priv->subh};
@@ -409,7 +424,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
       XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture);
 
       assert(subpicture_priv->surface == surface);
-      vpipe->set_picture_layers(vpipe, &subpicture_priv->sfc, &src_rects, &dst_rects, 1);
+      vpipe->set_picture_layers(vpipe, &subpicture_priv->sfc, src_rects, dst_rects, 1);
 
       surface_priv->subpicture = NULL;
       subpicture_priv->surface = NULL;
@@ -418,24 +433,25 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
       vpipe->set_picture_layers(vpipe, NULL, NULL, NULL, 0);
 
    vpipe->render_picture(vpipe, surface_priv->pipe_vsfc, PictureToPipe(flags), &src_rect,
-                         context_priv->backbuffer, &dst_rect, surface_priv->disp_fence);
+                         drawable_surface, &dst_rect, &surface_priv->disp_fence);
 
    XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display. Pushing to front buffer.\n", surface);
 
-   vl_video_bind_drawable(context_priv->vctx, drawable);
-
    vpipe->screen->flush_frontbuffer
    (
       vpipe->screen,
-      context_priv->backbuffer,
-      vpipe->priv
+      drawable_surface,
+      vl_contextprivate_get(context_priv->vctx, drawable_surface)
    );
 
+   pipe_surface_reference(&drawable_surface, NULL);
+
    XVMC_MSG(XVMC_TRACE, "[XvMC] Pushed surface %p to front buffer.\n", surface);
 
    return Success;
 }
 
+PUBLIC
 Status XvMCGetSurfaceStatus(Display *dpy, XvMCSurface *surface, int *status)
 {
    assert(dpy);
@@ -450,6 +466,7 @@ Status XvMCGetSurfaceStatus(Display *dpy, XvMCSurface *surface, int *status)
    return Success;
 }
 
+PUBLIC
 Status XvMCDestroySurface(Display *dpy, XvMCSurface *surface)
 {
    XvMCSurfacePrivate *surface_priv;
@@ -471,6 +488,7 @@ Status XvMCDestroySurface(Display *dpy, XvMCSurface *surface)
    return Success;
 }
 
+PUBLIC
 Status XvMCHideSurface(Display *dpy, XvMCSurface *surface)
 {
    assert(dpy);