Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright ?2009 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the
  6.  * "Software"), to deal in the Software without restriction, including
  7.  * without limitation the rights to use, copy, modify, merge, publish,
  8.  * distribute, sub license, and/or sell copies of the Software, and to
  9.  * permit persons to whom the Software is furnished to do so, subject to
  10.  * the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the
  13.  * next paragraph) shall be included in all copies or substantial portions
  14.  * of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  19.  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
  20.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  21.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  22.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  *
  24.  * Authors:
  25.  *    Xiang Haihao <haihao.xiang@intel.com>
  26.  *    Zou Nan hai <nanhai.zou@intel.com>
  27.  *
  28.  */
  29.  
  30. #include "sysdeps.h"
  31. #include <unistd.h>
  32.  
  33. #ifdef HAVE_VA_X11
  34. # include "i965_output_dri.h"
  35. #endif
  36.  
  37. #ifdef HAVE_VA_WAYLAND
  38. # include "i965_output_wayland.h"
  39. #endif
  40.  
  41. #include "intel_version.h"
  42. #include "intel_driver.h"
  43. #include "intel_memman.h"
  44. #include "intel_batchbuffer.h"
  45. #include "i965_defines.h"
  46. #include "i965_drv_video.h"
  47. #include "i965_decoder.h"
  48. #include "i965_encoder.h"
  49.  
  50. #define CONFIG_ID_OFFSET                0x01000000
  51. #define CONTEXT_ID_OFFSET               0x02000000
  52. #define SURFACE_ID_OFFSET               0x04000000
  53. #define BUFFER_ID_OFFSET                0x08000000
  54. #define IMAGE_ID_OFFSET                 0x0a000000
  55. #define SUBPIC_ID_OFFSET                0x10000000
  56.  
  57. #define HAS_MPEG2_DECODING(ctx)  ((ctx)->codec_info->has_mpeg2_decoding && \
  58.                                   (ctx)->intel.has_bsd)
  59.  
  60. #define HAS_MPEG2_ENCODING(ctx)  ((ctx)->codec_info->has_mpeg2_encoding && \
  61.                                   (ctx)->intel.has_bsd)
  62.  
  63. #define HAS_H264_DECODING(ctx)  ((ctx)->codec_info->has_h264_decoding && \
  64.                                  (ctx)->intel.has_bsd)
  65.  
  66. #define HAS_H264_ENCODING(ctx)  ((ctx)->codec_info->has_h264_encoding && \
  67.                                  (ctx)->intel.has_bsd)
  68.  
  69. #define HAS_VC1_DECODING(ctx)   ((ctx)->codec_info->has_vc1_decoding && \
  70.                                  (ctx)->intel.has_bsd)
  71.  
  72. #define HAS_JPEG_DECODING(ctx)  ((ctx)->codec_info->has_jpeg_decoding && \
  73.                                  (ctx)->intel.has_bsd)
  74.  
  75. #define HAS_JPEG_ENCODING(ctx)  ((ctx)->codec_info->has_jpeg_encoding && \
  76.                                  (ctx)->intel.has_bsd)
  77.  
  78. #define HAS_VPP(ctx)    ((ctx)->codec_info->has_vpp)
  79.  
  80. #define HAS_ACCELERATED_GETIMAGE(ctx)   ((ctx)->codec_info->has_accelerated_getimage)
  81.  
  82. #define HAS_ACCELERATED_PUTIMAGE(ctx)   ((ctx)->codec_info->has_accelerated_putimage)
  83.  
  84. #define HAS_TILED_SURFACE(ctx) ((ctx)->codec_info->has_tiled_surface)
  85.  
  86. #define HAS_VP8_DECODING(ctx)   ((ctx)->codec_info->has_vp8_decoding && \
  87.                                  (ctx)->intel.has_bsd)
  88.  
  89. #define HAS_VP8_ENCODING(ctx)   ((ctx)->codec_info->has_vp8_encoding && \
  90.                                  (ctx)->intel.has_bsd)
  91.  
  92. #define HAS_H264_MVC_DECODING(ctx) \
  93.     (HAS_H264_DECODING(ctx) && (ctx)->codec_info->h264_mvc_dec_profiles)
  94.  
  95. #define HAS_H264_MVC_DECODING_PROFILE(ctx, profile)                     \
  96.     (HAS_H264_MVC_DECODING(ctx) &&                                      \
  97.      ((ctx)->codec_info->h264_mvc_dec_profiles & (1U << profile)))
  98.  
  99. #define HAS_H264_MVC_ENCODING(ctx)  ((ctx)->codec_info->has_h264_mvc_encoding && \
  100.                                      (ctx)->intel.has_bsd)
  101.  
  102. #define HAS_HEVC_DECODING(ctx)          ((ctx)->codec_info->has_hevc_decoding && \
  103.                                          (ctx)->intel.has_bsd)
  104.  
  105. #define HAS_HEVC_ENCODING(ctx)          ((ctx)->codec_info->has_hevc_encoding && \
  106.                                          (ctx)->intel.has_bsd)
  107.  
  108. #define HAS_VP9_DECODING(ctx)          ((ctx)->codec_info->has_vp9_decoding && \
  109.                                          (ctx)->intel.has_bsd)
  110.  
  111. #define HAS_HEVC10_DECODING(ctx)        ((ctx)->codec_info->has_hevc10_decoding && \
  112.                                          (ctx)->intel.has_bsd)
  113.  
  114. static int get_sampling_from_fourcc(unsigned int fourcc);
  115.  
  116. /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */
  117. #define IS_VA_X11(ctx) \
  118.     (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_X11)
  119.  
  120. /* Check whether we are rendering to Wayland */
  121. #define IS_VA_WAYLAND(ctx) \
  122.     (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_WAYLAND)
  123.  
  124. #define I965_BIT        1
  125. #define I965_2BITS      (I965_BIT << 1)
  126. #define I965_4BITS      (I965_BIT << 2)
  127. #define I965_8BITS      (I965_BIT << 3)
  128. #define I965_16BITS     (I965_BIT << 4)
  129. #define I965_32BITS     (I965_BIT << 5)
  130.  
  131. #define PLANE_0         0
  132. #define PLANE_1         1
  133. #define PLANE_2         2
  134.  
  135. #define OFFSET_0        0
  136. #define OFFSET_4        4
  137. #define OFFSET_8        8
  138. #define OFFSET_16       16
  139. #define OFFSET_24       24
  140.  
  141. /* hfactor, vfactor, num_planes, bpp[], num_components, components[] */
  142. #define I_NV12  2, 2, 2, {I965_8BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_8} }
  143. #define I_I420  2, 2, 3, {I965_8BITS, I965_2BITS, I965_2BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
  144. #define I_IYUV  I_I420
  145. #define I_IMC3  I_I420
  146. #define I_YV12  2, 2, 3, {I965_8BITS, I965_2BITS, I965_2BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_2, OFFSET_0}, {PLANE_1, OFFSET_0} }
  147. #define I_IMC1  I_YV12
  148.  
  149. #define I_P010  2, 2, 2, {I965_16BITS, I965_8BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_16} }
  150.  
  151. #define I_422H  2, 1, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
  152. #define I_422V  1, 2, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
  153. #define I_YV16  2, 1, 3, {I965_8BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_2, OFFSET_0}, {PLANE_1, OFFSET_0} }
  154. #define I_YUY2  2, 1, 1, {I965_16BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_24} }
  155. #define I_UYVY  2, 1, 1, {I965_16BITS}, 3, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_16} }
  156.  
  157. #define I_444P  1, 1, 3, {I965_8BITS, I965_8BITS, I965_8BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
  158.  
  159. #define I_411P  4, 1, 3, {I965_8BITS, I965_2BITS, I965_2BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
  160.  
  161. #define I_Y800  1, 1, 1, {I965_8BITS}, 1, { {PLANE_0, OFFSET_0} }
  162.  
  163. #define I_RGBA  1, 1, 1, {I965_32BITS}, 4, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_24} }
  164. #define I_RGBX  1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16} }
  165. #define I_BGRA  1, 1, 1, {I965_32BITS}, 4, { {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_24} }
  166. #define I_BGRX  1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
  167.  
  168. #define I_ARGB  1, 1, 1, {I965_32BITS}, 4, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_24}, {PLANE_0, OFFSET_0} }
  169. #define I_ABGR  1, 1, 1, {I965_32BITS}, 4, { {PLANE_0, OFFSET_24}, {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
  170.  
  171. #define I_IA88  1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8} }
  172. #define I_AI88  1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
  173.  
  174. #define I_IA44  1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_4} }
  175. #define I_AI44  1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_4}, {PLANE_0, OFFSET_0} }
  176.  
  177. /* flag */
  178. #define I_S             1
  179. #define I_I             2
  180. #define I_SI            (I_S | I_I)
  181.  
  182. #define DEF_FOUCC_INFO(FOURCC, FORMAT, SUB, FLAG)       { VA_FOURCC_##FOURCC, I965_COLOR_##FORMAT, SUBSAMPLE_##SUB, FLAG, I_##FOURCC }
  183. #define DEF_YUV(FOURCC, SUB, FLAG)                      DEF_FOUCC_INFO(FOURCC, YUV, SUB, FLAG)
  184. #define DEF_RGB(FOURCC, SUB, FLAG)                      DEF_FOUCC_INFO(FOURCC, RGB, SUB, FLAG)
  185. #define DEF_INDEX(FOURCC, SUB, FLAG)                    DEF_FOUCC_INFO(FOURCC, INDEX, SUB, FLAG)
  186.  
  187. static const i965_fourcc_info i965_fourcc_infos[] = {
  188.     DEF_YUV(NV12, YUV420, I_SI),
  189.     DEF_YUV(I420, YUV420, I_SI),
  190.     DEF_YUV(IYUV, YUV420, I_S),
  191.     DEF_YUV(IMC3, YUV420, I_S),
  192.     DEF_YUV(YV12, YUV420, I_SI),
  193.     DEF_YUV(IMC1, YUV420, I_S),
  194.  
  195.     DEF_YUV(P010, YUV420, I_SI),
  196.  
  197.     DEF_YUV(422H, YUV422H, I_SI),
  198.     DEF_YUV(422V, YUV422V, I_S),
  199.     DEF_YUV(YV16, YUV422H, I_S),
  200.     DEF_YUV(YUY2, YUV422H, I_SI),
  201.     DEF_YUV(UYVY, YUV422H, I_SI),
  202.  
  203.     DEF_YUV(444P, YUV444, I_S),
  204.  
  205.     DEF_YUV(411P, YUV411, I_S),
  206.  
  207.     DEF_YUV(Y800, YUV400, I_S),
  208.  
  209.     DEF_RGB(RGBA, RGBX, I_SI),
  210.     DEF_RGB(RGBX, RGBX, I_SI),
  211.     DEF_RGB(BGRA, RGBX, I_SI),
  212.     DEF_RGB(BGRX, RGBX, I_SI),
  213.  
  214.     DEF_RGB(ARGB, RGBX, I_I),
  215.     DEF_RGB(ABGR, RGBX, I_I),
  216.  
  217.     DEF_INDEX(IA88, RGBX, I_I),
  218.     DEF_INDEX(AI88, RGBX, I_I),
  219.  
  220.     DEF_INDEX(IA44, RGBX, I_I),
  221.     DEF_INDEX(AI44, RGBX, I_I)
  222. };
  223.  
  224. const i965_fourcc_info *
  225. get_fourcc_info(unsigned int fourcc)
  226. {
  227.     unsigned int i;
  228.  
  229.     for (i = 0; ARRAY_ELEMS(i965_fourcc_infos); i++) {
  230.         const i965_fourcc_info * const info = &i965_fourcc_infos[i];
  231.  
  232.         if (info->fourcc == fourcc)
  233.             return info;
  234.     }
  235.  
  236.     return NULL;
  237. }
  238.  
  239. static int
  240. get_bpp_from_fourcc(unsigned int fourcc)
  241. {
  242.     const i965_fourcc_info *info = get_fourcc_info(fourcc);
  243.     unsigned int i = 0;
  244.     unsigned int bpp = 0;
  245.  
  246.     if (!info)
  247.         return 0;
  248.  
  249.     for (i = 0; i < info->num_planes; i++)
  250.         bpp += info->bpp[i];
  251.  
  252.     return bpp;
  253. }
  254.  
  255. enum {
  256.     I965_SURFACETYPE_RGBA = 1,
  257.     I965_SURFACETYPE_YUV,
  258.     I965_SURFACETYPE_INDEXED
  259. };
  260.  
  261. /* List of supported display attributes */
  262. static const VADisplayAttribute i965_display_attributes[] = {
  263.     {
  264.         VADisplayAttribBrightness,
  265.         -100, 100, DEFAULT_BRIGHTNESS,
  266.         VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
  267.     },
  268.  
  269.     {
  270.         VADisplayAttribContrast,
  271.         0, 100, DEFAULT_CONTRAST,
  272.         VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
  273.     },
  274.  
  275.     {
  276.         VADisplayAttribHue,
  277.         -180, 180, DEFAULT_HUE,
  278.         VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
  279.     },
  280.  
  281.     {
  282.         VADisplayAttribSaturation,
  283.         0, 100, DEFAULT_SATURATION,
  284.         VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
  285.     },
  286.  
  287.     {
  288.         VADisplayAttribRotation,
  289.         0, 3, VA_ROTATION_NONE,
  290.         VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE
  291.     },
  292. };
  293.  
  294. /* List of supported image formats */
  295. typedef struct {
  296.     unsigned int        type;
  297.     VAImageFormat       va_format;
  298. } i965_image_format_map_t;
  299.  
  300. static const i965_image_format_map_t
  301. i965_image_formats_map[I965_MAX_IMAGE_FORMATS + 1] = {
  302.     { I965_SURFACETYPE_YUV,
  303.       { VA_FOURCC_YV12, VA_LSB_FIRST, 12, } },
  304.     { I965_SURFACETYPE_YUV,
  305.       { VA_FOURCC_I420, VA_LSB_FIRST, 12, } },
  306.     { I965_SURFACETYPE_YUV,
  307.       { VA_FOURCC_NV12, VA_LSB_FIRST, 12, } },
  308.     { I965_SURFACETYPE_YUV,
  309.       { VA_FOURCC_YUY2, VA_LSB_FIRST, 16, } },
  310.     { I965_SURFACETYPE_YUV,
  311.       { VA_FOURCC_UYVY, VA_LSB_FIRST, 16, } },
  312.     { I965_SURFACETYPE_YUV,
  313.       { VA_FOURCC_422H, VA_LSB_FIRST, 16, } },
  314.     { I965_SURFACETYPE_RGBA,
  315.       { VA_FOURCC_RGBX, VA_LSB_FIRST, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000 } },
  316.     { I965_SURFACETYPE_RGBA,
  317.       { VA_FOURCC_BGRX, VA_LSB_FIRST, 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff } },
  318. };
  319.  
  320. /* List of supported subpicture formats */
  321. typedef struct {
  322.     unsigned int        type;
  323.     unsigned int        format;
  324.     VAImageFormat       va_format;
  325.     unsigned int        va_flags;
  326. } i965_subpic_format_map_t;
  327.  
  328. #define COMMON_SUBPICTURE_FLAGS                 \
  329.     (VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD| \
  330.      VA_SUBPICTURE_GLOBAL_ALPHA)
  331.  
  332. static const i965_subpic_format_map_t
  333. i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
  334.     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
  335.       { VA_FOURCC_IA44, VA_MSB_FIRST, 8, },
  336.       COMMON_SUBPICTURE_FLAGS },
  337.     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
  338.       { VA_FOURCC_AI44, VA_MSB_FIRST, 8, },
  339.       COMMON_SUBPICTURE_FLAGS },
  340.     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P8A8_UNORM,
  341.       { VA_FOURCC_IA88, VA_MSB_FIRST, 16, },
  342.       COMMON_SUBPICTURE_FLAGS },
  343.     { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A8P8_UNORM,
  344.       { VA_FOURCC_AI88, VA_MSB_FIRST, 16, },
  345.       COMMON_SUBPICTURE_FLAGS },
  346.      { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_B8G8R8A8_UNORM,
  347.       { VA_FOURCC_BGRA, VA_LSB_FIRST, 32,
  348.         32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
  349.       COMMON_SUBPICTURE_FLAGS },
  350.     { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_R8G8B8A8_UNORM,
  351.       { VA_FOURCC_RGBA, VA_LSB_FIRST, 32,
  352.         32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
  353.       COMMON_SUBPICTURE_FLAGS },
  354. };
  355.  
  356. static const i965_subpic_format_map_t *
  357. get_subpic_format(const VAImageFormat *va_format)
  358. {
  359.     unsigned int i;
  360.     for (i = 0; i965_subpic_formats_map[i].type != 0; i++) {
  361.         const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
  362.         if (m->va_format.fourcc == va_format->fourcc &&
  363.             (m->type == I965_SURFACETYPE_RGBA ?
  364.              (m->va_format.byte_order == va_format->byte_order &&
  365.               m->va_format.red_mask   == va_format->red_mask   &&
  366.               m->va_format.green_mask == va_format->green_mask &&
  367.               m->va_format.blue_mask  == va_format->blue_mask  &&
  368.               m->va_format.alpha_mask == va_format->alpha_mask) : 1))
  369.             return m;
  370.     }
  371.     return NULL;
  372. }
  373.  
  374. /* Checks whether the surface is in busy state */
  375. static bool
  376. is_surface_busy(struct i965_driver_data *i965,
  377.     struct object_surface *obj_surface)
  378. {
  379.     assert(obj_surface != NULL);
  380.  
  381.     if (obj_surface->locked_image_id != VA_INVALID_ID)
  382.         return true;
  383.     if (obj_surface->derived_image_id != VA_INVALID_ID)
  384.         return true;
  385.     return false;
  386. }
  387.  
  388. /* Checks whether the image is in busy state */
  389. static bool
  390. is_image_busy(struct i965_driver_data *i965, struct object_image *obj_image, VASurfaceID surface)
  391. {
  392.     struct object_buffer *obj_buffer;
  393.  
  394.     assert(obj_image != NULL);
  395.  
  396.     if (obj_image->derived_surface != VA_INVALID_ID &&
  397.         obj_image->derived_surface == surface)
  398.         return true;
  399.  
  400.     obj_buffer = BUFFER(obj_image->image.buf);
  401.     if (obj_buffer && obj_buffer->export_refcount > 0)
  402.         return true;
  403.     return false;
  404. }
  405.  
  406. #define I965_PACKED_HEADER_BASE         0
  407. #define I965_SEQ_PACKED_HEADER_BASE     0
  408. #define I965_SEQ_PACKED_HEADER_END      2
  409. #define I965_PIC_PACKED_HEADER_BASE     2
  410. #define I965_PACKED_MISC_HEADER_BASE    4
  411.  
  412. int
  413. va_enc_packed_type_to_idx(int packed_type)
  414. {
  415.     int idx = 0;
  416.  
  417.     if (packed_type & VAEncPackedHeaderMiscMask) {
  418.         idx = I965_PACKED_MISC_HEADER_BASE;
  419.         packed_type = (~VAEncPackedHeaderMiscMask & packed_type);
  420.         ASSERT_RET(packed_type > 0, 0);
  421.         idx += (packed_type - 1);
  422.     } else {
  423.         idx = I965_PACKED_HEADER_BASE;
  424.  
  425.         switch (packed_type) {
  426.         case VAEncPackedHeaderSequence:
  427.             idx = I965_SEQ_PACKED_HEADER_BASE + 0;
  428.             break;
  429.  
  430.         case VAEncPackedHeaderPicture:
  431.             idx = I965_PIC_PACKED_HEADER_BASE + 0;
  432.             break;
  433.  
  434.         case VAEncPackedHeaderSlice:
  435.             idx = I965_PIC_PACKED_HEADER_BASE + 1;
  436.             break;
  437.  
  438.         default:
  439.             /* Should not get here */
  440.             ASSERT_RET(0, 0);
  441.             break;
  442.         }
  443.     }
  444.  
  445.     ASSERT_RET(idx < 5, 0);
  446.     return idx;
  447. }
  448.  
  449. #define CALL_VTABLE(vawr, status, param) status = (vawr->vtable->param)
  450.  
  451. static VAStatus
  452. i965_surface_wrapper(VADriverContextP ctx, VASurfaceID surface)
  453. {
  454.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  455.     struct object_surface *obj_surface = SURFACE(surface);
  456.     VAStatus va_status = VA_STATUS_SUCCESS;
  457.  
  458.     if (!obj_surface) {
  459.         return VA_STATUS_ERROR_INVALID_SURFACE;
  460.     }
  461.  
  462.     if (obj_surface->wrapper_surface != VA_INVALID_ID) {
  463.         /* the wrapped surface already exists. just return it */
  464.        return va_status;
  465.     }
  466.  
  467.     if (obj_surface->fourcc == 0)
  468.         i965_check_alloc_surface_bo(ctx, obj_surface,
  469.                                     1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
  470.  
  471.     /*
  472.      * TBD: Support more surface formats.
  473.      * Currently only NV12 is support as NV12 is used by decoding.
  474.      */
  475.     if (obj_surface->fourcc != VA_FOURCC_NV12 )
  476.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  477.  
  478.     if ((i965->wrapper_pdrvctx == NULL) ||
  479.         (obj_surface->bo == NULL))
  480.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  481.  
  482.     {
  483.         int fd_handle;
  484.         VASurfaceAttrib attrib_list[2];
  485.         VASurfaceAttribExternalBuffers buffer_descriptor;
  486.         VAGenericID wrapper_surface;
  487.  
  488. //        if (drm_intel_bo_gem_export_to_prime(obj_surface->bo, &fd_handle) != 0)
  489.             return VA_STATUS_ERROR_OPERATION_FAILED;
  490.  
  491.         obj_surface->exported_primefd = fd_handle;
  492.  
  493.         memset(&attrib_list, 0, sizeof(attrib_list));
  494.         memset(&buffer_descriptor, 0, sizeof(buffer_descriptor));
  495.  
  496.         attrib_list[0].type = VASurfaceAttribExternalBufferDescriptor;
  497.         attrib_list[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
  498.         attrib_list[0].value.value.p = &buffer_descriptor;
  499.         attrib_list[0].value.type = VAGenericValueTypePointer;
  500.  
  501.         attrib_list[1].type = VASurfaceAttribMemoryType;
  502.         attrib_list[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
  503.         attrib_list[1].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
  504.         attrib_list[1].value.type = VAGenericValueTypeInteger;
  505.  
  506.         buffer_descriptor.num_buffers = 1;
  507.         buffer_descriptor.num_planes = 2;
  508.         buffer_descriptor.width = obj_surface->orig_width;
  509.         buffer_descriptor.height = obj_surface->orig_height;
  510.         buffer_descriptor.pixel_format = obj_surface->fourcc;
  511.         buffer_descriptor.data_size = obj_surface->size;
  512.         buffer_descriptor.pitches[0] = obj_surface->width;
  513.         buffer_descriptor.pitches[1] = obj_surface->cb_cr_pitch;
  514.         buffer_descriptor.offsets[0] = 0;
  515.         buffer_descriptor.offsets[1] = obj_surface->width * obj_surface->height;
  516.         buffer_descriptor.buffers = (void *)&fd_handle;
  517.  
  518.         CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
  519.                     vaCreateSurfaces2(i965->wrapper_pdrvctx,
  520.                                       VA_RT_FORMAT_YUV420,
  521.                                       obj_surface->orig_width,
  522.                                       obj_surface->orig_height,
  523.                                       &wrapper_surface, 1,
  524.                                       attrib_list, 2));
  525.  
  526.         if (va_status == VA_STATUS_SUCCESS) {
  527.             obj_surface->wrapper_surface = wrapper_surface;
  528.         } else {
  529.             /* This needs to be checked */
  530.             va_status = VA_STATUS_ERROR_OPERATION_FAILED;
  531.         }
  532.         return va_status;
  533.     }
  534.  
  535. }
  536.  
  537. VAStatus
  538. i965_QueryConfigProfiles(VADriverContextP ctx,
  539.                          VAProfile *profile_list,       /* out */
  540.                          int *num_profiles)             /* out */
  541. {
  542.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  543.     int i = 0;
  544.  
  545.     if (HAS_MPEG2_DECODING(i965) ||
  546.         HAS_MPEG2_ENCODING(i965)) {
  547.         profile_list[i++] = VAProfileMPEG2Simple;
  548.         profile_list[i++] = VAProfileMPEG2Main;
  549.     }
  550.  
  551.     if (HAS_H264_DECODING(i965) ||
  552.         HAS_H264_ENCODING(i965)) {
  553.         profile_list[i++] = VAProfileH264ConstrainedBaseline;
  554.         profile_list[i++] = VAProfileH264Main;
  555.         profile_list[i++] = VAProfileH264High;
  556.     }
  557.     if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264MultiviewHigh))
  558.         profile_list[i++] = VAProfileH264MultiviewHigh;
  559.     if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264StereoHigh))
  560.         profile_list[i++] = VAProfileH264StereoHigh;
  561.  
  562.     if (HAS_VC1_DECODING(i965)) {
  563.         profile_list[i++] = VAProfileVC1Simple;
  564.         profile_list[i++] = VAProfileVC1Main;
  565.         profile_list[i++] = VAProfileVC1Advanced;
  566.     }
  567.  
  568.     if (HAS_VPP(i965)) {
  569.         profile_list[i++] = VAProfileNone;
  570.     }
  571.  
  572.     if (HAS_JPEG_DECODING(i965) ||
  573.         HAS_JPEG_ENCODING(i965)) {
  574.         profile_list[i++] = VAProfileJPEGBaseline;
  575.     }
  576.  
  577.     if (HAS_VP8_DECODING(i965) ||
  578.         HAS_VP8_ENCODING(i965)) {
  579.         profile_list[i++] = VAProfileVP8Version0_3;
  580.     }
  581.  
  582.     if (HAS_H264_MVC_ENCODING(i965)) {
  583.         profile_list[i++] = VAProfileH264MultiviewHigh;
  584.         profile_list[i++] = VAProfileH264StereoHigh;
  585.     }
  586.  
  587.     if (HAS_HEVC_DECODING(i965)||
  588.         HAS_HEVC_ENCODING(i965)) {
  589.         profile_list[i++] = VAProfileHEVCMain;
  590.     }
  591.  
  592.     if (HAS_HEVC10_DECODING(i965)) {
  593.         profile_list[i++] = VAProfileHEVCMain10;
  594.     }
  595.  
  596.     if(HAS_VP9_DECODING(i965)) {
  597.         profile_list[i++] = VAProfileVP9Profile0;
  598.     }
  599.  
  600.     if (i965->wrapper_pdrvctx) {
  601.         VAProfile wrapper_list[4];
  602.         int wrapper_num;
  603.         VADriverContextP pdrvctx;
  604.         VAStatus va_status;
  605.  
  606.         pdrvctx = i965->wrapper_pdrvctx;
  607.         CALL_VTABLE(pdrvctx, va_status,
  608.                     vaQueryConfigProfiles(pdrvctx,
  609.                                           wrapper_list, &wrapper_num));
  610.  
  611.         if (va_status == VA_STATUS_SUCCESS) {
  612.             int j;
  613.             for (j = 0; j < wrapper_num; j++)
  614.                 if (wrapper_list[j] != VAProfileNone)
  615.                     profile_list[i++] = wrapper_list[j];
  616.         }
  617.     }
  618.  
  619.     /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
  620.     ASSERT_RET(i <= I965_MAX_PROFILES, VA_STATUS_ERROR_OPERATION_FAILED);
  621.     *num_profiles = i;
  622.  
  623.     return VA_STATUS_SUCCESS;
  624. }
  625.  
  626. VAStatus
  627. i965_QueryConfigEntrypoints(VADriverContextP ctx,
  628.                             VAProfile profile,
  629.                             VAEntrypoint *entrypoint_list,      /* out */
  630.                             int *num_entrypoints)               /* out */
  631. {
  632.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  633.     int n = 0;
  634.  
  635.     switch (profile) {
  636.     case VAProfileMPEG2Simple:
  637.     case VAProfileMPEG2Main:
  638.         if (HAS_MPEG2_DECODING(i965))
  639.             entrypoint_list[n++] = VAEntrypointVLD;
  640.  
  641.         if (HAS_MPEG2_ENCODING(i965))
  642.             entrypoint_list[n++] = VAEntrypointEncSlice;
  643.  
  644.         break;
  645.  
  646.     case VAProfileH264ConstrainedBaseline:
  647.     case VAProfileH264Main:
  648.     case VAProfileH264High:
  649.         if (HAS_H264_DECODING(i965))
  650.             entrypoint_list[n++] = VAEntrypointVLD;
  651.  
  652.         if (HAS_H264_ENCODING(i965))
  653.             entrypoint_list[n++] = VAEntrypointEncSlice;
  654.  
  655.         break;
  656.    case VAProfileH264MultiviewHigh:
  657.    case VAProfileH264StereoHigh:
  658.        if (HAS_H264_MVC_DECODING_PROFILE(i965, profile))
  659.             entrypoint_list[n++] = VAEntrypointVLD;
  660.  
  661.        if (HAS_H264_MVC_ENCODING(i965))
  662.             entrypoint_list[n++] = VAEntrypointEncSlice;
  663.         break;
  664.  
  665.     case VAProfileVC1Simple:
  666.     case VAProfileVC1Main:
  667.     case VAProfileVC1Advanced:
  668.         if (HAS_VC1_DECODING(i965))
  669.             entrypoint_list[n++] = VAEntrypointVLD;
  670.         break;
  671.  
  672.     case VAProfileNone:
  673.         if (HAS_VPP(i965))
  674.             entrypoint_list[n++] = VAEntrypointVideoProc;
  675.         break;
  676.  
  677.     case VAProfileJPEGBaseline:
  678.         if (HAS_JPEG_DECODING(i965))
  679.             entrypoint_list[n++] = VAEntrypointVLD;
  680.  
  681.         if (HAS_JPEG_ENCODING(i965))
  682.             entrypoint_list[n++] = VAEntrypointEncPicture;
  683.         break;
  684.  
  685.     case VAProfileVP8Version0_3:
  686.         if (HAS_VP8_DECODING(i965))
  687.             entrypoint_list[n++] = VAEntrypointVLD;
  688.  
  689.         if (HAS_VP8_ENCODING(i965))
  690.             entrypoint_list[n++] = VAEntrypointEncSlice;
  691.  
  692.         break;
  693.  
  694.     case VAProfileHEVCMain:
  695.         if (HAS_HEVC_DECODING(i965))
  696.             entrypoint_list[n++] = VAEntrypointVLD;
  697.  
  698.         if (HAS_HEVC_ENCODING(i965))
  699.             entrypoint_list[n++] = VAEntrypointEncSlice;
  700.  
  701.         break;
  702.  
  703.     case VAProfileHEVCMain10:
  704.         if (HAS_HEVC10_DECODING(i965))
  705.             entrypoint_list[n++] = VAEntrypointVLD;
  706.  
  707.         break;
  708.  
  709.     case VAProfileVP9Profile0:
  710.         if(HAS_VP9_DECODING(i965))
  711.             entrypoint_list[n++] = VAEntrypointVLD;
  712.  
  713.         if (i965->wrapper_pdrvctx) {
  714.             VAStatus va_status = VA_STATUS_SUCCESS;
  715.             VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
  716.  
  717.             CALL_VTABLE(pdrvctx, va_status,
  718.                         vaQueryConfigEntrypoints(pdrvctx, profile,
  719.                                                  entrypoint_list,
  720.                                                  num_entrypoints));
  721.             return va_status;
  722.         }
  723.  
  724.         break;
  725.  
  726.     default:
  727.         break;
  728.     }
  729.  
  730.     /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
  731.     ASSERT_RET(n <= I965_MAX_ENTRYPOINTS, VA_STATUS_ERROR_OPERATION_FAILED);
  732.     *num_entrypoints = n;
  733.     return n > 0 ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
  734. }
  735.  
  736. static VAStatus
  737. i965_validate_config(VADriverContextP ctx, VAProfile profile,
  738.     VAEntrypoint entrypoint)
  739. {
  740.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  741.     VAStatus va_status;
  742.  
  743.     /* Validate profile & entrypoint */
  744.     switch (profile) {
  745.     case VAProfileMPEG2Simple:
  746.     case VAProfileMPEG2Main:
  747.         if ((HAS_MPEG2_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
  748.             (HAS_MPEG2_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
  749.             va_status = VA_STATUS_SUCCESS;
  750.         } else {
  751.             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
  752.         }
  753.         break;
  754.  
  755.     case VAProfileH264ConstrainedBaseline:
  756.     case VAProfileH264Main:
  757.     case VAProfileH264High:
  758.         if ((HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
  759.             (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
  760.             va_status = VA_STATUS_SUCCESS;
  761.         } else {
  762.             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
  763.         }
  764.         break;
  765.  
  766.     case VAProfileVC1Simple:
  767.     case VAProfileVC1Main:
  768.     case VAProfileVC1Advanced:
  769.         if (HAS_VC1_DECODING(i965) && entrypoint == VAEntrypointVLD) {
  770.             va_status = VA_STATUS_SUCCESS;
  771.         } else {
  772.             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
  773.         }
  774.         break;
  775.  
  776.     case VAProfileNone:
  777.         if (HAS_VPP(i965) && VAEntrypointVideoProc == entrypoint) {
  778.             va_status = VA_STATUS_SUCCESS;
  779.         } else {
  780.             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
  781.         }
  782.         break;
  783.  
  784.     case VAProfileJPEGBaseline:
  785.         if ((HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
  786.             (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)) {
  787.             va_status = VA_STATUS_SUCCESS;
  788.         } else {
  789.             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
  790.         }
  791.         break;
  792.  
  793.     case VAProfileVP8Version0_3:
  794.         if ((HAS_VP8_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
  795.             (HAS_VP8_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
  796.             va_status = VA_STATUS_SUCCESS;
  797.         } else {
  798.             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
  799.         }
  800.         break;
  801.  
  802.     case VAProfileH264MultiviewHigh:
  803.     case VAProfileH264StereoHigh:
  804.         if ((HAS_H264_MVC_DECODING_PROFILE(i965, profile) &&
  805.              entrypoint == VAEntrypointVLD) ||
  806.             (HAS_H264_MVC_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
  807.             va_status = VA_STATUS_SUCCESS;
  808.         } else {
  809.             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
  810.         }
  811.  
  812.         break;
  813.  
  814.     case VAProfileHEVCMain:
  815.         if ((HAS_HEVC_DECODING(i965) && (entrypoint == VAEntrypointVLD))||
  816.             (HAS_HEVC_ENCODING(i965) && (entrypoint == VAEntrypointEncSlice)))
  817.             va_status = VA_STATUS_SUCCESS;
  818.         else
  819.             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
  820.  
  821.         break;
  822.  
  823.     case VAProfileHEVCMain10:
  824.         if (HAS_HEVC10_DECODING(i965) && (entrypoint == VAEntrypointVLD))
  825.             va_status = VA_STATUS_SUCCESS;
  826.         else
  827.             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
  828.  
  829.         break;
  830.  
  831.     case VAProfileVP9Profile0:
  832.         if ((HAS_VP9_DECODING(i965)) && (entrypoint == VAEntrypointVLD))
  833.             va_status = VA_STATUS_SUCCESS;
  834.         else if (i965->wrapper_pdrvctx)
  835.             va_status = VA_STATUS_SUCCESS;
  836.         else
  837.             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
  838.         break;
  839.  
  840.     default:
  841.         va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
  842.         break;
  843.     }
  844.     return va_status;
  845. }
  846.  
  847. static uint32_t
  848. i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
  849.     VAEntrypoint entrypoint)
  850. {
  851.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  852.     uint32_t chroma_formats = VA_RT_FORMAT_YUV420;
  853.  
  854.     switch (profile) {
  855.     case VAProfileH264ConstrainedBaseline:
  856.     case VAProfileH264Main:
  857.     case VAProfileH264High:
  858.         if (HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD)
  859.             chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
  860.         break;
  861.  
  862.     case VAProfileH264MultiviewHigh:
  863.     case VAProfileH264StereoHigh:
  864.         if (HAS_H264_MVC_DECODING(i965) && entrypoint == VAEntrypointVLD)
  865.             chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
  866.         break;
  867.  
  868.     case VAProfileJPEGBaseline:
  869.         if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD)
  870.             chroma_formats |= i965->codec_info->jpeg_dec_chroma_formats;
  871.         if (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)
  872.             chroma_formats |= i965->codec_info->jpeg_enc_chroma_formats;
  873.         break;
  874.  
  875.     case VAProfileHEVCMain10:
  876.         chroma_formats = 0; // clear YUV420 8bits format support
  877.         if (HAS_HEVC10_DECODING(i965) && entrypoint == VAEntrypointVLD)
  878.             chroma_formats |= i965->codec_info->hevc_dec_chroma_formats;
  879.         break;
  880.     default:
  881.         break;
  882.     }
  883.     return chroma_formats;
  884. }
  885.  
  886. VAStatus
  887. i965_GetConfigAttributes(VADriverContextP ctx,
  888.                          VAProfile profile,
  889.                          VAEntrypoint entrypoint,
  890.                          VAConfigAttrib *attrib_list,  /* in/out */
  891.                          int num_attribs)
  892. {
  893.     VAStatus va_status;
  894.     int i;
  895.  
  896.     va_status = i965_validate_config(ctx, profile, entrypoint);
  897.     if (va_status != VA_STATUS_SUCCESS)
  898.         return va_status;
  899.  
  900.     /* Other attributes don't seem to be defined */
  901.     /* What to do if we don't know the attribute? */
  902.     for (i = 0; i < num_attribs; i++) {
  903.         attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
  904.         switch (attrib_list[i].type) {
  905.         case VAConfigAttribRTFormat:
  906.             attrib_list[i].value = i965_get_default_chroma_formats(ctx,
  907.                 profile, entrypoint);
  908.             break;
  909.  
  910.         case VAConfigAttribRateControl:
  911.             if (entrypoint == VAEntrypointEncSlice) {
  912.                 attrib_list[i].value = VA_RC_CQP;
  913.  
  914.                 if (profile != VAProfileMPEG2Main &&
  915.                     profile != VAProfileMPEG2Simple)
  916.                     attrib_list[i].value |= VA_RC_CBR;
  917.                 break;
  918.             }
  919.             break;
  920.  
  921.         case VAConfigAttribEncPackedHeaders:
  922.             if (entrypoint == VAEntrypointEncSlice) {
  923.                 attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
  924.                 if (profile == VAProfileH264ConstrainedBaseline ||
  925.                     profile == VAProfileH264Main ||
  926.                     profile == VAProfileH264High ||
  927.                     profile == VAProfileH264StereoHigh ||
  928.                     profile == VAProfileH264MultiviewHigh ||
  929.                     profile == VAProfileHEVCMain) {
  930.                     attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA |
  931.                                              VA_ENC_PACKED_HEADER_SLICE);
  932.                 }
  933.                 break;
  934.             }
  935.             else if (entrypoint == VAEntrypointEncPicture) {
  936.                 if (profile == VAProfileJPEGBaseline)
  937.                     attrib_list[i].value = VA_ENC_PACKED_HEADER_RAW_DATA;
  938.             }
  939.             break;
  940.  
  941.         case VAConfigAttribEncMaxRefFrames:
  942.             if (entrypoint == VAEntrypointEncSlice) {
  943.                 attrib_list[i].value = (1 << 16) | (1 << 0);
  944.                 break;
  945.             }
  946.             break;
  947.  
  948.         case VAConfigAttribEncQualityRange:
  949.             if (entrypoint == VAEntrypointEncSlice) {
  950.                 attrib_list[i].value = 1;
  951.                 if (profile == VAProfileH264ConstrainedBaseline ||
  952.                     profile == VAProfileH264Main ||
  953.                     profile == VAProfileH264High )
  954.                     attrib_list[i].value = ENCODER_QUALITY_RANGE;
  955.                 break;
  956.             }
  957.             break;
  958.  
  959.         case VAConfigAttribEncJPEG:
  960.             if( entrypoint == VAEntrypointEncPicture) {
  961.                 VAConfigAttribValEncJPEG *configVal = (VAConfigAttribValEncJPEG*)&(attrib_list[i].value);
  962.                 (configVal->bits).arithmatic_coding_mode = 0; // Huffman coding is used
  963.                 (configVal->bits).progressive_dct_mode = 0;   // Only Sequential DCT is supported
  964.                 (configVal->bits).non_interleaved_mode = 1;   // Support both interleaved and non-interleaved
  965.                 (configVal->bits).differential_mode = 0;      // Baseline DCT is non-differential
  966.                 (configVal->bits).max_num_components = 3;     // Only 3 components supported
  967.                 (configVal->bits).max_num_scans = 1;          // Only 1 scan per frame
  968.                 (configVal->bits).max_num_huffman_tables = 3; // Max 3 huffman tables
  969.                 (configVal->bits).max_num_quantization_tables = 3; // Max 3 quantization tables
  970.             }
  971.             break;
  972.  
  973.         case VAConfigAttribDecSliceMode:
  974.             attrib_list[i].value = VA_DEC_SLICE_MODE_NORMAL;
  975.             break;
  976.  
  977.         default:
  978.             /* Do nothing */
  979.             attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
  980.             break;
  981.         }
  982.     }
  983.  
  984.     return VA_STATUS_SUCCESS;
  985. }
  986.  
  987. static void
  988. i965_destroy_config(struct object_heap *heap, struct object_base *obj)
  989. {
  990.     object_heap_free(heap, obj);
  991. }
  992.  
  993. static VAConfigAttrib *
  994. i965_lookup_config_attribute(struct object_config *obj_config,
  995.     VAConfigAttribType type)
  996. {
  997.     int i;
  998.  
  999.     for (i = 0; i < obj_config->num_attribs; i++) {
  1000.         VAConfigAttrib * const attrib = &obj_config->attrib_list[i];
  1001.         if (attrib->type == type)
  1002.             return attrib;
  1003.     }
  1004.     return NULL;
  1005. }
  1006.  
  1007. static VAStatus
  1008. i965_append_config_attribute(struct object_config *obj_config,
  1009.     const VAConfigAttrib *new_attrib)
  1010. {
  1011.     VAConfigAttrib *attrib;
  1012.  
  1013.     if (obj_config->num_attribs >= I965_MAX_CONFIG_ATTRIBUTES)
  1014.         return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
  1015.  
  1016.     attrib = &obj_config->attrib_list[obj_config->num_attribs++];
  1017.     attrib->type = new_attrib->type;
  1018.     attrib->value = new_attrib->value;
  1019.     return VA_STATUS_SUCCESS;
  1020. }
  1021.  
  1022. static VAStatus
  1023. i965_ensure_config_attribute(struct object_config *obj_config,
  1024.     const VAConfigAttrib *new_attrib)
  1025. {
  1026.     VAConfigAttrib *attrib;
  1027.  
  1028.     /* Check for existing attributes */
  1029.     attrib = i965_lookup_config_attribute(obj_config, new_attrib->type);
  1030.     if (attrib) {
  1031.         /* Update existing attribute */
  1032.         attrib->value = new_attrib->value;
  1033.         return VA_STATUS_SUCCESS;
  1034.     }
  1035.     return i965_append_config_attribute(obj_config, new_attrib);
  1036. }
  1037.  
  1038. VAStatus
  1039. i965_CreateConfig(VADriverContextP ctx,
  1040.                   VAProfile profile,
  1041.                   VAEntrypoint entrypoint,
  1042.                   VAConfigAttrib *attrib_list,
  1043.                   int num_attribs,
  1044.                   VAConfigID *config_id)        /* out */
  1045. {
  1046.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  1047.     struct object_config *obj_config;
  1048.     int configID;
  1049.     int i;
  1050.     VAStatus vaStatus;
  1051.  
  1052.     vaStatus = i965_validate_config(ctx, profile, entrypoint);
  1053.  
  1054.     if (VA_STATUS_SUCCESS != vaStatus) {
  1055.         return vaStatus;
  1056.     }
  1057.  
  1058.     configID = NEW_CONFIG_ID();
  1059.     obj_config = CONFIG(configID);
  1060.  
  1061.     if (NULL == obj_config) {
  1062.         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
  1063.         return vaStatus;
  1064.     }
  1065.  
  1066.     obj_config->profile = profile;
  1067.     obj_config->entrypoint = entrypoint;
  1068.     obj_config->num_attribs = 0;
  1069.     obj_config->wrapper_config = VA_INVALID_ID;
  1070.  
  1071.     for (i = 0; i < num_attribs; i++) {
  1072.         vaStatus = i965_ensure_config_attribute(obj_config, &attrib_list[i]);
  1073.         if (vaStatus != VA_STATUS_SUCCESS)
  1074.             break;
  1075.     }
  1076.  
  1077.     if (vaStatus == VA_STATUS_SUCCESS) {
  1078.         VAConfigAttrib attrib, *attrib_found;
  1079.         attrib.type = VAConfigAttribRTFormat;
  1080.         attrib.value = i965_get_default_chroma_formats(ctx, profile, entrypoint);
  1081.         attrib_found = i965_lookup_config_attribute(obj_config, attrib.type);
  1082.         if (!attrib_found || !attrib_found->value)
  1083.             vaStatus = i965_append_config_attribute(obj_config, &attrib);
  1084.         else if (!(attrib_found->value & attrib.value))
  1085.             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
  1086.     }
  1087.  
  1088.     if ((vaStatus == VA_STATUS_SUCCESS) &&
  1089.         (profile == VAProfileVP9Profile0)) {
  1090.  
  1091.         if (i965->wrapper_pdrvctx) {
  1092.             VAGenericID wrapper_config;
  1093.  
  1094.             CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
  1095.                         vaCreateConfig(i965->wrapper_pdrvctx, profile,
  1096.                                        entrypoint, attrib_list,
  1097.                                        num_attribs, &wrapper_config));
  1098.  
  1099.             if (vaStatus == VA_STATUS_SUCCESS)
  1100.                 obj_config->wrapper_config = wrapper_config;
  1101.         }
  1102.     }
  1103.  
  1104.     /* Error recovery */
  1105.     if (VA_STATUS_SUCCESS != vaStatus) {
  1106.         i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
  1107.     } else {
  1108.         *config_id = configID;
  1109.     }
  1110.  
  1111.     return vaStatus;
  1112. }
  1113.  
  1114. VAStatus
  1115. i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
  1116. {
  1117.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1118.     struct object_config *obj_config = CONFIG(config_id);
  1119.     VAStatus vaStatus;
  1120.  
  1121.     if (NULL == obj_config) {
  1122.         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
  1123.         return vaStatus;
  1124.     }
  1125.  
  1126.     if ((obj_config->wrapper_config != VA_INVALID_ID) &&
  1127.         i965->wrapper_pdrvctx) {
  1128.         CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
  1129.                     vaDestroyConfig(i965->wrapper_pdrvctx,
  1130.                                     obj_config->wrapper_config));
  1131.         obj_config->wrapper_config = VA_INVALID_ID;
  1132.     }
  1133.  
  1134.     i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
  1135.     return VA_STATUS_SUCCESS;
  1136. }
  1137.  
  1138. VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
  1139.                                     VAConfigID config_id,
  1140.                                     VAProfile *profile,                 /* out */
  1141.                                     VAEntrypoint *entrypoint,           /* out */
  1142.                                     VAConfigAttrib *attrib_list,        /* out */
  1143.                                     int *num_attribs)                   /* out */
  1144. {
  1145.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1146.     struct object_config *obj_config = CONFIG(config_id);
  1147.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  1148.     int i;
  1149.  
  1150.     ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
  1151.     *profile = obj_config->profile;
  1152.     *entrypoint = obj_config->entrypoint;
  1153.     *num_attribs = obj_config->num_attribs;
  1154.  
  1155.     for(i = 0; i < obj_config->num_attribs; i++) {
  1156.         attrib_list[i] = obj_config->attrib_list[i];
  1157.     }
  1158.  
  1159.     return vaStatus;
  1160. }
  1161.  
  1162. void
  1163. i965_destroy_surface_storage(struct object_surface *obj_surface)
  1164. {
  1165.     if (!obj_surface)
  1166.         return;
  1167.  
  1168.     dri_bo_unreference(obj_surface->bo);
  1169.     obj_surface->bo = NULL;
  1170.  
  1171.     if (obj_surface->free_private_data != NULL) {
  1172.         obj_surface->free_private_data(&obj_surface->private_data);
  1173.         obj_surface->private_data = NULL;
  1174.     }
  1175. }
  1176.  
  1177. static void
  1178. i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
  1179. {
  1180.     struct object_surface *obj_surface = (struct object_surface *)obj;
  1181.  
  1182.     i965_destroy_surface_storage(obj_surface);
  1183.     object_heap_free(heap, obj);
  1184. }
  1185.  
  1186. static VAStatus
  1187. i965_surface_native_memory(VADriverContextP ctx,
  1188.                            struct object_surface *obj_surface,
  1189.                            int format,
  1190.                            int expected_fourcc)
  1191. {
  1192.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1193.     int tiling = HAS_TILED_SURFACE(i965);
  1194.  
  1195.     if (!expected_fourcc)
  1196.         return VA_STATUS_SUCCESS;
  1197.  
  1198.     // todo, should we disable tiling for 422 format?
  1199.     if (expected_fourcc == VA_FOURCC_I420 ||
  1200.         expected_fourcc == VA_FOURCC_IYUV ||
  1201.         expected_fourcc == VA_FOURCC_YV12 ||
  1202.         expected_fourcc == VA_FOURCC_YV16)
  1203.         tiling = 0;
  1204.  
  1205.     return i965_check_alloc_surface_bo(ctx, obj_surface, tiling, expected_fourcc, get_sampling_from_fourcc(expected_fourcc));
  1206. }
  1207.  
  1208. static VAStatus
  1209. i965_suface_external_memory(VADriverContextP ctx,
  1210.                             struct object_surface *obj_surface,
  1211.                             int external_memory_type,
  1212.                             VASurfaceAttribExternalBuffers *memory_attibute,
  1213.                             int index)
  1214. {
  1215.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1216.  
  1217.     if (!memory_attibute ||
  1218.         !memory_attibute->buffers ||
  1219.         index > memory_attibute->num_buffers)
  1220.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  1221.  
  1222.     ASSERT_RET(obj_surface->orig_width == memory_attibute->width, VA_STATUS_ERROR_INVALID_PARAMETER);
  1223.     ASSERT_RET(obj_surface->orig_height == memory_attibute->height, VA_STATUS_ERROR_INVALID_PARAMETER);
  1224.     ASSERT_RET(memory_attibute->num_planes >= 1, VA_STATUS_ERROR_INVALID_PARAMETER);
  1225.  
  1226.     obj_surface->fourcc = memory_attibute->pixel_format;
  1227.     obj_surface->width = memory_attibute->pitches[0];
  1228.     obj_surface->size = memory_attibute->data_size;
  1229.  
  1230.     if (memory_attibute->num_planes == 1)
  1231.         obj_surface->height = memory_attibute->data_size / obj_surface->width;
  1232.     else
  1233.         obj_surface->height = memory_attibute->offsets[1] / obj_surface->width;
  1234.  
  1235.     obj_surface->x_cb_offset = 0; /* X offset is always 0 */
  1236.     obj_surface->x_cr_offset = 0;
  1237.  
  1238.     switch (obj_surface->fourcc) {
  1239.     case VA_FOURCC_NV12:
  1240.     case VA_FOURCC_P010:
  1241.         ASSERT_RET(memory_attibute->num_planes == 2, VA_STATUS_ERROR_INVALID_PARAMETER);
  1242.         ASSERT_RET(memory_attibute->pitches[0] == memory_attibute->pitches[1], VA_STATUS_ERROR_INVALID_PARAMETER);
  1243.  
  1244.         obj_surface->subsampling = SUBSAMPLE_YUV420;
  1245.         obj_surface->y_cb_offset = obj_surface->height;
  1246.         obj_surface->y_cr_offset = obj_surface->height;
  1247.         obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  1248.         obj_surface->cb_cr_height = obj_surface->orig_height / 2;
  1249.         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
  1250.  
  1251.         break;
  1252.  
  1253.     case VA_FOURCC_YV12:
  1254.     case VA_FOURCC_IMC1:
  1255.         ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
  1256.         ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
  1257.  
  1258.         obj_surface->subsampling = SUBSAMPLE_YUV420;
  1259.         obj_surface->y_cr_offset = obj_surface->height;
  1260.         obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
  1261.         obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  1262.         obj_surface->cb_cr_height = obj_surface->orig_height / 2;
  1263.         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
  1264.  
  1265.         break;
  1266.  
  1267.     case VA_FOURCC_I420:
  1268.     case VA_FOURCC_IYUV:
  1269.     case VA_FOURCC_IMC3:
  1270.         ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
  1271.         ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
  1272.  
  1273.         obj_surface->subsampling = SUBSAMPLE_YUV420;
  1274.         obj_surface->y_cb_offset = obj_surface->height;
  1275.         obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
  1276.         obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  1277.         obj_surface->cb_cr_height = obj_surface->orig_height / 2;
  1278.         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
  1279.  
  1280.         break;
  1281.  
  1282.     case VA_FOURCC_YUY2:
  1283.     case VA_FOURCC_UYVY:
  1284.         ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
  1285.  
  1286.         obj_surface->subsampling = SUBSAMPLE_YUV422H;
  1287.         obj_surface->y_cb_offset = 0;
  1288.         obj_surface->y_cr_offset = 0;
  1289.         obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  1290.         obj_surface->cb_cr_height = obj_surface->orig_height;
  1291.         obj_surface->cb_cr_pitch = memory_attibute->pitches[0];
  1292.  
  1293.         break;
  1294.  
  1295.     case VA_FOURCC_RGBA:
  1296.     case VA_FOURCC_RGBX:
  1297.     case VA_FOURCC_BGRA:
  1298.     case VA_FOURCC_BGRX:
  1299.         ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
  1300.  
  1301.         obj_surface->subsampling = SUBSAMPLE_RGBX;
  1302.         obj_surface->y_cb_offset = 0;
  1303.         obj_surface->y_cr_offset = 0;
  1304.         obj_surface->cb_cr_width = 0;
  1305.         obj_surface->cb_cr_height = 0;
  1306.         obj_surface->cb_cr_pitch = 0;
  1307.  
  1308.         break;
  1309.  
  1310.     case VA_FOURCC_Y800: /* monochrome surface */
  1311.         ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
  1312.  
  1313.         obj_surface->subsampling = SUBSAMPLE_YUV400;
  1314.         obj_surface->y_cb_offset = 0;
  1315.         obj_surface->y_cr_offset = 0;
  1316.         obj_surface->cb_cr_width = 0;
  1317.         obj_surface->cb_cr_height = 0;
  1318.         obj_surface->cb_cr_pitch = 0;
  1319.  
  1320.         break;
  1321.  
  1322.     case VA_FOURCC_411P:
  1323.         ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
  1324.         ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
  1325.  
  1326.         obj_surface->subsampling = SUBSAMPLE_YUV411;
  1327.         obj_surface->y_cb_offset = 0;
  1328.         obj_surface->y_cr_offset = 0;
  1329.         obj_surface->cb_cr_width = obj_surface->orig_width / 4;
  1330.         obj_surface->cb_cr_height = obj_surface->orig_height;
  1331.         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
  1332.  
  1333.         break;
  1334.  
  1335.     case VA_FOURCC_422H:
  1336.         ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
  1337.         ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
  1338.  
  1339.         obj_surface->subsampling = SUBSAMPLE_YUV422H;
  1340.         obj_surface->y_cb_offset = obj_surface->height;
  1341.         obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
  1342.         obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  1343.         obj_surface->cb_cr_height = obj_surface->orig_height;
  1344.         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
  1345.  
  1346.         break;
  1347.  
  1348.     case VA_FOURCC_YV16:
  1349.         assert(memory_attibute->num_planes == 3);
  1350.         assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
  1351.  
  1352.         obj_surface->subsampling = SUBSAMPLE_YUV422H;
  1353.         obj_surface->y_cr_offset = memory_attibute->offsets[1] / obj_surface->width;
  1354.         obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
  1355.         obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  1356.         obj_surface->cb_cr_height = obj_surface->orig_height;
  1357.         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
  1358.  
  1359.         break;
  1360.  
  1361.     case VA_FOURCC_422V:
  1362.         ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
  1363.         ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
  1364.  
  1365.         obj_surface->subsampling = SUBSAMPLE_YUV422H;
  1366.         obj_surface->y_cb_offset = obj_surface->height;
  1367.         obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
  1368.         obj_surface->cb_cr_width = obj_surface->orig_width;
  1369.         obj_surface->cb_cr_height = obj_surface->orig_height / 2;
  1370.         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
  1371.  
  1372.         break;
  1373.  
  1374.     case VA_FOURCC_444P:
  1375.         ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
  1376.         ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
  1377.  
  1378.         obj_surface->subsampling = SUBSAMPLE_YUV444;
  1379.         obj_surface->y_cb_offset = obj_surface->height;
  1380.         obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
  1381.         obj_surface->cb_cr_width = obj_surface->orig_width;
  1382.         obj_surface->cb_cr_height = obj_surface->orig_height;
  1383.         obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
  1384.  
  1385.         break;
  1386.  
  1387.     default:
  1388.  
  1389.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  1390.     }
  1391.  
  1392.     if (external_memory_type == I965_SURFACE_MEM_GEM_FLINK)
  1393.         obj_surface->bo = drm_intel_bo_gem_create_from_name(i965->intel.bufmgr,
  1394.                                                             "gem flinked vaapi surface",
  1395.                                                             memory_attibute->buffers[index]);
  1396. //    else if (external_memory_type == I965_SURFACE_MEM_DRM_PRIME)
  1397. //        obj_surface->bo = drm_intel_bo_gem_create_from_prime(i965->intel.bufmgr,
  1398. //                                                             memory_attibute->buffers[index],
  1399. //                                                             obj_surface->size);
  1400.  
  1401.     if (!obj_surface->bo)
  1402.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  1403.  
  1404.     return VA_STATUS_SUCCESS;
  1405. }
  1406.  
  1407. /* byte-per-pixel of the first plane */
  1408. static int
  1409. bpp_1stplane_by_fourcc(unsigned int fourcc)
  1410. {
  1411.     const i965_fourcc_info *info = get_fourcc_info(fourcc);
  1412.  
  1413.     if (info && (info->flag & I_S))
  1414.         return info->bpp[0] / 8;
  1415.     else
  1416.         return 0;
  1417. }
  1418.  
  1419. static VAStatus
  1420. i965_CreateSurfaces2(
  1421.     VADriverContextP    ctx,
  1422.     unsigned int        format,
  1423.     unsigned int        width,
  1424.     unsigned int        height,
  1425.     VASurfaceID        *surfaces,
  1426.     unsigned int        num_surfaces,
  1427.     VASurfaceAttrib    *attrib_list,
  1428.     unsigned int        num_attribs
  1429.     )
  1430. {
  1431.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1432.     int i,j;
  1433.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  1434.     int expected_fourcc = 0;
  1435.     int memory_type = I965_SURFACE_MEM_NATIVE; /* native */
  1436.     VASurfaceAttribExternalBuffers *memory_attibute = NULL;
  1437.  
  1438.     for (i = 0; i < num_attribs && attrib_list; i++) {
  1439.         if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
  1440.             (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
  1441.             ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
  1442.             expected_fourcc = attrib_list[i].value.value.i;
  1443.         }
  1444.  
  1445.         if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&
  1446.             (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
  1447.  
  1448.             ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
  1449.  
  1450.             if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
  1451.                 memory_type = I965_SURFACE_MEM_GEM_FLINK; /* flinked GEM handle */
  1452.             else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)
  1453.                 memory_type = I965_SURFACE_MEM_DRM_PRIME; /* drm prime fd */
  1454.             else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_VA)
  1455.                 memory_type = I965_SURFACE_MEM_NATIVE; /* va native memory, to be allocated */
  1456.         }
  1457.  
  1458.         if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&
  1459.             (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {
  1460.             ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypePointer, VA_STATUS_ERROR_INVALID_PARAMETER);
  1461.             memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;
  1462.         }
  1463.     }
  1464.  
  1465.     /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used
  1466.      * for post-processing (including color conversion) */
  1467.     if (VA_RT_FORMAT_YUV420 != format &&
  1468.         VA_RT_FORMAT_YUV420_10BPP != format &&
  1469.         VA_RT_FORMAT_YUV422 != format &&
  1470.         VA_RT_FORMAT_YUV444 != format &&
  1471.         VA_RT_FORMAT_YUV411 != format &&
  1472.         VA_RT_FORMAT_YUV400 != format &&
  1473.         VA_RT_FORMAT_RGB32  != format) {
  1474.         return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
  1475.     }
  1476.  
  1477.     for (i = 0; i < num_surfaces; i++) {
  1478.         int surfaceID = NEW_SURFACE_ID();
  1479.         struct object_surface *obj_surface = SURFACE(surfaceID);
  1480.  
  1481.         if (NULL == obj_surface) {
  1482.             vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
  1483.             break;
  1484.         }
  1485.  
  1486.         surfaces[i] = surfaceID;
  1487.         obj_surface->status = VASurfaceReady;
  1488.         obj_surface->orig_width = width;
  1489.         obj_surface->orig_height = height;
  1490.         obj_surface->user_disable_tiling = false;
  1491.         obj_surface->user_h_stride_set = false;
  1492.         obj_surface->user_v_stride_set = false;
  1493.  
  1494.         obj_surface->subpic_render_idx = 0;
  1495.         for(j = 0; j < I965_MAX_SUBPIC_SUM; j++){
  1496.            obj_surface->subpic[j] = VA_INVALID_ID;
  1497.            obj_surface->obj_subpic[j] = NULL;
  1498.         }
  1499.  
  1500.         assert(i965->codec_info->min_linear_wpitch);
  1501.         assert(i965->codec_info->min_linear_hpitch);
  1502.         obj_surface->width = ALIGN(width, i965->codec_info->min_linear_wpitch);
  1503.         obj_surface->height = ALIGN(height, i965->codec_info->min_linear_hpitch);
  1504.         obj_surface->flags = SURFACE_REFERENCED;
  1505.         obj_surface->fourcc = 0;
  1506.         obj_surface->expected_format = format;
  1507.         obj_surface->bo = NULL;
  1508.         obj_surface->locked_image_id = VA_INVALID_ID;
  1509.         obj_surface->derived_image_id = VA_INVALID_ID;
  1510.         obj_surface->private_data = NULL;
  1511.         obj_surface->free_private_data = NULL;
  1512.         obj_surface->subsampling = SUBSAMPLE_YUV420;
  1513.  
  1514.         obj_surface->wrapper_surface = VA_INVALID_ID;
  1515.         obj_surface->exported_primefd = -1;
  1516.  
  1517.         switch (memory_type) {
  1518.         case I965_SURFACE_MEM_NATIVE:
  1519.             if (memory_attibute) {
  1520.                 if (!(memory_attibute->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING))
  1521.                     obj_surface->user_disable_tiling = true;
  1522.  
  1523.                 if (memory_attibute->pixel_format) {
  1524.                     if (expected_fourcc)
  1525.                         ASSERT_RET(memory_attibute->pixel_format == expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
  1526.                     else
  1527.                         expected_fourcc = memory_attibute->pixel_format;
  1528.                 }
  1529.                 ASSERT_RET(expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
  1530.                 if (memory_attibute->pitches[0]) {
  1531.                     int bpp_1stplane = bpp_1stplane_by_fourcc(expected_fourcc);
  1532.                     ASSERT_RET(bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
  1533.                     obj_surface->width = memory_attibute->pitches[0];
  1534.                     obj_surface->user_h_stride_set = true;
  1535.                     ASSERT_RET(IS_ALIGNED(obj_surface->width, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
  1536.                     ASSERT_RET(obj_surface->width >= width * bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
  1537.  
  1538.                     if (memory_attibute->offsets[1]) {
  1539.                         ASSERT_RET(!memory_attibute->offsets[0], VA_STATUS_ERROR_INVALID_PARAMETER);
  1540.                         obj_surface->height = memory_attibute->offsets[1]/memory_attibute->pitches[0];
  1541.                         obj_surface->user_v_stride_set = true;
  1542.                         ASSERT_RET(IS_ALIGNED(obj_surface->height, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
  1543.                         ASSERT_RET(obj_surface->height >= height, VA_STATUS_ERROR_INVALID_PARAMETER);
  1544.                     }
  1545.                 }
  1546.             }
  1547.             vaStatus = i965_surface_native_memory(ctx,
  1548.                                                   obj_surface,
  1549.                                                   format,
  1550.                                                   expected_fourcc);
  1551.             break;
  1552.  
  1553.         case I965_SURFACE_MEM_GEM_FLINK:
  1554.         case I965_SURFACE_MEM_DRM_PRIME:
  1555.             vaStatus = i965_suface_external_memory(ctx,
  1556.                                                    obj_surface,
  1557.                                                    memory_type,
  1558.                                                    memory_attibute,
  1559.                                                    i);
  1560.             break;
  1561.         }
  1562.         if (VA_STATUS_SUCCESS != vaStatus) {
  1563.             i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
  1564.             break;
  1565.         }
  1566.     }
  1567.  
  1568.     /* Error recovery */
  1569.     if (VA_STATUS_SUCCESS != vaStatus) {
  1570.         /* surfaces[i-1] was the last successful allocation */
  1571.         for (; i--; ) {
  1572.             struct object_surface *obj_surface = SURFACE(surfaces[i]);
  1573.  
  1574.             surfaces[i] = VA_INVALID_SURFACE;
  1575.             assert(obj_surface);
  1576.             i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
  1577.         }
  1578.     }
  1579.  
  1580.     return vaStatus;
  1581. }
  1582.  
  1583. VAStatus
  1584. i965_CreateSurfaces(VADriverContextP ctx,
  1585.                     int width,
  1586.                     int height,
  1587.                     int format,
  1588.                     int num_surfaces,
  1589.                     VASurfaceID *surfaces)      /* out */
  1590. {
  1591.     return i965_CreateSurfaces2(ctx,
  1592.                                 format,
  1593.                                 width,
  1594.                                 height,
  1595.                                 surfaces,
  1596.                                 num_surfaces,
  1597.                                 NULL,
  1598.                                 0);
  1599. }
  1600.  
  1601. VAStatus
  1602. i965_DestroySurfaces(VADriverContextP ctx,
  1603.                      VASurfaceID *surface_list,
  1604.                      int num_surfaces)
  1605. {
  1606.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1607.     int i;
  1608.     VAStatus va_status = VA_STATUS_SUCCESS;
  1609.  
  1610.     for (i = num_surfaces; i--; ) {
  1611.         struct object_surface *obj_surface = SURFACE(surface_list[i]);
  1612.  
  1613.         ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
  1614.  
  1615.         if ((obj_surface->wrapper_surface != VA_INVALID_ID) &&
  1616.             i965->wrapper_pdrvctx) {
  1617.             CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
  1618.                         vaDestroySurfaces(i965->wrapper_pdrvctx,
  1619.                                           &(obj_surface->wrapper_surface),
  1620.                                           1));
  1621.             obj_surface->wrapper_surface = VA_INVALID_ID;
  1622.         }
  1623.         if (obj_surface->exported_primefd >= 0) {
  1624.            close(obj_surface->exported_primefd);
  1625.            obj_surface->exported_primefd = -1;
  1626.         }
  1627.  
  1628.         i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
  1629.     }
  1630.  
  1631.     return va_status;
  1632. }
  1633.  
  1634. VAStatus
  1635. i965_QueryImageFormats(VADriverContextP ctx,
  1636.                        VAImageFormat *format_list,      /* out */
  1637.                        int *num_formats)                /* out */
  1638. {
  1639.     int n;
  1640.  
  1641.     for (n = 0; i965_image_formats_map[n].va_format.fourcc != 0; n++) {
  1642.         const i965_image_format_map_t * const m = &i965_image_formats_map[n];
  1643.         if (format_list)
  1644.             format_list[n] = m->va_format;
  1645.     }
  1646.  
  1647.     if (num_formats)
  1648.         *num_formats = n;
  1649.  
  1650.     return VA_STATUS_SUCCESS;
  1651. }
  1652.  
  1653. /*
  1654.  * Guess the format when the usage of a VA surface is unknown
  1655.  * 1. Without a valid context: YV12
  1656.  * 2. The current context is valid:
  1657.  *    a) always NV12 on GEN6 and later
  1658.  *    b) I420 for MPEG-2 and NV12 for other codec on GEN4 & GEN5
  1659.  */
  1660. static void
  1661. i965_guess_surface_format(VADriverContextP ctx,
  1662.                           VASurfaceID surface,
  1663.                           unsigned int *fourcc,
  1664.                           unsigned int *is_tiled)
  1665. {
  1666.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1667.     struct object_context *obj_context = NULL;
  1668.     struct object_config *obj_config = NULL;
  1669.  
  1670.     *fourcc = VA_FOURCC_YV12;
  1671.     *is_tiled = 0;
  1672.  
  1673.     if (i965->current_context_id == VA_INVALID_ID)
  1674.         return;
  1675.  
  1676.     obj_context = CONTEXT(i965->current_context_id);
  1677.  
  1678.     if (!obj_context)
  1679.         return;
  1680.  
  1681.     obj_config = obj_context->obj_config;
  1682.     assert(obj_config);
  1683.  
  1684.     if (!obj_config)
  1685.         return;
  1686.  
  1687.     if (IS_GEN6(i965->intel.device_info) ||
  1688.         IS_GEN7(i965->intel.device_info) ||
  1689.         IS_GEN8(i965->intel.device_info) ||
  1690.         IS_GEN9(i965->intel.device_info)) {
  1691.         *fourcc = VA_FOURCC_NV12;
  1692.         *is_tiled = 1;
  1693.         return;
  1694.     }
  1695.  
  1696.     switch (obj_config->profile) {
  1697.     case VAProfileMPEG2Simple:
  1698.     case VAProfileMPEG2Main:
  1699.         *fourcc = VA_FOURCC_I420;
  1700.         *is_tiled = 0;
  1701.         break;
  1702.  
  1703.     default:
  1704.         *fourcc = VA_FOURCC_NV12;
  1705.         *is_tiled = 0;
  1706.         break;
  1707.     }
  1708. }
  1709.  
  1710. VAStatus
  1711. i965_QuerySubpictureFormats(VADriverContextP ctx,
  1712.                             VAImageFormat *format_list,         /* out */
  1713.                             unsigned int *flags,                /* out */
  1714.                             unsigned int *num_formats)          /* out */
  1715. {
  1716.     int n;
  1717.  
  1718.     for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
  1719.         const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
  1720.         if (format_list)
  1721.             format_list[n] = m->va_format;
  1722.         if (flags)
  1723.             flags[n] = m->va_flags;
  1724.     }
  1725.  
  1726.     if (num_formats)
  1727.         *num_formats = n;
  1728.  
  1729.     return VA_STATUS_SUCCESS;
  1730. }
  1731.  
  1732. static void
  1733. i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
  1734. {
  1735.     //    struct object_subpic *obj_subpic = (struct object_subpic *)obj;
  1736.  
  1737.     object_heap_free(heap, obj);
  1738. }
  1739.  
  1740. VAStatus
  1741. i965_CreateSubpicture(VADriverContextP ctx,
  1742.                       VAImageID image,
  1743.                       VASubpictureID *subpicture)         /* out */
  1744. {
  1745.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1746.     VASubpictureID subpicID = NEW_SUBPIC_ID()
  1747.     struct object_subpic *obj_subpic = SUBPIC(subpicID);
  1748.  
  1749.     if (!obj_subpic)
  1750.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  1751.  
  1752.     struct object_image *obj_image = IMAGE(image);
  1753.     if (!obj_image)
  1754.         return VA_STATUS_ERROR_INVALID_IMAGE;
  1755.  
  1756.     const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
  1757.     if (!m)
  1758.         return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
  1759.  
  1760.     *subpicture = subpicID;
  1761.     obj_subpic->image  = image;
  1762.     obj_subpic->obj_image = obj_image;
  1763.     obj_subpic->format = m->format;
  1764.     obj_subpic->width  = obj_image->image.width;
  1765.     obj_subpic->height = obj_image->image.height;
  1766.     obj_subpic->pitch  = obj_image->image.pitches[0];
  1767.     obj_subpic->bo     = obj_image->bo;
  1768.     obj_subpic->global_alpha = 1.0;
  1769.  
  1770.     return VA_STATUS_SUCCESS;
  1771. }
  1772.  
  1773. VAStatus
  1774. i965_DestroySubpicture(VADriverContextP ctx,
  1775.                        VASubpictureID subpicture)
  1776. {
  1777.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1778.     struct object_subpic *obj_subpic = SUBPIC(subpicture);
  1779.  
  1780.     if (!obj_subpic)
  1781.         return VA_STATUS_ERROR_INVALID_SUBPICTURE;
  1782.  
  1783.     ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
  1784.     i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
  1785.     return VA_STATUS_SUCCESS;
  1786. }
  1787.  
  1788. VAStatus
  1789. i965_SetSubpictureImage(VADriverContextP ctx,
  1790.                         VASubpictureID subpicture,
  1791.                         VAImageID image)
  1792. {
  1793.     /* TODO */
  1794.     return VA_STATUS_ERROR_UNIMPLEMENTED;
  1795. }
  1796.  
  1797. VAStatus
  1798. i965_SetSubpictureChromakey(VADriverContextP ctx,
  1799.                             VASubpictureID subpicture,
  1800.                             unsigned int chromakey_min,
  1801.                             unsigned int chromakey_max,
  1802.                             unsigned int chromakey_mask)
  1803. {
  1804.     /* TODO */
  1805.     return VA_STATUS_ERROR_UNIMPLEMENTED;
  1806. }
  1807.  
  1808. VAStatus
  1809. i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
  1810.                               VASubpictureID subpicture,
  1811.                               float global_alpha)
  1812. {
  1813.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1814.     struct object_subpic *obj_subpic = SUBPIC(subpicture);
  1815.  
  1816.     if(global_alpha > 1.0 || global_alpha < 0.0){
  1817.        return VA_STATUS_ERROR_INVALID_PARAMETER;
  1818.     }
  1819.  
  1820.     if (!obj_subpic)
  1821.         return VA_STATUS_ERROR_INVALID_SUBPICTURE;
  1822.  
  1823.     obj_subpic->global_alpha  = global_alpha;
  1824.  
  1825.     return VA_STATUS_SUCCESS;
  1826. }
  1827.  
  1828. VAStatus
  1829. i965_AssociateSubpicture(VADriverContextP ctx,
  1830.                          VASubpictureID subpicture,
  1831.                          VASurfaceID *target_surfaces,
  1832.                          int num_surfaces,
  1833.                          short src_x, /* upper left offset in subpicture */
  1834.                          short src_y,
  1835.                          unsigned short src_width,
  1836.                          unsigned short src_height,
  1837.                          short dest_x, /* upper left offset in surface */
  1838.                          short dest_y,
  1839.                          unsigned short dest_width,
  1840.                          unsigned short dest_height,
  1841.                          /*
  1842.                           * whether to enable chroma-keying or global-alpha
  1843.                           * see VA_SUBPICTURE_XXX values
  1844.                           */
  1845.                          unsigned int flags)
  1846. {
  1847.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1848.     struct object_subpic *obj_subpic = SUBPIC(subpicture);
  1849.     int i, j;
  1850.  
  1851.     if (!obj_subpic)
  1852.         return VA_STATUS_ERROR_INVALID_SUBPICTURE;
  1853.  
  1854.     ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
  1855.  
  1856.     obj_subpic->src_rect.x      = src_x;
  1857.     obj_subpic->src_rect.y      = src_y;
  1858.     obj_subpic->src_rect.width  = src_width;
  1859.     obj_subpic->src_rect.height = src_height;
  1860.     obj_subpic->dst_rect.x      = dest_x;
  1861.     obj_subpic->dst_rect.y      = dest_y;
  1862.     obj_subpic->dst_rect.width  = dest_width;
  1863.     obj_subpic->dst_rect.height = dest_height;
  1864.     obj_subpic->flags           = flags;
  1865.  
  1866.     for (i = 0; i < num_surfaces; i++) {
  1867.         struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
  1868.         if (!obj_surface)
  1869.             return VA_STATUS_ERROR_INVALID_SURFACE;
  1870.  
  1871.         for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
  1872.             if(obj_surface->subpic[j] == VA_INVALID_ID){
  1873.                 assert(obj_surface->obj_subpic[j] == NULL);
  1874.                 obj_surface->subpic[j] = subpicture;
  1875.                 obj_surface->obj_subpic[j] = obj_subpic;
  1876.                 break;
  1877.             }
  1878.         }
  1879.  
  1880.         if(j == I965_MAX_SUBPIC_SUM){
  1881.             return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
  1882.         }
  1883.  
  1884.     }
  1885.     return VA_STATUS_SUCCESS;
  1886. }
  1887.  
  1888.  
  1889. VAStatus
  1890. i965_DeassociateSubpicture(VADriverContextP ctx,
  1891.                            VASubpictureID subpicture,
  1892.                            VASurfaceID *target_surfaces,
  1893.                            int num_surfaces)
  1894. {
  1895.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  1896.     struct object_subpic *obj_subpic = SUBPIC(subpicture);
  1897.     int i, j;
  1898.  
  1899.     if (!obj_subpic)
  1900.         return VA_STATUS_ERROR_INVALID_SUBPICTURE;
  1901.  
  1902.     for (i = 0; i < num_surfaces; i++) {
  1903.         struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
  1904.         if (!obj_surface)
  1905.             return VA_STATUS_ERROR_INVALID_SURFACE;
  1906.  
  1907.         for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
  1908.             if (obj_surface->subpic[j] == subpicture) {
  1909.                 assert(obj_surface->obj_subpic[j] == obj_subpic);
  1910.                 obj_surface->subpic[j] = VA_INVALID_ID;
  1911.                 obj_surface->obj_subpic[j] = NULL;
  1912.                 break;
  1913.             }
  1914.         }
  1915.  
  1916.         if(j == I965_MAX_SUBPIC_SUM){
  1917.             return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
  1918.         }
  1919.     }
  1920.     return VA_STATUS_SUCCESS;
  1921. }
  1922.  
  1923. void
  1924. i965_reference_buffer_store(struct buffer_store **ptr,
  1925.                             struct buffer_store *buffer_store)
  1926. {
  1927.     assert(*ptr == NULL);
  1928.  
  1929.     if (buffer_store) {
  1930.         buffer_store->ref_count++;
  1931.         *ptr = buffer_store;
  1932.     }
  1933. }
  1934.  
  1935. void
  1936. i965_release_buffer_store(struct buffer_store **ptr)
  1937. {
  1938.     struct buffer_store *buffer_store = *ptr;
  1939.  
  1940.     if (buffer_store == NULL)
  1941.         return;
  1942.  
  1943.     assert(buffer_store->bo || buffer_store->buffer);
  1944.     assert(!(buffer_store->bo && buffer_store->buffer));
  1945.     buffer_store->ref_count--;
  1946.  
  1947.     if (buffer_store->ref_count == 0) {
  1948.         dri_bo_unreference(buffer_store->bo);
  1949.         free(buffer_store->buffer);
  1950.         buffer_store->bo = NULL;
  1951.         buffer_store->buffer = NULL;
  1952.         free(buffer_store);
  1953.     }
  1954.  
  1955.     *ptr = NULL;
  1956. }
  1957.  
  1958. static void
  1959. i965_destroy_context(struct object_heap *heap, struct object_base *obj)
  1960. {
  1961.     struct object_context *obj_context = (struct object_context *)obj;
  1962.     int i;
  1963.  
  1964.     if (obj_context->hw_context) {
  1965.         obj_context->hw_context->destroy(obj_context->hw_context);
  1966.         obj_context->hw_context = NULL;
  1967.     }
  1968.  
  1969.     if (obj_context->codec_type == CODEC_PROC) {
  1970.         i965_release_buffer_store(&obj_context->codec_state.proc.pipeline_param);
  1971.  
  1972.     } else if (obj_context->codec_type == CODEC_ENC) {
  1973.         assert(obj_context->codec_state.encode.num_slice_params <= obj_context->codec_state.encode.max_slice_params);
  1974.         i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
  1975.         i965_release_buffer_store(&obj_context->codec_state.encode.seq_param);
  1976.  
  1977.         for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++)
  1978.             i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
  1979.  
  1980.         free(obj_context->codec_state.encode.slice_params);
  1981.  
  1982.         assert(obj_context->codec_state.encode.num_slice_params_ext <= obj_context->codec_state.encode.max_slice_params_ext);
  1983.         i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
  1984.         i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
  1985.  
  1986.         for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
  1987.             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
  1988.  
  1989.         for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
  1990.             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
  1991.  
  1992.         for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
  1993.             i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i]);
  1994.  
  1995.         for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
  1996.             i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
  1997.  
  1998.         free(obj_context->codec_state.encode.slice_params_ext);
  1999.         if (obj_context->codec_state.encode.slice_rawdata_index) {
  2000.             free(obj_context->codec_state.encode.slice_rawdata_index);
  2001.             obj_context->codec_state.encode.slice_rawdata_index = NULL;
  2002.         }
  2003.         if (obj_context->codec_state.encode.slice_rawdata_count) {
  2004.             free(obj_context->codec_state.encode.slice_rawdata_count);
  2005.             obj_context->codec_state.encode.slice_rawdata_count = NULL;
  2006.         }
  2007.  
  2008.         if (obj_context->codec_state.encode.slice_header_index) {
  2009.             free(obj_context->codec_state.encode.slice_header_index);
  2010.             obj_context->codec_state.encode.slice_header_index = NULL;
  2011.         }
  2012.  
  2013.         for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
  2014.             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
  2015.         free(obj_context->codec_state.encode.packed_header_params_ext);
  2016.  
  2017.         for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
  2018.             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
  2019.         free(obj_context->codec_state.encode.packed_header_data_ext);
  2020.  
  2021.     } else {
  2022.         assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
  2023.         assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
  2024.  
  2025.         i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
  2026.         i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
  2027.         i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
  2028.  
  2029.         for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++)
  2030.             i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
  2031.  
  2032.         for (i = 0; i < obj_context->codec_state.decode.num_slice_datas; i++)
  2033.             i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
  2034.  
  2035.         free(obj_context->codec_state.decode.slice_params);
  2036.         free(obj_context->codec_state.decode.slice_datas);
  2037.     }
  2038.  
  2039.     free(obj_context->render_targets);
  2040.     object_heap_free(heap, obj);
  2041. }
  2042.  
  2043. VAStatus
  2044. i965_CreateContext(VADriverContextP ctx,
  2045.                    VAConfigID config_id,
  2046.                    int picture_width,
  2047.                    int picture_height,
  2048.                    int flag,
  2049.                    VASurfaceID *render_targets,
  2050.                    int num_render_targets,
  2051.                    VAContextID *context)                /* out */
  2052. {
  2053.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2054.     struct object_config *obj_config = CONFIG(config_id);
  2055.     struct object_context *obj_context = NULL;
  2056.     VAConfigAttrib *attrib;
  2057.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  2058.     int contextID;
  2059.     int i;
  2060.  
  2061.     if (NULL == obj_config) {
  2062.         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
  2063.         return vaStatus;
  2064.     }
  2065.  
  2066.     if (picture_width > i965->codec_info->max_width ||
  2067.         picture_height > i965->codec_info->max_height) {
  2068.         vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
  2069.         return vaStatus;
  2070.     }
  2071.  
  2072.     /* Validate flag */
  2073.     /* Validate picture dimensions */
  2074.     contextID = NEW_CONTEXT_ID();
  2075.     obj_context = CONTEXT(contextID);
  2076.  
  2077.     if (NULL == obj_context) {
  2078.         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
  2079.         return vaStatus;
  2080.     }
  2081.  
  2082.     *context = contextID;
  2083.     obj_context->flags = flag;
  2084.     obj_context->context_id = contextID;
  2085.     obj_context->obj_config = obj_config;
  2086.     obj_context->picture_width = picture_width;
  2087.     obj_context->picture_height = picture_height;
  2088.     obj_context->num_render_targets = num_render_targets;
  2089.     obj_context->render_targets =
  2090.         (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
  2091.     obj_context->hw_context = NULL;
  2092.     obj_context->wrapper_context = VA_INVALID_ID;
  2093.  
  2094.     if (!obj_context->render_targets)
  2095.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  2096.  
  2097.     for(i = 0; i < num_render_targets; i++) {
  2098.         if (NULL == SURFACE(render_targets[i])) {
  2099.             vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
  2100.             break;
  2101.         }
  2102.  
  2103.         obj_context->render_targets[i] = render_targets[i];
  2104.     }
  2105.  
  2106.     if (VA_STATUS_SUCCESS == vaStatus) {
  2107.         if (VAEntrypointVideoProc == obj_config->entrypoint) {
  2108.             obj_context->codec_type = CODEC_PROC;
  2109.             memset(&obj_context->codec_state.proc, 0, sizeof(obj_context->codec_state.proc));
  2110.             obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
  2111.             assert(i965->codec_info->proc_hw_context_init);
  2112.             obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
  2113.          } else if ((VAEntrypointEncSlice == obj_config->entrypoint) ||
  2114.                    (VAEntrypointEncPicture == obj_config->entrypoint)) { /*encode routine only*/
  2115.             VAConfigAttrib *packed_attrib;
  2116.             obj_context->codec_type = CODEC_ENC;
  2117.             memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
  2118.             obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
  2119.             obj_context->codec_state.encode.max_slice_params = NUM_SLICES;
  2120.             obj_context->codec_state.encode.slice_params = calloc(obj_context->codec_state.encode.max_slice_params,
  2121.                                                                sizeof(*obj_context->codec_state.encode.slice_params));
  2122.             obj_context->codec_state.encode.max_packed_header_params_ext = NUM_SLICES;
  2123.             obj_context->codec_state.encode.packed_header_params_ext =
  2124.                 calloc(obj_context->codec_state.encode.max_packed_header_params_ext,
  2125.                        sizeof(struct buffer_store *));
  2126.  
  2127.             obj_context->codec_state.encode.max_packed_header_data_ext = NUM_SLICES;
  2128.             obj_context->codec_state.encode.packed_header_data_ext =
  2129.                 calloc(obj_context->codec_state.encode.max_packed_header_data_ext,
  2130.                        sizeof(struct buffer_store *));
  2131.  
  2132.             obj_context->codec_state.encode.max_slice_num = NUM_SLICES;
  2133.             obj_context->codec_state.encode.slice_rawdata_index =
  2134.                 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
  2135.             obj_context->codec_state.encode.slice_rawdata_count =
  2136.                 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
  2137.  
  2138.             obj_context->codec_state.encode.slice_header_index =
  2139.                 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
  2140.  
  2141.             obj_context->codec_state.encode.vps_sps_seq_index = 0;
  2142.  
  2143.             obj_context->codec_state.encode.slice_index = 0;
  2144.             packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders);
  2145.             if (packed_attrib)
  2146.                 obj_context->codec_state.encode.packed_header_flag = packed_attrib->value;
  2147.             else {
  2148.                 /* use the default value. SPS/PPS/RAWDATA is passed from user
  2149.                  * while Slice_header data is generated by driver.
  2150.                  */
  2151.                 obj_context->codec_state.encode.packed_header_flag =
  2152.                                VA_ENC_PACKED_HEADER_SEQUENCE |
  2153.                                VA_ENC_PACKED_HEADER_PICTURE |
  2154.                                VA_ENC_PACKED_HEADER_RAW_DATA;
  2155.             }
  2156.             assert(i965->codec_info->enc_hw_context_init);
  2157.             obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
  2158.         } else {
  2159.             obj_context->codec_type = CODEC_DEC;
  2160.             memset(&obj_context->codec_state.decode, 0, sizeof(obj_context->codec_state.decode));
  2161.             obj_context->codec_state.decode.current_render_target = -1;
  2162.             obj_context->codec_state.decode.max_slice_params = NUM_SLICES;
  2163.             obj_context->codec_state.decode.max_slice_datas = NUM_SLICES;
  2164.             obj_context->codec_state.decode.slice_params = calloc(obj_context->codec_state.decode.max_slice_params,
  2165.                                                                sizeof(*obj_context->codec_state.decode.slice_params));
  2166.             obj_context->codec_state.decode.slice_datas = calloc(obj_context->codec_state.decode.max_slice_datas,
  2167.                                                               sizeof(*obj_context->codec_state.decode.slice_datas));
  2168.  
  2169.             assert(i965->codec_info->dec_hw_context_init);
  2170.             obj_context->hw_context = i965->codec_info->dec_hw_context_init(ctx, obj_config);
  2171.         }
  2172.     }
  2173.  
  2174.     attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribRTFormat);
  2175.     if (!attrib)
  2176.         return VA_STATUS_ERROR_INVALID_CONFIG;
  2177.     obj_context->codec_state.base.chroma_formats = attrib->value;
  2178.  
  2179.     if (obj_config->wrapper_config != VA_INVALID_ID) {
  2180.         /* The wrapper_pdrvctx should exist when wrapper_config is valid.
  2181.          * So it won't check i965->wrapper_pdrvctx again.
  2182.          * Fixme if it is incorrect.
  2183.          */
  2184.         VAGenericID wrapper_context;
  2185.  
  2186.         /*
  2187.          * The render_surface is not passed when calling
  2188.          * vaCreateContext.
  2189.          * If it is needed, we must get the wrapped surface
  2190.          * for the corresponding Surface_list.
  2191.          * So the wrapped surface conversion is deferred.
  2192.          */
  2193.         CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
  2194.                     vaCreateContext(i965->wrapper_pdrvctx,
  2195.                                     obj_config->wrapper_config,
  2196.                                     picture_width, picture_height,
  2197.                                     flag, NULL, 0,
  2198.                                     &wrapper_context));
  2199.  
  2200.         if (vaStatus == VA_STATUS_SUCCESS)
  2201.             obj_context->wrapper_context = wrapper_context;
  2202.     }
  2203.     /* Error recovery */
  2204.     if (VA_STATUS_SUCCESS != vaStatus) {
  2205.         i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
  2206.     }
  2207.  
  2208.     i965->current_context_id = contextID;
  2209.  
  2210.     return vaStatus;
  2211. }
  2212.  
  2213. VAStatus
  2214. i965_DestroyContext(VADriverContextP ctx, VAContextID context)
  2215. {
  2216.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2217.     struct object_context *obj_context = CONTEXT(context);
  2218.     VAStatus va_status = VA_STATUS_SUCCESS;
  2219.  
  2220.     ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
  2221.  
  2222.     if (i965->current_context_id == context)
  2223.         i965->current_context_id = VA_INVALID_ID;
  2224.  
  2225.     if ((obj_context->wrapper_context != VA_INVALID_ID) &&
  2226.         i965->wrapper_pdrvctx) {
  2227.         CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
  2228.                     vaDestroyContext(i965->wrapper_pdrvctx,
  2229.                                      obj_context->wrapper_context));
  2230.  
  2231.         obj_context->wrapper_context = VA_INVALID_ID;
  2232.     }
  2233.  
  2234.     i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
  2235.  
  2236.     return va_status;
  2237. }
  2238.  
  2239. static void
  2240. i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
  2241. {
  2242.     struct object_buffer *obj_buffer = (struct object_buffer *)obj;
  2243.  
  2244.     assert(obj_buffer->buffer_store);
  2245.     i965_release_buffer_store(&obj_buffer->buffer_store);
  2246.     object_heap_free(heap, obj);
  2247. }
  2248.  
  2249. static VAStatus
  2250. i965_create_buffer_internal(VADriverContextP ctx,
  2251.                             VAContextID context,
  2252.                             VABufferType type,
  2253.                             unsigned int size,
  2254.                             unsigned int num_elements,
  2255.                             void *data,
  2256.                             dri_bo *store_bo,
  2257.                             VABufferID *buf_id)
  2258. {
  2259.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2260.     struct object_buffer *obj_buffer = NULL;
  2261.     struct buffer_store *buffer_store = NULL;
  2262.     int bufferID;
  2263.     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
  2264.     struct object_context *obj_context = CONTEXT(context);
  2265.     int wrapper_flag = 0;
  2266.  
  2267.     /* Validate type */
  2268.     switch (type) {
  2269.     case VAPictureParameterBufferType:
  2270.     case VAIQMatrixBufferType:
  2271.     case VAQMatrixBufferType:
  2272.     case VABitPlaneBufferType:
  2273.     case VASliceGroupMapBufferType:
  2274.     case VASliceParameterBufferType:
  2275.     case VASliceDataBufferType:
  2276.     case VAMacroblockParameterBufferType:
  2277.     case VAResidualDataBufferType:
  2278.     case VADeblockingParameterBufferType:
  2279.     case VAImageBufferType:
  2280.     case VAEncCodedBufferType:
  2281.     case VAEncSequenceParameterBufferType:
  2282.     case VAEncPictureParameterBufferType:
  2283.     case VAEncSliceParameterBufferType:
  2284.     case VAEncPackedHeaderParameterBufferType:
  2285.     case VAEncPackedHeaderDataBufferType:
  2286.     case VAEncMiscParameterBufferType:
  2287.     case VAProcPipelineParameterBufferType:
  2288.     case VAProcFilterParameterBufferType:
  2289.     case VAHuffmanTableBufferType:
  2290.     case VAProbabilityBufferType:
  2291.         /* Ok */
  2292.         break;
  2293.  
  2294.     default:
  2295.         return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
  2296.     }
  2297.  
  2298.     bufferID = NEW_BUFFER_ID();
  2299.     obj_buffer = BUFFER(bufferID);
  2300.  
  2301.     if (NULL == obj_buffer) {
  2302.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  2303.     }
  2304.  
  2305.     if (type == VAEncCodedBufferType) {
  2306.         size += I965_CODEDBUFFER_HEADER_SIZE;
  2307.         size += 0x1000; /* for upper bound check */
  2308.     }
  2309.  
  2310.     obj_buffer->max_num_elements = num_elements;
  2311.     obj_buffer->num_elements = num_elements;
  2312.     obj_buffer->size_element = size;
  2313.     obj_buffer->type = type;
  2314.     obj_buffer->export_refcount = 0;
  2315.     obj_buffer->buffer_store = NULL;
  2316.     obj_buffer->wrapper_buffer = VA_INVALID_ID;
  2317.  
  2318.     buffer_store = calloc(1, sizeof(struct buffer_store));
  2319.     assert(buffer_store);
  2320.     buffer_store->ref_count = 1;
  2321.  
  2322.     if (obj_context &&
  2323.         (obj_context->wrapper_context != VA_INVALID_ID) &&
  2324.         i965->wrapper_pdrvctx) {
  2325.         VAGenericID wrapper_buffer;
  2326.         VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
  2327.  
  2328.         CALL_VTABLE(pdrvctx, vaStatus,
  2329.                     vaCreateBuffer(pdrvctx, obj_context->wrapper_context, type, size, num_elements,
  2330.                                    data, &wrapper_buffer));
  2331.         if (vaStatus == VA_STATUS_SUCCESS) {
  2332.             obj_buffer->wrapper_buffer = wrapper_buffer;
  2333.         } else {
  2334.             free(buffer_store);
  2335.             return vaStatus;
  2336.         }
  2337.         wrapper_flag = 1;
  2338.     }
  2339.  
  2340.     if (store_bo != NULL) {
  2341.         buffer_store->bo = store_bo;
  2342.         dri_bo_reference(buffer_store->bo);
  2343.  
  2344.         /* If the buffer is wrapped, the buffer_store is bogus. Unnecessary to copy it */
  2345.         if (data && !wrapper_flag)
  2346.             dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
  2347.     } else if (type == VASliceDataBufferType ||
  2348.                type == VAImageBufferType ||
  2349.                type == VAEncCodedBufferType ||
  2350.                type == VAProbabilityBufferType) {
  2351.  
  2352.         /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
  2353.          * So it is enough to allocate one 64 byte bo
  2354.          */
  2355.         if (wrapper_flag)
  2356.             buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr, "Bogus buffer",
  2357.                                             64, 64);
  2358.         else
  2359.             buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
  2360.                                             "Buffer",
  2361.                                             size * num_elements, 64);
  2362.         assert(buffer_store->bo);
  2363.  
  2364.         /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
  2365.          * In fact it can be skipped. But it is still allocated and it is
  2366.          * only to follow the normal flowchart of buffer_allocation/release.
  2367.          */
  2368.         if (!wrapper_flag) {
  2369.           if (type == VAEncCodedBufferType) {
  2370.             struct i965_coded_buffer_segment *coded_buffer_segment;
  2371.  
  2372.             dri_bo_map(buffer_store->bo, 1);
  2373.             coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual;
  2374.             coded_buffer_segment->base.size = size - I965_CODEDBUFFER_HEADER_SIZE;
  2375.             coded_buffer_segment->base.bit_offset = 0;
  2376.             coded_buffer_segment->base.status = 0;
  2377.             coded_buffer_segment->base.buf = NULL;
  2378.             coded_buffer_segment->base.next = NULL;
  2379.             coded_buffer_segment->mapped = 0;
  2380.             coded_buffer_segment->codec = 0;
  2381.             dri_bo_unmap(buffer_store->bo);
  2382.           } else if (data) {
  2383.               dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
  2384.           }
  2385.        }
  2386.  
  2387.     } else {
  2388.         int msize = size;
  2389.  
  2390.         if (type == VAEncPackedHeaderDataBufferType) {
  2391.             msize = ALIGN(size, 4);
  2392.         }
  2393.  
  2394.         /* If the buffer is wrapped, it is enough to allocate 4 bytes */
  2395.         if (wrapper_flag)
  2396.             buffer_store->buffer = malloc(4);
  2397.         else
  2398.             buffer_store->buffer = malloc(msize * num_elements);
  2399.         assert(buffer_store->buffer);
  2400.  
  2401.         if (data && (!wrapper_flag))
  2402.             memcpy(buffer_store->buffer, data, size * num_elements);
  2403.     }
  2404.  
  2405.     buffer_store->num_elements = obj_buffer->num_elements;
  2406.     i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
  2407.     i965_release_buffer_store(&buffer_store);
  2408.     *buf_id = bufferID;
  2409.  
  2410.     return VA_STATUS_SUCCESS;
  2411. }
  2412.  
  2413. VAStatus
  2414. i965_CreateBuffer(VADriverContextP ctx,
  2415.                   VAContextID context,          /* in */
  2416.                   VABufferType type,            /* in */
  2417.                   unsigned int size,            /* in */
  2418.                   unsigned int num_elements,    /* in */
  2419.                   void *data,                   /* in */
  2420.                   VABufferID *buf_id)           /* out */
  2421. {
  2422.     return i965_create_buffer_internal(ctx, context, type, size, num_elements, data, NULL, buf_id);
  2423. }
  2424.  
  2425.  
  2426. VAStatus
  2427. i965_BufferSetNumElements(VADriverContextP ctx,
  2428.                           VABufferID buf_id,           /* in */
  2429.                           unsigned int num_elements)   /* in */
  2430. {
  2431.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2432.     struct object_buffer *obj_buffer = BUFFER(buf_id);
  2433.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  2434.  
  2435.     ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
  2436.  
  2437.     /* When the wrapper_buffer exists, it will wrapper to the
  2438.      * buffer allocated from backend driver.
  2439.      */
  2440.     if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
  2441.         i965->wrapper_pdrvctx) {
  2442.         VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
  2443.  
  2444.         CALL_VTABLE(pdrvctx, vaStatus,
  2445.                     vaBufferSetNumElements(pdrvctx, obj_buffer->wrapper_buffer,
  2446.                                          num_elements));
  2447.         return vaStatus;
  2448.     }
  2449.  
  2450.     if ((num_elements < 0) ||
  2451.         (num_elements > obj_buffer->max_num_elements)) {
  2452.         vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
  2453.     } else {
  2454.         obj_buffer->num_elements = num_elements;
  2455.         if (obj_buffer->buffer_store != NULL) {
  2456.             obj_buffer->buffer_store->num_elements = num_elements;
  2457.         }
  2458.     }
  2459.  
  2460.     return vaStatus;
  2461. }
  2462.  
  2463. VAStatus
  2464. i965_MapBuffer(VADriverContextP ctx,
  2465.                VABufferID buf_id,       /* in */
  2466.                void **pbuf)             /* out */
  2467. {
  2468.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2469.     struct object_buffer *obj_buffer = BUFFER(buf_id);
  2470.     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
  2471.  
  2472.     ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
  2473.  
  2474.     /* When the wrapper_buffer exists, it will wrapper to the
  2475.      * buffer allocated from backend driver.
  2476.      */
  2477.     if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
  2478.         i965->wrapper_pdrvctx) {
  2479.         VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
  2480.  
  2481.         CALL_VTABLE(pdrvctx, vaStatus,
  2482.                     vaMapBuffer(pdrvctx, obj_buffer->wrapper_buffer, pbuf));
  2483.         return vaStatus;
  2484.     }
  2485.  
  2486.     ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
  2487.     ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_INVALID_BUFFER);
  2488.  
  2489.     if (obj_buffer->export_refcount > 0)
  2490.         return VA_STATUS_ERROR_INVALID_BUFFER;
  2491.  
  2492.     if (NULL != obj_buffer->buffer_store->bo) {
  2493.         unsigned int tiling, swizzle;
  2494.  
  2495.         dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
  2496.  
  2497.         if (tiling != I915_TILING_NONE)
  2498.             drm_intel_gem_bo_map_gtt(obj_buffer->buffer_store->bo);
  2499.         else
  2500.             dri_bo_map(obj_buffer->buffer_store->bo, 1);
  2501.  
  2502.         ASSERT_RET(obj_buffer->buffer_store->bo->virtual, VA_STATUS_ERROR_OPERATION_FAILED);
  2503.         *pbuf = obj_buffer->buffer_store->bo->virtual;
  2504.  
  2505.         if (obj_buffer->type == VAEncCodedBufferType) {
  2506.             int i;
  2507.             unsigned char *buffer = NULL;
  2508.             unsigned int  header_offset = I965_CODEDBUFFER_HEADER_SIZE;
  2509.             struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual);
  2510.  
  2511.             if (!coded_buffer_segment->mapped) {
  2512.                 unsigned char delimiter0, delimiter1, delimiter2, delimiter3, delimiter4;
  2513.  
  2514.                 coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
  2515.  
  2516.                 if (coded_buffer_segment->codec == CODEC_H264 ||
  2517.                     coded_buffer_segment->codec == CODEC_H264_MVC) {
  2518.                     delimiter0 = H264_DELIMITER0;
  2519.                     delimiter1 = H264_DELIMITER1;
  2520.                     delimiter2 = H264_DELIMITER2;
  2521.                     delimiter3 = H264_DELIMITER3;
  2522.                     delimiter4 = H264_DELIMITER4;
  2523.                 } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
  2524.                     delimiter0 = MPEG2_DELIMITER0;
  2525.                     delimiter1 = MPEG2_DELIMITER1;
  2526.                     delimiter2 = MPEG2_DELIMITER2;
  2527.                     delimiter3 = MPEG2_DELIMITER3;
  2528.                     delimiter4 = MPEG2_DELIMITER4;
  2529.                 } else if(coded_buffer_segment->codec == CODEC_JPEG) {
  2530.                     //In JPEG End of Image (EOI = 0xDDF9) marker can be used for delimiter.
  2531.                     delimiter0 = 0xFF;
  2532.                     delimiter1 = 0xD9;
  2533.                 } else if (coded_buffer_segment->codec == CODEC_HEVC) {
  2534.                     delimiter0 = HEVC_DELIMITER0;
  2535.                     delimiter1 = HEVC_DELIMITER1;
  2536.                     delimiter2 = HEVC_DELIMITER2;
  2537.                     delimiter3 = HEVC_DELIMITER3;
  2538.                     delimiter4 = HEVC_DELIMITER4;
  2539.                 } else if (coded_buffer_segment->codec != CODEC_VP8) {
  2540.                     ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
  2541.                 }
  2542.  
  2543.                 if(coded_buffer_segment->codec == CODEC_JPEG) {
  2544.                     for(i = 0; i <  obj_buffer->size_element - header_offset - 1 - 0x1000; i++) {
  2545.                         if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) {
  2546.                             break;
  2547.                         }
  2548.                    }
  2549.                    coded_buffer_segment->base.size = i + 2;
  2550.                 } else if (coded_buffer_segment->codec != CODEC_VP8) {
  2551.                     /* vp8 coded buffer size can be told by vp8 internal statistics buffer,
  2552.                        so it don't need to traversal the coded buffer */
  2553.                     for (i = 0; i < obj_buffer->size_element - header_offset - 3 - 0x1000; i++) {
  2554.                         if ((buffer[i] == delimiter0) &&
  2555.                             (buffer[i + 1] == delimiter1) &&
  2556.                             (buffer[i + 2] == delimiter2) &&
  2557.                             (buffer[i + 3] == delimiter3) &&
  2558.                             (buffer[i + 4] == delimiter4))
  2559.                             break;
  2560.                     }
  2561.  
  2562.                     if (i == obj_buffer->size_element - header_offset - 3 - 0x1000) {
  2563.                         coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
  2564.                     }
  2565.                     coded_buffer_segment->base.size = i;
  2566.                 }
  2567.  
  2568.                 if (coded_buffer_segment->base.size >= obj_buffer->size_element - header_offset - 0x1000) {
  2569.                     coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
  2570.                 }
  2571.  
  2572.                 coded_buffer_segment->mapped = 1;
  2573.             } else {
  2574.                 assert(coded_buffer_segment->base.buf);
  2575.             }
  2576.         }
  2577.  
  2578.         vaStatus = VA_STATUS_SUCCESS;
  2579.     } else if (NULL != obj_buffer->buffer_store->buffer) {
  2580.         *pbuf = obj_buffer->buffer_store->buffer;
  2581.         vaStatus = VA_STATUS_SUCCESS;
  2582.     }
  2583.  
  2584.     return vaStatus;
  2585. }
  2586.  
  2587. VAStatus
  2588. i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
  2589. {
  2590.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2591.     struct object_buffer *obj_buffer = BUFFER(buf_id);
  2592.     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
  2593.  
  2594.     if ((buf_id & OBJECT_HEAP_OFFSET_MASK) != BUFFER_ID_OFFSET)
  2595.         return VA_STATUS_ERROR_INVALID_BUFFER;
  2596.  
  2597.     ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
  2598.     /* When the wrapper_buffer exists, it will wrapper to the
  2599.      * buffer allocated from backend driver.
  2600.      */
  2601.     if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
  2602.         i965->wrapper_pdrvctx) {
  2603.         VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
  2604.  
  2605.         CALL_VTABLE(pdrvctx, vaStatus,
  2606.                     vaUnmapBuffer(pdrvctx, obj_buffer->wrapper_buffer));
  2607.         return vaStatus;
  2608.     }
  2609.  
  2610.     ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_OPERATION_FAILED);
  2611.     ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_OPERATION_FAILED);
  2612.  
  2613.     if (NULL != obj_buffer->buffer_store->bo) {
  2614.         unsigned int tiling, swizzle;
  2615.  
  2616.         dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
  2617.  
  2618.         if (tiling != I915_TILING_NONE)
  2619.             drm_intel_gem_bo_unmap_gtt(obj_buffer->buffer_store->bo);
  2620.         else
  2621.             dri_bo_unmap(obj_buffer->buffer_store->bo);
  2622.  
  2623.         vaStatus = VA_STATUS_SUCCESS;
  2624.     } else if (NULL != obj_buffer->buffer_store->buffer) {
  2625.         /* Do nothing */
  2626.         vaStatus = VA_STATUS_SUCCESS;
  2627.     }
  2628.  
  2629.     return vaStatus;
  2630. }
  2631.  
  2632. VAStatus
  2633. i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
  2634. {
  2635.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2636.     struct object_buffer *obj_buffer = BUFFER(buffer_id);
  2637.     VAStatus va_status = VA_STATUS_SUCCESS;
  2638.  
  2639.     ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
  2640.  
  2641.     if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
  2642.         i965->wrapper_pdrvctx) {
  2643.         CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
  2644.                     vaDestroyBuffer(i965->wrapper_pdrvctx,
  2645.                                     obj_buffer->wrapper_buffer));
  2646.         obj_buffer->wrapper_buffer = VA_INVALID_ID;
  2647.     }
  2648.  
  2649.     i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
  2650.  
  2651.     return va_status;
  2652. }
  2653.  
  2654. VAStatus
  2655. i965_BeginPicture(VADriverContextP ctx,
  2656.                   VAContextID context,
  2657.                   VASurfaceID render_target)
  2658. {
  2659.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2660.     struct object_context *obj_context = CONTEXT(context);
  2661.     struct object_surface *obj_surface = SURFACE(render_target);
  2662.     struct object_config *obj_config;
  2663.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  2664.     int i;
  2665.  
  2666.     ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
  2667.     ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
  2668.     obj_config = obj_context->obj_config;
  2669.     ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
  2670.  
  2671.     if (is_surface_busy(i965, obj_surface))
  2672.         return VA_STATUS_ERROR_SURFACE_BUSY;
  2673.  
  2674.     if (obj_context->codec_type == CODEC_PROC) {
  2675.         obj_context->codec_state.proc.current_render_target = render_target;
  2676.     } else if (obj_context->codec_type == CODEC_ENC) {
  2677.         i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
  2678.  
  2679.         for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++) {
  2680.             i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
  2681.         }
  2682.  
  2683.         obj_context->codec_state.encode.num_slice_params = 0;
  2684.  
  2685.         /* ext */
  2686.         i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
  2687.  
  2688.         for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
  2689.             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
  2690.  
  2691.         for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
  2692.             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
  2693.  
  2694.         for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
  2695.             i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
  2696.  
  2697.         obj_context->codec_state.encode.num_slice_params_ext = 0;
  2698.         obj_context->codec_state.encode.current_render_target = render_target;     /*This is input new frame*/
  2699.         obj_context->codec_state.encode.last_packed_header_type = 0;
  2700.         memset(obj_context->codec_state.encode.slice_rawdata_index, 0,
  2701.                sizeof(int) * obj_context->codec_state.encode.max_slice_num);
  2702.         memset(obj_context->codec_state.encode.slice_rawdata_count, 0,
  2703.                sizeof(int) * obj_context->codec_state.encode.max_slice_num);
  2704.         memset(obj_context->codec_state.encode.slice_header_index, 0,
  2705.                sizeof(int) * obj_context->codec_state.encode.max_slice_num);
  2706.  
  2707.         for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
  2708.             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
  2709.         for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
  2710.             i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
  2711.         obj_context->codec_state.encode.num_packed_header_params_ext = 0;
  2712.         obj_context->codec_state.encode.num_packed_header_data_ext = 0;
  2713.         obj_context->codec_state.encode.slice_index = 0;
  2714.         obj_context->codec_state.encode.vps_sps_seq_index = 0;
  2715.     } else {
  2716.         obj_context->codec_state.decode.current_render_target = render_target;
  2717.         i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
  2718.         i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
  2719.         i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
  2720.         i965_release_buffer_store(&obj_context->codec_state.decode.huffman_table);
  2721.  
  2722.         for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++) {
  2723.             i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
  2724.             i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
  2725.         }
  2726.  
  2727.         obj_context->codec_state.decode.num_slice_params = 0;
  2728.         obj_context->codec_state.decode.num_slice_datas = 0;
  2729.  
  2730.         if ((obj_context->wrapper_context != VA_INVALID_ID) &&
  2731.             i965->wrapper_pdrvctx) {
  2732.             if (obj_surface->wrapper_surface == VA_INVALID_ID)
  2733.                 vaStatus = i965_surface_wrapper(ctx, render_target);
  2734.  
  2735.             if (vaStatus != VA_STATUS_SUCCESS)
  2736.                 return vaStatus;
  2737.  
  2738.             CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
  2739.                         vaBeginPicture(i965->wrapper_pdrvctx,
  2740.                                        obj_context->wrapper_context,
  2741.                                        obj_surface->wrapper_surface));
  2742.         }
  2743.     }
  2744.  
  2745.     return vaStatus;
  2746. }
  2747.  
  2748. #define I965_RENDER_BUFFER(category, name) i965_render_##category##_##name##_buffer(ctx, obj_context, obj_buffer)
  2749.  
  2750. #define DEF_RENDER_SINGLE_BUFFER_FUNC(category, name, member)           \
  2751.     static VAStatus                                                     \
  2752.     i965_render_##category##_##name##_buffer(VADriverContextP ctx,      \
  2753.                                              struct object_context *obj_context, \
  2754.                                              struct object_buffer *obj_buffer) \
  2755.     {                                                                   \
  2756.         struct category##_state *category = &obj_context->codec_state.category; \
  2757.         i965_release_buffer_store(&category->member);                   \
  2758.         i965_reference_buffer_store(&category->member, obj_buffer->buffer_store); \
  2759.         return VA_STATUS_SUCCESS;                                       \
  2760.     }
  2761.  
  2762. #define DEF_RENDER_MULTI_BUFFER_FUNC(category, name, member)            \
  2763.     static VAStatus                                                     \
  2764.     i965_render_##category##_##name##_buffer(VADriverContextP ctx,      \
  2765.                                              struct object_context *obj_context, \
  2766.                                              struct object_buffer *obj_buffer) \
  2767.     {                                                                   \
  2768.         struct category##_state *category = &obj_context->codec_state.category; \
  2769.         if (category->num_##member == category->max_##member) {         \
  2770.             category->member = realloc(category->member, (category->max_##member + NUM_SLICES) * sizeof(*category->member)); \
  2771.             memset(category->member + category->max_##member, 0, NUM_SLICES * sizeof(*category->member)); \
  2772.             category->max_##member += NUM_SLICES;                       \
  2773.         }                                                               \
  2774.         i965_release_buffer_store(&category->member[category->num_##member]); \
  2775.         i965_reference_buffer_store(&category->member[category->num_##member], obj_buffer->buffer_store); \
  2776.         category->num_##member++;                                       \
  2777.         return VA_STATUS_SUCCESS;                                       \
  2778.     }
  2779.  
  2780. #define I965_RENDER_DECODE_BUFFER(name) I965_RENDER_BUFFER(decode, name)
  2781.  
  2782. #define DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(decode, name, member)
  2783. DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
  2784. DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(iq_matrix, iq_matrix)
  2785. DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(bit_plane, bit_plane)
  2786. DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
  2787. DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(probability_data, probability_data)
  2788.  
  2789. #define DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(decode, name, member)
  2790. DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
  2791. DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_data, slice_datas)
  2792.  
  2793.  
  2794. static VAStatus
  2795. i965_decoder_vp9_wrapper_picture(VADriverContextP ctx,
  2796.                              VABufferID *buffers,
  2797.                              int num_buffers)
  2798. {
  2799.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2800.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  2801.     int i;
  2802.     VADecPictureParameterBufferVP9 *pVp9PicParams;
  2803.     VADriverContextP pdrvctx;
  2804.     struct object_buffer *obj_buffer;
  2805.  
  2806.     pdrvctx = i965->wrapper_pdrvctx;
  2807.     /* do the conversion of VADecPictureParameterBufferVP9 */
  2808.     for (i = 0; i < num_buffers; i++) {
  2809.         obj_buffer = BUFFER(buffers[i]);
  2810.  
  2811.         if (!obj_buffer)
  2812.             continue;
  2813.  
  2814.         if (obj_buffer->wrapper_buffer == VA_INVALID_ID)
  2815.             continue;
  2816.  
  2817.         if (obj_buffer->type == VAPictureParameterBufferType) {
  2818.             int j;
  2819.             VASurfaceID surface_id;
  2820.             struct object_surface *obj_surface;
  2821.  
  2822.             pdrvctx = i965->wrapper_pdrvctx;
  2823.  
  2824.             CALL_VTABLE(pdrvctx, vaStatus,
  2825.                         vaMapBuffer(pdrvctx, obj_buffer->wrapper_buffer,
  2826.                                     (void **)(&pVp9PicParams)));
  2827.  
  2828.             if (vaStatus != VA_STATUS_SUCCESS)
  2829.                 return vaStatus;
  2830.  
  2831.             for (j = 0; j < 8; j++) {
  2832.                 surface_id = pVp9PicParams->reference_frames[j];
  2833.                 obj_surface = SURFACE(surface_id);
  2834.  
  2835.                 if (!obj_surface)
  2836.                     continue;
  2837.  
  2838.                 if (obj_surface->wrapper_surface == VA_INVALID_ID) {
  2839.                     vaStatus = i965_surface_wrapper(ctx, surface_id);
  2840.                     if (vaStatus != VA_STATUS_SUCCESS) {
  2841.                         pdrvctx->vtable->vaUnmapBuffer(pdrvctx,
  2842.                                     obj_buffer->wrapper_buffer);
  2843.                         goto fail_out;
  2844.                     }
  2845.                 }
  2846.  
  2847.                 pVp9PicParams->reference_frames[j] = obj_surface->wrapper_surface;
  2848.             }
  2849.             CALL_VTABLE(pdrvctx, vaStatus,
  2850.                         vaUnmapBuffer(pdrvctx, obj_buffer->wrapper_buffer));
  2851.             break;
  2852.         }
  2853.     }
  2854.  
  2855.     return VA_STATUS_SUCCESS;
  2856.  
  2857. fail_out:
  2858.     return vaStatus;
  2859. }
  2860.  
  2861. static VAStatus
  2862. i965_decoder_wrapper_picture(VADriverContextP ctx,
  2863.                              VAContextID context,
  2864.                              VABufferID *buffers,
  2865.                              int num_buffers)
  2866. {
  2867.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2868.     struct object_context *obj_context = CONTEXT(context);
  2869.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  2870.     int i;
  2871.     VADriverContextP pdrvctx;
  2872.     struct object_buffer *obj_buffer;
  2873.  
  2874.     if (obj_context == NULL)
  2875.         return VA_STATUS_ERROR_INVALID_CONTEXT;
  2876.  
  2877.     /* When it is not wrapped context, continue the normal flowchart */
  2878.     if (obj_context->wrapper_context == VA_INVALID_ID)
  2879.         return vaStatus;
  2880.  
  2881.     if (obj_context->obj_config &&
  2882.         (obj_context->obj_config->profile == VAProfileVP9Profile0)) {
  2883.         vaStatus = i965_decoder_vp9_wrapper_picture(ctx, buffers, num_buffers);
  2884.     } else
  2885.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  2886.  
  2887.     pdrvctx = i965->wrapper_pdrvctx;
  2888.  
  2889.     for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
  2890.         obj_buffer = BUFFER(buffers[i]);
  2891.  
  2892.         if (!obj_buffer)
  2893.             continue;
  2894.  
  2895.         if (obj_buffer->wrapper_buffer == VA_INVALID_ID) {
  2896.             vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
  2897.             break;
  2898.         }
  2899.  
  2900.         CALL_VTABLE(pdrvctx, vaStatus,
  2901.                     vaRenderPicture(pdrvctx, obj_context->wrapper_context,
  2902.                                     &(obj_buffer->wrapper_buffer), 1));
  2903.     }
  2904.     return vaStatus;
  2905. }
  2906.  
  2907. static VAStatus
  2908. i965_decoder_render_picture(VADriverContextP ctx,
  2909.                             VAContextID context,
  2910.                             VABufferID *buffers,
  2911.                             int num_buffers)
  2912. {
  2913.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  2914.     struct object_context *obj_context = CONTEXT(context);
  2915.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  2916.     int i;
  2917.  
  2918.     ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
  2919.  
  2920.     for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
  2921.         struct object_buffer *obj_buffer = BUFFER(buffers[i]);
  2922.  
  2923.         if (!obj_buffer)
  2924.             return VA_STATUS_ERROR_INVALID_BUFFER;
  2925.  
  2926.         switch (obj_buffer->type) {
  2927.         case VAPictureParameterBufferType:
  2928.             vaStatus = I965_RENDER_DECODE_BUFFER(picture_parameter);
  2929.             break;
  2930.  
  2931.         case VAIQMatrixBufferType:
  2932.             vaStatus = I965_RENDER_DECODE_BUFFER(iq_matrix);
  2933.             break;
  2934.  
  2935.         case VABitPlaneBufferType:
  2936.             vaStatus = I965_RENDER_DECODE_BUFFER(bit_plane);
  2937.             break;
  2938.  
  2939.         case VASliceParameterBufferType:
  2940.             vaStatus = I965_RENDER_DECODE_BUFFER(slice_parameter);
  2941.             break;
  2942.  
  2943.         case VASliceDataBufferType:
  2944.             vaStatus = I965_RENDER_DECODE_BUFFER(slice_data);
  2945.             break;
  2946.  
  2947.         case VAHuffmanTableBufferType:
  2948.             vaStatus = I965_RENDER_DECODE_BUFFER(huffman_table);
  2949.             break;
  2950.  
  2951.         case VAProbabilityBufferType:
  2952.             vaStatus = I965_RENDER_DECODE_BUFFER(probability_data);
  2953.             break;
  2954.  
  2955.         default:
  2956.             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
  2957.             break;
  2958.         }
  2959.     }
  2960.  
  2961.     if ((vaStatus == VA_STATUS_SUCCESS) &&
  2962.         (obj_context->wrapper_context != VA_INVALID_ID))
  2963.         vaStatus = i965_decoder_wrapper_picture(ctx, context, buffers, num_buffers);
  2964.  
  2965.     return vaStatus;
  2966. }
  2967.  
  2968. #define I965_RENDER_ENCODE_BUFFER(name) I965_RENDER_BUFFER(encode, name)
  2969.  
  2970. #define DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(encode, name, member)
  2971. // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter, seq_param)
  2972. // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
  2973. // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_control, pic_control)
  2974. DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(qmatrix, q_matrix)
  2975. DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(iqmatrix, iq_matrix)
  2976. DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
  2977. /* extended buffer */
  2978. DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
  2979. DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
  2980.  
  2981. #define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
  2982. // DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
  2983. DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter_ext, slice_params_ext)
  2984.  
  2985. DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_params_ext, packed_header_params_ext)
  2986. DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_data_ext, packed_header_data_ext)
  2987.  
  2988. static VAStatus
  2989. i965_encoder_render_packed_header_parameter_buffer(VADriverContextP ctx,
  2990.                                                    struct object_context *obj_context,
  2991.                                                    struct object_buffer *obj_buffer,
  2992.                                                    int type_index)
  2993. {
  2994.     struct encode_state *encode = &obj_context->codec_state.encode;
  2995.  
  2996.     ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
  2997.     ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
  2998.     i965_release_buffer_store(&encode->packed_header_param[type_index]);
  2999.     i965_reference_buffer_store(&encode->packed_header_param[type_index], obj_buffer->buffer_store);
  3000.  
  3001.     return VA_STATUS_SUCCESS;
  3002. }
  3003.  
  3004. static VAStatus
  3005. i965_encoder_render_packed_header_data_buffer(VADriverContextP ctx,
  3006.                                               struct object_context *obj_context,
  3007.                                               struct object_buffer *obj_buffer,
  3008.                                               int type_index)
  3009. {
  3010.     struct encode_state *encode = &obj_context->codec_state.encode;
  3011.  
  3012.     ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
  3013.     ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
  3014.     i965_release_buffer_store(&encode->packed_header_data[type_index]);
  3015.     i965_reference_buffer_store(&encode->packed_header_data[type_index], obj_buffer->buffer_store);
  3016.  
  3017.     return VA_STATUS_SUCCESS;
  3018. }
  3019.  
  3020. static VAStatus
  3021. i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
  3022.                                           struct object_context *obj_context,
  3023.                                           struct object_buffer *obj_buffer)
  3024. {
  3025.     struct encode_state *encode = &obj_context->codec_state.encode;
  3026.     VAEncMiscParameterBuffer *param = NULL;
  3027.  
  3028.     ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
  3029.     ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
  3030.  
  3031.     param = (VAEncMiscParameterBuffer *)obj_buffer->buffer_store->buffer;
  3032.  
  3033.     if (param->type >= ARRAY_ELEMS(encode->misc_param))
  3034.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  3035.  
  3036.     i965_release_buffer_store(&encode->misc_param[param->type]);
  3037.     i965_reference_buffer_store(&encode->misc_param[param->type], obj_buffer->buffer_store);
  3038.  
  3039.     return VA_STATUS_SUCCESS;
  3040. }
  3041.  
  3042. static VAStatus
  3043. i965_encoder_render_picture(VADriverContextP ctx,
  3044.                             VAContextID context,
  3045.                             VABufferID *buffers,
  3046.                             int num_buffers)
  3047. {
  3048.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3049.     struct object_context *obj_context = CONTEXT(context);
  3050.     struct object_config *obj_config;
  3051.     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
  3052.     struct encode_state *encode;
  3053.     int i;
  3054.  
  3055.     ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
  3056.     obj_config = obj_context->obj_config;
  3057.     ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
  3058.  
  3059.     encode = &obj_context->codec_state.encode;
  3060.     for (i = 0; i < num_buffers; i++) {
  3061.         struct object_buffer *obj_buffer = BUFFER(buffers[i]);
  3062.  
  3063.         if (!obj_buffer)
  3064.             return VA_STATUS_ERROR_INVALID_BUFFER;
  3065.  
  3066.         switch (obj_buffer->type) {
  3067.         case VAQMatrixBufferType:
  3068.             vaStatus = I965_RENDER_ENCODE_BUFFER(qmatrix);
  3069.             break;
  3070.  
  3071.         case VAIQMatrixBufferType:
  3072.             vaStatus = I965_RENDER_ENCODE_BUFFER(iqmatrix);
  3073.             break;
  3074.  
  3075.         case VAEncSequenceParameterBufferType:
  3076.             vaStatus = I965_RENDER_ENCODE_BUFFER(sequence_parameter_ext);
  3077.             break;
  3078.  
  3079.         case VAEncPictureParameterBufferType:
  3080.             vaStatus = I965_RENDER_ENCODE_BUFFER(picture_parameter_ext);
  3081.             break;
  3082.  
  3083.         case VAHuffmanTableBufferType:
  3084.             vaStatus = I965_RENDER_ENCODE_BUFFER(huffman_table);
  3085.             break;
  3086.  
  3087.         case VAEncSliceParameterBufferType:
  3088.             vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
  3089.             if (vaStatus == VA_STATUS_SUCCESS) {
  3090.                 /* When the max number of slices is updated, it also needs
  3091.                  * to reallocate the arrays that is used to store
  3092.                  * the packed data index/count for the slice
  3093.                  */
  3094.                 if (!(encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE)) {
  3095.                    encode->slice_index++;
  3096.                 }
  3097.                 if (encode->slice_index == encode->max_slice_num) {
  3098.                     int slice_num = encode->max_slice_num;
  3099.                     encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
  3100.                                                           (slice_num + NUM_SLICES) * sizeof(int));
  3101.                     encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
  3102.                                                           (slice_num + NUM_SLICES) * sizeof(int));
  3103.                     encode->slice_header_index = realloc(encode->slice_header_index,
  3104.                                                           (slice_num + NUM_SLICES) * sizeof(int));
  3105.                     memset(encode->slice_rawdata_index + slice_num, 0,
  3106.                         sizeof(int) * NUM_SLICES);
  3107.                     memset(encode->slice_rawdata_count + slice_num, 0,
  3108.                         sizeof(int) * NUM_SLICES);
  3109.                     memset(encode->slice_header_index + slice_num, 0,
  3110.                         sizeof(int) * NUM_SLICES);
  3111.  
  3112.                     encode->max_slice_num += NUM_SLICES;
  3113.                     if ((encode->slice_rawdata_index == NULL) ||
  3114.                         (encode->slice_header_index == NULL)  ||
  3115.                         (encode->slice_rawdata_count == NULL)) {
  3116.                         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
  3117.                         return vaStatus;
  3118.                     }
  3119.                 }
  3120.             }
  3121.             break;
  3122.  
  3123.         case VAEncPackedHeaderParameterBufferType:
  3124.         {
  3125.             VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer;
  3126.             encode->last_packed_header_type = param->type;
  3127.  
  3128.             if ((param->type == VAEncPackedHeaderRawData) ||
  3129.                 (param->type == VAEncPackedHeaderSlice)) {
  3130.                 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext);
  3131.             } else if((obj_config->profile == VAProfileHEVCMain) &&
  3132.                 (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
  3133.                 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
  3134.                                                                           obj_context,
  3135.                                                                           obj_buffer,
  3136.                                                                           va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index);
  3137.             } else {
  3138.                 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
  3139.                                                                           obj_context,
  3140.                                                                           obj_buffer,
  3141.                                                                           va_enc_packed_type_to_idx(encode->last_packed_header_type));
  3142.             }
  3143.             break;
  3144.         }
  3145.  
  3146.         case VAEncPackedHeaderDataBufferType:
  3147.         {
  3148.             if (encode->last_packed_header_type == 0) {
  3149.                 WARN_ONCE("the packed header data is passed without type!\n");
  3150.                 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
  3151.                 return vaStatus;
  3152.             }
  3153.             if (encode->last_packed_header_type == VAEncPackedHeaderRawData ||
  3154.                 encode->last_packed_header_type == VAEncPackedHeaderSlice) {
  3155.                 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext);
  3156.  
  3157.                 /* When the PACKED_SLICE_HEADER flag is passed, it will use
  3158.                  * the packed_slice_header as the delimeter to decide how
  3159.                  * the packed rawdata is inserted for the given slice.
  3160.                  * Otherwise it will use the VAEncSequenceParameterBuffer
  3161.                  * as the delimeter
  3162.                  */
  3163.                 if (encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) {
  3164.                     /* store the first index of the packed header data for current slice */
  3165.                     if (encode->slice_rawdata_index[encode->slice_index] == 0) {
  3166.                         encode->slice_rawdata_index[encode->slice_index] =
  3167.                             SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
  3168.                     }
  3169.                     encode->slice_rawdata_count[encode->slice_index]++;
  3170.                     if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
  3171.                         /* find one packed slice_header delimeter. And the following
  3172.                          * packed data is for the next slice
  3173.                          */
  3174.                         encode->slice_header_index[encode->slice_index] =
  3175.                             SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
  3176.                         encode->slice_index++;
  3177.                         /* Reallocate the buffer to record the index/count of
  3178.                          * packed_data for one slice.
  3179.                          */
  3180.                         if (encode->slice_index == encode->max_slice_num) {
  3181.                             int slice_num = encode->max_slice_num;
  3182.  
  3183.                             encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
  3184.                                                           (slice_num + NUM_SLICES) * sizeof(int));
  3185.                             encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
  3186.                                                           (slice_num + NUM_SLICES) * sizeof(int));
  3187.                             encode->slice_header_index = realloc(encode->slice_header_index,
  3188.                                                           (slice_num + NUM_SLICES) * sizeof(int));
  3189.                             memset(encode->slice_rawdata_index + slice_num, 0,
  3190.                                    sizeof(int) * NUM_SLICES);
  3191.                             memset(encode->slice_rawdata_count + slice_num, 0,
  3192.                                    sizeof(int) * NUM_SLICES);
  3193.                             memset(encode->slice_header_index + slice_num, 0,
  3194.                                    sizeof(int) * NUM_SLICES);
  3195.                             encode->max_slice_num += NUM_SLICES;
  3196.                         }
  3197.                     }
  3198.                 } else {
  3199.                     if (vaStatus == VA_STATUS_SUCCESS) {
  3200.                         /* store the first index of the packed header data for current slice */
  3201.                         if (encode->slice_rawdata_index[encode->slice_index] == 0) {
  3202.                             encode->slice_rawdata_index[encode->slice_index] =
  3203.                                 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
  3204.                         }
  3205.                         encode->slice_rawdata_count[encode->slice_index]++;
  3206.                         if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
  3207.                             if (encode->slice_header_index[encode->slice_index] == 0) {
  3208.                                 encode->slice_header_index[encode->slice_index] =
  3209.                                     SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
  3210.                             } else {
  3211.                                 WARN_ONCE("Multi slice header data is passed for"
  3212.                                       " slice %d!\n", encode->slice_index);
  3213.                             }
  3214.                         }
  3215.                     }
  3216.                 }
  3217.             } else {
  3218.                 ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
  3219.                     encode->last_packed_header_type == VAEncPackedHeaderPicture ||
  3220.                     encode->last_packed_header_type == VAEncPackedHeaderSlice ||
  3221.                    (((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) &&
  3222.                     ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)),
  3223.                     VA_STATUS_ERROR_ENCODING_ERROR);
  3224.  
  3225.                 if((obj_config->profile == VAProfileHEVCMain) &&
  3226.                     (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
  3227.  
  3228.                         vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
  3229.                             obj_context,
  3230.                             obj_buffer,
  3231.                             va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index);
  3232.                         encode->vps_sps_seq_index = (encode->vps_sps_seq_index + 1) % I965_SEQ_PACKED_HEADER_END;
  3233.                 }else{
  3234.                     vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
  3235.                         obj_context,
  3236.                         obj_buffer,
  3237.                         va_enc_packed_type_to_idx(encode->last_packed_header_type));
  3238.  
  3239.                 }
  3240.             }
  3241.             encode->last_packed_header_type = 0;
  3242.             break;
  3243.         }
  3244.  
  3245.         case VAEncMiscParameterBufferType:
  3246.             vaStatus = i965_encoder_render_misc_parameter_buffer(ctx,
  3247.                                                                  obj_context,
  3248.                                                                  obj_buffer);
  3249.             break;
  3250.  
  3251.         default:
  3252.             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
  3253.             break;
  3254.         }
  3255.     }
  3256.  
  3257.     return vaStatus;
  3258. }
  3259.  
  3260. #define I965_RENDER_PROC_BUFFER(name) I965_RENDER_BUFFER(proc, name)
  3261.  
  3262. #define DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(proc, name, member)
  3263. DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(pipeline_parameter, pipeline_param)
  3264.  
  3265. static VAStatus
  3266. i965_proc_render_picture(VADriverContextP ctx,
  3267.                          VAContextID context,
  3268.                          VABufferID *buffers,
  3269.                          int num_buffers)
  3270. {
  3271.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3272.     struct object_context *obj_context = CONTEXT(context);
  3273.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  3274.     int i;
  3275.  
  3276.     ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
  3277.  
  3278.     for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
  3279.         struct object_buffer *obj_buffer = BUFFER(buffers[i]);
  3280.  
  3281.         if (!obj_buffer)
  3282.             return VA_STATUS_ERROR_INVALID_BUFFER;
  3283.  
  3284.         switch (obj_buffer->type) {
  3285.         case VAProcPipelineParameterBufferType:
  3286.             vaStatus = I965_RENDER_PROC_BUFFER(pipeline_parameter);
  3287.             break;
  3288.  
  3289.         default:
  3290.             vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
  3291.             break;
  3292.         }
  3293.     }
  3294.  
  3295.     return vaStatus;
  3296. }
  3297.  
  3298. VAStatus
  3299. i965_RenderPicture(VADriverContextP ctx,
  3300.                    VAContextID context,
  3301.                    VABufferID *buffers,
  3302.                    int num_buffers)
  3303. {
  3304.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3305.     struct object_context *obj_context;
  3306.     struct object_config *obj_config;
  3307.     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
  3308.  
  3309.     obj_context = CONTEXT(context);
  3310.     ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
  3311.  
  3312.     if (num_buffers <= 0)
  3313.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  3314.  
  3315.     obj_config = obj_context->obj_config;
  3316.     ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
  3317.  
  3318.     if (VAEntrypointVideoProc == obj_config->entrypoint) {
  3319.         vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
  3320.     } else if ((VAEntrypointEncSlice == obj_config->entrypoint ) ||
  3321.                (VAEntrypointEncPicture == obj_config->entrypoint)) {
  3322.         vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
  3323.     } else {
  3324.         vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
  3325.     }
  3326.  
  3327.     return vaStatus;
  3328. }
  3329.  
  3330. VAStatus
  3331. i965_EndPicture(VADriverContextP ctx, VAContextID context)
  3332. {
  3333.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3334.     struct object_context *obj_context = CONTEXT(context);
  3335.     struct object_config *obj_config;
  3336.  
  3337.     ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
  3338.     obj_config = obj_context->obj_config;
  3339.     ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
  3340.  
  3341.     if (obj_context->codec_type == CODEC_PROC) {
  3342.         ASSERT_RET(VAEntrypointVideoProc == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
  3343.     } else if (obj_context->codec_type == CODEC_ENC) {
  3344.         ASSERT_RET(((VAEntrypointEncSlice == obj_config->entrypoint) || (VAEntrypointEncPicture == obj_config->entrypoint)), VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
  3345.  
  3346.         if (obj_context->codec_state.encode.num_packed_header_params_ext !=
  3347.                obj_context->codec_state.encode.num_packed_header_data_ext) {
  3348.             WARN_ONCE("the packed header/data is not paired for encoding!\n");
  3349.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  3350.         }
  3351.         if (!(obj_context->codec_state.encode.pic_param ||
  3352.                 obj_context->codec_state.encode.pic_param_ext)) {
  3353.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  3354.         }
  3355.         if (!(obj_context->codec_state.encode.seq_param ||
  3356.                 obj_context->codec_state.encode.seq_param_ext) &&
  3357.                 (VAEntrypointEncPicture != obj_config->entrypoint)) {
  3358.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  3359.         }
  3360.         if ((obj_context->codec_state.encode.num_slice_params <=0) &&
  3361.                 (obj_context->codec_state.encode.num_slice_params_ext <=0) &&
  3362.                 (obj_config->profile != VAProfileVP8Version0_3)) {
  3363.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  3364.         }
  3365.  
  3366.         if ((obj_context->codec_state.encode.packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) &&
  3367.             (obj_context->codec_state.encode.num_slice_params_ext !=
  3368.              obj_context->codec_state.encode.slice_index)) {
  3369.             WARN_ONCE("packed slice_header data is missing for some slice"
  3370.                       " under packed SLICE_HEADER mode\n");
  3371.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  3372.         }
  3373.     } else {
  3374.         if (obj_context->codec_state.decode.pic_param == NULL) {
  3375.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  3376.         }
  3377.         if (obj_context->codec_state.decode.num_slice_params <=0) {
  3378.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  3379.         }
  3380.         if (obj_context->codec_state.decode.num_slice_datas <=0) {
  3381.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  3382.         }
  3383.  
  3384.         if (obj_context->codec_state.decode.num_slice_params !=
  3385.                 obj_context->codec_state.decode.num_slice_datas) {
  3386.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  3387.         }
  3388.  
  3389.         if (obj_context->wrapper_context != VA_INVALID_ID) {
  3390.             /* call the vaEndPicture of wrapped driver */
  3391.             VADriverContextP pdrvctx;
  3392.             VAStatus va_status;
  3393.  
  3394.             pdrvctx = i965->wrapper_pdrvctx;
  3395.             CALL_VTABLE(pdrvctx, va_status,
  3396.                         vaEndPicture(pdrvctx, obj_context->wrapper_context));
  3397.  
  3398.             return va_status;
  3399.         }
  3400.     }
  3401.  
  3402.     ASSERT_RET(obj_context->hw_context->run, VA_STATUS_ERROR_OPERATION_FAILED);
  3403.     return obj_context->hw_context->run(ctx, obj_config->profile, &obj_context->codec_state, obj_context->hw_context);
  3404. }
  3405.  
  3406. VAStatus
  3407. i965_SyncSurface(VADriverContextP ctx,
  3408.                  VASurfaceID render_target)
  3409. {
  3410.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3411.     struct object_surface *obj_surface = SURFACE(render_target);
  3412.  
  3413.     ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
  3414.  
  3415.     if(obj_surface->bo)
  3416.         drm_intel_bo_wait_rendering(obj_surface->bo);
  3417.  
  3418.     return VA_STATUS_SUCCESS;
  3419. }
  3420.  
  3421. VAStatus
  3422. i965_QuerySurfaceStatus(VADriverContextP ctx,
  3423.                         VASurfaceID render_target,
  3424.                         VASurfaceStatus *status)        /* out */
  3425. {
  3426.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3427.     struct object_surface *obj_surface = SURFACE(render_target);
  3428.  
  3429.     ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
  3430.  
  3431.     if (obj_surface->bo) {
  3432.         if (drm_intel_bo_busy(obj_surface->bo)){
  3433.             *status = VASurfaceRendering;
  3434.         }
  3435.         else {
  3436.             *status = VASurfaceReady;
  3437.         }
  3438.     } else {
  3439.         *status = VASurfaceReady;
  3440.     }
  3441.  
  3442.     return VA_STATUS_SUCCESS;
  3443. }
  3444.  
  3445. static VADisplayAttribute *
  3446. get_display_attribute(VADriverContextP ctx, VADisplayAttribType type)
  3447. {
  3448.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  3449.     unsigned int i;
  3450.  
  3451.     if (!i965->display_attributes)
  3452.         return NULL;
  3453.  
  3454.     for (i = 0; i < i965->num_display_attributes; i++) {
  3455.         if (i965->display_attributes[i].type == type)
  3456.             return &i965->display_attributes[i];
  3457.     }
  3458.     return NULL;
  3459. }
  3460.  
  3461. static void
  3462. i965_display_attributes_terminate(VADriverContextP ctx)
  3463. {
  3464.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  3465.  
  3466.     if (i965->display_attributes) {
  3467.         free(i965->display_attributes);
  3468.         i965->display_attributes = NULL;
  3469.         i965->num_display_attributes = 0;
  3470.     }
  3471. }
  3472.  
  3473. static bool
  3474. i965_display_attributes_init(VADriverContextP ctx)
  3475. {
  3476.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  3477.  
  3478.     i965->num_display_attributes = ARRAY_ELEMS(i965_display_attributes);
  3479.     i965->display_attributes = malloc(
  3480.         i965->num_display_attributes * sizeof(i965->display_attributes[0]));
  3481.     if (!i965->display_attributes)
  3482.         goto error;
  3483.  
  3484.     memcpy(
  3485.         i965->display_attributes,
  3486.         i965_display_attributes,
  3487.         sizeof(i965_display_attributes)
  3488.     );
  3489.  
  3490.     i965->rotation_attrib = get_display_attribute(ctx, VADisplayAttribRotation);
  3491.     i965->brightness_attrib = get_display_attribute(ctx, VADisplayAttribBrightness);
  3492.     i965->contrast_attrib = get_display_attribute(ctx, VADisplayAttribContrast);
  3493.     i965->hue_attrib = get_display_attribute(ctx, VADisplayAttribHue);
  3494.     i965->saturation_attrib = get_display_attribute(ctx, VADisplayAttribSaturation);
  3495.  
  3496.     if (!i965->rotation_attrib ||
  3497.         !i965->brightness_attrib ||
  3498.         !i965->contrast_attrib ||
  3499.         !i965->hue_attrib ||
  3500.         !i965->saturation_attrib) {
  3501.         goto error;
  3502.     }
  3503.     return true;
  3504.  
  3505. error:
  3506.     i965_display_attributes_terminate(ctx);
  3507.     return false;
  3508. }
  3509.  
  3510. /*
  3511.  * Query display attributes
  3512.  * The caller must provide a "attr_list" array that can hold at
  3513.  * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
  3514.  * returned in "attr_list" is returned in "num_attributes".
  3515.  */
  3516. VAStatus
  3517. i965_QueryDisplayAttributes(
  3518.     VADriverContextP    ctx,
  3519.     VADisplayAttribute *attribs,        /* out */
  3520.     int                *num_attribs_ptr /* out */
  3521. )
  3522. {
  3523.     const int num_attribs = ARRAY_ELEMS(i965_display_attributes);
  3524.  
  3525.     if (attribs && num_attribs > 0)
  3526.         memcpy(attribs, i965_display_attributes, sizeof(i965_display_attributes));
  3527.  
  3528.     if (num_attribs_ptr)
  3529.         *num_attribs_ptr = num_attribs;
  3530.  
  3531.     return VA_STATUS_SUCCESS;
  3532. }
  3533.  
  3534. /*
  3535.  * Get display attributes
  3536.  * This function returns the current attribute values in "attr_list".
  3537.  * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
  3538.  * from vaQueryDisplayAttributes() can have their values retrieved.
  3539.  */
  3540. VAStatus
  3541. i965_GetDisplayAttributes(
  3542.     VADriverContextP    ctx,
  3543.     VADisplayAttribute *attribs,        /* inout */
  3544.     int                 num_attribs     /* in */
  3545. )
  3546. {
  3547.     int i;
  3548.  
  3549.     for (i = 0; i < num_attribs; i++) {
  3550.         VADisplayAttribute *src_attrib, * const dst_attrib = &attribs[i];
  3551.  
  3552.         src_attrib = get_display_attribute(ctx, dst_attrib->type);
  3553.         if (src_attrib && (src_attrib->flags & VA_DISPLAY_ATTRIB_GETTABLE)) {
  3554.             dst_attrib->min_value = src_attrib->min_value;
  3555.             dst_attrib->max_value = src_attrib->max_value;
  3556.             dst_attrib->value     = src_attrib->value;
  3557.         }
  3558.         else
  3559.             dst_attrib->flags = VA_DISPLAY_ATTRIB_NOT_SUPPORTED;
  3560.     }
  3561.     return VA_STATUS_SUCCESS;
  3562. }
  3563.  
  3564. /*
  3565.  * Set display attributes
  3566.  * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
  3567.  * from vaQueryDisplayAttributes() can be set.  If the attribute is not settable or
  3568.  * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
  3569.  */
  3570. VAStatus
  3571. i965_SetDisplayAttributes(
  3572.     VADriverContextP    ctx,
  3573.     VADisplayAttribute *attribs,        /* in */
  3574.     int                 num_attribs     /* in */
  3575. )
  3576. {
  3577.     int i;
  3578.  
  3579.     for (i = 0; i < num_attribs; i++) {
  3580.         VADisplayAttribute *dst_attrib, * const src_attrib = &attribs[i];
  3581.  
  3582.         dst_attrib = get_display_attribute(ctx, src_attrib->type);
  3583.         if (!dst_attrib)
  3584.             return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
  3585.  
  3586.         if (!(dst_attrib->flags & VA_DISPLAY_ATTRIB_SETTABLE))
  3587.             continue;
  3588.  
  3589.         if (src_attrib->value < dst_attrib->min_value ||
  3590.             src_attrib->value > dst_attrib->max_value)
  3591.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  3592.  
  3593.         dst_attrib->value = src_attrib->value;
  3594.         /* XXX: track modified attributes through timestamps */
  3595.     }
  3596.     return VA_STATUS_SUCCESS;
  3597. }
  3598.  
  3599. VAStatus
  3600. i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
  3601.                             VASurfaceID surface,
  3602.                             void **buffer,              /* out */
  3603.                             unsigned int *stride)       /* out */
  3604. {
  3605.     /* TODO */
  3606.     return VA_STATUS_ERROR_UNIMPLEMENTED;
  3607. }
  3608.  
  3609. static void
  3610. i965_destroy_heap(struct object_heap *heap,
  3611.                   void (*func)(struct object_heap *heap, struct object_base *object))
  3612. {
  3613.     struct object_base *object;
  3614.     object_heap_iterator iter;
  3615.  
  3616.     object = object_heap_first(heap, &iter);
  3617.  
  3618.     while (object) {
  3619.         if (func)
  3620.             func(heap, object);
  3621.  
  3622.         object = object_heap_next(heap, &iter);
  3623.     }
  3624.  
  3625.     object_heap_destroy(heap);
  3626. }
  3627.  
  3628.  
  3629. VAStatus
  3630. i965_DestroyImage(VADriverContextP ctx, VAImageID image);
  3631.  
  3632. VAStatus
  3633. i965_CreateImage(VADriverContextP ctx,
  3634.                  VAImageFormat *format,
  3635.                  int width,
  3636.                  int height,
  3637.                  VAImage *out_image)        /* out */
  3638. {
  3639.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3640.     struct object_image *obj_image;
  3641.     VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
  3642.     VAImageID image_id;
  3643.     unsigned int size2, size, awidth, aheight;
  3644.  
  3645.     out_image->image_id = VA_INVALID_ID;
  3646.     out_image->buf      = VA_INVALID_ID;
  3647.  
  3648.     image_id = NEW_IMAGE_ID();
  3649.     if (image_id == VA_INVALID_ID)
  3650.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  3651.  
  3652.     obj_image = IMAGE(image_id);
  3653.     if (!obj_image)
  3654.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  3655.     obj_image->bo         = NULL;
  3656.     obj_image->palette    = NULL;
  3657.     obj_image->derived_surface = VA_INVALID_ID;
  3658.  
  3659.     VAImage * const image = &obj_image->image;
  3660.     image->image_id       = image_id;
  3661.     image->buf            = VA_INVALID_ID;
  3662.  
  3663.     awidth = ALIGN(width, i965->codec_info->min_linear_wpitch);
  3664.  
  3665.     if ((format->fourcc == VA_FOURCC_YV12) ||
  3666.         (format->fourcc == VA_FOURCC_I420)) {
  3667.             if (awidth % 128 != 0) {
  3668.                 awidth = ALIGN(width, 128);
  3669.             }
  3670.     }
  3671.  
  3672.     aheight = ALIGN(height, i965->codec_info->min_linear_hpitch);
  3673.     size    = awidth * aheight;
  3674.     size2    = (awidth / 2) * (aheight / 2);
  3675.  
  3676.     image->num_palette_entries = 0;
  3677.     image->entry_bytes         = 0;
  3678.     memset(image->component_order, 0, sizeof(image->component_order));
  3679.  
  3680.     switch (format->fourcc) {
  3681.     case VA_FOURCC_IA44:
  3682.     case VA_FOURCC_AI44:
  3683.         image->num_planes = 1;
  3684.         image->pitches[0] = awidth;
  3685.         image->offsets[0] = 0;
  3686.         image->data_size  = image->offsets[0] + image->pitches[0] * aheight;
  3687.         image->num_palette_entries = 16;
  3688.         image->entry_bytes         = 3;
  3689.         image->component_order[0]  = 'R';
  3690.         image->component_order[1]  = 'G';
  3691.         image->component_order[2]  = 'B';
  3692.         break;
  3693.     case VA_FOURCC_IA88:
  3694.     case VA_FOURCC_AI88:
  3695.         image->num_planes = 1;
  3696.         image->pitches[0] = awidth * 2;
  3697.         image->offsets[0] = 0;
  3698.         image->data_size  = image->offsets[0] + image->pitches[0] * aheight;
  3699.         image->num_palette_entries = 256;
  3700.         image->entry_bytes         = 3;
  3701.         image->component_order[0]  = 'R';
  3702.         image->component_order[1]  = 'G';
  3703.         image->component_order[2]  = 'B';
  3704.         break;
  3705.     case VA_FOURCC_ARGB:
  3706.     case VA_FOURCC_ABGR:
  3707.     case VA_FOURCC_BGRA:
  3708.     case VA_FOURCC_RGBA:
  3709.     case VA_FOURCC_BGRX:
  3710.     case VA_FOURCC_RGBX:
  3711.         image->num_planes = 1;
  3712.         image->pitches[0] = awidth * 4;
  3713.         image->offsets[0] = 0;
  3714.         image->data_size  = image->offsets[0] + image->pitches[0] * aheight;
  3715.         break;
  3716.     case VA_FOURCC_YV12:
  3717.         image->num_planes = 3;
  3718.         image->pitches[0] = awidth;
  3719.         image->offsets[0] = 0;
  3720.         image->pitches[1] = awidth / 2;
  3721.         image->offsets[1] = size;
  3722.         image->pitches[2] = awidth / 2;
  3723.         image->offsets[2] = size + size2;
  3724.         image->data_size  = size + 2 * size2;
  3725.         break;
  3726.     case VA_FOURCC_I420:
  3727.         image->num_planes = 3;
  3728.         image->pitches[0] = awidth;
  3729.         image->offsets[0] = 0;
  3730.         image->pitches[1] = awidth / 2;
  3731.         image->offsets[1] = size;
  3732.         image->pitches[2] = awidth / 2;
  3733.         image->offsets[2] = size + size2;
  3734.         image->data_size  = size + 2 * size2;
  3735.         break;
  3736.     case VA_FOURCC_422H:
  3737.         image->num_planes = 3;
  3738.         image->pitches[0] = awidth;
  3739.         image->offsets[0] = 0;
  3740.         image->pitches[1] = awidth / 2;
  3741.         image->offsets[1] = size;
  3742.         image->pitches[2] = awidth / 2;
  3743.         image->offsets[2] = size + (awidth / 2) * aheight;
  3744.         image->data_size  = size + 2 * ((awidth / 2) * aheight);
  3745.         break;
  3746.     case VA_FOURCC_NV12:
  3747.         image->num_planes = 2;
  3748.         image->pitches[0] = awidth;
  3749.         image->offsets[0] = 0;
  3750.         image->pitches[1] = awidth;
  3751.         image->offsets[1] = size;
  3752.         image->data_size  = size + 2 * size2;
  3753.         break;
  3754.     case VA_FOURCC_YUY2:
  3755.     case VA_FOURCC_UYVY:
  3756.         image->num_planes = 1;
  3757.         image->pitches[0] = awidth * 2;
  3758.         image->offsets[0] = 0;
  3759.         image->data_size  = size * 2;
  3760.         break;
  3761.     default:
  3762.         goto error;
  3763.     }
  3764.  
  3765.     va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
  3766.                                   image->data_size, 1, NULL, &image->buf);
  3767.     if (va_status != VA_STATUS_SUCCESS)
  3768.         goto error;
  3769.  
  3770.     struct object_buffer *obj_buffer = BUFFER(image->buf);
  3771.  
  3772.     if (!obj_buffer ||
  3773.         !obj_buffer->buffer_store ||
  3774.         !obj_buffer->buffer_store->bo)
  3775.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  3776.  
  3777.     obj_image->bo = obj_buffer->buffer_store->bo;
  3778.     dri_bo_reference(obj_image->bo);
  3779.  
  3780.     if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
  3781.         obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
  3782.         if (!obj_image->palette)
  3783.             goto error;
  3784.     }
  3785.  
  3786.     image->image_id             = image_id;
  3787.     image->format               = *format;
  3788.     image->width                = width;
  3789.     image->height               = height;
  3790.  
  3791.     *out_image                  = *image;
  3792.     return VA_STATUS_SUCCESS;
  3793.  
  3794.  error:
  3795.     i965_DestroyImage(ctx, image_id);
  3796.     return va_status;
  3797. }
  3798.  
  3799. VAStatus
  3800. i965_check_alloc_surface_bo(VADriverContextP ctx,
  3801.                             struct object_surface *obj_surface,
  3802.                             int tiled,
  3803.                             unsigned int fourcc,
  3804.                             unsigned int subsampling)
  3805. {
  3806.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  3807.     int region_width, region_height;
  3808.  
  3809.     if (obj_surface->bo) {
  3810.         ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
  3811.         ASSERT_RET(obj_surface->fourcc == fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
  3812.         ASSERT_RET(obj_surface->subsampling == subsampling, VA_STATUS_ERROR_INVALID_SURFACE);
  3813.         return VA_STATUS_SUCCESS;
  3814.     }
  3815.  
  3816.     obj_surface->x_cb_offset = 0; /* X offset is always 0 */
  3817.     obj_surface->x_cr_offset = 0;
  3818.  
  3819.     int bpp_1stplane = bpp_1stplane_by_fourcc(fourcc);
  3820.  
  3821.     if (obj_surface->user_h_stride_set) {
  3822.         ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
  3823.     } else
  3824.         obj_surface->width = ALIGN(obj_surface->orig_width * bpp_1stplane, 128);
  3825.  
  3826.     if (obj_surface->user_v_stride_set) {
  3827.         ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
  3828.     } else
  3829.         obj_surface->height = ALIGN(obj_surface->orig_height, 32);
  3830.  
  3831.     if ((tiled && !obj_surface->user_disable_tiling)) {
  3832.         ASSERT_RET(fourcc != VA_FOURCC_I420 &&
  3833.                fourcc != VA_FOURCC_IYUV &&
  3834.                fourcc != VA_FOURCC_YV12,
  3835.                VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
  3836.  
  3837.         region_height = obj_surface->height;
  3838.  
  3839.         switch (fourcc) {
  3840.         case VA_FOURCC_NV12:
  3841.         case VA_FOURCC_P010:
  3842.             assert(subsampling == SUBSAMPLE_YUV420);
  3843.             obj_surface->cb_cr_pitch = obj_surface->width;
  3844.             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  3845.             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
  3846.             obj_surface->y_cb_offset = obj_surface->height;
  3847.             obj_surface->y_cr_offset = obj_surface->height;
  3848.             region_width = obj_surface->width;
  3849.             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
  3850.  
  3851.             break;
  3852.  
  3853.         case VA_FOURCC_IMC1:
  3854.             assert(subsampling == SUBSAMPLE_YUV420);
  3855.             obj_surface->cb_cr_pitch = obj_surface->width;
  3856.             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  3857.             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
  3858.             obj_surface->y_cr_offset = obj_surface->height;
  3859.             obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32);
  3860.             region_width = obj_surface->width;
  3861.             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
  3862.  
  3863.             break;
  3864.  
  3865.         case VA_FOURCC_IMC3:
  3866.             assert(subsampling == SUBSAMPLE_YUV420);
  3867.             obj_surface->cb_cr_pitch = obj_surface->width;
  3868.             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  3869.             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
  3870.             obj_surface->y_cb_offset = obj_surface->height;
  3871.             obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
  3872.             region_width = obj_surface->width;
  3873.             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
  3874.  
  3875.             break;
  3876.  
  3877.         case VA_FOURCC_422H:
  3878.             assert(subsampling == SUBSAMPLE_YUV422H);
  3879.             obj_surface->cb_cr_pitch = obj_surface->width;
  3880.             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  3881.             obj_surface->cb_cr_height = obj_surface->orig_height;
  3882.             obj_surface->y_cb_offset = obj_surface->height;
  3883.             obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
  3884.             region_width = obj_surface->width;
  3885.             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
  3886.  
  3887.             break;
  3888.  
  3889.         case VA_FOURCC_422V:
  3890.             assert(subsampling == SUBSAMPLE_YUV422V);
  3891.             obj_surface->cb_cr_pitch = obj_surface->width;
  3892.             obj_surface->cb_cr_width = obj_surface->orig_width;
  3893.             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
  3894.             obj_surface->y_cb_offset = obj_surface->height;
  3895.             obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
  3896.             region_width = obj_surface->width;
  3897.             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
  3898.  
  3899.             break;
  3900.  
  3901.         case VA_FOURCC_411P:
  3902.             assert(subsampling == SUBSAMPLE_YUV411);
  3903.             obj_surface->cb_cr_pitch = obj_surface->width;
  3904.             obj_surface->cb_cr_width = obj_surface->orig_width / 4;
  3905.             obj_surface->cb_cr_height = obj_surface->orig_height;
  3906.             obj_surface->y_cb_offset = obj_surface->height;
  3907.             obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
  3908.             region_width = obj_surface->width;
  3909.             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
  3910.  
  3911.             break;
  3912.  
  3913.         case VA_FOURCC_444P:
  3914.             assert(subsampling == SUBSAMPLE_YUV444);
  3915.             obj_surface->cb_cr_pitch = obj_surface->width;
  3916.             obj_surface->cb_cr_width = obj_surface->orig_width;
  3917.             obj_surface->cb_cr_height = obj_surface->orig_height;
  3918.             obj_surface->y_cb_offset = obj_surface->height;
  3919.             obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
  3920.             region_width = obj_surface->width;
  3921.             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
  3922.  
  3923.             break;
  3924.  
  3925.         case VA_FOURCC_Y800:
  3926.             assert(subsampling == SUBSAMPLE_YUV400);
  3927.             obj_surface->cb_cr_pitch = 0;
  3928.             obj_surface->cb_cr_width = 0;
  3929.             obj_surface->cb_cr_height = 0;
  3930.             obj_surface->y_cb_offset = 0;
  3931.             obj_surface->y_cr_offset = 0;
  3932.             region_width = obj_surface->width;
  3933.             region_height = obj_surface->height;
  3934.  
  3935.             break;
  3936.  
  3937.         case VA_FOURCC_YUY2:
  3938.         case VA_FOURCC_UYVY:
  3939.             assert(subsampling == SUBSAMPLE_YUV422H);
  3940.             obj_surface->width = ALIGN(obj_surface->orig_width * 2, 128);
  3941.             obj_surface->cb_cr_pitch = obj_surface->width;
  3942.             obj_surface->y_cb_offset = 0;
  3943.             obj_surface->y_cr_offset = 0;
  3944.             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  3945.             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
  3946.             region_width = obj_surface->width;
  3947.             region_height = obj_surface->height;
  3948.  
  3949.             break;
  3950.  
  3951.         case VA_FOURCC_RGBA:
  3952.         case VA_FOURCC_RGBX:
  3953.         case VA_FOURCC_BGRA:
  3954.         case VA_FOURCC_BGRX:
  3955.             assert(subsampling == SUBSAMPLE_RGBX);
  3956.  
  3957.             obj_surface->width = ALIGN(obj_surface->orig_width * 4, 128);
  3958.             region_width = obj_surface->width;
  3959.             region_height = obj_surface->height;
  3960.             break;
  3961.  
  3962.         default:
  3963.             /* Never get here */
  3964.             ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
  3965.             break;
  3966.         }
  3967.     } else {
  3968.         assert(subsampling == SUBSAMPLE_YUV420 ||
  3969.                subsampling == SUBSAMPLE_YUV422H ||
  3970.                subsampling == SUBSAMPLE_YUV422V ||
  3971.                subsampling == SUBSAMPLE_RGBX);
  3972.  
  3973.         region_width = obj_surface->width;
  3974.         region_height = obj_surface->height;
  3975.  
  3976.         switch (fourcc) {
  3977.         case VA_FOURCC_NV12:
  3978.         case VA_FOURCC_P010:
  3979.             obj_surface->y_cb_offset = obj_surface->height;
  3980.             obj_surface->y_cr_offset = obj_surface->height;
  3981.             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  3982.             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
  3983.             obj_surface->cb_cr_pitch = obj_surface->width;
  3984.             region_height = obj_surface->height + obj_surface->height / 2;
  3985.             break;
  3986.  
  3987.         case VA_FOURCC_YV16:
  3988.             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  3989.             obj_surface->cb_cr_height = obj_surface->orig_height;
  3990.             obj_surface->y_cr_offset = obj_surface->height;
  3991.             obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32) / 2;
  3992.             obj_surface->cb_cr_pitch = obj_surface->width / 2;
  3993.             region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
  3994.             break;
  3995.  
  3996.         case VA_FOURCC_YV12:
  3997.         case VA_FOURCC_I420:
  3998.             if (fourcc == VA_FOURCC_YV12) {
  3999.                 obj_surface->y_cr_offset = obj_surface->height;
  4000.                 obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4;
  4001.             } else {
  4002.                 obj_surface->y_cb_offset = obj_surface->height;
  4003.                 obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
  4004.             }
  4005.  
  4006.             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  4007.             obj_surface->cb_cr_height = obj_surface->orig_height / 2;
  4008.             obj_surface->cb_cr_pitch = obj_surface->width / 2;
  4009.             region_height = obj_surface->height + obj_surface->height / 2;
  4010.             break;
  4011.  
  4012.         case VA_FOURCC_YUY2:
  4013.         case VA_FOURCC_UYVY:
  4014.             obj_surface->width = ALIGN(obj_surface->orig_width * 2, i965->codec_info->min_linear_wpitch);
  4015.             obj_surface->y_cb_offset = 0;
  4016.             obj_surface->y_cr_offset = 0;
  4017.             obj_surface->cb_cr_width = obj_surface->orig_width / 2;
  4018.             obj_surface->cb_cr_height = obj_surface->orig_height;
  4019.             obj_surface->cb_cr_pitch = obj_surface->width;
  4020.             region_width = obj_surface->width;
  4021.             region_height = obj_surface->height;
  4022.             break;
  4023.         case VA_FOURCC_RGBA:
  4024.         case VA_FOURCC_RGBX:
  4025.         case VA_FOURCC_BGRA:
  4026.         case VA_FOURCC_BGRX:
  4027.             obj_surface->width = ALIGN(obj_surface->orig_width * 4, i965->codec_info->min_linear_wpitch);
  4028.             region_width = obj_surface->width;
  4029.             region_height = obj_surface->height;
  4030.             break;
  4031.  
  4032.         default:
  4033.             /* Never get here */
  4034.             ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
  4035.             break;
  4036.         }
  4037.     }
  4038.  
  4039.     obj_surface->size = ALIGN(region_width * region_height, 0x1000);
  4040.  
  4041.     if ((tiled && !obj_surface->user_disable_tiling)) {
  4042.         uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
  4043.         unsigned long pitch;
  4044.  
  4045.         obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr,
  4046.                                                    "vaapi surface",
  4047.                                                    region_width,
  4048.                                                    region_height,
  4049.                                                    1,
  4050.                                                    &tiling_mode,
  4051.                                                    &pitch,
  4052.                                                    0);
  4053.         assert(tiling_mode == I915_TILING_Y);
  4054.         assert(pitch == obj_surface->width);
  4055.     } else {
  4056.         obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
  4057.                                        "vaapi surface",
  4058.                                        obj_surface->size,
  4059.                                        0x1000);
  4060.     }
  4061.  
  4062.     obj_surface->fourcc = fourcc;
  4063.     obj_surface->subsampling = subsampling;
  4064.     assert(obj_surface->bo);
  4065.     return VA_STATUS_SUCCESS;
  4066. }
  4067.  
  4068. VAStatus i965_DeriveImage(VADriverContextP ctx,
  4069.                           VASurfaceID surface,
  4070.                           VAImage *out_image)        /* out */
  4071. {
  4072.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4073.     struct object_image *obj_image;
  4074.     struct object_surface *obj_surface;
  4075.     VAImageID image_id;
  4076.     unsigned int w_pitch;
  4077.     VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
  4078.  
  4079.     out_image->image_id = VA_INVALID_ID;
  4080.     obj_surface = SURFACE(surface);
  4081.  
  4082.     if (!obj_surface)
  4083.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4084.  
  4085.     if (!obj_surface->bo) {
  4086.         unsigned int is_tiled = 0;
  4087.         unsigned int fourcc = VA_FOURCC_YV12;
  4088.         i965_guess_surface_format(ctx, surface, &fourcc, &is_tiled);
  4089.         int sampling = get_sampling_from_fourcc(fourcc);
  4090.         va_status = i965_check_alloc_surface_bo(ctx, obj_surface, is_tiled, fourcc, sampling);
  4091.         if (va_status != VA_STATUS_SUCCESS)
  4092.             return va_status;
  4093.     }
  4094.  
  4095.     ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
  4096.  
  4097.     w_pitch = obj_surface->width;
  4098.  
  4099.     image_id = NEW_IMAGE_ID();
  4100.  
  4101.     if (image_id == VA_INVALID_ID)
  4102.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  4103.  
  4104.     obj_image = IMAGE(image_id);
  4105.  
  4106.     if (!obj_image)
  4107.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  4108.  
  4109.     obj_image->bo = NULL;
  4110.     obj_image->palette = NULL;
  4111.     obj_image->derived_surface = VA_INVALID_ID;
  4112.  
  4113.     VAImage * const image = &obj_image->image;
  4114.  
  4115.     memset(image, 0, sizeof(*image));
  4116.     image->image_id = image_id;
  4117.     image->buf = VA_INVALID_ID;
  4118.     image->num_palette_entries = 0;
  4119.     image->entry_bytes = 0;
  4120.     image->width = obj_surface->orig_width;
  4121.     image->height = obj_surface->orig_height;
  4122.     image->data_size = obj_surface->size;
  4123.  
  4124.     image->format.fourcc = obj_surface->fourcc;
  4125.     image->format.byte_order = VA_LSB_FIRST;
  4126.     image->format.bits_per_pixel = get_bpp_from_fourcc(obj_surface->fourcc);
  4127.  
  4128.     if (!image->format.bits_per_pixel)
  4129.         goto error;
  4130.  
  4131.     switch (image->format.fourcc) {
  4132.     case VA_FOURCC_YV12:
  4133.         image->num_planes = 3;
  4134.         image->pitches[0] = w_pitch; /* Y */
  4135.         image->offsets[0] = 0;
  4136.         image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
  4137.         image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
  4138.         image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
  4139.         image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
  4140.         break;
  4141.  
  4142.     case VA_FOURCC_YV16:
  4143.         image->num_planes = 3;
  4144.         image->pitches[0] = w_pitch; /* Y */
  4145.         image->offsets[0] = 0;
  4146.         image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
  4147.         image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
  4148.         image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
  4149.         image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
  4150.         break;
  4151.  
  4152.     case VA_FOURCC_NV12:
  4153.     case VA_FOURCC_P010:
  4154.         image->num_planes = 2;
  4155.         image->pitches[0] = w_pitch; /* Y */
  4156.         image->offsets[0] = 0;
  4157.         image->pitches[1] = obj_surface->cb_cr_pitch; /* UV */
  4158.         image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
  4159.         break;
  4160.  
  4161.     case VA_FOURCC_I420:
  4162.     case VA_FOURCC_422H:
  4163.     case VA_FOURCC_IMC3:
  4164.     case VA_FOURCC_444P:
  4165.     case VA_FOURCC_422V:
  4166.     case VA_FOURCC_411P:
  4167.         image->num_planes = 3;
  4168.         image->pitches[0] = w_pitch; /* Y */
  4169.         image->offsets[0] = 0;
  4170.         image->pitches[1] = obj_surface->cb_cr_pitch; /* U */
  4171.         image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
  4172.         image->pitches[2] = obj_surface->cb_cr_pitch; /* V */
  4173.         image->offsets[2] = w_pitch * obj_surface->y_cr_offset;
  4174.         break;
  4175.  
  4176.     case VA_FOURCC_YUY2:
  4177.     case VA_FOURCC_UYVY:
  4178.     case VA_FOURCC_Y800:
  4179.         image->num_planes = 1;
  4180.         image->pitches[0] = obj_surface->width; /* Y, width is aligned already */
  4181.         image->offsets[0] = 0;
  4182.         break;
  4183.     case VA_FOURCC_RGBA:
  4184.     case VA_FOURCC_RGBX:
  4185.     case VA_FOURCC_BGRA:
  4186.     case VA_FOURCC_BGRX:
  4187.         image->num_planes = 1;
  4188.         image->pitches[0] = obj_surface->width;
  4189.  
  4190.         switch (image->format.fourcc) {
  4191.         case VA_FOURCC_RGBA:
  4192.         case VA_FOURCC_RGBX:
  4193.             image->format.red_mask = 0x000000ff;
  4194.             image->format.green_mask = 0x0000ff00;
  4195.             image->format.blue_mask = 0x00ff0000;
  4196.             image->format.alpha_mask = 0x00000000;
  4197.             break;
  4198.         case VA_FOURCC_BGRA:
  4199.         case VA_FOURCC_BGRX:
  4200.             image->format.red_mask = 0x00ff0000;
  4201.             image->format.green_mask = 0x0000ff00;
  4202.             image->format.blue_mask = 0x000000ff;
  4203.             image->format.alpha_mask = 0x00000000;
  4204.             break;
  4205.         default:
  4206.             goto error;
  4207.         }
  4208.  
  4209.         switch (image->format.fourcc) {
  4210.         case VA_FOURCC_RGBA:
  4211.         case VA_FOURCC_BGRA:
  4212.             image->format.depth = 32;
  4213.             break;
  4214.         case VA_FOURCC_RGBX:
  4215.         case VA_FOURCC_BGRX:
  4216.             image->format.depth = 24;
  4217.             break;
  4218.         default:
  4219.             goto error;
  4220.         }
  4221.  
  4222.         break;
  4223.     default:
  4224.         goto error;
  4225.     }
  4226.  
  4227.     va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType,
  4228.                                             obj_surface->size, 1, NULL, obj_surface->bo, &image->buf);
  4229.     if (va_status != VA_STATUS_SUCCESS)
  4230.         goto error;
  4231.  
  4232.     struct object_buffer *obj_buffer = BUFFER(image->buf);
  4233.  
  4234.     if (!obj_buffer ||
  4235.         !obj_buffer->buffer_store ||
  4236.         !obj_buffer->buffer_store->bo)
  4237.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  4238.  
  4239.     obj_image->bo = obj_buffer->buffer_store->bo;
  4240.     dri_bo_reference(obj_image->bo);
  4241.  
  4242.     if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
  4243.         obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
  4244.         if (!obj_image->palette) {
  4245.             va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
  4246.             goto error;
  4247.         }
  4248.     }
  4249.  
  4250.     *out_image = *image;
  4251.     obj_surface->flags |= SURFACE_DERIVED;
  4252.     obj_surface->derived_image_id = image_id;
  4253.     obj_image->derived_surface = surface;
  4254.  
  4255.     return VA_STATUS_SUCCESS;
  4256.  
  4257.  error:
  4258.     i965_DestroyImage(ctx, image_id);
  4259.     return va_status;
  4260. }
  4261.  
  4262. static void
  4263. i965_destroy_image(struct object_heap *heap, struct object_base *obj)
  4264. {
  4265.     object_heap_free(heap, obj);
  4266. }
  4267.  
  4268.  
  4269. VAStatus
  4270. i965_DestroyImage(VADriverContextP ctx, VAImageID image)
  4271. {
  4272.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4273.     struct object_image *obj_image = IMAGE(image);
  4274.     struct object_surface *obj_surface;
  4275.  
  4276.     if (!obj_image)
  4277.         return VA_STATUS_SUCCESS;
  4278.  
  4279.     dri_bo_unreference(obj_image->bo);
  4280.     obj_image->bo = NULL;
  4281.  
  4282.     if (obj_image->image.buf != VA_INVALID_ID) {
  4283.         i965_DestroyBuffer(ctx, obj_image->image.buf);
  4284.         obj_image->image.buf = VA_INVALID_ID;
  4285.     }
  4286.  
  4287.     if (obj_image->palette) {
  4288.         free(obj_image->palette);
  4289.         obj_image->palette = NULL;
  4290.     }
  4291.  
  4292.     obj_surface = SURFACE(obj_image->derived_surface);
  4293.  
  4294.     if (obj_surface) {
  4295.         obj_surface->flags &= ~SURFACE_DERIVED;
  4296.         obj_surface->derived_image_id = VA_INVALID_ID;
  4297.     }
  4298.  
  4299.     i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
  4300.  
  4301.     return VA_STATUS_SUCCESS;
  4302. }
  4303.  
  4304. /*
  4305.  * pointer to an array holding the palette data.  The size of the array is
  4306.  * num_palette_entries * entry_bytes in size.  The order of the components
  4307.  * in the palette is described by the component_order in VASubpicture struct
  4308.  */
  4309. VAStatus
  4310. i965_SetImagePalette(VADriverContextP ctx,
  4311.                      VAImageID image,
  4312.                      unsigned char *palette)
  4313. {
  4314.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  4315.     unsigned int i;
  4316.  
  4317.     struct object_image *obj_image = IMAGE(image);
  4318.     if (!obj_image)
  4319.         return VA_STATUS_ERROR_INVALID_IMAGE;
  4320.  
  4321.     if (!obj_image->palette)
  4322.         return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
  4323.  
  4324.     for (i = 0; i < obj_image->image.num_palette_entries; i++)
  4325.         obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
  4326.                                  ((unsigned int)palette[3*i + 1] <<  8) |
  4327.                                  (unsigned int)palette[3*i + 2]);
  4328.     return VA_STATUS_SUCCESS;
  4329. }
  4330.  
  4331. static int
  4332. get_sampling_from_fourcc(unsigned int fourcc)
  4333. {
  4334.     const i965_fourcc_info *info = get_fourcc_info(fourcc);
  4335.  
  4336.     if (info && (info->flag & I_S))
  4337.         return info->subsampling;
  4338.     else
  4339.         return -1;
  4340. }
  4341.  
  4342. static inline void
  4343. memcpy_pic(uint8_t *dst, unsigned int dst_stride,
  4344.            const uint8_t *src, unsigned int src_stride,
  4345.            unsigned int len, unsigned int height)
  4346. {
  4347.     unsigned int i;
  4348.  
  4349.     for (i = 0; i < height; i++) {
  4350.         memcpy(dst, src, len);
  4351.         dst += dst_stride;
  4352.         src += src_stride;
  4353.     }
  4354. }
  4355.  
  4356. static VAStatus
  4357. get_image_i420(struct object_image *obj_image, uint8_t *image_data,
  4358.                struct object_surface *obj_surface,
  4359.                const VARectangle *rect)
  4360. {
  4361.     uint8_t *dst[3], *src[3];
  4362.     const int Y = 0;
  4363.     const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
  4364.     const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
  4365.     unsigned int tiling, swizzle;
  4366.     VAStatus va_status = VA_STATUS_SUCCESS;
  4367.  
  4368.     if (!obj_surface->bo)
  4369.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4370.  
  4371.     ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
  4372.     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
  4373.  
  4374.     if (tiling != I915_TILING_NONE)
  4375.         drm_intel_gem_bo_map_gtt(obj_surface->bo);
  4376.     else
  4377.         dri_bo_map(obj_surface->bo, 0);
  4378.  
  4379.     if (!obj_surface->bo->virtual)
  4380.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4381.  
  4382.     /* Dest VA image has either I420 or YV12 format.
  4383.        Source VA surface alway has I420 format */
  4384.     dst[Y] = image_data + obj_image->image.offsets[Y];
  4385.     src[0] = (uint8_t *)obj_surface->bo->virtual;
  4386.     dst[U] = image_data + obj_image->image.offsets[U];
  4387.     src[1] = src[0] + obj_surface->width * obj_surface->height;
  4388.     dst[V] = image_data + obj_image->image.offsets[V];
  4389.     src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
  4390.  
  4391.     /* Y plane */
  4392.     dst[Y] += rect->y * obj_image->image.pitches[Y] + rect->x;
  4393.     src[0] += rect->y * obj_surface->width + rect->x;
  4394.     memcpy_pic(dst[Y], obj_image->image.pitches[Y],
  4395.                src[0], obj_surface->width,
  4396.                rect->width, rect->height);
  4397.  
  4398.     /* U plane */
  4399.     dst[U] += (rect->y / 2) * obj_image->image.pitches[U] + rect->x / 2;
  4400.     src[1] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
  4401.     memcpy_pic(dst[U], obj_image->image.pitches[U],
  4402.                src[1], obj_surface->width / 2,
  4403.                rect->width / 2, rect->height / 2);
  4404.  
  4405.     /* V plane */
  4406.     dst[V] += (rect->y / 2) * obj_image->image.pitches[V] + rect->x / 2;
  4407.     src[2] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
  4408.     memcpy_pic(dst[V], obj_image->image.pitches[V],
  4409.                src[2], obj_surface->width / 2,
  4410.                rect->width / 2, rect->height / 2);
  4411.  
  4412.     if (tiling != I915_TILING_NONE)
  4413.         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
  4414.     else
  4415.         dri_bo_unmap(obj_surface->bo);
  4416.  
  4417.     return va_status;
  4418. }
  4419.  
  4420. static VAStatus
  4421. get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
  4422.                struct object_surface *obj_surface,
  4423.                const VARectangle *rect)
  4424. {
  4425.     uint8_t *dst[2], *src[2];
  4426.     unsigned int tiling, swizzle;
  4427.     VAStatus va_status = VA_STATUS_SUCCESS;
  4428.  
  4429.     if (!obj_surface->bo)
  4430.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4431.  
  4432.     assert(obj_surface->fourcc);
  4433.     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
  4434.  
  4435.     if (tiling != I915_TILING_NONE)
  4436.         drm_intel_gem_bo_map_gtt(obj_surface->bo);
  4437.     else
  4438.         dri_bo_map(obj_surface->bo, 0);
  4439.  
  4440.     if (!obj_surface->bo->virtual)
  4441.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4442.  
  4443.     /* Both dest VA image and source surface have NV12 format */
  4444.     dst[0] = image_data + obj_image->image.offsets[0];
  4445.     src[0] = (uint8_t *)obj_surface->bo->virtual;
  4446.     dst[1] = image_data + obj_image->image.offsets[1];
  4447.     src[1] = src[0] + obj_surface->width * obj_surface->height;
  4448.  
  4449.     /* Y plane */
  4450.     dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
  4451.     src[0] += rect->y * obj_surface->width + rect->x;
  4452.     memcpy_pic(dst[0], obj_image->image.pitches[0],
  4453.                src[0], obj_surface->width,
  4454.                rect->width, rect->height);
  4455.  
  4456.     /* UV plane */
  4457.     dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + (rect->x & -2);
  4458.     src[1] += (rect->y / 2) * obj_surface->width + (rect->x & -2);
  4459.     memcpy_pic(dst[1], obj_image->image.pitches[1],
  4460.                src[1], obj_surface->width,
  4461.                rect->width, rect->height / 2);
  4462.  
  4463.     if (tiling != I915_TILING_NONE)
  4464.         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
  4465.     else
  4466.         dri_bo_unmap(obj_surface->bo);
  4467.  
  4468.     return va_status;
  4469. }
  4470.  
  4471. static VAStatus
  4472. get_image_yuy2(struct object_image *obj_image, uint8_t *image_data,
  4473.                struct object_surface *obj_surface,
  4474.                const VARectangle *rect)
  4475. {
  4476.     uint8_t *dst, *src;
  4477.     unsigned int tiling, swizzle;
  4478.     VAStatus va_status = VA_STATUS_SUCCESS;
  4479.  
  4480.     if (!obj_surface->bo)
  4481.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4482.  
  4483.     assert(obj_surface->fourcc);
  4484.     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
  4485.  
  4486.     if (tiling != I915_TILING_NONE)
  4487.         drm_intel_gem_bo_map_gtt(obj_surface->bo);
  4488.     else
  4489.         dri_bo_map(obj_surface->bo, 0);
  4490.  
  4491.     if (!obj_surface->bo->virtual)
  4492.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4493.  
  4494.     /* Both dest VA image and source surface have YUYV format */
  4495.     dst = image_data + obj_image->image.offsets[0];
  4496.     src = (uint8_t *)obj_surface->bo->virtual;
  4497.  
  4498.     /* Y plane */
  4499.     dst += rect->y * obj_image->image.pitches[0] + rect->x*2;
  4500.     src += rect->y * obj_surface->width + rect->x*2;
  4501.     memcpy_pic(dst, obj_image->image.pitches[0],
  4502.                src, obj_surface->width*2,
  4503.                rect->width*2, rect->height);
  4504.  
  4505.     if (tiling != I915_TILING_NONE)
  4506.         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
  4507.     else
  4508.         dri_bo_unmap(obj_surface->bo);
  4509.  
  4510.     return va_status;
  4511. }
  4512.  
  4513. static VAStatus
  4514. i965_sw_getimage(VADriverContextP ctx,
  4515.     struct object_surface *obj_surface, struct object_image *obj_image,
  4516.     const VARectangle *rect)
  4517. {
  4518.     void *image_data = NULL;
  4519.     VAStatus va_status;
  4520.  
  4521.     if (obj_surface->fourcc != obj_image->image.format.fourcc)
  4522.         return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
  4523.  
  4524.     va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
  4525.     if (va_status != VA_STATUS_SUCCESS)
  4526.         return va_status;
  4527.  
  4528.     switch (obj_image->image.format.fourcc) {
  4529.     case VA_FOURCC_YV12:
  4530.     case VA_FOURCC_I420:
  4531.         get_image_i420(obj_image, image_data, obj_surface, rect);
  4532.         break;
  4533.     case VA_FOURCC_NV12:
  4534.         get_image_nv12(obj_image, image_data, obj_surface, rect);
  4535.         break;
  4536.     case VA_FOURCC_YUY2:
  4537.         /* YUY2 is the format supported by overlay plane */
  4538.         get_image_yuy2(obj_image, image_data, obj_surface, rect);
  4539.         break;
  4540.     default:
  4541.         va_status = VA_STATUS_ERROR_OPERATION_FAILED;
  4542.         break;
  4543.     }
  4544.     if (va_status != VA_STATUS_SUCCESS)
  4545.         return va_status;
  4546.  
  4547.     va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
  4548.     return va_status;
  4549. }
  4550.  
  4551. static VAStatus
  4552. i965_hw_getimage(VADriverContextP ctx,
  4553.     struct object_surface *obj_surface, struct object_image *obj_image,
  4554.     const VARectangle *rect)
  4555. {
  4556.     struct i965_surface src_surface;
  4557.     struct i965_surface dst_surface;
  4558.  
  4559.     src_surface.base = (struct object_base *)obj_surface;
  4560.     src_surface.type = I965_SURFACE_TYPE_SURFACE;
  4561.     src_surface.flags = I965_SURFACE_FLAG_FRAME;
  4562.  
  4563.     dst_surface.base = (struct object_base *)obj_image;
  4564.     dst_surface.type = I965_SURFACE_TYPE_IMAGE;
  4565.     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
  4566.  
  4567.     return i965_image_processing(ctx, &src_surface, rect, &dst_surface, rect);
  4568. }
  4569.  
  4570. VAStatus
  4571. i965_GetImage(VADriverContextP ctx,
  4572.               VASurfaceID surface,
  4573.               int x,   /* coordinates of the upper left source pixel */
  4574.               int y,
  4575.               unsigned int width,      /* width and height of the region */
  4576.               unsigned int height,
  4577.               VAImageID image)
  4578. {
  4579.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  4580.     struct object_surface * const obj_surface = SURFACE(surface);
  4581.     struct object_image * const obj_image = IMAGE(image);
  4582.     VARectangle rect;
  4583.     VAStatus va_status;
  4584.  
  4585.     if (!obj_surface)
  4586.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4587.     if (!obj_surface->bo) /* don't get anything, keep previous data */
  4588.         return VA_STATUS_SUCCESS;
  4589.     if (is_surface_busy(i965, obj_surface))
  4590.         return VA_STATUS_ERROR_SURFACE_BUSY;
  4591.  
  4592.     if (!obj_image || !obj_image->bo)
  4593.         return VA_STATUS_ERROR_INVALID_IMAGE;
  4594.     if (is_image_busy(i965, obj_image, surface))
  4595.         return VA_STATUS_ERROR_SURFACE_BUSY;
  4596.  
  4597.     if (x < 0 || y < 0)
  4598.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  4599.     if (x + width > obj_surface->orig_width ||
  4600.         y + height > obj_surface->orig_height)
  4601.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  4602.     if (x + width > obj_image->image.width ||
  4603.         y + height > obj_image->image.height)
  4604.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  4605.  
  4606.     rect.x = x;
  4607.     rect.y = y;
  4608.     rect.width = width;
  4609.     rect.height = height;
  4610.  
  4611.     if (HAS_ACCELERATED_GETIMAGE(i965))
  4612.         va_status = i965_hw_getimage(ctx, obj_surface, obj_image, &rect);
  4613.     else
  4614.         va_status = i965_sw_getimage(ctx, obj_surface, obj_image, &rect);
  4615.  
  4616.     return va_status;
  4617. }
  4618.  
  4619. static VAStatus
  4620. put_image_i420(struct object_surface *obj_surface,
  4621.                const VARectangle *dst_rect,
  4622.                struct object_image *obj_image, uint8_t *image_data,
  4623.                const VARectangle *src_rect)
  4624. {
  4625.     uint8_t *dst[3], *src[3];
  4626.     const int Y = 0;
  4627.     const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
  4628.     const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
  4629.     unsigned int tiling, swizzle;
  4630.     VAStatus va_status = VA_STATUS_SUCCESS;
  4631.  
  4632.     ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
  4633.  
  4634.     ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
  4635.     ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
  4636.     ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
  4637.     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
  4638.  
  4639.     if (tiling != I915_TILING_NONE)
  4640.         drm_intel_gem_bo_map_gtt(obj_surface->bo);
  4641.     else
  4642.         dri_bo_map(obj_surface->bo, 0);
  4643.  
  4644.     if (!obj_surface->bo->virtual)
  4645.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4646.  
  4647.     /* Dest VA image has either I420 or YV12 format.
  4648.        Source VA surface alway has I420 format */
  4649.     dst[0] = (uint8_t *)obj_surface->bo->virtual;
  4650.     src[Y] = image_data + obj_image->image.offsets[Y];
  4651.     dst[1] = dst[0] + obj_surface->width * obj_surface->height;
  4652.     src[U] = image_data + obj_image->image.offsets[U];
  4653.     dst[2] = dst[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
  4654.     src[V] = image_data + obj_image->image.offsets[V];
  4655.  
  4656.     /* Y plane */
  4657.     dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
  4658.     src[Y] += src_rect->y * obj_image->image.pitches[Y] + src_rect->x;
  4659.     memcpy_pic(dst[0], obj_surface->width,
  4660.                src[Y], obj_image->image.pitches[Y],
  4661.                src_rect->width, src_rect->height);
  4662.  
  4663.     /* U plane */
  4664.     dst[1] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
  4665.     src[U] += (src_rect->y / 2) * obj_image->image.pitches[U] + src_rect->x / 2;
  4666.     memcpy_pic(dst[1], obj_surface->width / 2,
  4667.                src[U], obj_image->image.pitches[U],
  4668.                src_rect->width / 2, src_rect->height / 2);
  4669.  
  4670.     /* V plane */
  4671.     dst[2] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
  4672.     src[V] += (src_rect->y / 2) * obj_image->image.pitches[V] + src_rect->x / 2;
  4673.     memcpy_pic(dst[2], obj_surface->width / 2,
  4674.                src[V], obj_image->image.pitches[V],
  4675.                src_rect->width / 2, src_rect->height / 2);
  4676.  
  4677.     if (tiling != I915_TILING_NONE)
  4678.         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
  4679.     else
  4680.         dri_bo_unmap(obj_surface->bo);
  4681.  
  4682.     return va_status;
  4683. }
  4684.  
  4685. static VAStatus
  4686. put_image_nv12(struct object_surface *obj_surface,
  4687.                const VARectangle *dst_rect,
  4688.                struct object_image *obj_image, uint8_t *image_data,
  4689.                const VARectangle *src_rect)
  4690. {
  4691.     uint8_t *dst[2], *src[2];
  4692.     unsigned int tiling, swizzle;
  4693.     VAStatus va_status = VA_STATUS_SUCCESS;
  4694.  
  4695.     if (!obj_surface->bo)
  4696.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4697.  
  4698.     ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
  4699.     ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
  4700.     ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
  4701.     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
  4702.  
  4703.     if (tiling != I915_TILING_NONE)
  4704.         drm_intel_gem_bo_map_gtt(obj_surface->bo);
  4705.     else
  4706.         dri_bo_map(obj_surface->bo, 0);
  4707.  
  4708.     if (!obj_surface->bo->virtual)
  4709.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4710.  
  4711.     /* Both dest VA image and source surface have NV12 format */
  4712.     dst[0] = (uint8_t *)obj_surface->bo->virtual;
  4713.     src[0] = image_data + obj_image->image.offsets[0];
  4714.     dst[1] = dst[0] + obj_surface->width * obj_surface->height;
  4715.     src[1] = image_data + obj_image->image.offsets[1];
  4716.  
  4717.     /* Y plane */
  4718.     dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
  4719.     src[0] += src_rect->y * obj_image->image.pitches[0] + src_rect->x;
  4720.     memcpy_pic(dst[0], obj_surface->width,
  4721.                src[0], obj_image->image.pitches[0],
  4722.                src_rect->width, src_rect->height);
  4723.  
  4724.     /* UV plane */
  4725.     dst[1] += (dst_rect->y / 2) * obj_surface->width + (dst_rect->x & -2);
  4726.     src[1] += (src_rect->y / 2) * obj_image->image.pitches[1] + (src_rect->x & -2);
  4727.     memcpy_pic(dst[1], obj_surface->width,
  4728.                src[1], obj_image->image.pitches[1],
  4729.                src_rect->width, src_rect->height / 2);
  4730.  
  4731.     if (tiling != I915_TILING_NONE)
  4732.         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
  4733.     else
  4734.         dri_bo_unmap(obj_surface->bo);
  4735.  
  4736.     return va_status;
  4737. }
  4738.  
  4739. static VAStatus
  4740. put_image_yuy2(struct object_surface *obj_surface,
  4741.                const VARectangle *dst_rect,
  4742.                struct object_image *obj_image, uint8_t *image_data,
  4743.                const VARectangle *src_rect)
  4744. {
  4745.     uint8_t *dst, *src;
  4746.     unsigned int tiling, swizzle;
  4747.     VAStatus va_status = VA_STATUS_SUCCESS;
  4748.  
  4749.     ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
  4750.     ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
  4751.     ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
  4752.     ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
  4753.     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
  4754.  
  4755.     if (tiling != I915_TILING_NONE)
  4756.         drm_intel_gem_bo_map_gtt(obj_surface->bo);
  4757.     else
  4758.         dri_bo_map(obj_surface->bo, 0);
  4759.  
  4760.     if (!obj_surface->bo->virtual)
  4761.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4762.  
  4763.     /* Both dest VA image and source surface have YUY2 format */
  4764.     dst = (uint8_t *)obj_surface->bo->virtual;
  4765.     src = image_data + obj_image->image.offsets[0];
  4766.  
  4767.     /* YUYV packed plane */
  4768.     dst += dst_rect->y * obj_surface->width + dst_rect->x*2;
  4769.     src += src_rect->y * obj_image->image.pitches[0] + src_rect->x*2;
  4770.     memcpy_pic(dst, obj_surface->width*2,
  4771.                src, obj_image->image.pitches[0],
  4772.                src_rect->width*2, src_rect->height);
  4773.  
  4774.     if (tiling != I915_TILING_NONE)
  4775.         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
  4776.     else
  4777.         dri_bo_unmap(obj_surface->bo);
  4778.  
  4779.     return va_status;
  4780. }
  4781.  
  4782. static VAStatus
  4783. i965_sw_putimage(VADriverContextP ctx,
  4784.     struct object_surface *obj_surface, struct object_image *obj_image,
  4785.     const VARectangle *src_rect, const VARectangle *dst_rect)
  4786. {
  4787.     VAStatus va_status = VA_STATUS_SUCCESS;
  4788.     void *image_data = NULL;
  4789.  
  4790.     /* XXX: don't allow scaling */
  4791.     if (src_rect->width != dst_rect->width ||
  4792.         src_rect->height != dst_rect->height)
  4793.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  4794.  
  4795.     if (obj_surface->fourcc) {
  4796.         /* Don't allow format mismatch */
  4797.         if (obj_surface->fourcc != obj_image->image.format.fourcc)
  4798.             return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
  4799.     }
  4800.  
  4801.     else {
  4802.         /* VA is surface not used for decoding, use same VA image format */
  4803.         va_status = i965_check_alloc_surface_bo(
  4804.             ctx,
  4805.             obj_surface,
  4806.             0, /* XXX: don't use tiled surface */
  4807.             obj_image->image.format.fourcc,
  4808.             get_sampling_from_fourcc (obj_image->image.format.fourcc));
  4809.     }
  4810.  
  4811.     if (va_status != VA_STATUS_SUCCESS)
  4812.         return va_status;
  4813.  
  4814.     va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
  4815.     if (va_status != VA_STATUS_SUCCESS)
  4816.         return va_status;
  4817.  
  4818.     switch (obj_image->image.format.fourcc) {
  4819.     case VA_FOURCC_YV12:
  4820.     case VA_FOURCC_I420:
  4821.         va_status = put_image_i420(obj_surface, dst_rect, obj_image, image_data, src_rect);
  4822.         break;
  4823.     case VA_FOURCC_NV12:
  4824.         va_status = put_image_nv12(obj_surface, dst_rect, obj_image, image_data, src_rect);
  4825.         break;
  4826.     case VA_FOURCC_YUY2:
  4827.         va_status = put_image_yuy2(obj_surface, dst_rect, obj_image, image_data, src_rect);
  4828.         break;
  4829.     default:
  4830.         va_status = VA_STATUS_ERROR_OPERATION_FAILED;
  4831.         break;
  4832.     }
  4833.     if (va_status != VA_STATUS_SUCCESS)
  4834.         return va_status;
  4835.  
  4836.     va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
  4837.     return va_status;
  4838. }
  4839.  
  4840. static VAStatus
  4841. i965_hw_putimage(VADriverContextP ctx,
  4842.     struct object_surface *obj_surface, struct object_image *obj_image,
  4843.     const VARectangle *src_rect, const VARectangle *dst_rect)
  4844. {
  4845.     struct i965_surface src_surface, dst_surface;
  4846.     VAStatus va_status = VA_STATUS_SUCCESS;
  4847.  
  4848.     if (!obj_surface->bo) {
  4849.         unsigned int tiling, swizzle;
  4850.         int surface_sampling = get_sampling_from_fourcc (obj_image->image.format.fourcc);;
  4851.         dri_bo_get_tiling(obj_image->bo, &tiling, &swizzle);
  4852.  
  4853.         i965_check_alloc_surface_bo(ctx,
  4854.                                     obj_surface,
  4855.                                     !!tiling,
  4856.                                     obj_image->image.format.fourcc,
  4857.                                     surface_sampling);
  4858.     }
  4859.  
  4860.     ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
  4861.  
  4862.     src_surface.base = (struct object_base *)obj_image;
  4863.     src_surface.type = I965_SURFACE_TYPE_IMAGE;
  4864.     src_surface.flags = I965_SURFACE_FLAG_FRAME;
  4865.  
  4866.     dst_surface.base = (struct object_base *)obj_surface;
  4867.     dst_surface.type = I965_SURFACE_TYPE_SURFACE;
  4868.     dst_surface.flags = I965_SURFACE_FLAG_FRAME;
  4869.  
  4870.     va_status = i965_image_processing(ctx,
  4871.                                       &src_surface,
  4872.                                       src_rect,
  4873.                                       &dst_surface,
  4874.                                       dst_rect);
  4875.  
  4876.     return  va_status;
  4877. }
  4878.  
  4879. static VAStatus
  4880. i965_PutImage(VADriverContextP ctx,
  4881.               VASurfaceID surface,
  4882.               VAImageID image,
  4883.               int src_x,
  4884.               int src_y,
  4885.               unsigned int src_width,
  4886.               unsigned int src_height,
  4887.               int dest_x,
  4888.               int dest_y,
  4889.               unsigned int dest_width,
  4890.               unsigned int dest_height)
  4891. {
  4892.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  4893.     struct object_surface * const obj_surface = SURFACE(surface);
  4894.     struct object_image * const obj_image = IMAGE(image);
  4895.     VARectangle src_rect, dst_rect;
  4896.     VAStatus va_status;
  4897.  
  4898.     if (!obj_surface)
  4899.         return VA_STATUS_ERROR_INVALID_SURFACE;
  4900.     if (is_surface_busy(i965, obj_surface))
  4901.         return VA_STATUS_ERROR_SURFACE_BUSY;
  4902.  
  4903.     if (!obj_image || !obj_image->bo)
  4904.         return VA_STATUS_ERROR_INVALID_IMAGE;
  4905.     if (is_image_busy(i965, obj_image, surface))
  4906.         return VA_STATUS_ERROR_SURFACE_BUSY;
  4907.  
  4908.     if (src_x < 0 ||
  4909.         src_y < 0 ||
  4910.         src_x + src_width > obj_image->image.width ||
  4911.         src_y + src_height > obj_image->image.height)
  4912.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  4913.  
  4914.     src_rect.x       = src_x;
  4915.     src_rect.y       = src_y;
  4916.     src_rect.width   = src_width;
  4917.     src_rect.height  = src_height;
  4918.  
  4919.     if (dest_x < 0 ||
  4920.         dest_y < 0 ||
  4921.         dest_x + dest_width > obj_surface->orig_width ||
  4922.         dest_y + dest_height > obj_surface->orig_height)
  4923.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  4924.  
  4925.     dst_rect.x      = dest_x;
  4926.     dst_rect.y      = dest_y;
  4927.     dst_rect.width  = dest_width;
  4928.     dst_rect.height = dest_height;
  4929.  
  4930.     if (HAS_ACCELERATED_PUTIMAGE(i965))
  4931.         va_status = i965_hw_putimage(ctx, obj_surface, obj_image,
  4932.             &src_rect, &dst_rect);
  4933.     else
  4934.         va_status = i965_sw_putimage(ctx, obj_surface, obj_image,
  4935.             &src_rect, &dst_rect);
  4936.  
  4937.     return va_status;
  4938. }
  4939.  
  4940. VAStatus
  4941. i965_PutSurface(VADriverContextP ctx,
  4942.                 VASurfaceID surface,
  4943.                 void *draw, /* X Drawable */
  4944.                 short srcx,
  4945.                 short srcy,
  4946.                 unsigned short srcw,
  4947.                 unsigned short srch,
  4948.                 short destx,
  4949.                 short desty,
  4950.                 unsigned short destw,
  4951.                 unsigned short desth,
  4952.                 VARectangle *cliprects, /* client supplied clip list */
  4953.                 unsigned int number_cliprects, /* number of clip rects in the clip list */
  4954.                 unsigned int flags) /* de-interlacing flags */
  4955. {
  4956. #ifdef HAVE_VA_X11
  4957.     if (IS_VA_X11(ctx)) {
  4958.         VARectangle src_rect, dst_rect;
  4959.  
  4960.         src_rect.x      = srcx;
  4961.         src_rect.y      = srcy;
  4962.         src_rect.width  = srcw;
  4963.         src_rect.height = srch;
  4964.  
  4965.         dst_rect.x      = destx;
  4966.         dst_rect.y      = desty;
  4967.         dst_rect.width  = destw;
  4968.         dst_rect.height = desth;
  4969.  
  4970.         return i965_put_surface_dri(ctx, surface, draw, &src_rect, &dst_rect,
  4971.                                     cliprects, number_cliprects, flags);
  4972.     }
  4973. #endif
  4974.     return VA_STATUS_ERROR_UNIMPLEMENTED;
  4975. }
  4976.  
  4977. static VAStatus
  4978. i965_BufferInfo(
  4979.     VADriverContextP ctx,       /* in */
  4980.     VABufferID buf_id,          /* in */
  4981.     VABufferType *type,         /* out */
  4982.     unsigned int *size,         /* out */
  4983.     unsigned int *num_elements  /* out */
  4984. )
  4985. {
  4986.     struct i965_driver_data *i965 = NULL;
  4987.     struct object_buffer *obj_buffer = NULL;
  4988.  
  4989.     i965 = i965_driver_data(ctx);
  4990.     obj_buffer = BUFFER(buf_id);
  4991.  
  4992.     ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
  4993.  
  4994.     *type = obj_buffer->type;
  4995.     *size = obj_buffer->size_element;
  4996.     *num_elements = obj_buffer->num_elements;
  4997.  
  4998.     return VA_STATUS_SUCCESS;
  4999. }
  5000.  
  5001. static VAStatus
  5002. i965_LockSurface(
  5003.     VADriverContextP ctx,           /* in */
  5004.     VASurfaceID surface,            /* in */
  5005.     unsigned int *fourcc,           /* out */
  5006.     unsigned int *luma_stride,      /* out */
  5007.     unsigned int *chroma_u_stride,  /* out */
  5008.     unsigned int *chroma_v_stride,  /* out */
  5009.     unsigned int *luma_offset,      /* out */
  5010.     unsigned int *chroma_u_offset,  /* out */
  5011.     unsigned int *chroma_v_offset,  /* out */
  5012.     unsigned int *buffer_name,      /* out */
  5013.     void **buffer                   /* out */
  5014. )
  5015. {
  5016.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  5017.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  5018.     struct object_surface *obj_surface = NULL;
  5019.     VAImage tmpImage;
  5020.  
  5021.     ASSERT_RET(fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
  5022.     ASSERT_RET(luma_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
  5023.     ASSERT_RET(chroma_u_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
  5024.     ASSERT_RET(chroma_v_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
  5025.     ASSERT_RET(luma_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
  5026.     ASSERT_RET(chroma_u_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
  5027.     ASSERT_RET(chroma_v_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
  5028.     ASSERT_RET(buffer_name, VA_STATUS_ERROR_INVALID_PARAMETER);
  5029.     ASSERT_RET(buffer, VA_STATUS_ERROR_INVALID_PARAMETER);
  5030.  
  5031.     tmpImage.image_id = VA_INVALID_ID;
  5032.  
  5033.     obj_surface = SURFACE(surface);
  5034.     if (obj_surface == NULL) {
  5035.         // Surface is absent.
  5036.         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
  5037.         goto error;
  5038.     }
  5039.  
  5040.     // Lock functionality is absent now.
  5041.     if (obj_surface->locked_image_id != VA_INVALID_ID) {
  5042.         // Surface is locked already.
  5043.         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
  5044.         goto error;
  5045.     }
  5046.  
  5047.     vaStatus = i965_DeriveImage(
  5048.         ctx,
  5049.         surface,
  5050.         &tmpImage);
  5051.     if (vaStatus != VA_STATUS_SUCCESS) {
  5052.         goto error;
  5053.     }
  5054.  
  5055.     obj_surface->locked_image_id = tmpImage.image_id;
  5056.  
  5057.     vaStatus = i965_MapBuffer(
  5058.         ctx,
  5059.         tmpImage.buf,
  5060.         buffer);
  5061.     if (vaStatus != VA_STATUS_SUCCESS) {
  5062.         goto error;
  5063.     }
  5064.  
  5065.     *fourcc = tmpImage.format.fourcc;
  5066.     *luma_offset = tmpImage.offsets[0];
  5067.     *luma_stride = tmpImage.pitches[0];
  5068.     *chroma_u_offset = tmpImage.offsets[1];
  5069.     *chroma_u_stride = tmpImage.pitches[1];
  5070.     *chroma_v_offset = tmpImage.offsets[2];
  5071.     *chroma_v_stride = tmpImage.pitches[2];
  5072.     *buffer_name = tmpImage.buf;
  5073.  
  5074. error:
  5075.     if (vaStatus != VA_STATUS_SUCCESS) {
  5076.         buffer = NULL;
  5077.     }
  5078.  
  5079.     return vaStatus;
  5080. }
  5081.  
  5082. static VAStatus
  5083. i965_UnlockSurface(
  5084.     VADriverContextP ctx,   /* in */
  5085.     VASurfaceID surface     /* in */
  5086. )
  5087. {
  5088.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  5089.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  5090.     struct object_image *locked_img = NULL;
  5091.     struct object_surface *obj_surface = NULL;
  5092.  
  5093.     obj_surface = SURFACE(surface);
  5094.  
  5095.     if (obj_surface == NULL) {
  5096.         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;   // Surface is absent
  5097.         return vaStatus;
  5098.     }
  5099.     if (obj_surface->locked_image_id == VA_INVALID_ID) {
  5100.         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;   // Surface is not locked
  5101.         return vaStatus;
  5102.     }
  5103.  
  5104.     locked_img = IMAGE(obj_surface->locked_image_id);
  5105.     if (locked_img == NULL || (locked_img->image.image_id == VA_INVALID_ID)) {
  5106.         // Work image was deallocated before i965_UnlockSurface()
  5107.         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
  5108.         goto error;
  5109.     }
  5110.  
  5111.     vaStatus = i965_UnmapBuffer(
  5112.         ctx,
  5113.         locked_img->image.buf);
  5114.     if (vaStatus != VA_STATUS_SUCCESS) {
  5115.         goto error;
  5116.     }
  5117.  
  5118.     vaStatus = i965_DestroyImage(
  5119.         ctx,
  5120.         locked_img->image.image_id);
  5121.     if (vaStatus != VA_STATUS_SUCCESS) {
  5122.         goto error;
  5123.     }
  5124.  
  5125.     locked_img->image.image_id = VA_INVALID_ID;
  5126.  
  5127.  error:
  5128.     obj_surface->locked_image_id = VA_INVALID_ID;
  5129.  
  5130.     return vaStatus;
  5131. }
  5132.  
  5133. static VAStatus
  5134. i965_GetSurfaceAttributes(
  5135.     VADriverContextP ctx,
  5136.     VAConfigID config,
  5137.     VASurfaceAttrib *attrib_list,
  5138.     unsigned int num_attribs
  5139.     )
  5140. {
  5141.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  5142.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  5143.     struct object_config *obj_config;
  5144.     int i;
  5145.  
  5146.     if (config == VA_INVALID_ID)
  5147.         return VA_STATUS_ERROR_INVALID_CONFIG;
  5148.  
  5149.     obj_config = CONFIG(config);
  5150.  
  5151.     if (obj_config == NULL)
  5152.         return VA_STATUS_ERROR_INVALID_CONFIG;
  5153.  
  5154.     if (attrib_list == NULL || num_attribs == 0)
  5155.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  5156.  
  5157.     for (i = 0; i < num_attribs; i++) {
  5158.         switch (attrib_list[i].type) {
  5159.         case VASurfaceAttribPixelFormat:
  5160.             attrib_list[i].value.type = VAGenericValueTypeInteger;
  5161.             attrib_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5162.  
  5163.             if (attrib_list[i].value.value.i == 0) {
  5164.                 if (IS_G4X(i965->intel.device_info)) {
  5165.                     if (obj_config->profile == VAProfileMPEG2Simple ||
  5166.                         obj_config->profile == VAProfileMPEG2Main) {
  5167.                         attrib_list[i].value.value.i = VA_FOURCC_I420;
  5168.                     } else {
  5169.                         assert(0);
  5170.                         attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
  5171.                     }
  5172.                 } else if (IS_IRONLAKE(i965->intel.device_info)) {
  5173.                     if (obj_config->profile == VAProfileMPEG2Simple ||
  5174.                         obj_config->profile == VAProfileMPEG2Main) {
  5175.                         attrib_list[i].value.value.i = VA_FOURCC_I420;
  5176.                     } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
  5177.                                obj_config->profile == VAProfileH264Main ||
  5178.                                obj_config->profile == VAProfileH264High) {
  5179.                         attrib_list[i].value.value.i = VA_FOURCC_NV12;
  5180.                     } else if (obj_config->profile == VAProfileNone) {
  5181.                         attrib_list[i].value.value.i = VA_FOURCC_NV12;
  5182.                     } else {
  5183.                         assert(0);
  5184.                         attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
  5185.                     }
  5186.                 } else if (IS_GEN6(i965->intel.device_info)) {
  5187.                     attrib_list[i].value.value.i = VA_FOURCC_NV12;
  5188.                 } else if (IS_GEN7(i965->intel.device_info) ||
  5189.                            IS_GEN8(i965->intel.device_info) ||
  5190.                            IS_GEN9(i965->intel.device_info)) {
  5191.                     if (obj_config->profile == VAProfileJPEGBaseline)
  5192.                         attrib_list[i].value.value.i = 0; /* internal format */
  5193.                     else
  5194.                         attrib_list[i].value.value.i = VA_FOURCC_NV12;
  5195.                 }
  5196.             } else {
  5197.                 if (IS_G4X(i965->intel.device_info)) {
  5198.                     if (obj_config->profile == VAProfileMPEG2Simple ||
  5199.                         obj_config->profile == VAProfileMPEG2Main) {
  5200.                         if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
  5201.                             attrib_list[i].value.value.i = 0;
  5202.                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
  5203.                         }
  5204.                     } else {
  5205.                         assert(0);
  5206.                         attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
  5207.                     }
  5208.                 } else if (IS_IRONLAKE(i965->intel.device_info)) {
  5209.                     if (obj_config->profile == VAProfileMPEG2Simple ||
  5210.                         obj_config->profile == VAProfileMPEG2Main) {
  5211.                         if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
  5212.                             attrib_list[i].value.value.i = 0;
  5213.                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
  5214.                         }
  5215.                     } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
  5216.                                obj_config->profile == VAProfileH264Main ||
  5217.                                obj_config->profile == VAProfileH264High) {
  5218.                         if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
  5219.                             attrib_list[i].value.value.i = 0;
  5220.                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
  5221.                         }
  5222.                     } else if (obj_config->profile == VAProfileNone) {
  5223.                         switch (attrib_list[i].value.value.i) {
  5224.                         case VA_FOURCC_NV12:
  5225.                         case VA_FOURCC_I420:
  5226.                         case VA_FOURCC_YV12:
  5227.                         case VA_FOURCC_YUY2:
  5228.                         case VA_FOURCC_BGRA:
  5229.                         case VA_FOURCC_BGRX:
  5230.                         case VA_FOURCC_RGBX:
  5231.                         case VA_FOURCC_RGBA:
  5232.                             break;
  5233.                         default:
  5234.                             attrib_list[i].value.value.i = 0;
  5235.                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
  5236.                             break;
  5237.                         }
  5238.                     } else {
  5239.                         assert(0);
  5240.                         attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
  5241.                     }
  5242.                 } else if (IS_GEN6(i965->intel.device_info)) {
  5243.                     if (obj_config->entrypoint == VAEntrypointEncSlice ||
  5244.                         obj_config->entrypoint == VAEntrypointVideoProc) {
  5245.                         switch (attrib_list[i].value.value.i) {
  5246.                         case VA_FOURCC_NV12:
  5247.                         case VA_FOURCC_I420:
  5248.                         case VA_FOURCC_YV12:
  5249.                         case VA_FOURCC_YUY2:
  5250.                         case VA_FOURCC_BGRA:
  5251.                         case VA_FOURCC_BGRX:
  5252.                         case VA_FOURCC_RGBX:
  5253.                         case VA_FOURCC_RGBA:
  5254.                             break;
  5255.                         default:
  5256.                             attrib_list[i].value.value.i = 0;
  5257.                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
  5258.                             break;
  5259.                         }
  5260.                     } else {
  5261.                         if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
  5262.                             attrib_list[i].value.value.i = 0;
  5263.                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
  5264.                         }
  5265.                     }
  5266.                 } else if (IS_GEN7(i965->intel.device_info) ||
  5267.                            IS_GEN8(i965->intel.device_info) ||
  5268.                            IS_GEN9(i965->intel.device_info)) {
  5269.                     if (obj_config->entrypoint == VAEntrypointEncSlice ||
  5270.                         obj_config->entrypoint == VAEntrypointVideoProc) {
  5271.                         switch (attrib_list[i].value.value.i) {
  5272.                         case VA_FOURCC_NV12:
  5273.                         case VA_FOURCC_I420:
  5274.                         case VA_FOURCC_YV12:
  5275.                             break;
  5276.                         default:
  5277.                             attrib_list[i].value.value.i = 0;
  5278.                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
  5279.                             break;
  5280.                         }
  5281.                     } else {
  5282.                         if (obj_config->profile == VAProfileJPEGBaseline) {
  5283.                             attrib_list[i].value.value.i = 0;   /* JPEG decoding always uses an internal format */
  5284.                             attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
  5285.                         } else {
  5286.                             if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
  5287.                                 attrib_list[i].value.value.i = 0;
  5288.                                 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
  5289.                             }
  5290.                         }
  5291.                     }
  5292.                 }
  5293.             }
  5294.  
  5295.             break;
  5296.         case VASurfaceAttribMinWidth:
  5297.             /* FIXME: add support for it later */
  5298.             attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
  5299.             break;
  5300.         case VASurfaceAttribMaxWidth:
  5301.             attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
  5302.             break;
  5303.         case VASurfaceAttribMinHeight:
  5304.             attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
  5305.             break;
  5306.         case VASurfaceAttribMaxHeight:
  5307.             attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
  5308.             break;
  5309.         default:
  5310.             attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
  5311.             break;
  5312.         }
  5313.     }
  5314.  
  5315.     return vaStatus;
  5316. }
  5317.  
  5318. static VAStatus
  5319. i965_QuerySurfaceAttributes(VADriverContextP ctx,
  5320.                             VAConfigID config,
  5321.                             VASurfaceAttrib *attrib_list,
  5322.                             unsigned int *num_attribs)
  5323. {
  5324.     VAStatus vaStatus = VA_STATUS_SUCCESS;
  5325.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  5326.     struct object_config *obj_config;
  5327.     int i = 0;
  5328.     VASurfaceAttrib *attribs = NULL;
  5329.  
  5330.     if (config == VA_INVALID_ID)
  5331.         return VA_STATUS_ERROR_INVALID_CONFIG;
  5332.  
  5333.     obj_config = CONFIG(config);
  5334.  
  5335.     if (obj_config == NULL)
  5336.         return VA_STATUS_ERROR_INVALID_CONFIG;
  5337.  
  5338.     if (!attrib_list && !num_attribs)
  5339.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  5340.  
  5341.     if (attrib_list == NULL) {
  5342.         *num_attribs = I965_MAX_SURFACE_ATTRIBUTES;
  5343.         return VA_STATUS_SUCCESS;
  5344.     }
  5345.  
  5346.     attribs = malloc(I965_MAX_SURFACE_ATTRIBUTES *sizeof(*attribs));
  5347.  
  5348.     if (attribs == NULL)
  5349.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  5350.  
  5351.     if (IS_G4X(i965->intel.device_info)) {
  5352.         if (obj_config->profile == VAProfileMPEG2Simple ||
  5353.             obj_config->profile == VAProfileMPEG2Main) {
  5354.             attribs[i].type = VASurfaceAttribPixelFormat;
  5355.             attribs[i].value.type = VAGenericValueTypeInteger;
  5356.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5357.             attribs[i].value.value.i = VA_FOURCC_I420;
  5358.             i++;
  5359.         }
  5360.     } else if (IS_IRONLAKE(i965->intel.device_info)) {
  5361.         switch (obj_config->profile) {
  5362.         case VAProfileMPEG2Simple:
  5363.         case VAProfileMPEG2Main:
  5364.             attribs[i].type = VASurfaceAttribPixelFormat;
  5365.             attribs[i].value.type = VAGenericValueTypeInteger;
  5366.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5367.             attribs[i].value.value.i = VA_FOURCC_I420;
  5368.             i++;
  5369.  
  5370.             break;
  5371.  
  5372.         case VAProfileH264ConstrainedBaseline:
  5373.         case VAProfileH264Main:
  5374.         case VAProfileH264High:
  5375.             attribs[i].type = VASurfaceAttribPixelFormat;
  5376.             attribs[i].value.type = VAGenericValueTypeInteger;
  5377.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5378.             attribs[i].value.value.i = VA_FOURCC_NV12;
  5379.             i++;
  5380.  
  5381.         case VAProfileNone:
  5382.             attribs[i].type = VASurfaceAttribPixelFormat;
  5383.             attribs[i].value.type = VAGenericValueTypeInteger;
  5384.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5385.             attribs[i].value.value.i = VA_FOURCC_NV12;
  5386.             i++;
  5387.  
  5388.             attribs[i].type = VASurfaceAttribPixelFormat;
  5389.             attribs[i].value.type = VAGenericValueTypeInteger;
  5390.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5391.             attribs[i].value.value.i = VA_FOURCC_I420;
  5392.             i++;
  5393.  
  5394.             break;
  5395.  
  5396.         default:
  5397.             break;
  5398.         }
  5399.     } else if (IS_GEN6(i965->intel.device_info)) {
  5400.         if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
  5401.             attribs[i].type = VASurfaceAttribPixelFormat;
  5402.             attribs[i].value.type = VAGenericValueTypeInteger;
  5403.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5404.             attribs[i].value.value.i = VA_FOURCC_NV12;
  5405.             i++;
  5406.         } else if (obj_config->entrypoint == VAEntrypointEncSlice ||  /* encode */
  5407.                    obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
  5408.             attribs[i].type = VASurfaceAttribPixelFormat;
  5409.             attribs[i].value.type = VAGenericValueTypeInteger;
  5410.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5411.             attribs[i].value.value.i = VA_FOURCC_NV12;
  5412.             i++;
  5413.  
  5414.             attribs[i].type = VASurfaceAttribPixelFormat;
  5415.             attribs[i].value.type = VAGenericValueTypeInteger;
  5416.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5417.             attribs[i].value.value.i = VA_FOURCC_I420;
  5418.             i++;
  5419.  
  5420.             attribs[i].type = VASurfaceAttribPixelFormat;
  5421.             attribs[i].value.type = VAGenericValueTypeInteger;
  5422.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5423.             attribs[i].value.value.i = VA_FOURCC_YV12;
  5424.             i++;
  5425.  
  5426.             if (obj_config->entrypoint == VAEntrypointVideoProc) {
  5427.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5428.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5429.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5430.                 attribs[i].value.value.i = VA_FOURCC_YUY2;
  5431.                 i++;
  5432.  
  5433.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5434.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5435.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5436.                 attribs[i].value.value.i = VA_FOURCC_RGBA;
  5437.                 i++;
  5438.  
  5439.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5440.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5441.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5442.                 attribs[i].value.value.i = VA_FOURCC_RGBX;
  5443.                 i++;
  5444.             }
  5445.         }
  5446.     } else if (IS_GEN7(i965->intel.device_info)) {
  5447.         if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
  5448.             if (obj_config->profile == VAProfileJPEGBaseline) {
  5449.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5450.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5451.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5452.                 attribs[i].value.value.i = VA_FOURCC_IMC3;
  5453.                 i++;
  5454.  
  5455.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5456.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5457.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5458.                 attribs[i].value.value.i = VA_FOURCC_IMC1;
  5459.                 i++;
  5460.  
  5461.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5462.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5463.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5464.                 attribs[i].value.value.i = VA_FOURCC_Y800;
  5465.                 i++;
  5466.  
  5467.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5468.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5469.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5470.                 attribs[i].value.value.i = VA_FOURCC_411P;
  5471.                 i++;
  5472.  
  5473.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5474.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5475.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5476.                 attribs[i].value.value.i = VA_FOURCC_422H;
  5477.                 i++;
  5478.  
  5479.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5480.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5481.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5482.                 attribs[i].value.value.i = VA_FOURCC_422V;
  5483.                 i++;
  5484.  
  5485.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5486.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5487.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5488.                 attribs[i].value.value.i = VA_FOURCC_444P;
  5489.                 i++;
  5490.             } else if (obj_config->profile == VAProfileHEVCMain10) {
  5491.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5492.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5493.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5494.                 attribs[i].value.value.i = VA_FOURCC_P010;
  5495.                 i++;
  5496.              } else {
  5497.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5498.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5499.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5500.                 attribs[i].value.value.i = VA_FOURCC_NV12;
  5501.                 i++;
  5502.             }
  5503.         } else if (obj_config->entrypoint == VAEntrypointEncSlice ||  /* encode */
  5504.                    obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
  5505.             attribs[i].type = VASurfaceAttribPixelFormat;
  5506.             attribs[i].value.type = VAGenericValueTypeInteger;
  5507.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5508.             attribs[i].value.value.i = VA_FOURCC_NV12;
  5509.             i++;
  5510.  
  5511.             attribs[i].type = VASurfaceAttribPixelFormat;
  5512.             attribs[i].value.type = VAGenericValueTypeInteger;
  5513.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5514.             attribs[i].value.value.i = VA_FOURCC_I420;
  5515.             i++;
  5516.  
  5517.             attribs[i].type = VASurfaceAttribPixelFormat;
  5518.             attribs[i].value.type = VAGenericValueTypeInteger;
  5519.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5520.             attribs[i].value.value.i = VA_FOURCC_YV12;
  5521.             i++;
  5522.  
  5523.             attribs[i].type = VASurfaceAttribPixelFormat;
  5524.             attribs[i].value.type = VAGenericValueTypeInteger;
  5525.             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5526.             attribs[i].value.value.i = VA_FOURCC_IMC3;
  5527.             i++;
  5528.  
  5529.             if (obj_config->entrypoint == VAEntrypointVideoProc) {
  5530.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5531.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5532.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5533.                 attribs[i].value.value.i = VA_FOURCC_YUY2;
  5534.                 i++;
  5535.  
  5536.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5537.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5538.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5539.                 attribs[i].value.value.i = VA_FOURCC_RGBA;
  5540.                 i++;
  5541.  
  5542.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5543.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5544.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5545.                 attribs[i].value.value.i = VA_FOURCC_RGBX;
  5546.                 i++;
  5547.  
  5548.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5549.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5550.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5551.                 attribs[i].value.value.i = VA_FOURCC_BGRA;
  5552.                 i++;
  5553.  
  5554.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5555.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5556.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5557.                 attribs[i].value.value.i = VA_FOURCC_BGRX;
  5558.                 i++;
  5559.  
  5560.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5561.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5562.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5563.                 attribs[i].value.value.i = VA_FOURCC_YV16;
  5564.                 i++;
  5565.             }
  5566.         }
  5567.     } else if (IS_GEN8(i965->intel.device_info) ||
  5568.                IS_GEN9(i965->intel.device_info)) {
  5569.         if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
  5570.             if (obj_config->profile == VAProfileJPEGBaseline) {
  5571.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5572.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5573.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5574.                 attribs[i].value.value.i = VA_FOURCC_IMC3;
  5575.                 i++;
  5576.  
  5577.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5578.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5579.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5580.                 attribs[i].value.value.i = VA_FOURCC_IMC1;
  5581.                 i++;
  5582.  
  5583.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5584.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5585.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5586.                 attribs[i].value.value.i = VA_FOURCC_Y800;
  5587.                 i++;
  5588.  
  5589.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5590.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5591.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5592.                 attribs[i].value.value.i = VA_FOURCC_411P;
  5593.                 i++;
  5594.  
  5595.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5596.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5597.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5598.                 attribs[i].value.value.i = VA_FOURCC_422H;
  5599.                 i++;
  5600.  
  5601.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5602.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5603.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5604.                 attribs[i].value.value.i = VA_FOURCC_422V;
  5605.                 i++;
  5606.  
  5607.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5608.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5609.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5610.                 attribs[i].value.value.i = VA_FOURCC_444P;
  5611.                 i++;
  5612.             } else {
  5613.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5614.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5615.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5616.                 attribs[i].value.value.i = VA_FOURCC_NV12;
  5617.                 i++;
  5618.             }
  5619.         } else if (obj_config->entrypoint == VAEntrypointEncSlice ||  /* encode */
  5620.                    obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
  5621.  
  5622.             if (obj_config->profile == VAProfileHEVCMain10) {
  5623.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5624.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5625.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5626.                 attribs[i].value.value.i = VA_FOURCC_P010;
  5627.                 i++;
  5628.             } else {
  5629.               attribs[i].type = VASurfaceAttribPixelFormat;
  5630.               attribs[i].value.type = VAGenericValueTypeInteger;
  5631.               attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5632.               attribs[i].value.value.i = VA_FOURCC_NV12;
  5633.               i++;
  5634.  
  5635.               attribs[i].type = VASurfaceAttribPixelFormat;
  5636.               attribs[i].value.type = VAGenericValueTypeInteger;
  5637.               attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5638.               attribs[i].value.value.i = VA_FOURCC_I420;
  5639.               i++;
  5640.  
  5641.               attribs[i].type = VASurfaceAttribPixelFormat;
  5642.               attribs[i].value.type = VAGenericValueTypeInteger;
  5643.               attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5644.               attribs[i].value.value.i = VA_FOURCC_YV12;
  5645.               i++;
  5646.  
  5647.               attribs[i].type = VASurfaceAttribPixelFormat;
  5648.               attribs[i].value.type = VAGenericValueTypeInteger;
  5649.               attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5650.               attribs[i].value.value.i = VA_FOURCC_IMC3;
  5651.               i++;
  5652.             }
  5653.  
  5654.             if (obj_config->entrypoint == VAEntrypointVideoProc) {
  5655.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5656.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5657.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5658.                 attribs[i].value.value.i = VA_FOURCC_YUY2;
  5659.                 i++;
  5660.  
  5661.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5662.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5663.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5664.                 attribs[i].value.value.i = VA_FOURCC_RGBA;
  5665.                 i++;
  5666.  
  5667.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5668.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5669.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5670.                 attribs[i].value.value.i = VA_FOURCC_RGBX;
  5671.                 i++;
  5672.  
  5673.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5674.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5675.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5676.                 attribs[i].value.value.i = VA_FOURCC_BGRA;
  5677.                 i++;
  5678.  
  5679.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5680.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5681.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5682.                 attribs[i].value.value.i = VA_FOURCC_BGRX;
  5683.                 i++;
  5684.  
  5685.                 attribs[i].type = VASurfaceAttribPixelFormat;
  5686.                 attribs[i].value.type = VAGenericValueTypeInteger;
  5687.                 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5688.                 attribs[i].value.value.i = VA_FOURCC_YV16;
  5689.                 i++;
  5690.             }
  5691.         }
  5692.     }
  5693.  
  5694.     attribs[i].type = VASurfaceAttribMemoryType;
  5695.     attribs[i].value.type = VAGenericValueTypeInteger;
  5696.     attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
  5697.     attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
  5698.         VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
  5699.         VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
  5700.     i++;
  5701.  
  5702.     attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
  5703.     attribs[i].value.type = VAGenericValueTypePointer;
  5704.     attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
  5705.     attribs[i].value.value.p = NULL; /* ignore */
  5706.     i++;
  5707.  
  5708.     attribs[i].type = VASurfaceAttribMaxWidth;
  5709.     attribs[i].value.type = VAGenericValueTypeInteger;
  5710.     attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
  5711.     attribs[i].value.value.i = i965->codec_info->max_width;
  5712.     i++;
  5713.  
  5714.     attribs[i].type = VASurfaceAttribMaxHeight;
  5715.     attribs[i].value.type = VAGenericValueTypeInteger;
  5716.     attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
  5717.     attribs[i].value.value.i = i965->codec_info->max_height;
  5718.     i++;
  5719.  
  5720.     if (i > *num_attribs) {
  5721.         *num_attribs = i;
  5722.         free(attribs);
  5723.         return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
  5724.     }
  5725.  
  5726.     *num_attribs = i;
  5727.     memcpy(attrib_list, attribs, i * sizeof(*attribs));
  5728.     free(attribs);
  5729.  
  5730.     return vaStatus;
  5731. }
  5732.  
  5733. /* Acquires buffer handle for external API usage (internal implementation) */
  5734. static VAStatus
  5735. i965_acquire_buffer_handle(struct object_buffer *obj_buffer,
  5736.     uint32_t mem_type, VABufferInfo *out_buf_info)
  5737. {
  5738.     struct buffer_store *buffer_store;
  5739.  
  5740.     buffer_store = obj_buffer->buffer_store;
  5741.     if (!buffer_store || !buffer_store->bo)
  5742.         return VA_STATUS_ERROR_INVALID_BUFFER;
  5743.  
  5744.     /* Synchronization point */
  5745.     drm_intel_bo_wait_rendering(buffer_store->bo);
  5746.  
  5747.     if (obj_buffer->export_refcount > 0) {
  5748.         if (obj_buffer->export_state.mem_type != mem_type)
  5749.             return VA_STATUS_ERROR_INVALID_PARAMETER;
  5750.     }
  5751.     else {
  5752.         VABufferInfo * const buf_info = &obj_buffer->export_state;
  5753.  
  5754.         switch (mem_type) {
  5755.         case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: {
  5756.             uint32_t name;
  5757.             if (drm_intel_bo_flink(buffer_store->bo, &name) != 0)
  5758.                 return VA_STATUS_ERROR_INVALID_BUFFER;
  5759.             buf_info->handle = name;
  5760.             break;
  5761.         }
  5762.         case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
  5763.             int fd = -1;
  5764. //            if (drm_intel_bo_gem_export_to_prime(buffer_store->bo, &fd) != 0)
  5765. //                return VA_STATUS_ERROR_INVALID_BUFFER;
  5766.             buf_info->handle = (intptr_t)fd;
  5767.             break;
  5768.         }
  5769.         }
  5770.  
  5771.         buf_info->type = obj_buffer->type;
  5772.         buf_info->mem_type = mem_type;
  5773.         buf_info->mem_size =
  5774.             obj_buffer->num_elements * obj_buffer->size_element;
  5775.     }
  5776.  
  5777.     obj_buffer->export_refcount++;
  5778.     *out_buf_info = obj_buffer->export_state;
  5779.     return VA_STATUS_SUCCESS;
  5780. }
  5781.  
  5782. /* Releases buffer handle after usage (internal implementation) */
  5783. static VAStatus
  5784. i965_release_buffer_handle(struct object_buffer *obj_buffer)
  5785. {
  5786.     if (obj_buffer->export_refcount == 0)
  5787.         return VA_STATUS_ERROR_INVALID_BUFFER;
  5788.  
  5789.     if (--obj_buffer->export_refcount == 0) {
  5790.         VABufferInfo * const buf_info = &obj_buffer->export_state;
  5791.  
  5792.         switch (buf_info->mem_type) {
  5793.         case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
  5794.             close((intptr_t)buf_info->handle);
  5795.             break;
  5796.         }
  5797.         }
  5798.         buf_info->mem_type = 0;
  5799.     }
  5800.     return VA_STATUS_SUCCESS;
  5801. }
  5802.  
  5803. /** Acquires buffer handle for external API usage */
  5804. static VAStatus
  5805. i965_AcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
  5806.     VABufferInfo *buf_info)
  5807. {
  5808.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  5809.     struct object_buffer * const obj_buffer = BUFFER(buf_id);
  5810.     uint32_t i, mem_type;
  5811.  
  5812.     /* List of supported memory types, in preferred order */
  5813.     static const uint32_t mem_types[] = {
  5814.         VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
  5815.         VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM,
  5816.         0
  5817.     };
  5818.  
  5819.     if (!obj_buffer)
  5820.         return VA_STATUS_ERROR_INVALID_BUFFER;
  5821.     /* XXX: only VA surface|image like buffers are supported for now */
  5822.     if (obj_buffer->type != VAImageBufferType)
  5823.         return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
  5824.  
  5825.     /*
  5826.      * As the allocated buffer by calling vaCreateBuffer is related with
  5827.      * the specific context, it is unnecessary to export it.
  5828.      * So it is not supported when the buffer is allocated from wrapped
  5829.      * backend dirver.
  5830.      */
  5831.     if (obj_buffer->wrapper_buffer != VA_INVALID_ID) {
  5832.         return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
  5833.     }
  5834.  
  5835.     if (!buf_info)
  5836.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  5837.  
  5838.     if (!buf_info->mem_type)
  5839.         mem_type = mem_types[0];
  5840.     else {
  5841.         mem_type = 0;
  5842.         for (i = 0; mem_types[i] != 0; i++) {
  5843.             if (buf_info->mem_type & mem_types[i]) {
  5844.                 mem_type = buf_info->mem_type;
  5845.                 break;
  5846.             }
  5847.         }
  5848.         if (!mem_type)
  5849.             return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
  5850.     }
  5851.     return i965_acquire_buffer_handle(obj_buffer, mem_type, buf_info);
  5852. }
  5853.  
  5854. /** Releases buffer handle after usage from external API */
  5855. static VAStatus
  5856. i965_ReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id)
  5857. {
  5858.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  5859.     struct object_buffer * const obj_buffer = BUFFER(buf_id);
  5860.  
  5861.     if (!obj_buffer)
  5862.         return VA_STATUS_ERROR_INVALID_BUFFER;
  5863.  
  5864.     if (obj_buffer->wrapper_buffer != VA_INVALID_ID) {
  5865.         return VA_STATUS_ERROR_INVALID_BUFFER;
  5866.     }
  5867.  
  5868.     return i965_release_buffer_handle(obj_buffer);
  5869. }
  5870.  
  5871. static int
  5872. i965_os_has_ring_support(VADriverContextP ctx,
  5873.                          int ring)
  5874. {
  5875.     struct i965_driver_data *const i965 = i965_driver_data(ctx);
  5876.  
  5877.     switch (ring) {
  5878.     case I965_RING_BSD:
  5879.         return i965->intel.has_bsd;
  5880.  
  5881.     case I965_RING_BLT:
  5882.         return i965->intel.has_blt;
  5883.  
  5884.     case I965_RING_VEBOX:
  5885.         return i965->intel.has_vebox;
  5886.  
  5887.     case I965_RING_NULL:
  5888.         return 1; /* Always support */
  5889.  
  5890.     default:
  5891.         /* should never get here */
  5892.         assert(0);
  5893.         break;
  5894.     }
  5895.  
  5896.     return 0;
  5897. }
  5898.  
  5899. /*
  5900.  * Query video processing pipeline
  5901.  */
  5902. VAStatus i965_QueryVideoProcFilters(
  5903.     VADriverContextP    ctx,
  5904.     VAContextID         context,
  5905.     VAProcFilterType   *filters,
  5906.     unsigned int       *num_filters
  5907.     )
  5908. {
  5909.     struct i965_driver_data *const i965 = i965_driver_data(ctx);
  5910.     unsigned int i = 0, num = 0;
  5911.  
  5912.     if (!num_filters  || !filters)
  5913.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  5914.  
  5915.     for (i = 0; i < i965->codec_info->num_filters; i++) {
  5916.         if (i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring)) {
  5917.             if (num == *num_filters) {
  5918.                 *num_filters = i965->codec_info->num_filters;
  5919.  
  5920.                 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
  5921.             }
  5922.  
  5923.             filters[num++] = i965->codec_info->filters[i].type;
  5924.         }
  5925.     }
  5926.  
  5927.     *num_filters = num;
  5928.  
  5929.     return VA_STATUS_SUCCESS;
  5930. }
  5931.  
  5932. VAStatus i965_QueryVideoProcFilterCaps(
  5933.     VADriverContextP    ctx,
  5934.     VAContextID         context,
  5935.     VAProcFilterType    type,
  5936.     void               *filter_caps,
  5937.     unsigned int       *num_filter_caps
  5938.     )
  5939. {
  5940.     unsigned int i = 0;
  5941.     struct i965_driver_data *const i965 = i965_driver_data(ctx);
  5942.  
  5943.     if (!filter_caps || !num_filter_caps)
  5944.         return VA_STATUS_ERROR_INVALID_PARAMETER;
  5945.  
  5946.     for (i = 0; i < i965->codec_info->num_filters; i++) {
  5947.         if (type == i965->codec_info->filters[i].type &&
  5948.             i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring))
  5949.             break;
  5950.     }
  5951.  
  5952.     if (i == i965->codec_info->num_filters)
  5953.         return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
  5954.  
  5955.     i = 0;
  5956.  
  5957.     switch (type) {
  5958.     case VAProcFilterNoiseReduction:
  5959.     case VAProcFilterSharpening:
  5960.         {
  5961.             VAProcFilterCap *cap = filter_caps;
  5962.  
  5963.             if (*num_filter_caps < 1) {
  5964.                 *num_filter_caps = 1;
  5965.                 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
  5966.             }
  5967.  
  5968.             cap->range.min_value = 0.0;
  5969.             cap->range.max_value = 1.0;
  5970.             cap->range.default_value = 0.5;
  5971.             cap->range.step = 0.03125; /* 1.0 / 32 */
  5972.             i++;
  5973.         }
  5974.  
  5975.         break;
  5976.  
  5977.     case VAProcFilterDeinterlacing:
  5978.         {
  5979.             VAProcFilterCapDeinterlacing *cap = filter_caps;
  5980.  
  5981.             if (*num_filter_caps < VAProcDeinterlacingCount) {
  5982.                 *num_filter_caps = VAProcDeinterlacingCount;
  5983.                 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
  5984.             }
  5985.  
  5986.             cap->type = VAProcDeinterlacingBob;
  5987.             i++;
  5988.             cap++;
  5989.  
  5990.  
  5991.             if (i965->codec_info->has_di_motion_adptive) {
  5992.                 cap->type = VAProcDeinterlacingMotionAdaptive;
  5993.                 i++;
  5994.                 cap++;
  5995.             }
  5996.  
  5997.             if (i965->codec_info->has_di_motion_compensated) {
  5998.                 cap->type = VAProcDeinterlacingMotionCompensated;
  5999.                 i++;
  6000.                 cap++;
  6001.             }
  6002.        }
  6003.  
  6004.         break;
  6005.  
  6006.     case VAProcFilterColorBalance:
  6007.         {
  6008.             VAProcFilterCapColorBalance *cap = filter_caps;
  6009.  
  6010.             if (*num_filter_caps < VAProcColorBalanceCount) {
  6011.                 *num_filter_caps = VAProcColorBalanceCount;
  6012.                 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
  6013.             }
  6014.  
  6015.             cap->type = VAProcColorBalanceHue;
  6016.             cap->range.min_value = -180.0;
  6017.             cap->range.max_value = 180.0;
  6018.             cap->range.default_value = 0.0;
  6019.             cap->range.step = 1.0;
  6020.             i++;
  6021.             cap++;
  6022.  
  6023.             cap->type = VAProcColorBalanceSaturation;
  6024.             cap->range.min_value = 0.0;
  6025.             cap->range.max_value = 10.0;
  6026.             cap->range.default_value = 1.0;
  6027.             cap->range.step = 0.1;
  6028.             i++;
  6029.             cap++;
  6030.  
  6031.             cap->type = VAProcColorBalanceBrightness;
  6032.             cap->range.min_value = -100.0;
  6033.             cap->range.max_value = 100.0;
  6034.             cap->range.default_value = 0.0;
  6035.             cap->range.step = 1.0;
  6036.             i++;
  6037.             cap++;
  6038.  
  6039.             cap->type = VAProcColorBalanceContrast;
  6040.             cap->range.min_value = 0.0;
  6041.             cap->range.max_value = 10.0;
  6042.             cap->range.default_value = 1.0;
  6043.             cap->range.step = 0.1;
  6044.             i++;
  6045.             cap++;
  6046.         }
  6047.  
  6048.         break;
  6049.  
  6050.     default:
  6051.  
  6052.         break;
  6053.     }
  6054.  
  6055.     *num_filter_caps = i;
  6056.  
  6057.     return VA_STATUS_SUCCESS;
  6058. }
  6059.  
  6060. static VAProcColorStandardType vpp_input_color_standards[VAProcColorStandardCount] = {
  6061.     VAProcColorStandardBT601,
  6062. };
  6063.  
  6064. static VAProcColorStandardType vpp_output_color_standards[VAProcColorStandardCount] = {
  6065.     VAProcColorStandardBT601,
  6066. };
  6067.  
  6068. VAStatus i965_QueryVideoProcPipelineCaps(
  6069.     VADriverContextP ctx,
  6070.     VAContextID context,
  6071.     VABufferID *filters,
  6072.     unsigned int num_filters,
  6073.     VAProcPipelineCaps *pipeline_cap     /* out */
  6074.     )
  6075. {
  6076.     struct i965_driver_data * const i965 = i965_driver_data(ctx);
  6077.     unsigned int i = 0;
  6078.  
  6079.     pipeline_cap->pipeline_flags = 0;
  6080.     pipeline_cap->filter_flags = 0;
  6081.     pipeline_cap->num_forward_references = 0;
  6082.     pipeline_cap->num_backward_references = 0;
  6083.     pipeline_cap->num_input_color_standards = 1;
  6084.     pipeline_cap->input_color_standards = vpp_input_color_standards;
  6085.     pipeline_cap->num_output_color_standards = 1;
  6086.     pipeline_cap->output_color_standards = vpp_output_color_standards;
  6087.  
  6088.     for (i = 0; i < num_filters; i++) {
  6089.         struct object_buffer *obj_buffer = BUFFER(filters[i]);
  6090.  
  6091.         if (!obj_buffer ||
  6092.             !obj_buffer->buffer_store ||
  6093.             !obj_buffer->buffer_store->buffer)
  6094.             return VA_STATUS_ERROR_INVALID_BUFFER;
  6095.  
  6096.         VAProcFilterParameterBufferBase *base = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
  6097.  
  6098.         if (base->type == VAProcFilterNoiseReduction) {
  6099.             VAProcFilterParameterBuffer *denoise = (VAProcFilterParameterBuffer *)base;
  6100.             (void)denoise;
  6101.         } else if (base->type == VAProcFilterDeinterlacing) {
  6102.             VAProcFilterParameterBufferDeinterlacing *deint = (VAProcFilterParameterBufferDeinterlacing *)base;
  6103.  
  6104.             ASSERT_RET(deint->algorithm == VAProcDeinterlacingBob ||
  6105.                    deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
  6106.                    deint->algorithm == VAProcDeinterlacingMotionCompensated,
  6107.                    VA_STATUS_ERROR_INVALID_PARAMETER);
  6108.  
  6109.             if (deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
  6110.                 deint->algorithm == VAProcDeinterlacingMotionCompensated)
  6111.                 pipeline_cap->num_forward_references++;
  6112.         } else if (base->type == VAProcFilterSkinToneEnhancement) {
  6113.                 VAProcFilterParameterBuffer *stde = (VAProcFilterParameterBuffer *)base;
  6114.                 (void)stde;
  6115.         }
  6116.     }
  6117.  
  6118.     return VA_STATUS_SUCCESS;
  6119. }
  6120.  
  6121. extern struct hw_codec_info *i965_get_codec_info(int devid);
  6122.  
  6123. static bool
  6124. i965_driver_data_init(VADriverContextP ctx)
  6125. {
  6126.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  6127.  
  6128.     i965->codec_info = i965_get_codec_info(i965->intel.device_id);
  6129.  
  6130.     if (!i965->codec_info)
  6131.         return false;
  6132.  
  6133.     if (object_heap_init(&i965->config_heap,
  6134.                          sizeof(struct object_config),
  6135.                          CONFIG_ID_OFFSET))
  6136.         goto err_config_heap;
  6137.     if (object_heap_init(&i965->context_heap,
  6138.                          sizeof(struct object_context),
  6139.                          CONTEXT_ID_OFFSET))
  6140.         goto err_context_heap;
  6141.  
  6142.     if (object_heap_init(&i965->surface_heap,
  6143.                          sizeof(struct object_surface),
  6144.                          SURFACE_ID_OFFSET))
  6145.         goto err_surface_heap;
  6146.     if (object_heap_init(&i965->buffer_heap,
  6147.                          sizeof(struct object_buffer),
  6148.                          BUFFER_ID_OFFSET))
  6149.         goto err_buffer_heap;
  6150.     if (object_heap_init(&i965->image_heap,
  6151.                          sizeof(struct object_image),
  6152.                          IMAGE_ID_OFFSET))
  6153.         goto err_image_heap;
  6154.     if (object_heap_init(&i965->subpic_heap,
  6155.                          sizeof(struct object_subpic),
  6156.                          SUBPIC_ID_OFFSET))
  6157.         goto err_subpic_heap;
  6158.  
  6159.     i965->batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
  6160.     i965->pp_batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
  6161.     _i965InitMutex(&i965->render_mutex);
  6162.     _i965InitMutex(&i965->pp_mutex);
  6163.  
  6164.     return true;
  6165.  
  6166. err_subpic_heap:
  6167.     object_heap_destroy(&i965->image_heap);
  6168. err_image_heap:
  6169.     object_heap_destroy(&i965->buffer_heap);
  6170. err_buffer_heap:
  6171.     object_heap_destroy(&i965->surface_heap);
  6172. err_surface_heap:
  6173.     object_heap_destroy(&i965->context_heap);
  6174. err_context_heap:
  6175.     object_heap_destroy(&i965->config_heap);
  6176. err_config_heap:
  6177.  
  6178.     return false;
  6179. }
  6180.  
  6181. static void
  6182. i965_driver_data_terminate(VADriverContextP ctx)
  6183. {
  6184.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  6185.  
  6186.     _i965DestroyMutex(&i965->pp_mutex);
  6187.     _i965DestroyMutex(&i965->render_mutex);
  6188.  
  6189.     if (i965->batch)
  6190.         intel_batchbuffer_free(i965->batch);
  6191.  
  6192.     if (i965->pp_batch)
  6193.         intel_batchbuffer_free(i965->pp_batch);
  6194.  
  6195.     i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
  6196.     i965_destroy_heap(&i965->image_heap, i965_destroy_image);
  6197.     i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
  6198.     i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
  6199.     i965_destroy_heap(&i965->context_heap, i965_destroy_context);
  6200.     i965_destroy_heap(&i965->config_heap, i965_destroy_config);
  6201. }
  6202.  
  6203. struct {
  6204.     bool (*init)(VADriverContextP ctx);
  6205.     void (*terminate)(VADriverContextP ctx);
  6206.     int display_type;
  6207. } i965_sub_ops[] =  {
  6208.     {
  6209.         intel_driver_init,
  6210.         intel_driver_terminate,
  6211.         0,
  6212.     },
  6213.  
  6214.     {
  6215.         i965_driver_data_init,
  6216.         i965_driver_data_terminate,
  6217.         0,
  6218.     },
  6219.  
  6220.     {
  6221.         i965_display_attributes_init,
  6222.         i965_display_attributes_terminate,
  6223.         0,
  6224.     },
  6225.  
  6226.     {
  6227.         i965_post_processing_init,
  6228.         i965_post_processing_terminate,
  6229.         0,
  6230.     },
  6231.  
  6232.     {
  6233.         i965_render_init,
  6234.         i965_render_terminate,
  6235.         0,
  6236.     },
  6237.  
  6238. #ifdef HAVE_VA_WAYLAND
  6239.     {
  6240.         i965_output_wayland_init,
  6241.         i965_output_wayland_terminate,
  6242.         VA_DISPLAY_WAYLAND,
  6243.     },
  6244. #endif
  6245.  
  6246. #ifdef HAVE_VA_X11
  6247.     {
  6248.         i965_output_dri_init,
  6249.         i965_output_dri_terminate,
  6250.         VA_DISPLAY_X11,
  6251.     },
  6252. #endif
  6253. };
  6254.  
  6255. static bool
  6256. ensure_vendor_string(struct i965_driver_data *i965, const char *chipset)
  6257. {
  6258.     int ret, len;
  6259.  
  6260.     if (i965->va_vendor[0] != '\0')
  6261.         return true;
  6262.  
  6263.     len = 0;
  6264.     ret = snprintf(i965->va_vendor, sizeof(i965->va_vendor),
  6265.         "%s %s driver for %s - %d.%d.%d",
  6266.         INTEL_STR_DRIVER_VENDOR, INTEL_STR_DRIVER_NAME, chipset,
  6267.         INTEL_DRIVER_MAJOR_VERSION, INTEL_DRIVER_MINOR_VERSION,
  6268.         INTEL_DRIVER_MICRO_VERSION);
  6269.     if (ret < 0 || ret >= sizeof(i965->va_vendor))
  6270.         goto error;
  6271.     len = ret;
  6272.  
  6273.     if (INTEL_DRIVER_PRE_VERSION > 0) {
  6274.         ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
  6275.             ".pre%d", INTEL_DRIVER_PRE_VERSION);
  6276.         if (ret < 0 || ret >= sizeof(i965->va_vendor))
  6277.             goto error;
  6278.         len += ret;
  6279.  
  6280.         ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
  6281.             " (%s)", INTEL_DRIVER_GIT_VERSION);
  6282.         if (ret < 0 || ret >= sizeof(i965->va_vendor))
  6283.             goto error;
  6284.         len += ret;
  6285.     }
  6286.     return true;
  6287.  
  6288. error:
  6289.     i965->va_vendor[0] = '\0';
  6290.     ASSERT_RET(ret > 0 && len < sizeof(i965->va_vendor), false);
  6291.     return false;
  6292. }
  6293.  
  6294. /* Only when the option of "enable-wrapper" is passed, it is possible
  6295.  * to initialize/load the wrapper context of backend driver.
  6296.  * Otherwise it is not loaded.
  6297.  */
  6298. #if HAVE_HYBRID_CODEC
  6299.  
  6300. static VAStatus
  6301. i965_initialize_wrapper(VADriverContextP ctx, const char *driver_name)
  6302. {
  6303. #define DRIVER_EXTENSION        "_drv_video.so"
  6304.  
  6305.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  6306.  
  6307.     VADriverContextP wrapper_pdrvctx;
  6308.     struct VADriverVTable *vtable;
  6309.     char *search_path, *driver_dir;
  6310.     char *saveptr;
  6311.     char driver_path[256];
  6312.     void *handle = NULL;
  6313.     VAStatus va_status = VA_STATUS_SUCCESS;
  6314.     bool driver_loaded = false;
  6315.  
  6316.     wrapper_pdrvctx = calloc(1, sizeof(*wrapper_pdrvctx));
  6317.     vtable = calloc(1, sizeof(*vtable));
  6318.  
  6319.     if (!wrapper_pdrvctx || !vtable) {
  6320.         fprintf(stderr, "Failed to allocate memory for wrapper \n");
  6321.         free(wrapper_pdrvctx);
  6322.         free(vtable);
  6323.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  6324.     }
  6325.  
  6326.     /* use the same drm_state with CTX */
  6327.     wrapper_pdrvctx->drm_state = ctx->drm_state;
  6328.     wrapper_pdrvctx->display_type = ctx->display_type;
  6329.     wrapper_pdrvctx->vtable = vtable;
  6330.  
  6331.     search_path = VA_DRIVERS_PATH;
  6332.     search_path = strdup((const char *)search_path);
  6333.  
  6334.     driver_dir = strtok_r(search_path, ":", &saveptr);
  6335.     while (driver_dir && !driver_loaded) {
  6336.         memset(driver_path, 0, sizeof(driver_path));
  6337.         sprintf(driver_path, "%s/%s%s", driver_dir, driver_name, DRIVER_EXTENSION);
  6338.  
  6339.         handle = dlopen(driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
  6340.         if (!handle) {
  6341.             fprintf(stderr, "failed to open %s\n", driver_path);
  6342.             driver_dir = strtok_r(NULL, ":", &saveptr);
  6343.             continue;
  6344.         }
  6345.         {
  6346.             VADriverInit init_func = NULL;
  6347.             char init_func_s[256];
  6348.             int i;
  6349.  
  6350.             static const struct {
  6351.                 int major;
  6352.                 int minor;
  6353.             } compatible_versions[] = {
  6354.                 { VA_MAJOR_VERSION, VA_MINOR_VERSION },
  6355.                 { 0, 37 },
  6356.                 { 0, 36 },
  6357.                 { 0, 35 },
  6358.                 { 0, 34 },
  6359.                 { 0, 33 },
  6360.                 { 0, 32 },
  6361.                 { -1, }
  6362.             };
  6363.             for (i = 0; compatible_versions[i].major >= 0; i++) {
  6364.                 snprintf(init_func_s, sizeof(init_func_s),
  6365.                      "__vaDriverInit_%d_%d",
  6366.                      compatible_versions[i].major,
  6367.                      compatible_versions[i].minor);
  6368.                 init_func = (VADriverInit)dlsym(handle, init_func_s);
  6369.                 if (init_func) {
  6370.                     break;
  6371.                 }
  6372.             }
  6373.             if (compatible_versions[i].major < 0) {
  6374.                 dlclose(handle);
  6375.                 fprintf(stderr, "%s has no function %s\n",
  6376.                             driver_path, init_func_s);
  6377.                 driver_dir = strtok_r(NULL, ":", &saveptr);
  6378.                 continue;
  6379.             }
  6380.  
  6381.             if (init_func)
  6382.                 va_status = (*init_func)(wrapper_pdrvctx);
  6383.  
  6384.             if (va_status != VA_STATUS_SUCCESS) {
  6385.                 dlclose(handle);
  6386.                 fprintf(stderr, "%s init failed\n", driver_path);
  6387.                 driver_dir = strtok_r(NULL, ":", &saveptr);
  6388.                 continue;
  6389.             }
  6390.  
  6391.             wrapper_pdrvctx->handle = handle;
  6392.             driver_loaded = true;
  6393.         }
  6394.     }
  6395.  
  6396.     free(search_path);
  6397.  
  6398.     if (driver_loaded) {
  6399.         i965->wrapper_pdrvctx = wrapper_pdrvctx;
  6400.         return VA_STATUS_SUCCESS;
  6401.     } else {
  6402.         fprintf(stderr, "Failed to wrapper %s%s\n", driver_name, DRIVER_EXTENSION);
  6403.         free(vtable);
  6404.         free(wrapper_pdrvctx);
  6405.         return VA_STATUS_ERROR_OPERATION_FAILED;
  6406.     }
  6407. }
  6408. #endif
  6409.  
  6410. static VAStatus
  6411. i965_Init(VADriverContextP ctx)
  6412. {
  6413.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  6414.     int i;
  6415.     const char *chipset;
  6416.  
  6417.     for (i = 0; i < ARRAY_ELEMS(i965_sub_ops); i++) {
  6418.         if ((i965_sub_ops[i].display_type == 0 ||
  6419.              i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) &&
  6420.             !i965_sub_ops[i].init(ctx))
  6421.             break;
  6422.     }
  6423.  
  6424.     if (i == ARRAY_ELEMS(i965_sub_ops)) {
  6425.         switch (i965->intel.device_id) {
  6426. #undef CHIPSET
  6427. #define CHIPSET(id, family, dev, str) case id: chipset = str; break;
  6428. #include "i965_pciids.h"
  6429.         default:
  6430.             chipset = "Unknown Intel Chipset";
  6431.             break;
  6432.         }
  6433.  
  6434.         if (!ensure_vendor_string(i965, chipset))
  6435.             return VA_STATUS_ERROR_ALLOCATION_FAILED;
  6436.  
  6437.         i965->current_context_id = VA_INVALID_ID;
  6438.  
  6439.         if (i965->codec_info && i965->codec_info->preinit_hw_codec)
  6440.             i965->codec_info->preinit_hw_codec(ctx, i965->codec_info);
  6441.  
  6442. #if HAVE_HYBRID_CODEC
  6443.         i965_initialize_wrapper(ctx, "hybrid");
  6444. #endif
  6445.  
  6446.         return VA_STATUS_SUCCESS;
  6447.     } else {
  6448.         i--;
  6449.  
  6450.         for (; i >= 0; i--) {
  6451.             if (i965_sub_ops[i].display_type == 0 ||
  6452.                 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
  6453.                 i965_sub_ops[i].terminate(ctx);
  6454.             }
  6455.         }
  6456.  
  6457.         return VA_STATUS_ERROR_UNKNOWN;
  6458.     }
  6459. }
  6460.  
  6461. VAStatus
  6462. i965_Terminate(VADriverContextP ctx)
  6463. {
  6464.     struct i965_driver_data *i965 = i965_driver_data(ctx);
  6465.     int i;
  6466.  
  6467.     if (i965) {
  6468.         if (i965->wrapper_pdrvctx) {
  6469.             VADriverContextP pdrvctx;
  6470.             pdrvctx = i965->wrapper_pdrvctx;
  6471.             if (pdrvctx->handle) {
  6472.                 pdrvctx->vtable->vaTerminate(pdrvctx);
  6473.                 pdrvctx->handle = NULL;
  6474.             }
  6475.             free(pdrvctx->vtable);
  6476.             free(pdrvctx);
  6477.             i965->wrapper_pdrvctx = NULL;
  6478.         }
  6479.  
  6480.         for (i = ARRAY_ELEMS(i965_sub_ops); i > 0; i--)
  6481.             if (i965_sub_ops[i - 1].display_type == 0 ||
  6482.                 i965_sub_ops[i - 1].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
  6483.                 i965_sub_ops[i - 1].terminate(ctx);
  6484.             }
  6485.  
  6486.         free(i965);
  6487.         ctx->pDriverData = NULL;
  6488.     }
  6489.  
  6490.     return VA_STATUS_SUCCESS;
  6491. }
  6492.  
  6493. VAStatus DLL_EXPORT
  6494. VA_DRIVER_INIT_FUNC(VADriverContextP ctx);
  6495.  
  6496. VAStatus
  6497. VA_DRIVER_INIT_FUNC(  VADriverContextP ctx )
  6498. {
  6499.     struct VADriverVTable * const vtable = ctx->vtable;
  6500.     struct VADriverVTableVPP * const vtable_vpp = ctx->vtable_vpp;
  6501.  
  6502.     struct i965_driver_data *i965;
  6503.     VAStatus ret = VA_STATUS_ERROR_UNKNOWN;
  6504.  
  6505.     ctx->version_major = VA_MAJOR_VERSION;
  6506.     ctx->version_minor = VA_MINOR_VERSION;
  6507.     ctx->max_profiles = I965_MAX_PROFILES;
  6508.     ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
  6509.     ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
  6510.     ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
  6511.     ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
  6512.     ctx->max_display_attributes = 1 + ARRAY_ELEMS(i965_display_attributes);
  6513.  
  6514.     vtable->vaTerminate = i965_Terminate;
  6515.     vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
  6516.     vtable->vaQueryConfigProfiles = i965_QueryConfigProfiles;
  6517.     vtable->vaQueryConfigAttributes = i965_QueryConfigAttributes;
  6518.     vtable->vaCreateConfig = i965_CreateConfig;
  6519.     vtable->vaDestroyConfig = i965_DestroyConfig;
  6520.     vtable->vaGetConfigAttributes = i965_GetConfigAttributes;
  6521.     vtable->vaCreateSurfaces = i965_CreateSurfaces;
  6522.     vtable->vaDestroySurfaces = i965_DestroySurfaces;
  6523.     vtable->vaCreateContext = i965_CreateContext;
  6524.     vtable->vaDestroyContext = i965_DestroyContext;
  6525.     vtable->vaCreateBuffer = i965_CreateBuffer;
  6526.     vtable->vaBufferSetNumElements = i965_BufferSetNumElements;
  6527.     vtable->vaMapBuffer = i965_MapBuffer;
  6528.     vtable->vaUnmapBuffer = i965_UnmapBuffer;
  6529.     vtable->vaDestroyBuffer = i965_DestroyBuffer;
  6530.     vtable->vaBeginPicture = i965_BeginPicture;
  6531.     vtable->vaRenderPicture = i965_RenderPicture;
  6532.     vtable->vaEndPicture = i965_EndPicture;
  6533.     vtable->vaSyncSurface = i965_SyncSurface;
  6534.     vtable->vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
  6535.     vtable->vaPutSurface = i965_PutSurface;
  6536.     vtable->vaQueryImageFormats = i965_QueryImageFormats;
  6537.     vtable->vaCreateImage = i965_CreateImage;
  6538.     vtable->vaDeriveImage = i965_DeriveImage;
  6539.     vtable->vaDestroyImage = i965_DestroyImage;
  6540.     vtable->vaSetImagePalette = i965_SetImagePalette;
  6541.     vtable->vaGetImage = i965_GetImage;
  6542.     vtable->vaPutImage = i965_PutImage;
  6543.     vtable->vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
  6544.     vtable->vaCreateSubpicture = i965_CreateSubpicture;
  6545.     vtable->vaDestroySubpicture = i965_DestroySubpicture;
  6546.     vtable->vaSetSubpictureImage = i965_SetSubpictureImage;
  6547.     vtable->vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
  6548.     vtable->vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
  6549.     vtable->vaAssociateSubpicture = i965_AssociateSubpicture;
  6550.     vtable->vaDeassociateSubpicture = i965_DeassociateSubpicture;
  6551.     vtable->vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
  6552.     vtable->vaGetDisplayAttributes = i965_GetDisplayAttributes;
  6553.     vtable->vaSetDisplayAttributes = i965_SetDisplayAttributes;
  6554.     vtable->vaBufferInfo = i965_BufferInfo;
  6555.     vtable->vaLockSurface = i965_LockSurface;
  6556.     vtable->vaUnlockSurface = i965_UnlockSurface;
  6557.     vtable->vaGetSurfaceAttributes = i965_GetSurfaceAttributes;
  6558.     vtable->vaQuerySurfaceAttributes = i965_QuerySurfaceAttributes;
  6559.     vtable->vaCreateSurfaces2 = i965_CreateSurfaces2;
  6560.  
  6561.     /* 0.36.0 */
  6562.     vtable->vaAcquireBufferHandle = i965_AcquireBufferHandle;
  6563.     vtable->vaReleaseBufferHandle = i965_ReleaseBufferHandle;
  6564.  
  6565.     vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters;
  6566.     vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps;
  6567.     vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;
  6568.  
  6569.     i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
  6570.  
  6571.     if (i965 == NULL) {
  6572.         ctx->pDriverData = NULL;
  6573.  
  6574.         return VA_STATUS_ERROR_ALLOCATION_FAILED;
  6575.     }
  6576.  
  6577.     i965->wrapper_pdrvctx = NULL;
  6578.     ctx->pDriverData = (void *)i965;
  6579.     ret = i965_Init(ctx);
  6580.  
  6581.     if (ret == VA_STATUS_SUCCESS) {
  6582.         ctx->str_vendor = i965->va_vendor;
  6583.     } else {
  6584.         free(i965);
  6585.         ctx->pDriverData = NULL;
  6586.     }
  6587.  
  6588.     return ret;
  6589. }
  6590.