OSDN Git Service

i965_drv_video: update post processing interface
authorXiang, Haihao <haihao.xiang@intel.com>
Tue, 12 Jul 2011 07:28:29 +0000 (15:28 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Tue, 12 Jul 2011 07:30:09 +0000 (15:30 +0800)
Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
i965_drv_video/i965_drv_video.c
i965_drv_video/i965_drv_video.h
i965_drv_video/i965_post_processing.c
i965_drv_video/i965_post_processing.h
i965_drv_video/i965_render.c

index 39ec1ba..26b07a2 100644 (file)
@@ -435,8 +435,6 @@ i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
 
     dri_bo_unreference(obj_surface->bo);
     obj_surface->bo = NULL;
-    dri_bo_unreference(obj_surface->pp_out_bo);
-    obj_surface->pp_out_bo = NULL;
 
     if (obj_surface->free_private_data != NULL) {
         obj_surface->free_private_data(&obj_surface->private_data);
@@ -491,7 +489,6 @@ i965_CreateSurfaces(VADriverContextP ctx,
         obj_surface->flags = SURFACE_REFERENCED;
         obj_surface->fourcc = 0;
         obj_surface->bo = NULL;
-        obj_surface->pp_out_bo = NULL;
         obj_surface->locked_image_id = VA_INVALID_ID;
         obj_surface->private_data = NULL;
         obj_surface->free_private_data = NULL;
index 94e7ed3..fd423bc 100644 (file)
@@ -156,11 +156,6 @@ struct object_surface
     int flags;
     unsigned int fourcc;    
     dri_bo *bo;
-    int pp_out_width;
-    int pp_out_height;
-    int orig_pp_out_width;
-    int orig_pp_out_height;
-    dri_bo *pp_out_bo;
     VAImageID locked_image_id;
     void (*free_private_data)(void **data);
     void *private_data;
index d0ad586..4201d09 100644 (file)
@@ -65,21 +65,21 @@ static const uint32_t pp_nv12_dndi_gen5[][4] = {
 #include "shaders/post_processing/nv12_dndi_nv12.g4b.gen5"
 };
 
-static void pp_null_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
-                               unsigned short srcw, unsigned short srch,
-                               unsigned short destw, unsigned short desth);
-static void pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
-                                   unsigned short srcw, unsigned short srch,
-                                   unsigned short destw, unsigned short desth);
-static void pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
-                                       unsigned short srcw, unsigned short srch,
-                                       unsigned short destw, unsigned short desth);
-static void pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
-                                         unsigned short srcw, unsigned short srch,
-                                         unsigned short destw, unsigned short desth);
-static void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
-                                    unsigned short srcw, unsigned short srch,
-                                    unsigned short destw, unsigned short desth);
+static void pp_null_initialize(VADriverContextP ctx,
+                               VASurfaceID in_surface_id, VASurfaceID out_surface_id,
+                               const VARectangle *src_rect, const VARectangle *dst_rect);
+static void pp_nv12_avs_initialize(VADriverContextP ctx,
+                                   VASurfaceID in_surface_id, VASurfaceID out_surface_id,
+                                   const VARectangle *src_rect, const VARectangle *dst_rect);
+static void pp_nv12_scaling_initialize(VADriverContextP ctx,
+                                       VASurfaceID in_surface_id, VASurfaceID out_surface_id,
+                                       const VARectangle *src_rect, const VARectangle *dst_rect);
+static void pp_nv12_load_save_initialize(VADriverContextP ctx,
+                                         VASurfaceID in_surface_id, VASurfaceID out_surface_id,
+                                         const VARectangle *src_rect, const VARectangle *dst_rect);
+static void pp_nv12_dndi_initialize(VADriverContextP ctx,
+                                    VASurfaceID in_surface_id, VASurfaceID out_surface_id,
+                                    const VARectangle *src_rect, const VARectangle *dst_rect);
 
 static struct pp_module pp_modules_gen5[] = {
     {
@@ -553,24 +553,12 @@ pp_null_set_block_parameter(struct i965_post_processing_context *pp_context, int
 }
 
 static void
-pp_null_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
-                   unsigned short srcw, unsigned short srch,
-                   unsigned short destw, unsigned short desth)
+pp_null_initialize(VADriverContextP ctx, 
+                   VASurfaceID in_surface_id, VASurfaceID out_surface_id,
+                   const VARectangle *src_rect, const VARectangle *dst_rect)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct i965_post_processing_context *pp_context = i965->pp_context;
-    struct object_surface *obj_surface;
-
-    /* surface */
-    obj_surface = SURFACE(surface);
-    dri_bo_unreference(obj_surface->pp_out_bo);
-    obj_surface->pp_out_bo = obj_surface->bo;
-    dri_bo_reference(obj_surface->pp_out_bo);
-    assert(obj_surface->pp_out_bo);
-    obj_surface->pp_out_width = obj_surface->width;
-    obj_surface->pp_out_height = obj_surface->height;
-    obj_surface->orig_pp_out_width = obj_surface->orig_width;
-    obj_surface->orig_pp_out_height = obj_surface->orig_height;
 
     /* private function & data */
     pp_context->pp_x_steps = pp_null_x_steps;
@@ -604,9 +592,9 @@ pp_load_save_set_block_parameter(struct i965_post_processing_context *pp_context
 }
 
 static void
-pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
-                             unsigned short srcw, unsigned short srch,
-                             unsigned short destw, unsigned short desth)
+pp_nv12_load_save_initialize(VADriverContextP ctx,
+                             VASurfaceID in_surface_id, VASurfaceID out_surface_id,
+                             const VARectangle *src_rect, const VARectangle *dst_rect)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct i965_post_processing_context *pp_context = i965->pp_context;
@@ -618,27 +606,15 @@ pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
     int orig_w, orig_h;
     unsigned int tiling, swizzle;
 
-    /* surface */
-    obj_surface = SURFACE(surface);
+    /* source surface */
+    obj_surface = SURFACE(in_surface_id);
     orig_w = obj_surface->orig_width;
     orig_h = obj_surface->orig_height;
     w = obj_surface->width;
     h = obj_surface->height;
-
-    dri_bo_unreference(obj_surface->pp_out_bo);
-    obj_surface->pp_out_bo = dri_bo_alloc(i965->intel.bufmgr,
-                                          "intermediate surface",
-                                          SIZE_YUV420(w, h),
-                                          4096);
-    assert(obj_surface->pp_out_bo);
-    obj_surface->pp_out_width = obj_surface->width;
-    obj_surface->pp_out_height = obj_surface->height;
-    obj_surface->orig_pp_out_width = obj_surface->orig_width;
-    obj_surface->orig_pp_out_height = obj_surface->orig_height;
-
-    /* source Y surface index 1 */
     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
 
+    /* source Y surface index 1 */
     index = 1;
     pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
@@ -696,9 +672,17 @@ pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
                       pp_context->surfaces[index].s_bo);
     dri_bo_unmap(bo);
 
+    /* destination surface */
+    obj_surface = SURFACE(out_surface_id);
+    orig_w = obj_surface->orig_width;
+    orig_h = obj_surface->orig_height;
+    w = obj_surface->width;
+    h = obj_surface->height;
+    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
+
     /* destination Y surface index 7 */
     index = 7;
-    pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo;
+    pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
     bo = dri_bo_alloc(i965->intel.bufmgr, 
                       "surface state", 
@@ -716,6 +700,7 @@ pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
     ss->ss2.width = orig_w / 4 - 1;
     ss->ss2.height = orig_h - 1;
     ss->ss3.pitch = w - 1;
+    pp_set_surface_tiling(ss, tiling);
     dri_bo_emit_reloc(bo,
                       I915_GEM_DOMAIN_RENDER, 
                       I915_GEM_DOMAIN_RENDER,
@@ -726,7 +711,7 @@ pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
 
     /* destination UV surface index 8 */
     index = 8;
-    pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo;
+    pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
     bo = dri_bo_alloc(i965->intel.bufmgr, 
                       "surface state", 
@@ -744,6 +729,7 @@ pp_nv12_load_save_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
     ss->ss2.width = orig_w / 4 - 1;
     ss->ss2.height = orig_h / 2 - 1;
     ss->ss3.pitch = w - 1;
+    pp_set_surface_tiling(ss, tiling);
     dri_bo_emit_reloc(bo,
                       I915_GEM_DOMAIN_RENDER, 
                       I915_GEM_DOMAIN_RENDER,
@@ -780,21 +766,22 @@ pp_scaling_y_steps(void *private_context)
 static int
 pp_scaling_set_block_parameter(struct i965_post_processing_context *pp_context, int x, int y)
 {
+    struct pp_scaling_context *pp_scaling_context = (struct pp_scaling_context *)&pp_context->private_context;
     float src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step;
     float src_y_steping = pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step;
 
-    pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16;
-    pp_inline_parameter.grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8;
-    pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16;
-    pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8;
+    pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = src_x_steping * x * 16 + pp_scaling_context->src_normalized_x;
+    pp_inline_parameter.grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_scaling_context->src_normalized_y;
+    pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16 + pp_scaling_context->dest_x;
+    pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8 + pp_scaling_context->dest_y;
     
     return 0;
 }
 
 static void
-pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
-                           unsigned short srcw, unsigned short srch,
-                           unsigned short destw, unsigned short desth)
+pp_nv12_scaling_initialize(VADriverContextP ctx,
+                           VASurfaceID in_surface_id, VASurfaceID out_surface_id,
+                           const VARectangle *src_rect, const VARectangle *dst_rect)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct i965_post_processing_context *pp_context = i965->pp_context;
@@ -804,37 +791,19 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     struct i965_surface_state *ss;
     dri_bo *bo;
     int index;
-    int w, h;
-    int orig_w, orig_h;
-    int pp_out_w, pp_out_h;
-    int orig_pp_out_w, orig_pp_out_h;
+    int in_w, in_h, in_wpitch, in_hpitch;
+    int out_w, out_h, out_wpitch, out_hpitch;
     unsigned int tiling, swizzle;
 
-    /* surface */
-    obj_surface = SURFACE(surface);
-    orig_w = obj_surface->orig_width;
-    orig_h = obj_surface->orig_height;
-    w = obj_surface->width;
-    h = obj_surface->height;
-
-    orig_pp_out_w = destw;
-    orig_pp_out_h = desth;
-    pp_out_w = ALIGN(orig_pp_out_w, 16);
-    pp_out_h = ALIGN(orig_pp_out_h, 16);
-    dri_bo_unreference(obj_surface->pp_out_bo);
-    obj_surface->pp_out_bo = dri_bo_alloc(i965->intel.bufmgr,
-                                          "intermediate surface",
-                                          SIZE_YUV420(pp_out_w, pp_out_h),
-                                          4096);
-    assert(obj_surface->pp_out_bo);
-    obj_surface->orig_pp_out_width = orig_pp_out_w;
-    obj_surface->orig_pp_out_height = orig_pp_out_h;
-    obj_surface->pp_out_width = pp_out_w;
-    obj_surface->pp_out_height = pp_out_h;
-
-    /* source Y surface index 1 */
+    /* source surface */
+    obj_surface = SURFACE(in_surface_id);
+    in_w = obj_surface->orig_width;
+    in_h = obj_surface->orig_height;
+    in_wpitch = obj_surface->width;
+    in_hpitch = obj_surface->height;
     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
 
+    /* source Y surface index 1 */
     index = 1;
     pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
@@ -851,9 +820,9 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     ss->ss0.surface_type = I965_SURFACE_2D;
     ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM;
     ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset;
-    ss->ss2.width = orig_w - 1;
-    ss->ss2.height = orig_h - 1;
-    ss->ss3.pitch = w - 1;
+    ss->ss2.width = in_w - 1;
+    ss->ss2.height = in_h - 1;
+    ss->ss3.pitch = in_wpitch - 1;
     pp_set_surface_tiling(ss, tiling);
     dri_bo_emit_reloc(bo,
                       I915_GEM_DOMAIN_RENDER, 
@@ -879,22 +848,30 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     memset(ss, 0, sizeof(*ss));
     ss->ss0.surface_type = I965_SURFACE_2D;
     ss->ss0.surface_format = I965_SURFACEFORMAT_R8G8_UNORM;
-    ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + w * h;
-    ss->ss2.width = orig_w / 2 - 1;
-    ss->ss2.height = orig_h / 2 - 1;
-    ss->ss3.pitch = w - 1;
+    ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + in_wpitch * in_hpitch;
+    ss->ss2.width = in_w / 2 - 1;
+    ss->ss2.height = in_h / 2 - 1;
+    ss->ss3.pitch = in_wpitch - 1;
     pp_set_surface_tiling(ss, tiling);
     dri_bo_emit_reloc(bo,
                       I915_GEM_DOMAIN_RENDER, 
                       0,
-                      w * h,
+                      in_wpitch * in_hpitch,
                       offsetof(struct i965_surface_state, ss1),
                       pp_context->surfaces[index].s_bo);
     dri_bo_unmap(bo);
 
+    /* destination surface */
+    obj_surface = SURFACE(out_surface_id);
+    out_w = obj_surface->orig_width;
+    out_h = obj_surface->orig_height;
+    out_wpitch = obj_surface->width;
+    out_hpitch = obj_surface->height;
+    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
+
     /* destination Y surface index 7 */
     index = 7;
-    pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo;
+    pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
     bo = dri_bo_alloc(i965->intel.bufmgr, 
                       "surface state", 
@@ -909,9 +886,10 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     ss->ss0.surface_type = I965_SURFACE_2D;
     ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM;
     ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset;
-    ss->ss2.width = pp_out_w / 4 - 1;
-    ss->ss2.height = pp_out_h - 1;
-    ss->ss3.pitch = pp_out_w - 1;
+    ss->ss2.width = out_w / 4 - 1;
+    ss->ss2.height = out_h - 1;
+    ss->ss3.pitch = out_wpitch - 1;
+    pp_set_surface_tiling(ss, tiling);
     dri_bo_emit_reloc(bo,
                       I915_GEM_DOMAIN_RENDER, 
                       I915_GEM_DOMAIN_RENDER,
@@ -922,7 +900,7 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
 
     /* destination UV surface index 8 */
     index = 8;
-    pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo;
+    pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
     bo = dri_bo_alloc(i965->intel.bufmgr, 
                       "surface state", 
@@ -936,14 +914,15 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     memset(ss, 0, sizeof(*ss));
     ss->ss0.surface_type = I965_SURFACE_2D;
     ss->ss0.surface_format = I965_SURFACEFORMAT_R8G8_UNORM;
-    ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + pp_out_w * pp_out_h;
-    ss->ss2.width = pp_out_w / 4 - 1;
-    ss->ss2.height = pp_out_h / 2 - 1;
-    ss->ss3.pitch = pp_out_w - 1;
+    ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + out_wpitch * out_hpitch;
+    ss->ss2.width = out_w / 4 - 1;
+    ss->ss2.height = out_h / 2 - 1;
+    ss->ss3.pitch = out_wpitch - 1;
+    pp_set_surface_tiling(ss, tiling);
     dri_bo_emit_reloc(bo,
                       I915_GEM_DOMAIN_RENDER, 
                       I915_GEM_DOMAIN_RENDER,
-                      pp_out_w * pp_out_h,
+                      out_wpitch * out_hpitch,
                       offsetof(struct i965_surface_state, ss1),
                       pp_context->surfaces[index].s_bo);
     dri_bo_unmap(bo);
@@ -974,13 +953,18 @@ pp_nv12_scaling_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     pp_context->pp_y_steps = pp_scaling_y_steps;
     pp_context->pp_set_block_parameter = pp_scaling_set_block_parameter;
 
-    pp_scaling_context->dest_w = pp_out_w;
-    pp_scaling_context->dest_h = pp_out_h;
+    pp_scaling_context->dest_x = dst_rect->x;
+    pp_scaling_context->dest_y = dst_rect->y;
+    pp_scaling_context->dest_w = ALIGN(dst_rect->width, 16);
+    pp_scaling_context->dest_h = ALIGN(dst_rect->height, 16);
+    pp_scaling_context->src_normalized_x = (float)src_rect->x / in_w / out_w;
+    pp_scaling_context->src_normalized_y = (float)src_rect->y / in_h / out_h;
+
+    pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / out_h;
 
-    pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step = (float) 1.0 / pp_out_h;
-    pp_inline_parameter.grf5.normalized_video_x_scaling_step = (float) 1.0 / pp_out_w;
-    pp_inline_parameter.grf5.block_count_x = pp_out_w / 16;   /* 1 x N */
-    pp_inline_parameter.grf5.number_blocks = pp_out_w / 16;
+    pp_inline_parameter.grf5.normalized_video_x_scaling_step = (float) src_rect->width / in_w / out_w;
+    pp_inline_parameter.grf5.block_count_x = pp_scaling_context->dest_w / 16;   /* 1 x N */
+    pp_inline_parameter.grf5.number_blocks = pp_scaling_context->dest_w / 16;
     pp_inline_parameter.grf5.block_vertical_mask = 0xff;
     pp_inline_parameter.grf5.block_horizontal_mask = 0xffff;
 }
@@ -1011,7 +995,8 @@ pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int
         pp_inline_parameter.grf6.video_step_delta = 0;
         
         if (x == 0) {
-            pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = (float)(tmp_w - pp_avs_context->dest_w) / tmp_w / 2;
+            pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = (float)(tmp_w - pp_avs_context->dest_w) / tmp_w / 2 +
+                pp_avs_context->src_normalized_x;
         } else {
             src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step;
             video_step_delta = pp_inline_parameter.grf6.video_step_delta;
@@ -1035,7 +1020,7 @@ pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int
 
             if (x == 0) {
                 pp_inline_parameter.grf5.normalized_video_x_scaling_step = 1.0 / pp_avs_context->dest_w;
-                pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = 0.0;
+                pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
             } else {
                 src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step;
                 video_step_delta = pp_inline_parameter.grf6.video_step_delta;
@@ -1051,7 +1036,7 @@ pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int
                 pp_inline_parameter.grf6.video_step_delta = b;
 
                 if (x == 0) {
-                    pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = 0.0;
+                    pp_inline_parameter.grf5.r5_1.source_surface_block_normalized_horizontal_origin = pp_avs_context->src_normalized_x;
                     pp_inline_parameter.grf5.normalized_video_x_scaling_step = a;
                 } else {
                     src_x_steping = pp_inline_parameter.grf5.normalized_video_x_scaling_step;
@@ -1087,17 +1072,17 @@ pp_avs_set_block_parameter(struct i965_post_processing_context *pp_context, int
     }
 
     src_y_steping = pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step;
-    pp_inline_parameter.grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8;
-    pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16;
-    pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8;
+    pp_inline_parameter.grf5.source_surface_block_normalized_vertical_origin = src_y_steping * y * 8 + pp_avs_context->src_normalized_y;
+    pp_inline_parameter.grf5.destination_block_horizontal_origin = x * 16 + pp_avs_context->dest_x;
+    pp_inline_parameter.grf5.destination_block_vertical_origin = y * 8 + pp_avs_context->dest_y;
 
     return 0;
 }
 
 static void
-pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
-                       unsigned short srcw, unsigned short srch,
-                       unsigned short destw, unsigned short desth)
+pp_nv12_avs_initialize(VADriverContextP ctx,
+                       VASurfaceID in_surface_id, VASurfaceID out_surface_id,
+                       const VARectangle *src_rect, const VARectangle *dst_rect)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct i965_post_processing_context *pp_context = i965->pp_context;
@@ -1107,37 +1092,23 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     struct i965_sampler_8x8 *sampler_8x8;
     struct i965_sampler_8x8_state *sampler_8x8_state;
     struct i965_surface_state2 *ss_8x8;
-    dri_bo *bo, *src_bo;
+    dri_bo *bo;
     int index;
-    int w, h;
-    int orig_w, orig_h;
-    int pp_out_w, pp_out_h;
-    int orig_pp_out_w, orig_pp_out_h;
+    int in_w, in_h, in_wpitch, in_hpitch;
+    int out_w, out_h, out_wpitch, out_hpitch;
     unsigned int tiling, swizzle;
 
     /* surface */
-    obj_surface = SURFACE(surface);
-    
-    if (input == 1) {
-        orig_w = obj_surface->orig_pp_out_width;
-        orig_h = obj_surface->orig_pp_out_height;
-        w = obj_surface->pp_out_width;
-        h = obj_surface->pp_out_height;
-        src_bo = obj_surface->pp_out_bo;
-    } else {
-        orig_w = obj_surface->orig_width;
-        orig_h = obj_surface->orig_height;
-        w = obj_surface->width;
-        h = obj_surface->height;
-        src_bo = obj_surface->bo;
-    }
-
-    assert(src_bo);
-    dri_bo_get_tiling(src_bo, &tiling, &swizzle);
+    obj_surface = SURFACE(in_surface_id);
+    in_w = obj_surface->orig_width;
+    in_h = obj_surface->orig_height;
+    in_wpitch = obj_surface->width;
+    in_hpitch = obj_surface->height;
+    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
 
     /* source Y surface index 1 */
     index = 1;
-    pp_context->surfaces[index].s_bo = src_bo;
+    pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
     bo = dri_bo_alloc(i965->intel.bufmgr, 
                       "Y surface state for sample_8x8", 
@@ -1151,10 +1122,10 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     memset(ss_8x8, 0, sizeof(*ss_8x8));
     ss_8x8->ss0.surface_base_address = pp_context->surfaces[index].s_bo->offset;
     ss_8x8->ss1.cbcr_pixel_offset_v_direction = 0;
-    ss_8x8->ss1.width = orig_w - 1;
-    ss_8x8->ss1.height = orig_h - 1;
+    ss_8x8->ss1.width = in_w - 1;
+    ss_8x8->ss1.height = in_h - 1;
     ss_8x8->ss2.half_pitch_for_chroma = 0;
-    ss_8x8->ss2.pitch = w - 1;
+    ss_8x8->ss2.pitch = in_wpitch - 1;
     ss_8x8->ss2.interleave_chroma = 0;
     ss_8x8->ss2.surface_format = SURFACE_FORMAT_Y8_UNORM;
     ss_8x8->ss3.x_offset_for_cb = 0;
@@ -1170,7 +1141,7 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
 
     /* source UV surface index 2 */
     index = 2;
-    pp_context->surfaces[index].s_bo = src_bo;
+    pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
     bo = dri_bo_alloc(i965->intel.bufmgr, 
                       "UV surface state for sample_8x8", 
@@ -1182,12 +1153,12 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     assert(bo->virtual);
     ss_8x8 = bo->virtual;
     memset(ss_8x8, 0, sizeof(*ss_8x8));
-    ss_8x8->ss0.surface_base_address = pp_context->surfaces[index].s_bo->offset + w * h;
+    ss_8x8->ss0.surface_base_address = pp_context->surfaces[index].s_bo->offset + in_wpitch * in_hpitch;
     ss_8x8->ss1.cbcr_pixel_offset_v_direction = 0;
-    ss_8x8->ss1.width = orig_w - 1;
-    ss_8x8->ss1.height = orig_h - 1;
+    ss_8x8->ss1.width = in_w - 1;
+    ss_8x8->ss1.height = in_h - 1;
     ss_8x8->ss2.half_pitch_for_chroma = 0;
-    ss_8x8->ss2.pitch = w - 1;
+    ss_8x8->ss2.pitch = in_wpitch - 1;
     ss_8x8->ss2.interleave_chroma = 1;
     ss_8x8->ss2.surface_format = SURFACE_FORMAT_PLANAR_420_8;
     ss_8x8->ss3.x_offset_for_cb = 0;
@@ -1196,29 +1167,23 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     dri_bo_emit_reloc(bo,
                       I915_GEM_DOMAIN_RENDER, 
                       0,
-                      w * h,
+                      in_wpitch * in_hpitch,
                       offsetof(struct i965_surface_state2, ss0),
                       pp_context->surfaces[index].s_bo);
     dri_bo_unmap(bo);
 
-    orig_pp_out_w = destw;
-    orig_pp_out_h = desth;
-    pp_out_w = ALIGN(orig_pp_out_w, 16);
-    pp_out_h = ALIGN(orig_pp_out_h, 16);
-    dri_bo_unreference(obj_surface->pp_out_bo);
-    obj_surface->pp_out_bo = dri_bo_alloc(i965->intel.bufmgr,
-                                          "intermediate surface",
-                                          SIZE_YUV420(pp_out_w, pp_out_h),
-                                          4096);
-    assert(obj_surface->pp_out_bo);
-    obj_surface->orig_pp_out_width = orig_pp_out_w;
-    obj_surface->orig_pp_out_height = orig_pp_out_h;
-    obj_surface->pp_out_width = pp_out_w;
-    obj_surface->pp_out_height = pp_out_h;
+    /* destination surface */
+    obj_surface = SURFACE(out_surface_id);
+    out_w = obj_surface->orig_width;
+    out_h = obj_surface->orig_height;
+    out_wpitch = obj_surface->width;
+    out_hpitch = obj_surface->height;
+    assert(out_w <= out_wpitch && out_h <= out_hpitch);
+    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
 
     /* destination Y surface index 7 */
     index = 7;
-    pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo;
+    pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
     bo = dri_bo_alloc(i965->intel.bufmgr, 
                       "surface state", 
@@ -1233,9 +1198,10 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     ss->ss0.surface_type = I965_SURFACE_2D;
     ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM;
     ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset;
-    ss->ss2.width = pp_out_w / 4 - 1;
-    ss->ss2.height = pp_out_h - 1;
-    ss->ss3.pitch = pp_out_w - 1;
+    ss->ss2.width = out_w / 4 - 1;
+    ss->ss2.height = out_h - 1;
+    ss->ss3.pitch = out_wpitch - 1;
+    pp_set_surface_tiling(ss, tiling);
     dri_bo_emit_reloc(bo,
                       I915_GEM_DOMAIN_RENDER, 
                       I915_GEM_DOMAIN_RENDER,
@@ -1246,7 +1212,7 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
 
     /* destination UV surface index 8 */
     index = 8;
-    pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo;
+    pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
     bo = dri_bo_alloc(i965->intel.bufmgr, 
                       "surface state", 
@@ -1260,14 +1226,15 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     memset(ss, 0, sizeof(*ss));
     ss->ss0.surface_type = I965_SURFACE_2D;
     ss->ss0.surface_format = I965_SURFACEFORMAT_R8G8_UNORM;
-    ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + pp_out_w * pp_out_h;
-    ss->ss2.width = pp_out_w / 4 - 1;
-    ss->ss2.height = pp_out_h / 2 - 1;
-    ss->ss3.pitch = pp_out_w - 1;
+    ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + out_wpitch * out_hpitch;
+    ss->ss2.width = out_w / 4 - 1;
+    ss->ss2.height = out_h / 2 - 1;
+    ss->ss3.pitch = out_wpitch - 1;
+    pp_set_surface_tiling(ss, tiling);
     dri_bo_emit_reloc(bo,
                       I915_GEM_DOMAIN_RENDER, 
                       I915_GEM_DOMAIN_RENDER,
-                      pp_out_w * pp_out_h,
+                      out_wpitch * out_hpitch,
                       offsetof(struct i965_surface_state, ss1),
                       pp_context->surfaces[index].s_bo);
     dri_bo_unmap(bo);
@@ -1436,16 +1403,21 @@ pp_nv12_avs_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
     pp_context->pp_y_steps = pp_avs_y_steps;
     pp_context->pp_set_block_parameter = pp_avs_set_block_parameter;
 
-    pp_avs_context->dest_w = pp_out_w;
-    pp_avs_context->dest_h = pp_out_h;
-    pp_avs_context->src_w = w;
-    pp_avs_context->src_h = h;
+    pp_avs_context->dest_x = dst_rect->x;
+    pp_avs_context->dest_y = dst_rect->y;
+    pp_avs_context->dest_w = ALIGN(dst_rect->width, 16);
+    pp_avs_context->dest_h = ALIGN(dst_rect->height, 16);
+    pp_avs_context->src_normalized_x = (float)src_rect->x / in_w / out_w;
+    pp_avs_context->src_normalized_y = (float)src_rect->y / in_h / out_h;
+    pp_avs_context->src_w = src_rect->width;
+    pp_avs_context->src_h = src_rect->height;
 
     pp_static_parameter.grf4.r4_2.avs.nlas = 1;
-    pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step = (float) 1.0 / pp_out_h;
-    pp_inline_parameter.grf5.normalized_video_x_scaling_step = (float) 1.0 / pp_out_w;
+    pp_static_parameter.grf1.r1_6.normalized_video_y_scaling_step = (float) src_rect->height / in_h / out_h;
+
+    pp_inline_parameter.grf5.normalized_video_x_scaling_step = (float) src_rect->width / in_w / out_w;
     pp_inline_parameter.grf5.block_count_x = 1;        /* M x 1 */
-    pp_inline_parameter.grf5.number_blocks = pp_out_h / 8;
+    pp_inline_parameter.grf5.number_blocks = pp_avs_context->dest_h / 8;
     pp_inline_parameter.grf5.block_vertical_mask = 0xff;
     pp_inline_parameter.grf5.block_horizontal_mask = 0xffff;
     pp_inline_parameter.grf6.video_step_delta = 0.0;
@@ -1475,9 +1447,9 @@ pp_dndi_set_block_parameter(struct i965_post_processing_context *pp_context, int
 }
 
 static 
-void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int input,
-                             unsigned short srcw, unsigned short srch,
-                             unsigned short destw, unsigned short desth)
+void pp_nv12_dndi_initialize(VADriverContextP ctx,
+                             VASurfaceID in_surface_id, VASurfaceID out_surface_id,
+                             const VARectangle *src_rect, const VARectangle *dst_rect)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct i965_post_processing_context *pp_context = i965->pp_context;
@@ -1493,11 +1465,12 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
     unsigned int tiling, swizzle;
 
     /* surface */
-    obj_surface = SURFACE(surface);
+    obj_surface = SURFACE(in_surface_id);
     orig_w = obj_surface->orig_width;
     orig_h = obj_surface->orig_height;
     w = obj_surface->width;
     h = obj_surface->height;
+    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
 
     if (pp_context->stmm.bo == NULL) {
         pp_context->stmm.bo = dri_bo_alloc(i965->intel.bufmgr,
@@ -1507,18 +1480,6 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
         assert(pp_context->stmm.bo);
     }
 
-    dri_bo_unreference(obj_surface->pp_out_bo);
-    obj_surface->pp_out_bo = dri_bo_alloc(i965->intel.bufmgr,
-                                          "intermediate surface",
-                                          SIZE_YUV420(w, h),
-                                          4096);
-    assert(obj_surface->pp_out_bo);
-    obj_surface->orig_pp_out_width = orig_w;
-    obj_surface->orig_pp_out_height = orig_h;
-    obj_surface->pp_out_width = w;
-    obj_surface->pp_out_height = h;
-
-    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
     /* source UV surface index 2 */
     index = 2;
     pp_context->surfaces[index].s_bo = obj_surface->bo;
@@ -1612,9 +1573,17 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
                       pp_context->surfaces[index].s_bo);
     dri_bo_unmap(bo);
 
+    /* destination surface */
+    obj_surface = SURFACE(out_surface_id);
+    orig_w = obj_surface->orig_width;
+    orig_h = obj_surface->orig_height;
+    w = obj_surface->width;
+    h = obj_surface->height;
+    dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
+
     /* destination Y surface index 7 */
     index = 7;
-    pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo;
+    pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
     bo = dri_bo_alloc(i965->intel.bufmgr, 
                       "surface state", 
@@ -1629,9 +1598,10 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
     ss->ss0.surface_type = I965_SURFACE_2D;
     ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM;
     ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset;
-    ss->ss2.width = w / 4 - 1;
-    ss->ss2.height = h - 1;
+    ss->ss2.width = orig_w / 4 - 1;
+    ss->ss2.height = orig_h - 1;
     ss->ss3.pitch = w - 1;
+    pp_set_surface_tiling(ss, tiling);
     dri_bo_emit_reloc(bo,
                       I915_GEM_DOMAIN_RENDER, 
                       I915_GEM_DOMAIN_RENDER,
@@ -1642,7 +1612,7 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
 
     /* destination UV surface index 8 */
     index = 8;
-    pp_context->surfaces[index].s_bo = obj_surface->pp_out_bo;
+    pp_context->surfaces[index].s_bo = obj_surface->bo;
     dri_bo_reference(pp_context->surfaces[index].s_bo);
     bo = dri_bo_alloc(i965->intel.bufmgr, 
                       "surface state", 
@@ -1657,9 +1627,10 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
     ss->ss0.surface_type = I965_SURFACE_2D;
     ss->ss0.surface_format = I965_SURFACEFORMAT_R8G8_UNORM;
     ss->ss1.base_addr = pp_context->surfaces[index].s_bo->offset + w * h;
-    ss->ss2.width = w / 4 - 1;
-    ss->ss2.height = h / 2 - 1;
+    ss->ss2.width = orig_w / 4 - 1;
+    ss->ss2.height = orig_h / 2 - 1;
     ss->ss3.pitch = w - 1;
+    pp_set_surface_tiling(ss, tiling);
     dri_bo_emit_reloc(bo,
                       I915_GEM_DOMAIN_RENDER, 
                       I915_GEM_DOMAIN_RENDER,
@@ -1750,8 +1721,8 @@ void pp_nv12_dndi_initialize(VADriverContextP ctx, VASurfaceID surface, int inpu
 static void
 ironlake_pp_initialize(
     VADriverContextP   ctx,
-    VASurfaceID        surface,
-    int                input,
+    VASurfaceID        in_surface_id,
+    VASurfaceID        out_surface_id,
     const VARectangle *src_rect,
     const VARectangle *dst_rect,
     int                pp_index
@@ -1838,22 +1809,21 @@ ironlake_pp_initialize(
     pp_module = &pp_context->pp_modules[pp_index];
     
     if (pp_module->initialize)
-        pp_module->initialize(ctx, surface, input,
-                              src_rect->width, src_rect->height,
-                              dst_rect->width, dst_rect->height);
+        pp_module->initialize(ctx, in_surface_id, out_surface_id,
+                              src_rect, dst_rect);
 }
 
 static void
 ironlake_post_processing(
     VADriverContextP   ctx,
-    VASurfaceID        surface,
-    int                input,
+    VASurfaceID        in_surface_id,
+    VASurfaceID        out_surface_id,
     const VARectangle *src_rect,
     const VARectangle *dst_rect,
     int                pp_index
 )
 {
-    ironlake_pp_initialize(ctx, surface, input, src_rect, dst_rect, pp_index);
+    ironlake_pp_initialize(ctx, in_surface_id, out_surface_id, src_rect, dst_rect, pp_index);
     ironlake_pp_states_setup(ctx);
     ironlake_pp_pipeline_setup(ctx);
 }
@@ -1861,8 +1831,8 @@ ironlake_post_processing(
 static void
 gen6_pp_initialize(
     VADriverContextP   ctx,
-    VASurfaceID        surface,
-    int                input,
+    VASurfaceID        in_surface_id,
+    VASurfaceID        out_surface_id,
     const VARectangle *src_rect,
     const VARectangle *dst_rect,
     int                pp_index
@@ -1949,9 +1919,8 @@ gen6_pp_initialize(
     pp_module = &pp_context->pp_modules[pp_index];
     
     if (pp_module->initialize)
-        pp_module->initialize(ctx, surface, input,
-                              src_rect->width, src_rect->height,
-                              dst_rect->width, dst_rect->height);
+        pp_module->initialize(ctx, in_surface_id, out_surface_id,
+                              src_rect, dst_rect);
 }
 
 static void
@@ -2197,14 +2166,14 @@ gen6_pp_pipeline_setup(VADriverContextP ctx)
 static void
 gen6_post_processing(
     VADriverContextP   ctx,
-    VASurfaceID        surface,
-    int                input,
+    VASurfaceID        in_surface_id,
+    VASurfaceID        out_surface_id,
     const VARectangle *src_rect,
     const VARectangle *dst_rect,
     int                pp_index
 )
 {
-    gen6_pp_initialize(ctx, surface, input, src_rect, dst_rect, pp_index);
+    gen6_pp_initialize(ctx, in_surface_id, out_surface_id, src_rect, dst_rect, pp_index);
     gen6_pp_states_setup(ctx);
     gen6_pp_pipeline_setup(ctx);
 }
@@ -2212,8 +2181,8 @@ gen6_post_processing(
 static void
 i965_post_processing_internal(
     VADriverContextP   ctx,
-    VASurfaceID        surface,
-    int                input,
+    VASurfaceID        in_surface_id,
+    VASurfaceID        out_surface_id,
     const VARectangle *src_rect,
     const VARectangle *dst_rect,
     int                pp_index
@@ -2223,42 +2192,89 @@ i965_post_processing_internal(
 
     if (IS_GEN6(i965->intel.device_id) ||
         IS_GEN7(i965->intel.device_id))
-        gen6_post_processing(ctx, surface, input, src_rect, dst_rect, pp_index);
+        gen6_post_processing(ctx, in_surface_id, out_surface_id, src_rect, dst_rect, pp_index);
     else
-        ironlake_post_processing(ctx, surface, input, src_rect, dst_rect,
-                                 pp_index);
+        ironlake_post_processing(ctx, in_surface_id, out_surface_id, src_rect, dst_rect, pp_index);
 }
 
-void
+VAStatus 
+i965_DestroySurfaces(VADriverContextP ctx,
+                     VASurfaceID *surface_list,
+                     int num_surfaces);
+VAStatus 
+i965_CreateSurfaces(VADriverContextP ctx,
+                    int width,
+                    int height,
+                    int format,
+                    int num_surfaces,
+                    VASurfaceID *surfaces);
+VASurfaceID
 i965_post_processing(
     VADriverContextP   ctx,
     VASurfaceID        surface,
     const VARectangle *src_rect,
     const VARectangle *dst_rect,
-    unsigned int       flags
+    unsigned int       flags,
+    int               *has_done_scaling  
 )
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
+    VASurfaceID in_surface_id = surface;
+    VASurfaceID out_surface_id = VA_INVALID_ID;
 
     if (HAS_PP(i965)) {
         /* Currently only support post processing for NV12 surface */
         if (i965->render_state.interleaved_uv) {
-            int internal_input = 0;
+            struct object_surface *obj_surface;
+            VAStatus status;
 
             if (flags & I965_PP_FLAG_DEINTERLACING) {
-                i965_post_processing_internal(ctx, surface, internal_input,
+                obj_surface = SURFACE(in_surface_id);
+                status = i965_CreateSurfaces(ctx,
+                                             obj_surface->orig_width,
+                                             obj_surface->orig_height,
+                                             VA_RT_FORMAT_YUV420,
+                                             1,
+                                             &out_surface_id);
+                assert(status == VA_STATUS_SUCCESS);
+                obj_surface = SURFACE(out_surface_id);
+                i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
+                i965_post_processing_internal(ctx,
+                                              in_surface_id, out_surface_id,
                                               src_rect, dst_rect,
                                               PP_NV12_DNDI);
-                internal_input = 1;
             }
 
             if (flags & I965_PP_FLAG_AVS) {
-                i965_post_processing_internal(ctx, surface, internal_input,
+                struct i965_render_state *render_state = &i965->render_state;
+                struct intel_region *dest_region = render_state->draw_region;
+
+                if (out_surface_id != VA_INVALID_ID)
+                    in_surface_id = out_surface_id;
+
+                status = i965_CreateSurfaces(ctx,
+                                             dest_region->width,
+                                             dest_region->height,
+                                             VA_RT_FORMAT_YUV420,
+                                             1,
+                                             &out_surface_id);
+                assert(status == VA_STATUS_SUCCESS);
+                obj_surface = SURFACE(out_surface_id);
+                i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
+                i965_post_processing_internal(ctx,
+                                              in_surface_id, out_surface_id,
                                               src_rect, dst_rect,
                                               PP_NV12_AVS);
+
+                if (in_surface_id != surface)
+                    i965_DestroySurfaces(ctx, &in_surface_id, 1);
+                
+                *has_done_scaling = 1;
             }
         }
     }
+
+    return out_surface_id;
 }       
 
 Bool
index 0982410..0981854 100644 (file)
@@ -53,14 +53,22 @@ struct pp_load_save_context
 
 struct pp_scaling_context
 {
+    int dest_x; /* in pixel */
+    int dest_y; /* in pixel */
     int dest_w;
     int dest_h;
+    int src_normalized_x;
+    int src_normalized_y;
 };
 
 struct pp_avs_context
 {
+    int dest_x; /* in pixel */
+    int dest_y; /* in pixel */
     int dest_w;
     int dest_h;
+    int src_normalized_x;
+    int src_normalized_y;
     int src_w;
     int src_h;
 };
@@ -69,7 +77,6 @@ struct pp_dndi_context
 {
     int dest_w;
     int dest_h;
-
 };
 
 struct pp_module
@@ -77,9 +84,9 @@ struct pp_module
     struct i965_kernel kernel;
     
     /* others */
-    void (*initialize)(VADriverContextP ctx, VASurfaceID surface, int input,
-                       unsigned short srcw, unsigned short srch,
-                       unsigned short destw, unsigned short desth);
+    void (*initialize)(VADriverContextP ctx, 
+                       VASurfaceID in_surface_id, VASurfaceID out_surface_id,
+                       const VARectangle *src_rect, const VARectangle *dst_rect);
 };
 
 struct pp_static_parameter
@@ -350,13 +357,14 @@ struct i965_post_processing_context
     int (*pp_set_block_parameter)(struct i965_post_processing_context *pp_context, int x, int y);
 };
 
-void
+VASurfaceID
 i965_post_processing(
     VADriverContextP   ctx,
     VASurfaceID        surface,
     const VARectangle *src_rect,
     const VARectangle *dst_rect,
-    unsigned int       flags
+    unsigned int       flags,
+    int                *has_done_scaling 
 );
 
 Bool
index e86464c..fee7109 100644 (file)
@@ -757,7 +757,6 @@ i965_render_src_surfaces_state(VADriverContextP ctx,
                               VASurfaceID surface)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);  
-    struct i965_render_state *render_state = &i965->render_state;
     struct object_surface *obj_surface;
     int w, h;
     int rw, rh;
@@ -766,19 +765,11 @@ i965_render_src_surfaces_state(VADriverContextP ctx,
     obj_surface = SURFACE(surface);
     assert(obj_surface);
 
-    if (obj_surface->pp_out_bo) {
-        w = obj_surface->pp_out_width;
-        h = obj_surface->pp_out_height;
-        rw = obj_surface->orig_pp_out_width;
-        rh = obj_surface->orig_pp_out_height;
-        region = obj_surface->pp_out_bo;
-    } else {
-        w = obj_surface->width;
-        h = obj_surface->height;
-        rw = obj_surface->orig_width;
-        rh = obj_surface->orig_height;
-        region = obj_surface->bo;
-    }
+    w = obj_surface->width;
+    h = obj_surface->height;
+    rw = obj_surface->orig_width;
+    rh = obj_surface->orig_height;
+    region = obj_surface->bo;
 
     i965_render_src_surface_state(ctx, 1, region, 0, rw, rh, w, I965_SURFACEFORMAT_R8_UNORM);     /* Y */
     i965_render_src_surface_state(ctx, 2, region, 0, rw, rh, w, I965_SURFACEFORMAT_R8_UNORM);
@@ -2901,7 +2892,10 @@ gen7_render_put_subpicture(
 /*
  * global functions
  */
-
+VAStatus 
+i965_DestroySurfaces(VADriverContextP ctx,
+                     VASurfaceID *surface_list,
+                     int num_surfaces);
 void
 intel_render_put_surface(
     VADriverContextP   ctx,
@@ -2912,15 +2906,24 @@ intel_render_put_surface(
 )
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
+    int has_done_scaling = 0;
+    VASurfaceID in_surface_id = surface;
+    VASurfaceID out_surface_id = i965_post_processing(ctx, surface, src_rect, dst_rect, flags, &has_done_scaling);
 
-    i965_post_processing(ctx, surface, src_rect, dst_rect, flags);
+    assert((!has_done_scaling) || (out_surface_id != VA_INVALID_ID));
+
+    if (out_surface_id != VA_INVALID_ID)
+        in_surface_id = out_surface_id;
 
     if (IS_GEN7(i965->intel.device_id))
-        gen7_render_put_surface(ctx, surface, src_rect, dst_rect, flags);
+        gen7_render_put_surface(ctx, in_surface_id, has_done_scaling ? dst_rect : src_rect, dst_rect, flags);
     else if (IS_GEN6(i965->intel.device_id))
-        gen6_render_put_surface(ctx, surface, src_rect, dst_rect, flags);
+        gen6_render_put_surface(ctx, in_surface_id, has_done_scaling ? dst_rect : src_rect, dst_rect, flags);
     else
-        i965_render_put_surface(ctx, surface, src_rect, dst_rect, flags);
+        i965_render_put_surface(ctx, in_surface_id, has_done_scaling ? dst_rect : src_rect, dst_rect, flags);
+
+    if (in_surface_id != surface)
+        i965_DestroySurfaces(ctx, &in_surface_id, 1);
 }
 
 void