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>
35 # include "i965_output_dri.h"
38 #ifdef HAVE_VA_WAYLAND
39 # include "i965_output_wayland.h"
42 #include "intel_version.h"
43 #include "intel_driver.h"
44 #include "intel_memman.h"
45 #include "intel_batchbuffer.h"
46 #include "i965_defines.h"
47 #include "i965_drv_video.h"
48 #include "i965_decoder.h"
49 #include "i965_encoder.h"
51 #include "i965_post_processing.h"
53 #include "gen9_vp9_encapi.h"
55 #define CONFIG_ID_OFFSET 0x01000000
56 #define CONTEXT_ID_OFFSET 0x02000000
57 #define SURFACE_ID_OFFSET 0x04000000
58 #define BUFFER_ID_OFFSET 0x08000000
59 #define IMAGE_ID_OFFSET 0x0a000000
60 #define SUBPIC_ID_OFFSET 0x10000000
62 static int get_sampling_from_fourcc(unsigned int fourcc);
64 /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */
65 #define IS_VA_X11(ctx) \
66 (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_X11)
68 /* Check whether we are rendering to Wayland */
69 #define IS_VA_WAYLAND(ctx) \
70 (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_WAYLAND)
73 #define I965_2BITS (I965_BIT << 1)
74 #define I965_4BITS (I965_BIT << 2)
75 #define I965_8BITS (I965_BIT << 3)
76 #define I965_16BITS (I965_BIT << 4)
77 #define I965_32BITS (I965_BIT << 5)
89 /* hfactor, vfactor, num_planes, bpp[], num_components, components[] */
90 #define I_NV12 2, 2, 2, {I965_8BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_8} }
91 #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} }
94 #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} }
97 #define I_P010 2, 2, 2, {I965_16BITS, I965_8BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_16} }
99 #define I_I010 2, 2, 3, {I965_16BITS, I965_4BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
101 #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} }
102 #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} }
103 #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} }
104 #define I_YUY2 2, 1, 1, {I965_16BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_24} }
105 #define I_UYVY 2, 1, 1, {I965_16BITS}, 3, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_16} }
107 #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} }
109 #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} }
111 #define I_Y800 1, 1, 1, {I965_8BITS}, 1, { {PLANE_0, OFFSET_0} }
113 #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} }
114 #define I_RGBX 1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16} }
115 #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} }
116 #define I_BGRX 1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
118 #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} }
119 #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} }
121 #define I_IA88 1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8} }
122 #define I_AI88 1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
124 #define I_IA44 1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_4} }
125 #define I_AI44 1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_4}, {PLANE_0, OFFSET_0} }
130 #define I_SI (I_S | I_I)
132 #define DEF_FOUCC_INFO(FOURCC, FORMAT, SUB, FLAG) { VA_FOURCC_##FOURCC, I965_COLOR_##FORMAT, SUBSAMPLE_##SUB, FLAG, I_##FOURCC }
133 #define DEF_YUV(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, YUV, SUB, FLAG)
134 #define DEF_RGB(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, RGB, SUB, FLAG)
135 #define DEF_INDEX(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, INDEX, SUB, FLAG)
137 static const i965_fourcc_info i965_fourcc_infos[] = {
138 DEF_YUV(NV12, YUV420, I_SI),
139 DEF_YUV(I420, YUV420, I_SI),
140 DEF_YUV(IYUV, YUV420, I_S),
141 DEF_YUV(IMC3, YUV420, I_S),
142 DEF_YUV(YV12, YUV420, I_SI),
143 DEF_YUV(IMC1, YUV420, I_S),
145 DEF_YUV(P010, YUV420, I_SI),
146 DEF_YUV(I010, YUV420, I_S),
148 DEF_YUV(422H, YUV422H, I_SI),
149 DEF_YUV(422V, YUV422V, I_S),
150 DEF_YUV(YV16, YUV422H, I_S),
151 DEF_YUV(YUY2, YUV422H, I_SI),
152 DEF_YUV(UYVY, YUV422H, I_SI),
154 DEF_YUV(444P, YUV444, I_S),
156 DEF_YUV(411P, YUV411, I_S),
158 DEF_YUV(Y800, YUV400, I_S),
160 DEF_RGB(RGBA, RGBX, I_SI),
161 DEF_RGB(RGBX, RGBX, I_SI),
162 DEF_RGB(BGRA, RGBX, I_SI),
163 DEF_RGB(BGRX, RGBX, I_SI),
165 DEF_RGB(ARGB, RGBX, I_I),
166 DEF_RGB(ABGR, RGBX, I_I),
168 DEF_INDEX(IA88, RGBX, I_I),
169 DEF_INDEX(AI88, RGBX, I_I),
171 DEF_INDEX(IA44, RGBX, I_I),
172 DEF_INDEX(AI44, RGBX, I_I)
175 const i965_fourcc_info *
176 get_fourcc_info(unsigned int fourcc)
180 for (i = 0; i < ARRAY_ELEMS(i965_fourcc_infos); i++) {
181 const i965_fourcc_info * const info = &i965_fourcc_infos[i];
183 if (info->fourcc == fourcc)
191 get_bpp_from_fourcc(unsigned int fourcc)
193 const i965_fourcc_info *info = get_fourcc_info(fourcc);
195 unsigned int bpp = 0;
200 for (i = 0; i < info->num_planes; i++)
207 I965_SURFACETYPE_RGBA = 1,
208 I965_SURFACETYPE_YUV,
209 I965_SURFACETYPE_INDEXED
212 /* List of supported display attributes */
213 static const VADisplayAttribute i965_display_attributes[] = {
215 VADisplayAttribBrightness,
216 -100, 100, DEFAULT_BRIGHTNESS,
217 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
221 VADisplayAttribContrast,
222 0, 100, DEFAULT_CONTRAST,
223 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
228 -180, 180, DEFAULT_HUE,
229 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
233 VADisplayAttribSaturation,
234 0, 100, DEFAULT_SATURATION,
235 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
239 VADisplayAttribRotation,
240 0, 3, VA_ROTATION_NONE,
241 VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE
245 /* List of supported image formats */
248 VAImageFormat va_format;
249 } i965_image_format_map_t;
251 static const i965_image_format_map_t
252 i965_image_formats_map[I965_MAX_IMAGE_FORMATS + 1] = {
253 { I965_SURFACETYPE_YUV,
254 { VA_FOURCC_YV12, VA_LSB_FIRST, 12, } },
255 { I965_SURFACETYPE_YUV,
256 { VA_FOURCC_I420, VA_LSB_FIRST, 12, } },
257 { I965_SURFACETYPE_YUV,
258 { VA_FOURCC_NV12, VA_LSB_FIRST, 12, } },
259 { I965_SURFACETYPE_YUV,
260 { VA_FOURCC_YUY2, VA_LSB_FIRST, 16, } },
261 { I965_SURFACETYPE_YUV,
262 { VA_FOURCC_UYVY, VA_LSB_FIRST, 16, } },
263 { I965_SURFACETYPE_YUV,
264 { VA_FOURCC_422H, VA_LSB_FIRST, 16, } },
265 { I965_SURFACETYPE_RGBA,
266 { VA_FOURCC_RGBX, VA_LSB_FIRST, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000 } },
267 { I965_SURFACETYPE_RGBA,
268 { VA_FOURCC_BGRX, VA_LSB_FIRST, 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff } },
269 { I965_SURFACETYPE_YUV,
270 { VA_FOURCC_P010, VA_LSB_FIRST, 24, } },
273 /* List of supported subpicture formats */
277 VAImageFormat va_format;
278 unsigned int va_flags;
279 } i965_subpic_format_map_t;
281 #define COMMON_SUBPICTURE_FLAGS \
282 (VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD| \
283 VA_SUBPICTURE_GLOBAL_ALPHA)
285 static const i965_subpic_format_map_t
286 i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
287 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
288 { VA_FOURCC_IA44, VA_MSB_FIRST, 8, },
289 COMMON_SUBPICTURE_FLAGS },
290 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
291 { VA_FOURCC_AI44, VA_MSB_FIRST, 8, },
292 COMMON_SUBPICTURE_FLAGS },
293 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P8A8_UNORM,
294 { VA_FOURCC_IA88, VA_MSB_FIRST, 16, },
295 COMMON_SUBPICTURE_FLAGS },
296 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A8P8_UNORM,
297 { VA_FOURCC_AI88, VA_MSB_FIRST, 16, },
298 COMMON_SUBPICTURE_FLAGS },
299 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_B8G8R8A8_UNORM,
300 { VA_FOURCC_BGRA, VA_LSB_FIRST, 32,
301 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
302 COMMON_SUBPICTURE_FLAGS },
303 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_R8G8B8A8_UNORM,
304 { VA_FOURCC_RGBA, VA_LSB_FIRST, 32,
305 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
306 COMMON_SUBPICTURE_FLAGS },
309 static const i965_subpic_format_map_t *
310 get_subpic_format(const VAImageFormat *va_format)
313 for (i = 0; i965_subpic_formats_map[i].type != 0; i++) {
314 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
315 if (m->va_format.fourcc == va_format->fourcc &&
316 (m->type == I965_SURFACETYPE_RGBA ?
317 (m->va_format.byte_order == va_format->byte_order &&
318 m->va_format.red_mask == va_format->red_mask &&
319 m->va_format.green_mask == va_format->green_mask &&
320 m->va_format.blue_mask == va_format->blue_mask &&
321 m->va_format.alpha_mask == va_format->alpha_mask) : 1))
327 /* Checks whether the surface is in busy state */
329 is_surface_busy(struct i965_driver_data *i965,
330 struct object_surface *obj_surface)
332 assert(obj_surface != NULL);
334 if (obj_surface->locked_image_id != VA_INVALID_ID)
336 if (obj_surface->derived_image_id != VA_INVALID_ID)
341 /* Checks whether the image is in busy state */
343 is_image_busy(struct i965_driver_data *i965, struct object_image *obj_image, VASurfaceID surface)
345 struct object_buffer *obj_buffer;
347 assert(obj_image != NULL);
349 if (obj_image->derived_surface != VA_INVALID_ID &&
350 obj_image->derived_surface == surface)
353 obj_buffer = BUFFER(obj_image->image.buf);
354 if (obj_buffer && obj_buffer->export_refcount > 0)
359 #define I965_PACKED_HEADER_BASE 0
360 #define I965_SEQ_PACKED_HEADER_BASE 0
361 #define I965_SEQ_PACKED_HEADER_END 2
362 #define I965_PIC_PACKED_HEADER_BASE 2
363 #define I965_PACKED_MISC_HEADER_BASE 4
366 va_enc_packed_type_to_idx(int packed_type)
370 if (packed_type & VAEncPackedHeaderMiscMask) {
371 idx = I965_PACKED_MISC_HEADER_BASE;
372 packed_type = (~VAEncPackedHeaderMiscMask & packed_type);
373 ASSERT_RET(packed_type > 0, 0);
374 idx += (packed_type - 1);
376 idx = I965_PACKED_HEADER_BASE;
378 switch (packed_type) {
379 case VAEncPackedHeaderSequence:
380 idx = I965_SEQ_PACKED_HEADER_BASE + 0;
383 case VAEncPackedHeaderPicture:
384 idx = I965_PIC_PACKED_HEADER_BASE + 0;
387 case VAEncPackedHeaderSlice:
388 idx = I965_PIC_PACKED_HEADER_BASE + 1;
392 /* Should not get here */
398 ASSERT_RET(idx < 5, 0);
402 #define CALL_VTABLE(vawr, status, param) status = (vawr->vtable->param)
405 i965_surface_wrapper(VADriverContextP ctx, VASurfaceID surface)
407 struct i965_driver_data *i965 = i965_driver_data(ctx);
408 struct object_surface *obj_surface = SURFACE(surface);
409 VAStatus va_status = VA_STATUS_SUCCESS;
412 return VA_STATUS_ERROR_INVALID_SURFACE;
415 if (obj_surface->wrapper_surface != VA_INVALID_ID) {
416 /* the wrapped surface already exists. just return it */
420 if (obj_surface->fourcc == 0)
421 i965_check_alloc_surface_bo(ctx, obj_surface,
422 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
425 * TBD: Support more surface formats.
426 * Currently only NV12 is support as NV12 is used by decoding.
428 if (obj_surface->fourcc != VA_FOURCC_NV12 )
429 return VA_STATUS_ERROR_INVALID_PARAMETER;
431 if ((i965->wrapper_pdrvctx == NULL) ||
432 (obj_surface->bo == NULL))
433 return VA_STATUS_ERROR_INVALID_PARAMETER;
437 VASurfaceAttrib attrib_list[2];
438 VASurfaceAttribExternalBuffers buffer_descriptor;
439 VAGenericID wrapper_surface;
441 if (drm_intel_bo_gem_export_to_prime(obj_surface->bo, &fd_handle) != 0)
442 return VA_STATUS_ERROR_OPERATION_FAILED;
444 obj_surface->exported_primefd = fd_handle;
446 memset(&attrib_list, 0, sizeof(attrib_list));
447 memset(&buffer_descriptor, 0, sizeof(buffer_descriptor));
449 attrib_list[0].type = VASurfaceAttribExternalBufferDescriptor;
450 attrib_list[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
451 attrib_list[0].value.value.p = &buffer_descriptor;
452 attrib_list[0].value.type = VAGenericValueTypePointer;
454 attrib_list[1].type = VASurfaceAttribMemoryType;
455 attrib_list[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
456 attrib_list[1].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
457 attrib_list[1].value.type = VAGenericValueTypeInteger;
459 buffer_descriptor.num_buffers = 1;
460 buffer_descriptor.num_planes = 2;
461 buffer_descriptor.width = obj_surface->orig_width;
462 buffer_descriptor.height = obj_surface->orig_height;
463 buffer_descriptor.pixel_format = obj_surface->fourcc;
464 buffer_descriptor.data_size = obj_surface->size;
465 buffer_descriptor.pitches[0] = obj_surface->width;
466 buffer_descriptor.pitches[1] = obj_surface->cb_cr_pitch;
467 buffer_descriptor.offsets[0] = 0;
468 buffer_descriptor.offsets[1] = obj_surface->width * obj_surface->height;
469 buffer_descriptor.buffers = (void *)&fd_handle;
471 CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
472 vaCreateSurfaces2(i965->wrapper_pdrvctx,
474 obj_surface->orig_width,
475 obj_surface->orig_height,
479 if (va_status == VA_STATUS_SUCCESS) {
480 obj_surface->wrapper_surface = wrapper_surface;
482 /* This needs to be checked */
483 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
491 i965_QueryConfigProfiles(VADriverContextP ctx,
492 VAProfile *profile_list, /* out */
493 int *num_profiles) /* out */
495 struct i965_driver_data * const i965 = i965_driver_data(ctx);
498 if (HAS_MPEG2_DECODING(i965) ||
499 HAS_MPEG2_ENCODING(i965)) {
500 profile_list[i++] = VAProfileMPEG2Simple;
501 profile_list[i++] = VAProfileMPEG2Main;
504 if (HAS_H264_DECODING(i965) ||
505 HAS_H264_ENCODING(i965) ||
506 HAS_LP_H264_ENCODING(i965)) {
507 profile_list[i++] = VAProfileH264ConstrainedBaseline;
508 profile_list[i++] = VAProfileH264Main;
509 profile_list[i++] = VAProfileH264High;
511 if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264MultiviewHigh) ||
512 HAS_H264_MVC_ENCODING(i965))
513 profile_list[i++] = VAProfileH264MultiviewHigh;
514 if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264StereoHigh) ||
515 HAS_H264_MVC_ENCODING(i965))
516 profile_list[i++] = VAProfileH264StereoHigh;
518 if (HAS_VC1_DECODING(i965)) {
519 profile_list[i++] = VAProfileVC1Simple;
520 profile_list[i++] = VAProfileVC1Main;
521 profile_list[i++] = VAProfileVC1Advanced;
525 profile_list[i++] = VAProfileNone;
528 if (HAS_JPEG_DECODING(i965) ||
529 HAS_JPEG_ENCODING(i965)) {
530 profile_list[i++] = VAProfileJPEGBaseline;
533 if (HAS_VP8_DECODING(i965) ||
534 HAS_VP8_ENCODING(i965)) {
535 profile_list[i++] = VAProfileVP8Version0_3;
538 if (HAS_HEVC_DECODING(i965)||
539 HAS_HEVC_ENCODING(i965)) {
540 profile_list[i++] = VAProfileHEVCMain;
543 if (HAS_HEVC10_DECODING(i965)||
544 HAS_HEVC10_ENCODING(i965)) {
545 profile_list[i++] = VAProfileHEVCMain10;
548 if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile0) ||
549 HAS_VP9_ENCODING(i965)) {
550 profile_list[i++] = VAProfileVP9Profile0;
553 if(HAS_VP9_DECODING_PROFILE(i965, VAProfileVP9Profile2)) {
554 profile_list[i++] = VAProfileVP9Profile2;
557 if (i965->wrapper_pdrvctx) {
558 VAProfile wrapper_list[4];
560 VADriverContextP pdrvctx;
563 pdrvctx = i965->wrapper_pdrvctx;
564 CALL_VTABLE(pdrvctx, va_status,
565 vaQueryConfigProfiles(pdrvctx,
566 wrapper_list, &wrapper_num));
568 if (va_status == VA_STATUS_SUCCESS) {
570 for (j = 0; j < wrapper_num; j++)
571 if (wrapper_list[j] != VAProfileNone)
572 profile_list[i++] = wrapper_list[j];
576 /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
577 ASSERT_RET(i <= I965_MAX_PROFILES, VA_STATUS_ERROR_OPERATION_FAILED);
580 return VA_STATUS_SUCCESS;
584 i965_QueryConfigEntrypoints(VADriverContextP ctx,
586 VAEntrypoint *entrypoint_list, /* out */
587 int *num_entrypoints) /* out */
589 struct i965_driver_data * const i965 = i965_driver_data(ctx);
593 case VAProfileMPEG2Simple:
594 case VAProfileMPEG2Main:
595 if (HAS_MPEG2_DECODING(i965))
596 entrypoint_list[n++] = VAEntrypointVLD;
598 if (HAS_MPEG2_ENCODING(i965))
599 entrypoint_list[n++] = VAEntrypointEncSlice;
603 case VAProfileH264ConstrainedBaseline:
604 case VAProfileH264Main:
605 case VAProfileH264High:
606 if (HAS_H264_DECODING(i965))
607 entrypoint_list[n++] = VAEntrypointVLD;
609 if (HAS_H264_ENCODING(i965))
610 entrypoint_list[n++] = VAEntrypointEncSlice;
612 if (HAS_LP_H264_ENCODING(i965))
613 entrypoint_list[n++] = VAEntrypointEncSliceLP;
616 case VAProfileH264MultiviewHigh:
617 case VAProfileH264StereoHigh:
618 if (HAS_H264_MVC_DECODING_PROFILE(i965, profile))
619 entrypoint_list[n++] = VAEntrypointVLD;
621 if (HAS_H264_MVC_ENCODING(i965))
622 entrypoint_list[n++] = VAEntrypointEncSlice;
625 case VAProfileVC1Simple:
626 case VAProfileVC1Main:
627 case VAProfileVC1Advanced:
628 if (HAS_VC1_DECODING(i965))
629 entrypoint_list[n++] = VAEntrypointVLD;
634 entrypoint_list[n++] = VAEntrypointVideoProc;
637 case VAProfileJPEGBaseline:
638 if (HAS_JPEG_DECODING(i965))
639 entrypoint_list[n++] = VAEntrypointVLD;
641 if (HAS_JPEG_ENCODING(i965))
642 entrypoint_list[n++] = VAEntrypointEncPicture;
645 case VAProfileVP8Version0_3:
646 if (HAS_VP8_DECODING(i965))
647 entrypoint_list[n++] = VAEntrypointVLD;
649 if (HAS_VP8_ENCODING(i965))
650 entrypoint_list[n++] = VAEntrypointEncSlice;
654 case VAProfileHEVCMain:
655 if (HAS_HEVC_DECODING(i965))
656 entrypoint_list[n++] = VAEntrypointVLD;
658 if (HAS_HEVC_ENCODING(i965))
659 entrypoint_list[n++] = VAEntrypointEncSlice;
663 case VAProfileHEVCMain10:
664 if (HAS_HEVC10_DECODING(i965))
665 entrypoint_list[n++] = VAEntrypointVLD;
667 if (HAS_HEVC10_ENCODING(i965))
668 entrypoint_list[n++] = VAEntrypointEncSlice;
672 case VAProfileVP9Profile0:
673 case VAProfileVP9Profile2:
674 if(HAS_VP9_DECODING_PROFILE(i965, profile))
675 entrypoint_list[n++] = VAEntrypointVLD;
677 if (HAS_VP9_ENCODING(i965) && (profile == VAProfileVP9Profile0))
678 entrypoint_list[n++] = VAEntrypointEncSlice;
680 if(profile == VAProfileVP9Profile0) {
681 if (i965->wrapper_pdrvctx) {
682 VAStatus va_status = VA_STATUS_SUCCESS;
683 VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
685 CALL_VTABLE(pdrvctx, va_status,
686 vaQueryConfigEntrypoints(pdrvctx, profile,
699 /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
700 ASSERT_RET(n <= I965_MAX_ENTRYPOINTS, VA_STATUS_ERROR_OPERATION_FAILED);
701 *num_entrypoints = n;
702 return n > 0 ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
706 i965_validate_config(VADriverContextP ctx, VAProfile profile,
707 VAEntrypoint entrypoint)
709 struct i965_driver_data * const i965 = i965_driver_data(ctx);
712 /* Validate profile & entrypoint */
714 case VAProfileMPEG2Simple:
715 case VAProfileMPEG2Main:
716 if ((HAS_MPEG2_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
717 (HAS_MPEG2_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
718 va_status = VA_STATUS_SUCCESS;
719 } else if (!HAS_MPEG2_DECODING(i965) && !HAS_MPEG2_ENCODING(i965)){
720 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
722 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
726 case VAProfileH264ConstrainedBaseline:
727 case VAProfileH264Main:
728 case VAProfileH264High:
729 if ((HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
730 (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice) ||
731 (HAS_LP_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSliceLP)) {
732 va_status = VA_STATUS_SUCCESS;
733 } else if (!HAS_H264_DECODING(i965) && !HAS_H264_ENCODING(i965) &&
734 !HAS_LP_H264_ENCODING(i965)){
735 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
737 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
741 case VAProfileVC1Simple:
742 case VAProfileVC1Main:
743 case VAProfileVC1Advanced:
744 if (HAS_VC1_DECODING(i965) && entrypoint == VAEntrypointVLD) {
745 va_status = VA_STATUS_SUCCESS;
746 } else if (!HAS_VC1_DECODING(i965)) {
747 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
749 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
754 if (HAS_VPP(i965) && VAEntrypointVideoProc == entrypoint) {
755 va_status = VA_STATUS_SUCCESS;
756 } else if (!HAS_VPP(i965)){
757 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
759 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
763 case VAProfileJPEGBaseline:
764 if ((HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
765 (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)) {
766 va_status = VA_STATUS_SUCCESS;
767 } else if (!HAS_JPEG_DECODING(i965) && !HAS_JPEG_ENCODING(i965)){
768 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
770 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
774 case VAProfileVP8Version0_3:
775 if ((HAS_VP8_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
776 (HAS_VP8_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
777 va_status = VA_STATUS_SUCCESS;
778 } else if (!HAS_VP8_DECODING(i965) && !HAS_VP8_ENCODING(i965)){
779 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
781 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
785 case VAProfileH264MultiviewHigh:
786 case VAProfileH264StereoHigh:
787 if ((HAS_H264_MVC_DECODING_PROFILE(i965, profile) &&
788 entrypoint == VAEntrypointVLD) ||
789 (HAS_H264_MVC_ENCODING(i965) &&
790 entrypoint == VAEntrypointEncSlice)) {
791 va_status = VA_STATUS_SUCCESS;
792 } else if(!HAS_H264_MVC_DECODING_PROFILE(i965, profile) &&
793 !HAS_H264_MVC_ENCODING(i965)) {
794 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
796 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
801 case VAProfileHEVCMain:
802 if ((HAS_HEVC_DECODING(i965) && (entrypoint == VAEntrypointVLD))||
803 (HAS_HEVC_ENCODING(i965) && (entrypoint == VAEntrypointEncSlice))) {
804 va_status = VA_STATUS_SUCCESS;
805 } else if (!HAS_HEVC_DECODING(i965) && !HAS_HEVC_ENCODING(i965)) {
806 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
808 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
813 case VAProfileHEVCMain10:
814 if ((HAS_HEVC10_DECODING(i965) && (entrypoint == VAEntrypointVLD))||
815 (HAS_HEVC10_ENCODING(i965) &&
816 (entrypoint == VAEntrypointEncSlice))) {
817 va_status = VA_STATUS_SUCCESS;
818 } else if (!HAS_HEVC10_DECODING(i965) && !HAS_HEVC10_ENCODING(i965)) {
819 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
821 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
826 case VAProfileVP9Profile0:
827 case VAProfileVP9Profile2:
828 if ((HAS_VP9_DECODING_PROFILE(i965, profile)) &&
829 (entrypoint == VAEntrypointVLD)) {
830 va_status = VA_STATUS_SUCCESS;
831 } else if ((HAS_VP9_ENCODING_PROFILE(i965, profile)) &&
832 (entrypoint == VAEntrypointEncSlice)) {
833 va_status = VA_STATUS_SUCCESS;
834 } else if (profile == VAProfileVP9Profile0 &&
835 entrypoint == VAEntrypointVLD &&
836 i965->wrapper_pdrvctx) {
837 va_status = VA_STATUS_SUCCESS;
838 } else if(!HAS_VP9_DECODING_PROFILE(i965, profile) &&
839 !HAS_VP9_ENCODING(i965) && !i965->wrapper_pdrvctx) {
840 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
842 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
848 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
855 i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
856 VAEntrypoint entrypoint)
858 struct i965_driver_data * const i965 = i965_driver_data(ctx);
859 uint32_t chroma_formats = VA_RT_FORMAT_YUV420;
862 case VAProfileH264ConstrainedBaseline:
863 case VAProfileH264Main:
864 case VAProfileH264High:
865 if (HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD)
866 chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
869 case VAProfileH264MultiviewHigh:
870 case VAProfileH264StereoHigh:
871 if (HAS_H264_MVC_DECODING(i965) && entrypoint == VAEntrypointVLD)
872 chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
875 case VAProfileJPEGBaseline:
876 if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD)
877 chroma_formats |= i965->codec_info->jpeg_dec_chroma_formats;
878 if (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)
879 chroma_formats |= i965->codec_info->jpeg_enc_chroma_formats;
882 case VAProfileHEVCMain10:
883 if (HAS_HEVC10_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)
884 chroma_formats = VA_RT_FORMAT_YUV420_10BPP;
885 if (HAS_HEVC10_DECODING(i965) && entrypoint == VAEntrypointVLD)
886 chroma_formats |= i965->codec_info->hevc_dec_chroma_formats;
890 if (HAS_VPP_P010(i965))
891 chroma_formats |= VA_RT_FORMAT_YUV420_10BPP;
894 chroma_formats |= VA_RT_FORMAT_YUV422 | VA_RT_FORMAT_RGB32;
897 case VAProfileVP9Profile0:
898 case VAProfileVP9Profile2:
899 if (HAS_VP9_DECODING_PROFILE(i965, profile) && entrypoint == VAEntrypointVLD)
900 chroma_formats |= i965->codec_info->vp9_dec_chroma_formats;
906 return chroma_formats;
910 i965_GetConfigAttributes(VADriverContextP ctx,
912 VAEntrypoint entrypoint,
913 VAConfigAttrib *attrib_list, /* in/out */
916 struct i965_driver_data * const i965 = i965_driver_data(ctx);
920 va_status = i965_validate_config(ctx, profile, entrypoint);
921 if (va_status != VA_STATUS_SUCCESS)
924 /* Other attributes don't seem to be defined */
925 /* What to do if we don't know the attribute? */
926 for (i = 0; i < num_attribs; i++) {
927 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
928 switch (attrib_list[i].type) {
929 case VAConfigAttribRTFormat:
930 attrib_list[i].value = i965_get_default_chroma_formats(ctx,
931 profile, entrypoint);
934 case VAConfigAttribRateControl:
935 if (entrypoint == VAEntrypointEncSlice) {
936 attrib_list[i].value = VA_RC_CQP;
938 if (profile != VAProfileMPEG2Main &&
939 profile != VAProfileMPEG2Simple)
940 attrib_list[i].value |= VA_RC_CBR;
942 if (profile == VAProfileVP9Profile0 ||
943 profile == VAProfileH264ConstrainedBaseline ||
944 profile == VAProfileH264Main ||
945 profile == VAProfileH264High)
946 attrib_list[i].value |= VA_RC_VBR;
949 } else if (entrypoint == VAEntrypointEncSliceLP) {
950 struct i965_driver_data * const i965 = i965_driver_data(ctx);
952 /* Support low power encoding for H.264 only by now */
953 if (profile == VAProfileH264ConstrainedBaseline ||
954 profile == VAProfileH264Main ||
955 profile == VAProfileH264High)
956 attrib_list[i].value = i965->codec_info->lp_h264_brc_mode;
958 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
960 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
964 case VAConfigAttribEncPackedHeaders:
965 if (entrypoint == VAEntrypointEncSlice ||
966 entrypoint == VAEntrypointEncSliceLP) {
967 attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
968 if (profile == VAProfileH264ConstrainedBaseline ||
969 profile == VAProfileH264Main ||
970 profile == VAProfileH264High ||
971 profile == VAProfileH264StereoHigh ||
972 profile == VAProfileH264MultiviewHigh ||
973 profile == VAProfileHEVCMain ||
974 profile == VAProfileHEVCMain10) {
975 attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA |
976 VA_ENC_PACKED_HEADER_SLICE);
978 else if (profile == VAProfileVP9Profile0)
979 attrib_list[i].value = VA_ENC_PACKED_HEADER_RAW_DATA;
982 else if (entrypoint == VAEntrypointEncPicture) {
983 if (profile == VAProfileJPEGBaseline)
984 attrib_list[i].value = VA_ENC_PACKED_HEADER_RAW_DATA;
988 case VAConfigAttribEncMaxRefFrames:
989 if (entrypoint == VAEntrypointEncSlice)
990 attrib_list[i].value = (1 << 16) | (1 << 0);
991 else if (entrypoint == VAEntrypointEncSliceLP) {
992 /* Don't support B frame for low power mode */
993 if (profile == VAProfileH264ConstrainedBaseline ||
994 profile == VAProfileH264Main ||
995 profile == VAProfileH264High)
996 attrib_list[i].value = (1 << 0);
998 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
1003 case VAConfigAttribEncQualityRange:
1004 if (entrypoint == VAEntrypointEncSlice ||
1005 entrypoint == VAEntrypointEncSliceLP) {
1006 attrib_list[i].value = 1;
1007 if (profile == VAProfileH264ConstrainedBaseline ||
1008 profile == VAProfileH264Main ||
1009 profile == VAProfileH264High ){
1010 attrib_list[i].value = ENCODER_QUALITY_RANGE;
1011 if(entrypoint == VAEntrypointEncSlice){
1012 if (IS_GEN9(i965->intel.device_info))
1013 attrib_list[i].value = ENCODER_QUALITY_RANGE_AVC;
1020 case VAConfigAttribEncJPEG:
1021 if( entrypoint == VAEntrypointEncPicture) {
1022 VAConfigAttribValEncJPEG *configVal = (VAConfigAttribValEncJPEG*)&(attrib_list[i].value);
1023 (configVal->bits).arithmatic_coding_mode = 0; // Huffman coding is used
1024 (configVal->bits).progressive_dct_mode = 0; // Only Sequential DCT is supported
1025 (configVal->bits).non_interleaved_mode = 1; // Support both interleaved and non-interleaved
1026 (configVal->bits).differential_mode = 0; // Baseline DCT is non-differential
1027 (configVal->bits).max_num_components = 3; // Only 3 components supported
1028 (configVal->bits).max_num_scans = 1; // Only 1 scan per frame
1029 (configVal->bits).max_num_huffman_tables = 3; // Max 3 huffman tables
1030 (configVal->bits).max_num_quantization_tables = 3; // Max 3 quantization tables
1034 case VAConfigAttribDecSliceMode:
1035 attrib_list[i].value = VA_DEC_SLICE_MODE_NORMAL;
1038 case VAConfigAttribEncROI:
1039 if (entrypoint == VAEntrypointEncSlice ||
1040 entrypoint == VAEntrypointEncSliceLP) {
1042 if (profile == VAProfileH264ConstrainedBaseline ||
1043 profile == VAProfileH264Main ||
1044 profile == VAProfileH264High) {
1046 if (IS_GEN9(i965->intel.device_info)&&
1047 entrypoint == VAEntrypointEncSlice)
1048 attrib_list[i].value = 0;
1051 VAConfigAttribValEncROI *roi_config =
1052 (VAConfigAttribValEncROI *)&(attrib_list[i].value);
1054 if(entrypoint == VAEntrypointEncSliceLP) {
1055 roi_config->bits.num_roi_regions = 3;
1056 roi_config->bits.roi_rc_priority_support = 0;
1057 roi_config->bits.roi_rc_qp_delat_support = 0;
1059 roi_config->bits.num_roi_regions =
1060 I965_MAX_NUM_ROI_REGIONS;
1061 roi_config->bits.roi_rc_priority_support = 0;
1062 roi_config->bits.roi_rc_qp_delat_support = 1;
1066 attrib_list[i].value = 0;
1072 case VAConfigAttribEncRateControlExt:
1073 if ((profile == VAProfileH264ConstrainedBaseline ||
1074 profile == VAProfileH264Main ||
1075 profile == VAProfileH264High) &&
1076 entrypoint == VAEntrypointEncSlice) {
1077 if (IS_GEN9(i965->intel.device_info))
1078 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
1080 VAConfigAttribValEncRateControlExt *val_config = (VAConfigAttribValEncRateControlExt *)&(attrib_list[i].value);
1082 val_config->bits.max_num_temporal_layers_minus1 = MAX_TEMPORAL_LAYERS - 1;
1083 val_config->bits.temporal_layer_bitrate_control_flag = 1;
1086 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
1091 case VAConfigAttribEncMaxSlices:
1092 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
1093 if (entrypoint == VAEntrypointEncSlice) {
1094 if ((profile == VAProfileH264ConstrainedBaseline ||
1095 profile == VAProfileH264Main ||
1096 profile == VAProfileH264High) ||
1097 profile == VAProfileH264StereoHigh ||
1098 profile == VAProfileH264MultiviewHigh) {
1099 attrib_list[i].value = I965_MAX_NUM_SLICE;
1100 } else if (profile == VAProfileHEVCMain ||
1101 profile == VAProfileHEVCMain10) {
1102 attrib_list[i].value = I965_MAX_NUM_SLICE;
1104 } else if (entrypoint == VAEntrypointEncSliceLP) {
1105 if ((profile == VAProfileH264ConstrainedBaseline ||
1106 profile == VAProfileH264Main ||
1107 profile == VAProfileH264High) ||
1108 profile == VAProfileH264StereoHigh ||
1109 profile == VAProfileH264MultiviewHigh)
1110 attrib_list[i].value = I965_MAX_NUM_SLICE;
1115 case VAConfigAttribEncSliceStructure:
1116 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
1117 if (entrypoint == VAEntrypointEncSlice) {
1118 if ((profile == VAProfileH264ConstrainedBaseline ||
1119 profile == VAProfileH264Main ||
1120 profile == VAProfileH264High) ||
1121 profile == VAProfileH264StereoHigh ||
1122 profile == VAProfileH264MultiviewHigh) {
1123 attrib_list[i].value = VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS;
1130 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
1135 return VA_STATUS_SUCCESS;
1139 i965_destroy_config(struct object_heap *heap, struct object_base *obj)
1141 object_heap_free(heap, obj);
1144 static VAConfigAttrib *
1145 i965_lookup_config_attribute(struct object_config *obj_config,
1146 VAConfigAttribType type)
1150 for (i = 0; i < obj_config->num_attribs; i++) {
1151 VAConfigAttrib * const attrib = &obj_config->attrib_list[i];
1152 if (attrib->type == type)
1159 i965_append_config_attribute(struct object_config *obj_config,
1160 const VAConfigAttrib *new_attrib)
1162 VAConfigAttrib *attrib;
1164 if (obj_config->num_attribs >= I965_MAX_CONFIG_ATTRIBUTES)
1165 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1167 attrib = &obj_config->attrib_list[obj_config->num_attribs++];
1168 attrib->type = new_attrib->type;
1169 attrib->value = new_attrib->value;
1170 return VA_STATUS_SUCCESS;
1174 i965_ensure_config_attribute(struct object_config *obj_config,
1175 const VAConfigAttrib *new_attrib)
1177 VAConfigAttrib *attrib;
1179 /* Check for existing attributes */
1180 attrib = i965_lookup_config_attribute(obj_config, new_attrib->type);
1182 /* Update existing attribute */
1183 attrib->value = new_attrib->value;
1184 return VA_STATUS_SUCCESS;
1186 return i965_append_config_attribute(obj_config, new_attrib);
1190 i965_CreateConfig(VADriverContextP ctx,
1192 VAEntrypoint entrypoint,
1193 VAConfigAttrib *attrib_list,
1195 VAConfigID *config_id) /* out */
1197 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1198 struct object_config *obj_config;
1203 vaStatus = i965_validate_config(ctx, profile, entrypoint);
1205 if (VA_STATUS_SUCCESS != vaStatus) {
1209 configID = NEW_CONFIG_ID();
1210 obj_config = CONFIG(configID);
1212 if (NULL == obj_config) {
1213 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1217 obj_config->profile = profile;
1218 obj_config->entrypoint = entrypoint;
1219 obj_config->num_attribs = 0;
1220 obj_config->wrapper_config = VA_INVALID_ID;
1222 for (i = 0; i < num_attribs; i++) {
1223 // add it later and ignore the user input for VAConfigAttribEncMaxSlices
1224 if (attrib_list[i].type == VAConfigAttribEncMaxSlices ||
1225 attrib_list[i].type == VAConfigAttribEncSliceStructure)
1227 vaStatus = i965_ensure_config_attribute(obj_config, &attrib_list[i]);
1228 if (vaStatus != VA_STATUS_SUCCESS)
1232 if (vaStatus == VA_STATUS_SUCCESS) {
1233 VAConfigAttrib attrib, *attrib_found;
1234 attrib.type = VAConfigAttribRTFormat;
1235 attrib.value = i965_get_default_chroma_formats(ctx, profile, entrypoint);
1236 attrib_found = i965_lookup_config_attribute(obj_config, attrib.type);
1237 if (!attrib_found || !attrib_found->value)
1238 vaStatus = i965_append_config_attribute(obj_config, &attrib);
1239 else if (!(attrib_found->value & attrib.value))
1240 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
1243 if (vaStatus == VA_STATUS_SUCCESS) {
1244 VAConfigAttrib attrib;
1245 attrib.type = VAConfigAttribEncMaxSlices;
1246 attrib.value = VA_ATTRIB_NOT_SUPPORTED;
1247 if (entrypoint == VAEntrypointEncSlice) {
1248 if ((profile == VAProfileH264ConstrainedBaseline ||
1249 profile == VAProfileH264Main ||
1250 profile == VAProfileH264High) ||
1251 profile == VAProfileH264StereoHigh ||
1252 profile == VAProfileH264MultiviewHigh) {
1253 attrib.value = I965_MAX_NUM_SLICE;
1254 } else if (profile == VAProfileHEVCMain ||
1255 profile == VAProfileHEVCMain10)
1256 attrib.value = I965_MAX_NUM_SLICE;
1257 } else if (entrypoint == VAEntrypointEncSliceLP) {
1258 if ((profile == VAProfileH264ConstrainedBaseline ||
1259 profile == VAProfileH264Main ||
1260 profile == VAProfileH264High) ||
1261 profile == VAProfileH264StereoHigh ||
1262 profile == VAProfileH264MultiviewHigh)
1263 attrib.value = I965_MAX_NUM_SLICE;
1266 if (attrib.value != VA_ATTRIB_NOT_SUPPORTED)
1267 vaStatus = i965_append_config_attribute(obj_config, &attrib);
1270 if (vaStatus == VA_STATUS_SUCCESS) {
1271 VAConfigAttrib attrib;
1272 attrib.type = VAConfigAttribEncSliceStructure;
1273 attrib.value = VA_ATTRIB_NOT_SUPPORTED;
1274 if (entrypoint == VAEntrypointEncSlice) {
1275 if ((profile == VAProfileH264ConstrainedBaseline ||
1276 profile == VAProfileH264Main ||
1277 profile == VAProfileH264High) ||
1278 profile == VAProfileH264StereoHigh ||
1279 profile == VAProfileH264MultiviewHigh) {
1280 attrib.value = VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS;
1284 if(attrib.value != VA_ATTRIB_NOT_SUPPORTED)
1285 vaStatus = i965_append_config_attribute(obj_config, &attrib);
1288 if ((vaStatus == VA_STATUS_SUCCESS) &&
1289 (profile == VAProfileVP9Profile0) &&
1290 (entrypoint == VAEntrypointVLD) &&
1291 !HAS_VP9_DECODING(i965)) {
1293 if (i965->wrapper_pdrvctx) {
1294 VAGenericID wrapper_config;
1296 CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
1297 vaCreateConfig(i965->wrapper_pdrvctx, profile,
1298 entrypoint, attrib_list,
1299 num_attribs, &wrapper_config));
1301 if (vaStatus == VA_STATUS_SUCCESS)
1302 obj_config->wrapper_config = wrapper_config;
1306 /* Error recovery */
1307 if (VA_STATUS_SUCCESS != vaStatus) {
1308 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
1310 *config_id = configID;
1317 i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
1319 struct i965_driver_data *i965 = i965_driver_data(ctx);
1320 struct object_config *obj_config = CONFIG(config_id);
1323 if (NULL == obj_config) {
1324 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
1328 if ((obj_config->wrapper_config != VA_INVALID_ID) &&
1329 i965->wrapper_pdrvctx) {
1330 CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
1331 vaDestroyConfig(i965->wrapper_pdrvctx,
1332 obj_config->wrapper_config));
1333 obj_config->wrapper_config = VA_INVALID_ID;
1336 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
1337 return VA_STATUS_SUCCESS;
1340 VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
1341 VAConfigID config_id,
1342 VAProfile *profile, /* out */
1343 VAEntrypoint *entrypoint, /* out */
1344 VAConfigAttrib *attrib_list, /* out */
1345 int *num_attribs) /* out */
1347 struct i965_driver_data *i965 = i965_driver_data(ctx);
1348 struct object_config *obj_config = CONFIG(config_id);
1349 VAStatus vaStatus = VA_STATUS_SUCCESS;
1352 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
1353 *profile = obj_config->profile;
1354 *entrypoint = obj_config->entrypoint;
1355 *num_attribs = obj_config->num_attribs;
1357 for(i = 0; i < obj_config->num_attribs; i++) {
1358 attrib_list[i] = obj_config->attrib_list[i];
1365 i965_destroy_surface_storage(struct object_surface *obj_surface)
1370 dri_bo_unreference(obj_surface->bo);
1371 obj_surface->bo = NULL;
1373 if (obj_surface->free_private_data != NULL) {
1374 obj_surface->free_private_data(&obj_surface->private_data);
1375 obj_surface->private_data = NULL;
1380 i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
1382 struct object_surface *obj_surface = (struct object_surface *)obj;
1384 i965_destroy_surface_storage(obj_surface);
1385 object_heap_free(heap, obj);
1388 /* byte-per-pixel of the first plane */
1390 bpp_1stplane_by_fourcc(unsigned int fourcc)
1392 const i965_fourcc_info *info = get_fourcc_info(fourcc);
1394 if (info && (info->flag & I_S))
1395 return info->bpp[0] / 8;
1401 i965_surface_native_memory(VADriverContextP ctx,
1402 struct object_surface *obj_surface,
1404 int expected_fourcc)
1406 struct i965_driver_data *i965 = i965_driver_data(ctx);
1407 int tiling = HAS_TILED_SURFACE(i965);
1409 if (!expected_fourcc)
1410 return VA_STATUS_SUCCESS;
1412 // todo, should we disable tiling for 422 format?
1413 if (expected_fourcc == VA_FOURCC_I420 ||
1414 expected_fourcc == VA_FOURCC_IYUV ||
1415 expected_fourcc == VA_FOURCC_I010 ||
1416 expected_fourcc == VA_FOURCC_YV12 ||
1417 expected_fourcc == VA_FOURCC_YV16)
1420 return i965_check_alloc_surface_bo(ctx, obj_surface, tiling, expected_fourcc, get_sampling_from_fourcc(expected_fourcc));
1424 i965_suface_external_memory(VADriverContextP ctx,
1425 struct object_surface *obj_surface,
1426 int external_memory_type,
1427 VASurfaceAttribExternalBuffers *memory_attibute,
1430 struct i965_driver_data *i965 = i965_driver_data(ctx);
1431 unsigned int tiling,swizzle;
1433 obj_surface->size = memory_attibute->data_size;
1434 if (external_memory_type == I965_SURFACE_MEM_GEM_FLINK)
1435 obj_surface->bo = drm_intel_bo_gem_create_from_name(i965->intel.bufmgr,
1436 "gem flinked vaapi surface",
1437 memory_attibute->buffers[index]);
1438 else if (external_memory_type == I965_SURFACE_MEM_DRM_PRIME)
1439 obj_surface->bo = drm_intel_bo_gem_create_from_prime(i965->intel.bufmgr,
1440 memory_attibute->buffers[index],
1443 if (!obj_surface->bo)
1444 return VA_STATUS_ERROR_INVALID_PARAMETER;
1446 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
1447 if (!memory_attibute ||
1448 !memory_attibute->buffers ||
1449 index > memory_attibute->num_buffers)
1450 return VA_STATUS_ERROR_INVALID_PARAMETER;
1452 ASSERT_RET(obj_surface->orig_width == memory_attibute->width, VA_STATUS_ERROR_INVALID_PARAMETER);
1453 ASSERT_RET(obj_surface->orig_height == memory_attibute->height, VA_STATUS_ERROR_INVALID_PARAMETER);
1454 ASSERT_RET(memory_attibute->num_planes >= 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1456 obj_surface->fourcc = memory_attibute->pixel_format;
1457 obj_surface->width = memory_attibute->pitches[0];
1458 int bpp_1stplane = bpp_1stplane_by_fourcc(obj_surface->fourcc);
1459 ASSERT_RET(IS_ALIGNED(obj_surface->width, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1460 ASSERT_RET(obj_surface->width >= obj_surface->orig_width * bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
1462 if (memory_attibute->num_planes == 1)
1463 obj_surface->height = memory_attibute->data_size / obj_surface->width;
1465 obj_surface->height = memory_attibute->offsets[1] / obj_surface->width;
1466 ASSERT_RET(IS_ALIGNED(obj_surface->height, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1467 ASSERT_RET(obj_surface->height >= obj_surface->orig_height, VA_STATUS_ERROR_INVALID_PARAMETER);
1470 ASSERT_RET(IS_ALIGNED(obj_surface->width,128),VA_STATUS_ERROR_INVALID_PARAMETER);
1471 ASSERT_RET(IS_ALIGNED(obj_surface->height,32),VA_STATUS_ERROR_INVALID_PARAMETER);
1473 ASSERT_RET(IS_ALIGNED(obj_surface->width,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
1474 ASSERT_RET(IS_ALIGNED(obj_surface->height,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
1477 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
1478 obj_surface->x_cr_offset = 0;
1479 if ((obj_surface->fourcc == VA_FOURCC_I420 ||
1480 obj_surface->fourcc == VA_FOURCC_IYUV ||
1481 obj_surface->fourcc == VA_FOURCC_I010 ||
1482 obj_surface->fourcc == VA_FOURCC_YV12 ||
1483 obj_surface->fourcc == VA_FOURCC_YV16) && tiling)
1484 return VA_STATUS_ERROR_INVALID_PARAMETER;
1486 switch (obj_surface->fourcc) {
1487 case VA_FOURCC_NV12:
1488 case VA_FOURCC_P010:
1489 ASSERT_RET(memory_attibute->num_planes == 2, VA_STATUS_ERROR_INVALID_PARAMETER);
1490 ASSERT_RET(memory_attibute->pitches[0] == memory_attibute->pitches[1], VA_STATUS_ERROR_INVALID_PARAMETER);
1492 obj_surface->subsampling = SUBSAMPLE_YUV420;
1493 obj_surface->y_cb_offset = obj_surface->height;
1494 obj_surface->y_cr_offset = obj_surface->height;
1495 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1496 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1497 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1499 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
1501 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
1505 case VA_FOURCC_YV12:
1506 case VA_FOURCC_IMC1:
1507 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1508 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1510 obj_surface->subsampling = SUBSAMPLE_YUV420;
1511 obj_surface->y_cr_offset = obj_surface->height;
1512 obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
1513 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1514 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1515 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1517 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
1519 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
1523 case VA_FOURCC_I420:
1524 case VA_FOURCC_IYUV:
1525 case VA_FOURCC_IMC3:
1526 case VA_FOURCC_I010:
1527 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1528 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1530 obj_surface->subsampling = SUBSAMPLE_YUV420;
1531 obj_surface->y_cb_offset = obj_surface->height;
1532 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1533 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1534 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1535 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1537 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
1539 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
1543 case VA_FOURCC_YUY2:
1544 case VA_FOURCC_UYVY:
1545 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1547 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1548 obj_surface->y_cb_offset = 0;
1549 obj_surface->y_cr_offset = 0;
1550 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1551 obj_surface->cb_cr_height = obj_surface->orig_height;
1552 obj_surface->cb_cr_pitch = memory_attibute->pitches[0];
1556 case VA_FOURCC_RGBA:
1557 case VA_FOURCC_RGBX:
1558 case VA_FOURCC_BGRA:
1559 case VA_FOURCC_BGRX:
1560 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1562 obj_surface->subsampling = SUBSAMPLE_RGBX;
1563 obj_surface->y_cb_offset = 0;
1564 obj_surface->y_cr_offset = 0;
1565 obj_surface->cb_cr_width = 0;
1566 obj_surface->cb_cr_height = 0;
1567 obj_surface->cb_cr_pitch = 0;
1571 case VA_FOURCC_Y800: /* monochrome surface */
1572 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1574 obj_surface->subsampling = SUBSAMPLE_YUV400;
1575 obj_surface->y_cb_offset = 0;
1576 obj_surface->y_cr_offset = 0;
1577 obj_surface->cb_cr_width = 0;
1578 obj_surface->cb_cr_height = 0;
1579 obj_surface->cb_cr_pitch = 0;
1583 case VA_FOURCC_411P:
1584 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1585 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1587 obj_surface->subsampling = SUBSAMPLE_YUV411;
1588 obj_surface->y_cb_offset = obj_surface->height;
1589 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1590 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
1591 obj_surface->cb_cr_height = obj_surface->orig_height;
1592 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1594 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
1596 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
1599 case VA_FOURCC_422H:
1600 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1601 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1603 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1604 obj_surface->y_cb_offset = obj_surface->height;
1605 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1606 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1607 obj_surface->cb_cr_height = obj_surface->orig_height;
1608 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1610 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
1612 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
1616 case VA_FOURCC_YV16:
1617 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1618 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1620 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1621 obj_surface->y_cr_offset = memory_attibute->offsets[1] / obj_surface->width;
1622 obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
1623 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1624 obj_surface->cb_cr_height = obj_surface->orig_height;
1625 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1626 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
1630 case VA_FOURCC_422V:
1631 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1632 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1634 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1635 obj_surface->y_cb_offset = obj_surface->height;
1636 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1637 obj_surface->cb_cr_width = obj_surface->orig_width;
1638 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1639 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1641 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
1643 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
1647 case VA_FOURCC_444P:
1648 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1649 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1651 obj_surface->subsampling = SUBSAMPLE_YUV444;
1652 obj_surface->y_cb_offset = obj_surface->height;
1653 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1654 obj_surface->cb_cr_width = obj_surface->orig_width;
1655 obj_surface->cb_cr_height = obj_surface->orig_height;
1656 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1658 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,128),VA_STATUS_ERROR_INVALID_PARAMETER);
1660 ASSERT_RET(IS_ALIGNED(obj_surface->cb_cr_pitch,i965->codec_info->min_linear_wpitch),VA_STATUS_ERROR_INVALID_PARAMETER);
1665 return VA_STATUS_ERROR_INVALID_PARAMETER;
1668 return VA_STATUS_SUCCESS;
1672 i965_CreateSurfaces2(
1673 VADriverContextP ctx,
1674 unsigned int format,
1676 unsigned int height,
1677 VASurfaceID *surfaces,
1678 unsigned int num_surfaces,
1679 VASurfaceAttrib *attrib_list,
1680 unsigned int num_attribs
1683 struct i965_driver_data *i965 = i965_driver_data(ctx);
1685 VAStatus vaStatus = VA_STATUS_SUCCESS;
1686 int expected_fourcc = 0;
1687 int memory_type = I965_SURFACE_MEM_NATIVE; /* native */
1688 VASurfaceAttribExternalBuffers *memory_attibute = NULL;
1690 for (i = 0; i < num_attribs && attrib_list; i++) {
1691 if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
1692 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
1693 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
1694 expected_fourcc = attrib_list[i].value.value.i;
1697 if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&
1698 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
1700 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
1702 if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
1703 memory_type = I965_SURFACE_MEM_GEM_FLINK; /* flinked GEM handle */
1704 else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)
1705 memory_type = I965_SURFACE_MEM_DRM_PRIME; /* drm prime fd */
1706 else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_VA)
1707 memory_type = I965_SURFACE_MEM_NATIVE; /* va native memory, to be allocated */
1710 if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&
1711 (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {
1712 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypePointer, VA_STATUS_ERROR_INVALID_PARAMETER);
1713 memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;
1717 /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used
1718 * for post-processing (including color conversion) */
1719 if (VA_RT_FORMAT_YUV420 != format &&
1720 VA_RT_FORMAT_YUV420_10BPP != format &&
1721 VA_RT_FORMAT_YUV422 != format &&
1722 VA_RT_FORMAT_YUV444 != format &&
1723 VA_RT_FORMAT_YUV411 != format &&
1724 VA_RT_FORMAT_YUV400 != format &&
1725 VA_RT_FORMAT_RGB32 != format) {
1726 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
1729 for (i = 0; i < num_surfaces; i++) {
1730 int surfaceID = NEW_SURFACE_ID();
1731 struct object_surface *obj_surface = SURFACE(surfaceID);
1733 if (NULL == obj_surface) {
1734 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1738 surfaces[i] = surfaceID;
1739 obj_surface->status = VASurfaceReady;
1740 obj_surface->orig_width = width;
1741 obj_surface->orig_height = height;
1742 obj_surface->user_disable_tiling = false;
1743 obj_surface->user_h_stride_set = false;
1744 obj_surface->user_v_stride_set = false;
1745 obj_surface->border_cleared = false;
1747 obj_surface->subpic_render_idx = 0;
1748 for(j = 0; j < I965_MAX_SUBPIC_SUM; j++){
1749 obj_surface->subpic[j] = VA_INVALID_ID;
1750 obj_surface->obj_subpic[j] = NULL;
1753 assert(i965->codec_info->min_linear_wpitch);
1754 assert(i965->codec_info->min_linear_hpitch);
1755 obj_surface->width = ALIGN(width, i965->codec_info->min_linear_wpitch);
1756 obj_surface->height = ALIGN(height, i965->codec_info->min_linear_hpitch);
1757 obj_surface->flags = SURFACE_REFERENCED;
1758 obj_surface->fourcc = 0;
1759 obj_surface->expected_format = format;
1760 obj_surface->bo = NULL;
1761 obj_surface->locked_image_id = VA_INVALID_ID;
1762 obj_surface->derived_image_id = VA_INVALID_ID;
1763 obj_surface->private_data = NULL;
1764 obj_surface->free_private_data = NULL;
1765 obj_surface->subsampling = SUBSAMPLE_YUV420;
1767 obj_surface->wrapper_surface = VA_INVALID_ID;
1768 obj_surface->exported_primefd = -1;
1770 switch (memory_type) {
1771 case I965_SURFACE_MEM_NATIVE:
1772 if (memory_attibute) {
1773 if (!(memory_attibute->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING))
1774 obj_surface->user_disable_tiling = true;
1776 if (memory_attibute->pixel_format) {
1777 if (expected_fourcc)
1778 ASSERT_RET(memory_attibute->pixel_format == expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1780 expected_fourcc = memory_attibute->pixel_format;
1782 ASSERT_RET(expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1783 if (memory_attibute->pitches[0]) {
1784 int bpp_1stplane = bpp_1stplane_by_fourcc(expected_fourcc);
1785 ASSERT_RET(bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
1786 obj_surface->width = memory_attibute->pitches[0];
1787 obj_surface->user_h_stride_set = true;
1788 ASSERT_RET(IS_ALIGNED(obj_surface->width, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1789 ASSERT_RET(obj_surface->width >= width * bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
1791 if (memory_attibute->offsets[1]) {
1792 ASSERT_RET(!memory_attibute->offsets[0], VA_STATUS_ERROR_INVALID_PARAMETER);
1793 obj_surface->height = memory_attibute->offsets[1]/memory_attibute->pitches[0];
1794 obj_surface->user_v_stride_set = true;
1795 ASSERT_RET(IS_ALIGNED(obj_surface->height, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1796 ASSERT_RET(obj_surface->height >= height, VA_STATUS_ERROR_INVALID_PARAMETER);
1800 vaStatus = i965_surface_native_memory(ctx,
1806 case I965_SURFACE_MEM_GEM_FLINK:
1807 case I965_SURFACE_MEM_DRM_PRIME:
1808 vaStatus = i965_suface_external_memory(ctx,
1815 if (VA_STATUS_SUCCESS != vaStatus) {
1816 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1821 /* Error recovery */
1822 if (VA_STATUS_SUCCESS != vaStatus) {
1823 /* surfaces[i-1] was the last successful allocation */
1825 struct object_surface *obj_surface = SURFACE(surfaces[i]);
1827 surfaces[i] = VA_INVALID_SURFACE;
1828 assert(obj_surface);
1829 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1837 i965_CreateSurfaces(VADriverContextP ctx,
1842 VASurfaceID *surfaces) /* out */
1844 return i965_CreateSurfaces2(ctx,
1855 i965_DestroySurfaces(VADriverContextP ctx,
1856 VASurfaceID *surface_list,
1859 struct i965_driver_data *i965 = i965_driver_data(ctx);
1861 VAStatus va_status = VA_STATUS_SUCCESS;
1863 for (i = num_surfaces; i--; ) {
1864 struct object_surface *obj_surface = SURFACE(surface_list[i]);
1866 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
1868 if ((obj_surface->wrapper_surface != VA_INVALID_ID) &&
1869 i965->wrapper_pdrvctx) {
1870 CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
1871 vaDestroySurfaces(i965->wrapper_pdrvctx,
1872 &(obj_surface->wrapper_surface),
1874 obj_surface->wrapper_surface = VA_INVALID_ID;
1876 if (obj_surface->exported_primefd >= 0) {
1877 close(obj_surface->exported_primefd);
1878 obj_surface->exported_primefd = -1;
1881 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1888 i965_QueryImageFormats(VADriverContextP ctx,
1889 VAImageFormat *format_list, /* out */
1890 int *num_formats) /* out */
1894 for (n = 0; i965_image_formats_map[n].va_format.fourcc != 0; n++) {
1895 const i965_image_format_map_t * const m = &i965_image_formats_map[n];
1897 format_list[n] = m->va_format;
1903 return VA_STATUS_SUCCESS;
1907 * Guess the format when the usage of a VA surface is unknown
1908 * 1. Without a valid context: YV12
1909 * 2. The current context is valid:
1910 * a) always NV12 on GEN6 and later
1911 * b) I420 for MPEG-2 and NV12 for other codec on GEN4 & GEN5
1914 i965_guess_surface_format(VADriverContextP ctx,
1915 VASurfaceID surface,
1916 unsigned int *fourcc,
1917 unsigned int *is_tiled)
1919 struct i965_driver_data *i965 = i965_driver_data(ctx);
1920 struct object_context *obj_context = NULL;
1921 struct object_config *obj_config = NULL;
1923 *fourcc = VA_FOURCC_YV12;
1926 if (i965->current_context_id == VA_INVALID_ID)
1929 obj_context = CONTEXT(i965->current_context_id);
1934 obj_config = obj_context->obj_config;
1940 if (IS_GEN6(i965->intel.device_info) ||
1941 IS_GEN7(i965->intel.device_info) ||
1942 IS_GEN8(i965->intel.device_info) ||
1943 IS_GEN9(i965->intel.device_info)) {
1944 *fourcc = VA_FOURCC_NV12;
1949 switch (obj_config->profile) {
1950 case VAProfileMPEG2Simple:
1951 case VAProfileMPEG2Main:
1952 *fourcc = VA_FOURCC_I420;
1957 *fourcc = VA_FOURCC_NV12;
1964 i965_QuerySubpictureFormats(VADriverContextP ctx,
1965 VAImageFormat *format_list, /* out */
1966 unsigned int *flags, /* out */
1967 unsigned int *num_formats) /* out */
1971 for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
1972 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
1974 format_list[n] = m->va_format;
1976 flags[n] = m->va_flags;
1982 return VA_STATUS_SUCCESS;
1986 i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
1988 // struct object_subpic *obj_subpic = (struct object_subpic *)obj;
1990 object_heap_free(heap, obj);
1994 i965_CreateSubpicture(VADriverContextP ctx,
1996 VASubpictureID *subpicture) /* out */
1998 struct i965_driver_data *i965 = i965_driver_data(ctx);
1999 VASubpictureID subpicID = NEW_SUBPIC_ID()
2000 struct object_subpic *obj_subpic = SUBPIC(subpicID);
2003 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2005 struct object_image *obj_image = IMAGE(image);
2007 return VA_STATUS_ERROR_INVALID_IMAGE;
2009 const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
2011 return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
2013 *subpicture = subpicID;
2014 obj_subpic->image = image;
2015 obj_subpic->obj_image = obj_image;
2016 obj_subpic->format = m->format;
2017 obj_subpic->width = obj_image->image.width;
2018 obj_subpic->height = obj_image->image.height;
2019 obj_subpic->pitch = obj_image->image.pitches[0];
2020 obj_subpic->bo = obj_image->bo;
2021 obj_subpic->global_alpha = 1.0;
2023 return VA_STATUS_SUCCESS;
2027 i965_DestroySubpicture(VADriverContextP ctx,
2028 VASubpictureID subpicture)
2030 struct i965_driver_data *i965 = i965_driver_data(ctx);
2031 struct object_subpic *obj_subpic = SUBPIC(subpicture);
2034 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
2036 ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
2037 i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
2038 return VA_STATUS_SUCCESS;
2042 i965_SetSubpictureImage(VADriverContextP ctx,
2043 VASubpictureID subpicture,
2047 return VA_STATUS_ERROR_UNIMPLEMENTED;
2051 i965_SetSubpictureChromakey(VADriverContextP ctx,
2052 VASubpictureID subpicture,
2053 unsigned int chromakey_min,
2054 unsigned int chromakey_max,
2055 unsigned int chromakey_mask)
2058 return VA_STATUS_ERROR_UNIMPLEMENTED;
2062 i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
2063 VASubpictureID subpicture,
2066 struct i965_driver_data *i965 = i965_driver_data(ctx);
2067 struct object_subpic *obj_subpic = SUBPIC(subpicture);
2069 if(global_alpha > 1.0 || global_alpha < 0.0){
2070 return VA_STATUS_ERROR_INVALID_PARAMETER;
2074 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
2076 obj_subpic->global_alpha = global_alpha;
2078 return VA_STATUS_SUCCESS;
2082 i965_AssociateSubpicture(VADriverContextP ctx,
2083 VASubpictureID subpicture,
2084 VASurfaceID *target_surfaces,
2086 short src_x, /* upper left offset in subpicture */
2088 unsigned short src_width,
2089 unsigned short src_height,
2090 short dest_x, /* upper left offset in surface */
2092 unsigned short dest_width,
2093 unsigned short dest_height,
2095 * whether to enable chroma-keying or global-alpha
2096 * see VA_SUBPICTURE_XXX values
2100 struct i965_driver_data *i965 = i965_driver_data(ctx);
2101 struct object_subpic *obj_subpic = SUBPIC(subpicture);
2105 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
2107 ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
2109 obj_subpic->src_rect.x = src_x;
2110 obj_subpic->src_rect.y = src_y;
2111 obj_subpic->src_rect.width = src_width;
2112 obj_subpic->src_rect.height = src_height;
2113 obj_subpic->dst_rect.x = dest_x;
2114 obj_subpic->dst_rect.y = dest_y;
2115 obj_subpic->dst_rect.width = dest_width;
2116 obj_subpic->dst_rect.height = dest_height;
2117 obj_subpic->flags = flags;
2119 for (i = 0; i < num_surfaces; i++) {
2120 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
2122 return VA_STATUS_ERROR_INVALID_SURFACE;
2124 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
2125 if(obj_surface->subpic[j] == VA_INVALID_ID){
2126 assert(obj_surface->obj_subpic[j] == NULL);
2127 obj_surface->subpic[j] = subpicture;
2128 obj_surface->obj_subpic[j] = obj_subpic;
2133 if(j == I965_MAX_SUBPIC_SUM){
2134 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2138 return VA_STATUS_SUCCESS;
2143 i965_DeassociateSubpicture(VADriverContextP ctx,
2144 VASubpictureID subpicture,
2145 VASurfaceID *target_surfaces,
2148 struct i965_driver_data *i965 = i965_driver_data(ctx);
2149 struct object_subpic *obj_subpic = SUBPIC(subpicture);
2153 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
2155 for (i = 0; i < num_surfaces; i++) {
2156 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
2158 return VA_STATUS_ERROR_INVALID_SURFACE;
2160 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
2161 if (obj_surface->subpic[j] == subpicture) {
2162 assert(obj_surface->obj_subpic[j] == obj_subpic);
2163 obj_surface->subpic[j] = VA_INVALID_ID;
2164 obj_surface->obj_subpic[j] = NULL;
2169 if(j == I965_MAX_SUBPIC_SUM){
2170 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2173 return VA_STATUS_SUCCESS;
2177 i965_reference_buffer_store(struct buffer_store **ptr,
2178 struct buffer_store *buffer_store)
2180 assert(*ptr == NULL);
2183 buffer_store->ref_count++;
2184 *ptr = buffer_store;
2189 i965_release_buffer_store(struct buffer_store **ptr)
2191 struct buffer_store *buffer_store = *ptr;
2193 if (buffer_store == NULL)
2196 assert(buffer_store->bo || buffer_store->buffer);
2197 assert(!(buffer_store->bo && buffer_store->buffer));
2198 buffer_store->ref_count--;
2200 if (buffer_store->ref_count == 0) {
2201 dri_bo_unreference(buffer_store->bo);
2202 free(buffer_store->buffer);
2203 buffer_store->bo = NULL;
2204 buffer_store->buffer = NULL;
2212 i965_destroy_context(struct object_heap *heap, struct object_base *obj)
2214 struct object_context *obj_context = (struct object_context *)obj;
2217 if (obj_context->hw_context) {
2218 obj_context->hw_context->destroy(obj_context->hw_context);
2219 obj_context->hw_context = NULL;
2222 if (obj_context->codec_type == CODEC_PROC) {
2223 i965_release_buffer_store(&obj_context->codec_state.proc.pipeline_param);
2225 } else if (obj_context->codec_type == CODEC_ENC) {
2226 i965_release_buffer_store(&obj_context->codec_state.encode.q_matrix);
2227 i965_release_buffer_store(&obj_context->codec_state.encode.huffman_table);
2229 assert(obj_context->codec_state.encode.num_slice_params_ext <= obj_context->codec_state.encode.max_slice_params_ext);
2230 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
2231 i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
2233 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
2234 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
2236 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
2237 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
2239 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
2240 for (j = 0; j < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param[0]); j++)
2241 i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i][j]);
2243 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
2244 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
2246 free(obj_context->codec_state.encode.slice_params_ext);
2247 if (obj_context->codec_state.encode.slice_rawdata_index) {
2248 free(obj_context->codec_state.encode.slice_rawdata_index);
2249 obj_context->codec_state.encode.slice_rawdata_index = NULL;
2251 if (obj_context->codec_state.encode.slice_rawdata_count) {
2252 free(obj_context->codec_state.encode.slice_rawdata_count);
2253 obj_context->codec_state.encode.slice_rawdata_count = NULL;
2256 if (obj_context->codec_state.encode.slice_header_index) {
2257 free(obj_context->codec_state.encode.slice_header_index);
2258 obj_context->codec_state.encode.slice_header_index = NULL;
2261 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
2262 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
2263 free(obj_context->codec_state.encode.packed_header_params_ext);
2265 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
2266 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
2267 free(obj_context->codec_state.encode.packed_header_data_ext);
2269 i965_release_buffer_store(&obj_context->codec_state.encode.encmb_map);
2271 assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
2272 assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
2274 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
2275 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
2276 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
2278 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++)
2279 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
2281 for (i = 0; i < obj_context->codec_state.decode.num_slice_datas; i++)
2282 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
2284 free(obj_context->codec_state.decode.slice_params);
2285 free(obj_context->codec_state.decode.slice_datas);
2288 free(obj_context->render_targets);
2289 object_heap_free(heap, obj);
2293 max_resolution(struct i965_driver_data *i965,
2294 struct object_config *obj_config,
2298 if (i965->codec_info->max_resolution) {
2299 i965->codec_info->max_resolution(i965, obj_config, w, h);
2301 *w = i965->codec_info->max_width;
2302 *h = i965->codec_info->max_height;
2307 i965_CreateContext(VADriverContextP ctx,
2308 VAConfigID config_id,
2312 VASurfaceID *render_targets,
2313 int num_render_targets,
2314 VAContextID *context) /* out */
2316 struct i965_driver_data *i965 = i965_driver_data(ctx);
2317 struct object_config *obj_config = CONFIG(config_id);
2318 struct object_context *obj_context = NULL;
2319 VAConfigAttrib *attrib;
2320 VAStatus vaStatus = VA_STATUS_SUCCESS;
2326 if (NULL == obj_config) {
2327 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
2331 max_resolution(i965, obj_config, &max_width, &max_height);
2333 if (picture_width > max_width ||
2334 picture_height > max_height) {
2335 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
2340 /* Validate picture dimensions */
2341 contextID = NEW_CONTEXT_ID();
2342 obj_context = CONTEXT(contextID);
2344 if (NULL == obj_context) {
2345 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2349 *context = contextID;
2350 obj_context->flags = flag;
2351 obj_context->context_id = contextID;
2352 obj_context->obj_config = obj_config;
2353 obj_context->picture_width = picture_width;
2354 obj_context->picture_height = picture_height;
2355 obj_context->num_render_targets = num_render_targets;
2356 obj_context->render_targets =
2357 (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
2358 obj_context->hw_context = NULL;
2359 obj_context->wrapper_context = VA_INVALID_ID;
2361 if (!obj_context->render_targets)
2362 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2364 for(i = 0; i < num_render_targets; i++) {
2365 if (NULL == SURFACE(render_targets[i])) {
2366 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
2370 obj_context->render_targets[i] = render_targets[i];
2373 if (VA_STATUS_SUCCESS == vaStatus) {
2374 if (VAEntrypointVideoProc == obj_config->entrypoint) {
2375 obj_context->codec_type = CODEC_PROC;
2376 memset(&obj_context->codec_state.proc, 0, sizeof(obj_context->codec_state.proc));
2377 obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
2378 assert(i965->codec_info->proc_hw_context_init);
2379 obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
2380 } else if ((VAEntrypointEncSlice == obj_config->entrypoint) ||
2381 (VAEntrypointEncPicture == obj_config->entrypoint) ||
2382 (VAEntrypointEncSliceLP == obj_config->entrypoint)) {
2383 VAConfigAttrib *packed_attrib;
2384 obj_context->codec_type = CODEC_ENC;
2385 memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
2386 obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
2387 obj_context->codec_state.encode.max_packed_header_params_ext = NUM_SLICES;
2388 obj_context->codec_state.encode.packed_header_params_ext =
2389 calloc(obj_context->codec_state.encode.max_packed_header_params_ext,
2390 sizeof(struct buffer_store *));
2392 obj_context->codec_state.encode.max_packed_header_data_ext = NUM_SLICES;
2393 obj_context->codec_state.encode.packed_header_data_ext =
2394 calloc(obj_context->codec_state.encode.max_packed_header_data_ext,
2395 sizeof(struct buffer_store *));
2397 obj_context->codec_state.encode.max_slice_num = NUM_SLICES;
2398 obj_context->codec_state.encode.slice_rawdata_index =
2399 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
2400 obj_context->codec_state.encode.slice_rawdata_count =
2401 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
2403 obj_context->codec_state.encode.slice_header_index =
2404 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
2406 obj_context->codec_state.encode.vps_sps_seq_index = 0;
2408 obj_context->codec_state.encode.slice_index = 0;
2409 packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders);
2410 if (packed_attrib) {
2411 obj_context->codec_state.encode.packed_header_flag = packed_attrib->value;
2412 if (obj_config->profile == VAProfileVP9Profile0)
2413 obj_context->codec_state.encode.packed_header_flag =
2414 packed_attrib->value & VA_ENC_PACKED_HEADER_RAW_DATA;
2416 /* use the default value. SPS/PPS/RAWDATA is passed from user
2417 * while Slice_header data is generated by driver.
2419 obj_context->codec_state.encode.packed_header_flag =
2420 VA_ENC_PACKED_HEADER_SEQUENCE |
2421 VA_ENC_PACKED_HEADER_PICTURE |
2422 VA_ENC_PACKED_HEADER_RAW_DATA;
2424 /* it is not used for VP9 */
2425 if (obj_config->profile == VAProfileVP9Profile0)
2426 obj_context->codec_state.encode.packed_header_flag = 0;
2428 assert(i965->codec_info->enc_hw_context_init);
2429 obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
2431 obj_context->codec_type = CODEC_DEC;
2432 memset(&obj_context->codec_state.decode, 0, sizeof(obj_context->codec_state.decode));
2433 obj_context->codec_state.decode.current_render_target = -1;
2434 obj_context->codec_state.decode.max_slice_params = NUM_SLICES;
2435 obj_context->codec_state.decode.max_slice_datas = NUM_SLICES;
2436 obj_context->codec_state.decode.slice_params = calloc(obj_context->codec_state.decode.max_slice_params,
2437 sizeof(*obj_context->codec_state.decode.slice_params));
2438 obj_context->codec_state.decode.slice_datas = calloc(obj_context->codec_state.decode.max_slice_datas,
2439 sizeof(*obj_context->codec_state.decode.slice_datas));
2441 assert(i965->codec_info->dec_hw_context_init);
2442 obj_context->hw_context = i965->codec_info->dec_hw_context_init(ctx, obj_config);
2446 attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribRTFormat);
2448 return VA_STATUS_ERROR_INVALID_CONFIG;
2449 obj_context->codec_state.base.chroma_formats = attrib->value;
2451 if (obj_config->wrapper_config != VA_INVALID_ID) {
2452 /* The wrapper_pdrvctx should exist when wrapper_config is valid.
2453 * So it won't check i965->wrapper_pdrvctx again.
2454 * Fixme if it is incorrect.
2456 VAGenericID wrapper_context;
2459 * The render_surface is not passed when calling
2461 * If it is needed, we must get the wrapped surface
2462 * for the corresponding Surface_list.
2463 * So the wrapped surface conversion is deferred.
2465 CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
2466 vaCreateContext(i965->wrapper_pdrvctx,
2467 obj_config->wrapper_config,
2468 picture_width, picture_height,
2472 if (vaStatus == VA_STATUS_SUCCESS)
2473 obj_context->wrapper_context = wrapper_context;
2475 /* Error recovery */
2476 if (VA_STATUS_SUCCESS != vaStatus) {
2477 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
2480 i965->current_context_id = contextID;
2486 i965_DestroyContext(VADriverContextP ctx, VAContextID context)
2488 struct i965_driver_data *i965 = i965_driver_data(ctx);
2489 struct object_context *obj_context = CONTEXT(context);
2490 VAStatus va_status = VA_STATUS_SUCCESS;
2492 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2494 if (i965->current_context_id == context)
2495 i965->current_context_id = VA_INVALID_ID;
2497 if ((obj_context->wrapper_context != VA_INVALID_ID) &&
2498 i965->wrapper_pdrvctx) {
2499 CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
2500 vaDestroyContext(i965->wrapper_pdrvctx,
2501 obj_context->wrapper_context));
2503 obj_context->wrapper_context = VA_INVALID_ID;
2506 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
2512 i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
2514 struct object_buffer *obj_buffer = (struct object_buffer *)obj;
2516 assert(obj_buffer->buffer_store);
2517 i965_release_buffer_store(&obj_buffer->buffer_store);
2518 object_heap_free(heap, obj);
2522 i965_create_buffer_internal(VADriverContextP ctx,
2523 VAContextID context,
2526 unsigned int num_elements,
2531 struct i965_driver_data *i965 = i965_driver_data(ctx);
2532 struct object_buffer *obj_buffer = NULL;
2533 struct buffer_store *buffer_store = NULL;
2535 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2536 struct object_context *obj_context = CONTEXT(context);
2537 int wrapper_flag = 0;
2541 case VAPictureParameterBufferType:
2542 case VAIQMatrixBufferType:
2543 case VAQMatrixBufferType:
2544 case VABitPlaneBufferType:
2545 case VASliceGroupMapBufferType:
2546 case VASliceParameterBufferType:
2547 case VASliceDataBufferType:
2548 case VAMacroblockParameterBufferType:
2549 case VAResidualDataBufferType:
2550 case VADeblockingParameterBufferType:
2551 case VAImageBufferType:
2552 case VAEncCodedBufferType:
2553 case VAEncSequenceParameterBufferType:
2554 case VAEncPictureParameterBufferType:
2555 case VAEncSliceParameterBufferType:
2556 case VAEncPackedHeaderParameterBufferType:
2557 case VAEncPackedHeaderDataBufferType:
2558 case VAEncMiscParameterBufferType:
2559 case VAProcPipelineParameterBufferType:
2560 case VAProcFilterParameterBufferType:
2561 case VAHuffmanTableBufferType:
2562 case VAProbabilityBufferType:
2563 case VAEncMacroblockMapBufferType:
2568 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2571 bufferID = NEW_BUFFER_ID();
2572 obj_buffer = BUFFER(bufferID);
2574 if (NULL == obj_buffer) {
2575 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2578 if (type == VAEncCodedBufferType) {
2579 size += I965_CODEDBUFFER_HEADER_SIZE;
2580 size += 0x1000; /* for upper bound check */
2583 obj_buffer->max_num_elements = num_elements;
2584 obj_buffer->num_elements = num_elements;
2585 obj_buffer->size_element = size;
2586 obj_buffer->type = type;
2587 obj_buffer->export_refcount = 0;
2588 obj_buffer->buffer_store = NULL;
2589 obj_buffer->wrapper_buffer = VA_INVALID_ID;
2590 obj_buffer->context_id = context;
2592 buffer_store = calloc(1, sizeof(struct buffer_store));
2593 assert(buffer_store);
2594 buffer_store->ref_count = 1;
2597 (obj_context->wrapper_context != VA_INVALID_ID) &&
2598 i965->wrapper_pdrvctx) {
2599 VAGenericID wrapper_buffer;
2600 VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
2602 CALL_VTABLE(pdrvctx, vaStatus,
2603 vaCreateBuffer(pdrvctx, obj_context->wrapper_context, type, size, num_elements,
2604 data, &wrapper_buffer));
2605 if (vaStatus == VA_STATUS_SUCCESS) {
2606 obj_buffer->wrapper_buffer = wrapper_buffer;
2614 if (store_bo != NULL) {
2615 buffer_store->bo = store_bo;
2616 dri_bo_reference(buffer_store->bo);
2618 /* If the buffer is wrapped, the buffer_store is bogus. Unnecessary to copy it */
2619 if (data && !wrapper_flag)
2620 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
2621 } else if (type == VASliceDataBufferType ||
2622 type == VAImageBufferType ||
2623 type == VAEncCodedBufferType ||
2624 type == VAEncMacroblockMapBufferType ||
2625 type == VAProbabilityBufferType) {
2627 /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
2628 * So it is enough to allocate one 64 byte bo
2631 buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr, "Bogus buffer",
2634 buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
2636 size * num_elements, 64);
2637 assert(buffer_store->bo);
2639 /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
2640 * In fact it can be skipped. But it is still allocated and it is
2641 * only to follow the normal flowchart of buffer_allocation/release.
2643 if (!wrapper_flag) {
2644 if (type == VAEncCodedBufferType) {
2645 struct i965_coded_buffer_segment *coded_buffer_segment;
2647 dri_bo_map(buffer_store->bo, 1);
2648 coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual;
2649 coded_buffer_segment->base.size = size - I965_CODEDBUFFER_HEADER_SIZE;
2650 coded_buffer_segment->base.bit_offset = 0;
2651 coded_buffer_segment->base.status = 0;
2652 coded_buffer_segment->base.buf = NULL;
2653 coded_buffer_segment->base.next = NULL;
2654 coded_buffer_segment->mapped = 0;
2655 coded_buffer_segment->codec = 0;
2656 coded_buffer_segment->status_support = 0;
2657 dri_bo_unmap(buffer_store->bo);
2659 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
2666 if (type == VAEncPackedHeaderDataBufferType) {
2667 msize = ALIGN(size, 4);
2670 /* If the buffer is wrapped, it is enough to allocate 4 bytes */
2672 buffer_store->buffer = malloc(4);
2674 buffer_store->buffer = malloc(msize * num_elements);
2675 assert(buffer_store->buffer);
2677 if (!wrapper_flag) {
2679 memcpy(buffer_store->buffer, data, size * num_elements);
2681 memset(buffer_store->buffer, 0, size * num_elements);
2685 buffer_store->num_elements = obj_buffer->num_elements;
2686 i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
2687 i965_release_buffer_store(&buffer_store);
2690 return VA_STATUS_SUCCESS;
2694 i965_CreateBuffer(VADriverContextP ctx,
2695 VAContextID context, /* in */
2696 VABufferType type, /* in */
2697 unsigned int size, /* in */
2698 unsigned int num_elements, /* in */
2699 void *data, /* in */
2700 VABufferID *buf_id) /* out */
2702 return i965_create_buffer_internal(ctx, context, type, size, num_elements, data, NULL, buf_id);
2707 i965_BufferSetNumElements(VADriverContextP ctx,
2708 VABufferID buf_id, /* in */
2709 unsigned int num_elements) /* in */
2711 struct i965_driver_data *i965 = i965_driver_data(ctx);
2712 struct object_buffer *obj_buffer = BUFFER(buf_id);
2713 VAStatus vaStatus = VA_STATUS_SUCCESS;
2715 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2717 /* When the wrapper_buffer exists, it will wrapper to the
2718 * buffer allocated from backend driver.
2720 if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
2721 i965->wrapper_pdrvctx) {
2722 VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
2724 CALL_VTABLE(pdrvctx, vaStatus,
2725 vaBufferSetNumElements(pdrvctx, obj_buffer->wrapper_buffer,
2730 if ((num_elements < 0) ||
2731 (num_elements > obj_buffer->max_num_elements)) {
2732 vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2734 obj_buffer->num_elements = num_elements;
2735 if (obj_buffer->buffer_store != NULL) {
2736 obj_buffer->buffer_store->num_elements = num_elements;
2744 i965_MapBuffer(VADriverContextP ctx,
2745 VABufferID buf_id, /* in */
2746 void **pbuf) /* out */
2748 struct i965_driver_data *i965 = i965_driver_data(ctx);
2749 struct object_buffer *obj_buffer = BUFFER(buf_id);
2750 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2751 struct object_context *obj_context;
2753 ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
2755 obj_context = CONTEXT(obj_buffer->context_id);
2757 /* When the wrapper_buffer exists, it will wrapper to the
2758 * buffer allocated from backend driver.
2760 if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
2761 i965->wrapper_pdrvctx) {
2762 VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
2764 CALL_VTABLE(pdrvctx, vaStatus,
2765 vaMapBuffer(pdrvctx, obj_buffer->wrapper_buffer, pbuf));
2769 ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2770 ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_INVALID_BUFFER);
2772 if (obj_buffer->export_refcount > 0)
2773 return VA_STATUS_ERROR_INVALID_BUFFER;
2775 if (NULL != obj_buffer->buffer_store->bo) {
2776 unsigned int tiling, swizzle;
2778 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
2780 if (tiling != I915_TILING_NONE)
2781 drm_intel_gem_bo_map_gtt(obj_buffer->buffer_store->bo);
2783 dri_bo_map(obj_buffer->buffer_store->bo, 1);
2785 ASSERT_RET(obj_buffer->buffer_store->bo->virtual, VA_STATUS_ERROR_OPERATION_FAILED);
2786 *pbuf = obj_buffer->buffer_store->bo->virtual;
2787 vaStatus = VA_STATUS_SUCCESS;
2789 if (obj_buffer->type == VAEncCodedBufferType) {
2791 unsigned char *buffer = NULL;
2792 unsigned int header_offset = I965_CODEDBUFFER_HEADER_SIZE;
2793 struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual);
2795 if (!coded_buffer_segment->mapped) {
2796 unsigned char delimiter0, delimiter1, delimiter2, delimiter3, delimiter4;
2798 coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
2801 obj_context->hw_context &&
2802 obj_context->hw_context->get_status &&
2803 coded_buffer_segment->status_support) {
2804 vaStatus = obj_context->hw_context->get_status(ctx, obj_context->hw_context, coded_buffer_segment);
2806 if (coded_buffer_segment->codec == CODEC_H264 ||
2807 coded_buffer_segment->codec == CODEC_H264_MVC) {
2808 delimiter0 = H264_DELIMITER0;
2809 delimiter1 = H264_DELIMITER1;
2810 delimiter2 = H264_DELIMITER2;
2811 delimiter3 = H264_DELIMITER3;
2812 delimiter4 = H264_DELIMITER4;
2813 } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
2814 delimiter0 = MPEG2_DELIMITER0;
2815 delimiter1 = MPEG2_DELIMITER1;
2816 delimiter2 = MPEG2_DELIMITER2;
2817 delimiter3 = MPEG2_DELIMITER3;
2818 delimiter4 = MPEG2_DELIMITER4;
2819 } else if(coded_buffer_segment->codec == CODEC_JPEG) {
2820 //In JPEG End of Image (EOI = 0xDDF9) marker can be used for delimiter.
2823 } else if (coded_buffer_segment->codec == CODEC_HEVC) {
2824 delimiter0 = HEVC_DELIMITER0;
2825 delimiter1 = HEVC_DELIMITER1;
2826 delimiter2 = HEVC_DELIMITER2;
2827 delimiter3 = HEVC_DELIMITER3;
2828 delimiter4 = HEVC_DELIMITER4;
2829 } else if (coded_buffer_segment->codec != CODEC_VP8) {
2830 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
2833 if(coded_buffer_segment->codec == CODEC_JPEG) {
2834 for(i = 0; i < obj_buffer->size_element - header_offset - 1 - 0x1000; i++) {
2835 if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) {
2839 coded_buffer_segment->base.size = i + 2;
2840 } else if (coded_buffer_segment->codec != CODEC_VP8) {
2841 /* vp8 coded buffer size can be told by vp8 internal statistics buffer,
2842 so it don't need to traversal the coded buffer */
2843 for (i = 0; i < obj_buffer->size_element - header_offset - 3 - 0x1000; i++) {
2844 if ((buffer[i] == delimiter0) &&
2845 (buffer[i + 1] == delimiter1) &&
2846 (buffer[i + 2] == delimiter2) &&
2847 (buffer[i + 3] == delimiter3) &&
2848 (buffer[i + 4] == delimiter4))
2852 if (i == obj_buffer->size_element - header_offset - 3 - 0x1000) {
2853 coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
2855 coded_buffer_segment->base.size = i;
2858 if (coded_buffer_segment->base.size >= obj_buffer->size_element - header_offset - 0x1000) {
2859 coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
2862 vaStatus = VA_STATUS_SUCCESS;
2865 coded_buffer_segment->mapped = 1;
2867 assert(coded_buffer_segment->base.buf);
2868 vaStatus = VA_STATUS_SUCCESS;
2871 } else if (NULL != obj_buffer->buffer_store->buffer) {
2872 *pbuf = obj_buffer->buffer_store->buffer;
2873 vaStatus = VA_STATUS_SUCCESS;
2880 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
2882 struct i965_driver_data *i965 = i965_driver_data(ctx);
2883 struct object_buffer *obj_buffer = BUFFER(buf_id);
2884 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2886 if ((buf_id & OBJECT_HEAP_OFFSET_MASK) != BUFFER_ID_OFFSET)
2887 return VA_STATUS_ERROR_INVALID_BUFFER;
2889 ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
2890 /* When the wrapper_buffer exists, it will wrapper to the
2891 * buffer allocated from backend driver.
2893 if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
2894 i965->wrapper_pdrvctx) {
2895 VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
2897 CALL_VTABLE(pdrvctx, vaStatus,
2898 vaUnmapBuffer(pdrvctx, obj_buffer->wrapper_buffer));
2902 ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_OPERATION_FAILED);
2903 ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_OPERATION_FAILED);
2905 if (NULL != obj_buffer->buffer_store->bo) {
2906 unsigned int tiling, swizzle;
2908 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
2910 if (tiling != I915_TILING_NONE)
2911 drm_intel_gem_bo_unmap_gtt(obj_buffer->buffer_store->bo);
2913 dri_bo_unmap(obj_buffer->buffer_store->bo);
2915 vaStatus = VA_STATUS_SUCCESS;
2916 } else if (NULL != obj_buffer->buffer_store->buffer) {
2918 vaStatus = VA_STATUS_SUCCESS;
2925 i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
2927 struct i965_driver_data *i965 = i965_driver_data(ctx);
2928 struct object_buffer *obj_buffer = BUFFER(buffer_id);
2929 VAStatus va_status = VA_STATUS_SUCCESS;
2931 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2933 if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
2934 i965->wrapper_pdrvctx) {
2935 CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
2936 vaDestroyBuffer(i965->wrapper_pdrvctx,
2937 obj_buffer->wrapper_buffer));
2938 obj_buffer->wrapper_buffer = VA_INVALID_ID;
2941 i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
2947 i965_BeginPicture(VADriverContextP ctx,
2948 VAContextID context,
2949 VASurfaceID render_target)
2951 struct i965_driver_data *i965 = i965_driver_data(ctx);
2952 struct object_context *obj_context = CONTEXT(context);
2953 struct object_surface *obj_surface = SURFACE(render_target);
2954 struct object_config *obj_config;
2955 VAStatus vaStatus = VA_STATUS_SUCCESS;
2958 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2959 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2960 obj_config = obj_context->obj_config;
2961 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2963 if (is_surface_busy(i965, obj_surface))
2964 return VA_STATUS_ERROR_SURFACE_BUSY;
2966 if (obj_context->codec_type == CODEC_PROC) {
2967 obj_context->codec_state.proc.current_render_target = render_target;
2968 } else if (obj_context->codec_type == CODEC_ENC) {
2970 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
2972 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
2973 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
2975 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
2976 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
2978 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
2979 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
2981 obj_context->codec_state.encode.num_slice_params_ext = 0;
2982 obj_context->codec_state.encode.current_render_target = render_target; /*This is input new frame*/
2983 obj_context->codec_state.encode.last_packed_header_type = 0;
2984 memset(obj_context->codec_state.encode.slice_rawdata_index, 0,
2985 sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2986 memset(obj_context->codec_state.encode.slice_rawdata_count, 0,
2987 sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2988 memset(obj_context->codec_state.encode.slice_header_index, 0,
2989 sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2991 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
2992 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
2993 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
2994 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
2995 obj_context->codec_state.encode.num_packed_header_params_ext = 0;
2996 obj_context->codec_state.encode.num_packed_header_data_ext = 0;
2997 obj_context->codec_state.encode.slice_index = 0;
2998 obj_context->codec_state.encode.vps_sps_seq_index = 0;
3000 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
3001 for (j = 0; j < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param[0]); j++)
3002 i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i][j]);
3004 i965_release_buffer_store(&obj_context->codec_state.encode.encmb_map);
3006 obj_context->codec_state.decode.current_render_target = render_target;
3007 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
3008 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
3009 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
3010 i965_release_buffer_store(&obj_context->codec_state.decode.huffman_table);
3012 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++) {
3013 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
3014 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
3017 obj_context->codec_state.decode.num_slice_params = 0;
3018 obj_context->codec_state.decode.num_slice_datas = 0;
3020 if ((obj_context->wrapper_context != VA_INVALID_ID) &&
3021 i965->wrapper_pdrvctx) {
3022 if (obj_surface->wrapper_surface == VA_INVALID_ID)
3023 vaStatus = i965_surface_wrapper(ctx, render_target);
3025 if (vaStatus != VA_STATUS_SUCCESS)
3028 CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
3029 vaBeginPicture(i965->wrapper_pdrvctx,
3030 obj_context->wrapper_context,
3031 obj_surface->wrapper_surface));
3038 #define I965_RENDER_BUFFER(category, name) i965_render_##category##_##name##_buffer(ctx, obj_context, obj_buffer)
3040 #define DEF_RENDER_SINGLE_BUFFER_FUNC(category, name, member) \
3042 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
3043 struct object_context *obj_context, \
3044 struct object_buffer *obj_buffer) \
3046 struct category##_state *category = &obj_context->codec_state.category; \
3047 i965_release_buffer_store(&category->member); \
3048 i965_reference_buffer_store(&category->member, obj_buffer->buffer_store); \
3049 return VA_STATUS_SUCCESS; \
3052 #define DEF_RENDER_MULTI_BUFFER_FUNC(category, name, member) \
3054 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
3055 struct object_context *obj_context, \
3056 struct object_buffer *obj_buffer) \
3058 struct category##_state *category = &obj_context->codec_state.category; \
3059 if (category->num_##member == category->max_##member) { \
3060 category->member = realloc(category->member, (category->max_##member + NUM_SLICES) * sizeof(*category->member)); \
3061 memset(category->member + category->max_##member, 0, NUM_SLICES * sizeof(*category->member)); \
3062 category->max_##member += NUM_SLICES; \
3064 i965_release_buffer_store(&category->member[category->num_##member]); \
3065 i965_reference_buffer_store(&category->member[category->num_##member], obj_buffer->buffer_store); \
3066 category->num_##member++; \
3067 return VA_STATUS_SUCCESS; \
3070 #define I965_RENDER_DECODE_BUFFER(name) I965_RENDER_BUFFER(decode, name)
3072 #define DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(decode, name, member)
3073 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
3074 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(iq_matrix, iq_matrix)
3075 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(bit_plane, bit_plane)
3076 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
3077 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(probability_data, probability_data)
3079 #define DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(decode, name, member)
3080 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
3081 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_data, slice_datas)
3085 i965_decoder_vp9_wrapper_picture(VADriverContextP ctx,
3086 VABufferID *buffers,
3089 struct i965_driver_data *i965 = i965_driver_data(ctx);
3090 VAStatus vaStatus = VA_STATUS_SUCCESS;
3092 VADecPictureParameterBufferVP9 *pVp9PicParams;
3093 VADriverContextP pdrvctx;
3094 struct object_buffer *obj_buffer;
3096 pdrvctx = i965->wrapper_pdrvctx;
3097 /* do the conversion of VADecPictureParameterBufferVP9 */
3098 for (i = 0; i < num_buffers; i++) {
3099 obj_buffer = BUFFER(buffers[i]);
3104 if (obj_buffer->wrapper_buffer == VA_INVALID_ID)
3107 if (obj_buffer->type == VAPictureParameterBufferType) {
3109 VASurfaceID surface_id;
3110 struct object_surface *obj_surface;
3112 pdrvctx = i965->wrapper_pdrvctx;
3114 CALL_VTABLE(pdrvctx, vaStatus,
3115 vaMapBuffer(pdrvctx, obj_buffer->wrapper_buffer,
3116 (void **)(&pVp9PicParams)));
3118 if (vaStatus != VA_STATUS_SUCCESS)
3121 for (j = 0; j < 8; j++) {
3122 surface_id = pVp9PicParams->reference_frames[j];
3123 obj_surface = SURFACE(surface_id);
3128 if (obj_surface->wrapper_surface == VA_INVALID_ID) {
3129 vaStatus = i965_surface_wrapper(ctx, surface_id);
3130 if (vaStatus != VA_STATUS_SUCCESS) {
3131 pdrvctx->vtable->vaUnmapBuffer(pdrvctx,
3132 obj_buffer->wrapper_buffer);
3137 pVp9PicParams->reference_frames[j] = obj_surface->wrapper_surface;
3139 CALL_VTABLE(pdrvctx, vaStatus,
3140 vaUnmapBuffer(pdrvctx, obj_buffer->wrapper_buffer));
3145 return VA_STATUS_SUCCESS;
3152 i965_decoder_wrapper_picture(VADriverContextP ctx,
3153 VAContextID context,
3154 VABufferID *buffers,
3157 struct i965_driver_data *i965 = i965_driver_data(ctx);
3158 struct object_context *obj_context = CONTEXT(context);
3159 VAStatus vaStatus = VA_STATUS_SUCCESS;
3161 VADriverContextP pdrvctx;
3162 struct object_buffer *obj_buffer;
3164 if (obj_context == NULL)
3165 return VA_STATUS_ERROR_INVALID_CONTEXT;
3167 /* When it is not wrapped context, continue the normal flowchart */
3168 if (obj_context->wrapper_context == VA_INVALID_ID)
3171 if (obj_context->obj_config &&
3172 (obj_context->obj_config->profile == VAProfileVP9Profile0)) {
3173 vaStatus = i965_decoder_vp9_wrapper_picture(ctx, buffers, num_buffers);
3175 return VA_STATUS_ERROR_INVALID_PARAMETER;
3177 pdrvctx = i965->wrapper_pdrvctx;
3179 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
3180 obj_buffer = BUFFER(buffers[i]);
3185 if (obj_buffer->wrapper_buffer == VA_INVALID_ID) {
3186 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
3190 CALL_VTABLE(pdrvctx, vaStatus,
3191 vaRenderPicture(pdrvctx, obj_context->wrapper_context,
3192 &(obj_buffer->wrapper_buffer), 1));
3198 i965_decoder_render_picture(VADriverContextP ctx,
3199 VAContextID context,
3200 VABufferID *buffers,
3203 struct i965_driver_data *i965 = i965_driver_data(ctx);
3204 struct object_context *obj_context = CONTEXT(context);
3205 VAStatus vaStatus = VA_STATUS_SUCCESS;
3208 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
3210 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
3211 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
3214 return VA_STATUS_ERROR_INVALID_BUFFER;
3216 switch (obj_buffer->type) {
3217 case VAPictureParameterBufferType:
3218 vaStatus = I965_RENDER_DECODE_BUFFER(picture_parameter);
3221 case VAIQMatrixBufferType:
3222 vaStatus = I965_RENDER_DECODE_BUFFER(iq_matrix);
3225 case VABitPlaneBufferType:
3226 vaStatus = I965_RENDER_DECODE_BUFFER(bit_plane);
3229 case VASliceParameterBufferType:
3230 vaStatus = I965_RENDER_DECODE_BUFFER(slice_parameter);
3233 case VASliceDataBufferType:
3234 vaStatus = I965_RENDER_DECODE_BUFFER(slice_data);
3237 case VAHuffmanTableBufferType:
3238 vaStatus = I965_RENDER_DECODE_BUFFER(huffman_table);
3241 case VAProbabilityBufferType:
3242 vaStatus = I965_RENDER_DECODE_BUFFER(probability_data);
3246 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
3251 if ((vaStatus == VA_STATUS_SUCCESS) &&
3252 (obj_context->wrapper_context != VA_INVALID_ID))
3253 vaStatus = i965_decoder_wrapper_picture(ctx, context, buffers, num_buffers);
3258 #define I965_RENDER_ENCODE_BUFFER(name) I965_RENDER_BUFFER(encode, name)
3260 #define DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(encode, name, member)
3261 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter, seq_param)
3262 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
3263 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_control, pic_control)
3264 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(qmatrix, q_matrix)
3265 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(iqmatrix, iq_matrix)
3266 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
3267 /* extended buffer */
3268 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
3269 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
3270 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(encmb_map, encmb_map)
3272 #define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
3273 // DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
3274 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter_ext, slice_params_ext)
3276 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_params_ext, packed_header_params_ext)
3277 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_data_ext, packed_header_data_ext)
3280 i965_encoder_render_packed_header_parameter_buffer(VADriverContextP ctx,
3281 struct object_context *obj_context,
3282 struct object_buffer *obj_buffer,
3285 struct encode_state *encode = &obj_context->codec_state.encode;
3287 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
3288 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
3289 i965_release_buffer_store(&encode->packed_header_param[type_index]);
3290 i965_reference_buffer_store(&encode->packed_header_param[type_index], obj_buffer->buffer_store);
3292 return VA_STATUS_SUCCESS;
3296 i965_encoder_render_packed_header_data_buffer(VADriverContextP ctx,
3297 struct object_context *obj_context,
3298 struct object_buffer *obj_buffer,
3301 struct encode_state *encode = &obj_context->codec_state.encode;
3303 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
3304 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
3305 i965_release_buffer_store(&encode->packed_header_data[type_index]);
3306 i965_reference_buffer_store(&encode->packed_header_data[type_index], obj_buffer->buffer_store);
3308 return VA_STATUS_SUCCESS;
3312 i965_encoder_get_misc_paramerter_buffer_index(VADriverContextP ctx,
3313 struct encode_state *encode,
3314 VAEncMiscParameterBuffer *misc_param)
3318 if (!encode->has_layers)
3321 if (misc_param->type == VAEncMiscParameterTypeRateControl) {
3322 VAEncMiscParameterRateControl *misc_rate_control = (VAEncMiscParameterRateControl *)misc_param->data;
3324 index = misc_rate_control->rc_flags.bits.temporal_id;
3325 } else if (misc_param->type == VAEncMiscParameterTypeFrameRate) {
3326 VAEncMiscParameterFrameRate *misc_frame_rate = (VAEncMiscParameterFrameRate *)misc_param->data;
3328 index = misc_frame_rate->framerate_flags.bits.temporal_id;
3335 i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
3336 struct object_context *obj_context,
3337 struct object_buffer *obj_buffer)
3339 struct encode_state *encode = &obj_context->codec_state.encode;
3340 VAEncMiscParameterBuffer *param = NULL;
3343 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
3344 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
3346 param = (VAEncMiscParameterBuffer *)obj_buffer->buffer_store->buffer;
3348 if (param->type >= ARRAY_ELEMS(encode->misc_param))
3349 return VA_STATUS_ERROR_INVALID_PARAMETER;
3351 if (param->type == VAEncMiscParameterTypeTemporalLayerStructure)
3352 encode->has_layers = 1;
3354 index = i965_encoder_get_misc_paramerter_buffer_index(ctx, encode, param);
3356 if (index >= ARRAY_ELEMS(encode->misc_param[0]))
3357 return VA_STATUS_ERROR_INVALID_PARAMETER;
3359 i965_release_buffer_store(&encode->misc_param[param->type][index]);
3360 i965_reference_buffer_store(&encode->misc_param[param->type][index], obj_buffer->buffer_store);
3362 return VA_STATUS_SUCCESS;
3366 i965_encoder_render_picture(VADriverContextP ctx,
3367 VAContextID context,
3368 VABufferID *buffers,
3371 struct i965_driver_data *i965 = i965_driver_data(ctx);
3372 struct object_context *obj_context = CONTEXT(context);
3373 struct object_config *obj_config;
3374 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
3375 struct encode_state *encode;
3378 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
3379 obj_config = obj_context->obj_config;
3380 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
3382 encode = &obj_context->codec_state.encode;
3383 for (i = 0; i < num_buffers; i++) {
3384 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
3387 return VA_STATUS_ERROR_INVALID_BUFFER;
3389 switch (obj_buffer->type) {
3390 case VAQMatrixBufferType:
3391 vaStatus = I965_RENDER_ENCODE_BUFFER(qmatrix);
3394 case VAIQMatrixBufferType:
3395 vaStatus = I965_RENDER_ENCODE_BUFFER(iqmatrix);
3398 case VAEncSequenceParameterBufferType:
3399 vaStatus = I965_RENDER_ENCODE_BUFFER(sequence_parameter_ext);
3402 case VAEncPictureParameterBufferType:
3403 vaStatus = I965_RENDER_ENCODE_BUFFER(picture_parameter_ext);
3406 case VAHuffmanTableBufferType:
3407 vaStatus = I965_RENDER_ENCODE_BUFFER(huffman_table);
3410 case VAEncSliceParameterBufferType:
3411 vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
3412 if (vaStatus == VA_STATUS_SUCCESS) {
3413 /* When the max number of slices is updated, it also needs
3414 * to reallocate the arrays that is used to store
3415 * the packed data index/count for the slice
3417 if (!(encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE)) {
3418 encode->slice_index++;
3420 if (encode->slice_index == encode->max_slice_num) {
3421 int slice_num = encode->max_slice_num;
3422 encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
3423 (slice_num + NUM_SLICES) * sizeof(int));
3424 encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
3425 (slice_num + NUM_SLICES) * sizeof(int));
3426 encode->slice_header_index = realloc(encode->slice_header_index,
3427 (slice_num + NUM_SLICES) * sizeof(int));
3428 memset(encode->slice_rawdata_index + slice_num, 0,
3429 sizeof(int) * NUM_SLICES);
3430 memset(encode->slice_rawdata_count + slice_num, 0,
3431 sizeof(int) * NUM_SLICES);
3432 memset(encode->slice_header_index + slice_num, 0,
3433 sizeof(int) * NUM_SLICES);
3435 encode->max_slice_num += NUM_SLICES;
3436 if ((encode->slice_rawdata_index == NULL) ||
3437 (encode->slice_header_index == NULL) ||
3438 (encode->slice_rawdata_count == NULL)) {
3439 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
3446 case VAEncPackedHeaderParameterBufferType:
3448 VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer;
3449 encode->last_packed_header_type = param->type;
3451 if ((param->type == VAEncPackedHeaderRawData) ||
3452 (param->type == VAEncPackedHeaderSlice)) {
3453 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext);
3454 } else if((obj_config->profile == VAProfileHEVCMain ||
3455 obj_config->profile == VAProfileHEVCMain10) &&
3456 (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
3457 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
3460 va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index);
3462 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
3465 va_enc_packed_type_to_idx(encode->last_packed_header_type));
3470 case VAEncPackedHeaderDataBufferType:
3472 if (encode->last_packed_header_type == 0) {
3473 WARN_ONCE("the packed header data is passed without type!\n");
3474 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
3478 if (encode->last_packed_header_type == VAEncPackedHeaderRawData ||
3479 encode->last_packed_header_type == VAEncPackedHeaderSlice) {
3480 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext);
3482 if (obj_config->profile == VAProfileVP9Profile0)
3485 /* When the PACKED_SLICE_HEADER flag is passed, it will use
3486 * the packed_slice_header as the delimeter to decide how
3487 * the packed rawdata is inserted for the given slice.
3488 * Otherwise it will use the VAEncSequenceParameterBuffer
3491 if (encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) {
3492 /* store the first index of the packed header data for current slice */
3493 if (encode->slice_rawdata_index[encode->slice_index] == 0) {
3494 encode->slice_rawdata_index[encode->slice_index] =
3495 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
3497 encode->slice_rawdata_count[encode->slice_index]++;
3498 if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
3499 /* find one packed slice_header delimeter. And the following
3500 * packed data is for the next slice
3502 encode->slice_header_index[encode->slice_index] =
3503 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
3504 encode->slice_index++;
3505 /* Reallocate the buffer to record the index/count of
3506 * packed_data for one slice.
3508 if (encode->slice_index == encode->max_slice_num) {
3509 int slice_num = encode->max_slice_num;
3511 encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
3512 (slice_num + NUM_SLICES) * sizeof(int));
3513 encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
3514 (slice_num + NUM_SLICES) * sizeof(int));
3515 encode->slice_header_index = realloc(encode->slice_header_index,
3516 (slice_num + NUM_SLICES) * sizeof(int));
3517 memset(encode->slice_rawdata_index + slice_num, 0,
3518 sizeof(int) * NUM_SLICES);
3519 memset(encode->slice_rawdata_count + slice_num, 0,
3520 sizeof(int) * NUM_SLICES);
3521 memset(encode->slice_header_index + slice_num, 0,
3522 sizeof(int) * NUM_SLICES);
3523 encode->max_slice_num += NUM_SLICES;
3527 if (vaStatus == VA_STATUS_SUCCESS) {
3528 /* store the first index of the packed header data for current slice */
3529 if (encode->slice_rawdata_index[encode->slice_index] == 0) {
3530 encode->slice_rawdata_index[encode->slice_index] =
3531 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
3533 encode->slice_rawdata_count[encode->slice_index]++;
3534 if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
3535 if (encode->slice_header_index[encode->slice_index] == 0) {
3536 encode->slice_header_index[encode->slice_index] =
3537 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
3539 WARN_ONCE("Multi slice header data is passed for"
3540 " slice %d!\n", encode->slice_index);
3546 ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
3547 encode->last_packed_header_type == VAEncPackedHeaderPicture ||
3548 encode->last_packed_header_type == VAEncPackedHeaderSlice ||
3549 (((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) &&
3550 ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)),
3551 VA_STATUS_ERROR_ENCODING_ERROR);
3553 if((obj_config->profile == VAProfileHEVCMain ||
3554 obj_config->profile == VAProfileHEVCMain10) &&
3555 (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
3557 vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
3560 va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index);
3561 encode->vps_sps_seq_index = (encode->vps_sps_seq_index + 1) % I965_SEQ_PACKED_HEADER_END;
3563 vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
3566 va_enc_packed_type_to_idx(encode->last_packed_header_type));
3570 encode->last_packed_header_type = 0;
3574 case VAEncMiscParameterBufferType:
3575 vaStatus = i965_encoder_render_misc_parameter_buffer(ctx,
3580 case VAEncMacroblockMapBufferType:
3581 vaStatus = I965_RENDER_ENCODE_BUFFER(encmb_map);
3585 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
3593 #define I965_RENDER_PROC_BUFFER(name) I965_RENDER_BUFFER(proc, name)
3595 #define DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(proc, name, member)
3596 DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(pipeline_parameter, pipeline_param)
3599 i965_proc_render_picture(VADriverContextP ctx,
3600 VAContextID context,
3601 VABufferID *buffers,
3604 struct i965_driver_data *i965 = i965_driver_data(ctx);
3605 struct object_context *obj_context = CONTEXT(context);
3606 VAStatus vaStatus = VA_STATUS_SUCCESS;
3609 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
3611 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
3612 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
3615 return VA_STATUS_ERROR_INVALID_BUFFER;
3617 switch (obj_buffer->type) {
3618 case VAProcPipelineParameterBufferType:
3619 vaStatus = I965_RENDER_PROC_BUFFER(pipeline_parameter);
3623 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
3632 i965_RenderPicture(VADriverContextP ctx,
3633 VAContextID context,
3634 VABufferID *buffers,
3637 struct i965_driver_data *i965 = i965_driver_data(ctx);
3638 struct object_context *obj_context;
3639 struct object_config *obj_config;
3640 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
3642 obj_context = CONTEXT(context);
3643 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
3645 if (num_buffers <= 0)
3646 return VA_STATUS_ERROR_INVALID_PARAMETER;
3648 obj_config = obj_context->obj_config;
3649 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
3651 if (VAEntrypointVideoProc == obj_config->entrypoint) {
3652 vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
3653 } else if ((VAEntrypointEncSlice == obj_config->entrypoint ) ||
3654 (VAEntrypointEncPicture == obj_config->entrypoint) ||
3655 (VAEntrypointEncSliceLP == obj_config->entrypoint)) {
3656 vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
3658 vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
3665 i965_EndPicture(VADriverContextP ctx, VAContextID context)
3667 struct i965_driver_data *i965 = i965_driver_data(ctx);
3668 struct object_context *obj_context = CONTEXT(context);
3669 struct object_config *obj_config;
3671 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
3672 obj_config = obj_context->obj_config;
3673 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
3675 if (obj_context->codec_type == CODEC_PROC) {
3676 ASSERT_RET(VAEntrypointVideoProc == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
3677 } else if (obj_context->codec_type == CODEC_ENC) {
3678 ASSERT_RET(((VAEntrypointEncSlice == obj_config->entrypoint) ||
3679 (VAEntrypointEncPicture == obj_config->entrypoint) ||
3680 (VAEntrypointEncSliceLP == obj_config->entrypoint)),
3681 VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
3683 if (obj_context->codec_state.encode.num_packed_header_params_ext !=
3684 obj_context->codec_state.encode.num_packed_header_data_ext) {
3685 WARN_ONCE("the packed header/data is not paired for encoding!\n");
3686 return VA_STATUS_ERROR_INVALID_PARAMETER;
3688 if (!obj_context->codec_state.encode.pic_param_ext) {
3689 return VA_STATUS_ERROR_INVALID_PARAMETER;
3691 if (!obj_context->codec_state.encode.seq_param_ext &&
3692 (VAEntrypointEncPicture != obj_config->entrypoint)) {
3693 /* The seq_param is not mandatory for VP9 encoding */
3694 if (obj_config->profile != VAProfileVP9Profile0)
3695 return VA_STATUS_ERROR_INVALID_PARAMETER;
3697 if ((obj_context->codec_state.encode.num_slice_params_ext <=0) &&
3698 ((obj_config->profile != VAProfileVP8Version0_3) &&
3699 (obj_config->profile != VAProfileVP9Profile0))) {
3700 return VA_STATUS_ERROR_INVALID_PARAMETER;
3703 if ((obj_context->codec_state.encode.packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) &&
3704 (obj_context->codec_state.encode.num_slice_params_ext !=
3705 obj_context->codec_state.encode.slice_index)) {
3706 WARN_ONCE("packed slice_header data is missing for some slice"
3707 " under packed SLICE_HEADER mode\n");
3708 return VA_STATUS_ERROR_INVALID_PARAMETER;
3711 if (obj_context->codec_state.decode.pic_param == NULL) {
3712 return VA_STATUS_ERROR_INVALID_PARAMETER;
3714 if (obj_context->codec_state.decode.num_slice_params <=0) {
3715 return VA_STATUS_ERROR_INVALID_PARAMETER;
3717 if (obj_context->codec_state.decode.num_slice_datas <=0) {
3718 return VA_STATUS_ERROR_INVALID_PARAMETER;
3721 if (obj_context->codec_state.decode.num_slice_params !=
3722 obj_context->codec_state.decode.num_slice_datas) {
3723 return VA_STATUS_ERROR_INVALID_PARAMETER;
3726 if (obj_context->wrapper_context != VA_INVALID_ID) {
3727 /* call the vaEndPicture of wrapped driver */
3728 VADriverContextP pdrvctx;
3731 pdrvctx = i965->wrapper_pdrvctx;
3732 CALL_VTABLE(pdrvctx, va_status,
3733 vaEndPicture(pdrvctx, obj_context->wrapper_context));
3739 ASSERT_RET(obj_context->hw_context->run, VA_STATUS_ERROR_OPERATION_FAILED);
3740 return obj_context->hw_context->run(ctx, obj_config->profile, &obj_context->codec_state, obj_context->hw_context);
3744 i965_SyncSurface(VADriverContextP ctx,
3745 VASurfaceID render_target)
3747 struct i965_driver_data *i965 = i965_driver_data(ctx);
3748 struct object_surface *obj_surface = SURFACE(render_target);
3750 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
3753 drm_intel_bo_wait_rendering(obj_surface->bo);
3755 return VA_STATUS_SUCCESS;
3759 i965_QuerySurfaceStatus(VADriverContextP ctx,
3760 VASurfaceID render_target,
3761 VASurfaceStatus *status) /* out */
3763 struct i965_driver_data *i965 = i965_driver_data(ctx);
3764 struct object_surface *obj_surface = SURFACE(render_target);
3766 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
3768 if (obj_surface->bo) {
3769 if (drm_intel_bo_busy(obj_surface->bo)){
3770 *status = VASurfaceRendering;
3773 *status = VASurfaceReady;
3776 *status = VASurfaceReady;
3779 return VA_STATUS_SUCCESS;
3782 static VADisplayAttribute *
3783 get_display_attribute(VADriverContextP ctx, VADisplayAttribType type)
3785 struct i965_driver_data * const i965 = i965_driver_data(ctx);
3788 if (!i965->display_attributes)
3791 for (i = 0; i < i965->num_display_attributes; i++) {
3792 if (i965->display_attributes[i].type == type)
3793 return &i965->display_attributes[i];
3799 i965_display_attributes_terminate(VADriverContextP ctx)
3801 struct i965_driver_data * const i965 = i965_driver_data(ctx);
3803 if (i965->display_attributes) {
3804 free(i965->display_attributes);
3805 i965->display_attributes = NULL;
3806 i965->num_display_attributes = 0;
3811 i965_display_attributes_init(VADriverContextP ctx)
3813 struct i965_driver_data * const i965 = i965_driver_data(ctx);
3815 i965->num_display_attributes = ARRAY_ELEMS(i965_display_attributes);
3816 i965->display_attributes = malloc(
3817 i965->num_display_attributes * sizeof(i965->display_attributes[0]));
3818 if (!i965->display_attributes)
3822 i965->display_attributes,
3823 i965_display_attributes,
3824 sizeof(i965_display_attributes)
3827 i965->rotation_attrib = get_display_attribute(ctx, VADisplayAttribRotation);
3828 i965->brightness_attrib = get_display_attribute(ctx, VADisplayAttribBrightness);
3829 i965->contrast_attrib = get_display_attribute(ctx, VADisplayAttribContrast);
3830 i965->hue_attrib = get_display_attribute(ctx, VADisplayAttribHue);
3831 i965->saturation_attrib = get_display_attribute(ctx, VADisplayAttribSaturation);
3833 if (!i965->rotation_attrib ||
3834 !i965->brightness_attrib ||
3835 !i965->contrast_attrib ||
3836 !i965->hue_attrib ||
3837 !i965->saturation_attrib) {
3843 i965_display_attributes_terminate(ctx);
3848 * Query display attributes
3849 * The caller must provide a "attr_list" array that can hold at
3850 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
3851 * returned in "attr_list" is returned in "num_attributes".
3854 i965_QueryDisplayAttributes(
3855 VADriverContextP ctx,
3856 VADisplayAttribute *attribs, /* out */
3857 int *num_attribs_ptr /* out */
3860 const int num_attribs = ARRAY_ELEMS(i965_display_attributes);
3862 if (attribs && num_attribs > 0)
3863 memcpy(attribs, i965_display_attributes, sizeof(i965_display_attributes));
3865 if (num_attribs_ptr)
3866 *num_attribs_ptr = num_attribs;
3868 return VA_STATUS_SUCCESS;
3872 * Get display attributes
3873 * This function returns the current attribute values in "attr_list".
3874 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
3875 * from vaQueryDisplayAttributes() can have their values retrieved.
3878 i965_GetDisplayAttributes(
3879 VADriverContextP ctx,
3880 VADisplayAttribute *attribs, /* inout */
3881 int num_attribs /* in */
3886 for (i = 0; i < num_attribs; i++) {
3887 VADisplayAttribute *src_attrib, * const dst_attrib = &attribs[i];
3889 src_attrib = get_display_attribute(ctx, dst_attrib->type);
3891 if (src_attrib && (src_attrib->flags & VA_DISPLAY_ATTRIB_GETTABLE)) {
3892 dst_attrib->min_value = src_attrib->min_value;
3893 dst_attrib->max_value = src_attrib->max_value;
3894 dst_attrib->value = src_attrib->value;
3895 dst_attrib->flags = src_attrib->flags;
3896 } else if (src_attrib &&
3897 (src_attrib->flags & VA_DISPLAY_ATTRIB_SETTABLE)) {
3898 dst_attrib->flags = src_attrib->flags;
3901 dst_attrib->flags = VA_DISPLAY_ATTRIB_NOT_SUPPORTED;
3903 return VA_STATUS_SUCCESS;
3907 * Set display attributes
3908 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
3909 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
3910 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
3913 i965_SetDisplayAttributes(
3914 VADriverContextP ctx,
3915 VADisplayAttribute *attribs, /* in */
3916 int num_attribs /* in */
3921 for (i = 0; i < num_attribs; i++) {
3922 VADisplayAttribute *dst_attrib, * const src_attrib = &attribs[i];
3924 dst_attrib = get_display_attribute(ctx, src_attrib->type);
3926 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
3928 if (!(dst_attrib->flags & VA_DISPLAY_ATTRIB_SETTABLE))
3931 if (src_attrib->value < dst_attrib->min_value ||
3932 src_attrib->value > dst_attrib->max_value)
3933 return VA_STATUS_ERROR_INVALID_PARAMETER;
3935 dst_attrib->value = src_attrib->value;
3936 /* XXX: track modified attributes through timestamps */
3938 return VA_STATUS_SUCCESS;
3942 i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
3943 VASurfaceID surface,
3944 void **buffer, /* out */
3945 unsigned int *stride) /* out */
3948 return VA_STATUS_ERROR_UNIMPLEMENTED;
3952 i965_destroy_heap(struct object_heap *heap,
3953 void (*func)(struct object_heap *heap, struct object_base *object))
3955 struct object_base *object;
3956 object_heap_iterator iter;
3958 object = object_heap_first(heap, &iter);
3964 object = object_heap_next(heap, &iter);
3967 object_heap_destroy(heap);
3972 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
3975 i965_CreateImage(VADriverContextP ctx,
3976 VAImageFormat *format,
3979 VAImage *out_image) /* out */
3981 struct i965_driver_data *i965 = i965_driver_data(ctx);
3982 struct object_image *obj_image;
3983 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3985 unsigned int size2, size, awidth, aheight;
3987 out_image->image_id = VA_INVALID_ID;
3988 out_image->buf = VA_INVALID_ID;
3990 image_id = NEW_IMAGE_ID();
3991 if (image_id == VA_INVALID_ID)
3992 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3994 obj_image = IMAGE(image_id);
3996 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3997 obj_image->bo = NULL;
3998 obj_image->palette = NULL;
3999 obj_image->derived_surface = VA_INVALID_ID;
4001 VAImage * const image = &obj_image->image;
4002 image->image_id = image_id;
4003 image->buf = VA_INVALID_ID;
4005 awidth = ALIGN(width, i965->codec_info->min_linear_wpitch);
4007 if ((format->fourcc == VA_FOURCC_YV12) ||
4008 (format->fourcc == VA_FOURCC_I420)) {
4009 if (awidth % 128 != 0) {
4010 awidth = ALIGN(width, 128);
4014 aheight = ALIGN(height, i965->codec_info->min_linear_hpitch);
4015 size = awidth * aheight;
4016 size2 = (awidth / 2) * (aheight / 2);
4018 image->num_palette_entries = 0;
4019 image->entry_bytes = 0;
4020 memset(image->component_order, 0, sizeof(image->component_order));
4022 switch (format->fourcc) {
4023 case VA_FOURCC_IA44:
4024 case VA_FOURCC_AI44:
4025 image->num_planes = 1;
4026 image->pitches[0] = awidth;
4027 image->offsets[0] = 0;
4028 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
4029 image->num_palette_entries = 16;
4030 image->entry_bytes = 3;
4031 image->component_order[0] = 'R';
4032 image->component_order[1] = 'G';
4033 image->component_order[2] = 'B';
4035 case VA_FOURCC_IA88:
4036 case VA_FOURCC_AI88:
4037 image->num_planes = 1;
4038 image->pitches[0] = awidth * 2;
4039 image->offsets[0] = 0;
4040 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
4041 image->num_palette_entries = 256;
4042 image->entry_bytes = 3;
4043 image->component_order[0] = 'R';
4044 image->component_order[1] = 'G';
4045 image->component_order[2] = 'B';
4047 case VA_FOURCC_ARGB:
4048 case VA_FOURCC_ABGR:
4049 case VA_FOURCC_BGRA:
4050 case VA_FOURCC_RGBA:
4051 case VA_FOURCC_BGRX:
4052 case VA_FOURCC_RGBX:
4053 image->num_planes = 1;
4054 image->pitches[0] = awidth * 4;
4055 image->offsets[0] = 0;
4056 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
4058 case VA_FOURCC_YV12:
4059 image->num_planes = 3;
4060 image->pitches[0] = awidth;
4061 image->offsets[0] = 0;
4062 image->pitches[1] = awidth / 2;
4063 image->offsets[1] = size;
4064 image->pitches[2] = awidth / 2;
4065 image->offsets[2] = size + size2;
4066 image->data_size = size + 2 * size2;
4068 case VA_FOURCC_I420:
4069 image->num_planes = 3;
4070 image->pitches[0] = awidth;
4071 image->offsets[0] = 0;
4072 image->pitches[1] = awidth / 2;
4073 image->offsets[1] = size;
4074 image->pitches[2] = awidth / 2;
4075 image->offsets[2] = size + size2;
4076 image->data_size = size + 2 * size2;
4078 case VA_FOURCC_422H:
4079 image->num_planes = 3;
4080 image->pitches[0] = awidth;
4081 image->offsets[0] = 0;
4082 image->pitches[1] = awidth / 2;
4083 image->offsets[1] = size;
4084 image->pitches[2] = awidth / 2;
4085 image->offsets[2] = size + (awidth / 2) * aheight;
4086 image->data_size = size + 2 * ((awidth / 2) * aheight);
4088 case VA_FOURCC_NV12:
4089 image->num_planes = 2;
4090 image->pitches[0] = awidth;
4091 image->offsets[0] = 0;
4092 image->pitches[1] = awidth;
4093 image->offsets[1] = size;
4094 image->data_size = size + 2 * size2;
4096 case VA_FOURCC_YUY2:
4097 case VA_FOURCC_UYVY:
4098 image->num_planes = 1;
4099 image->pitches[0] = awidth * 2;
4100 image->offsets[0] = 0;
4101 image->data_size = size * 2;
4103 case VA_FOURCC_P010:
4104 image->num_planes = 2;
4105 image->pitches[0] = awidth * 2;
4106 image->offsets[0] = 0;
4107 image->pitches[1] = awidth * 2;
4108 image->offsets[1] = size * 2;
4109 image->data_size = size * 2 + 2 * size2 * 2;
4115 va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
4116 image->data_size, 1, NULL, &image->buf);
4117 if (va_status != VA_STATUS_SUCCESS)
4120 struct object_buffer *obj_buffer = BUFFER(image->buf);
4123 !obj_buffer->buffer_store ||
4124 !obj_buffer->buffer_store->bo)
4125 return VA_STATUS_ERROR_ALLOCATION_FAILED;
4127 obj_image->bo = obj_buffer->buffer_store->bo;
4128 dri_bo_reference(obj_image->bo);
4130 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
4131 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
4132 if (!obj_image->palette)
4136 image->image_id = image_id;
4137 image->format = *format;
4138 image->width = width;
4139 image->height = height;
4141 *out_image = *image;
4142 return VA_STATUS_SUCCESS;
4145 i965_DestroyImage(ctx, image_id);
4150 i965_check_alloc_surface_bo(VADriverContextP ctx,
4151 struct object_surface *obj_surface,
4153 unsigned int fourcc,
4154 unsigned int subsampling)
4156 struct i965_driver_data *i965 = i965_driver_data(ctx);
4157 int region_width, region_height;
4159 if (obj_surface->bo) {
4160 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4161 ASSERT_RET(obj_surface->fourcc == fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4162 ASSERT_RET(obj_surface->subsampling == subsampling, VA_STATUS_ERROR_INVALID_SURFACE);
4163 return VA_STATUS_SUCCESS;
4166 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
4167 obj_surface->x_cr_offset = 0;
4169 int bpp_1stplane = bpp_1stplane_by_fourcc(fourcc);
4171 if ((tiled && !obj_surface->user_disable_tiling)) {
4172 ASSERT_RET(fourcc != VA_FOURCC_I420 &&
4173 fourcc != VA_FOURCC_IYUV &&
4174 fourcc != VA_FOURCC_YV12,
4175 VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
4177 if (obj_surface->user_h_stride_set) {
4178 ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
4180 obj_surface->width = ALIGN(obj_surface->orig_width * bpp_1stplane, 128);
4182 if (obj_surface->user_v_stride_set) {
4183 ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
4185 obj_surface->height = ALIGN(obj_surface->orig_height, 32);
4187 region_height = obj_surface->height;
4190 case VA_FOURCC_NV12:
4191 case VA_FOURCC_P010:
4192 assert(subsampling == SUBSAMPLE_YUV420);
4193 obj_surface->cb_cr_pitch = obj_surface->width;
4194 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4195 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
4196 obj_surface->y_cb_offset = obj_surface->height;
4197 obj_surface->y_cr_offset = obj_surface->height;
4198 region_width = obj_surface->width;
4199 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
4203 case VA_FOURCC_IMC1:
4204 assert(subsampling == SUBSAMPLE_YUV420);
4205 obj_surface->cb_cr_pitch = obj_surface->width;
4206 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4207 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
4208 obj_surface->y_cr_offset = obj_surface->height;
4209 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32);
4210 region_width = obj_surface->width;
4211 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
4215 case VA_FOURCC_IMC3:
4216 assert(subsampling == SUBSAMPLE_YUV420);
4217 obj_surface->cb_cr_pitch = obj_surface->width;
4218 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4219 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
4220 obj_surface->y_cb_offset = obj_surface->height;
4221 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
4222 region_width = obj_surface->width;
4223 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
4227 case VA_FOURCC_422H:
4228 assert(subsampling == SUBSAMPLE_YUV422H);
4229 obj_surface->cb_cr_pitch = obj_surface->width;
4230 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4231 obj_surface->cb_cr_height = obj_surface->orig_height;
4232 obj_surface->y_cb_offset = obj_surface->height;
4233 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
4234 region_width = obj_surface->width;
4235 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
4239 case VA_FOURCC_422V:
4240 assert(subsampling == SUBSAMPLE_YUV422V);
4241 obj_surface->cb_cr_pitch = obj_surface->width;
4242 obj_surface->cb_cr_width = obj_surface->orig_width;
4243 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
4244 obj_surface->y_cb_offset = obj_surface->height;
4245 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
4246 region_width = obj_surface->width;
4247 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
4251 case VA_FOURCC_411P:
4252 assert(subsampling == SUBSAMPLE_YUV411);
4253 obj_surface->cb_cr_pitch = obj_surface->width;
4254 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
4255 obj_surface->cb_cr_height = obj_surface->orig_height;
4256 obj_surface->y_cb_offset = obj_surface->height;
4257 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
4258 region_width = obj_surface->width;
4259 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
4263 case VA_FOURCC_444P:
4264 assert(subsampling == SUBSAMPLE_YUV444);
4265 obj_surface->cb_cr_pitch = obj_surface->width;
4266 obj_surface->cb_cr_width = obj_surface->orig_width;
4267 obj_surface->cb_cr_height = obj_surface->orig_height;
4268 obj_surface->y_cb_offset = obj_surface->height;
4269 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
4270 region_width = obj_surface->width;
4271 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
4275 case VA_FOURCC_Y800:
4276 assert(subsampling == SUBSAMPLE_YUV400);
4277 obj_surface->cb_cr_pitch = 0;
4278 obj_surface->cb_cr_width = 0;
4279 obj_surface->cb_cr_height = 0;
4280 obj_surface->y_cb_offset = 0;
4281 obj_surface->y_cr_offset = 0;
4282 region_width = obj_surface->width;
4283 region_height = obj_surface->height;
4287 case VA_FOURCC_YUY2:
4288 case VA_FOURCC_UYVY:
4289 assert(subsampling == SUBSAMPLE_YUV422H);
4290 obj_surface->width = ALIGN(obj_surface->orig_width * 2, 128);
4291 obj_surface->cb_cr_pitch = obj_surface->width;
4292 obj_surface->y_cb_offset = 0;
4293 obj_surface->y_cr_offset = 0;
4294 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4295 obj_surface->cb_cr_height = obj_surface->orig_height;
4296 region_width = obj_surface->width;
4297 region_height = obj_surface->height;
4301 case VA_FOURCC_RGBA:
4302 case VA_FOURCC_RGBX:
4303 case VA_FOURCC_BGRA:
4304 case VA_FOURCC_BGRX:
4305 assert(subsampling == SUBSAMPLE_RGBX);
4307 obj_surface->width = ALIGN(obj_surface->orig_width * 4, 128);
4308 region_width = obj_surface->width;
4309 region_height = obj_surface->height;
4313 /* Never get here */
4314 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
4318 assert(subsampling == SUBSAMPLE_YUV420 ||
4319 subsampling == SUBSAMPLE_YUV422H ||
4320 subsampling == SUBSAMPLE_YUV422V ||
4321 subsampling == SUBSAMPLE_RGBX);
4323 region_width = obj_surface->width;
4324 region_height = obj_surface->height;
4327 case VA_FOURCC_NV12:
4328 case VA_FOURCC_P010:
4329 obj_surface->y_cb_offset = obj_surface->height;
4330 obj_surface->y_cr_offset = obj_surface->height;
4331 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4332 obj_surface->width = ALIGN(obj_surface->cb_cr_width * 2, i965->codec_info->min_linear_wpitch) *
4334 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
4335 obj_surface->cb_cr_pitch = obj_surface->width;
4336 region_width = obj_surface->width;
4337 region_height = obj_surface->height + obj_surface->height / 2;
4340 case VA_FOURCC_YV16:
4341 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4342 obj_surface->width = ALIGN(obj_surface->cb_cr_width, i965->codec_info->min_linear_wpitch) * 2;
4343 obj_surface->cb_cr_height = obj_surface->orig_height;
4344 obj_surface->y_cr_offset = obj_surface->height;
4345 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32) / 2;
4346 obj_surface->cb_cr_pitch = obj_surface->width / 2;
4347 region_width = obj_surface->width;
4348 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
4351 case VA_FOURCC_YV12:
4352 case VA_FOURCC_I420:
4353 case VA_FOURCC_IYUV:
4354 if (fourcc == VA_FOURCC_YV12) {
4355 obj_surface->y_cr_offset = obj_surface->height;
4356 obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4;
4358 obj_surface->y_cb_offset = obj_surface->height;
4359 obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
4362 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4363 obj_surface->width = ALIGN(obj_surface->cb_cr_width, i965->codec_info->min_linear_wpitch) * 2;
4364 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
4365 obj_surface->cb_cr_pitch = obj_surface->width / 2;
4366 region_width = obj_surface->width;
4367 region_height = obj_surface->height + obj_surface->height / 2;
4370 case VA_FOURCC_I010:
4371 obj_surface->y_cb_offset = obj_surface->height;
4372 obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
4373 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4374 obj_surface->width = ALIGN(obj_surface->cb_cr_width * 2, i965->codec_info->min_linear_wpitch) * 2;
4375 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
4376 obj_surface->cb_cr_pitch = obj_surface->width / 2;
4377 region_width = obj_surface->width;
4378 region_height = obj_surface->height + obj_surface->height / 2;
4381 case VA_FOURCC_YUY2:
4382 case VA_FOURCC_UYVY:
4383 obj_surface->width = ALIGN(obj_surface->orig_width * 2, i965->codec_info->min_linear_wpitch);
4384 obj_surface->y_cb_offset = 0;
4385 obj_surface->y_cr_offset = 0;
4386 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4387 obj_surface->cb_cr_height = obj_surface->orig_height;
4388 obj_surface->cb_cr_pitch = obj_surface->width;
4389 region_width = obj_surface->width;
4390 region_height = obj_surface->height;
4392 case VA_FOURCC_RGBA:
4393 case VA_FOURCC_RGBX:
4394 case VA_FOURCC_BGRA:
4395 case VA_FOURCC_BGRX:
4396 obj_surface->width = ALIGN(obj_surface->orig_width * 4, i965->codec_info->min_linear_wpitch);
4397 region_width = obj_surface->width;
4398 region_height = obj_surface->height;
4402 /* Never get here */
4403 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
4408 obj_surface->size = ALIGN(region_width * region_height, 0x1000);
4410 if ((tiled && !obj_surface->user_disable_tiling)) {
4411 uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
4412 unsigned long pitch;
4414 obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr,
4422 assert(tiling_mode == I915_TILING_Y);
4423 assert(pitch == obj_surface->width);
4425 obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
4431 obj_surface->fourcc = fourcc;
4432 obj_surface->subsampling = subsampling;
4433 assert(obj_surface->bo);
4434 return VA_STATUS_SUCCESS;
4437 VAStatus i965_DeriveImage(VADriverContextP ctx,
4438 VASurfaceID surface,
4439 VAImage *out_image) /* out */
4441 struct i965_driver_data *i965 = i965_driver_data(ctx);
4442 struct object_image *obj_image;
4443 struct object_surface *obj_surface;
4445 unsigned int w_pitch;
4446 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
4448 out_image->image_id = VA_INVALID_ID;
4449 obj_surface = SURFACE(surface);
4452 return VA_STATUS_ERROR_INVALID_SURFACE;
4454 if (!obj_surface->bo) {
4455 unsigned int is_tiled = 0;
4456 unsigned int fourcc = VA_FOURCC_YV12;
4457 i965_guess_surface_format(ctx, surface, &fourcc, &is_tiled);
4458 int sampling = get_sampling_from_fourcc(fourcc);
4459 va_status = i965_check_alloc_surface_bo(ctx, obj_surface, is_tiled, fourcc, sampling);
4460 if (va_status != VA_STATUS_SUCCESS)
4464 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4466 w_pitch = obj_surface->width;
4468 image_id = NEW_IMAGE_ID();
4470 if (image_id == VA_INVALID_ID)
4471 return VA_STATUS_ERROR_ALLOCATION_FAILED;
4473 obj_image = IMAGE(image_id);
4476 return VA_STATUS_ERROR_ALLOCATION_FAILED;
4478 obj_image->bo = NULL;
4479 obj_image->palette = NULL;
4480 obj_image->derived_surface = VA_INVALID_ID;
4482 VAImage * const image = &obj_image->image;
4484 memset(image, 0, sizeof(*image));
4485 image->image_id = image_id;
4486 image->buf = VA_INVALID_ID;
4487 image->num_palette_entries = 0;
4488 image->entry_bytes = 0;
4489 image->width = obj_surface->orig_width;
4490 image->height = obj_surface->orig_height;
4491 image->data_size = obj_surface->size;
4493 image->format.fourcc = obj_surface->fourcc;
4494 image->format.byte_order = VA_LSB_FIRST;
4495 image->format.bits_per_pixel = get_bpp_from_fourcc(obj_surface->fourcc);
4497 if (!image->format.bits_per_pixel)
4500 switch (image->format.fourcc) {
4501 case VA_FOURCC_YV12:
4502 image->num_planes = 3;
4503 image->pitches[0] = w_pitch; /* Y */
4504 image->offsets[0] = 0;
4505 image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
4506 image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
4507 image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
4508 image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
4511 case VA_FOURCC_YV16:
4512 image->num_planes = 3;
4513 image->pitches[0] = w_pitch; /* Y */
4514 image->offsets[0] = 0;
4515 image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
4516 image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
4517 image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
4518 image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
4521 case VA_FOURCC_NV12:
4522 case VA_FOURCC_P010:
4523 image->num_planes = 2;
4524 image->pitches[0] = w_pitch; /* Y */
4525 image->offsets[0] = 0;
4526 image->pitches[1] = obj_surface->cb_cr_pitch; /* UV */
4527 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
4530 case VA_FOURCC_I420:
4531 case VA_FOURCC_I010:
4532 case VA_FOURCC_422H:
4533 case VA_FOURCC_IMC3:
4534 case VA_FOURCC_444P:
4535 case VA_FOURCC_422V:
4536 case VA_FOURCC_411P:
4537 image->num_planes = 3;
4538 image->pitches[0] = w_pitch; /* Y */
4539 image->offsets[0] = 0;
4540 image->pitches[1] = obj_surface->cb_cr_pitch; /* U */
4541 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
4542 image->pitches[2] = obj_surface->cb_cr_pitch; /* V */
4543 image->offsets[2] = w_pitch * obj_surface->y_cr_offset;
4546 case VA_FOURCC_YUY2:
4547 case VA_FOURCC_UYVY:
4548 case VA_FOURCC_Y800:
4549 image->num_planes = 1;
4550 image->pitches[0] = obj_surface->width; /* Y, width is aligned already */
4551 image->offsets[0] = 0;
4553 case VA_FOURCC_RGBA:
4554 case VA_FOURCC_RGBX:
4555 case VA_FOURCC_BGRA:
4556 case VA_FOURCC_BGRX:
4557 image->num_planes = 1;
4558 image->pitches[0] = obj_surface->width;
4560 switch (image->format.fourcc) {
4561 case VA_FOURCC_RGBA:
4562 case VA_FOURCC_RGBX:
4563 image->format.red_mask = 0x000000ff;
4564 image->format.green_mask = 0x0000ff00;
4565 image->format.blue_mask = 0x00ff0000;
4567 case VA_FOURCC_BGRA:
4568 case VA_FOURCC_BGRX:
4569 image->format.red_mask = 0x00ff0000;
4570 image->format.green_mask = 0x0000ff00;
4571 image->format.blue_mask = 0x000000ff;
4577 switch (image->format.fourcc) {
4578 case VA_FOURCC_RGBA:
4579 case VA_FOURCC_BGRA:
4580 image->format.alpha_mask = 0xff000000;
4581 image->format.depth = 32;
4583 case VA_FOURCC_RGBX:
4584 case VA_FOURCC_BGRX:
4585 image->format.alpha_mask = 0x00000000;
4586 image->format.depth = 24;
4597 va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType,
4598 obj_surface->size, 1, NULL, obj_surface->bo, &image->buf);
4599 if (va_status != VA_STATUS_SUCCESS)
4602 struct object_buffer *obj_buffer = BUFFER(image->buf);
4605 !obj_buffer->buffer_store ||
4606 !obj_buffer->buffer_store->bo)
4607 return VA_STATUS_ERROR_ALLOCATION_FAILED;
4609 obj_image->bo = obj_buffer->buffer_store->bo;
4610 dri_bo_reference(obj_image->bo);
4612 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
4613 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
4614 if (!obj_image->palette) {
4615 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
4620 *out_image = *image;
4621 obj_surface->flags |= SURFACE_DERIVED;
4622 obj_surface->derived_image_id = image_id;
4623 obj_image->derived_surface = surface;
4625 return VA_STATUS_SUCCESS;
4628 i965_DestroyImage(ctx, image_id);
4633 i965_destroy_image(struct object_heap *heap, struct object_base *obj)
4635 object_heap_free(heap, obj);
4640 i965_DestroyImage(VADriverContextP ctx, VAImageID image)
4642 struct i965_driver_data *i965 = i965_driver_data(ctx);
4643 struct object_image *obj_image = IMAGE(image);
4644 struct object_surface *obj_surface;
4647 return VA_STATUS_SUCCESS;
4649 dri_bo_unreference(obj_image->bo);
4650 obj_image->bo = NULL;
4652 if (obj_image->image.buf != VA_INVALID_ID) {
4653 i965_DestroyBuffer(ctx, obj_image->image.buf);
4654 obj_image->image.buf = VA_INVALID_ID;
4657 if (obj_image->palette) {
4658 free(obj_image->palette);
4659 obj_image->palette = NULL;
4662 obj_surface = SURFACE(obj_image->derived_surface);
4665 obj_surface->flags &= ~SURFACE_DERIVED;
4666 obj_surface->derived_image_id = VA_INVALID_ID;
4669 i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
4671 return VA_STATUS_SUCCESS;
4675 * pointer to an array holding the palette data. The size of the array is
4676 * num_palette_entries * entry_bytes in size. The order of the components
4677 * in the palette is described by the component_order in VASubpicture struct
4680 i965_SetImagePalette(VADriverContextP ctx,
4682 unsigned char *palette)
4684 struct i965_driver_data *i965 = i965_driver_data(ctx);
4687 struct object_image *obj_image = IMAGE(image);
4689 return VA_STATUS_ERROR_INVALID_IMAGE;
4691 if (!obj_image->palette)
4692 return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
4694 for (i = 0; i < obj_image->image.num_palette_entries; i++)
4695 obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
4696 ((unsigned int)palette[3*i + 1] << 8) |
4697 (unsigned int)palette[3*i + 2]);
4698 return VA_STATUS_SUCCESS;
4702 get_sampling_from_fourcc(unsigned int fourcc)
4704 const i965_fourcc_info *info = get_fourcc_info(fourcc);
4706 if (info && (info->flag & I_S))
4707 return info->subsampling;
4713 memcpy_pic(uint8_t *dst, unsigned int dst_stride,
4714 const uint8_t *src, unsigned int src_stride,
4715 unsigned int len, unsigned int height)
4719 for (i = 0; i < height; i++) {
4720 memcpy(dst, src, len);
4727 get_image_i420(struct object_image *obj_image, uint8_t *image_data,
4728 struct object_surface *obj_surface,
4729 const VARectangle *rect)
4731 uint8_t *dst[3], *src[3];
4733 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
4734 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
4735 unsigned int tiling, swizzle;
4736 VAStatus va_status = VA_STATUS_SUCCESS;
4738 if (!obj_surface->bo)
4739 return VA_STATUS_ERROR_INVALID_SURFACE;
4741 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4742 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4744 if (tiling != I915_TILING_NONE)
4745 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4747 dri_bo_map(obj_surface->bo, 0);
4749 if (!obj_surface->bo->virtual)
4750 return VA_STATUS_ERROR_INVALID_SURFACE;
4752 /* Dest VA image has either I420 or YV12 format.
4753 Source VA surface alway has I420 format */
4754 dst[Y] = image_data + obj_image->image.offsets[Y];
4755 src[0] = (uint8_t *)obj_surface->bo->virtual;
4756 dst[U] = image_data + obj_image->image.offsets[U];
4757 src[1] = src[0] + obj_surface->width * obj_surface->height;
4758 dst[V] = image_data + obj_image->image.offsets[V];
4759 src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
4762 dst[Y] += rect->y * obj_image->image.pitches[Y] + rect->x;
4763 src[0] += rect->y * obj_surface->width + rect->x;
4764 memcpy_pic(dst[Y], obj_image->image.pitches[Y],
4765 src[0], obj_surface->width,
4766 rect->width, rect->height);
4769 dst[U] += (rect->y / 2) * obj_image->image.pitches[U] + rect->x / 2;
4770 src[1] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
4771 memcpy_pic(dst[U], obj_image->image.pitches[U],
4772 src[1], obj_surface->width / 2,
4773 rect->width / 2, rect->height / 2);
4776 dst[V] += (rect->y / 2) * obj_image->image.pitches[V] + rect->x / 2;
4777 src[2] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
4778 memcpy_pic(dst[V], obj_image->image.pitches[V],
4779 src[2], obj_surface->width / 2,
4780 rect->width / 2, rect->height / 2);
4782 if (tiling != I915_TILING_NONE)
4783 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4785 dri_bo_unmap(obj_surface->bo);
4791 get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
4792 struct object_surface *obj_surface,
4793 const VARectangle *rect)
4795 uint8_t *dst[2], *src[2];
4796 unsigned int tiling, swizzle;
4797 VAStatus va_status = VA_STATUS_SUCCESS;
4799 if (!obj_surface->bo)
4800 return VA_STATUS_ERROR_INVALID_SURFACE;
4802 assert(obj_surface->fourcc);
4803 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4805 if (tiling != I915_TILING_NONE)
4806 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4808 dri_bo_map(obj_surface->bo, 0);
4810 if (!obj_surface->bo->virtual)
4811 return VA_STATUS_ERROR_INVALID_SURFACE;
4813 /* Both dest VA image and source surface have NV12 format */
4814 dst[0] = image_data + obj_image->image.offsets[0];
4815 src[0] = (uint8_t *)obj_surface->bo->virtual;
4816 dst[1] = image_data + obj_image->image.offsets[1];
4817 src[1] = src[0] + obj_surface->width * obj_surface->height;
4820 dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
4821 src[0] += rect->y * obj_surface->width + rect->x;
4822 memcpy_pic(dst[0], obj_image->image.pitches[0],
4823 src[0], obj_surface->width,
4824 rect->width, rect->height);
4827 dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + (rect->x & -2);
4828 src[1] += (rect->y / 2) * obj_surface->width + (rect->x & -2);
4829 memcpy_pic(dst[1], obj_image->image.pitches[1],
4830 src[1], obj_surface->width,
4831 rect->width, rect->height / 2);
4833 if (tiling != I915_TILING_NONE)
4834 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4836 dri_bo_unmap(obj_surface->bo);
4842 get_image_yuy2(struct object_image *obj_image, uint8_t *image_data,
4843 struct object_surface *obj_surface,
4844 const VARectangle *rect)
4847 unsigned int tiling, swizzle;
4848 VAStatus va_status = VA_STATUS_SUCCESS;
4850 if (!obj_surface->bo)
4851 return VA_STATUS_ERROR_INVALID_SURFACE;
4853 assert(obj_surface->fourcc);
4854 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4856 if (tiling != I915_TILING_NONE)
4857 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4859 dri_bo_map(obj_surface->bo, 0);
4861 if (!obj_surface->bo->virtual)
4862 return VA_STATUS_ERROR_INVALID_SURFACE;
4864 /* Both dest VA image and source surface have YUYV format */
4865 dst = image_data + obj_image->image.offsets[0];
4866 src = (uint8_t *)obj_surface->bo->virtual;
4869 dst += rect->y * obj_image->image.pitches[0] + rect->x*2;
4870 src += rect->y * obj_surface->width + rect->x*2;
4871 memcpy_pic(dst, obj_image->image.pitches[0],
4872 src, obj_surface->width*2,
4873 rect->width*2, rect->height);
4875 if (tiling != I915_TILING_NONE)
4876 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4878 dri_bo_unmap(obj_surface->bo);
4884 i965_sw_getimage(VADriverContextP ctx,
4885 struct object_surface *obj_surface, struct object_image *obj_image,
4886 const VARectangle *rect)
4888 void *image_data = NULL;
4891 if (obj_surface->fourcc != obj_image->image.format.fourcc)
4892 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
4894 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
4895 if (va_status != VA_STATUS_SUCCESS)
4898 switch (obj_image->image.format.fourcc) {
4899 case VA_FOURCC_YV12:
4900 case VA_FOURCC_I420:
4901 get_image_i420(obj_image, image_data, obj_surface, rect);
4903 case VA_FOURCC_NV12:
4904 get_image_nv12(obj_image, image_data, obj_surface, rect);
4906 case VA_FOURCC_YUY2:
4907 /* YUY2 is the format supported by overlay plane */
4908 get_image_yuy2(obj_image, image_data, obj_surface, rect);
4911 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
4914 if (va_status != VA_STATUS_SUCCESS)
4917 va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
4922 i965_hw_getimage(VADriverContextP ctx,
4923 struct object_surface *obj_surface, struct object_image *obj_image,
4924 const VARectangle *rect)
4926 struct i965_surface src_surface;
4927 struct i965_surface dst_surface;
4929 src_surface.base = (struct object_base *)obj_surface;
4930 src_surface.type = I965_SURFACE_TYPE_SURFACE;
4931 src_surface.flags = I965_SURFACE_FLAG_FRAME;
4933 dst_surface.base = (struct object_base *)obj_image;
4934 dst_surface.type = I965_SURFACE_TYPE_IMAGE;
4935 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4937 return i965_image_processing(ctx, &src_surface, rect, &dst_surface, rect);
4941 i965_GetImage(VADriverContextP ctx,
4942 VASurfaceID surface,
4943 int x, /* coordinates of the upper left source pixel */
4945 unsigned int width, /* width and height of the region */
4946 unsigned int height,
4949 struct i965_driver_data * const i965 = i965_driver_data(ctx);
4950 struct object_surface * const obj_surface = SURFACE(surface);
4951 struct object_image * const obj_image = IMAGE(image);
4956 return VA_STATUS_ERROR_INVALID_SURFACE;
4957 if (!obj_surface->bo) /* don't get anything, keep previous data */
4958 return VA_STATUS_SUCCESS;
4959 if (is_surface_busy(i965, obj_surface))
4960 return VA_STATUS_ERROR_SURFACE_BUSY;
4962 if (!obj_image || !obj_image->bo)
4963 return VA_STATUS_ERROR_INVALID_IMAGE;
4964 if (is_image_busy(i965, obj_image, surface))
4965 return VA_STATUS_ERROR_SURFACE_BUSY;
4968 return VA_STATUS_ERROR_INVALID_PARAMETER;
4969 if (x + width > obj_surface->orig_width ||
4970 y + height > obj_surface->orig_height)
4971 return VA_STATUS_ERROR_INVALID_PARAMETER;
4972 if (x + width > obj_image->image.width ||
4973 y + height > obj_image->image.height)
4974 return VA_STATUS_ERROR_INVALID_PARAMETER;
4979 rect.height = height;
4981 if (HAS_ACCELERATED_GETIMAGE(i965))
4982 va_status = i965_hw_getimage(ctx, obj_surface, obj_image, &rect);
4984 va_status = i965_sw_getimage(ctx, obj_surface, obj_image, &rect);
4990 put_image_i420(struct object_surface *obj_surface,
4991 const VARectangle *dst_rect,
4992 struct object_image *obj_image, uint8_t *image_data,
4993 const VARectangle *src_rect)
4995 uint8_t *dst[3], *src[3];
4997 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
4998 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
4999 unsigned int tiling, swizzle;
5000 VAStatus va_status = VA_STATUS_SUCCESS;
5002 ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
5004 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
5005 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
5006 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
5007 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
5009 if (tiling != I915_TILING_NONE)
5010 drm_intel_gem_bo_map_gtt(obj_surface->bo);
5012 dri_bo_map(obj_surface->bo, 0);
5014 if (!obj_surface->bo->virtual)
5015 return VA_STATUS_ERROR_INVALID_SURFACE;
5017 /* Dest VA image has either I420 or YV12 format.
5018 Source VA surface alway has I420 format */
5019 dst[0] = (uint8_t *)obj_surface->bo->virtual;
5020 src[Y] = image_data + obj_image->image.offsets[Y];
5021 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
5022 src[U] = image_data + obj_image->image.offsets[U];
5023 dst[2] = dst[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
5024 src[V] = image_data + obj_image->image.offsets[V];
5027 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
5028 src[Y] += src_rect->y * obj_image->image.pitches[Y] + src_rect->x;
5029 memcpy_pic(dst[0], obj_surface->width,
5030 src[Y], obj_image->image.pitches[Y],
5031 src_rect->width, src_rect->height);
5034 dst[1] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
5035 src[U] += (src_rect->y / 2) * obj_image->image.pitches[U] + src_rect->x / 2;
5036 memcpy_pic(dst[1], obj_surface->width / 2,
5037 src[U], obj_image->image.pitches[U],
5038 src_rect->width / 2, src_rect->height / 2);
5041 dst[2] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
5042 src[V] += (src_rect->y / 2) * obj_image->image.pitches[V] + src_rect->x / 2;
5043 memcpy_pic(dst[2], obj_surface->width / 2,
5044 src[V], obj_image->image.pitches[V],
5045 src_rect->width / 2, src_rect->height / 2);
5047 if (tiling != I915_TILING_NONE)
5048 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
5050 dri_bo_unmap(obj_surface->bo);
5056 put_image_nv12(struct object_surface *obj_surface,
5057 const VARectangle *dst_rect,
5058 struct object_image *obj_image, uint8_t *image_data,
5059 const VARectangle *src_rect)
5061 uint8_t *dst[2], *src[2];
5062 unsigned int tiling, swizzle;
5063 VAStatus va_status = VA_STATUS_SUCCESS;
5065 if (!obj_surface->bo)
5066 return VA_STATUS_ERROR_INVALID_SURFACE;
5068 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
5069 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
5070 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
5071 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
5073 if (tiling != I915_TILING_NONE)
5074 drm_intel_gem_bo_map_gtt(obj_surface->bo);
5076 dri_bo_map(obj_surface->bo, 0);
5078 if (!obj_surface->bo->virtual)
5079 return VA_STATUS_ERROR_INVALID_SURFACE;
5081 /* Both dest VA image and source surface have NV12 format */
5082 dst[0] = (uint8_t *)obj_surface->bo->virtual;
5083 src[0] = image_data + obj_image->image.offsets[0];
5084 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
5085 src[1] = image_data + obj_image->image.offsets[1];
5088 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
5089 src[0] += src_rect->y * obj_image->image.pitches[0] + src_rect->x;
5090 memcpy_pic(dst[0], obj_surface->width,
5091 src[0], obj_image->image.pitches[0],
5092 src_rect->width, src_rect->height);
5095 dst[1] += (dst_rect->y / 2) * obj_surface->width + (dst_rect->x & -2);
5096 src[1] += (src_rect->y / 2) * obj_image->image.pitches[1] + (src_rect->x & -2);
5097 memcpy_pic(dst[1], obj_surface->width,
5098 src[1], obj_image->image.pitches[1],
5099 src_rect->width, src_rect->height / 2);
5101 if (tiling != I915_TILING_NONE)
5102 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
5104 dri_bo_unmap(obj_surface->bo);
5110 put_image_yuy2(struct object_surface *obj_surface,
5111 const VARectangle *dst_rect,
5112 struct object_image *obj_image, uint8_t *image_data,
5113 const VARectangle *src_rect)
5116 unsigned int tiling, swizzle;
5117 VAStatus va_status = VA_STATUS_SUCCESS;
5119 ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
5120 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
5121 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
5122 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
5123 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
5125 if (tiling != I915_TILING_NONE)
5126 drm_intel_gem_bo_map_gtt(obj_surface->bo);
5128 dri_bo_map(obj_surface->bo, 0);
5130 if (!obj_surface->bo->virtual)
5131 return VA_STATUS_ERROR_INVALID_SURFACE;
5133 /* Both dest VA image and source surface have YUY2 format */
5134 dst = (uint8_t *)obj_surface->bo->virtual;
5135 src = image_data + obj_image->image.offsets[0];
5137 /* YUYV packed plane */
5138 dst += dst_rect->y * obj_surface->width + dst_rect->x*2;
5139 src += src_rect->y * obj_image->image.pitches[0] + src_rect->x*2;
5140 memcpy_pic(dst, obj_surface->width*2,
5141 src, obj_image->image.pitches[0],
5142 src_rect->width*2, src_rect->height);
5144 if (tiling != I915_TILING_NONE)
5145 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
5147 dri_bo_unmap(obj_surface->bo);
5153 i965_sw_putimage(VADriverContextP ctx,
5154 struct object_surface *obj_surface, struct object_image *obj_image,
5155 const VARectangle *src_rect, const VARectangle *dst_rect)
5157 VAStatus va_status = VA_STATUS_SUCCESS;
5158 void *image_data = NULL;
5160 /* XXX: don't allow scaling */
5161 if (src_rect->width != dst_rect->width ||
5162 src_rect->height != dst_rect->height)
5163 return VA_STATUS_ERROR_INVALID_PARAMETER;
5165 if (obj_surface->fourcc) {
5166 /* Don't allow format mismatch */
5167 if (obj_surface->fourcc != obj_image->image.format.fourcc)
5168 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
5172 /* VA is surface not used for decoding, use same VA image format */
5173 va_status = i965_check_alloc_surface_bo(
5176 0, /* XXX: don't use tiled surface */
5177 obj_image->image.format.fourcc,
5178 get_sampling_from_fourcc (obj_image->image.format.fourcc));
5181 if (va_status != VA_STATUS_SUCCESS)
5184 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
5185 if (va_status != VA_STATUS_SUCCESS)
5188 switch (obj_image->image.format.fourcc) {
5189 case VA_FOURCC_YV12:
5190 case VA_FOURCC_I420:
5191 va_status = put_image_i420(obj_surface, dst_rect, obj_image, image_data, src_rect);
5193 case VA_FOURCC_NV12:
5194 va_status = put_image_nv12(obj_surface, dst_rect, obj_image, image_data, src_rect);
5196 case VA_FOURCC_YUY2:
5197 va_status = put_image_yuy2(obj_surface, dst_rect, obj_image, image_data, src_rect);
5200 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
5203 if (va_status != VA_STATUS_SUCCESS)
5206 va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
5211 i965_hw_putimage(VADriverContextP ctx,
5212 struct object_surface *obj_surface, struct object_image *obj_image,
5213 const VARectangle *src_rect, const VARectangle *dst_rect)
5215 struct i965_surface src_surface, dst_surface;
5216 VAStatus va_status = VA_STATUS_SUCCESS;
5218 if (!obj_surface->bo) {
5219 unsigned int tiling, swizzle;
5220 int surface_sampling = get_sampling_from_fourcc (obj_image->image.format.fourcc);;
5221 dri_bo_get_tiling(obj_image->bo, &tiling, &swizzle);
5223 i965_check_alloc_surface_bo(ctx,
5226 obj_image->image.format.fourcc,
5230 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
5232 src_surface.base = (struct object_base *)obj_image;
5233 src_surface.type = I965_SURFACE_TYPE_IMAGE;
5234 src_surface.flags = I965_SURFACE_FLAG_FRAME;
5236 dst_surface.base = (struct object_base *)obj_surface;
5237 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
5238 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
5240 va_status = i965_image_processing(ctx,
5250 i965_PutImage(VADriverContextP ctx,
5251 VASurfaceID surface,
5255 unsigned int src_width,
5256 unsigned int src_height,
5259 unsigned int dest_width,
5260 unsigned int dest_height)
5262 struct i965_driver_data * const i965 = i965_driver_data(ctx);
5263 struct object_surface * const obj_surface = SURFACE(surface);
5264 struct object_image * const obj_image = IMAGE(image);
5265 VARectangle src_rect, dst_rect;
5269 return VA_STATUS_ERROR_INVALID_SURFACE;
5270 if (is_surface_busy(i965, obj_surface))
5271 return VA_STATUS_ERROR_SURFACE_BUSY;
5273 if (!obj_image || !obj_image->bo)
5274 return VA_STATUS_ERROR_INVALID_IMAGE;
5275 if (is_image_busy(i965, obj_image, surface))
5276 return VA_STATUS_ERROR_SURFACE_BUSY;
5280 src_x + src_width > obj_image->image.width ||
5281 src_y + src_height > obj_image->image.height)
5282 return VA_STATUS_ERROR_INVALID_PARAMETER;
5286 src_rect.width = src_width;
5287 src_rect.height = src_height;
5291 dest_x + dest_width > obj_surface->orig_width ||
5292 dest_y + dest_height > obj_surface->orig_height)
5293 return VA_STATUS_ERROR_INVALID_PARAMETER;
5295 dst_rect.x = dest_x;
5296 dst_rect.y = dest_y;
5297 dst_rect.width = dest_width;
5298 dst_rect.height = dest_height;
5300 if (HAS_ACCELERATED_PUTIMAGE(i965))
5301 va_status = i965_hw_putimage(ctx, obj_surface, obj_image,
5302 &src_rect, &dst_rect);
5304 va_status = i965_sw_putimage(ctx, obj_surface, obj_image,
5305 &src_rect, &dst_rect);
5311 i965_PutSurface(VADriverContextP ctx,
5312 VASurfaceID surface,
5313 void *draw, /* X Drawable */
5316 unsigned short srcw,
5317 unsigned short srch,
5320 unsigned short destw,
5321 unsigned short desth,
5322 VARectangle *cliprects, /* client supplied clip list */
5323 unsigned int number_cliprects, /* number of clip rects in the clip list */
5324 unsigned int flags) /* de-interlacing flags */
5327 if (IS_VA_X11(ctx)) {
5328 VARectangle src_rect, dst_rect;
5332 src_rect.width = srcw;
5333 src_rect.height = srch;
5337 dst_rect.width = destw;
5338 dst_rect.height = desth;
5340 return i965_put_surface_dri(ctx, surface, draw, &src_rect, &dst_rect,
5341 cliprects, number_cliprects, flags);
5344 return VA_STATUS_ERROR_UNIMPLEMENTED;
5349 VADriverContextP ctx, /* in */
5350 VABufferID buf_id, /* in */
5351 VABufferType *type, /* out */
5352 unsigned int *size, /* out */
5353 unsigned int *num_elements /* out */
5356 struct i965_driver_data *i965 = NULL;
5357 struct object_buffer *obj_buffer = NULL;
5359 i965 = i965_driver_data(ctx);
5360 obj_buffer = BUFFER(buf_id);
5362 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
5364 *type = obj_buffer->type;
5365 *size = obj_buffer->size_element;
5366 *num_elements = obj_buffer->num_elements;
5368 return VA_STATUS_SUCCESS;
5373 VADriverContextP ctx, /* in */
5374 VASurfaceID surface, /* in */
5375 unsigned int *fourcc, /* out */
5376 unsigned int *luma_stride, /* out */
5377 unsigned int *chroma_u_stride, /* out */
5378 unsigned int *chroma_v_stride, /* out */
5379 unsigned int *luma_offset, /* out */
5380 unsigned int *chroma_u_offset, /* out */
5381 unsigned int *chroma_v_offset, /* out */
5382 unsigned int *buffer_name, /* out */
5383 void **buffer /* out */
5386 VAStatus vaStatus = VA_STATUS_SUCCESS;
5387 struct i965_driver_data *i965 = i965_driver_data(ctx);
5388 struct object_surface *obj_surface = NULL;
5391 ASSERT_RET(fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
5392 ASSERT_RET(luma_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
5393 ASSERT_RET(chroma_u_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
5394 ASSERT_RET(chroma_v_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
5395 ASSERT_RET(luma_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
5396 ASSERT_RET(chroma_u_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
5397 ASSERT_RET(chroma_v_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
5398 ASSERT_RET(buffer_name, VA_STATUS_ERROR_INVALID_PARAMETER);
5399 ASSERT_RET(buffer, VA_STATUS_ERROR_INVALID_PARAMETER);
5401 tmpImage.image_id = VA_INVALID_ID;
5403 obj_surface = SURFACE(surface);
5404 if (obj_surface == NULL) {
5405 // Surface is absent.
5406 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
5410 // Lock functionality is absent now.
5411 if (obj_surface->locked_image_id != VA_INVALID_ID) {
5412 // Surface is locked already.
5413 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
5417 vaStatus = i965_DeriveImage(
5421 if (vaStatus != VA_STATUS_SUCCESS) {
5425 obj_surface->locked_image_id = tmpImage.image_id;
5427 vaStatus = i965_MapBuffer(
5431 if (vaStatus != VA_STATUS_SUCCESS) {
5435 *fourcc = tmpImage.format.fourcc;
5436 *luma_offset = tmpImage.offsets[0];
5437 *luma_stride = tmpImage.pitches[0];
5438 *chroma_u_offset = tmpImage.offsets[1];
5439 *chroma_u_stride = tmpImage.pitches[1];
5440 *chroma_v_offset = tmpImage.offsets[2];
5441 *chroma_v_stride = tmpImage.pitches[2];
5442 *buffer_name = tmpImage.buf;
5445 if (vaStatus != VA_STATUS_SUCCESS) {
5454 VADriverContextP ctx, /* in */
5455 VASurfaceID surface /* in */
5458 VAStatus vaStatus = VA_STATUS_SUCCESS;
5459 struct i965_driver_data *i965 = i965_driver_data(ctx);
5460 struct object_image *locked_img = NULL;
5461 struct object_surface *obj_surface = NULL;
5463 obj_surface = SURFACE(surface);
5465 if (obj_surface == NULL) {
5466 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is absent
5469 if (obj_surface->locked_image_id == VA_INVALID_ID) {
5470 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is not locked
5474 locked_img = IMAGE(obj_surface->locked_image_id);
5475 if (locked_img == NULL || (locked_img->image.image_id == VA_INVALID_ID)) {
5476 // Work image was deallocated before i965_UnlockSurface()
5477 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
5481 vaStatus = i965_UnmapBuffer(
5483 locked_img->image.buf);
5484 if (vaStatus != VA_STATUS_SUCCESS) {
5488 vaStatus = i965_DestroyImage(
5490 locked_img->image.image_id);
5491 if (vaStatus != VA_STATUS_SUCCESS) {
5495 locked_img->image.image_id = VA_INVALID_ID;
5498 obj_surface->locked_image_id = VA_INVALID_ID;
5504 i965_GetSurfaceAttributes(
5505 VADriverContextP ctx,
5507 VASurfaceAttrib *attrib_list,
5508 unsigned int num_attribs
5511 VAStatus vaStatus = VA_STATUS_SUCCESS;
5512 struct i965_driver_data *i965 = i965_driver_data(ctx);
5513 struct object_config *obj_config;
5516 if (config == VA_INVALID_ID)
5517 return VA_STATUS_ERROR_INVALID_CONFIG;
5519 obj_config = CONFIG(config);
5521 if (obj_config == NULL)
5522 return VA_STATUS_ERROR_INVALID_CONFIG;
5524 if (attrib_list == NULL || num_attribs == 0)
5525 return VA_STATUS_ERROR_INVALID_PARAMETER;
5527 for (i = 0; i < num_attribs; i++) {
5528 switch (attrib_list[i].type) {
5529 case VASurfaceAttribPixelFormat:
5530 attrib_list[i].value.type = VAGenericValueTypeInteger;
5531 attrib_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5533 if (attrib_list[i].value.value.i == 0) {
5534 if (IS_G4X(i965->intel.device_info)) {
5535 if (obj_config->profile == VAProfileMPEG2Simple ||
5536 obj_config->profile == VAProfileMPEG2Main) {
5537 attrib_list[i].value.value.i = VA_FOURCC_I420;
5540 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5542 } else if (IS_IRONLAKE(i965->intel.device_info)) {
5543 if (obj_config->profile == VAProfileMPEG2Simple ||
5544 obj_config->profile == VAProfileMPEG2Main) {
5545 attrib_list[i].value.value.i = VA_FOURCC_I420;
5546 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
5547 obj_config->profile == VAProfileH264Main ||
5548 obj_config->profile == VAProfileH264High) {
5549 attrib_list[i].value.value.i = VA_FOURCC_NV12;
5550 } else if (obj_config->profile == VAProfileNone) {
5551 attrib_list[i].value.value.i = VA_FOURCC_NV12;
5554 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5556 } else if (IS_GEN6(i965->intel.device_info)) {
5557 attrib_list[i].value.value.i = VA_FOURCC_NV12;
5558 } else if (IS_GEN7(i965->intel.device_info) ||
5559 IS_GEN8(i965->intel.device_info) ||
5560 IS_GEN9(i965->intel.device_info)) {
5561 if (obj_config->profile == VAProfileJPEGBaseline)
5562 attrib_list[i].value.value.i = 0; /* internal format */
5564 attrib_list[i].value.value.i = VA_FOURCC_NV12;
5567 if (IS_G4X(i965->intel.device_info)) {
5568 if (obj_config->profile == VAProfileMPEG2Simple ||
5569 obj_config->profile == VAProfileMPEG2Main) {
5570 if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
5571 attrib_list[i].value.value.i = 0;
5572 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5576 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5578 } else if (IS_IRONLAKE(i965->intel.device_info)) {
5579 if (obj_config->profile == VAProfileMPEG2Simple ||
5580 obj_config->profile == VAProfileMPEG2Main) {
5581 if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
5582 attrib_list[i].value.value.i = 0;
5583 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5585 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
5586 obj_config->profile == VAProfileH264Main ||
5587 obj_config->profile == VAProfileH264High) {
5588 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
5589 attrib_list[i].value.value.i = 0;
5590 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5592 } else if (obj_config->profile == VAProfileNone) {
5593 switch (attrib_list[i].value.value.i) {
5594 case VA_FOURCC_NV12:
5595 case VA_FOURCC_I420:
5596 case VA_FOURCC_YV12:
5597 case VA_FOURCC_YUY2:
5598 case VA_FOURCC_BGRA:
5599 case VA_FOURCC_BGRX:
5600 case VA_FOURCC_RGBX:
5601 case VA_FOURCC_RGBA:
5604 attrib_list[i].value.value.i = 0;
5605 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5610 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5612 } else if (IS_GEN6(i965->intel.device_info)) {
5613 if (obj_config->entrypoint == VAEntrypointEncSlice ||
5614 obj_config->entrypoint == VAEntrypointVideoProc) {
5615 switch (attrib_list[i].value.value.i) {
5616 case VA_FOURCC_NV12:
5617 case VA_FOURCC_I420:
5618 case VA_FOURCC_YV12:
5619 case VA_FOURCC_YUY2:
5620 case VA_FOURCC_BGRA:
5621 case VA_FOURCC_BGRX:
5622 case VA_FOURCC_RGBX:
5623 case VA_FOURCC_RGBA:
5626 attrib_list[i].value.value.i = 0;
5627 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5631 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
5632 attrib_list[i].value.value.i = 0;
5633 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5636 } else if (IS_GEN7(i965->intel.device_info) ||
5637 IS_GEN8(i965->intel.device_info) ||
5638 IS_GEN9(i965->intel.device_info)) {
5639 if (obj_config->entrypoint == VAEntrypointEncSlice ||
5640 obj_config->entrypoint == VAEntrypointVideoProc ||
5641 obj_config->entrypoint == VAEntrypointEncSliceLP) {
5642 switch (attrib_list[i].value.value.i) {
5643 case VA_FOURCC_NV12:
5644 case VA_FOURCC_I420:
5645 case VA_FOURCC_YV12:
5648 attrib_list[i].value.value.i = 0;
5649 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5653 if (obj_config->profile == VAProfileJPEGBaseline) {
5654 attrib_list[i].value.value.i = 0; /* JPEG decoding always uses an internal format */
5655 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5657 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
5658 attrib_list[i].value.value.i = 0;
5659 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5667 case VASurfaceAttribMinWidth:
5668 /* FIXME: add support for it later */
5669 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5671 case VASurfaceAttribMaxWidth:
5672 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5674 case VASurfaceAttribMinHeight:
5675 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5677 case VASurfaceAttribMaxHeight:
5678 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5681 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5690 i965_QuerySurfaceAttributes(VADriverContextP ctx,
5692 VASurfaceAttrib *attrib_list,
5693 unsigned int *num_attribs)
5695 VAStatus vaStatus = VA_STATUS_SUCCESS;
5696 struct i965_driver_data *i965 = i965_driver_data(ctx);
5697 struct object_config *obj_config;
5699 VASurfaceAttrib *attribs = NULL;
5703 if (config == VA_INVALID_ID)
5704 return VA_STATUS_ERROR_INVALID_CONFIG;
5706 obj_config = CONFIG(config);
5708 if (obj_config == NULL)
5709 return VA_STATUS_ERROR_INVALID_CONFIG;
5711 if (!attrib_list && !num_attribs)
5712 return VA_STATUS_ERROR_INVALID_PARAMETER;
5714 if (attrib_list == NULL) {
5715 *num_attribs = I965_MAX_SURFACE_ATTRIBUTES;
5716 return VA_STATUS_SUCCESS;
5719 attribs = malloc(I965_MAX_SURFACE_ATTRIBUTES *sizeof(*attribs));
5721 if (attribs == NULL)
5722 return VA_STATUS_ERROR_ALLOCATION_FAILED;
5724 if (IS_G4X(i965->intel.device_info)) {
5725 if (obj_config->profile == VAProfileMPEG2Simple ||
5726 obj_config->profile == VAProfileMPEG2Main) {
5727 attribs[i].type = VASurfaceAttribPixelFormat;
5728 attribs[i].value.type = VAGenericValueTypeInteger;
5729 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5730 attribs[i].value.value.i = VA_FOURCC_I420;
5733 } else if (IS_IRONLAKE(i965->intel.device_info)) {
5734 switch (obj_config->profile) {
5735 case VAProfileMPEG2Simple:
5736 case VAProfileMPEG2Main:
5737 attribs[i].type = VASurfaceAttribPixelFormat;
5738 attribs[i].value.type = VAGenericValueTypeInteger;
5739 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5740 attribs[i].value.value.i = VA_FOURCC_I420;
5745 case VAProfileH264ConstrainedBaseline:
5746 case VAProfileH264Main:
5747 case VAProfileH264High:
5748 attribs[i].type = VASurfaceAttribPixelFormat;
5749 attribs[i].value.type = VAGenericValueTypeInteger;
5750 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5751 attribs[i].value.value.i = VA_FOURCC_NV12;
5755 attribs[i].type = VASurfaceAttribPixelFormat;
5756 attribs[i].value.type = VAGenericValueTypeInteger;
5757 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5758 attribs[i].value.value.i = VA_FOURCC_NV12;
5761 attribs[i].type = VASurfaceAttribPixelFormat;
5762 attribs[i].value.type = VAGenericValueTypeInteger;
5763 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5764 attribs[i].value.value.i = VA_FOURCC_I420;
5772 } else if (IS_GEN6(i965->intel.device_info)) {
5773 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
5774 attribs[i].type = VASurfaceAttribPixelFormat;
5775 attribs[i].value.type = VAGenericValueTypeInteger;
5776 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5777 attribs[i].value.value.i = VA_FOURCC_NV12;
5779 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
5780 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
5781 attribs[i].type = VASurfaceAttribPixelFormat;
5782 attribs[i].value.type = VAGenericValueTypeInteger;
5783 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5784 attribs[i].value.value.i = VA_FOURCC_NV12;
5787 attribs[i].type = VASurfaceAttribPixelFormat;
5788 attribs[i].value.type = VAGenericValueTypeInteger;
5789 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5790 attribs[i].value.value.i = VA_FOURCC_I420;
5793 attribs[i].type = VASurfaceAttribPixelFormat;
5794 attribs[i].value.type = VAGenericValueTypeInteger;
5795 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5796 attribs[i].value.value.i = VA_FOURCC_YV12;
5799 if (obj_config->entrypoint == VAEntrypointVideoProc) {
5800 attribs[i].type = VASurfaceAttribPixelFormat;
5801 attribs[i].value.type = VAGenericValueTypeInteger;
5802 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5803 attribs[i].value.value.i = VA_FOURCC_YUY2;
5806 attribs[i].type = VASurfaceAttribPixelFormat;
5807 attribs[i].value.type = VAGenericValueTypeInteger;
5808 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5809 attribs[i].value.value.i = VA_FOURCC_RGBA;
5812 attribs[i].type = VASurfaceAttribPixelFormat;
5813 attribs[i].value.type = VAGenericValueTypeInteger;
5814 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5815 attribs[i].value.value.i = VA_FOURCC_RGBX;
5819 } else if (IS_GEN7(i965->intel.device_info)) {
5820 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
5821 if (obj_config->profile == VAProfileJPEGBaseline) {
5822 attribs[i].type = VASurfaceAttribPixelFormat;
5823 attribs[i].value.type = VAGenericValueTypeInteger;
5824 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5825 attribs[i].value.value.i = VA_FOURCC_IMC3;
5828 attribs[i].type = VASurfaceAttribPixelFormat;
5829 attribs[i].value.type = VAGenericValueTypeInteger;
5830 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5831 attribs[i].value.value.i = VA_FOURCC_IMC1;
5834 attribs[i].type = VASurfaceAttribPixelFormat;
5835 attribs[i].value.type = VAGenericValueTypeInteger;
5836 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5837 attribs[i].value.value.i = VA_FOURCC_Y800;
5840 attribs[i].type = VASurfaceAttribPixelFormat;
5841 attribs[i].value.type = VAGenericValueTypeInteger;
5842 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5843 attribs[i].value.value.i = VA_FOURCC_411P;
5846 attribs[i].type = VASurfaceAttribPixelFormat;
5847 attribs[i].value.type = VAGenericValueTypeInteger;
5848 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5849 attribs[i].value.value.i = VA_FOURCC_422H;
5852 attribs[i].type = VASurfaceAttribPixelFormat;
5853 attribs[i].value.type = VAGenericValueTypeInteger;
5854 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5855 attribs[i].value.value.i = VA_FOURCC_422V;
5858 attribs[i].type = VASurfaceAttribPixelFormat;
5859 attribs[i].value.type = VAGenericValueTypeInteger;
5860 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5861 attribs[i].value.value.i = VA_FOURCC_444P;
5863 } else if (obj_config->profile == VAProfileHEVCMain10) {
5864 attribs[i].type = VASurfaceAttribPixelFormat;
5865 attribs[i].value.type = VAGenericValueTypeInteger;
5866 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5867 attribs[i].value.value.i = VA_FOURCC_P010;
5870 attribs[i].type = VASurfaceAttribPixelFormat;
5871 attribs[i].value.type = VAGenericValueTypeInteger;
5872 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5873 attribs[i].value.value.i = VA_FOURCC_NV12;
5876 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
5877 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
5878 attribs[i].type = VASurfaceAttribPixelFormat;
5879 attribs[i].value.type = VAGenericValueTypeInteger;
5880 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5881 attribs[i].value.value.i = VA_FOURCC_NV12;
5884 attribs[i].type = VASurfaceAttribPixelFormat;
5885 attribs[i].value.type = VAGenericValueTypeInteger;
5886 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5887 attribs[i].value.value.i = VA_FOURCC_I420;
5890 attribs[i].type = VASurfaceAttribPixelFormat;
5891 attribs[i].value.type = VAGenericValueTypeInteger;
5892 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5893 attribs[i].value.value.i = VA_FOURCC_YV12;
5896 attribs[i].type = VASurfaceAttribPixelFormat;
5897 attribs[i].value.type = VAGenericValueTypeInteger;
5898 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5899 attribs[i].value.value.i = VA_FOURCC_IMC3;
5902 if (obj_config->entrypoint == VAEntrypointVideoProc) {
5903 attribs[i].type = VASurfaceAttribPixelFormat;
5904 attribs[i].value.type = VAGenericValueTypeInteger;
5905 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5906 attribs[i].value.value.i = VA_FOURCC_YUY2;
5909 attribs[i].type = VASurfaceAttribPixelFormat;
5910 attribs[i].value.type = VAGenericValueTypeInteger;
5911 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5912 attribs[i].value.value.i = VA_FOURCC_RGBA;
5915 attribs[i].type = VASurfaceAttribPixelFormat;
5916 attribs[i].value.type = VAGenericValueTypeInteger;
5917 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5918 attribs[i].value.value.i = VA_FOURCC_RGBX;
5921 attribs[i].type = VASurfaceAttribPixelFormat;
5922 attribs[i].value.type = VAGenericValueTypeInteger;
5923 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5924 attribs[i].value.value.i = VA_FOURCC_BGRA;
5927 attribs[i].type = VASurfaceAttribPixelFormat;
5928 attribs[i].value.type = VAGenericValueTypeInteger;
5929 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5930 attribs[i].value.value.i = VA_FOURCC_BGRX;
5933 attribs[i].type = VASurfaceAttribPixelFormat;
5934 attribs[i].value.type = VAGenericValueTypeInteger;
5935 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5936 attribs[i].value.value.i = VA_FOURCC_YV16;
5940 } else if (IS_GEN8(i965->intel.device_info) ||
5941 IS_GEN9(i965->intel.device_info)) {
5942 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
5943 if (obj_config->profile == VAProfileJPEGBaseline) {
5944 attribs[i].type = VASurfaceAttribPixelFormat;
5945 attribs[i].value.type = VAGenericValueTypeInteger;
5946 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5947 attribs[i].value.value.i = VA_FOURCC_IMC3;
5950 attribs[i].type = VASurfaceAttribPixelFormat;
5951 attribs[i].value.type = VAGenericValueTypeInteger;
5952 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5953 attribs[i].value.value.i = VA_FOURCC_IMC1;
5956 attribs[i].type = VASurfaceAttribPixelFormat;
5957 attribs[i].value.type = VAGenericValueTypeInteger;
5958 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5959 attribs[i].value.value.i = VA_FOURCC_Y800;
5962 attribs[i].type = VASurfaceAttribPixelFormat;
5963 attribs[i].value.type = VAGenericValueTypeInteger;
5964 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5965 attribs[i].value.value.i = VA_FOURCC_411P;
5968 attribs[i].type = VASurfaceAttribPixelFormat;
5969 attribs[i].value.type = VAGenericValueTypeInteger;
5970 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5971 attribs[i].value.value.i = VA_FOURCC_422H;
5974 attribs[i].type = VASurfaceAttribPixelFormat;
5975 attribs[i].value.type = VAGenericValueTypeInteger;
5976 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5977 attribs[i].value.value.i = VA_FOURCC_422V;
5980 attribs[i].type = VASurfaceAttribPixelFormat;
5981 attribs[i].value.type = VAGenericValueTypeInteger;
5982 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5983 attribs[i].value.value.i = VA_FOURCC_444P;
5986 attribs[i].type = VASurfaceAttribPixelFormat;
5987 attribs[i].value.type = VAGenericValueTypeInteger;
5988 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5989 attribs[i].value.value.i = VA_FOURCC_NV12;
5992 if ((obj_config->profile == VAProfileHEVCMain10) ||
5993 (obj_config->profile == VAProfileVP9Profile2)) {
5994 attribs[i].type = VASurfaceAttribPixelFormat;
5995 attribs[i].value.type = VAGenericValueTypeInteger;
5996 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5997 attribs[i].value.value.i = VA_FOURCC_P010;
6001 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
6002 obj_config->entrypoint == VAEntrypointVideoProc ||
6003 obj_config->entrypoint == VAEntrypointEncSliceLP ||
6004 obj_config->entrypoint == VAEntrypointEncPicture) {
6006 if (obj_config->profile == VAProfileHEVCMain10) {
6007 attribs[i].type = VASurfaceAttribPixelFormat;
6008 attribs[i].value.type = VAGenericValueTypeInteger;
6009 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6010 attribs[i].value.value.i = VA_FOURCC_P010;
6013 attribs[i].type = VASurfaceAttribPixelFormat;
6014 attribs[i].value.type = VAGenericValueTypeInteger;
6015 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6016 attribs[i].value.value.i = VA_FOURCC_NV12;
6019 attribs[i].type = VASurfaceAttribPixelFormat;
6020 attribs[i].value.type = VAGenericValueTypeInteger;
6021 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6022 attribs[i].value.value.i = VA_FOURCC_I420;
6025 attribs[i].type = VASurfaceAttribPixelFormat;
6026 attribs[i].value.type = VAGenericValueTypeInteger;
6027 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6028 attribs[i].value.value.i = VA_FOURCC_YV12;
6031 attribs[i].type = VASurfaceAttribPixelFormat;
6032 attribs[i].value.type = VAGenericValueTypeInteger;
6033 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6034 attribs[i].value.value.i = VA_FOURCC_IMC3;
6038 if (obj_config->entrypoint == VAEntrypointVideoProc) {
6039 attribs[i].type = VASurfaceAttribPixelFormat;
6040 attribs[i].value.type = VAGenericValueTypeInteger;
6041 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6042 attribs[i].value.value.i = VA_FOURCC_YUY2;
6045 attribs[i].type = VASurfaceAttribPixelFormat;
6046 attribs[i].value.type = VAGenericValueTypeInteger;
6047 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6048 attribs[i].value.value.i = VA_FOURCC_RGBA;
6051 attribs[i].type = VASurfaceAttribPixelFormat;
6052 attribs[i].value.type = VAGenericValueTypeInteger;
6053 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6054 attribs[i].value.value.i = VA_FOURCC_RGBX;
6057 attribs[i].type = VASurfaceAttribPixelFormat;
6058 attribs[i].value.type = VAGenericValueTypeInteger;
6059 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6060 attribs[i].value.value.i = VA_FOURCC_BGRA;
6063 attribs[i].type = VASurfaceAttribPixelFormat;
6064 attribs[i].value.type = VAGenericValueTypeInteger;
6065 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6066 attribs[i].value.value.i = VA_FOURCC_BGRX;
6069 attribs[i].type = VASurfaceAttribPixelFormat;
6070 attribs[i].value.type = VAGenericValueTypeInteger;
6071 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6072 attribs[i].value.value.i = VA_FOURCC_YV16;
6075 if(HAS_VPP_P010(i965)) {
6076 attribs[i].type = VASurfaceAttribPixelFormat;
6077 attribs[i].value.type = VAGenericValueTypeInteger;
6078 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6079 attribs[i].value.value.i = VA_FOURCC_P010;
6082 attribs[i].type = VASurfaceAttribPixelFormat;
6083 attribs[i].value.type = VAGenericValueTypeInteger;
6084 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6085 attribs[i].value.value.i = VA_FOURCC_I010;
6090 /* Additional support for jpeg encoder */
6091 if (obj_config->profile == VAProfileJPEGBaseline
6092 && obj_config->entrypoint == VAEntrypointEncPicture) {
6093 attribs[i].type = VASurfaceAttribPixelFormat;
6094 attribs[i].value.type = VAGenericValueTypeInteger;
6095 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6096 attribs[i].value.value.i = VA_FOURCC_YUY2;
6099 attribs[i].type = VASurfaceAttribPixelFormat;
6100 attribs[i].value.type = VAGenericValueTypeInteger;
6101 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6102 attribs[i].value.value.i = VA_FOURCC_UYVY;
6105 attribs[i].type = VASurfaceAttribPixelFormat;
6106 attribs[i].value.type = VAGenericValueTypeInteger;
6107 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6108 attribs[i].value.value.i = VA_FOURCC_YV16;
6111 attribs[i].type = VASurfaceAttribPixelFormat;
6112 attribs[i].value.type = VAGenericValueTypeInteger;
6113 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6114 attribs[i].value.value.i = VA_FOURCC_Y800;
6120 attribs[i].type = VASurfaceAttribMemoryType;
6121 attribs[i].value.type = VAGenericValueTypeInteger;
6122 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
6123 attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
6124 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
6125 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
6128 attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
6129 attribs[i].value.type = VAGenericValueTypePointer;
6130 attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
6131 attribs[i].value.value.p = NULL; /* ignore */
6134 max_resolution(i965, obj_config, &max_width, &max_height);
6136 attribs[i].type = VASurfaceAttribMaxWidth;
6137 attribs[i].value.type = VAGenericValueTypeInteger;
6138 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
6139 attribs[i].value.value.i = max_width;
6142 attribs[i].type = VASurfaceAttribMaxHeight;
6143 attribs[i].value.type = VAGenericValueTypeInteger;
6144 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
6145 attribs[i].value.value.i = max_height;
6148 if (i > *num_attribs) {
6151 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
6155 memcpy(attrib_list, attribs, i * sizeof(*attribs));
6161 /* Acquires buffer handle for external API usage (internal implementation) */
6163 i965_acquire_buffer_handle(struct object_buffer *obj_buffer,
6164 uint32_t mem_type, VABufferInfo *out_buf_info)
6166 struct buffer_store *buffer_store;
6168 buffer_store = obj_buffer->buffer_store;
6169 if (!buffer_store || !buffer_store->bo)
6170 return VA_STATUS_ERROR_INVALID_BUFFER;
6172 /* Synchronization point */
6173 drm_intel_bo_wait_rendering(buffer_store->bo);
6175 if (obj_buffer->export_refcount > 0) {
6176 if (obj_buffer->export_state.mem_type != mem_type)
6177 return VA_STATUS_ERROR_INVALID_PARAMETER;
6180 VABufferInfo * const buf_info = &obj_buffer->export_state;
6183 case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: {
6185 if (drm_intel_bo_flink(buffer_store->bo, &name) != 0)
6186 return VA_STATUS_ERROR_INVALID_BUFFER;
6187 buf_info->handle = name;
6190 case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
6192 if (drm_intel_bo_gem_export_to_prime(buffer_store->bo, &fd) != 0)
6193 return VA_STATUS_ERROR_INVALID_BUFFER;
6194 buf_info->handle = (intptr_t)fd;
6199 buf_info->type = obj_buffer->type;
6200 buf_info->mem_type = mem_type;
6201 buf_info->mem_size =
6202 obj_buffer->num_elements * obj_buffer->size_element;
6205 obj_buffer->export_refcount++;
6206 *out_buf_info = obj_buffer->export_state;
6207 return VA_STATUS_SUCCESS;
6210 /* Releases buffer handle after usage (internal implementation) */
6212 i965_release_buffer_handle(struct object_buffer *obj_buffer)
6214 if (obj_buffer->export_refcount == 0)
6215 return VA_STATUS_ERROR_INVALID_BUFFER;
6217 if (--obj_buffer->export_refcount == 0) {
6218 VABufferInfo * const buf_info = &obj_buffer->export_state;
6220 switch (buf_info->mem_type) {
6221 case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
6222 close((intptr_t)buf_info->handle);
6226 buf_info->mem_type = 0;
6228 return VA_STATUS_SUCCESS;
6231 /** Acquires buffer handle for external API usage */
6233 i965_AcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
6234 VABufferInfo *buf_info)
6236 struct i965_driver_data * const i965 = i965_driver_data(ctx);
6237 struct object_buffer * const obj_buffer = BUFFER(buf_id);
6238 uint32_t i, mem_type;
6240 /* List of supported memory types, in preferred order */
6241 static const uint32_t mem_types[] = {
6242 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
6243 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM,
6248 return VA_STATUS_ERROR_INVALID_BUFFER;
6249 /* XXX: only VA surface|image like buffers are supported for now */
6250 if (obj_buffer->type != VAImageBufferType)
6251 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
6254 * As the allocated buffer by calling vaCreateBuffer is related with
6255 * the specific context, it is unnecessary to export it.
6256 * So it is not supported when the buffer is allocated from wrapped
6259 if (obj_buffer->wrapper_buffer != VA_INVALID_ID) {
6260 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
6264 return VA_STATUS_ERROR_INVALID_PARAMETER;
6266 if (!buf_info->mem_type)
6267 mem_type = mem_types[0];
6270 for (i = 0; mem_types[i] != 0; i++) {
6271 if (buf_info->mem_type & mem_types[i]) {
6272 mem_type = buf_info->mem_type;
6277 return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
6279 return i965_acquire_buffer_handle(obj_buffer, mem_type, buf_info);
6282 /** Releases buffer handle after usage from external API */
6284 i965_ReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id)
6286 struct i965_driver_data * const i965 = i965_driver_data(ctx);
6287 struct object_buffer * const obj_buffer = BUFFER(buf_id);
6290 return VA_STATUS_ERROR_INVALID_BUFFER;
6292 if (obj_buffer->wrapper_buffer != VA_INVALID_ID) {
6293 return VA_STATUS_ERROR_INVALID_BUFFER;
6296 return i965_release_buffer_handle(obj_buffer);
6300 i965_os_has_ring_support(VADriverContextP ctx,
6303 struct i965_driver_data *const i965 = i965_driver_data(ctx);
6307 return i965->intel.has_bsd;
6310 return i965->intel.has_blt;
6312 case I965_RING_VEBOX:
6313 return i965->intel.has_vebox;
6315 case I965_RING_NULL:
6316 return 1; /* Always support */
6319 /* should never get here */
6328 * Query video processing pipeline
6330 VAStatus i965_QueryVideoProcFilters(
6331 VADriverContextP ctx,
6332 VAContextID context,
6333 VAProcFilterType *filters,
6334 unsigned int *num_filters
6337 struct i965_driver_data *const i965 = i965_driver_data(ctx);
6338 unsigned int i = 0, num = 0;
6340 if (!num_filters || !filters)
6341 return VA_STATUS_ERROR_INVALID_PARAMETER;
6343 for (i = 0; i < i965->codec_info->num_filters; i++) {
6344 if (i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring)) {
6345 if (num == *num_filters) {
6346 *num_filters = i965->codec_info->num_filters;
6348 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
6351 filters[num++] = i965->codec_info->filters[i].type;
6357 return VA_STATUS_SUCCESS;
6360 VAStatus i965_QueryVideoProcFilterCaps(
6361 VADriverContextP ctx,
6362 VAContextID context,
6363 VAProcFilterType type,
6365 unsigned int *num_filter_caps
6369 struct i965_driver_data *const i965 = i965_driver_data(ctx);
6371 if (!filter_caps || !num_filter_caps)
6372 return VA_STATUS_ERROR_INVALID_PARAMETER;
6374 for (i = 0; i < i965->codec_info->num_filters; i++) {
6375 if (type == i965->codec_info->filters[i].type &&
6376 i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring))
6380 if (i == i965->codec_info->num_filters)
6381 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
6386 case VAProcFilterNoiseReduction:
6387 case VAProcFilterSharpening:
6389 VAProcFilterCap *cap = filter_caps;
6391 if (*num_filter_caps < 1) {
6392 *num_filter_caps = 1;
6393 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
6396 cap->range.min_value = 0.0;
6397 cap->range.max_value = 1.0;
6398 cap->range.default_value = 0.5;
6399 cap->range.step = 0.03125; /* 1.0 / 32 */
6405 case VAProcFilterDeinterlacing:
6407 VAProcFilterCapDeinterlacing *cap = filter_caps;
6409 if (*num_filter_caps < VAProcDeinterlacingCount) {
6410 *num_filter_caps = VAProcDeinterlacingCount;
6411 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
6414 cap->type = VAProcDeinterlacingBob;
6419 if (i965->codec_info->has_di_motion_adptive) {
6420 cap->type = VAProcDeinterlacingMotionAdaptive;
6425 if (i965->codec_info->has_di_motion_compensated) {
6426 cap->type = VAProcDeinterlacingMotionCompensated;
6434 case VAProcFilterColorBalance:
6436 VAProcFilterCapColorBalance *cap = filter_caps;
6438 if (*num_filter_caps < VAProcColorBalanceCount) {
6439 *num_filter_caps = VAProcColorBalanceCount;
6440 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
6443 cap->type = VAProcColorBalanceHue;
6444 cap->range.min_value = -180.0;
6445 cap->range.max_value = 180.0;
6446 cap->range.default_value = 0.0;
6447 cap->range.step = 1.0;
6451 cap->type = VAProcColorBalanceSaturation;
6452 cap->range.min_value = 0.0;
6453 cap->range.max_value = 10.0;
6454 cap->range.default_value = 1.0;
6455 cap->range.step = 0.1;
6459 cap->type = VAProcColorBalanceBrightness;
6460 cap->range.min_value = -100.0;
6461 cap->range.max_value = 100.0;
6462 cap->range.default_value = 0.0;
6463 cap->range.step = 1.0;
6467 cap->type = VAProcColorBalanceContrast;
6468 cap->range.min_value = 0.0;
6469 cap->range.max_value = 10.0;
6470 cap->range.default_value = 1.0;
6471 cap->range.step = 0.1;
6483 *num_filter_caps = i;
6485 return VA_STATUS_SUCCESS;
6488 static VAProcColorStandardType vpp_input_color_standards[VAProcColorStandardCount] = {
6489 VAProcColorStandardBT601,
6492 static VAProcColorStandardType vpp_output_color_standards[VAProcColorStandardCount] = {
6493 VAProcColorStandardBT601,
6496 VAStatus i965_QueryVideoProcPipelineCaps(
6497 VADriverContextP ctx,
6498 VAContextID context,
6499 VABufferID *filters,
6500 unsigned int num_filters,
6501 VAProcPipelineCaps *pipeline_cap /* out */
6504 struct i965_driver_data * const i965 = i965_driver_data(ctx);
6507 pipeline_cap->pipeline_flags = 0;
6508 pipeline_cap->filter_flags = 0;
6509 pipeline_cap->num_forward_references = 0;
6510 pipeline_cap->num_backward_references = 0;
6511 pipeline_cap->num_input_color_standards = 1;
6512 pipeline_cap->input_color_standards = vpp_input_color_standards;
6513 pipeline_cap->num_output_color_standards = 1;
6514 pipeline_cap->output_color_standards = vpp_output_color_standards;
6516 for (i = 0; i < num_filters; i++) {
6517 struct object_buffer *obj_buffer = BUFFER(filters[i]);
6520 !obj_buffer->buffer_store ||
6521 !obj_buffer->buffer_store->buffer)
6522 return VA_STATUS_ERROR_INVALID_BUFFER;
6524 VAProcFilterParameterBufferBase *base = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
6526 if (base->type == VAProcFilterNoiseReduction) {
6527 VAProcFilterParameterBuffer *denoise = (VAProcFilterParameterBuffer *)base;
6529 } else if (base->type == VAProcFilterDeinterlacing) {
6530 VAProcFilterParameterBufferDeinterlacing *deint = (VAProcFilterParameterBufferDeinterlacing *)base;
6532 ASSERT_RET(deint->algorithm == VAProcDeinterlacingBob ||
6533 deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
6534 deint->algorithm == VAProcDeinterlacingMotionCompensated,
6535 VA_STATUS_ERROR_INVALID_PARAMETER);
6537 if (deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
6538 deint->algorithm == VAProcDeinterlacingMotionCompensated)
6539 pipeline_cap->num_forward_references++;
6540 } else if (base->type == VAProcFilterSkinToneEnhancement) {
6541 VAProcFilterParameterBuffer *stde = (VAProcFilterParameterBuffer *)base;
6546 return VA_STATUS_SUCCESS;
6549 extern struct hw_codec_info *i965_get_codec_info(int devid);
6552 i965_driver_data_init(VADriverContextP ctx)
6554 struct i965_driver_data *i965 = i965_driver_data(ctx);
6556 i965->codec_info = i965_get_codec_info(i965->intel.device_id);
6558 if (!i965->codec_info)
6561 if (object_heap_init(&i965->config_heap,
6562 sizeof(struct object_config),
6564 goto err_config_heap;
6565 if (object_heap_init(&i965->context_heap,
6566 sizeof(struct object_context),
6568 goto err_context_heap;
6570 if (object_heap_init(&i965->surface_heap,
6571 sizeof(struct object_surface),
6573 goto err_surface_heap;
6574 if (object_heap_init(&i965->buffer_heap,
6575 sizeof(struct object_buffer),
6577 goto err_buffer_heap;
6578 if (object_heap_init(&i965->image_heap,
6579 sizeof(struct object_image),
6581 goto err_image_heap;
6582 if (object_heap_init(&i965->subpic_heap,
6583 sizeof(struct object_subpic),
6585 goto err_subpic_heap;
6587 i965->batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
6588 i965->pp_batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
6589 _i965InitMutex(&i965->render_mutex);
6590 _i965InitMutex(&i965->pp_mutex);
6595 object_heap_destroy(&i965->image_heap);
6597 object_heap_destroy(&i965->buffer_heap);
6599 object_heap_destroy(&i965->surface_heap);
6601 object_heap_destroy(&i965->context_heap);
6603 object_heap_destroy(&i965->config_heap);
6610 i965_driver_data_terminate(VADriverContextP ctx)
6612 struct i965_driver_data *i965 = i965_driver_data(ctx);
6614 _i965DestroyMutex(&i965->pp_mutex);
6615 _i965DestroyMutex(&i965->render_mutex);
6618 intel_batchbuffer_free(i965->batch);
6621 intel_batchbuffer_free(i965->pp_batch);
6623 i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
6624 i965_destroy_heap(&i965->image_heap, i965_destroy_image);
6625 i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
6626 i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
6627 i965_destroy_heap(&i965->context_heap, i965_destroy_context);
6628 i965_destroy_heap(&i965->config_heap, i965_destroy_config);
6632 bool (*init)(VADriverContextP ctx);
6633 void (*terminate)(VADriverContextP ctx);
6635 } i965_sub_ops[] = {
6638 intel_driver_terminate,
6643 i965_driver_data_init,
6644 i965_driver_data_terminate,
6649 i965_display_attributes_init,
6650 i965_display_attributes_terminate,
6655 i965_post_processing_init,
6656 i965_post_processing_terminate,
6662 i965_render_terminate,
6666 #ifdef HAVE_VA_WAYLAND
6668 i965_output_wayland_init,
6669 i965_output_wayland_terminate,
6676 i965_output_dri_init,
6677 i965_output_dri_terminate,
6683 i965_gpe_table_init,
6684 i965_gpe_table_terminate,
6690 ensure_vendor_string(struct i965_driver_data *i965, const char *chipset)
6694 if (i965->va_vendor[0] != '\0')
6698 ret = snprintf(i965->va_vendor, sizeof(i965->va_vendor),
6699 "%s %s driver for %s - %d.%d.%d",
6700 INTEL_STR_DRIVER_VENDOR, INTEL_STR_DRIVER_NAME, chipset,
6701 INTEL_DRIVER_MAJOR_VERSION, INTEL_DRIVER_MINOR_VERSION,
6702 INTEL_DRIVER_MICRO_VERSION);
6703 if (ret < 0 || ret >= sizeof(i965->va_vendor))
6707 if (INTEL_DRIVER_PRE_VERSION > 0) {
6708 ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
6709 ".pre%d", INTEL_DRIVER_PRE_VERSION);
6710 if (ret < 0 || ret >= sizeof(i965->va_vendor))
6714 ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
6715 " (%s)", INTEL_DRIVER_GIT_VERSION);
6716 if (ret < 0 || ret >= sizeof(i965->va_vendor))
6723 i965->va_vendor[0] = '\0';
6724 ASSERT_RET(ret > 0 && len < sizeof(i965->va_vendor), false);
6728 /* Only when the option of "enable-wrapper" is passed, it is possible
6729 * to initialize/load the wrapper context of backend driver.
6730 * Otherwise it is not loaded.
6732 #if HAVE_HYBRID_CODEC
6735 i965_initialize_wrapper(VADriverContextP ctx, const char *driver_name)
6737 #define DRIVER_EXTENSION "_drv_video.so"
6739 struct i965_driver_data *i965 = i965_driver_data(ctx);
6741 VADriverContextP wrapper_pdrvctx;
6742 struct VADriverVTable *vtable;
6743 char *search_path, *driver_dir;
6745 char driver_path[256];
6746 void *handle = NULL;
6747 VAStatus va_status = VA_STATUS_SUCCESS;
6748 bool driver_loaded = false;
6750 if (HAS_VP9_DECODING(i965)) {
6751 i965->wrapper_pdrvctx = NULL;
6755 wrapper_pdrvctx = calloc(1, sizeof(*wrapper_pdrvctx));
6756 vtable = calloc(1, sizeof(*vtable));
6758 if (!wrapper_pdrvctx || !vtable) {
6759 fprintf(stderr, "Failed to allocate memory for wrapper \n");
6760 free(wrapper_pdrvctx);
6762 return VA_STATUS_ERROR_ALLOCATION_FAILED;
6765 /* use the same drm_state with CTX */
6766 wrapper_pdrvctx->drm_state = ctx->drm_state;
6767 wrapper_pdrvctx->display_type = ctx->display_type;
6768 wrapper_pdrvctx->vtable = vtable;
6770 search_path = VA_DRIVERS_PATH;
6771 search_path = strdup((const char *)search_path);
6773 driver_dir = strtok_r(search_path, ":", &saveptr);
6774 while (driver_dir && !driver_loaded) {
6775 memset(driver_path, 0, sizeof(driver_path));
6776 sprintf(driver_path, "%s/%s%s", driver_dir, driver_name, DRIVER_EXTENSION);
6778 handle = dlopen(driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
6780 fprintf(stderr, "failed to open %s\n", driver_path);
6781 driver_dir = strtok_r(NULL, ":", &saveptr);
6785 VADriverInit init_func = NULL;
6786 char init_func_s[256];
6789 static const struct {
6792 } compatible_versions[] = {
6793 { VA_MAJOR_VERSION, VA_MINOR_VERSION },
6802 for (i = 0; compatible_versions[i].major >= 0; i++) {
6803 snprintf(init_func_s, sizeof(init_func_s),
6804 "__vaDriverInit_%d_%d",
6805 compatible_versions[i].major,
6806 compatible_versions[i].minor);
6807 init_func = (VADriverInit)dlsym(handle, init_func_s);
6812 if (compatible_versions[i].major < 0) {
6814 fprintf(stderr, "%s has no function %s\n",
6815 driver_path, init_func_s);
6816 driver_dir = strtok_r(NULL, ":", &saveptr);
6821 va_status = (*init_func)(wrapper_pdrvctx);
6823 if (va_status != VA_STATUS_SUCCESS) {
6825 fprintf(stderr, "%s init failed\n", driver_path);
6826 driver_dir = strtok_r(NULL, ":", &saveptr);
6830 wrapper_pdrvctx->handle = handle;
6831 driver_loaded = true;
6837 if (driver_loaded) {
6838 i965->wrapper_pdrvctx = wrapper_pdrvctx;
6839 return VA_STATUS_SUCCESS;
6841 fprintf(stderr, "Failed to wrapper %s%s\n", driver_name, DRIVER_EXTENSION);
6843 free(wrapper_pdrvctx);
6844 return VA_STATUS_ERROR_OPERATION_FAILED;
6850 i965_Init(VADriverContextP ctx)
6852 struct i965_driver_data *i965 = i965_driver_data(ctx);
6854 const char *chipset;
6856 for (i = 0; i < ARRAY_ELEMS(i965_sub_ops); i++) {
6857 if ((i965_sub_ops[i].display_type == 0 ||
6858 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) &&
6859 !i965_sub_ops[i].init(ctx))
6863 if (i == ARRAY_ELEMS(i965_sub_ops)) {
6864 switch (i965->intel.device_id) {
6866 #define CHIPSET(id, family, dev, str) case id: chipset = str; break;
6867 #include "i965_pciids.h"
6869 chipset = "Unknown Intel Chipset";
6873 if (!ensure_vendor_string(i965, chipset))
6874 return VA_STATUS_ERROR_ALLOCATION_FAILED;
6876 i965->current_context_id = VA_INVALID_ID;
6878 if (i965->codec_info && i965->codec_info->preinit_hw_codec)
6879 i965->codec_info->preinit_hw_codec(ctx, i965->codec_info);
6881 #if HAVE_HYBRID_CODEC
6882 i965_initialize_wrapper(ctx, "hybrid");
6885 return VA_STATUS_SUCCESS;
6889 for (; i >= 0; i--) {
6890 if (i965_sub_ops[i].display_type == 0 ||
6891 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
6892 i965_sub_ops[i].terminate(ctx);
6896 return VA_STATUS_ERROR_UNKNOWN;
6901 i965_Terminate(VADriverContextP ctx)
6903 struct i965_driver_data *i965 = i965_driver_data(ctx);
6907 #if HAVE_HYBRID_CODEC
6908 if (i965->wrapper_pdrvctx) {
6909 VADriverContextP pdrvctx;
6910 pdrvctx = i965->wrapper_pdrvctx;
6911 if (pdrvctx->handle) {
6912 pdrvctx->vtable->vaTerminate(pdrvctx);
6913 dlclose(pdrvctx->handle);
6914 pdrvctx->handle = NULL;
6916 free(pdrvctx->vtable);
6918 i965->wrapper_pdrvctx = NULL;
6922 for (i = ARRAY_ELEMS(i965_sub_ops); i > 0; i--)
6923 if (i965_sub_ops[i - 1].display_type == 0 ||
6924 i965_sub_ops[i - 1].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
6925 i965_sub_ops[i - 1].terminate(ctx);
6929 ctx->pDriverData = NULL;
6932 return VA_STATUS_SUCCESS;
6936 VA_DRIVER_INIT_FUNC(VADriverContextP ctx);
6939 VA_DRIVER_INIT_FUNC( VADriverContextP ctx )
6941 struct VADriverVTable * const vtable = ctx->vtable;
6942 struct VADriverVTableVPP * const vtable_vpp = ctx->vtable_vpp;
6944 struct i965_driver_data *i965;
6945 VAStatus ret = VA_STATUS_ERROR_UNKNOWN;
6947 ctx->version_major = VA_MAJOR_VERSION;
6948 ctx->version_minor = VA_MINOR_VERSION;
6949 ctx->max_profiles = I965_MAX_PROFILES;
6950 ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
6951 ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
6952 ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
6953 ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
6954 ctx->max_display_attributes = 1 + ARRAY_ELEMS(i965_display_attributes);
6956 vtable->vaTerminate = i965_Terminate;
6957 vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
6958 vtable->vaQueryConfigProfiles = i965_QueryConfigProfiles;
6959 vtable->vaQueryConfigAttributes = i965_QueryConfigAttributes;
6960 vtable->vaCreateConfig = i965_CreateConfig;
6961 vtable->vaDestroyConfig = i965_DestroyConfig;
6962 vtable->vaGetConfigAttributes = i965_GetConfigAttributes;
6963 vtable->vaCreateSurfaces = i965_CreateSurfaces;
6964 vtable->vaDestroySurfaces = i965_DestroySurfaces;
6965 vtable->vaCreateContext = i965_CreateContext;
6966 vtable->vaDestroyContext = i965_DestroyContext;
6967 vtable->vaCreateBuffer = i965_CreateBuffer;
6968 vtable->vaBufferSetNumElements = i965_BufferSetNumElements;
6969 vtable->vaMapBuffer = i965_MapBuffer;
6970 vtable->vaUnmapBuffer = i965_UnmapBuffer;
6971 vtable->vaDestroyBuffer = i965_DestroyBuffer;
6972 vtable->vaBeginPicture = i965_BeginPicture;
6973 vtable->vaRenderPicture = i965_RenderPicture;
6974 vtable->vaEndPicture = i965_EndPicture;
6975 vtable->vaSyncSurface = i965_SyncSurface;
6976 vtable->vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
6977 vtable->vaPutSurface = i965_PutSurface;
6978 vtable->vaQueryImageFormats = i965_QueryImageFormats;
6979 vtable->vaCreateImage = i965_CreateImage;
6980 vtable->vaDeriveImage = i965_DeriveImage;
6981 vtable->vaDestroyImage = i965_DestroyImage;
6982 vtable->vaSetImagePalette = i965_SetImagePalette;
6983 vtable->vaGetImage = i965_GetImage;
6984 vtable->vaPutImage = i965_PutImage;
6985 vtable->vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
6986 vtable->vaCreateSubpicture = i965_CreateSubpicture;
6987 vtable->vaDestroySubpicture = i965_DestroySubpicture;
6988 vtable->vaSetSubpictureImage = i965_SetSubpictureImage;
6989 vtable->vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
6990 vtable->vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
6991 vtable->vaAssociateSubpicture = i965_AssociateSubpicture;
6992 vtable->vaDeassociateSubpicture = i965_DeassociateSubpicture;
6993 vtable->vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
6994 vtable->vaGetDisplayAttributes = i965_GetDisplayAttributes;
6995 vtable->vaSetDisplayAttributes = i965_SetDisplayAttributes;
6996 vtable->vaBufferInfo = i965_BufferInfo;
6997 vtable->vaLockSurface = i965_LockSurface;
6998 vtable->vaUnlockSurface = i965_UnlockSurface;
6999 vtable->vaGetSurfaceAttributes = i965_GetSurfaceAttributes;
7000 vtable->vaQuerySurfaceAttributes = i965_QuerySurfaceAttributes;
7001 vtable->vaCreateSurfaces2 = i965_CreateSurfaces2;
7004 vtable->vaAcquireBufferHandle = i965_AcquireBufferHandle;
7005 vtable->vaReleaseBufferHandle = i965_ReleaseBufferHandle;
7007 vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters;
7008 vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps;
7009 vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;
7011 i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
7014 ctx->pDriverData = NULL;
7016 return VA_STATUS_ERROR_ALLOCATION_FAILED;
7019 i965->wrapper_pdrvctx = NULL;
7020 ctx->pDriverData = (void *)i965;
7021 ret = i965_Init(ctx);
7023 if (ret == VA_STATUS_SUCCESS) {
7024 ctx->str_vendor = i965->va_vendor;
7027 ctx->pDriverData = NULL;