Fix graphics memory allocation for VA surface
authorXiang, Haihao <haihao.xiang@intel.com>
Tue, 7 Feb 2012 01:19:03 +0000 (09:19 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Tue, 7 Feb 2012 01:19:03 +0000 (09:19 +0800)
Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
src/gen6_mfc.c
src/gen6_mfd.c
src/gen7_mfd.c
src/i965_avc_bsd.c
src/i965_defines.h
src/i965_drv_video.c
src/i965_drv_video.h
src/i965_media_mpeg2.c
src/i965_post_processing.c
src/i965_render.c

index 34de745..863d4ec 100644 (file)
@@ -851,8 +851,7 @@ static VAStatus gen6_mfc_avc_prepare(VADriverContextP ctx,
     /*Setup all the input&output object*/
     obj_surface = SURFACE(pPicParameter->reconstructed_picture);
     assert(obj_surface);
-    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
-
+    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
     mfc_context->post_deblocking_output.bo = obj_surface->bo;
     dri_bo_reference(mfc_context->post_deblocking_output.bo);
 
index 1dec16d..8280771 100644 (file)
@@ -120,7 +120,7 @@ gen6_mfd_avc_frame_store_index(VADriverContextP ctx,
             struct object_surface *obj_surface = SURFACE(ref_pic->picture_id);
             
             assert(obj_surface);
-            i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N', 'V', '1', '2'));
+            i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N', 'V', '1', '2'), SUBSAMPLE_YUV420);
 
             for (frame_idx = 0; frame_idx < ARRAY_ELEMS(gen6_mfd_context->reference_surface); frame_idx++) {
                 for (j = 0; j < ARRAY_ELEMS(gen6_mfd_context->reference_surface); j++) {
@@ -975,7 +975,7 @@ gen6_mfd_avc_decode_init(VADriverContextP ctx,
     assert(obj_surface);
     obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
     obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
-    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
     gen6_mfd_init_avc_surface(ctx, pic_param, obj_surface);
 
     dri_bo_unreference(gen6_mfd_context->post_deblocking_output.bo);
@@ -1125,7 +1125,7 @@ gen6_mfd_mpeg2_decode_init(VADriverContextP ctx,
     /* Current decoded picture */
     obj_surface = SURFACE(decode_state->current_render_target);
     assert(obj_surface);
-    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
 
     dri_bo_unreference(gen6_mfd_context->pre_deblocking_output.bo);
     gen6_mfd_context->pre_deblocking_output.bo = obj_surface->bo;
@@ -1445,7 +1445,7 @@ gen6_mfd_vc1_decode_init(VADriverContextP ctx,
     /* Current decoded picture */
     obj_surface = SURFACE(decode_state->current_render_target);
     assert(obj_surface);
-    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
     gen6_mfd_init_vc1_surface(ctx, pic_param, obj_surface);
 
     dri_bo_unreference(gen6_mfd_context->post_deblocking_output.bo);
index 4120745..0e05f72 100644 (file)
@@ -120,7 +120,7 @@ gen7_mfd_avc_frame_store_index(VADriverContextP ctx,
             struct object_surface *obj_surface = SURFACE(ref_pic->picture_id);
             
             assert(obj_surface);
-            i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+            i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
 
             for (frame_idx = 0; frame_idx < ARRAY_ELEMS(gen7_mfd_context->reference_surface); frame_idx++) {
                 for (j = 0; j < ARRAY_ELEMS(gen7_mfd_context->reference_surface); j++) {
@@ -270,17 +270,9 @@ gen7_mfd_surface_state(VADriverContextP ctx,
 
     assert(obj_surface);
 
-    if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '1')) {
-        y_cb_offset = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32);
-        y_cr_offset = ALIGN(obj_surface->height, 32);
-    } else if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '3')) {
-        y_cb_offset = ALIGN(obj_surface->height, 32);
-        y_cr_offset = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32);
-    } else {
-        y_cb_offset = ALIGN(obj_surface->height, 32);
-        y_cr_offset = 0;
-    }
-    
+    y_cb_offset = obj_surface->y_cb_offset;
+    y_cr_offset = obj_surface->y_cr_offset;
+
     BEGIN_BCS_BATCH(batch, 6);
     OUT_BCS_BATCH(batch, MFX_SURFACE_STATE | (6 - 2));
     OUT_BCS_BATCH(batch, 0);
@@ -938,7 +930,7 @@ gen7_mfd_avc_decode_init(VADriverContextP ctx,
     assert(obj_surface);
     obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
     obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
-    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
     gen7_mfd_init_avc_surface(ctx, pic_param, obj_surface);
 
     dri_bo_unreference(gen7_mfd_context->post_deblocking_output.bo);
@@ -1087,7 +1079,7 @@ gen7_mfd_mpeg2_decode_init(VADriverContextP ctx,
     /* Current decoded picture */
     obj_surface = SURFACE(decode_state->current_render_target);
     assert(obj_surface);
-    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
 
     dri_bo_unreference(gen7_mfd_context->pre_deblocking_output.bo);
     gen7_mfd_context->pre_deblocking_output.bo = obj_surface->bo;
@@ -1416,7 +1408,7 @@ gen7_mfd_vc1_decode_init(VADriverContextP ctx,
     /* Current decoded picture */
     obj_surface = SURFACE(decode_state->current_render_target);
     assert(obj_surface);
-    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'));
+    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
     gen7_mfd_init_vc1_surface(ctx, pic_param, obj_surface);
 
     dri_bo_unreference(gen7_mfd_context->post_deblocking_output.bo);
@@ -1938,11 +1930,52 @@ gen7_mfd_jpeg_decode_init(VADriverContextP ctx,
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct object_surface *obj_surface;
+    VAPictureParameterBufferJPEG *pic_param;
+    int subsampling = SUBSAMPLE_YUV420;
+
+    pic_param = (VAPictureParameterBufferJPEG *)decode_state->pic_param->buffer;
+
+    if (pic_param->num_components == 1)
+        subsampling = SUBSAMPLE_YUV400;
+    else if (pic_param->num_components == 3) {
+        int h1 = pic_param->components[0].h_sampling_factor;
+        int h2 = pic_param->components[1].h_sampling_factor;
+        int h3 = pic_param->components[2].h_sampling_factor;
+        int v1 = pic_param->components[0].v_sampling_factor;
+        int v2 = pic_param->components[1].v_sampling_factor;
+        int v3 = pic_param->components[2].v_sampling_factor;
+
+        if (h1 == 2 && h2 == 1 && h3 == 1 &&
+            v1 == 2 && v2 == 1 && v3 == 1)
+            subsampling = SUBSAMPLE_YUV420;
+        else if (h1 == 2 && h2 == 1 && h3 == 1 &&
+                 v1 == 1 && v2 == 1 && v3 == 1)
+            subsampling = SUBSAMPLE_YUV422H;
+        else if (h1 == 1 && h2 == 1 && h3 == 1 &&
+                 v1 == 1 && v2 == 1 && v3 == 1)
+            subsampling = SUBSAMPLE_YUV444;
+        else if (h1 == 4 && h2 == 1 && h3 == 1 &&
+                 v1 == 1 && v2 == 1 && v3 == 1)
+            subsampling = SUBSAMPLE_YUV411;
+        else if (h1 == 1 && h2 == 1 && h3 == 1 &&
+                 v1 == 2 && v2 == 1 && v3 == 1)
+            subsampling = SUBSAMPLE_YUV422V;
+        else if (h1 == 2 && h2 == 1 && h3 == 1 &&
+                 v1 == 2 && v2 == 2 && v3 == 2)
+            subsampling = SUBSAMPLE_YUV422H;
+        else if (h2 == 2 && h2 == 2 && h3 == 2 &&
+                 v1 == 2 && v2 == 1 && v3 == 1)
+            subsampling = SUBSAMPLE_YUV422V;
+        else
+            assert(0);
+    } else {
+        assert(0);
+    }
 
     /* Current decoded picture */
     obj_surface = SURFACE(decode_state->current_render_target);
     assert(obj_surface);
-    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('I','M','C','1'));
+    i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('I','M','C','1'), subsampling);
 
     dri_bo_unreference(gen7_mfd_context->pre_deblocking_output.bo);
     gen7_mfd_context->pre_deblocking_output.bo = obj_surface->bo;
@@ -1982,7 +2015,7 @@ gen7_mfd_jpeg_pic_state(VADriverContextP ctx,
 {
     struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
     VAPictureParameterBufferJPEG *pic_param;
-    int chroma_type = GEN7_YUV400;
+    int chroma_type = GEN7_YUV420;
     int frame_width_in_blks;
     int frame_height_in_blks;
 
index 4cc2095..612d0ee 100644 (file)
@@ -482,7 +482,7 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
     assert(obj_surface);
     obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
     obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
-    i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
+    i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
     i965_avc_bsd_init_avc_bsd_surface(ctx, obj_surface, pic_param, i965_h264_context);
     avc_bsd_surface = obj_surface->private_data;
 
@@ -927,7 +927,7 @@ i965_avc_bsd_frame_store_index(VADriverContextP ctx,
             int frame_idx;
             struct object_surface *obj_surface = SURFACE(ref_pic->picture_id);
             assert(obj_surface);
-            i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'));
+            i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
             
             for (frame_idx = 0; frame_idx < ARRAY_ELEMS(i965_h264_context->fsid_list); frame_idx++) {
                 for (j = 0; j < ARRAY_ELEMS(i965_h264_context->fsid_list); j++) {
index 13f6ed8..d530a5b 100644 (file)
 #define MFD_MODE_IT             1
 
 #define MFX_SURFACE_PLANAR_420_8        4
+#define MFX_SURFACE_PLANAR_411_8        5
+#define MFX_SURFACE_PLANAR_422_8        6
 #define MFX_SURFACE_MONOCHROME          12
 
 #define MPEG_TOP_FIELD         1
 #define MPEG_BOTTOM_FIELD      2
 #define MPEG_FRAME             3
 
+#define SUBSAMPLE_YUV400        0
+#define SUBSAMPLE_YUV420        1
+#define SUBSAMPLE_YUV422H       2
+#define SUBSAMPLE_YUV422V       3
+#define SUBSAMPLE_YUV444        4
+#define SUBSAMPLE_YUV411        5
+
 #define URB_SIZE(intel)         (IS_GEN7(intel->device_id) ? 4096 :     \
                                  IS_GEN6(intel->device_id) ? 1024 :     \
                                  IS_IRONLAKE(intel->device_id) ? 1024 : \
index 665f3f5..f4ff879 100644 (file)
@@ -498,21 +498,15 @@ i965_CreateSurfaces(VADriverContextP ctx,
         obj_surface->orig_width = width;
         obj_surface->orig_height = height;
 
-        if (IS_GEN6(i965->intel.device_id) ||
-            IS_GEN7(i965->intel.device_id)) {
-            obj_surface->width = ALIGN(obj_surface->orig_width, 128);
-            obj_surface->height = ALIGN(obj_surface->orig_height, 32);
-        } else {
-            obj_surface->width = ALIGN(obj_surface->orig_width, 16);
-            obj_surface->height = ALIGN(obj_surface->orig_height, 16);
-        }
-
+        obj_surface->width = ALIGN(width, 16);
+        obj_surface->height = ALIGN(height, 16);
         obj_surface->flags = SURFACE_REFERENCED;
         obj_surface->fourcc = 0;
         obj_surface->bo = NULL;
         obj_surface->locked_image_id = VA_INVALID_ID;
         obj_surface->private_data = NULL;
         obj_surface->free_private_data = NULL;
+        obj_surface->subsampling = SUBSAMPLE_YUV420;
     }
 
     /* Error recovery */
@@ -1729,36 +1723,138 @@ void
 i965_check_alloc_surface_bo(VADriverContextP ctx,
                             struct object_surface *obj_surface,
                             int tiled,
-                            unsigned int fourcc)
+                            unsigned int fourcc,
+                            unsigned int subsampling)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
+    int region_width, region_height;
 
     if (obj_surface->bo) {
         assert(obj_surface->fourcc);
         assert(obj_surface->fourcc == fourcc);
+        assert(obj_surface->subsampling == subsampling);
         return;
+    }
 
-    if (fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
-        fourcc == VA_FOURCC('I', 'M', 'C', '3'))
-        obj_surface->size = ALIGN(obj_surface->width * obj_surface->height * 2, 0x1000);
-    else 
-        obj_surface->size = ALIGN(obj_surface->width * obj_surface->height * 3 / 2, 0x1000);
+    obj_surface->x_cb_offset = 0; /* X offset is always 0 */
+    obj_surface->x_cr_offset = 0;
+
+    if (tiled) {
+        assert(fourcc == VA_FOURCC('N', 'V', '1', '2') ||
+               fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
+               fourcc == VA_FOURCC('I', 'M', 'C', '3'));
+
+        obj_surface->width = ALIGN(obj_surface->orig_width, 128);
+        obj_surface->height = ALIGN(obj_surface->orig_height, 32);
+        obj_surface->cb_cr_pitch = obj_surface->width;
+        region_width = obj_surface->width;
+        region_height = obj_surface->height;
+
+        if (fourcc == VA_FOURCC('N', 'V', '1', '2')) {
+            assert(subsampling == SUBSAMPLE_YUV420);
+            obj_surface->y_cb_offset = obj_surface->height;
+            obj_surface->y_cr_offset = obj_surface->height;
+            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
+            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
+            region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
+        } else if (fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
+                   fourcc == VA_FOURCC('I', 'M', 'C', '3')) {
+            switch (subsampling) {
+            case SUBSAMPLE_YUV400:
+                obj_surface->cb_cr_width = 0;
+                obj_surface->cb_cr_height = 0;
+                break;
+
+            case SUBSAMPLE_YUV420:
+                obj_surface->cb_cr_width = obj_surface->orig_width / 2;
+                obj_surface->cb_cr_height = obj_surface->orig_height / 2;
+                break;
+
+            case SUBSAMPLE_YUV422H:
+                obj_surface->cb_cr_width = obj_surface->orig_width / 2;
+                obj_surface->cb_cr_height = obj_surface->orig_height;
+                break;
+
+            case SUBSAMPLE_YUV422V:
+                obj_surface->cb_cr_width = obj_surface->orig_width;
+                obj_surface->cb_cr_height = obj_surface->orig_height / 2;
+                break;
+
+            case SUBSAMPLE_YUV444:
+                obj_surface->cb_cr_width = obj_surface->orig_width;
+                obj_surface->cb_cr_height = obj_surface->orig_height;
+                break;
+
+            case SUBSAMPLE_YUV411:
+                obj_surface->cb_cr_width = obj_surface->orig_width / 4;
+                obj_surface->cb_cr_height = obj_surface->orig_height;
+                break;
+
+            default:
+                assert(0);
+                break;
+            }
+
+            region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
+
+            if (fourcc == VA_FOURCC('I', 'M', 'C', '1')) {
+                obj_surface->y_cb_offset = obj_surface->height;
+                obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
+            } else {
+                obj_surface->y_cb_offset = obj_surface->height;
+                obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
+            }
+        }
+    } else {
+        assert(fourcc != VA_FOURCC('I', 'M', 'C', '1') &&
+               fourcc != VA_FOURCC('I', 'M', 'C', '3'));
+        assert(subsampling == SUBSAMPLE_YUV420);
+
+        region_width = obj_surface->width;
+        region_height = obj_surface->height;
+
+        switch (fourcc) {
+        case VA_FOURCC('N', 'V', '1', '2'):
+            obj_surface->y_cb_offset = obj_surface->height;
+            obj_surface->y_cr_offset = obj_surface->height;
+            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
+            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
+            obj_surface->cb_cr_pitch = obj_surface->width;
+            region_height = obj_surface->height + obj_surface->height / 2;
+            break;
+
+        case VA_FOURCC('Y', 'V', '1', '2'):
+        case VA_FOURCC('I', '4', '2', '0'):
+            if (fourcc == VA_FOURCC('Y', 'V', '1', '2')) {
+                obj_surface->y_cr_offset = obj_surface->height;
+                obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4;
+            } else {
+                obj_surface->y_cb_offset = obj_surface->height;
+                obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
+            }
+
+            obj_surface->cb_cr_width = obj_surface->orig_width / 2;
+            obj_surface->cb_cr_height = obj_surface->orig_height / 2;
+            obj_surface->cb_cr_pitch = obj_surface->width / 2;
+            region_height = obj_surface->height + obj_surface->height / 2;
+            break;
+
+        default:
+            assert(0);
+            break;
+        }
+    }
+
+    obj_surface->size = ALIGN(region_width * region_height, 0x1000);
 
     if (tiled) {
         uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
         unsigned long pitch;
-        unsigned long height;
-
-        if (fourcc == VA_FOURCC('I', 'M', 'C', '1') ||
-            fourcc == VA_FOURCC('I', 'M', 'C', '3'))
-            height = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32) * 2;
-        else
-            height = ALIGN(obj_surface->height, 32) + ALIGN(obj_surface->height / 2, 32);
 
         obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr, 
                                                    "vaapi surface",
-                                                   obj_surface->width,
-                                                   height,
+                                                   region_width,
+                                                   region_height,
                                                    1,
                                                    &tiling_mode,
                                                    &pitch,
@@ -1773,6 +1869,7 @@ i965_check_alloc_surface_bo(VADriverContextP ctx,
     }
 
     obj_surface->fourcc = fourcc;
+    obj_surface->subsampling = subsampling;
     assert(obj_surface->bo);
 }
 
@@ -1857,7 +1954,7 @@ VAStatus i965_DeriveImage(VADriverContextP ctx,
         }
     }
 
-    i965_check_alloc_surface_bo(ctx, obj_surface, HAS_TILED_SURFACE(i965), image->format.fourcc);
+    i965_check_alloc_surface_bo(ctx, obj_surface, HAS_TILED_SURFACE(i965), image->format.fourcc, SUBSAMPLE_YUV420);
     va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType,
                                             obj_surface->size, 1, NULL, obj_surface->bo, &image->buf);
     if (va_status != VA_STATUS_SUCCESS)
index 146438b..03b4c5d 100644 (file)
@@ -162,6 +162,14 @@ struct object_surface
     VAImageID locked_image_id;
     void (*free_private_data)(void **data);
     void *private_data;
+    unsigned int subsampling;
+    int x_cb_offset;
+    int y_cb_offset;
+    int x_cr_offset;
+    int y_cr_offset;
+    int cb_cr_width;
+    int cb_cr_height;
+    int cb_cr_pitch;
 };
 
 struct object_buffer 
@@ -254,6 +262,7 @@ void
 i965_check_alloc_surface_bo(VADriverContextP ctx,
                             struct object_surface *obj_surface,
                             int tiled,
-                            unsigned int fourcc);
+                            unsigned int fourcc,
+                            unsigned int subsampling);
 
 #endif /* _I965_DRV_VIDEO_H_ */
index 1d87d9b..9278ab7 100644 (file)
@@ -514,7 +514,7 @@ i965_media_mpeg2_surface_setup(VADriverContextP ctx,
     int w = obj_surface->width;
     int h = obj_surface->height;
 
-    i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('I','4','2','0'));
+    i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('I','4','2','0'), SUBSAMPLE_YUV420);
 
     if (picture_structure == MPEG_FRAME) {
        i965_media_mpeg2_surface_state(ctx, base_index + 0, obj_surface,
index 090403c..6e238b4 100644 (file)
@@ -2236,7 +2236,7 @@ i965_post_processing(
                                              &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_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
                 i965_post_processing_internal(ctx,
                                               in_surface_id, out_surface_id,
                                               src_rect, dst_rect,
@@ -2258,7 +2258,7 @@ i965_post_processing(
                                              &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_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
                 i965_post_processing_internal(ctx,
                                               in_surface_id, out_surface_id,
                                               src_rect, dst_rect,
index 99ab159..19edbf3 100644 (file)
@@ -757,53 +757,47 @@ i965_render_src_surfaces_state(VADriverContextP ctx,
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);  
     struct object_surface *obj_surface;
-    int w, h;
+    int region_pitch;
     int rw, rh;
     dri_bo *region;
 
     obj_surface = SURFACE(surface);
     assert(obj_surface);
 
-    w = obj_surface->width;
-    h = obj_surface->height;
+    region_pitch = obj_surface->width;
     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);
-
-    if (obj_surface->fourcc == VA_FOURCC('Y','V','1','2')) {
-        int u3 = 5, u4 = 6, v5 = 3, v6 = 4;
-
-        i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM); /* U */
-        i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
-        i965_render_src_surface_state(ctx, v5, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);     /* V */
-        i965_render_src_surface_state(ctx, v6, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
-    } else if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '1')) {
-        int u3 = 5, u4 = 6, v5 = 3, v6 = 4;
-
-        i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM); /* U */
-        i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
-        i965_render_src_surface_state(ctx, v5, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);     /* V */
-        i965_render_src_surface_state(ctx, v6, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
-    } else if (obj_surface->fourcc == VA_FOURCC('I', 'M', 'C', '3')) {
-        int u3 = 3, u4 = 4, v5 = 5, v6 = 6;
-
-        i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM); /* U */
-        i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
-        i965_render_src_surface_state(ctx, v5, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);     /* V */
-        i965_render_src_surface_state(ctx, v6, region, w * h + w * ALIGN(h / 2, 32), rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8_UNORM);
-    } else if (obj_surface->fourcc == VA_FOURCC('N','V','1','2')) {
-        i965_render_src_surface_state(ctx, 3, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8G8_UNORM); /* UV */
-        i965_render_src_surface_state(ctx, 4, region, w * h, rw / 2, rh / 2, w, I965_SURFACEFORMAT_R8G8_UNORM);
+    i965_render_src_surface_state(ctx, 1, region, 0, rw, rh, region_pitch, I965_SURFACEFORMAT_R8_UNORM);     /* Y */
+    i965_render_src_surface_state(ctx, 2, region, 0, rw, rh, region_pitch, I965_SURFACEFORMAT_R8_UNORM);
+
+    if (obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2')) {
+        i965_render_src_surface_state(ctx, 3, region,
+                                      region_pitch * obj_surface->y_cb_offset,
+                                      obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
+                                      I965_SURFACEFORMAT_R8G8_UNORM); /* UV */
+        i965_render_src_surface_state(ctx, 4, region,
+                                      region_pitch * obj_surface->y_cb_offset,
+                                      obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
+                                      I965_SURFACEFORMAT_R8G8_UNORM);
     } else {
-        int u3 = 3, u4 = 4, v5 = 5, v6 = 6;
-        
-        i965_render_src_surface_state(ctx, u3, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM); /* U */
-        i965_render_src_surface_state(ctx, u4, region, w * h, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
-        i965_render_src_surface_state(ctx, v5, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);     /* V */
-        i965_render_src_surface_state(ctx, v6, region, w * h + w * h / 4, rw / 2, rh / 2, w / 2, I965_SURFACEFORMAT_R8_UNORM);
+        i965_render_src_surface_state(ctx, 3, region,
+                                      region_pitch * obj_surface->y_cb_offset,
+                                      obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
+                                      I965_SURFACEFORMAT_R8_UNORM); /* U */
+        i965_render_src_surface_state(ctx, 4, region,
+                                      region_pitch * obj_surface->y_cb_offset,
+                                      obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
+                                      I965_SURFACEFORMAT_R8_UNORM);
+        i965_render_src_surface_state(ctx, 5, region,
+                                      region_pitch * obj_surface->y_cr_offset,
+                                      obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
+                                      I965_SURFACEFORMAT_R8_UNORM); /* V */
+        i965_render_src_surface_state(ctx, 6, region,
+                                      region_pitch * obj_surface->y_cr_offset,
+                                      obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
+                                      I965_SURFACEFORMAT_R8_UNORM);
     }
 }