2 * Copyright ?2009 Intel Corporation
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
25 * Xiang Haihao <haihao.xiang@intel.com>
26 * Zou Nan hai <nanhai.zou@intel.com>
34 # include "i965_output_dri.h"
37 #ifdef HAVE_VA_WAYLAND
38 # include "i965_output_wayland.h"
41 #include "intel_version.h"
42 #include "intel_driver.h"
43 #include "intel_memman.h"
44 #include "intel_batchbuffer.h"
45 #include "i965_defines.h"
46 #include "i965_drv_video.h"
47 #include "i965_decoder.h"
48 #include "i965_encoder.h"
50 #define CONFIG_ID_OFFSET 0x01000000
51 #define CONTEXT_ID_OFFSET 0x02000000
52 #define SURFACE_ID_OFFSET 0x04000000
53 #define BUFFER_ID_OFFSET 0x08000000
54 #define IMAGE_ID_OFFSET 0x0a000000
55 #define SUBPIC_ID_OFFSET 0x10000000
57 #define HAS_MPEG2_DECODING(ctx) ((ctx)->codec_info->has_mpeg2_decoding && \
60 #define HAS_MPEG2_ENCODING(ctx) ((ctx)->codec_info->has_mpeg2_encoding && \
63 #define HAS_H264_DECODING(ctx) ((ctx)->codec_info->has_h264_decoding && \
66 #define HAS_H264_ENCODING(ctx) ((ctx)->codec_info->has_h264_encoding && \
69 #define HAS_VC1_DECODING(ctx) ((ctx)->codec_info->has_vc1_decoding && \
72 #define HAS_JPEG_DECODING(ctx) ((ctx)->codec_info->has_jpeg_decoding && \
75 #define HAS_JPEG_ENCODING(ctx) ((ctx)->codec_info->has_jpeg_encoding && \
78 #define HAS_VPP(ctx) ((ctx)->codec_info->has_vpp)
80 #define HAS_ACCELERATED_GETIMAGE(ctx) ((ctx)->codec_info->has_accelerated_getimage)
82 #define HAS_ACCELERATED_PUTIMAGE(ctx) ((ctx)->codec_info->has_accelerated_putimage)
84 #define HAS_TILED_SURFACE(ctx) ((ctx)->codec_info->has_tiled_surface)
86 #define HAS_VP8_DECODING(ctx) ((ctx)->codec_info->has_vp8_decoding && \
89 #define HAS_VP8_ENCODING(ctx) ((ctx)->codec_info->has_vp8_encoding && \
92 #define HAS_H264_MVC_DECODING(ctx) \
93 (HAS_H264_DECODING(ctx) && (ctx)->codec_info->h264_mvc_dec_profiles)
95 #define HAS_H264_MVC_DECODING_PROFILE(ctx, profile) \
96 (HAS_H264_MVC_DECODING(ctx) && \
97 ((ctx)->codec_info->h264_mvc_dec_profiles & (1U << profile)))
99 #define HAS_H264_MVC_ENCODING(ctx) ((ctx)->codec_info->has_h264_mvc_encoding && \
100 (ctx)->intel.has_bsd)
102 #define HAS_HEVC_DECODING(ctx) ((ctx)->codec_info->has_hevc_decoding && \
103 (ctx)->intel.has_bsd)
105 #define HAS_HEVC_ENCODING(ctx) ((ctx)->codec_info->has_hevc_encoding && \
106 (ctx)->intel.has_bsd)
108 static int get_sampling_from_fourcc(unsigned int fourcc);
110 /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */
111 #define IS_VA_X11(ctx) \
112 (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_X11)
114 /* Check whether we are rendering to Wayland */
115 #define IS_VA_WAYLAND(ctx) \
116 (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_WAYLAND)
119 #define I965_2BITS (I965_BIT << 1)
120 #define I965_4BITS (I965_BIT << 2)
121 #define I965_8BITS (I965_BIT << 3)
122 #define I965_16BITS (I965_BIT << 4)
123 #define I965_32BITS (I965_BIT << 5)
135 /* hfactor, vfactor, num_planes, bpp[], num_components, components[] */
136 #define I_NV12 2, 2, 2, {I965_8BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_8} }
137 #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} }
138 #define I_IYUV I_I420
139 #define I_IMC3 I_I420
140 #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} }
141 #define I_IMC1 I_YV12
143 #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} }
144 #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} }
145 #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} }
146 #define I_YUY2 2, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_24} }
147 #define I_UYVY 2, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16} }
149 #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} }
151 #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} }
153 #define I_Y800 1, 1, 1, {I965_8BITS}, 1, { {PLANE_0, OFFSET_0} }
155 #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} }
156 #define I_RGBX 1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16} }
157 #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} }
158 #define I_BGRX 1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
160 #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} }
161 #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} }
163 #define I_IA88 1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8} }
164 #define I_AI88 1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
166 #define I_IA44 1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_4} }
167 #define I_AI44 1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_4}, {PLANE_0, OFFSET_0} }
172 #define I_SI (I_S | I_I)
174 #define DEF_FOUCC_INFO(FOURCC, FORMAT, SUB, FLAG) { VA_FOURCC_##FOURCC, I965_COLOR_##FORMAT, SUBSAMPLE_##SUB, FLAG, I_##FOURCC }
175 #define DEF_YUV(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, YUV, SUB, FLAG)
176 #define DEF_RGB(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, RGB, SUB, FLAG)
177 #define DEF_INDEX(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, INDEX, SUB, FLAG)
179 static const i965_fourcc_info i965_fourcc_infos[] = {
180 DEF_YUV(NV12, YUV420, I_SI),
181 DEF_YUV(I420, YUV420, I_SI),
182 DEF_YUV(IYUV, YUV420, I_S),
183 DEF_YUV(IMC3, YUV420, I_S),
184 DEF_YUV(YV12, YUV420, I_SI),
185 DEF_YUV(IMC1, YUV420, I_S),
187 DEF_YUV(422H, YUV422H, I_SI),
188 DEF_YUV(422V, YUV422V, I_S),
189 DEF_YUV(YV16, YUV422H, I_S),
190 DEF_YUV(YUY2, YUV422H, I_SI),
191 DEF_YUV(UYVY, YUV422H, I_SI),
193 DEF_YUV(444P, YUV444, I_S),
195 DEF_YUV(411P, YUV411, I_S),
197 DEF_YUV(Y800, YUV400, I_S),
199 DEF_RGB(RGBA, RGBX, I_SI),
200 DEF_RGB(RGBX, RGBX, I_SI),
201 DEF_RGB(BGRA, RGBX, I_SI),
202 DEF_RGB(BGRX, RGBX, I_SI),
204 DEF_RGB(ARGB, RGBX, I_I),
205 DEF_RGB(ABGR, RGBX, I_I),
207 DEF_INDEX(IA88, RGBX, I_I),
208 DEF_INDEX(AI88, RGBX, I_I),
210 DEF_INDEX(IA44, RGBX, I_I),
211 DEF_INDEX(AI44, RGBX, I_I)
214 const i965_fourcc_info *
215 get_fourcc_info(unsigned int fourcc)
219 for (i = 0; ARRAY_ELEMS(i965_fourcc_infos); i++) {
220 const i965_fourcc_info * const info = &i965_fourcc_infos[i];
222 if (info->fourcc == fourcc)
230 I965_SURFACETYPE_RGBA = 1,
231 I965_SURFACETYPE_YUV,
232 I965_SURFACETYPE_INDEXED
235 /* List of supported display attributes */
236 static const VADisplayAttribute i965_display_attributes[] = {
238 VADisplayAttribBrightness,
239 -100, 100, DEFAULT_BRIGHTNESS,
240 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
244 VADisplayAttribContrast,
245 0, 100, DEFAULT_CONTRAST,
246 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
251 -180, 180, DEFAULT_HUE,
252 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
256 VADisplayAttribSaturation,
257 0, 100, DEFAULT_SATURATION,
258 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
262 VADisplayAttribRotation,
263 0, 3, VA_ROTATION_NONE,
264 VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE
268 /* List of supported image formats */
271 VAImageFormat va_format;
272 } i965_image_format_map_t;
274 static const i965_image_format_map_t
275 i965_image_formats_map[I965_MAX_IMAGE_FORMATS + 1] = {
276 { I965_SURFACETYPE_YUV,
277 { VA_FOURCC_YV12, VA_LSB_FIRST, 12, } },
278 { I965_SURFACETYPE_YUV,
279 { VA_FOURCC_I420, VA_LSB_FIRST, 12, } },
280 { I965_SURFACETYPE_YUV,
281 { VA_FOURCC_NV12, VA_LSB_FIRST, 12, } },
282 { I965_SURFACETYPE_YUV,
283 { VA_FOURCC_YUY2, VA_LSB_FIRST, 16, } },
284 { I965_SURFACETYPE_YUV,
285 { VA_FOURCC_UYVY, VA_LSB_FIRST, 16, } },
286 { I965_SURFACETYPE_YUV,
287 { VA_FOURCC_422H, VA_LSB_FIRST, 16, } },
288 { I965_SURFACETYPE_RGBA,
289 { VA_FOURCC_RGBX, VA_LSB_FIRST, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000 } },
290 { I965_SURFACETYPE_RGBA,
291 { VA_FOURCC_BGRX, VA_LSB_FIRST, 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff } },
294 /* List of supported subpicture formats */
298 VAImageFormat va_format;
299 unsigned int va_flags;
300 } i965_subpic_format_map_t;
302 #define COMMON_SUBPICTURE_FLAGS \
303 (VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD| \
304 VA_SUBPICTURE_GLOBAL_ALPHA)
306 static const i965_subpic_format_map_t
307 i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
308 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
309 { VA_FOURCC_IA44, VA_MSB_FIRST, 8, },
310 COMMON_SUBPICTURE_FLAGS },
311 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
312 { VA_FOURCC_AI44, VA_MSB_FIRST, 8, },
313 COMMON_SUBPICTURE_FLAGS },
314 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P8A8_UNORM,
315 { VA_FOURCC_IA88, VA_MSB_FIRST, 16, },
316 COMMON_SUBPICTURE_FLAGS },
317 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A8P8_UNORM,
318 { VA_FOURCC_AI88, VA_MSB_FIRST, 16, },
319 COMMON_SUBPICTURE_FLAGS },
320 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_B8G8R8A8_UNORM,
321 { VA_FOURCC_BGRA, VA_LSB_FIRST, 32,
322 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
323 COMMON_SUBPICTURE_FLAGS },
324 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_R8G8B8A8_UNORM,
325 { VA_FOURCC_RGBA, VA_LSB_FIRST, 32,
326 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
327 COMMON_SUBPICTURE_FLAGS },
330 static const i965_subpic_format_map_t *
331 get_subpic_format(const VAImageFormat *va_format)
334 for (i = 0; i965_subpic_formats_map[i].type != 0; i++) {
335 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
336 if (m->va_format.fourcc == va_format->fourcc &&
337 (m->type == I965_SURFACETYPE_RGBA ?
338 (m->va_format.byte_order == va_format->byte_order &&
339 m->va_format.red_mask == va_format->red_mask &&
340 m->va_format.green_mask == va_format->green_mask &&
341 m->va_format.blue_mask == va_format->blue_mask &&
342 m->va_format.alpha_mask == va_format->alpha_mask) : 1))
348 /* Checks whether the surface is in busy state */
350 is_surface_busy(struct i965_driver_data *i965,
351 struct object_surface *obj_surface)
353 assert(obj_surface != NULL);
355 if (obj_surface->locked_image_id != VA_INVALID_ID)
357 if (obj_surface->derived_image_id != VA_INVALID_ID)
362 /* Checks whether the image is in busy state */
364 is_image_busy(struct i965_driver_data *i965, struct object_image *obj_image, VASurfaceID surface)
366 struct object_buffer *obj_buffer;
368 assert(obj_image != NULL);
370 if (obj_image->derived_surface != VA_INVALID_ID &&
371 obj_image->derived_surface == surface)
374 obj_buffer = BUFFER(obj_image->image.buf);
375 if (obj_buffer && obj_buffer->export_refcount > 0)
380 #define I965_PACKED_HEADER_BASE 0
381 #define I965_SEQ_PACKED_HEADER_BASE 0
382 #define I965_SEQ_PACKED_HEADER_END 2
383 #define I965_PIC_PACKED_HEADER_BASE 2
384 #define I965_PACKED_MISC_HEADER_BASE 4
387 va_enc_packed_type_to_idx(int packed_type)
391 if (packed_type & VAEncPackedHeaderMiscMask) {
392 idx = I965_PACKED_MISC_HEADER_BASE;
393 packed_type = (~VAEncPackedHeaderMiscMask & packed_type);
394 ASSERT_RET(packed_type > 0, 0);
395 idx += (packed_type - 1);
397 idx = I965_PACKED_HEADER_BASE;
399 switch (packed_type) {
400 case VAEncPackedHeaderSequence:
401 idx = I965_SEQ_PACKED_HEADER_BASE + 0;
404 case VAEncPackedHeaderPicture:
405 idx = I965_PIC_PACKED_HEADER_BASE + 0;
408 case VAEncPackedHeaderSlice:
409 idx = I965_PIC_PACKED_HEADER_BASE + 1;
413 /* Should not get here */
419 ASSERT_RET(idx < 5, 0);
424 i965_QueryConfigProfiles(VADriverContextP ctx,
425 VAProfile *profile_list, /* out */
426 int *num_profiles) /* out */
428 struct i965_driver_data * const i965 = i965_driver_data(ctx);
431 if (HAS_MPEG2_DECODING(i965) ||
432 HAS_MPEG2_ENCODING(i965)) {
433 profile_list[i++] = VAProfileMPEG2Simple;
434 profile_list[i++] = VAProfileMPEG2Main;
437 if (HAS_H264_DECODING(i965) ||
438 HAS_H264_ENCODING(i965)) {
439 profile_list[i++] = VAProfileH264ConstrainedBaseline;
440 profile_list[i++] = VAProfileH264Main;
441 profile_list[i++] = VAProfileH264High;
443 if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264MultiviewHigh))
444 profile_list[i++] = VAProfileH264MultiviewHigh;
445 if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264StereoHigh))
446 profile_list[i++] = VAProfileH264StereoHigh;
448 if (HAS_VC1_DECODING(i965)) {
449 profile_list[i++] = VAProfileVC1Simple;
450 profile_list[i++] = VAProfileVC1Main;
451 profile_list[i++] = VAProfileVC1Advanced;
455 profile_list[i++] = VAProfileNone;
458 if (HAS_JPEG_DECODING(i965) ||
459 HAS_JPEG_ENCODING(i965)) {
460 profile_list[i++] = VAProfileJPEGBaseline;
463 if (HAS_VP8_DECODING(i965) ||
464 HAS_VP8_ENCODING(i965)) {
465 profile_list[i++] = VAProfileVP8Version0_3;
468 if (HAS_H264_MVC_ENCODING(i965)) {
469 profile_list[i++] = VAProfileH264MultiviewHigh;
470 profile_list[i++] = VAProfileH264StereoHigh;
473 if (HAS_HEVC_DECODING(i965)||
474 HAS_HEVC_ENCODING(i965)) {
475 profile_list[i++] = VAProfileHEVCMain;
478 /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
479 ASSERT_RET(i <= I965_MAX_PROFILES, VA_STATUS_ERROR_OPERATION_FAILED);
482 return VA_STATUS_SUCCESS;
486 i965_QueryConfigEntrypoints(VADriverContextP ctx,
488 VAEntrypoint *entrypoint_list, /* out */
489 int *num_entrypoints) /* out */
491 struct i965_driver_data * const i965 = i965_driver_data(ctx);
495 case VAProfileMPEG2Simple:
496 case VAProfileMPEG2Main:
497 if (HAS_MPEG2_DECODING(i965))
498 entrypoint_list[n++] = VAEntrypointVLD;
500 if (HAS_MPEG2_ENCODING(i965))
501 entrypoint_list[n++] = VAEntrypointEncSlice;
505 case VAProfileH264ConstrainedBaseline:
506 case VAProfileH264Main:
507 case VAProfileH264High:
508 if (HAS_H264_DECODING(i965))
509 entrypoint_list[n++] = VAEntrypointVLD;
511 if (HAS_H264_ENCODING(i965))
512 entrypoint_list[n++] = VAEntrypointEncSlice;
515 case VAProfileH264MultiviewHigh:
516 case VAProfileH264StereoHigh:
517 if (HAS_H264_MVC_DECODING_PROFILE(i965, profile))
518 entrypoint_list[n++] = VAEntrypointVLD;
520 if (HAS_H264_MVC_ENCODING(i965))
521 entrypoint_list[n++] = VAEntrypointEncSlice;
524 case VAProfileVC1Simple:
525 case VAProfileVC1Main:
526 case VAProfileVC1Advanced:
527 if (HAS_VC1_DECODING(i965))
528 entrypoint_list[n++] = VAEntrypointVLD;
533 entrypoint_list[n++] = VAEntrypointVideoProc;
536 case VAProfileJPEGBaseline:
537 if (HAS_JPEG_DECODING(i965))
538 entrypoint_list[n++] = VAEntrypointVLD;
540 if (HAS_JPEG_ENCODING(i965))
541 entrypoint_list[n++] = VAEntrypointEncPicture;
544 case VAProfileVP8Version0_3:
545 if (HAS_VP8_DECODING(i965))
546 entrypoint_list[n++] = VAEntrypointVLD;
548 if (HAS_VP8_ENCODING(i965))
549 entrypoint_list[n++] = VAEntrypointEncSlice;
553 case VAProfileHEVCMain:
554 if (HAS_HEVC_DECODING(i965))
555 entrypoint_list[n++] = VAEntrypointVLD;
557 if (HAS_HEVC_ENCODING(i965))
558 entrypoint_list[n++] = VAEntrypointEncSlice;
566 /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
567 ASSERT_RET(n <= I965_MAX_ENTRYPOINTS, VA_STATUS_ERROR_OPERATION_FAILED);
568 *num_entrypoints = n;
569 return n > 0 ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
573 i965_validate_config(VADriverContextP ctx, VAProfile profile,
574 VAEntrypoint entrypoint)
576 struct i965_driver_data * const i965 = i965_driver_data(ctx);
579 /* Validate profile & entrypoint */
581 case VAProfileMPEG2Simple:
582 case VAProfileMPEG2Main:
583 if ((HAS_MPEG2_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
584 (HAS_MPEG2_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
585 va_status = VA_STATUS_SUCCESS;
587 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
591 case VAProfileH264ConstrainedBaseline:
592 case VAProfileH264Main:
593 case VAProfileH264High:
594 if ((HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
595 (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
596 va_status = VA_STATUS_SUCCESS;
598 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
602 case VAProfileVC1Simple:
603 case VAProfileVC1Main:
604 case VAProfileVC1Advanced:
605 if (HAS_VC1_DECODING(i965) && entrypoint == VAEntrypointVLD) {
606 va_status = VA_STATUS_SUCCESS;
608 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
613 if (HAS_VPP(i965) && VAEntrypointVideoProc == entrypoint) {
614 va_status = VA_STATUS_SUCCESS;
616 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
620 case VAProfileJPEGBaseline:
621 if ((HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
622 (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)) {
623 va_status = VA_STATUS_SUCCESS;
625 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
629 case VAProfileVP8Version0_3:
630 if ((HAS_VP8_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
631 (HAS_VP8_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
632 va_status = VA_STATUS_SUCCESS;
634 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
638 case VAProfileH264MultiviewHigh:
639 case VAProfileH264StereoHigh:
640 if ((HAS_H264_MVC_DECODING_PROFILE(i965, profile) &&
641 entrypoint == VAEntrypointVLD) ||
642 (HAS_H264_MVC_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
643 va_status = VA_STATUS_SUCCESS;
645 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
650 case VAProfileHEVCMain:
651 if ((HAS_HEVC_DECODING(i965) && (entrypoint == VAEntrypointVLD))||
652 (HAS_HEVC_ENCODING(i965) && (entrypoint == VAEntrypointEncSlice)))
653 va_status = VA_STATUS_SUCCESS;
655 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
660 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
667 i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
668 VAEntrypoint entrypoint)
670 struct i965_driver_data * const i965 = i965_driver_data(ctx);
671 uint32_t chroma_formats = VA_RT_FORMAT_YUV420;
674 case VAProfileH264ConstrainedBaseline:
675 case VAProfileH264Main:
676 case VAProfileH264High:
677 if (HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD)
678 chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
681 case VAProfileH264MultiviewHigh:
682 case VAProfileH264StereoHigh:
683 if (HAS_H264_MVC_DECODING(i965) && entrypoint == VAEntrypointVLD)
684 chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
687 case VAProfileJPEGBaseline:
688 if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD)
689 chroma_formats |= i965->codec_info->jpeg_dec_chroma_formats;
690 if (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)
691 chroma_formats |= i965->codec_info->jpeg_enc_chroma_formats;
698 return chroma_formats;
702 i965_GetConfigAttributes(VADriverContextP ctx,
704 VAEntrypoint entrypoint,
705 VAConfigAttrib *attrib_list, /* in/out */
709 struct i965_driver_data *i965 = i965_driver_data(ctx);
712 va_status = i965_validate_config(ctx, profile, entrypoint);
713 if (va_status != VA_STATUS_SUCCESS)
716 /* Other attributes don't seem to be defined */
717 /* What to do if we don't know the attribute? */
718 for (i = 0; i < num_attribs; i++) {
719 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
720 switch (attrib_list[i].type) {
721 case VAConfigAttribRTFormat:
722 attrib_list[i].value = i965_get_default_chroma_formats(ctx,
723 profile, entrypoint);
726 case VAConfigAttribRateControl:
727 if (entrypoint == VAEntrypointEncSlice) {
728 attrib_list[i].value = VA_RC_CQP;
730 if (profile != VAProfileMPEG2Main &&
731 profile != VAProfileMPEG2Simple)
732 attrib_list[i].value |= VA_RC_CBR;
737 case VAConfigAttribEncPackedHeaders:
738 if (entrypoint == VAEntrypointEncSlice) {
739 attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
740 if (profile == VAProfileH264ConstrainedBaseline ||
741 profile == VAProfileH264Main ||
742 profile == VAProfileH264High ||
743 profile == VAProfileH264StereoHigh ||
744 profile == VAProfileH264MultiviewHigh ||
745 profile == VAProfileHEVCMain) {
746 attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA |
747 VA_ENC_PACKED_HEADER_SLICE);
751 else if (entrypoint == VAEntrypointEncPicture) {
752 if (profile == VAProfileJPEGBaseline)
753 attrib_list[i].value = VA_ENC_PACKED_HEADER_RAW_DATA;
757 case VAConfigAttribEncMaxRefFrames:
758 if (entrypoint == VAEntrypointEncSlice) {
759 attrib_list[i].value = (1 << 16) | (1 << 0);
764 case VAConfigAttribEncQualityRange:
765 if (entrypoint == VAEntrypointEncSlice) {
766 attrib_list[i].value = 1;
767 if (profile == VAProfileH264ConstrainedBaseline ||
768 profile == VAProfileH264Main ||
769 profile == VAProfileH264High )
770 attrib_list[i].value = ENCODER_QUALITY_RANGE;
775 case VAConfigAttribEncJPEG:
776 if( entrypoint == VAEntrypointEncPicture) {
777 VAConfigAttribValEncJPEG *configVal = (VAConfigAttribValEncJPEG*)&(attrib_list[i].value);
778 (configVal->bits).arithmatic_coding_mode = 0; // Huffman coding is used
779 (configVal->bits).progressive_dct_mode = 0; // Only Sequential DCT is supported
780 (configVal->bits).non_interleaved_mode = 1; // Support both interleaved and non-interleaved
781 (configVal->bits).differential_mode = 0; // Baseline DCT is non-differential
782 (configVal->bits).max_num_components = 3; // Only 3 components supported
783 (configVal->bits).max_num_scans = 1; // Only 1 scan per frame
784 (configVal->bits).max_num_huffman_tables = 3; // Max 3 huffman tables
785 (configVal->bits).max_num_quantization_tables = 3; // Max 3 quantization tables
791 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
796 return VA_STATUS_SUCCESS;
800 i965_destroy_config(struct object_heap *heap, struct object_base *obj)
802 object_heap_free(heap, obj);
805 static VAConfigAttrib *
806 i965_lookup_config_attribute(struct object_config *obj_config,
807 VAConfigAttribType type)
811 for (i = 0; i < obj_config->num_attribs; i++) {
812 VAConfigAttrib * const attrib = &obj_config->attrib_list[i];
813 if (attrib->type == type)
820 i965_append_config_attribute(struct object_config *obj_config,
821 const VAConfigAttrib *new_attrib)
823 VAConfigAttrib *attrib;
825 if (obj_config->num_attribs >= I965_MAX_CONFIG_ATTRIBUTES)
826 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
828 attrib = &obj_config->attrib_list[obj_config->num_attribs++];
829 attrib->type = new_attrib->type;
830 attrib->value = new_attrib->value;
831 return VA_STATUS_SUCCESS;
835 i965_ensure_config_attribute(struct object_config *obj_config,
836 const VAConfigAttrib *new_attrib)
838 VAConfigAttrib *attrib;
840 /* Check for existing attributes */
841 attrib = i965_lookup_config_attribute(obj_config, new_attrib->type);
843 /* Update existing attribute */
844 attrib->value = new_attrib->value;
845 return VA_STATUS_SUCCESS;
847 return i965_append_config_attribute(obj_config, new_attrib);
851 i965_CreateConfig(VADriverContextP ctx,
853 VAEntrypoint entrypoint,
854 VAConfigAttrib *attrib_list,
856 VAConfigID *config_id) /* out */
858 struct i965_driver_data * const i965 = i965_driver_data(ctx);
859 struct object_config *obj_config;
864 vaStatus = i965_validate_config(ctx, profile, entrypoint);
866 if (VA_STATUS_SUCCESS != vaStatus) {
870 configID = NEW_CONFIG_ID();
871 obj_config = CONFIG(configID);
873 if (NULL == obj_config) {
874 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
878 obj_config->profile = profile;
879 obj_config->entrypoint = entrypoint;
880 obj_config->num_attribs = 0;
882 for (i = 0; i < num_attribs; i++) {
883 vaStatus = i965_ensure_config_attribute(obj_config, &attrib_list[i]);
884 if (vaStatus != VA_STATUS_SUCCESS)
888 if (vaStatus == VA_STATUS_SUCCESS) {
889 VAConfigAttrib attrib, *attrib_found;
890 attrib.type = VAConfigAttribRTFormat;
891 attrib.value = i965_get_default_chroma_formats(ctx, profile, entrypoint);
892 attrib_found = i965_lookup_config_attribute(obj_config, attrib.type);
893 if (!attrib_found || !attrib_found->value)
894 vaStatus = i965_append_config_attribute(obj_config, &attrib);
895 else if (!(attrib_found->value & attrib.value))
896 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
900 if (VA_STATUS_SUCCESS != vaStatus) {
901 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
903 *config_id = configID;
910 i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
912 struct i965_driver_data *i965 = i965_driver_data(ctx);
913 struct object_config *obj_config = CONFIG(config_id);
916 if (NULL == obj_config) {
917 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
921 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
922 return VA_STATUS_SUCCESS;
925 VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
926 VAConfigID config_id,
927 VAProfile *profile, /* out */
928 VAEntrypoint *entrypoint, /* out */
929 VAConfigAttrib *attrib_list, /* out */
930 int *num_attribs) /* out */
932 struct i965_driver_data *i965 = i965_driver_data(ctx);
933 struct object_config *obj_config = CONFIG(config_id);
934 VAStatus vaStatus = VA_STATUS_SUCCESS;
937 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
938 *profile = obj_config->profile;
939 *entrypoint = obj_config->entrypoint;
940 *num_attribs = obj_config->num_attribs;
942 for(i = 0; i < obj_config->num_attribs; i++) {
943 attrib_list[i] = obj_config->attrib_list[i];
950 i965_destroy_surface_storage(struct object_surface *obj_surface)
955 dri_bo_unreference(obj_surface->bo);
956 obj_surface->bo = NULL;
958 if (obj_surface->free_private_data != NULL) {
959 obj_surface->free_private_data(&obj_surface->private_data);
960 obj_surface->private_data = NULL;
965 i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
967 struct object_surface *obj_surface = (struct object_surface *)obj;
969 i965_destroy_surface_storage(obj_surface);
970 object_heap_free(heap, obj);
974 i965_surface_native_memory(VADriverContextP ctx,
975 struct object_surface *obj_surface,
979 struct i965_driver_data *i965 = i965_driver_data(ctx);
980 int tiling = HAS_TILED_SURFACE(i965);
982 if (!expected_fourcc)
983 return VA_STATUS_SUCCESS;
985 // todo, should we disable tiling for 422 format?
986 if (expected_fourcc == VA_FOURCC_I420 ||
987 expected_fourcc == VA_FOURCC_IYUV ||
988 expected_fourcc == VA_FOURCC_YV12 ||
989 expected_fourcc == VA_FOURCC_YV16)
992 return i965_check_alloc_surface_bo(ctx, obj_surface, tiling, expected_fourcc, get_sampling_from_fourcc(expected_fourcc));
996 i965_suface_external_memory(VADriverContextP ctx,
997 struct object_surface *obj_surface,
998 int external_memory_type,
999 VASurfaceAttribExternalBuffers *memory_attibute,
1002 struct i965_driver_data *i965 = i965_driver_data(ctx);
1004 if (!memory_attibute ||
1005 !memory_attibute->buffers ||
1006 index > memory_attibute->num_buffers)
1007 return VA_STATUS_ERROR_INVALID_PARAMETER;
1009 ASSERT_RET(obj_surface->orig_width == memory_attibute->width, VA_STATUS_ERROR_INVALID_PARAMETER);
1010 ASSERT_RET(obj_surface->orig_height == memory_attibute->height, VA_STATUS_ERROR_INVALID_PARAMETER);
1011 ASSERT_RET(memory_attibute->num_planes >= 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1013 obj_surface->fourcc = memory_attibute->pixel_format;
1014 obj_surface->width = memory_attibute->pitches[0];
1015 obj_surface->size = memory_attibute->data_size;
1017 if (memory_attibute->num_planes == 1)
1018 obj_surface->height = memory_attibute->data_size / obj_surface->width;
1020 obj_surface->height = memory_attibute->offsets[1] / obj_surface->width;
1022 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
1023 obj_surface->x_cr_offset = 0;
1025 switch (obj_surface->fourcc) {
1026 case VA_FOURCC_NV12:
1027 ASSERT_RET(memory_attibute->num_planes == 2, VA_STATUS_ERROR_INVALID_PARAMETER);
1028 ASSERT_RET(memory_attibute->pitches[0] == memory_attibute->pitches[1], VA_STATUS_ERROR_INVALID_PARAMETER);
1030 obj_surface->subsampling = SUBSAMPLE_YUV420;
1031 obj_surface->y_cb_offset = obj_surface->height;
1032 obj_surface->y_cr_offset = obj_surface->height;
1033 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1034 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1035 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1039 case VA_FOURCC_YV12:
1040 case VA_FOURCC_IMC1:
1041 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1042 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1044 obj_surface->subsampling = SUBSAMPLE_YUV420;
1045 obj_surface->y_cr_offset = obj_surface->height;
1046 obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
1047 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1048 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1049 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1053 case VA_FOURCC_I420:
1054 case VA_FOURCC_IYUV:
1055 case VA_FOURCC_IMC3:
1056 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1057 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1059 obj_surface->subsampling = SUBSAMPLE_YUV420;
1060 obj_surface->y_cb_offset = obj_surface->height;
1061 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1062 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1063 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1064 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1068 case VA_FOURCC_YUY2:
1069 case VA_FOURCC_UYVY:
1070 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1072 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1073 obj_surface->y_cb_offset = 0;
1074 obj_surface->y_cr_offset = 0;
1075 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1076 obj_surface->cb_cr_height = obj_surface->orig_height;
1077 obj_surface->cb_cr_pitch = memory_attibute->pitches[0];
1081 case VA_FOURCC_RGBA:
1082 case VA_FOURCC_RGBX:
1083 case VA_FOURCC_BGRA:
1084 case VA_FOURCC_BGRX:
1085 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1087 obj_surface->subsampling = SUBSAMPLE_RGBX;
1088 obj_surface->y_cb_offset = 0;
1089 obj_surface->y_cr_offset = 0;
1090 obj_surface->cb_cr_width = 0;
1091 obj_surface->cb_cr_height = 0;
1092 obj_surface->cb_cr_pitch = 0;
1096 case VA_FOURCC_Y800: /* monochrome surface */
1097 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1099 obj_surface->subsampling = SUBSAMPLE_YUV400;
1100 obj_surface->y_cb_offset = 0;
1101 obj_surface->y_cr_offset = 0;
1102 obj_surface->cb_cr_width = 0;
1103 obj_surface->cb_cr_height = 0;
1104 obj_surface->cb_cr_pitch = 0;
1108 case VA_FOURCC_411P:
1109 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1110 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1112 obj_surface->subsampling = SUBSAMPLE_YUV411;
1113 obj_surface->y_cb_offset = 0;
1114 obj_surface->y_cr_offset = 0;
1115 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
1116 obj_surface->cb_cr_height = obj_surface->orig_height;
1117 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1121 case VA_FOURCC_422H:
1122 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1123 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1125 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1126 obj_surface->y_cb_offset = obj_surface->height;
1127 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1128 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1129 obj_surface->cb_cr_height = obj_surface->orig_height;
1130 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1134 case VA_FOURCC_YV16:
1135 assert(memory_attibute->num_planes == 3);
1136 assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
1138 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1139 obj_surface->y_cr_offset = memory_attibute->offsets[1] / obj_surface->width;
1140 obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
1141 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1142 obj_surface->cb_cr_height = obj_surface->orig_height;
1143 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1147 case VA_FOURCC_422V:
1148 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1149 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1151 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1152 obj_surface->y_cb_offset = obj_surface->height;
1153 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1154 obj_surface->cb_cr_width = obj_surface->orig_width;
1155 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1156 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1160 case VA_FOURCC_444P:
1161 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1162 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1164 obj_surface->subsampling = SUBSAMPLE_YUV444;
1165 obj_surface->y_cb_offset = obj_surface->height;
1166 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1167 obj_surface->cb_cr_width = obj_surface->orig_width;
1168 obj_surface->cb_cr_height = obj_surface->orig_height;
1169 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1175 return VA_STATUS_ERROR_INVALID_PARAMETER;
1178 if (external_memory_type == I965_SURFACE_MEM_GEM_FLINK)
1179 obj_surface->bo = drm_intel_bo_gem_create_from_name(i965->intel.bufmgr,
1180 "gem flinked vaapi surface",
1181 memory_attibute->buffers[index]);
1182 else if (external_memory_type == I965_SURFACE_MEM_DRM_PRIME)
1183 obj_surface->bo = drm_intel_bo_gem_create_from_prime(i965->intel.bufmgr,
1184 memory_attibute->buffers[index],
1187 if (!obj_surface->bo)
1188 return VA_STATUS_ERROR_INVALID_PARAMETER;
1190 return VA_STATUS_SUCCESS;
1193 /* byte-per-pixel of the first plane */
1195 bpp_1stplane_by_fourcc(unsigned int fourcc)
1197 const i965_fourcc_info *info = get_fourcc_info(fourcc);
1199 if (info && (info->flag & I_S))
1200 return info->bpp[0] / 8;
1206 i965_CreateSurfaces2(
1207 VADriverContextP ctx,
1208 unsigned int format,
1210 unsigned int height,
1211 VASurfaceID *surfaces,
1212 unsigned int num_surfaces,
1213 VASurfaceAttrib *attrib_list,
1214 unsigned int num_attribs
1217 struct i965_driver_data *i965 = i965_driver_data(ctx);
1219 VAStatus vaStatus = VA_STATUS_SUCCESS;
1220 int expected_fourcc = 0;
1221 int memory_type = I965_SURFACE_MEM_NATIVE; /* native */
1222 VASurfaceAttribExternalBuffers *memory_attibute = NULL;
1224 for (i = 0; i < num_attribs && attrib_list; i++) {
1225 if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
1226 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
1227 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
1228 expected_fourcc = attrib_list[i].value.value.i;
1231 if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&
1232 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
1234 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
1236 if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
1237 memory_type = I965_SURFACE_MEM_GEM_FLINK; /* flinked GEM handle */
1238 else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)
1239 memory_type = I965_SURFACE_MEM_DRM_PRIME; /* drm prime fd */
1240 else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_VA)
1241 memory_type = I965_SURFACE_MEM_NATIVE; /* va native memory, to be allocated */
1244 if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&
1245 (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {
1246 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypePointer, VA_STATUS_ERROR_INVALID_PARAMETER);
1247 memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;
1251 /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used
1252 * for post-processing (including color conversion) */
1253 if (VA_RT_FORMAT_YUV420 != format &&
1254 VA_RT_FORMAT_YUV422 != format &&
1255 VA_RT_FORMAT_YUV444 != format &&
1256 VA_RT_FORMAT_YUV411 != format &&
1257 VA_RT_FORMAT_YUV400 != format &&
1258 VA_RT_FORMAT_RGB32 != format) {
1259 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
1262 for (i = 0; i < num_surfaces; i++) {
1263 int surfaceID = NEW_SURFACE_ID();
1264 struct object_surface *obj_surface = SURFACE(surfaceID);
1266 if (NULL == obj_surface) {
1267 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1271 surfaces[i] = surfaceID;
1272 obj_surface->status = VASurfaceReady;
1273 obj_surface->orig_width = width;
1274 obj_surface->orig_height = height;
1275 obj_surface->user_disable_tiling = false;
1276 obj_surface->user_h_stride_set = false;
1277 obj_surface->user_v_stride_set = false;
1279 obj_surface->subpic_render_idx = 0;
1280 for(j = 0; j < I965_MAX_SUBPIC_SUM; j++){
1281 obj_surface->subpic[j] = VA_INVALID_ID;
1282 obj_surface->obj_subpic[j] = NULL;
1285 assert(i965->codec_info->min_linear_wpitch);
1286 assert(i965->codec_info->min_linear_hpitch);
1287 obj_surface->width = ALIGN(width, i965->codec_info->min_linear_wpitch);
1288 obj_surface->height = ALIGN(height, i965->codec_info->min_linear_hpitch);
1289 obj_surface->flags = SURFACE_REFERENCED;
1290 obj_surface->fourcc = 0;
1291 obj_surface->expected_format = format;
1292 obj_surface->bo = NULL;
1293 obj_surface->locked_image_id = VA_INVALID_ID;
1294 obj_surface->derived_image_id = VA_INVALID_ID;
1295 obj_surface->private_data = NULL;
1296 obj_surface->free_private_data = NULL;
1297 obj_surface->subsampling = SUBSAMPLE_YUV420;
1299 switch (memory_type) {
1300 case I965_SURFACE_MEM_NATIVE:
1301 if (memory_attibute) {
1302 if (!(memory_attibute->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING))
1303 obj_surface->user_disable_tiling = true;
1305 if (memory_attibute->pixel_format) {
1306 if (expected_fourcc)
1307 ASSERT_RET(memory_attibute->pixel_format == expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1309 expected_fourcc = memory_attibute->pixel_format;
1311 ASSERT_RET(expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1312 if (memory_attibute->pitches[0]) {
1313 int bpp_1stplane = bpp_1stplane_by_fourcc(expected_fourcc);
1314 ASSERT_RET(bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
1315 obj_surface->width = memory_attibute->pitches[0]/bpp_1stplane;
1316 obj_surface->user_h_stride_set = true;
1317 ASSERT_RET(IS_ALIGNED(obj_surface->width, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1318 ASSERT_RET(obj_surface->width >= width, VA_STATUS_ERROR_INVALID_PARAMETER);
1320 if (memory_attibute->offsets[1]) {
1321 ASSERT_RET(!memory_attibute->offsets[0], VA_STATUS_ERROR_INVALID_PARAMETER);
1322 obj_surface->height = memory_attibute->offsets[1]/memory_attibute->pitches[0];
1323 obj_surface->user_v_stride_set = true;
1324 ASSERT_RET(IS_ALIGNED(obj_surface->height, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1325 ASSERT_RET(obj_surface->height >= height, VA_STATUS_ERROR_INVALID_PARAMETER);
1329 vaStatus = i965_surface_native_memory(ctx,
1335 case I965_SURFACE_MEM_GEM_FLINK:
1336 case I965_SURFACE_MEM_DRM_PRIME:
1337 vaStatus = i965_suface_external_memory(ctx,
1344 if (VA_STATUS_SUCCESS != vaStatus) {
1345 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1350 /* Error recovery */
1351 if (VA_STATUS_SUCCESS != vaStatus) {
1352 /* surfaces[i-1] was the last successful allocation */
1354 struct object_surface *obj_surface = SURFACE(surfaces[i]);
1356 surfaces[i] = VA_INVALID_SURFACE;
1357 assert(obj_surface);
1358 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1366 i965_CreateSurfaces(VADriverContextP ctx,
1371 VASurfaceID *surfaces) /* out */
1373 return i965_CreateSurfaces2(ctx,
1384 i965_DestroySurfaces(VADriverContextP ctx,
1385 VASurfaceID *surface_list,
1388 struct i965_driver_data *i965 = i965_driver_data(ctx);
1391 for (i = num_surfaces; i--; ) {
1392 struct object_surface *obj_surface = SURFACE(surface_list[i]);
1394 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
1395 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1398 return VA_STATUS_SUCCESS;
1402 i965_QueryImageFormats(VADriverContextP ctx,
1403 VAImageFormat *format_list, /* out */
1404 int *num_formats) /* out */
1408 for (n = 0; i965_image_formats_map[n].va_format.fourcc != 0; n++) {
1409 const i965_image_format_map_t * const m = &i965_image_formats_map[n];
1411 format_list[n] = m->va_format;
1417 return VA_STATUS_SUCCESS;
1421 * Guess the format when the usage of a VA surface is unknown
1422 * 1. Without a valid context: YV12
1423 * 2. The current context is valid:
1424 * a) always NV12 on GEN6 and later
1425 * b) I420 for MPEG-2 and NV12 for other codec on GEN4 & GEN5
1428 i965_guess_surface_format(VADriverContextP ctx,
1429 VASurfaceID surface,
1430 unsigned int *fourcc,
1431 unsigned int *is_tiled)
1433 struct i965_driver_data *i965 = i965_driver_data(ctx);
1434 struct object_context *obj_context = NULL;
1435 struct object_config *obj_config = NULL;
1437 *fourcc = VA_FOURCC_YV12;
1440 if (i965->current_context_id == VA_INVALID_ID)
1443 obj_context = CONTEXT(i965->current_context_id);
1448 obj_config = obj_context->obj_config;
1454 if (IS_GEN6(i965->intel.device_info) ||
1455 IS_GEN7(i965->intel.device_info) ||
1456 IS_GEN8(i965->intel.device_info) ||
1457 IS_GEN9(i965->intel.device_info)) {
1458 *fourcc = VA_FOURCC_NV12;
1463 switch (obj_config->profile) {
1464 case VAProfileMPEG2Simple:
1465 case VAProfileMPEG2Main:
1466 *fourcc = VA_FOURCC_I420;
1471 *fourcc = VA_FOURCC_NV12;
1478 i965_QuerySubpictureFormats(VADriverContextP ctx,
1479 VAImageFormat *format_list, /* out */
1480 unsigned int *flags, /* out */
1481 unsigned int *num_formats) /* out */
1485 for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
1486 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
1488 format_list[n] = m->va_format;
1490 flags[n] = m->va_flags;
1496 return VA_STATUS_SUCCESS;
1500 i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
1502 // struct object_subpic *obj_subpic = (struct object_subpic *)obj;
1504 object_heap_free(heap, obj);
1508 i965_CreateSubpicture(VADriverContextP ctx,
1510 VASubpictureID *subpicture) /* out */
1512 struct i965_driver_data *i965 = i965_driver_data(ctx);
1513 VASubpictureID subpicID = NEW_SUBPIC_ID()
1514 struct object_subpic *obj_subpic = SUBPIC(subpicID);
1517 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1519 struct object_image *obj_image = IMAGE(image);
1521 return VA_STATUS_ERROR_INVALID_IMAGE;
1523 const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
1525 return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
1527 *subpicture = subpicID;
1528 obj_subpic->image = image;
1529 obj_subpic->obj_image = obj_image;
1530 obj_subpic->format = m->format;
1531 obj_subpic->width = obj_image->image.width;
1532 obj_subpic->height = obj_image->image.height;
1533 obj_subpic->pitch = obj_image->image.pitches[0];
1534 obj_subpic->bo = obj_image->bo;
1535 obj_subpic->global_alpha = 1.0;
1537 return VA_STATUS_SUCCESS;
1541 i965_DestroySubpicture(VADriverContextP ctx,
1542 VASubpictureID subpicture)
1544 struct i965_driver_data *i965 = i965_driver_data(ctx);
1545 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1548 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1550 ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
1551 i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
1552 return VA_STATUS_SUCCESS;
1556 i965_SetSubpictureImage(VADriverContextP ctx,
1557 VASubpictureID subpicture,
1561 return VA_STATUS_ERROR_UNIMPLEMENTED;
1565 i965_SetSubpictureChromakey(VADriverContextP ctx,
1566 VASubpictureID subpicture,
1567 unsigned int chromakey_min,
1568 unsigned int chromakey_max,
1569 unsigned int chromakey_mask)
1572 return VA_STATUS_ERROR_UNIMPLEMENTED;
1576 i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
1577 VASubpictureID subpicture,
1580 struct i965_driver_data *i965 = i965_driver_data(ctx);
1581 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1583 if(global_alpha > 1.0 || global_alpha < 0.0){
1584 return VA_STATUS_ERROR_INVALID_PARAMETER;
1588 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1590 obj_subpic->global_alpha = global_alpha;
1592 return VA_STATUS_SUCCESS;
1596 i965_AssociateSubpicture(VADriverContextP ctx,
1597 VASubpictureID subpicture,
1598 VASurfaceID *target_surfaces,
1600 short src_x, /* upper left offset in subpicture */
1602 unsigned short src_width,
1603 unsigned short src_height,
1604 short dest_x, /* upper left offset in surface */
1606 unsigned short dest_width,
1607 unsigned short dest_height,
1609 * whether to enable chroma-keying or global-alpha
1610 * see VA_SUBPICTURE_XXX values
1614 struct i965_driver_data *i965 = i965_driver_data(ctx);
1615 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1619 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1621 ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
1623 obj_subpic->src_rect.x = src_x;
1624 obj_subpic->src_rect.y = src_y;
1625 obj_subpic->src_rect.width = src_width;
1626 obj_subpic->src_rect.height = src_height;
1627 obj_subpic->dst_rect.x = dest_x;
1628 obj_subpic->dst_rect.y = dest_y;
1629 obj_subpic->dst_rect.width = dest_width;
1630 obj_subpic->dst_rect.height = dest_height;
1631 obj_subpic->flags = flags;
1633 for (i = 0; i < num_surfaces; i++) {
1634 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1636 return VA_STATUS_ERROR_INVALID_SURFACE;
1638 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1639 if(obj_surface->subpic[j] == VA_INVALID_ID){
1640 assert(obj_surface->obj_subpic[j] == NULL);
1641 obj_surface->subpic[j] = subpicture;
1642 obj_surface->obj_subpic[j] = obj_subpic;
1647 if(j == I965_MAX_SUBPIC_SUM){
1648 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1652 return VA_STATUS_SUCCESS;
1657 i965_DeassociateSubpicture(VADriverContextP ctx,
1658 VASubpictureID subpicture,
1659 VASurfaceID *target_surfaces,
1662 struct i965_driver_data *i965 = i965_driver_data(ctx);
1663 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1667 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1669 for (i = 0; i < num_surfaces; i++) {
1670 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1672 return VA_STATUS_ERROR_INVALID_SURFACE;
1674 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1675 if (obj_surface->subpic[j] == subpicture) {
1676 assert(obj_surface->obj_subpic[j] == obj_subpic);
1677 obj_surface->subpic[j] = VA_INVALID_ID;
1678 obj_surface->obj_subpic[j] = NULL;
1683 if(j == I965_MAX_SUBPIC_SUM){
1684 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1687 return VA_STATUS_SUCCESS;
1691 i965_reference_buffer_store(struct buffer_store **ptr,
1692 struct buffer_store *buffer_store)
1694 assert(*ptr == NULL);
1697 buffer_store->ref_count++;
1698 *ptr = buffer_store;
1703 i965_release_buffer_store(struct buffer_store **ptr)
1705 struct buffer_store *buffer_store = *ptr;
1707 if (buffer_store == NULL)
1710 assert(buffer_store->bo || buffer_store->buffer);
1711 assert(!(buffer_store->bo && buffer_store->buffer));
1712 buffer_store->ref_count--;
1714 if (buffer_store->ref_count == 0) {
1715 dri_bo_unreference(buffer_store->bo);
1716 free(buffer_store->buffer);
1717 buffer_store->bo = NULL;
1718 buffer_store->buffer = NULL;
1726 i965_destroy_context(struct object_heap *heap, struct object_base *obj)
1728 struct object_context *obj_context = (struct object_context *)obj;
1731 if (obj_context->hw_context) {
1732 obj_context->hw_context->destroy(obj_context->hw_context);
1733 obj_context->hw_context = NULL;
1736 if (obj_context->codec_type == CODEC_PROC) {
1737 i965_release_buffer_store(&obj_context->codec_state.proc.pipeline_param);
1739 } else if (obj_context->codec_type == CODEC_ENC) {
1740 assert(obj_context->codec_state.encode.num_slice_params <= obj_context->codec_state.encode.max_slice_params);
1741 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
1742 i965_release_buffer_store(&obj_context->codec_state.encode.seq_param);
1744 for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++)
1745 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
1747 free(obj_context->codec_state.encode.slice_params);
1749 assert(obj_context->codec_state.encode.num_slice_params_ext <= obj_context->codec_state.encode.max_slice_params_ext);
1750 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
1751 i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
1753 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
1754 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
1756 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
1757 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
1759 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
1760 i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i]);
1762 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
1763 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
1765 free(obj_context->codec_state.encode.slice_params_ext);
1766 if (obj_context->codec_state.encode.slice_rawdata_index) {
1767 free(obj_context->codec_state.encode.slice_rawdata_index);
1768 obj_context->codec_state.encode.slice_rawdata_index = NULL;
1770 if (obj_context->codec_state.encode.slice_rawdata_count) {
1771 free(obj_context->codec_state.encode.slice_rawdata_count);
1772 obj_context->codec_state.encode.slice_rawdata_count = NULL;
1775 if (obj_context->codec_state.encode.slice_header_index) {
1776 free(obj_context->codec_state.encode.slice_header_index);
1777 obj_context->codec_state.encode.slice_header_index = NULL;
1780 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
1781 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
1782 free(obj_context->codec_state.encode.packed_header_params_ext);
1784 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
1785 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
1786 free(obj_context->codec_state.encode.packed_header_data_ext);
1789 assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
1790 assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
1792 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
1793 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
1794 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
1796 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++)
1797 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
1799 for (i = 0; i < obj_context->codec_state.decode.num_slice_datas; i++)
1800 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
1802 free(obj_context->codec_state.decode.slice_params);
1803 free(obj_context->codec_state.decode.slice_datas);
1806 free(obj_context->render_targets);
1807 object_heap_free(heap, obj);
1811 i965_CreateContext(VADriverContextP ctx,
1812 VAConfigID config_id,
1816 VASurfaceID *render_targets,
1817 int num_render_targets,
1818 VAContextID *context) /* out */
1820 struct i965_driver_data *i965 = i965_driver_data(ctx);
1821 struct i965_render_state *render_state = &i965->render_state;
1822 struct object_config *obj_config = CONFIG(config_id);
1823 struct object_context *obj_context = NULL;
1824 VAConfigAttrib *attrib;
1825 VAStatus vaStatus = VA_STATUS_SUCCESS;
1829 if (NULL == obj_config) {
1830 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
1834 if (picture_width > i965->codec_info->max_width ||
1835 picture_height > i965->codec_info->max_height) {
1836 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
1841 /* Validate picture dimensions */
1842 contextID = NEW_CONTEXT_ID();
1843 obj_context = CONTEXT(contextID);
1845 if (NULL == obj_context) {
1846 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1850 *context = contextID;
1851 obj_context->flags = flag;
1852 obj_context->context_id = contextID;
1853 obj_context->obj_config = obj_config;
1854 obj_context->picture_width = picture_width;
1855 obj_context->picture_height = picture_height;
1856 obj_context->num_render_targets = num_render_targets;
1857 obj_context->render_targets =
1858 (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
1859 obj_context->hw_context = NULL;
1861 for(i = 0; i < num_render_targets; i++) {
1862 if (NULL == SURFACE(render_targets[i])) {
1863 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1867 obj_context->render_targets[i] = render_targets[i];
1870 if (VA_STATUS_SUCCESS == vaStatus) {
1871 if (VAEntrypointVideoProc == obj_config->entrypoint) {
1872 obj_context->codec_type = CODEC_PROC;
1873 memset(&obj_context->codec_state.proc, 0, sizeof(obj_context->codec_state.proc));
1874 obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
1875 assert(i965->codec_info->proc_hw_context_init);
1876 obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
1877 } else if ((VAEntrypointEncSlice == obj_config->entrypoint) ||
1878 (VAEntrypointEncPicture == obj_config->entrypoint)) { /*encode routine only*/
1879 VAConfigAttrib *packed_attrib;
1880 obj_context->codec_type = CODEC_ENC;
1881 memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
1882 obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
1883 obj_context->codec_state.encode.max_slice_params = NUM_SLICES;
1884 obj_context->codec_state.encode.slice_params = calloc(obj_context->codec_state.encode.max_slice_params,
1885 sizeof(*obj_context->codec_state.encode.slice_params));
1886 obj_context->codec_state.encode.max_packed_header_params_ext = NUM_SLICES;
1887 obj_context->codec_state.encode.packed_header_params_ext =
1888 calloc(obj_context->codec_state.encode.max_packed_header_params_ext,
1889 sizeof(struct buffer_store *));
1891 obj_context->codec_state.encode.max_packed_header_data_ext = NUM_SLICES;
1892 obj_context->codec_state.encode.packed_header_data_ext =
1893 calloc(obj_context->codec_state.encode.max_packed_header_data_ext,
1894 sizeof(struct buffer_store *));
1896 obj_context->codec_state.encode.max_slice_num = NUM_SLICES;
1897 obj_context->codec_state.encode.slice_rawdata_index =
1898 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
1899 obj_context->codec_state.encode.slice_rawdata_count =
1900 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
1902 obj_context->codec_state.encode.slice_header_index =
1903 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
1905 obj_context->codec_state.encode.vps_sps_seq_index = 0;
1907 obj_context->codec_state.encode.slice_index = 0;
1908 packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders);
1910 obj_context->codec_state.encode.packed_header_flag = packed_attrib->value;
1912 /* use the default value. SPS/PPS/RAWDATA is passed from user
1913 * while Slice_header data is generated by driver.
1915 obj_context->codec_state.encode.packed_header_flag =
1916 VA_ENC_PACKED_HEADER_SEQUENCE |
1917 VA_ENC_PACKED_HEADER_PICTURE |
1918 VA_ENC_PACKED_HEADER_RAW_DATA;
1920 assert(i965->codec_info->enc_hw_context_init);
1921 obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
1923 obj_context->codec_type = CODEC_DEC;
1924 memset(&obj_context->codec_state.decode, 0, sizeof(obj_context->codec_state.decode));
1925 obj_context->codec_state.decode.current_render_target = -1;
1926 obj_context->codec_state.decode.max_slice_params = NUM_SLICES;
1927 obj_context->codec_state.decode.max_slice_datas = NUM_SLICES;
1928 obj_context->codec_state.decode.slice_params = calloc(obj_context->codec_state.decode.max_slice_params,
1929 sizeof(*obj_context->codec_state.decode.slice_params));
1930 obj_context->codec_state.decode.slice_datas = calloc(obj_context->codec_state.decode.max_slice_datas,
1931 sizeof(*obj_context->codec_state.decode.slice_datas));
1933 assert(i965->codec_info->dec_hw_context_init);
1934 obj_context->hw_context = i965->codec_info->dec_hw_context_init(ctx, obj_config);
1938 attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribRTFormat);
1940 return VA_STATUS_ERROR_INVALID_CONFIG;
1941 obj_context->codec_state.base.chroma_formats = attrib->value;
1943 /* Error recovery */
1944 if (VA_STATUS_SUCCESS != vaStatus) {
1945 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1948 i965->current_context_id = contextID;
1954 i965_DestroyContext(VADriverContextP ctx, VAContextID context)
1956 struct i965_driver_data *i965 = i965_driver_data(ctx);
1957 struct object_context *obj_context = CONTEXT(context);
1959 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
1961 if (i965->current_context_id == context)
1962 i965->current_context_id = VA_INVALID_ID;
1964 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1966 return VA_STATUS_SUCCESS;
1970 i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
1972 struct object_buffer *obj_buffer = (struct object_buffer *)obj;
1974 assert(obj_buffer->buffer_store);
1975 i965_release_buffer_store(&obj_buffer->buffer_store);
1976 object_heap_free(heap, obj);
1980 i965_create_buffer_internal(VADriverContextP ctx,
1981 VAContextID context,
1984 unsigned int num_elements,
1989 struct i965_driver_data *i965 = i965_driver_data(ctx);
1990 struct object_buffer *obj_buffer = NULL;
1991 struct buffer_store *buffer_store = NULL;
1993 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1997 case VAPictureParameterBufferType:
1998 case VAIQMatrixBufferType:
1999 case VAQMatrixBufferType:
2000 case VABitPlaneBufferType:
2001 case VASliceGroupMapBufferType:
2002 case VASliceParameterBufferType:
2003 case VASliceDataBufferType:
2004 case VAMacroblockParameterBufferType:
2005 case VAResidualDataBufferType:
2006 case VADeblockingParameterBufferType:
2007 case VAImageBufferType:
2008 case VAEncCodedBufferType:
2009 case VAEncSequenceParameterBufferType:
2010 case VAEncPictureParameterBufferType:
2011 case VAEncSliceParameterBufferType:
2012 case VAEncPackedHeaderParameterBufferType:
2013 case VAEncPackedHeaderDataBufferType:
2014 case VAEncMiscParameterBufferType:
2015 case VAProcPipelineParameterBufferType:
2016 case VAProcFilterParameterBufferType:
2017 case VAHuffmanTableBufferType:
2018 case VAProbabilityBufferType:
2023 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2026 bufferID = NEW_BUFFER_ID();
2027 obj_buffer = BUFFER(bufferID);
2029 if (NULL == obj_buffer) {
2030 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2033 if (type == VAEncCodedBufferType) {
2034 size += I965_CODEDBUFFER_HEADER_SIZE;
2035 size += 0x1000; /* for upper bound check */
2038 obj_buffer->max_num_elements = num_elements;
2039 obj_buffer->num_elements = num_elements;
2040 obj_buffer->size_element = size;
2041 obj_buffer->type = type;
2042 obj_buffer->export_refcount = 0;
2043 obj_buffer->buffer_store = NULL;
2044 buffer_store = calloc(1, sizeof(struct buffer_store));
2045 assert(buffer_store);
2046 buffer_store->ref_count = 1;
2048 if (store_bo != NULL) {
2049 buffer_store->bo = store_bo;
2050 dri_bo_reference(buffer_store->bo);
2053 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
2054 } else if (type == VASliceDataBufferType ||
2055 type == VAImageBufferType ||
2056 type == VAEncCodedBufferType ||
2057 type == VAProbabilityBufferType) {
2058 buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
2060 size * num_elements, 64);
2061 assert(buffer_store->bo);
2063 if (type == VAEncCodedBufferType) {
2064 struct i965_coded_buffer_segment *coded_buffer_segment;
2066 dri_bo_map(buffer_store->bo, 1);
2067 coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual;
2068 coded_buffer_segment->base.size = size - I965_CODEDBUFFER_HEADER_SIZE;
2069 coded_buffer_segment->base.bit_offset = 0;
2070 coded_buffer_segment->base.status = 0;
2071 coded_buffer_segment->base.buf = NULL;
2072 coded_buffer_segment->base.next = NULL;
2073 coded_buffer_segment->mapped = 0;
2074 coded_buffer_segment->codec = 0;
2075 dri_bo_unmap(buffer_store->bo);
2077 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
2083 if (type == VAEncPackedHeaderDataBufferType) {
2084 msize = ALIGN(size, 4);
2087 buffer_store->buffer = malloc(msize * num_elements);
2088 assert(buffer_store->buffer);
2091 memcpy(buffer_store->buffer, data, size * num_elements);
2094 buffer_store->num_elements = obj_buffer->num_elements;
2095 i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
2096 i965_release_buffer_store(&buffer_store);
2099 return VA_STATUS_SUCCESS;
2103 i965_CreateBuffer(VADriverContextP ctx,
2104 VAContextID context, /* in */
2105 VABufferType type, /* in */
2106 unsigned int size, /* in */
2107 unsigned int num_elements, /* in */
2108 void *data, /* in */
2109 VABufferID *buf_id) /* out */
2111 return i965_create_buffer_internal(ctx, context, type, size, num_elements, data, NULL, buf_id);
2116 i965_BufferSetNumElements(VADriverContextP ctx,
2117 VABufferID buf_id, /* in */
2118 unsigned int num_elements) /* in */
2120 struct i965_driver_data *i965 = i965_driver_data(ctx);
2121 struct object_buffer *obj_buffer = BUFFER(buf_id);
2122 VAStatus vaStatus = VA_STATUS_SUCCESS;
2124 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2126 if ((num_elements < 0) ||
2127 (num_elements > obj_buffer->max_num_elements)) {
2128 vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2130 obj_buffer->num_elements = num_elements;
2131 if (obj_buffer->buffer_store != NULL) {
2132 obj_buffer->buffer_store->num_elements = num_elements;
2140 i965_MapBuffer(VADriverContextP ctx,
2141 VABufferID buf_id, /* in */
2142 void **pbuf) /* out */
2144 struct i965_driver_data *i965 = i965_driver_data(ctx);
2145 struct object_buffer *obj_buffer = BUFFER(buf_id);
2146 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2148 ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
2149 ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2150 ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_INVALID_BUFFER);
2152 if (obj_buffer->export_refcount > 0)
2153 return VA_STATUS_ERROR_INVALID_BUFFER;
2155 if (NULL != obj_buffer->buffer_store->bo) {
2156 unsigned int tiling, swizzle;
2158 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
2160 if (tiling != I915_TILING_NONE)
2161 drm_intel_gem_bo_map_gtt(obj_buffer->buffer_store->bo);
2163 dri_bo_map(obj_buffer->buffer_store->bo, 1);
2165 ASSERT_RET(obj_buffer->buffer_store->bo->virtual, VA_STATUS_ERROR_OPERATION_FAILED);
2166 *pbuf = obj_buffer->buffer_store->bo->virtual;
2168 if (obj_buffer->type == VAEncCodedBufferType) {
2170 unsigned char *buffer = NULL;
2171 unsigned int header_offset = I965_CODEDBUFFER_HEADER_SIZE;
2172 struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual);
2174 if (!coded_buffer_segment->mapped) {
2175 unsigned char delimiter0, delimiter1, delimiter2, delimiter3, delimiter4;
2177 coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
2179 if (coded_buffer_segment->codec == CODEC_H264 ||
2180 coded_buffer_segment->codec == CODEC_H264_MVC) {
2181 delimiter0 = H264_DELIMITER0;
2182 delimiter1 = H264_DELIMITER1;
2183 delimiter2 = H264_DELIMITER2;
2184 delimiter3 = H264_DELIMITER3;
2185 delimiter4 = H264_DELIMITER4;
2186 } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
2187 delimiter0 = MPEG2_DELIMITER0;
2188 delimiter1 = MPEG2_DELIMITER1;
2189 delimiter2 = MPEG2_DELIMITER2;
2190 delimiter3 = MPEG2_DELIMITER3;
2191 delimiter4 = MPEG2_DELIMITER4;
2192 } else if(coded_buffer_segment->codec == CODEC_JPEG) {
2193 //In JPEG End of Image (EOI = 0xDDF9) marker can be used for delimiter.
2196 } else if (coded_buffer_segment->codec == CODEC_HEVC) {
2197 delimiter0 = HEVC_DELIMITER0;
2198 delimiter1 = HEVC_DELIMITER1;
2199 delimiter2 = HEVC_DELIMITER2;
2200 delimiter3 = HEVC_DELIMITER3;
2201 delimiter4 = HEVC_DELIMITER4;
2202 } else if (coded_buffer_segment->codec != CODEC_VP8) {
2203 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
2206 if(coded_buffer_segment->codec == CODEC_JPEG) {
2207 for(i = 0; i < obj_buffer->size_element - header_offset - 1 - 0x1000; i++) {
2208 if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) {
2212 coded_buffer_segment->base.size = i + 2;
2213 } else if (coded_buffer_segment->codec != CODEC_VP8) {
2214 /* vp8 coded buffer size can be told by vp8 internal statistics buffer,
2215 so it don't need to traversal the coded buffer */
2216 for (i = 0; i < obj_buffer->size_element - header_offset - 3 - 0x1000; i++) {
2217 if ((buffer[i] == delimiter0) &&
2218 (buffer[i + 1] == delimiter1) &&
2219 (buffer[i + 2] == delimiter2) &&
2220 (buffer[i + 3] == delimiter3) &&
2221 (buffer[i + 4] == delimiter4))
2225 if (i == obj_buffer->size_element - header_offset - 3 - 0x1000) {
2226 coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
2228 coded_buffer_segment->base.size = i;
2231 if (coded_buffer_segment->base.size >= obj_buffer->size_element - header_offset - 0x1000) {
2232 coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
2235 coded_buffer_segment->mapped = 1;
2237 assert(coded_buffer_segment->base.buf);
2241 vaStatus = VA_STATUS_SUCCESS;
2242 } else if (NULL != obj_buffer->buffer_store->buffer) {
2243 *pbuf = obj_buffer->buffer_store->buffer;
2244 vaStatus = VA_STATUS_SUCCESS;
2251 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
2253 struct i965_driver_data *i965 = i965_driver_data(ctx);
2254 struct object_buffer *obj_buffer = BUFFER(buf_id);
2255 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2257 if ((buf_id & OBJECT_HEAP_OFFSET_MASK) != BUFFER_ID_OFFSET)
2258 return VA_STATUS_ERROR_INVALID_BUFFER;
2260 ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
2261 ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_OPERATION_FAILED);
2262 ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_OPERATION_FAILED);
2264 if (NULL != obj_buffer->buffer_store->bo) {
2265 unsigned int tiling, swizzle;
2267 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
2269 if (tiling != I915_TILING_NONE)
2270 drm_intel_gem_bo_unmap_gtt(obj_buffer->buffer_store->bo);
2272 dri_bo_unmap(obj_buffer->buffer_store->bo);
2274 vaStatus = VA_STATUS_SUCCESS;
2275 } else if (NULL != obj_buffer->buffer_store->buffer) {
2277 vaStatus = VA_STATUS_SUCCESS;
2284 i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
2286 struct i965_driver_data *i965 = i965_driver_data(ctx);
2287 struct object_buffer *obj_buffer = BUFFER(buffer_id);
2289 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2291 i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
2293 return VA_STATUS_SUCCESS;
2297 i965_BeginPicture(VADriverContextP ctx,
2298 VAContextID context,
2299 VASurfaceID render_target)
2301 struct i965_driver_data *i965 = i965_driver_data(ctx);
2302 struct object_context *obj_context = CONTEXT(context);
2303 struct object_surface *obj_surface = SURFACE(render_target);
2304 struct object_config *obj_config;
2308 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2309 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2310 obj_config = obj_context->obj_config;
2311 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2313 if (is_surface_busy(i965, obj_surface))
2314 return VA_STATUS_ERROR_SURFACE_BUSY;
2316 switch (obj_config->profile) {
2317 case VAProfileMPEG2Simple:
2318 case VAProfileMPEG2Main:
2319 vaStatus = VA_STATUS_SUCCESS;
2322 case VAProfileH264ConstrainedBaseline:
2323 case VAProfileH264Main:
2324 case VAProfileH264High:
2325 vaStatus = VA_STATUS_SUCCESS;
2328 case VAProfileH264MultiviewHigh:
2329 case VAProfileH264StereoHigh:
2330 if (HAS_H264_MVC_DECODING_PROFILE(i965, obj_config->profile) ||
2331 HAS_H264_MVC_ENCODING(i965)) {
2332 vaStatus = VA_STATUS_SUCCESS;
2334 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
2338 case VAProfileVC1Simple:
2339 case VAProfileVC1Main:
2340 case VAProfileVC1Advanced:
2341 vaStatus = VA_STATUS_SUCCESS;
2344 case VAProfileJPEGBaseline:
2345 vaStatus = VA_STATUS_SUCCESS;
2349 vaStatus = VA_STATUS_SUCCESS;
2352 case VAProfileVP8Version0_3:
2353 vaStatus = VA_STATUS_SUCCESS;
2356 case VAProfileHEVCMain:
2357 vaStatus = VA_STATUS_SUCCESS;
2361 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
2365 if (obj_context->codec_type == CODEC_PROC) {
2366 obj_context->codec_state.proc.current_render_target = render_target;
2367 } else if (obj_context->codec_type == CODEC_ENC) {
2368 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
2370 for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++) {
2371 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
2374 obj_context->codec_state.encode.num_slice_params = 0;
2377 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
2379 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
2380 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
2382 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
2383 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
2385 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
2386 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
2388 obj_context->codec_state.encode.num_slice_params_ext = 0;
2389 obj_context->codec_state.encode.current_render_target = render_target; /*This is input new frame*/
2390 obj_context->codec_state.encode.last_packed_header_type = 0;
2391 memset(obj_context->codec_state.encode.slice_rawdata_index, 0,
2392 sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2393 memset(obj_context->codec_state.encode.slice_rawdata_count, 0,
2394 sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2395 memset(obj_context->codec_state.encode.slice_header_index, 0,
2396 sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2398 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
2399 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
2400 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
2401 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
2402 obj_context->codec_state.encode.num_packed_header_params_ext = 0;
2403 obj_context->codec_state.encode.num_packed_header_data_ext = 0;
2404 obj_context->codec_state.encode.slice_index = 0;
2405 obj_context->codec_state.encode.vps_sps_seq_index = 0;
2407 obj_context->codec_state.decode.current_render_target = render_target;
2408 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
2409 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
2410 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
2411 i965_release_buffer_store(&obj_context->codec_state.decode.huffman_table);
2413 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++) {
2414 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
2415 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
2418 obj_context->codec_state.decode.num_slice_params = 0;
2419 obj_context->codec_state.decode.num_slice_datas = 0;
2425 #define I965_RENDER_BUFFER(category, name) i965_render_##category##_##name##_buffer(ctx, obj_context, obj_buffer)
2427 #define DEF_RENDER_SINGLE_BUFFER_FUNC(category, name, member) \
2429 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
2430 struct object_context *obj_context, \
2431 struct object_buffer *obj_buffer) \
2433 struct category##_state *category = &obj_context->codec_state.category; \
2434 i965_release_buffer_store(&category->member); \
2435 i965_reference_buffer_store(&category->member, obj_buffer->buffer_store); \
2436 return VA_STATUS_SUCCESS; \
2439 #define DEF_RENDER_MULTI_BUFFER_FUNC(category, name, member) \
2441 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
2442 struct object_context *obj_context, \
2443 struct object_buffer *obj_buffer) \
2445 struct category##_state *category = &obj_context->codec_state.category; \
2446 if (category->num_##member == category->max_##member) { \
2447 category->member = realloc(category->member, (category->max_##member + NUM_SLICES) * sizeof(*category->member)); \
2448 memset(category->member + category->max_##member, 0, NUM_SLICES * sizeof(*category->member)); \
2449 category->max_##member += NUM_SLICES; \
2451 i965_release_buffer_store(&category->member[category->num_##member]); \
2452 i965_reference_buffer_store(&category->member[category->num_##member], obj_buffer->buffer_store); \
2453 category->num_##member++; \
2454 return VA_STATUS_SUCCESS; \
2457 #define I965_RENDER_DECODE_BUFFER(name) I965_RENDER_BUFFER(decode, name)
2459 #define DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(decode, name, member)
2460 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2461 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(iq_matrix, iq_matrix)
2462 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(bit_plane, bit_plane)
2463 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
2464 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(probability_data, probability_data)
2466 #define DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(decode, name, member)
2467 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2468 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_data, slice_datas)
2471 i965_decoder_render_picture(VADriverContextP ctx,
2472 VAContextID context,
2473 VABufferID *buffers,
2476 struct i965_driver_data *i965 = i965_driver_data(ctx);
2477 struct object_context *obj_context = CONTEXT(context);
2478 VAStatus vaStatus = VA_STATUS_SUCCESS;
2481 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2483 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2484 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2487 return VA_STATUS_ERROR_INVALID_BUFFER;
2489 switch (obj_buffer->type) {
2490 case VAPictureParameterBufferType:
2491 vaStatus = I965_RENDER_DECODE_BUFFER(picture_parameter);
2494 case VAIQMatrixBufferType:
2495 vaStatus = I965_RENDER_DECODE_BUFFER(iq_matrix);
2498 case VABitPlaneBufferType:
2499 vaStatus = I965_RENDER_DECODE_BUFFER(bit_plane);
2502 case VASliceParameterBufferType:
2503 vaStatus = I965_RENDER_DECODE_BUFFER(slice_parameter);
2506 case VASliceDataBufferType:
2507 vaStatus = I965_RENDER_DECODE_BUFFER(slice_data);
2510 case VAHuffmanTableBufferType:
2511 vaStatus = I965_RENDER_DECODE_BUFFER(huffman_table);
2514 case VAProbabilityBufferType:
2515 vaStatus = I965_RENDER_DECODE_BUFFER(probability_data);
2519 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2527 #define I965_RENDER_ENCODE_BUFFER(name) I965_RENDER_BUFFER(encode, name)
2529 #define DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(encode, name, member)
2530 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter, seq_param)
2531 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2532 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_control, pic_control)
2533 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(qmatrix, q_matrix)
2534 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(iqmatrix, iq_matrix)
2535 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
2536 /* extended buffer */
2537 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
2538 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
2540 #define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
2541 // DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2542 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter_ext, slice_params_ext)
2544 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_params_ext, packed_header_params_ext)
2545 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_data_ext, packed_header_data_ext)
2548 i965_encoder_render_packed_header_parameter_buffer(VADriverContextP ctx,
2549 struct object_context *obj_context,
2550 struct object_buffer *obj_buffer,
2553 struct encode_state *encode = &obj_context->codec_state.encode;
2555 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2556 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2557 i965_release_buffer_store(&encode->packed_header_param[type_index]);
2558 i965_reference_buffer_store(&encode->packed_header_param[type_index], obj_buffer->buffer_store);
2560 return VA_STATUS_SUCCESS;
2564 i965_encoder_render_packed_header_data_buffer(VADriverContextP ctx,
2565 struct object_context *obj_context,
2566 struct object_buffer *obj_buffer,
2569 struct encode_state *encode = &obj_context->codec_state.encode;
2571 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2572 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2573 i965_release_buffer_store(&encode->packed_header_data[type_index]);
2574 i965_reference_buffer_store(&encode->packed_header_data[type_index], obj_buffer->buffer_store);
2576 return VA_STATUS_SUCCESS;
2580 i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
2581 struct object_context *obj_context,
2582 struct object_buffer *obj_buffer)
2584 struct encode_state *encode = &obj_context->codec_state.encode;
2585 VAEncMiscParameterBuffer *param = NULL;
2587 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2588 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2590 param = (VAEncMiscParameterBuffer *)obj_buffer->buffer_store->buffer;
2592 if (param->type >= ARRAY_ELEMS(encode->misc_param))
2593 return VA_STATUS_ERROR_INVALID_PARAMETER;
2595 i965_release_buffer_store(&encode->misc_param[param->type]);
2596 i965_reference_buffer_store(&encode->misc_param[param->type], obj_buffer->buffer_store);
2598 return VA_STATUS_SUCCESS;
2602 i965_encoder_render_picture(VADriverContextP ctx,
2603 VAContextID context,
2604 VABufferID *buffers,
2607 struct i965_driver_data *i965 = i965_driver_data(ctx);
2608 struct object_context *obj_context = CONTEXT(context);
2609 struct object_config *obj_config;
2610 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2611 struct encode_state *encode;
2614 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2615 obj_config = obj_context->obj_config;
2616 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2618 encode = &obj_context->codec_state.encode;
2619 for (i = 0; i < num_buffers; i++) {
2620 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2623 return VA_STATUS_ERROR_INVALID_BUFFER;
2625 switch (obj_buffer->type) {
2626 case VAQMatrixBufferType:
2627 vaStatus = I965_RENDER_ENCODE_BUFFER(qmatrix);
2630 case VAIQMatrixBufferType:
2631 vaStatus = I965_RENDER_ENCODE_BUFFER(iqmatrix);
2634 case VAEncSequenceParameterBufferType:
2635 vaStatus = I965_RENDER_ENCODE_BUFFER(sequence_parameter_ext);
2638 case VAEncPictureParameterBufferType:
2639 vaStatus = I965_RENDER_ENCODE_BUFFER(picture_parameter_ext);
2642 case VAHuffmanTableBufferType:
2643 vaStatus = I965_RENDER_ENCODE_BUFFER(huffman_table);
2646 case VAEncSliceParameterBufferType:
2647 vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
2648 if (vaStatus == VA_STATUS_SUCCESS) {
2649 /* When the max number of slices is updated, it also needs
2650 * to reallocate the arrays that is used to store
2651 * the packed data index/count for the slice
2653 if (!(encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE)) {
2654 encode->slice_index++;
2656 if (encode->slice_index == encode->max_slice_num) {
2657 int slice_num = encode->max_slice_num;
2658 encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
2659 (slice_num + NUM_SLICES) * sizeof(int));
2660 encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
2661 (slice_num + NUM_SLICES) * sizeof(int));
2662 encode->slice_header_index = realloc(encode->slice_header_index,
2663 (slice_num + NUM_SLICES) * sizeof(int));
2664 memset(encode->slice_rawdata_index + slice_num, 0,
2665 sizeof(int) * NUM_SLICES);
2666 memset(encode->slice_rawdata_count + slice_num, 0,
2667 sizeof(int) * NUM_SLICES);
2668 memset(encode->slice_header_index + slice_num, 0,
2669 sizeof(int) * NUM_SLICES);
2671 encode->max_slice_num += NUM_SLICES;
2672 if ((encode->slice_rawdata_index == NULL) ||
2673 (encode->slice_header_index == NULL) ||
2674 (encode->slice_rawdata_count == NULL)) {
2675 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2682 case VAEncPackedHeaderParameterBufferType:
2684 VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer;
2685 encode->last_packed_header_type = param->type;
2687 if ((param->type == VAEncPackedHeaderRawData) ||
2688 (param->type == VAEncPackedHeaderSlice)) {
2689 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext);
2690 } else if((obj_config->profile == VAProfileHEVCMain)&&
2691 (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
2692 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
2695 va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index);
2697 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
2700 va_enc_packed_type_to_idx(encode->last_packed_header_type));
2705 case VAEncPackedHeaderDataBufferType:
2707 if (encode->last_packed_header_type == 0) {
2708 WARN_ONCE("the packed header data is passed without type!\n");
2709 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
2712 if (encode->last_packed_header_type == VAEncPackedHeaderRawData ||
2713 encode->last_packed_header_type == VAEncPackedHeaderSlice) {
2714 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext);
2716 /* When the PACKED_SLICE_HEADER flag is passed, it will use
2717 * the packed_slice_header as the delimeter to decide how
2718 * the packed rawdata is inserted for the given slice.
2719 * Otherwise it will use the VAEncSequenceParameterBuffer
2722 if (encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) {
2723 /* store the first index of the packed header data for current slice */
2724 if (encode->slice_rawdata_index[encode->slice_index] == 0) {
2725 encode->slice_rawdata_index[encode->slice_index] =
2726 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
2728 encode->slice_rawdata_count[encode->slice_index]++;
2729 if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
2730 /* find one packed slice_header delimeter. And the following
2731 * packed data is for the next slice
2733 encode->slice_header_index[encode->slice_index] =
2734 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
2735 encode->slice_index++;
2736 /* Reallocate the buffer to record the index/count of
2737 * packed_data for one slice.
2739 if (encode->slice_index == encode->max_slice_num) {
2740 int slice_num = encode->max_slice_num;
2742 encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
2743 (slice_num + NUM_SLICES) * sizeof(int));
2744 encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
2745 (slice_num + NUM_SLICES) * sizeof(int));
2746 encode->slice_header_index = realloc(encode->slice_header_index,
2747 (slice_num + NUM_SLICES) * sizeof(int));
2748 memset(encode->slice_rawdata_index + slice_num, 0,
2749 sizeof(int) * NUM_SLICES);
2750 memset(encode->slice_rawdata_count + slice_num, 0,
2751 sizeof(int) * NUM_SLICES);
2752 memset(encode->slice_header_index + slice_num, 0,
2753 sizeof(int) * NUM_SLICES);
2754 encode->max_slice_num += NUM_SLICES;
2758 if (vaStatus == VA_STATUS_SUCCESS) {
2759 /* store the first index of the packed header data for current slice */
2760 if (encode->slice_rawdata_index[encode->slice_index] == 0) {
2761 encode->slice_rawdata_index[encode->slice_index] =
2762 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
2764 encode->slice_rawdata_count[encode->slice_index]++;
2765 if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
2766 if (encode->slice_header_index[encode->slice_index] == 0) {
2767 encode->slice_header_index[encode->slice_index] =
2768 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
2770 WARN_ONCE("Multi slice header data is passed for"
2771 " slice %d!\n", encode->slice_index);
2777 ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
2778 encode->last_packed_header_type == VAEncPackedHeaderPicture ||
2779 encode->last_packed_header_type == VAEncPackedHeaderSlice ||
2780 (((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) &&
2781 ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)),
2782 VA_STATUS_ERROR_ENCODING_ERROR);
2784 if((obj_config->profile == VAProfileHEVCMain)&&
2785 (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
2787 vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
2790 va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index);
2791 encode->vps_sps_seq_index = (encode->vps_sps_seq_index + 1) % I965_SEQ_PACKED_HEADER_END;
2793 vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
2796 va_enc_packed_type_to_idx(encode->last_packed_header_type));
2800 encode->last_packed_header_type = 0;
2804 case VAEncMiscParameterBufferType:
2805 vaStatus = i965_encoder_render_misc_parameter_buffer(ctx,
2811 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2819 #define I965_RENDER_PROC_BUFFER(name) I965_RENDER_BUFFER(proc, name)
2821 #define DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(proc, name, member)
2822 DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(pipeline_parameter, pipeline_param)
2825 i965_proc_render_picture(VADriverContextP ctx,
2826 VAContextID context,
2827 VABufferID *buffers,
2830 struct i965_driver_data *i965 = i965_driver_data(ctx);
2831 struct object_context *obj_context = CONTEXT(context);
2832 VAStatus vaStatus = VA_STATUS_SUCCESS;
2835 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2837 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2838 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2841 return VA_STATUS_ERROR_INVALID_BUFFER;
2843 switch (obj_buffer->type) {
2844 case VAProcPipelineParameterBufferType:
2845 vaStatus = I965_RENDER_PROC_BUFFER(pipeline_parameter);
2849 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2858 i965_RenderPicture(VADriverContextP ctx,
2859 VAContextID context,
2860 VABufferID *buffers,
2863 struct i965_driver_data *i965 = i965_driver_data(ctx);
2864 struct object_context *obj_context;
2865 struct object_config *obj_config;
2866 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2868 obj_context = CONTEXT(context);
2869 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2871 if (num_buffers <= 0)
2872 return VA_STATUS_ERROR_INVALID_PARAMETER;
2874 obj_config = obj_context->obj_config;
2875 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2877 if (VAEntrypointVideoProc == obj_config->entrypoint) {
2878 vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
2879 } else if ((VAEntrypointEncSlice == obj_config->entrypoint ) ||
2880 (VAEntrypointEncPicture == obj_config->entrypoint)) {
2881 vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
2883 vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
2890 i965_EndPicture(VADriverContextP ctx, VAContextID context)
2892 struct i965_driver_data *i965 = i965_driver_data(ctx);
2893 struct object_context *obj_context = CONTEXT(context);
2894 struct object_config *obj_config;
2896 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2897 obj_config = obj_context->obj_config;
2898 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2900 if (obj_context->codec_type == CODEC_PROC) {
2901 ASSERT_RET(VAEntrypointVideoProc == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
2902 } else if (obj_context->codec_type == CODEC_ENC) {
2903 ASSERT_RET(((VAEntrypointEncSlice == obj_config->entrypoint) || (VAEntrypointEncPicture == obj_config->entrypoint)), VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
2905 if (obj_context->codec_state.encode.num_packed_header_params_ext !=
2906 obj_context->codec_state.encode.num_packed_header_data_ext) {
2907 WARN_ONCE("the packed header/data is not paired for encoding!\n");
2908 return VA_STATUS_ERROR_INVALID_PARAMETER;
2910 if (!(obj_context->codec_state.encode.pic_param ||
2911 obj_context->codec_state.encode.pic_param_ext)) {
2912 return VA_STATUS_ERROR_INVALID_PARAMETER;
2914 if (!(obj_context->codec_state.encode.seq_param ||
2915 obj_context->codec_state.encode.seq_param_ext) &&
2916 (VAEntrypointEncPicture != obj_config->entrypoint)) {
2917 return VA_STATUS_ERROR_INVALID_PARAMETER;
2919 if ((obj_context->codec_state.encode.num_slice_params <=0) &&
2920 (obj_context->codec_state.encode.num_slice_params_ext <=0) &&
2921 (obj_config->profile != VAProfileVP8Version0_3)) {
2922 return VA_STATUS_ERROR_INVALID_PARAMETER;
2925 if ((obj_context->codec_state.encode.packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) &&
2926 (obj_context->codec_state.encode.num_slice_params_ext !=
2927 obj_context->codec_state.encode.slice_index)) {
2928 WARN_ONCE("packed slice_header data is missing for some slice"
2929 " under packed SLICE_HEADER mode\n");
2930 return VA_STATUS_ERROR_INVALID_PARAMETER;
2933 if (obj_context->codec_state.decode.pic_param == NULL) {
2934 return VA_STATUS_ERROR_INVALID_PARAMETER;
2936 if (obj_context->codec_state.decode.num_slice_params <=0) {
2937 return VA_STATUS_ERROR_INVALID_PARAMETER;
2939 if (obj_context->codec_state.decode.num_slice_datas <=0) {
2940 return VA_STATUS_ERROR_INVALID_PARAMETER;
2943 if (obj_context->codec_state.decode.num_slice_params !=
2944 obj_context->codec_state.decode.num_slice_datas) {
2945 return VA_STATUS_ERROR_INVALID_PARAMETER;
2949 ASSERT_RET(obj_context->hw_context->run, VA_STATUS_ERROR_OPERATION_FAILED);
2950 return obj_context->hw_context->run(ctx, obj_config->profile, &obj_context->codec_state, obj_context->hw_context);
2954 i965_SyncSurface(VADriverContextP ctx,
2955 VASurfaceID render_target)
2957 struct i965_driver_data *i965 = i965_driver_data(ctx);
2958 struct object_surface *obj_surface = SURFACE(render_target);
2960 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2963 drm_intel_bo_wait_rendering(obj_surface->bo);
2965 return VA_STATUS_SUCCESS;
2969 i965_QuerySurfaceStatus(VADriverContextP ctx,
2970 VASurfaceID render_target,
2971 VASurfaceStatus *status) /* out */
2973 struct i965_driver_data *i965 = i965_driver_data(ctx);
2974 struct object_surface *obj_surface = SURFACE(render_target);
2976 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2978 if (obj_surface->bo) {
2979 if (drm_intel_bo_busy(obj_surface->bo)){
2980 *status = VASurfaceRendering;
2983 *status = VASurfaceReady;
2986 *status = VASurfaceReady;
2989 return VA_STATUS_SUCCESS;
2992 static VADisplayAttribute *
2993 get_display_attribute(VADriverContextP ctx, VADisplayAttribType type)
2995 struct i965_driver_data * const i965 = i965_driver_data(ctx);
2998 if (!i965->display_attributes)
3001 for (i = 0; i < i965->num_display_attributes; i++) {
3002 if (i965->display_attributes[i].type == type)
3003 return &i965->display_attributes[i];
3009 i965_display_attributes_terminate(VADriverContextP ctx)
3011 struct i965_driver_data * const i965 = i965_driver_data(ctx);
3013 if (i965->display_attributes) {
3014 free(i965->display_attributes);
3015 i965->display_attributes = NULL;
3016 i965->num_display_attributes = 0;
3021 i965_display_attributes_init(VADriverContextP ctx)
3023 struct i965_driver_data * const i965 = i965_driver_data(ctx);
3025 i965->num_display_attributes = ARRAY_ELEMS(i965_display_attributes);
3026 i965->display_attributes = malloc(
3027 i965->num_display_attributes * sizeof(i965->display_attributes[0]));
3028 if (!i965->display_attributes)
3032 i965->display_attributes,
3033 i965_display_attributes,
3034 sizeof(i965_display_attributes)
3037 i965->rotation_attrib = get_display_attribute(ctx, VADisplayAttribRotation);
3038 i965->brightness_attrib = get_display_attribute(ctx, VADisplayAttribBrightness);
3039 i965->contrast_attrib = get_display_attribute(ctx, VADisplayAttribContrast);
3040 i965->hue_attrib = get_display_attribute(ctx, VADisplayAttribHue);
3041 i965->saturation_attrib = get_display_attribute(ctx, VADisplayAttribSaturation);
3043 if (!i965->rotation_attrib ||
3044 !i965->brightness_attrib ||
3045 !i965->contrast_attrib ||
3046 !i965->hue_attrib ||
3047 !i965->saturation_attrib) {
3053 i965_display_attributes_terminate(ctx);
3058 * Query display attributes
3059 * The caller must provide a "attr_list" array that can hold at
3060 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
3061 * returned in "attr_list" is returned in "num_attributes".
3064 i965_QueryDisplayAttributes(
3065 VADriverContextP ctx,
3066 VADisplayAttribute *attribs, /* out */
3067 int *num_attribs_ptr /* out */
3070 const int num_attribs = ARRAY_ELEMS(i965_display_attributes);
3072 if (attribs && num_attribs > 0)
3073 memcpy(attribs, i965_display_attributes, sizeof(i965_display_attributes));
3075 if (num_attribs_ptr)
3076 *num_attribs_ptr = num_attribs;
3078 return VA_STATUS_SUCCESS;
3082 * Get display attributes
3083 * This function returns the current attribute values in "attr_list".
3084 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
3085 * from vaQueryDisplayAttributes() can have their values retrieved.
3088 i965_GetDisplayAttributes(
3089 VADriverContextP ctx,
3090 VADisplayAttribute *attribs, /* inout */
3091 int num_attribs /* in */
3096 for (i = 0; i < num_attribs; i++) {
3097 VADisplayAttribute *src_attrib, * const dst_attrib = &attribs[i];
3099 src_attrib = get_display_attribute(ctx, dst_attrib->type);
3100 if (src_attrib && (src_attrib->flags & VA_DISPLAY_ATTRIB_GETTABLE)) {
3101 dst_attrib->min_value = src_attrib->min_value;
3102 dst_attrib->max_value = src_attrib->max_value;
3103 dst_attrib->value = src_attrib->value;
3106 dst_attrib->flags = VA_DISPLAY_ATTRIB_NOT_SUPPORTED;
3108 return VA_STATUS_SUCCESS;
3112 * Set display attributes
3113 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
3114 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
3115 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
3118 i965_SetDisplayAttributes(
3119 VADriverContextP ctx,
3120 VADisplayAttribute *attribs, /* in */
3121 int num_attribs /* in */
3126 for (i = 0; i < num_attribs; i++) {
3127 VADisplayAttribute *dst_attrib, * const src_attrib = &attribs[i];
3129 dst_attrib = get_display_attribute(ctx, src_attrib->type);
3131 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
3133 if (!(dst_attrib->flags & VA_DISPLAY_ATTRIB_SETTABLE))
3136 if (src_attrib->value < dst_attrib->min_value ||
3137 src_attrib->value > dst_attrib->max_value)
3138 return VA_STATUS_ERROR_INVALID_PARAMETER;
3140 dst_attrib->value = src_attrib->value;
3141 /* XXX: track modified attributes through timestamps */
3143 return VA_STATUS_SUCCESS;
3147 i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
3148 VASurfaceID surface,
3149 void **buffer, /* out */
3150 unsigned int *stride) /* out */
3153 return VA_STATUS_ERROR_UNIMPLEMENTED;
3157 i965_destroy_heap(struct object_heap *heap,
3158 void (*func)(struct object_heap *heap, struct object_base *object))
3160 struct object_base *object;
3161 object_heap_iterator iter;
3163 object = object_heap_first(heap, &iter);
3169 object = object_heap_next(heap, &iter);
3172 object_heap_destroy(heap);
3177 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
3180 i965_CreateImage(VADriverContextP ctx,
3181 VAImageFormat *format,
3184 VAImage *out_image) /* out */
3186 struct i965_driver_data *i965 = i965_driver_data(ctx);
3187 struct object_image *obj_image;
3188 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3190 unsigned int size2, size, awidth, aheight;
3192 out_image->image_id = VA_INVALID_ID;
3193 out_image->buf = VA_INVALID_ID;
3195 image_id = NEW_IMAGE_ID();
3196 if (image_id == VA_INVALID_ID)
3197 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3199 obj_image = IMAGE(image_id);
3201 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3202 obj_image->bo = NULL;
3203 obj_image->palette = NULL;
3204 obj_image->derived_surface = VA_INVALID_ID;
3206 VAImage * const image = &obj_image->image;
3207 image->image_id = image_id;
3208 image->buf = VA_INVALID_ID;
3210 awidth = ALIGN(width, i965->codec_info->min_linear_wpitch);
3212 if ((format->fourcc == VA_FOURCC_YV12) ||
3213 (format->fourcc == VA_FOURCC_I420)) {
3214 if (awidth % 128 != 0) {
3215 awidth = ALIGN(width, 128);
3219 aheight = ALIGN(height, i965->codec_info->min_linear_hpitch);
3220 size = awidth * aheight;
3221 size2 = (awidth / 2) * (aheight / 2);
3223 image->num_palette_entries = 0;
3224 image->entry_bytes = 0;
3225 memset(image->component_order, 0, sizeof(image->component_order));
3227 switch (format->fourcc) {
3228 case VA_FOURCC_IA44:
3229 case VA_FOURCC_AI44:
3230 image->num_planes = 1;
3231 image->pitches[0] = awidth;
3232 image->offsets[0] = 0;
3233 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
3234 image->num_palette_entries = 16;
3235 image->entry_bytes = 3;
3236 image->component_order[0] = 'R';
3237 image->component_order[1] = 'G';
3238 image->component_order[2] = 'B';
3240 case VA_FOURCC_IA88:
3241 case VA_FOURCC_AI88:
3242 image->num_planes = 1;
3243 image->pitches[0] = awidth * 2;
3244 image->offsets[0] = 0;
3245 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
3246 image->num_palette_entries = 256;
3247 image->entry_bytes = 3;
3248 image->component_order[0] = 'R';
3249 image->component_order[1] = 'G';
3250 image->component_order[2] = 'B';
3252 case VA_FOURCC_ARGB:
3253 case VA_FOURCC_ABGR:
3254 case VA_FOURCC_BGRA:
3255 case VA_FOURCC_RGBA:
3256 case VA_FOURCC_BGRX:
3257 case VA_FOURCC_RGBX:
3258 image->num_planes = 1;
3259 image->pitches[0] = awidth * 4;
3260 image->offsets[0] = 0;
3261 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
3263 case VA_FOURCC_YV12:
3264 image->num_planes = 3;
3265 image->pitches[0] = awidth;
3266 image->offsets[0] = 0;
3267 image->pitches[1] = awidth / 2;
3268 image->offsets[1] = size;
3269 image->pitches[2] = awidth / 2;
3270 image->offsets[2] = size + size2;
3271 image->data_size = size + 2 * size2;
3273 case VA_FOURCC_I420:
3274 image->num_planes = 3;
3275 image->pitches[0] = awidth;
3276 image->offsets[0] = 0;
3277 image->pitches[1] = awidth / 2;
3278 image->offsets[1] = size;
3279 image->pitches[2] = awidth / 2;
3280 image->offsets[2] = size + size2;
3281 image->data_size = size + 2 * size2;
3283 case VA_FOURCC_422H:
3284 image->num_planes = 3;
3285 image->pitches[0] = awidth;
3286 image->offsets[0] = 0;
3287 image->pitches[1] = awidth / 2;
3288 image->offsets[1] = size;
3289 image->pitches[2] = awidth / 2;
3290 image->offsets[2] = size + (awidth / 2) * aheight;
3291 image->data_size = size + 2 * ((awidth / 2) * aheight);
3293 case VA_FOURCC_NV12:
3294 image->num_planes = 2;
3295 image->pitches[0] = awidth;
3296 image->offsets[0] = 0;
3297 image->pitches[1] = awidth;
3298 image->offsets[1] = size;
3299 image->data_size = size + 2 * size2;
3301 case VA_FOURCC_YUY2:
3302 case VA_FOURCC_UYVY:
3303 image->num_planes = 1;
3304 image->pitches[0] = awidth * 2;
3305 image->offsets[0] = 0;
3306 image->data_size = size * 2;
3312 va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
3313 image->data_size, 1, NULL, &image->buf);
3314 if (va_status != VA_STATUS_SUCCESS)
3317 struct object_buffer *obj_buffer = BUFFER(image->buf);
3320 !obj_buffer->buffer_store ||
3321 !obj_buffer->buffer_store->bo)
3322 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3324 obj_image->bo = obj_buffer->buffer_store->bo;
3325 dri_bo_reference(obj_image->bo);
3327 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
3328 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
3329 if (!obj_image->palette)
3333 image->image_id = image_id;
3334 image->format = *format;
3335 image->width = width;
3336 image->height = height;
3338 *out_image = *image;
3339 return VA_STATUS_SUCCESS;
3342 i965_DestroyImage(ctx, image_id);
3347 i965_check_alloc_surface_bo(VADriverContextP ctx,
3348 struct object_surface *obj_surface,
3350 unsigned int fourcc,
3351 unsigned int subsampling)
3353 struct i965_driver_data *i965 = i965_driver_data(ctx);
3354 int region_width, region_height;
3356 if (obj_surface->bo) {
3357 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3358 ASSERT_RET(obj_surface->fourcc == fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3359 ASSERT_RET(obj_surface->subsampling == subsampling, VA_STATUS_ERROR_INVALID_SURFACE);
3360 return VA_STATUS_SUCCESS;
3363 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
3364 obj_surface->x_cr_offset = 0;
3366 if ((tiled && !obj_surface->user_disable_tiling)) {
3367 ASSERT_RET(fourcc != VA_FOURCC_I420 &&
3368 fourcc != VA_FOURCC_IYUV &&
3369 fourcc != VA_FOURCC_YV12,
3370 VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3371 if (obj_surface->user_h_stride_set) {
3372 ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
3374 obj_surface->width = ALIGN(obj_surface->orig_width, 128);
3376 if (obj_surface->user_v_stride_set) {
3377 ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
3379 obj_surface->height = ALIGN(obj_surface->orig_height, 32);
3381 region_height = obj_surface->height;
3384 case VA_FOURCC_NV12:
3385 assert(subsampling == SUBSAMPLE_YUV420);
3386 obj_surface->cb_cr_pitch = obj_surface->width;
3387 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3388 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3389 obj_surface->y_cb_offset = obj_surface->height;
3390 obj_surface->y_cr_offset = obj_surface->height;
3391 region_width = obj_surface->width;
3392 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
3396 case VA_FOURCC_IMC1:
3397 assert(subsampling == SUBSAMPLE_YUV420);
3398 obj_surface->cb_cr_pitch = obj_surface->width;
3399 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3400 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3401 obj_surface->y_cr_offset = obj_surface->height;
3402 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32);
3403 region_width = obj_surface->width;
3404 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3408 case VA_FOURCC_IMC3:
3409 assert(subsampling == SUBSAMPLE_YUV420);
3410 obj_surface->cb_cr_pitch = obj_surface->width;
3411 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3412 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3413 obj_surface->y_cb_offset = obj_surface->height;
3414 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3415 region_width = obj_surface->width;
3416 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3420 case VA_FOURCC_422H:
3421 assert(subsampling == SUBSAMPLE_YUV422H);
3422 obj_surface->cb_cr_pitch = obj_surface->width;
3423 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3424 obj_surface->cb_cr_height = obj_surface->orig_height;
3425 obj_surface->y_cb_offset = obj_surface->height;
3426 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3427 region_width = obj_surface->width;
3428 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3432 case VA_FOURCC_422V:
3433 assert(subsampling == SUBSAMPLE_YUV422V);
3434 obj_surface->cb_cr_pitch = obj_surface->width;
3435 obj_surface->cb_cr_width = obj_surface->orig_width;
3436 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3437 obj_surface->y_cb_offset = obj_surface->height;
3438 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3439 region_width = obj_surface->width;
3440 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3444 case VA_FOURCC_411P:
3445 assert(subsampling == SUBSAMPLE_YUV411);
3446 obj_surface->cb_cr_pitch = obj_surface->width;
3447 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
3448 obj_surface->cb_cr_height = obj_surface->orig_height;
3449 obj_surface->y_cb_offset = obj_surface->height;
3450 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3451 region_width = obj_surface->width;
3452 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3456 case VA_FOURCC_444P:
3457 assert(subsampling == SUBSAMPLE_YUV444);
3458 obj_surface->cb_cr_pitch = obj_surface->width;
3459 obj_surface->cb_cr_width = obj_surface->orig_width;
3460 obj_surface->cb_cr_height = obj_surface->orig_height;
3461 obj_surface->y_cb_offset = obj_surface->height;
3462 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3463 region_width = obj_surface->width;
3464 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3468 case VA_FOURCC_Y800:
3469 assert(subsampling == SUBSAMPLE_YUV400);
3470 obj_surface->cb_cr_pitch = 0;
3471 obj_surface->cb_cr_width = 0;
3472 obj_surface->cb_cr_height = 0;
3473 obj_surface->y_cb_offset = 0;
3474 obj_surface->y_cr_offset = 0;
3475 region_width = obj_surface->width;
3476 region_height = obj_surface->height;
3480 case VA_FOURCC_YUY2:
3481 case VA_FOURCC_UYVY:
3482 assert(subsampling == SUBSAMPLE_YUV422H);
3483 obj_surface->width = ALIGN(obj_surface->orig_width * 2, 128);
3484 obj_surface->cb_cr_pitch = obj_surface->width;
3485 obj_surface->y_cb_offset = 0;
3486 obj_surface->y_cr_offset = 0;
3487 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3488 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3489 region_width = obj_surface->width;
3490 region_height = obj_surface->height;
3494 case VA_FOURCC_RGBA:
3495 case VA_FOURCC_RGBX:
3496 case VA_FOURCC_BGRA:
3497 case VA_FOURCC_BGRX:
3498 assert(subsampling == SUBSAMPLE_RGBX);
3500 obj_surface->width = ALIGN(obj_surface->orig_width * 4, 128);
3501 region_width = obj_surface->width;
3502 region_height = obj_surface->height;
3506 /* Never get here */
3507 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3511 assert(subsampling == SUBSAMPLE_YUV420 ||
3512 subsampling == SUBSAMPLE_YUV422H ||
3513 subsampling == SUBSAMPLE_YUV422V ||
3514 subsampling == SUBSAMPLE_RGBX);
3516 region_width = obj_surface->width;
3517 region_height = obj_surface->height;
3520 case VA_FOURCC_NV12:
3521 obj_surface->y_cb_offset = obj_surface->height;
3522 obj_surface->y_cr_offset = obj_surface->height;
3523 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3524 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3525 obj_surface->cb_cr_pitch = obj_surface->width;
3526 region_height = obj_surface->height + obj_surface->height / 2;
3529 case VA_FOURCC_YV16:
3530 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3531 obj_surface->cb_cr_height = obj_surface->orig_height;
3532 obj_surface->y_cr_offset = obj_surface->height;
3533 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32) / 2;
3534 obj_surface->cb_cr_pitch = obj_surface->width / 2;
3535 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
3538 case VA_FOURCC_YV12:
3539 case VA_FOURCC_I420:
3540 if (fourcc == VA_FOURCC_YV12) {
3541 obj_surface->y_cr_offset = obj_surface->height;
3542 obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4;
3544 obj_surface->y_cb_offset = obj_surface->height;
3545 obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
3548 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3549 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3550 obj_surface->cb_cr_pitch = obj_surface->width / 2;
3551 region_height = obj_surface->height + obj_surface->height / 2;
3554 case VA_FOURCC_YUY2:
3555 case VA_FOURCC_UYVY:
3556 obj_surface->width = ALIGN(obj_surface->orig_width * 2, i965->codec_info->min_linear_wpitch);
3557 obj_surface->y_cb_offset = 0;
3558 obj_surface->y_cr_offset = 0;
3559 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3560 obj_surface->cb_cr_height = obj_surface->orig_height;
3561 obj_surface->cb_cr_pitch = obj_surface->width;
3562 region_width = obj_surface->width;
3563 region_height = obj_surface->height;
3565 case VA_FOURCC_RGBA:
3566 case VA_FOURCC_RGBX:
3567 case VA_FOURCC_BGRA:
3568 case VA_FOURCC_BGRX:
3569 obj_surface->width = ALIGN(obj_surface->orig_width * 4, i965->codec_info->min_linear_wpitch);
3570 region_width = obj_surface->width;
3571 region_height = obj_surface->height;
3575 /* Never get here */
3576 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3581 obj_surface->size = ALIGN(region_width * region_height, 0x1000);
3583 if ((tiled && !obj_surface->user_disable_tiling)) {
3584 uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
3585 unsigned long pitch;
3587 obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr,
3595 assert(tiling_mode == I915_TILING_Y);
3596 assert(pitch == obj_surface->width);
3598 obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
3604 obj_surface->fourcc = fourcc;
3605 obj_surface->subsampling = subsampling;
3606 assert(obj_surface->bo);
3607 return VA_STATUS_SUCCESS;
3610 VAStatus i965_DeriveImage(VADriverContextP ctx,
3611 VASurfaceID surface,
3612 VAImage *out_image) /* out */
3614 struct i965_driver_data *i965 = i965_driver_data(ctx);
3615 struct object_image *obj_image;
3616 struct object_surface *obj_surface;
3618 unsigned int w_pitch;
3619 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3621 out_image->image_id = VA_INVALID_ID;
3622 obj_surface = SURFACE(surface);
3625 return VA_STATUS_ERROR_INVALID_SURFACE;
3627 if (!obj_surface->bo) {
3628 unsigned int is_tiled = 0;
3629 unsigned int fourcc = VA_FOURCC_YV12;
3630 i965_guess_surface_format(ctx, surface, &fourcc, &is_tiled);
3631 int sampling = get_sampling_from_fourcc(fourcc);
3632 va_status = i965_check_alloc_surface_bo(ctx, obj_surface, is_tiled, fourcc, sampling);
3633 if (va_status != VA_STATUS_SUCCESS)
3637 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3639 w_pitch = obj_surface->width;
3641 image_id = NEW_IMAGE_ID();
3643 if (image_id == VA_INVALID_ID)
3644 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3646 obj_image = IMAGE(image_id);
3649 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3651 obj_image->bo = NULL;
3652 obj_image->palette = NULL;
3653 obj_image->derived_surface = VA_INVALID_ID;
3655 VAImage * const image = &obj_image->image;
3657 memset(image, 0, sizeof(*image));
3658 image->image_id = image_id;
3659 image->buf = VA_INVALID_ID;
3660 image->num_palette_entries = 0;
3661 image->entry_bytes = 0;
3662 image->width = obj_surface->orig_width;
3663 image->height = obj_surface->orig_height;
3664 image->data_size = obj_surface->size;
3666 image->format.fourcc = obj_surface->fourcc;
3667 image->format.byte_order = VA_LSB_FIRST;
3668 image->format.bits_per_pixel = 12;
3670 switch (image->format.fourcc) {
3671 case VA_FOURCC_YV12:
3672 image->num_planes = 3;
3673 image->pitches[0] = w_pitch; /* Y */
3674 image->offsets[0] = 0;
3675 image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
3676 image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
3677 image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
3678 image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
3681 case VA_FOURCC_YV16:
3682 image->num_planes = 3;
3683 image->pitches[0] = w_pitch; /* Y */
3684 image->offsets[0] = 0;
3685 image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
3686 image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
3687 image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
3688 image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
3691 case VA_FOURCC_NV12:
3692 image->num_planes = 2;
3693 image->pitches[0] = w_pitch; /* Y */
3694 image->offsets[0] = 0;
3695 image->pitches[1] = obj_surface->cb_cr_pitch; /* UV */
3696 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
3699 case VA_FOURCC_I420:
3700 case VA_FOURCC_422H:
3701 case VA_FOURCC_IMC3:
3702 case VA_FOURCC_444P:
3703 case VA_FOURCC_422V:
3704 case VA_FOURCC_411P:
3705 image->num_planes = 3;
3706 image->pitches[0] = w_pitch; /* Y */
3707 image->offsets[0] = 0;
3708 image->pitches[1] = obj_surface->cb_cr_pitch; /* U */
3709 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
3710 image->pitches[2] = obj_surface->cb_cr_pitch; /* V */
3711 image->offsets[2] = w_pitch * obj_surface->y_cr_offset;
3714 case VA_FOURCC_YUY2:
3715 case VA_FOURCC_UYVY:
3716 case VA_FOURCC_Y800:
3717 image->num_planes = 1;
3718 image->pitches[0] = obj_surface->width; /* Y, width is aligned already */
3719 image->offsets[0] = 0;
3721 case VA_FOURCC_RGBA:
3722 case VA_FOURCC_RGBX:
3723 case VA_FOURCC_BGRA:
3724 case VA_FOURCC_BGRX:
3725 image->num_planes = 1;
3726 image->pitches[0] = obj_surface->width;
3732 va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType,
3733 obj_surface->size, 1, NULL, obj_surface->bo, &image->buf);
3734 if (va_status != VA_STATUS_SUCCESS)
3737 struct object_buffer *obj_buffer = BUFFER(image->buf);
3740 !obj_buffer->buffer_store ||
3741 !obj_buffer->buffer_store->bo)
3742 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3744 obj_image->bo = obj_buffer->buffer_store->bo;
3745 dri_bo_reference(obj_image->bo);
3747 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
3748 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
3749 if (!obj_image->palette) {
3750 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
3755 *out_image = *image;
3756 obj_surface->flags |= SURFACE_DERIVED;
3757 obj_surface->derived_image_id = image_id;
3758 obj_image->derived_surface = surface;
3760 return VA_STATUS_SUCCESS;
3763 i965_DestroyImage(ctx, image_id);
3768 i965_destroy_image(struct object_heap *heap, struct object_base *obj)
3770 object_heap_free(heap, obj);
3775 i965_DestroyImage(VADriverContextP ctx, VAImageID image)
3777 struct i965_driver_data *i965 = i965_driver_data(ctx);
3778 struct object_image *obj_image = IMAGE(image);
3779 struct object_surface *obj_surface;
3782 return VA_STATUS_SUCCESS;
3784 dri_bo_unreference(obj_image->bo);
3785 obj_image->bo = NULL;
3787 if (obj_image->image.buf != VA_INVALID_ID) {
3788 i965_DestroyBuffer(ctx, obj_image->image.buf);
3789 obj_image->image.buf = VA_INVALID_ID;
3792 if (obj_image->palette) {
3793 free(obj_image->palette);
3794 obj_image->palette = NULL;
3797 obj_surface = SURFACE(obj_image->derived_surface);
3800 obj_surface->flags &= ~SURFACE_DERIVED;
3801 obj_surface->derived_image_id = VA_INVALID_ID;
3804 i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
3806 return VA_STATUS_SUCCESS;
3810 * pointer to an array holding the palette data. The size of the array is
3811 * num_palette_entries * entry_bytes in size. The order of the components
3812 * in the palette is described by the component_order in VASubpicture struct
3815 i965_SetImagePalette(VADriverContextP ctx,
3817 unsigned char *palette)
3819 struct i965_driver_data *i965 = i965_driver_data(ctx);
3822 struct object_image *obj_image = IMAGE(image);
3824 return VA_STATUS_ERROR_INVALID_IMAGE;
3826 if (!obj_image->palette)
3827 return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
3829 for (i = 0; i < obj_image->image.num_palette_entries; i++)
3830 obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
3831 ((unsigned int)palette[3*i + 1] << 8) |
3832 (unsigned int)palette[3*i + 2]);
3833 return VA_STATUS_SUCCESS;
3837 get_sampling_from_fourcc(unsigned int fourcc)
3839 const i965_fourcc_info *info = get_fourcc_info(fourcc);
3841 if (info && (info->flag & I_S))
3842 return info->subsampling;
3848 memcpy_pic(uint8_t *dst, unsigned int dst_stride,
3849 const uint8_t *src, unsigned int src_stride,
3850 unsigned int len, unsigned int height)
3854 for (i = 0; i < height; i++) {
3855 memcpy(dst, src, len);
3862 get_image_i420(struct object_image *obj_image, uint8_t *image_data,
3863 struct object_surface *obj_surface,
3864 const VARectangle *rect)
3866 uint8_t *dst[3], *src[3];
3868 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
3869 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
3870 unsigned int tiling, swizzle;
3871 VAStatus va_status = VA_STATUS_SUCCESS;
3873 if (!obj_surface->bo)
3874 return VA_STATUS_ERROR_INVALID_SURFACE;
3876 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3877 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3879 if (tiling != I915_TILING_NONE)
3880 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3882 dri_bo_map(obj_surface->bo, 0);
3884 if (!obj_surface->bo->virtual)
3885 return VA_STATUS_ERROR_INVALID_SURFACE;
3887 /* Dest VA image has either I420 or YV12 format.
3888 Source VA surface alway has I420 format */
3889 dst[Y] = image_data + obj_image->image.offsets[Y];
3890 src[0] = (uint8_t *)obj_surface->bo->virtual;
3891 dst[U] = image_data + obj_image->image.offsets[U];
3892 src[1] = src[0] + obj_surface->width * obj_surface->height;
3893 dst[V] = image_data + obj_image->image.offsets[V];
3894 src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
3897 dst[Y] += rect->y * obj_image->image.pitches[Y] + rect->x;
3898 src[0] += rect->y * obj_surface->width + rect->x;
3899 memcpy_pic(dst[Y], obj_image->image.pitches[Y],
3900 src[0], obj_surface->width,
3901 rect->width, rect->height);
3904 dst[U] += (rect->y / 2) * obj_image->image.pitches[U] + rect->x / 2;
3905 src[1] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
3906 memcpy_pic(dst[U], obj_image->image.pitches[U],
3907 src[1], obj_surface->width / 2,
3908 rect->width / 2, rect->height / 2);
3911 dst[V] += (rect->y / 2) * obj_image->image.pitches[V] + rect->x / 2;
3912 src[2] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
3913 memcpy_pic(dst[V], obj_image->image.pitches[V],
3914 src[2], obj_surface->width / 2,
3915 rect->width / 2, rect->height / 2);
3917 if (tiling != I915_TILING_NONE)
3918 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3920 dri_bo_unmap(obj_surface->bo);
3926 get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
3927 struct object_surface *obj_surface,
3928 const VARectangle *rect)
3930 uint8_t *dst[2], *src[2];
3931 unsigned int tiling, swizzle;
3932 VAStatus va_status = VA_STATUS_SUCCESS;
3934 if (!obj_surface->bo)
3935 return VA_STATUS_ERROR_INVALID_SURFACE;
3937 assert(obj_surface->fourcc);
3938 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3940 if (tiling != I915_TILING_NONE)
3941 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3943 dri_bo_map(obj_surface->bo, 0);
3945 if (!obj_surface->bo->virtual)
3946 return VA_STATUS_ERROR_INVALID_SURFACE;
3948 /* Both dest VA image and source surface have NV12 format */
3949 dst[0] = image_data + obj_image->image.offsets[0];
3950 src[0] = (uint8_t *)obj_surface->bo->virtual;
3951 dst[1] = image_data + obj_image->image.offsets[1];
3952 src[1] = src[0] + obj_surface->width * obj_surface->height;
3955 dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
3956 src[0] += rect->y * obj_surface->width + rect->x;
3957 memcpy_pic(dst[0], obj_image->image.pitches[0],
3958 src[0], obj_surface->width,
3959 rect->width, rect->height);
3962 dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + (rect->x & -2);
3963 src[1] += (rect->y / 2) * obj_surface->width + (rect->x & -2);
3964 memcpy_pic(dst[1], obj_image->image.pitches[1],
3965 src[1], obj_surface->width,
3966 rect->width, rect->height / 2);
3968 if (tiling != I915_TILING_NONE)
3969 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3971 dri_bo_unmap(obj_surface->bo);
3977 get_image_yuy2(struct object_image *obj_image, uint8_t *image_data,
3978 struct object_surface *obj_surface,
3979 const VARectangle *rect)
3982 unsigned int tiling, swizzle;
3983 VAStatus va_status = VA_STATUS_SUCCESS;
3985 if (!obj_surface->bo)
3986 return VA_STATUS_ERROR_INVALID_SURFACE;
3988 assert(obj_surface->fourcc);
3989 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3991 if (tiling != I915_TILING_NONE)
3992 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3994 dri_bo_map(obj_surface->bo, 0);
3996 if (!obj_surface->bo->virtual)
3997 return VA_STATUS_ERROR_INVALID_SURFACE;
3999 /* Both dest VA image and source surface have YUYV format */
4000 dst = image_data + obj_image->image.offsets[0];
4001 src = (uint8_t *)obj_surface->bo->virtual;
4004 dst += rect->y * obj_image->image.pitches[0] + rect->x*2;
4005 src += rect->y * obj_surface->width + rect->x*2;
4006 memcpy_pic(dst, obj_image->image.pitches[0],
4007 src, obj_surface->width*2,
4008 rect->width*2, rect->height);
4010 if (tiling != I915_TILING_NONE)
4011 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4013 dri_bo_unmap(obj_surface->bo);
4019 i965_sw_getimage(VADriverContextP ctx,
4020 struct object_surface *obj_surface, struct object_image *obj_image,
4021 const VARectangle *rect)
4023 struct i965_driver_data * const i965 = i965_driver_data(ctx);
4024 struct i965_render_state *render_state = &i965->render_state;
4025 void *image_data = NULL;
4028 if (obj_surface->fourcc != obj_image->image.format.fourcc)
4029 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
4031 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
4032 if (va_status != VA_STATUS_SUCCESS)
4035 switch (obj_image->image.format.fourcc) {
4036 case VA_FOURCC_YV12:
4037 case VA_FOURCC_I420:
4038 get_image_i420(obj_image, image_data, obj_surface, rect);
4040 case VA_FOURCC_NV12:
4041 get_image_nv12(obj_image, image_data, obj_surface, rect);
4043 case VA_FOURCC_YUY2:
4044 /* YUY2 is the format supported by overlay plane */
4045 get_image_yuy2(obj_image, image_data, obj_surface, rect);
4049 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
4052 if (va_status != VA_STATUS_SUCCESS)
4055 va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
4060 i965_hw_getimage(VADriverContextP ctx,
4061 struct object_surface *obj_surface, struct object_image *obj_image,
4062 const VARectangle *rect)
4064 struct i965_surface src_surface;
4065 struct i965_surface dst_surface;
4067 src_surface.base = (struct object_base *)obj_surface;
4068 src_surface.type = I965_SURFACE_TYPE_SURFACE;
4069 src_surface.flags = I965_SURFACE_FLAG_FRAME;
4071 dst_surface.base = (struct object_base *)obj_image;
4072 dst_surface.type = I965_SURFACE_TYPE_IMAGE;
4073 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4075 return i965_image_processing(ctx, &src_surface, rect, &dst_surface, rect);
4079 i965_GetImage(VADriverContextP ctx,
4080 VASurfaceID surface,
4081 int x, /* coordinates of the upper left source pixel */
4083 unsigned int width, /* width and height of the region */
4084 unsigned int height,
4087 struct i965_driver_data * const i965 = i965_driver_data(ctx);
4088 struct object_surface * const obj_surface = SURFACE(surface);
4089 struct object_image * const obj_image = IMAGE(image);
4094 return VA_STATUS_ERROR_INVALID_SURFACE;
4095 if (!obj_surface->bo) /* don't get anything, keep previous data */
4096 return VA_STATUS_SUCCESS;
4097 if (is_surface_busy(i965, obj_surface))
4098 return VA_STATUS_ERROR_SURFACE_BUSY;
4100 if (!obj_image || !obj_image->bo)
4101 return VA_STATUS_ERROR_INVALID_IMAGE;
4102 if (is_image_busy(i965, obj_image, surface))
4103 return VA_STATUS_ERROR_SURFACE_BUSY;
4106 return VA_STATUS_ERROR_INVALID_PARAMETER;
4107 if (x + width > obj_surface->orig_width ||
4108 y + height > obj_surface->orig_height)
4109 return VA_STATUS_ERROR_INVALID_PARAMETER;
4110 if (x + width > obj_image->image.width ||
4111 y + height > obj_image->image.height)
4112 return VA_STATUS_ERROR_INVALID_PARAMETER;
4117 rect.height = height;
4119 if (HAS_ACCELERATED_GETIMAGE(i965))
4120 va_status = i965_hw_getimage(ctx, obj_surface, obj_image, &rect);
4122 va_status = i965_sw_getimage(ctx, obj_surface, obj_image, &rect);
4128 put_image_i420(struct object_surface *obj_surface,
4129 const VARectangle *dst_rect,
4130 struct object_image *obj_image, uint8_t *image_data,
4131 const VARectangle *src_rect)
4133 uint8_t *dst[3], *src[3];
4135 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
4136 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
4137 unsigned int tiling, swizzle;
4138 VAStatus va_status = VA_STATUS_SUCCESS;
4140 ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
4142 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4143 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
4144 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
4145 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4147 if (tiling != I915_TILING_NONE)
4148 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4150 dri_bo_map(obj_surface->bo, 0);
4152 if (!obj_surface->bo->virtual)
4153 return VA_STATUS_ERROR_INVALID_SURFACE;
4155 /* Dest VA image has either I420 or YV12 format.
4156 Source VA surface alway has I420 format */
4157 dst[0] = (uint8_t *)obj_surface->bo->virtual;
4158 src[Y] = image_data + obj_image->image.offsets[Y];
4159 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
4160 src[U] = image_data + obj_image->image.offsets[U];
4161 dst[2] = dst[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
4162 src[V] = image_data + obj_image->image.offsets[V];
4165 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
4166 src[Y] += src_rect->y * obj_image->image.pitches[Y] + src_rect->x;
4167 memcpy_pic(dst[0], obj_surface->width,
4168 src[Y], obj_image->image.pitches[Y],
4169 src_rect->width, src_rect->height);
4172 dst[1] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
4173 src[U] += (src_rect->y / 2) * obj_image->image.pitches[U] + src_rect->x / 2;
4174 memcpy_pic(dst[1], obj_surface->width / 2,
4175 src[U], obj_image->image.pitches[U],
4176 src_rect->width / 2, src_rect->height / 2);
4179 dst[2] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
4180 src[V] += (src_rect->y / 2) * obj_image->image.pitches[V] + src_rect->x / 2;
4181 memcpy_pic(dst[2], obj_surface->width / 2,
4182 src[V], obj_image->image.pitches[V],
4183 src_rect->width / 2, src_rect->height / 2);
4185 if (tiling != I915_TILING_NONE)
4186 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4188 dri_bo_unmap(obj_surface->bo);
4194 put_image_nv12(struct object_surface *obj_surface,
4195 const VARectangle *dst_rect,
4196 struct object_image *obj_image, uint8_t *image_data,
4197 const VARectangle *src_rect)
4199 uint8_t *dst[2], *src[2];
4200 unsigned int tiling, swizzle;
4201 VAStatus va_status = VA_STATUS_SUCCESS;
4203 if (!obj_surface->bo)
4204 return VA_STATUS_ERROR_INVALID_SURFACE;
4206 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4207 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
4208 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
4209 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4211 if (tiling != I915_TILING_NONE)
4212 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4214 dri_bo_map(obj_surface->bo, 0);
4216 if (!obj_surface->bo->virtual)
4217 return VA_STATUS_ERROR_INVALID_SURFACE;
4219 /* Both dest VA image and source surface have NV12 format */
4220 dst[0] = (uint8_t *)obj_surface->bo->virtual;
4221 src[0] = image_data + obj_image->image.offsets[0];
4222 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
4223 src[1] = image_data + obj_image->image.offsets[1];
4226 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
4227 src[0] += src_rect->y * obj_image->image.pitches[0] + src_rect->x;
4228 memcpy_pic(dst[0], obj_surface->width,
4229 src[0], obj_image->image.pitches[0],
4230 src_rect->width, src_rect->height);
4233 dst[1] += (dst_rect->y / 2) * obj_surface->width + (dst_rect->x & -2);
4234 src[1] += (src_rect->y / 2) * obj_image->image.pitches[1] + (src_rect->x & -2);
4235 memcpy_pic(dst[1], obj_surface->width,
4236 src[1], obj_image->image.pitches[1],
4237 src_rect->width, src_rect->height / 2);
4239 if (tiling != I915_TILING_NONE)
4240 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4242 dri_bo_unmap(obj_surface->bo);
4248 put_image_yuy2(struct object_surface *obj_surface,
4249 const VARectangle *dst_rect,
4250 struct object_image *obj_image, uint8_t *image_data,
4251 const VARectangle *src_rect)
4254 unsigned int tiling, swizzle;
4255 VAStatus va_status = VA_STATUS_SUCCESS;
4257 ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
4258 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4259 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
4260 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
4261 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4263 if (tiling != I915_TILING_NONE)
4264 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4266 dri_bo_map(obj_surface->bo, 0);
4268 if (!obj_surface->bo->virtual)
4269 return VA_STATUS_ERROR_INVALID_SURFACE;
4271 /* Both dest VA image and source surface have YUY2 format */
4272 dst = (uint8_t *)obj_surface->bo->virtual;
4273 src = image_data + obj_image->image.offsets[0];
4275 /* YUYV packed plane */
4276 dst += dst_rect->y * obj_surface->width + dst_rect->x*2;
4277 src += src_rect->y * obj_image->image.pitches[0] + src_rect->x*2;
4278 memcpy_pic(dst, obj_surface->width*2,
4279 src, obj_image->image.pitches[0],
4280 src_rect->width*2, src_rect->height);
4282 if (tiling != I915_TILING_NONE)
4283 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4285 dri_bo_unmap(obj_surface->bo);
4291 i965_sw_putimage(VADriverContextP ctx,
4292 struct object_surface *obj_surface, struct object_image *obj_image,
4293 const VARectangle *src_rect, const VARectangle *dst_rect)
4295 VAStatus va_status = VA_STATUS_SUCCESS;
4296 void *image_data = NULL;
4298 /* XXX: don't allow scaling */
4299 if (src_rect->width != dst_rect->width ||
4300 src_rect->height != dst_rect->height)
4301 return VA_STATUS_ERROR_INVALID_PARAMETER;
4303 if (obj_surface->fourcc) {
4304 /* Don't allow format mismatch */
4305 if (obj_surface->fourcc != obj_image->image.format.fourcc)
4306 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
4310 /* VA is surface not used for decoding, use same VA image format */
4311 va_status = i965_check_alloc_surface_bo(
4314 0, /* XXX: don't use tiled surface */
4315 obj_image->image.format.fourcc,
4316 get_sampling_from_fourcc (obj_image->image.format.fourcc));
4319 if (va_status != VA_STATUS_SUCCESS)
4322 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
4323 if (va_status != VA_STATUS_SUCCESS)
4326 switch (obj_image->image.format.fourcc) {
4327 case VA_FOURCC_YV12:
4328 case VA_FOURCC_I420:
4329 va_status = put_image_i420(obj_surface, dst_rect, obj_image, image_data, src_rect);
4331 case VA_FOURCC_NV12:
4332 va_status = put_image_nv12(obj_surface, dst_rect, obj_image, image_data, src_rect);
4334 case VA_FOURCC_YUY2:
4335 va_status = put_image_yuy2(obj_surface, dst_rect, obj_image, image_data, src_rect);
4338 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
4341 if (va_status != VA_STATUS_SUCCESS)
4344 va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
4349 i965_hw_putimage(VADriverContextP ctx,
4350 struct object_surface *obj_surface, struct object_image *obj_image,
4351 const VARectangle *src_rect, const VARectangle *dst_rect)
4353 struct i965_surface src_surface, dst_surface;
4354 VAStatus va_status = VA_STATUS_SUCCESS;
4356 if (!obj_surface->bo) {
4357 unsigned int tiling, swizzle;
4358 int surface_sampling = get_sampling_from_fourcc (obj_image->image.format.fourcc);;
4359 dri_bo_get_tiling(obj_image->bo, &tiling, &swizzle);
4361 i965_check_alloc_surface_bo(ctx,
4364 obj_image->image.format.fourcc,
4368 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4370 src_surface.base = (struct object_base *)obj_image;
4371 src_surface.type = I965_SURFACE_TYPE_IMAGE;
4372 src_surface.flags = I965_SURFACE_FLAG_FRAME;
4374 dst_surface.base = (struct object_base *)obj_surface;
4375 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4376 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4378 va_status = i965_image_processing(ctx,
4388 i965_PutImage(VADriverContextP ctx,
4389 VASurfaceID surface,
4393 unsigned int src_width,
4394 unsigned int src_height,
4397 unsigned int dest_width,
4398 unsigned int dest_height)
4400 struct i965_driver_data * const i965 = i965_driver_data(ctx);
4401 struct object_surface * const obj_surface = SURFACE(surface);
4402 struct object_image * const obj_image = IMAGE(image);
4403 VARectangle src_rect, dst_rect;
4407 return VA_STATUS_ERROR_INVALID_SURFACE;
4408 if (is_surface_busy(i965, obj_surface))
4409 return VA_STATUS_ERROR_SURFACE_BUSY;
4411 if (!obj_image || !obj_image->bo)
4412 return VA_STATUS_ERROR_INVALID_IMAGE;
4413 if (is_image_busy(i965, obj_image, surface))
4414 return VA_STATUS_ERROR_SURFACE_BUSY;
4418 src_x + src_width > obj_image->image.width ||
4419 src_y + src_height > obj_image->image.height)
4420 return VA_STATUS_ERROR_INVALID_PARAMETER;
4424 src_rect.width = src_width;
4425 src_rect.height = src_height;
4429 dest_x + dest_width > obj_surface->orig_width ||
4430 dest_y + dest_height > obj_surface->orig_height)
4431 return VA_STATUS_ERROR_INVALID_PARAMETER;
4433 dst_rect.x = dest_x;
4434 dst_rect.y = dest_y;
4435 dst_rect.width = dest_width;
4436 dst_rect.height = dest_height;
4438 if (HAS_ACCELERATED_PUTIMAGE(i965))
4439 va_status = i965_hw_putimage(ctx, obj_surface, obj_image,
4440 &src_rect, &dst_rect);
4442 va_status = i965_sw_putimage(ctx, obj_surface, obj_image,
4443 &src_rect, &dst_rect);
4449 i965_PutSurface(VADriverContextP ctx,
4450 VASurfaceID surface,
4451 void *draw, /* X Drawable */
4454 unsigned short srcw,
4455 unsigned short srch,
4458 unsigned short destw,
4459 unsigned short desth,
4460 VARectangle *cliprects, /* client supplied clip list */
4461 unsigned int number_cliprects, /* number of clip rects in the clip list */
4462 unsigned int flags) /* de-interlacing flags */
4465 if (IS_VA_X11(ctx)) {
4466 VARectangle src_rect, dst_rect;
4470 src_rect.width = srcw;
4471 src_rect.height = srch;
4475 dst_rect.width = destw;
4476 dst_rect.height = desth;
4478 return i965_put_surface_dri(ctx, surface, draw, &src_rect, &dst_rect,
4479 cliprects, number_cliprects, flags);
4482 return VA_STATUS_ERROR_UNIMPLEMENTED;
4487 VADriverContextP ctx, /* in */
4488 VABufferID buf_id, /* in */
4489 VABufferType *type, /* out */
4490 unsigned int *size, /* out */
4491 unsigned int *num_elements /* out */
4494 struct i965_driver_data *i965 = NULL;
4495 struct object_buffer *obj_buffer = NULL;
4497 i965 = i965_driver_data(ctx);
4498 obj_buffer = BUFFER(buf_id);
4500 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
4502 *type = obj_buffer->type;
4503 *size = obj_buffer->size_element;
4504 *num_elements = obj_buffer->num_elements;
4506 return VA_STATUS_SUCCESS;
4511 VADriverContextP ctx, /* in */
4512 VASurfaceID surface, /* in */
4513 unsigned int *fourcc, /* out */
4514 unsigned int *luma_stride, /* out */
4515 unsigned int *chroma_u_stride, /* out */
4516 unsigned int *chroma_v_stride, /* out */
4517 unsigned int *luma_offset, /* out */
4518 unsigned int *chroma_u_offset, /* out */
4519 unsigned int *chroma_v_offset, /* out */
4520 unsigned int *buffer_name, /* out */
4521 void **buffer /* out */
4524 VAStatus vaStatus = VA_STATUS_SUCCESS;
4525 struct i965_driver_data *i965 = i965_driver_data(ctx);
4526 struct object_surface *obj_surface = NULL;
4529 ASSERT_RET(fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
4530 ASSERT_RET(luma_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4531 ASSERT_RET(chroma_u_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4532 ASSERT_RET(chroma_v_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4533 ASSERT_RET(luma_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4534 ASSERT_RET(chroma_u_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4535 ASSERT_RET(chroma_v_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4536 ASSERT_RET(buffer_name, VA_STATUS_ERROR_INVALID_PARAMETER);
4537 ASSERT_RET(buffer, VA_STATUS_ERROR_INVALID_PARAMETER);
4539 tmpImage.image_id = VA_INVALID_ID;
4541 obj_surface = SURFACE(surface);
4542 if (obj_surface == NULL) {
4543 // Surface is absent.
4544 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4548 // Lock functionality is absent now.
4549 if (obj_surface->locked_image_id != VA_INVALID_ID) {
4550 // Surface is locked already.
4551 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4555 vaStatus = i965_DeriveImage(
4559 if (vaStatus != VA_STATUS_SUCCESS) {
4563 obj_surface->locked_image_id = tmpImage.image_id;
4565 vaStatus = i965_MapBuffer(
4569 if (vaStatus != VA_STATUS_SUCCESS) {
4573 *fourcc = tmpImage.format.fourcc;
4574 *luma_offset = tmpImage.offsets[0];
4575 *luma_stride = tmpImage.pitches[0];
4576 *chroma_u_offset = tmpImage.offsets[1];
4577 *chroma_u_stride = tmpImage.pitches[1];
4578 *chroma_v_offset = tmpImage.offsets[2];
4579 *chroma_v_stride = tmpImage.pitches[2];
4580 *buffer_name = tmpImage.buf;
4583 if (vaStatus != VA_STATUS_SUCCESS) {
4592 VADriverContextP ctx, /* in */
4593 VASurfaceID surface /* in */
4596 VAStatus vaStatus = VA_STATUS_SUCCESS;
4597 struct i965_driver_data *i965 = i965_driver_data(ctx);
4598 struct object_image *locked_img = NULL;
4599 struct object_surface *obj_surface = NULL;
4601 obj_surface = SURFACE(surface);
4603 if (obj_surface == NULL) {
4604 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is absent
4607 if (obj_surface->locked_image_id == VA_INVALID_ID) {
4608 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is not locked
4612 locked_img = IMAGE(obj_surface->locked_image_id);
4613 if (locked_img == NULL || (locked_img->image.image_id == VA_INVALID_ID)) {
4614 // Work image was deallocated before i965_UnlockSurface()
4615 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4619 vaStatus = i965_UnmapBuffer(
4621 locked_img->image.buf);
4622 if (vaStatus != VA_STATUS_SUCCESS) {
4626 vaStatus = i965_DestroyImage(
4628 locked_img->image.image_id);
4629 if (vaStatus != VA_STATUS_SUCCESS) {
4633 locked_img->image.image_id = VA_INVALID_ID;
4636 obj_surface->locked_image_id = VA_INVALID_ID;
4642 i965_GetSurfaceAttributes(
4643 VADriverContextP ctx,
4645 VASurfaceAttrib *attrib_list,
4646 unsigned int num_attribs
4649 VAStatus vaStatus = VA_STATUS_SUCCESS;
4650 struct i965_driver_data *i965 = i965_driver_data(ctx);
4651 struct object_config *obj_config;
4654 if (config == VA_INVALID_ID)
4655 return VA_STATUS_ERROR_INVALID_CONFIG;
4657 obj_config = CONFIG(config);
4659 if (obj_config == NULL)
4660 return VA_STATUS_ERROR_INVALID_CONFIG;
4662 if (attrib_list == NULL || num_attribs == 0)
4663 return VA_STATUS_ERROR_INVALID_PARAMETER;
4665 for (i = 0; i < num_attribs; i++) {
4666 switch (attrib_list[i].type) {
4667 case VASurfaceAttribPixelFormat:
4668 attrib_list[i].value.type = VAGenericValueTypeInteger;
4669 attrib_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4671 if (attrib_list[i].value.value.i == 0) {
4672 if (IS_G4X(i965->intel.device_info)) {
4673 if (obj_config->profile == VAProfileMPEG2Simple ||
4674 obj_config->profile == VAProfileMPEG2Main) {
4675 attrib_list[i].value.value.i = VA_FOURCC_I420;
4678 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4680 } else if (IS_IRONLAKE(i965->intel.device_info)) {
4681 if (obj_config->profile == VAProfileMPEG2Simple ||
4682 obj_config->profile == VAProfileMPEG2Main) {
4683 attrib_list[i].value.value.i = VA_FOURCC_I420;
4684 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
4685 obj_config->profile == VAProfileH264Main ||
4686 obj_config->profile == VAProfileH264High) {
4687 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4688 } else if (obj_config->profile == VAProfileNone) {
4689 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4692 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4694 } else if (IS_GEN6(i965->intel.device_info)) {
4695 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4696 } else if (IS_GEN7(i965->intel.device_info) ||
4697 IS_GEN8(i965->intel.device_info) ||
4698 IS_GEN9(i965->intel.device_info)) {
4699 if (obj_config->profile == VAProfileJPEGBaseline)
4700 attrib_list[i].value.value.i = 0; /* internal format */
4702 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4705 if (IS_G4X(i965->intel.device_info)) {
4706 if (obj_config->profile == VAProfileMPEG2Simple ||
4707 obj_config->profile == VAProfileMPEG2Main) {
4708 if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
4709 attrib_list[i].value.value.i = 0;
4710 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4714 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4716 } else if (IS_IRONLAKE(i965->intel.device_info)) {
4717 if (obj_config->profile == VAProfileMPEG2Simple ||
4718 obj_config->profile == VAProfileMPEG2Main) {
4719 if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
4720 attrib_list[i].value.value.i = 0;
4721 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4723 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
4724 obj_config->profile == VAProfileH264Main ||
4725 obj_config->profile == VAProfileH264High) {
4726 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4727 attrib_list[i].value.value.i = 0;
4728 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4730 } else if (obj_config->profile == VAProfileNone) {
4731 switch (attrib_list[i].value.value.i) {
4732 case VA_FOURCC_NV12:
4733 case VA_FOURCC_I420:
4734 case VA_FOURCC_YV12:
4735 case VA_FOURCC_YUY2:
4736 case VA_FOURCC_BGRA:
4737 case VA_FOURCC_BGRX:
4738 case VA_FOURCC_RGBX:
4739 case VA_FOURCC_RGBA:
4742 attrib_list[i].value.value.i = 0;
4743 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4748 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4750 } else if (IS_GEN6(i965->intel.device_info)) {
4751 if (obj_config->entrypoint == VAEntrypointEncSlice ||
4752 obj_config->entrypoint == VAEntrypointVideoProc) {
4753 switch (attrib_list[i].value.value.i) {
4754 case VA_FOURCC_NV12:
4755 case VA_FOURCC_I420:
4756 case VA_FOURCC_YV12:
4757 case VA_FOURCC_YUY2:
4758 case VA_FOURCC_BGRA:
4759 case VA_FOURCC_BGRX:
4760 case VA_FOURCC_RGBX:
4761 case VA_FOURCC_RGBA:
4764 attrib_list[i].value.value.i = 0;
4765 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4769 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4770 attrib_list[i].value.value.i = 0;
4771 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4774 } else if (IS_GEN7(i965->intel.device_info) ||
4775 IS_GEN8(i965->intel.device_info) ||
4776 IS_GEN9(i965->intel.device_info)) {
4777 if (obj_config->entrypoint == VAEntrypointEncSlice ||
4778 obj_config->entrypoint == VAEntrypointVideoProc) {
4779 switch (attrib_list[i].value.value.i) {
4780 case VA_FOURCC_NV12:
4781 case VA_FOURCC_I420:
4782 case VA_FOURCC_YV12:
4785 attrib_list[i].value.value.i = 0;
4786 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4790 if (obj_config->profile == VAProfileJPEGBaseline) {
4791 attrib_list[i].value.value.i = 0; /* JPEG decoding always uses an internal format */
4792 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4794 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4795 attrib_list[i].value.value.i = 0;
4796 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4804 case VASurfaceAttribMinWidth:
4805 /* FIXME: add support for it later */
4806 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4808 case VASurfaceAttribMaxWidth:
4809 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4811 case VASurfaceAttribMinHeight:
4812 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4814 case VASurfaceAttribMaxHeight:
4815 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4818 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4827 i965_QuerySurfaceAttributes(VADriverContextP ctx,
4829 VASurfaceAttrib *attrib_list,
4830 unsigned int *num_attribs)
4832 VAStatus vaStatus = VA_STATUS_SUCCESS;
4833 struct i965_driver_data *i965 = i965_driver_data(ctx);
4834 struct object_config *obj_config;
4836 VASurfaceAttrib *attribs = NULL;
4838 if (config == VA_INVALID_ID)
4839 return VA_STATUS_ERROR_INVALID_CONFIG;
4841 obj_config = CONFIG(config);
4843 if (obj_config == NULL)
4844 return VA_STATUS_ERROR_INVALID_CONFIG;
4846 if (!attrib_list && !num_attribs)
4847 return VA_STATUS_ERROR_INVALID_PARAMETER;
4849 if (attrib_list == NULL) {
4850 *num_attribs = I965_MAX_SURFACE_ATTRIBUTES;
4851 return VA_STATUS_SUCCESS;
4854 attribs = malloc(I965_MAX_SURFACE_ATTRIBUTES *sizeof(*attribs));
4856 if (attribs == NULL)
4857 return VA_STATUS_ERROR_ALLOCATION_FAILED;
4859 if (IS_G4X(i965->intel.device_info)) {
4860 if (obj_config->profile == VAProfileMPEG2Simple ||
4861 obj_config->profile == VAProfileMPEG2Main) {
4862 attribs[i].type = VASurfaceAttribPixelFormat;
4863 attribs[i].value.type = VAGenericValueTypeInteger;
4864 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4865 attribs[i].value.value.i = VA_FOURCC_I420;
4868 } else if (IS_IRONLAKE(i965->intel.device_info)) {
4869 switch (obj_config->profile) {
4870 case VAProfileMPEG2Simple:
4871 case VAProfileMPEG2Main:
4872 attribs[i].type = VASurfaceAttribPixelFormat;
4873 attribs[i].value.type = VAGenericValueTypeInteger;
4874 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4875 attribs[i].value.value.i = VA_FOURCC_I420;
4880 case VAProfileH264ConstrainedBaseline:
4881 case VAProfileH264Main:
4882 case VAProfileH264High:
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_NV12;
4890 attribs[i].type = VASurfaceAttribPixelFormat;
4891 attribs[i].value.type = VAGenericValueTypeInteger;
4892 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4893 attribs[i].value.value.i = VA_FOURCC_NV12;
4896 attribs[i].type = VASurfaceAttribPixelFormat;
4897 attribs[i].value.type = VAGenericValueTypeInteger;
4898 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4899 attribs[i].value.value.i = VA_FOURCC_I420;
4907 } else if (IS_GEN6(i965->intel.device_info)) {
4908 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4909 attribs[i].type = VASurfaceAttribPixelFormat;
4910 attribs[i].value.type = VAGenericValueTypeInteger;
4911 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4912 attribs[i].value.value.i = VA_FOURCC_NV12;
4914 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
4915 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4916 attribs[i].type = VASurfaceAttribPixelFormat;
4917 attribs[i].value.type = VAGenericValueTypeInteger;
4918 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4919 attribs[i].value.value.i = VA_FOURCC_NV12;
4922 attribs[i].type = VASurfaceAttribPixelFormat;
4923 attribs[i].value.type = VAGenericValueTypeInteger;
4924 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4925 attribs[i].value.value.i = VA_FOURCC_I420;
4928 attribs[i].type = VASurfaceAttribPixelFormat;
4929 attribs[i].value.type = VAGenericValueTypeInteger;
4930 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4931 attribs[i].value.value.i = VA_FOURCC_YV12;
4934 if (obj_config->entrypoint == VAEntrypointVideoProc) {
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_YUY2;
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_RGBA;
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_RGBX;
4954 } else if (IS_GEN7(i965->intel.device_info)) {
4955 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4956 if (obj_config->profile == VAProfileJPEGBaseline) {
4957 attribs[i].type = VASurfaceAttribPixelFormat;
4958 attribs[i].value.type = VAGenericValueTypeInteger;
4959 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4960 attribs[i].value.value.i = VA_FOURCC_IMC3;
4963 attribs[i].type = VASurfaceAttribPixelFormat;
4964 attribs[i].value.type = VAGenericValueTypeInteger;
4965 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4966 attribs[i].value.value.i = VA_FOURCC_IMC1;
4969 attribs[i].type = VASurfaceAttribPixelFormat;
4970 attribs[i].value.type = VAGenericValueTypeInteger;
4971 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4972 attribs[i].value.value.i = VA_FOURCC_Y800;
4975 attribs[i].type = VASurfaceAttribPixelFormat;
4976 attribs[i].value.type = VAGenericValueTypeInteger;
4977 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4978 attribs[i].value.value.i = VA_FOURCC_411P;
4981 attribs[i].type = VASurfaceAttribPixelFormat;
4982 attribs[i].value.type = VAGenericValueTypeInteger;
4983 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4984 attribs[i].value.value.i = VA_FOURCC_422H;
4987 attribs[i].type = VASurfaceAttribPixelFormat;
4988 attribs[i].value.type = VAGenericValueTypeInteger;
4989 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4990 attribs[i].value.value.i = VA_FOURCC_422V;
4993 attribs[i].type = VASurfaceAttribPixelFormat;
4994 attribs[i].value.type = VAGenericValueTypeInteger;
4995 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4996 attribs[i].value.value.i = VA_FOURCC_444P;
4999 attribs[i].type = VASurfaceAttribPixelFormat;
5000 attribs[i].value.type = VAGenericValueTypeInteger;
5001 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5002 attribs[i].value.value.i = VA_FOURCC_NV12;
5005 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
5006 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
5007 attribs[i].type = VASurfaceAttribPixelFormat;
5008 attribs[i].value.type = VAGenericValueTypeInteger;
5009 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5010 attribs[i].value.value.i = VA_FOURCC_NV12;
5013 attribs[i].type = VASurfaceAttribPixelFormat;
5014 attribs[i].value.type = VAGenericValueTypeInteger;
5015 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5016 attribs[i].value.value.i = VA_FOURCC_I420;
5019 attribs[i].type = VASurfaceAttribPixelFormat;
5020 attribs[i].value.type = VAGenericValueTypeInteger;
5021 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5022 attribs[i].value.value.i = VA_FOURCC_YV12;
5025 attribs[i].type = VASurfaceAttribPixelFormat;
5026 attribs[i].value.type = VAGenericValueTypeInteger;
5027 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5028 attribs[i].value.value.i = VA_FOURCC_IMC3;
5031 if (obj_config->entrypoint == VAEntrypointVideoProc) {
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_YUY2;
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_RGBA;
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_RGBX;
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_BGRA;
5056 attribs[i].type = VASurfaceAttribPixelFormat;
5057 attribs[i].value.type = VAGenericValueTypeInteger;
5058 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5059 attribs[i].value.value.i = VA_FOURCC_BGRX;
5062 attribs[i].type = VASurfaceAttribPixelFormat;
5063 attribs[i].value.type = VAGenericValueTypeInteger;
5064 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5065 attribs[i].value.value.i = VA_FOURCC_YV16;
5069 } else if (IS_GEN8(i965->intel.device_info) ||
5070 IS_GEN9(i965->intel.device_info)) {
5071 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
5072 if (obj_config->profile == VAProfileJPEGBaseline) {
5073 attribs[i].type = VASurfaceAttribPixelFormat;
5074 attribs[i].value.type = VAGenericValueTypeInteger;
5075 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5076 attribs[i].value.value.i = VA_FOURCC_IMC3;
5079 attribs[i].type = VASurfaceAttribPixelFormat;
5080 attribs[i].value.type = VAGenericValueTypeInteger;
5081 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5082 attribs[i].value.value.i = VA_FOURCC_IMC1;
5085 attribs[i].type = VASurfaceAttribPixelFormat;
5086 attribs[i].value.type = VAGenericValueTypeInteger;
5087 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5088 attribs[i].value.value.i = VA_FOURCC_Y800;
5091 attribs[i].type = VASurfaceAttribPixelFormat;
5092 attribs[i].value.type = VAGenericValueTypeInteger;
5093 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5094 attribs[i].value.value.i = VA_FOURCC_411P;
5097 attribs[i].type = VASurfaceAttribPixelFormat;
5098 attribs[i].value.type = VAGenericValueTypeInteger;
5099 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5100 attribs[i].value.value.i = VA_FOURCC_422H;
5103 attribs[i].type = VASurfaceAttribPixelFormat;
5104 attribs[i].value.type = VAGenericValueTypeInteger;
5105 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5106 attribs[i].value.value.i = VA_FOURCC_422V;
5109 attribs[i].type = VASurfaceAttribPixelFormat;
5110 attribs[i].value.type = VAGenericValueTypeInteger;
5111 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5112 attribs[i].value.value.i = VA_FOURCC_444P;
5115 attribs[i].type = VASurfaceAttribPixelFormat;
5116 attribs[i].value.type = VAGenericValueTypeInteger;
5117 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5118 attribs[i].value.value.i = VA_FOURCC_NV12;
5121 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
5122 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
5124 attribs[i].type = VASurfaceAttribPixelFormat;
5125 attribs[i].value.type = VAGenericValueTypeInteger;
5126 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5127 attribs[i].value.value.i = VA_FOURCC_NV12;
5130 attribs[i].type = VASurfaceAttribPixelFormat;
5131 attribs[i].value.type = VAGenericValueTypeInteger;
5132 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5133 attribs[i].value.value.i = VA_FOURCC_I420;
5136 attribs[i].type = VASurfaceAttribPixelFormat;
5137 attribs[i].value.type = VAGenericValueTypeInteger;
5138 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5139 attribs[i].value.value.i = VA_FOURCC_YV12;
5142 attribs[i].type = VASurfaceAttribPixelFormat;
5143 attribs[i].value.type = VAGenericValueTypeInteger;
5144 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5145 attribs[i].value.value.i = VA_FOURCC_IMC3;
5148 if (obj_config->entrypoint == VAEntrypointVideoProc) {
5149 attribs[i].type = VASurfaceAttribPixelFormat;
5150 attribs[i].value.type = VAGenericValueTypeInteger;
5151 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5152 attribs[i].value.value.i = VA_FOURCC_YUY2;
5155 attribs[i].type = VASurfaceAttribPixelFormat;
5156 attribs[i].value.type = VAGenericValueTypeInteger;
5157 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5158 attribs[i].value.value.i = VA_FOURCC_RGBA;
5161 attribs[i].type = VASurfaceAttribPixelFormat;
5162 attribs[i].value.type = VAGenericValueTypeInteger;
5163 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5164 attribs[i].value.value.i = VA_FOURCC_RGBX;
5167 attribs[i].type = VASurfaceAttribPixelFormat;
5168 attribs[i].value.type = VAGenericValueTypeInteger;
5169 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5170 attribs[i].value.value.i = VA_FOURCC_BGRA;
5173 attribs[i].type = VASurfaceAttribPixelFormat;
5174 attribs[i].value.type = VAGenericValueTypeInteger;
5175 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5176 attribs[i].value.value.i = VA_FOURCC_BGRX;
5179 attribs[i].type = VASurfaceAttribPixelFormat;
5180 attribs[i].value.type = VAGenericValueTypeInteger;
5181 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5182 attribs[i].value.value.i = VA_FOURCC_YV16;
5188 attribs[i].type = VASurfaceAttribMemoryType;
5189 attribs[i].value.type = VAGenericValueTypeInteger;
5190 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5191 attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
5192 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
5193 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
5196 attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
5197 attribs[i].value.type = VAGenericValueTypePointer;
5198 attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
5199 attribs[i].value.value.p = NULL; /* ignore */
5202 attribs[i].type = VASurfaceAttribMaxWidth;
5203 attribs[i].value.type = VAGenericValueTypeInteger;
5204 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
5205 attribs[i].value.value.i = i965->codec_info->max_width;
5208 attribs[i].type = VASurfaceAttribMaxHeight;
5209 attribs[i].value.type = VAGenericValueTypeInteger;
5210 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
5211 attribs[i].value.value.i = i965->codec_info->max_height;
5214 if (i > *num_attribs) {
5217 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5221 memcpy(attrib_list, attribs, i * sizeof(*attribs));
5227 /* Acquires buffer handle for external API usage (internal implementation) */
5229 i965_acquire_buffer_handle(struct object_buffer *obj_buffer,
5230 uint32_t mem_type, VABufferInfo *out_buf_info)
5232 struct buffer_store *buffer_store;
5234 buffer_store = obj_buffer->buffer_store;
5235 if (!buffer_store || !buffer_store->bo)
5236 return VA_STATUS_ERROR_INVALID_BUFFER;
5238 /* Synchronization point */
5239 drm_intel_bo_wait_rendering(buffer_store->bo);
5241 if (obj_buffer->export_refcount > 0) {
5242 if (obj_buffer->export_state.mem_type != mem_type)
5243 return VA_STATUS_ERROR_INVALID_PARAMETER;
5246 VABufferInfo * const buf_info = &obj_buffer->export_state;
5249 case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: {
5251 if (drm_intel_bo_flink(buffer_store->bo, &name) != 0)
5252 return VA_STATUS_ERROR_INVALID_BUFFER;
5253 buf_info->handle = name;
5256 case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
5258 if (drm_intel_bo_gem_export_to_prime(buffer_store->bo, &fd) != 0)
5259 return VA_STATUS_ERROR_INVALID_BUFFER;
5260 buf_info->handle = (intptr_t)fd;
5265 buf_info->type = obj_buffer->type;
5266 buf_info->mem_type = mem_type;
5267 buf_info->mem_size =
5268 obj_buffer->num_elements * obj_buffer->size_element;
5271 obj_buffer->export_refcount++;
5272 *out_buf_info = obj_buffer->export_state;
5273 return VA_STATUS_SUCCESS;
5276 /* Releases buffer handle after usage (internal implementation) */
5278 i965_release_buffer_handle(struct object_buffer *obj_buffer)
5280 if (obj_buffer->export_refcount == 0)
5281 return VA_STATUS_ERROR_INVALID_BUFFER;
5283 if (--obj_buffer->export_refcount == 0) {
5284 VABufferInfo * const buf_info = &obj_buffer->export_state;
5286 switch (buf_info->mem_type) {
5287 case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
5288 close((intptr_t)buf_info->handle);
5292 buf_info->mem_type = 0;
5294 return VA_STATUS_SUCCESS;
5297 /** Acquires buffer handle for external API usage */
5299 i965_AcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
5300 VABufferInfo *buf_info)
5302 struct i965_driver_data * const i965 = i965_driver_data(ctx);
5303 struct object_buffer * const obj_buffer = BUFFER(buf_id);
5304 uint32_t i, mem_type;
5306 /* List of supported memory types, in preferred order */
5307 static const uint32_t mem_types[] = {
5308 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
5309 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM,
5314 return VA_STATUS_ERROR_INVALID_BUFFER;
5315 /* XXX: only VA surface|image like buffers are supported for now */
5316 if (obj_buffer->type != VAImageBufferType)
5317 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
5320 return VA_STATUS_ERROR_INVALID_PARAMETER;
5322 if (!buf_info->mem_type)
5323 mem_type = mem_types[0];
5326 for (i = 0; mem_types[i] != 0; i++) {
5327 if (buf_info->mem_type & mem_types[i]) {
5328 mem_type = buf_info->mem_type;
5333 return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
5335 return i965_acquire_buffer_handle(obj_buffer, mem_type, buf_info);
5338 /** Releases buffer handle after usage from external API */
5340 i965_ReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id)
5342 struct i965_driver_data * const i965 = i965_driver_data(ctx);
5343 struct object_buffer * const obj_buffer = BUFFER(buf_id);
5346 return VA_STATUS_ERROR_INVALID_BUFFER;
5348 return i965_release_buffer_handle(obj_buffer);
5352 i965_os_has_ring_support(VADriverContextP ctx,
5355 struct i965_driver_data *const i965 = i965_driver_data(ctx);
5359 return i965->intel.has_bsd;
5362 return i965->intel.has_blt;
5364 case I965_RING_VEBOX:
5365 return i965->intel.has_vebox;
5367 case I965_RING_NULL:
5368 return 1; /* Always support */
5371 /* should never get here */
5380 * Query video processing pipeline
5382 VAStatus i965_QueryVideoProcFilters(
5383 VADriverContextP ctx,
5384 VAContextID context,
5385 VAProcFilterType *filters,
5386 unsigned int *num_filters
5389 struct i965_driver_data *const i965 = i965_driver_data(ctx);
5390 unsigned int i = 0, num = 0;
5392 if (!num_filters || !filters)
5393 return VA_STATUS_ERROR_INVALID_PARAMETER;
5395 for (i = 0; i < i965->codec_info->num_filters; i++) {
5396 if (i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring)) {
5397 if (num == *num_filters) {
5398 *num_filters = i965->codec_info->num_filters;
5400 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5403 filters[num++] = i965->codec_info->filters[i].type;
5409 return VA_STATUS_SUCCESS;
5412 VAStatus i965_QueryVideoProcFilterCaps(
5413 VADriverContextP ctx,
5414 VAContextID context,
5415 VAProcFilterType type,
5417 unsigned int *num_filter_caps
5421 struct i965_driver_data *const i965 = i965_driver_data(ctx);
5423 if (!filter_caps || !num_filter_caps)
5424 return VA_STATUS_ERROR_INVALID_PARAMETER;
5426 for (i = 0; i < i965->codec_info->num_filters; i++) {
5427 if (type == i965->codec_info->filters[i].type &&
5428 i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring))
5432 if (i == i965->codec_info->num_filters)
5433 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
5438 case VAProcFilterNoiseReduction:
5439 case VAProcFilterSharpening:
5441 VAProcFilterCap *cap = filter_caps;
5443 if (*num_filter_caps < 1) {
5444 *num_filter_caps = 1;
5445 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5448 cap->range.min_value = 0.0;
5449 cap->range.max_value = 1.0;
5450 cap->range.default_value = 0.5;
5451 cap->range.step = 0.03125; /* 1.0 / 32 */
5457 case VAProcFilterDeinterlacing:
5459 VAProcFilterCapDeinterlacing *cap = filter_caps;
5461 if (*num_filter_caps < VAProcDeinterlacingCount) {
5462 *num_filter_caps = VAProcDeinterlacingCount;
5463 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5466 cap->type = VAProcDeinterlacingBob;
5471 if (i965->codec_info->has_di_motion_adptive) {
5472 cap->type = VAProcDeinterlacingMotionAdaptive;
5477 if (i965->codec_info->has_di_motion_compensated) {
5478 cap->type = VAProcDeinterlacingMotionCompensated;
5486 case VAProcFilterColorBalance:
5488 VAProcFilterCapColorBalance *cap = filter_caps;
5490 if (*num_filter_caps < VAProcColorBalanceCount) {
5491 *num_filter_caps = VAProcColorBalanceCount;
5492 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5495 cap->type = VAProcColorBalanceHue;
5496 cap->range.min_value = -180.0;
5497 cap->range.max_value = 180.0;
5498 cap->range.default_value = 0.0;
5499 cap->range.step = 1.0;
5503 cap->type = VAProcColorBalanceSaturation;
5504 cap->range.min_value = 0.0;
5505 cap->range.max_value = 10.0;
5506 cap->range.default_value = 1.0;
5507 cap->range.step = 0.1;
5511 cap->type = VAProcColorBalanceBrightness;
5512 cap->range.min_value = -100.0;
5513 cap->range.max_value = 100.0;
5514 cap->range.default_value = 0.0;
5515 cap->range.step = 1.0;
5519 cap->type = VAProcColorBalanceContrast;
5520 cap->range.min_value = 0.0;
5521 cap->range.max_value = 10.0;
5522 cap->range.default_value = 1.0;
5523 cap->range.step = 0.1;
5535 *num_filter_caps = i;
5537 return VA_STATUS_SUCCESS;
5540 static VAProcColorStandardType vpp_input_color_standards[VAProcColorStandardCount] = {
5541 VAProcColorStandardBT601,
5544 static VAProcColorStandardType vpp_output_color_standards[VAProcColorStandardCount] = {
5545 VAProcColorStandardBT601,
5548 VAStatus i965_QueryVideoProcPipelineCaps(
5549 VADriverContextP ctx,
5550 VAContextID context,
5551 VABufferID *filters,
5552 unsigned int num_filters,
5553 VAProcPipelineCaps *pipeline_cap /* out */
5556 struct i965_driver_data * const i965 = i965_driver_data(ctx);
5559 pipeline_cap->pipeline_flags = 0;
5560 pipeline_cap->filter_flags = 0;
5561 pipeline_cap->num_forward_references = 0;
5562 pipeline_cap->num_backward_references = 0;
5563 pipeline_cap->num_input_color_standards = 1;
5564 pipeline_cap->input_color_standards = vpp_input_color_standards;
5565 pipeline_cap->num_output_color_standards = 1;
5566 pipeline_cap->output_color_standards = vpp_output_color_standards;
5568 for (i = 0; i < num_filters; i++) {
5569 struct object_buffer *obj_buffer = BUFFER(filters[i]);
5572 !obj_buffer->buffer_store ||
5573 !obj_buffer->buffer_store->buffer)
5574 return VA_STATUS_ERROR_INVALID_BUFFER;
5576 VAProcFilterParameterBufferBase *base = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
5578 if (base->type == VAProcFilterNoiseReduction) {
5579 VAProcFilterParameterBuffer *denoise = (VAProcFilterParameterBuffer *)base;
5581 } else if (base->type == VAProcFilterDeinterlacing) {
5582 VAProcFilterParameterBufferDeinterlacing *deint = (VAProcFilterParameterBufferDeinterlacing *)base;
5584 ASSERT_RET(deint->algorithm == VAProcDeinterlacingBob ||
5585 deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
5586 deint->algorithm == VAProcDeinterlacingMotionCompensated,
5587 VA_STATUS_ERROR_INVALID_PARAMETER);
5589 if (deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
5590 deint->algorithm == VAProcDeinterlacingMotionCompensated)
5591 pipeline_cap->num_forward_references++;
5592 } else if (base->type == VAProcFilterSkinToneEnhancement) {
5593 VAProcFilterParameterBuffer *stde = (VAProcFilterParameterBuffer *)base;
5598 return VA_STATUS_SUCCESS;
5601 extern struct hw_codec_info *i965_get_codec_info(int devid);
5604 i965_driver_data_init(VADriverContextP ctx)
5606 struct i965_driver_data *i965 = i965_driver_data(ctx);
5608 i965->codec_info = i965_get_codec_info(i965->intel.device_id);
5610 if (!i965->codec_info)
5613 if (object_heap_init(&i965->config_heap,
5614 sizeof(struct object_config),
5616 goto err_config_heap;
5617 if (object_heap_init(&i965->context_heap,
5618 sizeof(struct object_context),
5620 goto err_context_heap;
5622 if (object_heap_init(&i965->surface_heap,
5623 sizeof(struct object_surface),
5625 goto err_surface_heap;
5626 if (object_heap_init(&i965->buffer_heap,
5627 sizeof(struct object_buffer),
5629 goto err_buffer_heap;
5630 if (object_heap_init(&i965->image_heap,
5631 sizeof(struct object_image),
5633 goto err_image_heap;
5634 if (object_heap_init(&i965->subpic_heap,
5635 sizeof(struct object_subpic),
5637 goto err_subpic_heap;
5639 i965->batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
5640 i965->pp_batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
5641 _i965InitMutex(&i965->render_mutex);
5642 _i965InitMutex(&i965->pp_mutex);
5647 object_heap_destroy(&i965->image_heap);
5649 object_heap_destroy(&i965->buffer_heap);
5651 object_heap_destroy(&i965->surface_heap);
5653 object_heap_destroy(&i965->context_heap);
5655 object_heap_destroy(&i965->config_heap);
5662 i965_driver_data_terminate(VADriverContextP ctx)
5664 struct i965_driver_data *i965 = i965_driver_data(ctx);
5666 _i965DestroyMutex(&i965->pp_mutex);
5667 _i965DestroyMutex(&i965->render_mutex);
5670 intel_batchbuffer_free(i965->batch);
5673 intel_batchbuffer_free(i965->pp_batch);
5675 i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
5676 i965_destroy_heap(&i965->image_heap, i965_destroy_image);
5677 i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
5678 i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
5679 i965_destroy_heap(&i965->context_heap, i965_destroy_context);
5680 i965_destroy_heap(&i965->config_heap, i965_destroy_config);
5684 bool (*init)(VADriverContextP ctx);
5685 void (*terminate)(VADriverContextP ctx);
5687 } i965_sub_ops[] = {
5690 intel_driver_terminate,
5695 i965_driver_data_init,
5696 i965_driver_data_terminate,
5701 i965_display_attributes_init,
5702 i965_display_attributes_terminate,
5707 i965_post_processing_init,
5708 i965_post_processing_terminate,
5714 i965_render_terminate,
5718 #ifdef HAVE_VA_WAYLAND
5720 i965_output_wayland_init,
5721 i965_output_wayland_terminate,
5728 i965_output_dri_init,
5729 i965_output_dri_terminate,
5736 ensure_vendor_string(struct i965_driver_data *i965, const char *chipset)
5740 if (i965->va_vendor[0] != '\0')
5744 ret = snprintf(i965->va_vendor, sizeof(i965->va_vendor),
5745 "%s %s driver for %s - %d.%d.%d",
5746 INTEL_STR_DRIVER_VENDOR, INTEL_STR_DRIVER_NAME, chipset,
5747 INTEL_DRIVER_MAJOR_VERSION, INTEL_DRIVER_MINOR_VERSION,
5748 INTEL_DRIVER_MICRO_VERSION);
5749 if (ret < 0 || ret >= sizeof(i965->va_vendor))
5753 if (INTEL_DRIVER_PRE_VERSION > 0) {
5754 ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
5755 ".pre%d", INTEL_DRIVER_PRE_VERSION);
5756 if (ret < 0 || ret >= sizeof(i965->va_vendor))
5760 ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
5761 " (%s)", INTEL_DRIVER_GIT_VERSION);
5762 if (ret < 0 || ret >= sizeof(i965->va_vendor))
5769 i965->va_vendor[0] = '\0';
5770 ASSERT_RET(ret > 0 && len < sizeof(i965->va_vendor), false);
5775 i965_Init(VADriverContextP ctx)
5777 struct i965_driver_data *i965 = i965_driver_data(ctx);
5779 const char *chipset;
5781 for (i = 0; i < ARRAY_ELEMS(i965_sub_ops); i++) {
5782 if ((i965_sub_ops[i].display_type == 0 ||
5783 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) &&
5784 !i965_sub_ops[i].init(ctx))
5788 if (i == ARRAY_ELEMS(i965_sub_ops)) {
5789 switch (i965->intel.device_id) {
5791 #define CHIPSET(id, family, dev, str) case id: chipset = str; break;
5792 #include "i965_pciids.h"
5794 chipset = "Unknown Intel Chipset";
5798 if (!ensure_vendor_string(i965, chipset))
5799 return VA_STATUS_ERROR_ALLOCATION_FAILED;
5801 i965->current_context_id = VA_INVALID_ID;
5803 if (i965->codec_info && i965->codec_info->preinit_hw_codec)
5804 i965->codec_info->preinit_hw_codec(ctx, i965->codec_info);
5806 return VA_STATUS_SUCCESS;
5810 for (; i >= 0; i--) {
5811 if (i965_sub_ops[i].display_type == 0 ||
5812 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
5813 i965_sub_ops[i].terminate(ctx);
5817 return VA_STATUS_ERROR_UNKNOWN;
5822 i965_Terminate(VADriverContextP ctx)
5824 struct i965_driver_data *i965 = i965_driver_data(ctx);
5828 for (i = ARRAY_ELEMS(i965_sub_ops); i > 0; i--)
5829 if (i965_sub_ops[i - 1].display_type == 0 ||
5830 i965_sub_ops[i - 1].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
5831 i965_sub_ops[i - 1].terminate(ctx);
5835 ctx->pDriverData = NULL;
5838 return VA_STATUS_SUCCESS;
5842 VA_DRIVER_INIT_FUNC(VADriverContextP ctx);
5845 VA_DRIVER_INIT_FUNC( VADriverContextP ctx )
5847 struct VADriverVTable * const vtable = ctx->vtable;
5848 struct VADriverVTableVPP * const vtable_vpp = ctx->vtable_vpp;
5850 struct i965_driver_data *i965;
5851 VAStatus ret = VA_STATUS_ERROR_UNKNOWN;
5853 ctx->version_major = VA_MAJOR_VERSION;
5854 ctx->version_minor = VA_MINOR_VERSION;
5855 ctx->max_profiles = I965_MAX_PROFILES;
5856 ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
5857 ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
5858 ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
5859 ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
5860 ctx->max_display_attributes = 1 + ARRAY_ELEMS(i965_display_attributes);
5862 vtable->vaTerminate = i965_Terminate;
5863 vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
5864 vtable->vaQueryConfigProfiles = i965_QueryConfigProfiles;
5865 vtable->vaQueryConfigAttributes = i965_QueryConfigAttributes;
5866 vtable->vaCreateConfig = i965_CreateConfig;
5867 vtable->vaDestroyConfig = i965_DestroyConfig;
5868 vtable->vaGetConfigAttributes = i965_GetConfigAttributes;
5869 vtable->vaCreateSurfaces = i965_CreateSurfaces;
5870 vtable->vaDestroySurfaces = i965_DestroySurfaces;
5871 vtable->vaCreateContext = i965_CreateContext;
5872 vtable->vaDestroyContext = i965_DestroyContext;
5873 vtable->vaCreateBuffer = i965_CreateBuffer;
5874 vtable->vaBufferSetNumElements = i965_BufferSetNumElements;
5875 vtable->vaMapBuffer = i965_MapBuffer;
5876 vtable->vaUnmapBuffer = i965_UnmapBuffer;
5877 vtable->vaDestroyBuffer = i965_DestroyBuffer;
5878 vtable->vaBeginPicture = i965_BeginPicture;
5879 vtable->vaRenderPicture = i965_RenderPicture;
5880 vtable->vaEndPicture = i965_EndPicture;
5881 vtable->vaSyncSurface = i965_SyncSurface;
5882 vtable->vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
5883 vtable->vaPutSurface = i965_PutSurface;
5884 vtable->vaQueryImageFormats = i965_QueryImageFormats;
5885 vtable->vaCreateImage = i965_CreateImage;
5886 vtable->vaDeriveImage = i965_DeriveImage;
5887 vtable->vaDestroyImage = i965_DestroyImage;
5888 vtable->vaSetImagePalette = i965_SetImagePalette;
5889 vtable->vaGetImage = i965_GetImage;
5890 vtable->vaPutImage = i965_PutImage;
5891 vtable->vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
5892 vtable->vaCreateSubpicture = i965_CreateSubpicture;
5893 vtable->vaDestroySubpicture = i965_DestroySubpicture;
5894 vtable->vaSetSubpictureImage = i965_SetSubpictureImage;
5895 vtable->vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
5896 vtable->vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
5897 vtable->vaAssociateSubpicture = i965_AssociateSubpicture;
5898 vtable->vaDeassociateSubpicture = i965_DeassociateSubpicture;
5899 vtable->vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
5900 vtable->vaGetDisplayAttributes = i965_GetDisplayAttributes;
5901 vtable->vaSetDisplayAttributes = i965_SetDisplayAttributes;
5902 vtable->vaBufferInfo = i965_BufferInfo;
5903 vtable->vaLockSurface = i965_LockSurface;
5904 vtable->vaUnlockSurface = i965_UnlockSurface;
5905 vtable->vaGetSurfaceAttributes = i965_GetSurfaceAttributes;
5906 vtable->vaQuerySurfaceAttributes = i965_QuerySurfaceAttributes;
5907 vtable->vaCreateSurfaces2 = i965_CreateSurfaces2;
5910 vtable->vaAcquireBufferHandle = i965_AcquireBufferHandle;
5911 vtable->vaReleaseBufferHandle = i965_ReleaseBufferHandle;
5913 vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters;
5914 vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps;
5915 vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;
5917 i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
5920 ctx->pDriverData = NULL;
5922 return VA_STATUS_ERROR_ALLOCATION_FAILED;
5925 ctx->pDriverData = (void *)i965;
5926 ret = i965_Init(ctx);
5928 if (ret == VA_STATUS_SUCCESS) {
5929 ctx->str_vendor = i965->va_vendor;
5932 ctx->pDriverData = NULL;