Subversion Repositories Kolibri OS

Rev

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