commit d4b63e6a92660f487d631c8a0f5319d2bd5817d6
Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>
Date:   Wed Nov 4 13:36:39 2009 +0000

    [G45] Implement vaPutImage() for full-sized surface uploads.

diff --git a/i965_drv_video/i965_drv_video.c b/i965_drv_video/i965_drv_video.c
index 8dfb39e..6696728 100644
--- a/i965_drv_video/i965_drv_video.c
+++ b/i965_drv_video/i965_drv_video.c
@@ -457,22 +457,6 @@ i965_QueryImageFormats(VADriverContextP ctx,
 }
 
 VAStatus 
-i965_PutImage(VADriverContextP ctx,
-              VASurfaceID surface,
-              VAImageID image,
-              int src_x,
-              int src_y,
-              unsigned int src_width,
-              unsigned int src_height,
-              int dest_x,
-              int dest_y,
-              unsigned int dest_width,
-              unsigned int dest_height)
-{
-    return VA_STATUS_SUCCESS;
-}
-
-VAStatus 
 i965_QuerySubpictureFormats(VADriverContextP ctx,
                             VAImageFormat *format_list,         /* out */
                             unsigned int *flags,                /* out */
@@ -1649,6 +1633,80 @@ i965_GetImage(VADriverContextP ctx,
 }
 
 VAStatus 
+i965_PutImage(VADriverContextP ctx,
+               VASurfaceID surface,
+               VAImageID image,
+               int src_x,
+               int src_y,
+               unsigned int src_width,
+               unsigned int src_height,
+               int dest_x,
+               int dest_y,
+               unsigned int dest_width,
+               unsigned int dest_height)
+{
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+    struct i965_render_state *render_state = &i965->render_state;
+
+    struct object_surface *obj_surface = SURFACE(surface);
+    if (!obj_surface)
+        return VA_STATUS_ERROR_INVALID_SURFACE;
+
+    struct object_image *obj_image = IMAGE(image);
+    if (!obj_image)
+        return VA_STATUS_ERROR_INVALID_IMAGE;
+
+    /* XXX: we don't support partial video surface updates */
+    if (src_x != 0 ||
+        src_y != 0 ||
+        src_width != obj_image->image.width ||
+        src_height != obj_image->image.height)
+        return VA_STATUS_ERROR_OPERATION_FAILED;
+    if (dest_x != 0 ||
+        dest_y != 0 ||
+        dest_width != obj_surface->width ||
+        dest_height != obj_surface->height)
+        return VA_STATUS_ERROR_OPERATION_FAILED;
+    if (src_width != dest_width ||
+        src_height != dest_height)
+        return VA_STATUS_ERROR_OPERATION_FAILED;
+
+    VAStatus va_status;
+    void *image_data = NULL;
+
+    va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
+    if (va_status != VA_STATUS_SUCCESS)
+        return va_status;
+
+    dri_bo_map(obj_surface->bo, 1);
+
+    switch (obj_image->image.format.fourcc) {
+    case VA_FOURCC('Y','V','1','2'):
+    case VA_FOURCC('I','4','2','0'):
+        /* I420 is native format for MPEG-2 decoded surfaces */
+        if (render_state->interleaved_uv)
+            goto operation_failed;
+        memcpy(obj_surface->bo->virtual, image_data, obj_surface->bo->size);
+        break;
+    case VA_FOURCC('N','V','1','2'):
+        /* NV12 is native format for H.264 decoded surfaces */
+        if (!render_state->interleaved_uv)
+            goto operation_failed;
+        memcpy(obj_surface->bo->virtual, image_data, obj_surface->bo->size);
+        break;
+    default:
+    operation_failed:
+        va_status = VA_STATUS_ERROR_OPERATION_FAILED;
+        break;
+    }
+
+    dri_bo_unmap(obj_surface->bo);
+
+    i965_UnmapBuffer(ctx, obj_image->image.buf);
+    return va_status;
+}
+
+VAStatus 
 i965_PutSurface(VADriverContextP ctx,
                 VASurfaceID surface,
                 Drawable draw, /* X Drawable */
