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 #define CONFIG_ID_OFFSET 0x01000000
52 #define CONTEXT_ID_OFFSET 0x02000000
53 #define SURFACE_ID_OFFSET 0x04000000
54 #define BUFFER_ID_OFFSET 0x08000000
55 #define IMAGE_ID_OFFSET 0x0a000000
56 #define SUBPIC_ID_OFFSET 0x10000000
58 #define HAS_MPEG2_DECODING(ctx) ((ctx)->codec_info->has_mpeg2_decoding && \
61 #define HAS_MPEG2_ENCODING(ctx) ((ctx)->codec_info->has_mpeg2_encoding && \
64 #define HAS_H264_DECODING(ctx) ((ctx)->codec_info->has_h264_decoding && \
67 #define HAS_H264_ENCODING(ctx) ((ctx)->codec_info->has_h264_encoding && \
70 #define HAS_VC1_DECODING(ctx) ((ctx)->codec_info->has_vc1_decoding && \
73 #define HAS_JPEG_DECODING(ctx) ((ctx)->codec_info->has_jpeg_decoding && \
76 #define HAS_JPEG_ENCODING(ctx) ((ctx)->codec_info->has_jpeg_encoding && \
79 #define HAS_VPP(ctx) ((ctx)->codec_info->has_vpp)
81 #define HAS_ACCELERATED_GETIMAGE(ctx) ((ctx)->codec_info->has_accelerated_getimage)
83 #define HAS_ACCELERATED_PUTIMAGE(ctx) ((ctx)->codec_info->has_accelerated_putimage)
85 #define HAS_TILED_SURFACE(ctx) ((ctx)->codec_info->has_tiled_surface)
87 #define HAS_VP8_DECODING(ctx) ((ctx)->codec_info->has_vp8_decoding && \
90 #define HAS_VP8_ENCODING(ctx) ((ctx)->codec_info->has_vp8_encoding && \
93 #define HAS_H264_MVC_DECODING(ctx) \
94 (HAS_H264_DECODING(ctx) && (ctx)->codec_info->h264_mvc_dec_profiles)
96 #define HAS_H264_MVC_DECODING_PROFILE(ctx, profile) \
97 (HAS_H264_MVC_DECODING(ctx) && \
98 ((ctx)->codec_info->h264_mvc_dec_profiles & (1U << profile)))
100 #define HAS_H264_MVC_ENCODING(ctx) ((ctx)->codec_info->has_h264_mvc_encoding && \
101 (ctx)->intel.has_bsd)
103 #define HAS_HEVC_DECODING(ctx) ((ctx)->codec_info->has_hevc_decoding && \
104 (ctx)->intel.has_bsd)
106 #define HAS_HEVC_ENCODING(ctx) ((ctx)->codec_info->has_hevc_encoding && \
107 (ctx)->intel.has_bsd)
109 #define HAS_VP9_DECODING(ctx) ((ctx)->codec_info->has_vp9_decoding && \
110 (ctx)->intel.has_bsd)
112 #define HAS_HEVC10_DECODING(ctx) ((ctx)->codec_info->has_hevc10_decoding && \
113 (ctx)->intel.has_bsd)
115 #define HAS_VPP_P010(ctx) ((ctx)->codec_info->has_vpp_p010 && \
116 (ctx)->intel.has_bsd)
118 static int get_sampling_from_fourcc(unsigned int fourcc);
120 /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */
121 #define IS_VA_X11(ctx) \
122 (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_X11)
124 /* Check whether we are rendering to Wayland */
125 #define IS_VA_WAYLAND(ctx) \
126 (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_WAYLAND)
129 #define I965_2BITS (I965_BIT << 1)
130 #define I965_4BITS (I965_BIT << 2)
131 #define I965_8BITS (I965_BIT << 3)
132 #define I965_16BITS (I965_BIT << 4)
133 #define I965_32BITS (I965_BIT << 5)
145 /* hfactor, vfactor, num_planes, bpp[], num_components, components[] */
146 #define I_NV12 2, 2, 2, {I965_8BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_8} }
147 #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} }
148 #define I_IYUV I_I420
149 #define I_IMC3 I_I420
150 #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} }
151 #define I_IMC1 I_YV12
153 #define I_P010 2, 2, 2, {I965_16BITS, I965_8BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_16} }
155 #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} }
156 #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} }
157 #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} }
158 #define I_YUY2 2, 1, 1, {I965_16BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_24} }
159 #define I_UYVY 2, 1, 1, {I965_16BITS}, 3, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_16} }
161 #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} }
163 #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} }
165 #define I_Y800 1, 1, 1, {I965_8BITS}, 1, { {PLANE_0, OFFSET_0} }
167 #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} }
168 #define I_RGBX 1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16} }
169 #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} }
170 #define I_BGRX 1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
172 #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} }
173 #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} }
175 #define I_IA88 1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8} }
176 #define I_AI88 1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
178 #define I_IA44 1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_4} }
179 #define I_AI44 1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_4}, {PLANE_0, OFFSET_0} }
184 #define I_SI (I_S | I_I)
186 #define DEF_FOUCC_INFO(FOURCC, FORMAT, SUB, FLAG) { VA_FOURCC_##FOURCC, I965_COLOR_##FORMAT, SUBSAMPLE_##SUB, FLAG, I_##FOURCC }
187 #define DEF_YUV(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, YUV, SUB, FLAG)
188 #define DEF_RGB(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, RGB, SUB, FLAG)
189 #define DEF_INDEX(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, INDEX, SUB, FLAG)
191 static const i965_fourcc_info i965_fourcc_infos[] = {
192 DEF_YUV(NV12, YUV420, I_SI),
193 DEF_YUV(I420, YUV420, I_SI),
194 DEF_YUV(IYUV, YUV420, I_S),
195 DEF_YUV(IMC3, YUV420, I_S),
196 DEF_YUV(YV12, YUV420, I_SI),
197 DEF_YUV(IMC1, YUV420, I_S),
199 DEF_YUV(P010, YUV420, I_SI),
201 DEF_YUV(422H, YUV422H, I_SI),
202 DEF_YUV(422V, YUV422V, I_S),
203 DEF_YUV(YV16, YUV422H, I_S),
204 DEF_YUV(YUY2, YUV422H, I_SI),
205 DEF_YUV(UYVY, YUV422H, I_SI),
207 DEF_YUV(444P, YUV444, I_S),
209 DEF_YUV(411P, YUV411, I_S),
211 DEF_YUV(Y800, YUV400, I_S),
213 DEF_RGB(RGBA, RGBX, I_SI),
214 DEF_RGB(RGBX, RGBX, I_SI),
215 DEF_RGB(BGRA, RGBX, I_SI),
216 DEF_RGB(BGRX, RGBX, I_SI),
218 DEF_RGB(ARGB, RGBX, I_I),
219 DEF_RGB(ABGR, RGBX, I_I),
221 DEF_INDEX(IA88, RGBX, I_I),
222 DEF_INDEX(AI88, RGBX, I_I),
224 DEF_INDEX(IA44, RGBX, I_I),
225 DEF_INDEX(AI44, RGBX, I_I)
228 const i965_fourcc_info *
229 get_fourcc_info(unsigned int fourcc)
233 for (i = 0; ARRAY_ELEMS(i965_fourcc_infos); i++) {
234 const i965_fourcc_info * const info = &i965_fourcc_infos[i];
236 if (info->fourcc == fourcc)
244 get_bpp_from_fourcc(unsigned int fourcc)
246 const i965_fourcc_info *info = get_fourcc_info(fourcc);
248 unsigned int bpp = 0;
253 for (i = 0; i < info->num_planes; i++)
260 I965_SURFACETYPE_RGBA = 1,
261 I965_SURFACETYPE_YUV,
262 I965_SURFACETYPE_INDEXED
265 /* List of supported display attributes */
266 static const VADisplayAttribute i965_display_attributes[] = {
268 VADisplayAttribBrightness,
269 -100, 100, DEFAULT_BRIGHTNESS,
270 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
274 VADisplayAttribContrast,
275 0, 100, DEFAULT_CONTRAST,
276 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
281 -180, 180, DEFAULT_HUE,
282 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
286 VADisplayAttribSaturation,
287 0, 100, DEFAULT_SATURATION,
288 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
292 VADisplayAttribRotation,
293 0, 3, VA_ROTATION_NONE,
294 VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE
298 /* List of supported image formats */
301 VAImageFormat va_format;
302 } i965_image_format_map_t;
304 static const i965_image_format_map_t
305 i965_image_formats_map[I965_MAX_IMAGE_FORMATS + 1] = {
306 { I965_SURFACETYPE_YUV,
307 { VA_FOURCC_YV12, VA_LSB_FIRST, 12, } },
308 { I965_SURFACETYPE_YUV,
309 { VA_FOURCC_I420, VA_LSB_FIRST, 12, } },
310 { I965_SURFACETYPE_YUV,
311 { VA_FOURCC_NV12, VA_LSB_FIRST, 12, } },
312 { I965_SURFACETYPE_YUV,
313 { VA_FOURCC_YUY2, VA_LSB_FIRST, 16, } },
314 { I965_SURFACETYPE_YUV,
315 { VA_FOURCC_UYVY, VA_LSB_FIRST, 16, } },
316 { I965_SURFACETYPE_YUV,
317 { VA_FOURCC_422H, VA_LSB_FIRST, 16, } },
318 { I965_SURFACETYPE_RGBA,
319 { VA_FOURCC_RGBX, VA_LSB_FIRST, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000 } },
320 { I965_SURFACETYPE_RGBA,
321 { VA_FOURCC_BGRX, VA_LSB_FIRST, 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff } },
322 { I965_SURFACETYPE_YUV,
323 { VA_FOURCC_P010, VA_LSB_FIRST, 24, } },
326 /* List of supported subpicture formats */
330 VAImageFormat va_format;
331 unsigned int va_flags;
332 } i965_subpic_format_map_t;
334 #define COMMON_SUBPICTURE_FLAGS \
335 (VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD| \
336 VA_SUBPICTURE_GLOBAL_ALPHA)
338 static const i965_subpic_format_map_t
339 i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
340 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
341 { VA_FOURCC_IA44, VA_MSB_FIRST, 8, },
342 COMMON_SUBPICTURE_FLAGS },
343 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
344 { VA_FOURCC_AI44, VA_MSB_FIRST, 8, },
345 COMMON_SUBPICTURE_FLAGS },
346 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P8A8_UNORM,
347 { VA_FOURCC_IA88, VA_MSB_FIRST, 16, },
348 COMMON_SUBPICTURE_FLAGS },
349 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A8P8_UNORM,
350 { VA_FOURCC_AI88, VA_MSB_FIRST, 16, },
351 COMMON_SUBPICTURE_FLAGS },
352 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_B8G8R8A8_UNORM,
353 { VA_FOURCC_BGRA, VA_LSB_FIRST, 32,
354 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
355 COMMON_SUBPICTURE_FLAGS },
356 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_R8G8B8A8_UNORM,
357 { VA_FOURCC_RGBA, VA_LSB_FIRST, 32,
358 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
359 COMMON_SUBPICTURE_FLAGS },
362 static const i965_subpic_format_map_t *
363 get_subpic_format(const VAImageFormat *va_format)
366 for (i = 0; i965_subpic_formats_map[i].type != 0; i++) {
367 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
368 if (m->va_format.fourcc == va_format->fourcc &&
369 (m->type == I965_SURFACETYPE_RGBA ?
370 (m->va_format.byte_order == va_format->byte_order &&
371 m->va_format.red_mask == va_format->red_mask &&
372 m->va_format.green_mask == va_format->green_mask &&
373 m->va_format.blue_mask == va_format->blue_mask &&
374 m->va_format.alpha_mask == va_format->alpha_mask) : 1))
380 /* Checks whether the surface is in busy state */
382 is_surface_busy(struct i965_driver_data *i965,
383 struct object_surface *obj_surface)
385 assert(obj_surface != NULL);
387 if (obj_surface->locked_image_id != VA_INVALID_ID)
389 if (obj_surface->derived_image_id != VA_INVALID_ID)
394 /* Checks whether the image is in busy state */
396 is_image_busy(struct i965_driver_data *i965, struct object_image *obj_image, VASurfaceID surface)
398 struct object_buffer *obj_buffer;
400 assert(obj_image != NULL);
402 if (obj_image->derived_surface != VA_INVALID_ID &&
403 obj_image->derived_surface == surface)
406 obj_buffer = BUFFER(obj_image->image.buf);
407 if (obj_buffer && obj_buffer->export_refcount > 0)
412 #define I965_PACKED_HEADER_BASE 0
413 #define I965_SEQ_PACKED_HEADER_BASE 0
414 #define I965_SEQ_PACKED_HEADER_END 2
415 #define I965_PIC_PACKED_HEADER_BASE 2
416 #define I965_PACKED_MISC_HEADER_BASE 4
419 va_enc_packed_type_to_idx(int packed_type)
423 if (packed_type & VAEncPackedHeaderMiscMask) {
424 idx = I965_PACKED_MISC_HEADER_BASE;
425 packed_type = (~VAEncPackedHeaderMiscMask & packed_type);
426 ASSERT_RET(packed_type > 0, 0);
427 idx += (packed_type - 1);
429 idx = I965_PACKED_HEADER_BASE;
431 switch (packed_type) {
432 case VAEncPackedHeaderSequence:
433 idx = I965_SEQ_PACKED_HEADER_BASE + 0;
436 case VAEncPackedHeaderPicture:
437 idx = I965_PIC_PACKED_HEADER_BASE + 0;
440 case VAEncPackedHeaderSlice:
441 idx = I965_PIC_PACKED_HEADER_BASE + 1;
445 /* Should not get here */
451 ASSERT_RET(idx < 5, 0);
455 #define CALL_VTABLE(vawr, status, param) status = (vawr->vtable->param)
458 i965_surface_wrapper(VADriverContextP ctx, VASurfaceID surface)
460 struct i965_driver_data *i965 = i965_driver_data(ctx);
461 struct object_surface *obj_surface = SURFACE(surface);
462 VAStatus va_status = VA_STATUS_SUCCESS;
465 return VA_STATUS_ERROR_INVALID_SURFACE;
468 if (obj_surface->wrapper_surface != VA_INVALID_ID) {
469 /* the wrapped surface already exists. just return it */
473 if (obj_surface->fourcc == 0)
474 i965_check_alloc_surface_bo(ctx, obj_surface,
475 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
478 * TBD: Support more surface formats.
479 * Currently only NV12 is support as NV12 is used by decoding.
481 if (obj_surface->fourcc != VA_FOURCC_NV12 )
482 return VA_STATUS_ERROR_INVALID_PARAMETER;
484 if ((i965->wrapper_pdrvctx == NULL) ||
485 (obj_surface->bo == NULL))
486 return VA_STATUS_ERROR_INVALID_PARAMETER;
490 VASurfaceAttrib attrib_list[2];
491 VASurfaceAttribExternalBuffers buffer_descriptor;
492 VAGenericID wrapper_surface;
494 if (drm_intel_bo_gem_export_to_prime(obj_surface->bo, &fd_handle) != 0)
495 return VA_STATUS_ERROR_OPERATION_FAILED;
497 obj_surface->exported_primefd = fd_handle;
499 memset(&attrib_list, 0, sizeof(attrib_list));
500 memset(&buffer_descriptor, 0, sizeof(buffer_descriptor));
502 attrib_list[0].type = VASurfaceAttribExternalBufferDescriptor;
503 attrib_list[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
504 attrib_list[0].value.value.p = &buffer_descriptor;
505 attrib_list[0].value.type = VAGenericValueTypePointer;
507 attrib_list[1].type = VASurfaceAttribMemoryType;
508 attrib_list[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
509 attrib_list[1].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
510 attrib_list[1].value.type = VAGenericValueTypeInteger;
512 buffer_descriptor.num_buffers = 1;
513 buffer_descriptor.num_planes = 2;
514 buffer_descriptor.width = obj_surface->orig_width;
515 buffer_descriptor.height = obj_surface->orig_height;
516 buffer_descriptor.pixel_format = obj_surface->fourcc;
517 buffer_descriptor.data_size = obj_surface->size;
518 buffer_descriptor.pitches[0] = obj_surface->width;
519 buffer_descriptor.pitches[1] = obj_surface->cb_cr_pitch;
520 buffer_descriptor.offsets[0] = 0;
521 buffer_descriptor.offsets[1] = obj_surface->width * obj_surface->height;
522 buffer_descriptor.buffers = (void *)&fd_handle;
524 CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
525 vaCreateSurfaces2(i965->wrapper_pdrvctx,
527 obj_surface->orig_width,
528 obj_surface->orig_height,
532 if (va_status == VA_STATUS_SUCCESS) {
533 obj_surface->wrapper_surface = wrapper_surface;
535 /* This needs to be checked */
536 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
544 i965_QueryConfigProfiles(VADriverContextP ctx,
545 VAProfile *profile_list, /* out */
546 int *num_profiles) /* out */
548 struct i965_driver_data * const i965 = i965_driver_data(ctx);
551 if (HAS_MPEG2_DECODING(i965) ||
552 HAS_MPEG2_ENCODING(i965)) {
553 profile_list[i++] = VAProfileMPEG2Simple;
554 profile_list[i++] = VAProfileMPEG2Main;
557 if (HAS_H264_DECODING(i965) ||
558 HAS_H264_ENCODING(i965)) {
559 profile_list[i++] = VAProfileH264ConstrainedBaseline;
560 profile_list[i++] = VAProfileH264Main;
561 profile_list[i++] = VAProfileH264High;
563 if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264MultiviewHigh))
564 profile_list[i++] = VAProfileH264MultiviewHigh;
565 if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264StereoHigh))
566 profile_list[i++] = VAProfileH264StereoHigh;
568 if (HAS_VC1_DECODING(i965)) {
569 profile_list[i++] = VAProfileVC1Simple;
570 profile_list[i++] = VAProfileVC1Main;
571 profile_list[i++] = VAProfileVC1Advanced;
575 profile_list[i++] = VAProfileNone;
578 if (HAS_JPEG_DECODING(i965) ||
579 HAS_JPEG_ENCODING(i965)) {
580 profile_list[i++] = VAProfileJPEGBaseline;
583 if (HAS_VP8_DECODING(i965) ||
584 HAS_VP8_ENCODING(i965)) {
585 profile_list[i++] = VAProfileVP8Version0_3;
588 if (HAS_H264_MVC_ENCODING(i965)) {
589 profile_list[i++] = VAProfileH264MultiviewHigh;
590 profile_list[i++] = VAProfileH264StereoHigh;
593 if (HAS_HEVC_DECODING(i965)||
594 HAS_HEVC_ENCODING(i965)) {
595 profile_list[i++] = VAProfileHEVCMain;
598 if (HAS_HEVC10_DECODING(i965)) {
599 profile_list[i++] = VAProfileHEVCMain10;
602 if(HAS_VP9_DECODING(i965)) {
603 profile_list[i++] = VAProfileVP9Profile0;
606 if (i965->wrapper_pdrvctx) {
607 VAProfile wrapper_list[4];
609 VADriverContextP pdrvctx;
612 pdrvctx = i965->wrapper_pdrvctx;
613 CALL_VTABLE(pdrvctx, va_status,
614 vaQueryConfigProfiles(pdrvctx,
615 wrapper_list, &wrapper_num));
617 if (va_status == VA_STATUS_SUCCESS) {
619 for (j = 0; j < wrapper_num; j++)
620 if (wrapper_list[j] != VAProfileNone)
621 profile_list[i++] = wrapper_list[j];
625 /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
626 ASSERT_RET(i <= I965_MAX_PROFILES, VA_STATUS_ERROR_OPERATION_FAILED);
629 return VA_STATUS_SUCCESS;
633 i965_QueryConfigEntrypoints(VADriverContextP ctx,
635 VAEntrypoint *entrypoint_list, /* out */
636 int *num_entrypoints) /* out */
638 struct i965_driver_data * const i965 = i965_driver_data(ctx);
642 case VAProfileMPEG2Simple:
643 case VAProfileMPEG2Main:
644 if (HAS_MPEG2_DECODING(i965))
645 entrypoint_list[n++] = VAEntrypointVLD;
647 if (HAS_MPEG2_ENCODING(i965))
648 entrypoint_list[n++] = VAEntrypointEncSlice;
652 case VAProfileH264ConstrainedBaseline:
653 case VAProfileH264Main:
654 case VAProfileH264High:
655 if (HAS_H264_DECODING(i965))
656 entrypoint_list[n++] = VAEntrypointVLD;
658 if (HAS_H264_ENCODING(i965))
659 entrypoint_list[n++] = VAEntrypointEncSlice;
662 case VAProfileH264MultiviewHigh:
663 case VAProfileH264StereoHigh:
664 if (HAS_H264_MVC_DECODING_PROFILE(i965, profile))
665 entrypoint_list[n++] = VAEntrypointVLD;
667 if (HAS_H264_MVC_ENCODING(i965))
668 entrypoint_list[n++] = VAEntrypointEncSlice;
671 case VAProfileVC1Simple:
672 case VAProfileVC1Main:
673 case VAProfileVC1Advanced:
674 if (HAS_VC1_DECODING(i965))
675 entrypoint_list[n++] = VAEntrypointVLD;
680 entrypoint_list[n++] = VAEntrypointVideoProc;
683 case VAProfileJPEGBaseline:
684 if (HAS_JPEG_DECODING(i965))
685 entrypoint_list[n++] = VAEntrypointVLD;
687 if (HAS_JPEG_ENCODING(i965))
688 entrypoint_list[n++] = VAEntrypointEncPicture;
691 case VAProfileVP8Version0_3:
692 if (HAS_VP8_DECODING(i965))
693 entrypoint_list[n++] = VAEntrypointVLD;
695 if (HAS_VP8_ENCODING(i965))
696 entrypoint_list[n++] = VAEntrypointEncSlice;
700 case VAProfileHEVCMain:
701 if (HAS_HEVC_DECODING(i965))
702 entrypoint_list[n++] = VAEntrypointVLD;
704 if (HAS_HEVC_ENCODING(i965))
705 entrypoint_list[n++] = VAEntrypointEncSlice;
709 case VAProfileHEVCMain10:
710 if (HAS_HEVC10_DECODING(i965))
711 entrypoint_list[n++] = VAEntrypointVLD;
715 case VAProfileVP9Profile0:
716 if(HAS_VP9_DECODING(i965))
717 entrypoint_list[n++] = VAEntrypointVLD;
719 if (i965->wrapper_pdrvctx) {
720 VAStatus va_status = VA_STATUS_SUCCESS;
721 VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
723 CALL_VTABLE(pdrvctx, va_status,
724 vaQueryConfigEntrypoints(pdrvctx, profile,
736 /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
737 ASSERT_RET(n <= I965_MAX_ENTRYPOINTS, VA_STATUS_ERROR_OPERATION_FAILED);
738 *num_entrypoints = n;
739 return n > 0 ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
743 i965_validate_config(VADriverContextP ctx, VAProfile profile,
744 VAEntrypoint entrypoint)
746 struct i965_driver_data * const i965 = i965_driver_data(ctx);
749 /* Validate profile & entrypoint */
751 case VAProfileMPEG2Simple:
752 case VAProfileMPEG2Main:
753 if ((HAS_MPEG2_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
754 (HAS_MPEG2_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
755 va_status = VA_STATUS_SUCCESS;
757 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
761 case VAProfileH264ConstrainedBaseline:
762 case VAProfileH264Main:
763 case VAProfileH264High:
764 if ((HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
765 (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
766 va_status = VA_STATUS_SUCCESS;
768 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
772 case VAProfileVC1Simple:
773 case VAProfileVC1Main:
774 case VAProfileVC1Advanced:
775 if (HAS_VC1_DECODING(i965) && entrypoint == VAEntrypointVLD) {
776 va_status = VA_STATUS_SUCCESS;
778 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
783 if (HAS_VPP(i965) && VAEntrypointVideoProc == entrypoint) {
784 va_status = VA_STATUS_SUCCESS;
786 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
790 case VAProfileJPEGBaseline:
791 if ((HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
792 (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)) {
793 va_status = VA_STATUS_SUCCESS;
795 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
799 case VAProfileVP8Version0_3:
800 if ((HAS_VP8_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
801 (HAS_VP8_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
802 va_status = VA_STATUS_SUCCESS;
804 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
808 case VAProfileH264MultiviewHigh:
809 case VAProfileH264StereoHigh:
810 if ((HAS_H264_MVC_DECODING_PROFILE(i965, profile) &&
811 entrypoint == VAEntrypointVLD) ||
812 (HAS_H264_MVC_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
813 va_status = VA_STATUS_SUCCESS;
815 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
820 case VAProfileHEVCMain:
821 if ((HAS_HEVC_DECODING(i965) && (entrypoint == VAEntrypointVLD))||
822 (HAS_HEVC_ENCODING(i965) && (entrypoint == VAEntrypointEncSlice)))
823 va_status = VA_STATUS_SUCCESS;
825 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
829 case VAProfileHEVCMain10:
830 if (HAS_HEVC10_DECODING(i965) && (entrypoint == VAEntrypointVLD))
831 va_status = VA_STATUS_SUCCESS;
833 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
837 case VAProfileVP9Profile0:
838 if ((HAS_VP9_DECODING(i965)) && (entrypoint == VAEntrypointVLD))
839 va_status = VA_STATUS_SUCCESS;
840 else if (i965->wrapper_pdrvctx)
841 va_status = VA_STATUS_SUCCESS;
843 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
847 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
854 i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
855 VAEntrypoint entrypoint)
857 struct i965_driver_data * const i965 = i965_driver_data(ctx);
858 uint32_t chroma_formats = VA_RT_FORMAT_YUV420;
861 case VAProfileH264ConstrainedBaseline:
862 case VAProfileH264Main:
863 case VAProfileH264High:
864 if (HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD)
865 chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
868 case VAProfileH264MultiviewHigh:
869 case VAProfileH264StereoHigh:
870 if (HAS_H264_MVC_DECODING(i965) && entrypoint == VAEntrypointVLD)
871 chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
874 case VAProfileJPEGBaseline:
875 if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD)
876 chroma_formats |= i965->codec_info->jpeg_dec_chroma_formats;
877 if (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)
878 chroma_formats |= i965->codec_info->jpeg_enc_chroma_formats;
881 case VAProfileHEVCMain10:
882 if (HAS_HEVC10_DECODING(i965) && entrypoint == VAEntrypointVLD)
883 chroma_formats |= i965->codec_info->hevc_dec_chroma_formats;
887 if(HAS_VPP_P010(i965))
888 chroma_formats |= VA_RT_FORMAT_YUV420_10BPP;
894 return chroma_formats;
898 i965_GetConfigAttributes(VADriverContextP ctx,
900 VAEntrypoint entrypoint,
901 VAConfigAttrib *attrib_list, /* in/out */
907 va_status = i965_validate_config(ctx, profile, entrypoint);
908 if (va_status != VA_STATUS_SUCCESS)
911 /* Other attributes don't seem to be defined */
912 /* What to do if we don't know the attribute? */
913 for (i = 0; i < num_attribs; i++) {
914 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
915 switch (attrib_list[i].type) {
916 case VAConfigAttribRTFormat:
917 attrib_list[i].value = i965_get_default_chroma_formats(ctx,
918 profile, entrypoint);
921 case VAConfigAttribRateControl:
922 if (entrypoint == VAEntrypointEncSlice) {
923 attrib_list[i].value = VA_RC_CQP;
925 if (profile != VAProfileMPEG2Main &&
926 profile != VAProfileMPEG2Simple)
927 attrib_list[i].value |= VA_RC_CBR;
932 case VAConfigAttribEncPackedHeaders:
933 if (entrypoint == VAEntrypointEncSlice) {
934 attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
935 if (profile == VAProfileH264ConstrainedBaseline ||
936 profile == VAProfileH264Main ||
937 profile == VAProfileH264High ||
938 profile == VAProfileH264StereoHigh ||
939 profile == VAProfileH264MultiviewHigh ||
940 profile == VAProfileHEVCMain) {
941 attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA |
942 VA_ENC_PACKED_HEADER_SLICE);
946 else if (entrypoint == VAEntrypointEncPicture) {
947 if (profile == VAProfileJPEGBaseline)
948 attrib_list[i].value = VA_ENC_PACKED_HEADER_RAW_DATA;
952 case VAConfigAttribEncMaxRefFrames:
953 if (entrypoint == VAEntrypointEncSlice) {
954 attrib_list[i].value = (1 << 16) | (1 << 0);
959 case VAConfigAttribEncQualityRange:
960 if (entrypoint == VAEntrypointEncSlice) {
961 attrib_list[i].value = 1;
962 if (profile == VAProfileH264ConstrainedBaseline ||
963 profile == VAProfileH264Main ||
964 profile == VAProfileH264High )
965 attrib_list[i].value = ENCODER_QUALITY_RANGE;
970 case VAConfigAttribEncJPEG:
971 if( entrypoint == VAEntrypointEncPicture) {
972 VAConfigAttribValEncJPEG *configVal = (VAConfigAttribValEncJPEG*)&(attrib_list[i].value);
973 (configVal->bits).arithmatic_coding_mode = 0; // Huffman coding is used
974 (configVal->bits).progressive_dct_mode = 0; // Only Sequential DCT is supported
975 (configVal->bits).non_interleaved_mode = 1; // Support both interleaved and non-interleaved
976 (configVal->bits).differential_mode = 0; // Baseline DCT is non-differential
977 (configVal->bits).max_num_components = 3; // Only 3 components supported
978 (configVal->bits).max_num_scans = 1; // Only 1 scan per frame
979 (configVal->bits).max_num_huffman_tables = 3; // Max 3 huffman tables
980 (configVal->bits).max_num_quantization_tables = 3; // Max 3 quantization tables
984 case VAConfigAttribDecSliceMode:
985 attrib_list[i].value = VA_DEC_SLICE_MODE_NORMAL;
990 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
995 return VA_STATUS_SUCCESS;
999 i965_destroy_config(struct object_heap *heap, struct object_base *obj)
1001 object_heap_free(heap, obj);
1004 static VAConfigAttrib *
1005 i965_lookup_config_attribute(struct object_config *obj_config,
1006 VAConfigAttribType type)
1010 for (i = 0; i < obj_config->num_attribs; i++) {
1011 VAConfigAttrib * const attrib = &obj_config->attrib_list[i];
1012 if (attrib->type == type)
1019 i965_append_config_attribute(struct object_config *obj_config,
1020 const VAConfigAttrib *new_attrib)
1022 VAConfigAttrib *attrib;
1024 if (obj_config->num_attribs >= I965_MAX_CONFIG_ATTRIBUTES)
1025 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1027 attrib = &obj_config->attrib_list[obj_config->num_attribs++];
1028 attrib->type = new_attrib->type;
1029 attrib->value = new_attrib->value;
1030 return VA_STATUS_SUCCESS;
1034 i965_ensure_config_attribute(struct object_config *obj_config,
1035 const VAConfigAttrib *new_attrib)
1037 VAConfigAttrib *attrib;
1039 /* Check for existing attributes */
1040 attrib = i965_lookup_config_attribute(obj_config, new_attrib->type);
1042 /* Update existing attribute */
1043 attrib->value = new_attrib->value;
1044 return VA_STATUS_SUCCESS;
1046 return i965_append_config_attribute(obj_config, new_attrib);
1050 i965_CreateConfig(VADriverContextP ctx,
1052 VAEntrypoint entrypoint,
1053 VAConfigAttrib *attrib_list,
1055 VAConfigID *config_id) /* out */
1057 struct i965_driver_data * const i965 = i965_driver_data(ctx);
1058 struct object_config *obj_config;
1063 vaStatus = i965_validate_config(ctx, profile, entrypoint);
1065 if (VA_STATUS_SUCCESS != vaStatus) {
1069 configID = NEW_CONFIG_ID();
1070 obj_config = CONFIG(configID);
1072 if (NULL == obj_config) {
1073 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1077 obj_config->profile = profile;
1078 obj_config->entrypoint = entrypoint;
1079 obj_config->num_attribs = 0;
1080 obj_config->wrapper_config = VA_INVALID_ID;
1082 for (i = 0; i < num_attribs; i++) {
1083 vaStatus = i965_ensure_config_attribute(obj_config, &attrib_list[i]);
1084 if (vaStatus != VA_STATUS_SUCCESS)
1088 if (vaStatus == VA_STATUS_SUCCESS) {
1089 VAConfigAttrib attrib, *attrib_found;
1090 attrib.type = VAConfigAttribRTFormat;
1091 attrib.value = i965_get_default_chroma_formats(ctx, profile, entrypoint);
1092 attrib_found = i965_lookup_config_attribute(obj_config, attrib.type);
1093 if (!attrib_found || !attrib_found->value)
1094 vaStatus = i965_append_config_attribute(obj_config, &attrib);
1095 else if (!(attrib_found->value & attrib.value))
1096 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
1099 if ((vaStatus == VA_STATUS_SUCCESS) &&
1100 (profile == VAProfileVP9Profile0)) {
1102 if (i965->wrapper_pdrvctx) {
1103 VAGenericID wrapper_config;
1105 CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
1106 vaCreateConfig(i965->wrapper_pdrvctx, profile,
1107 entrypoint, attrib_list,
1108 num_attribs, &wrapper_config));
1110 if (vaStatus == VA_STATUS_SUCCESS)
1111 obj_config->wrapper_config = wrapper_config;
1115 /* Error recovery */
1116 if (VA_STATUS_SUCCESS != vaStatus) {
1117 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
1119 *config_id = configID;
1126 i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
1128 struct i965_driver_data *i965 = i965_driver_data(ctx);
1129 struct object_config *obj_config = CONFIG(config_id);
1132 if (NULL == obj_config) {
1133 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
1137 if ((obj_config->wrapper_config != VA_INVALID_ID) &&
1138 i965->wrapper_pdrvctx) {
1139 CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
1140 vaDestroyConfig(i965->wrapper_pdrvctx,
1141 obj_config->wrapper_config));
1142 obj_config->wrapper_config = VA_INVALID_ID;
1145 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
1146 return VA_STATUS_SUCCESS;
1149 VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
1150 VAConfigID config_id,
1151 VAProfile *profile, /* out */
1152 VAEntrypoint *entrypoint, /* out */
1153 VAConfigAttrib *attrib_list, /* out */
1154 int *num_attribs) /* out */
1156 struct i965_driver_data *i965 = i965_driver_data(ctx);
1157 struct object_config *obj_config = CONFIG(config_id);
1158 VAStatus vaStatus = VA_STATUS_SUCCESS;
1161 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
1162 *profile = obj_config->profile;
1163 *entrypoint = obj_config->entrypoint;
1164 *num_attribs = obj_config->num_attribs;
1166 for(i = 0; i < obj_config->num_attribs; i++) {
1167 attrib_list[i] = obj_config->attrib_list[i];
1174 i965_destroy_surface_storage(struct object_surface *obj_surface)
1179 dri_bo_unreference(obj_surface->bo);
1180 obj_surface->bo = NULL;
1182 if (obj_surface->free_private_data != NULL) {
1183 obj_surface->free_private_data(&obj_surface->private_data);
1184 obj_surface->private_data = NULL;
1189 i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
1191 struct object_surface *obj_surface = (struct object_surface *)obj;
1193 i965_destroy_surface_storage(obj_surface);
1194 object_heap_free(heap, obj);
1198 i965_surface_native_memory(VADriverContextP ctx,
1199 struct object_surface *obj_surface,
1201 int expected_fourcc)
1203 struct i965_driver_data *i965 = i965_driver_data(ctx);
1204 int tiling = HAS_TILED_SURFACE(i965);
1206 if (!expected_fourcc)
1207 return VA_STATUS_SUCCESS;
1209 // todo, should we disable tiling for 422 format?
1210 if (expected_fourcc == VA_FOURCC_I420 ||
1211 expected_fourcc == VA_FOURCC_IYUV ||
1212 expected_fourcc == VA_FOURCC_YV12 ||
1213 expected_fourcc == VA_FOURCC_YV16)
1216 return i965_check_alloc_surface_bo(ctx, obj_surface, tiling, expected_fourcc, get_sampling_from_fourcc(expected_fourcc));
1220 i965_suface_external_memory(VADriverContextP ctx,
1221 struct object_surface *obj_surface,
1222 int external_memory_type,
1223 VASurfaceAttribExternalBuffers *memory_attibute,
1226 struct i965_driver_data *i965 = i965_driver_data(ctx);
1228 if (!memory_attibute ||
1229 !memory_attibute->buffers ||
1230 index > memory_attibute->num_buffers)
1231 return VA_STATUS_ERROR_INVALID_PARAMETER;
1233 ASSERT_RET(obj_surface->orig_width == memory_attibute->width, VA_STATUS_ERROR_INVALID_PARAMETER);
1234 ASSERT_RET(obj_surface->orig_height == memory_attibute->height, VA_STATUS_ERROR_INVALID_PARAMETER);
1235 ASSERT_RET(memory_attibute->num_planes >= 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1237 obj_surface->fourcc = memory_attibute->pixel_format;
1238 obj_surface->width = memory_attibute->pitches[0];
1239 obj_surface->size = memory_attibute->data_size;
1241 if (memory_attibute->num_planes == 1)
1242 obj_surface->height = memory_attibute->data_size / obj_surface->width;
1244 obj_surface->height = memory_attibute->offsets[1] / obj_surface->width;
1246 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
1247 obj_surface->x_cr_offset = 0;
1249 switch (obj_surface->fourcc) {
1250 case VA_FOURCC_NV12:
1251 case VA_FOURCC_P010:
1252 ASSERT_RET(memory_attibute->num_planes == 2, VA_STATUS_ERROR_INVALID_PARAMETER);
1253 ASSERT_RET(memory_attibute->pitches[0] == memory_attibute->pitches[1], VA_STATUS_ERROR_INVALID_PARAMETER);
1255 obj_surface->subsampling = SUBSAMPLE_YUV420;
1256 obj_surface->y_cb_offset = obj_surface->height;
1257 obj_surface->y_cr_offset = obj_surface->height;
1258 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1259 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1260 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1264 case VA_FOURCC_YV12:
1265 case VA_FOURCC_IMC1:
1266 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1267 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1269 obj_surface->subsampling = SUBSAMPLE_YUV420;
1270 obj_surface->y_cr_offset = obj_surface->height;
1271 obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
1272 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1273 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1274 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1278 case VA_FOURCC_I420:
1279 case VA_FOURCC_IYUV:
1280 case VA_FOURCC_IMC3:
1281 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1282 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1284 obj_surface->subsampling = SUBSAMPLE_YUV420;
1285 obj_surface->y_cb_offset = obj_surface->height;
1286 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1287 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1288 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1289 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1293 case VA_FOURCC_YUY2:
1294 case VA_FOURCC_UYVY:
1295 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1297 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1298 obj_surface->y_cb_offset = 0;
1299 obj_surface->y_cr_offset = 0;
1300 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1301 obj_surface->cb_cr_height = obj_surface->orig_height;
1302 obj_surface->cb_cr_pitch = memory_attibute->pitches[0];
1306 case VA_FOURCC_RGBA:
1307 case VA_FOURCC_RGBX:
1308 case VA_FOURCC_BGRA:
1309 case VA_FOURCC_BGRX:
1310 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1312 obj_surface->subsampling = SUBSAMPLE_RGBX;
1313 obj_surface->y_cb_offset = 0;
1314 obj_surface->y_cr_offset = 0;
1315 obj_surface->cb_cr_width = 0;
1316 obj_surface->cb_cr_height = 0;
1317 obj_surface->cb_cr_pitch = 0;
1321 case VA_FOURCC_Y800: /* monochrome surface */
1322 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
1324 obj_surface->subsampling = SUBSAMPLE_YUV400;
1325 obj_surface->y_cb_offset = 0;
1326 obj_surface->y_cr_offset = 0;
1327 obj_surface->cb_cr_width = 0;
1328 obj_surface->cb_cr_height = 0;
1329 obj_surface->cb_cr_pitch = 0;
1333 case VA_FOURCC_411P:
1334 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1335 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1337 obj_surface->subsampling = SUBSAMPLE_YUV411;
1338 obj_surface->y_cb_offset = 0;
1339 obj_surface->y_cr_offset = 0;
1340 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
1341 obj_surface->cb_cr_height = obj_surface->orig_height;
1342 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1346 case VA_FOURCC_422H:
1347 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1348 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1350 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1351 obj_surface->y_cb_offset = obj_surface->height;
1352 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1353 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1354 obj_surface->cb_cr_height = obj_surface->orig_height;
1355 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1359 case VA_FOURCC_YV16:
1360 assert(memory_attibute->num_planes == 3);
1361 assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
1363 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1364 obj_surface->y_cr_offset = memory_attibute->offsets[1] / obj_surface->width;
1365 obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
1366 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1367 obj_surface->cb_cr_height = obj_surface->orig_height;
1368 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1372 case VA_FOURCC_422V:
1373 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1374 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1376 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1377 obj_surface->y_cb_offset = obj_surface->height;
1378 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1379 obj_surface->cb_cr_width = obj_surface->orig_width;
1380 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1381 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1385 case VA_FOURCC_444P:
1386 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1387 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1389 obj_surface->subsampling = SUBSAMPLE_YUV444;
1390 obj_surface->y_cb_offset = obj_surface->height;
1391 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1392 obj_surface->cb_cr_width = obj_surface->orig_width;
1393 obj_surface->cb_cr_height = obj_surface->orig_height;
1394 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1400 return VA_STATUS_ERROR_INVALID_PARAMETER;
1403 if (external_memory_type == I965_SURFACE_MEM_GEM_FLINK)
1404 obj_surface->bo = drm_intel_bo_gem_create_from_name(i965->intel.bufmgr,
1405 "gem flinked vaapi surface",
1406 memory_attibute->buffers[index]);
1407 else if (external_memory_type == I965_SURFACE_MEM_DRM_PRIME)
1408 obj_surface->bo = drm_intel_bo_gem_create_from_prime(i965->intel.bufmgr,
1409 memory_attibute->buffers[index],
1412 if (!obj_surface->bo)
1413 return VA_STATUS_ERROR_INVALID_PARAMETER;
1415 return VA_STATUS_SUCCESS;
1418 /* byte-per-pixel of the first plane */
1420 bpp_1stplane_by_fourcc(unsigned int fourcc)
1422 const i965_fourcc_info *info = get_fourcc_info(fourcc);
1424 if (info && (info->flag & I_S))
1425 return info->bpp[0] / 8;
1431 i965_CreateSurfaces2(
1432 VADriverContextP ctx,
1433 unsigned int format,
1435 unsigned int height,
1436 VASurfaceID *surfaces,
1437 unsigned int num_surfaces,
1438 VASurfaceAttrib *attrib_list,
1439 unsigned int num_attribs
1442 struct i965_driver_data *i965 = i965_driver_data(ctx);
1444 VAStatus vaStatus = VA_STATUS_SUCCESS;
1445 int expected_fourcc = 0;
1446 int memory_type = I965_SURFACE_MEM_NATIVE; /* native */
1447 VASurfaceAttribExternalBuffers *memory_attibute = NULL;
1449 for (i = 0; i < num_attribs && attrib_list; i++) {
1450 if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
1451 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
1452 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
1453 expected_fourcc = attrib_list[i].value.value.i;
1456 if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&
1457 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
1459 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
1461 if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
1462 memory_type = I965_SURFACE_MEM_GEM_FLINK; /* flinked GEM handle */
1463 else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)
1464 memory_type = I965_SURFACE_MEM_DRM_PRIME; /* drm prime fd */
1465 else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_VA)
1466 memory_type = I965_SURFACE_MEM_NATIVE; /* va native memory, to be allocated */
1469 if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&
1470 (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {
1471 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypePointer, VA_STATUS_ERROR_INVALID_PARAMETER);
1472 memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;
1476 /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used
1477 * for post-processing (including color conversion) */
1478 if (VA_RT_FORMAT_YUV420 != format &&
1479 VA_RT_FORMAT_YUV420_10BPP != format &&
1480 VA_RT_FORMAT_YUV422 != format &&
1481 VA_RT_FORMAT_YUV444 != format &&
1482 VA_RT_FORMAT_YUV411 != format &&
1483 VA_RT_FORMAT_YUV400 != format &&
1484 VA_RT_FORMAT_RGB32 != format) {
1485 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
1488 for (i = 0; i < num_surfaces; i++) {
1489 int surfaceID = NEW_SURFACE_ID();
1490 struct object_surface *obj_surface = SURFACE(surfaceID);
1492 if (NULL == obj_surface) {
1493 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1497 surfaces[i] = surfaceID;
1498 obj_surface->status = VASurfaceReady;
1499 obj_surface->orig_width = width;
1500 obj_surface->orig_height = height;
1501 obj_surface->user_disable_tiling = false;
1502 obj_surface->user_h_stride_set = false;
1503 obj_surface->user_v_stride_set = false;
1505 obj_surface->subpic_render_idx = 0;
1506 for(j = 0; j < I965_MAX_SUBPIC_SUM; j++){
1507 obj_surface->subpic[j] = VA_INVALID_ID;
1508 obj_surface->obj_subpic[j] = NULL;
1511 assert(i965->codec_info->min_linear_wpitch);
1512 assert(i965->codec_info->min_linear_hpitch);
1513 obj_surface->width = ALIGN(width, i965->codec_info->min_linear_wpitch);
1514 obj_surface->height = ALIGN(height, i965->codec_info->min_linear_hpitch);
1515 obj_surface->flags = SURFACE_REFERENCED;
1516 obj_surface->fourcc = 0;
1517 obj_surface->expected_format = format;
1518 obj_surface->bo = NULL;
1519 obj_surface->locked_image_id = VA_INVALID_ID;
1520 obj_surface->derived_image_id = VA_INVALID_ID;
1521 obj_surface->private_data = NULL;
1522 obj_surface->free_private_data = NULL;
1523 obj_surface->subsampling = SUBSAMPLE_YUV420;
1525 obj_surface->wrapper_surface = VA_INVALID_ID;
1526 obj_surface->exported_primefd = -1;
1528 switch (memory_type) {
1529 case I965_SURFACE_MEM_NATIVE:
1530 if (memory_attibute) {
1531 if (!(memory_attibute->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING))
1532 obj_surface->user_disable_tiling = true;
1534 if (memory_attibute->pixel_format) {
1535 if (expected_fourcc)
1536 ASSERT_RET(memory_attibute->pixel_format == expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1538 expected_fourcc = memory_attibute->pixel_format;
1540 ASSERT_RET(expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1541 if (memory_attibute->pitches[0]) {
1542 int bpp_1stplane = bpp_1stplane_by_fourcc(expected_fourcc);
1543 ASSERT_RET(bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
1544 obj_surface->width = memory_attibute->pitches[0];
1545 obj_surface->user_h_stride_set = true;
1546 ASSERT_RET(IS_ALIGNED(obj_surface->width, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1547 ASSERT_RET(obj_surface->width >= width * bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
1549 if (memory_attibute->offsets[1]) {
1550 ASSERT_RET(!memory_attibute->offsets[0], VA_STATUS_ERROR_INVALID_PARAMETER);
1551 obj_surface->height = memory_attibute->offsets[1]/memory_attibute->pitches[0];
1552 obj_surface->user_v_stride_set = true;
1553 ASSERT_RET(IS_ALIGNED(obj_surface->height, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1554 ASSERT_RET(obj_surface->height >= height, VA_STATUS_ERROR_INVALID_PARAMETER);
1558 vaStatus = i965_surface_native_memory(ctx,
1564 case I965_SURFACE_MEM_GEM_FLINK:
1565 case I965_SURFACE_MEM_DRM_PRIME:
1566 vaStatus = i965_suface_external_memory(ctx,
1573 if (VA_STATUS_SUCCESS != vaStatus) {
1574 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1579 /* Error recovery */
1580 if (VA_STATUS_SUCCESS != vaStatus) {
1581 /* surfaces[i-1] was the last successful allocation */
1583 struct object_surface *obj_surface = SURFACE(surfaces[i]);
1585 surfaces[i] = VA_INVALID_SURFACE;
1586 assert(obj_surface);
1587 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1595 i965_CreateSurfaces(VADriverContextP ctx,
1600 VASurfaceID *surfaces) /* out */
1602 return i965_CreateSurfaces2(ctx,
1613 i965_DestroySurfaces(VADriverContextP ctx,
1614 VASurfaceID *surface_list,
1617 struct i965_driver_data *i965 = i965_driver_data(ctx);
1619 VAStatus va_status = VA_STATUS_SUCCESS;
1621 for (i = num_surfaces; i--; ) {
1622 struct object_surface *obj_surface = SURFACE(surface_list[i]);
1624 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
1626 if ((obj_surface->wrapper_surface != VA_INVALID_ID) &&
1627 i965->wrapper_pdrvctx) {
1628 CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
1629 vaDestroySurfaces(i965->wrapper_pdrvctx,
1630 &(obj_surface->wrapper_surface),
1632 obj_surface->wrapper_surface = VA_INVALID_ID;
1634 if (obj_surface->exported_primefd >= 0) {
1635 close(obj_surface->exported_primefd);
1636 obj_surface->exported_primefd = -1;
1639 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1646 i965_QueryImageFormats(VADriverContextP ctx,
1647 VAImageFormat *format_list, /* out */
1648 int *num_formats) /* out */
1652 for (n = 0; i965_image_formats_map[n].va_format.fourcc != 0; n++) {
1653 const i965_image_format_map_t * const m = &i965_image_formats_map[n];
1655 format_list[n] = m->va_format;
1661 return VA_STATUS_SUCCESS;
1665 * Guess the format when the usage of a VA surface is unknown
1666 * 1. Without a valid context: YV12
1667 * 2. The current context is valid:
1668 * a) always NV12 on GEN6 and later
1669 * b) I420 for MPEG-2 and NV12 for other codec on GEN4 & GEN5
1672 i965_guess_surface_format(VADriverContextP ctx,
1673 VASurfaceID surface,
1674 unsigned int *fourcc,
1675 unsigned int *is_tiled)
1677 struct i965_driver_data *i965 = i965_driver_data(ctx);
1678 struct object_context *obj_context = NULL;
1679 struct object_config *obj_config = NULL;
1681 *fourcc = VA_FOURCC_YV12;
1684 if (i965->current_context_id == VA_INVALID_ID)
1687 obj_context = CONTEXT(i965->current_context_id);
1692 obj_config = obj_context->obj_config;
1698 if (IS_GEN6(i965->intel.device_info) ||
1699 IS_GEN7(i965->intel.device_info) ||
1700 IS_GEN8(i965->intel.device_info) ||
1701 IS_GEN9(i965->intel.device_info)) {
1702 *fourcc = VA_FOURCC_NV12;
1707 switch (obj_config->profile) {
1708 case VAProfileMPEG2Simple:
1709 case VAProfileMPEG2Main:
1710 *fourcc = VA_FOURCC_I420;
1715 *fourcc = VA_FOURCC_NV12;
1722 i965_QuerySubpictureFormats(VADriverContextP ctx,
1723 VAImageFormat *format_list, /* out */
1724 unsigned int *flags, /* out */
1725 unsigned int *num_formats) /* out */
1729 for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
1730 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
1732 format_list[n] = m->va_format;
1734 flags[n] = m->va_flags;
1740 return VA_STATUS_SUCCESS;
1744 i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
1746 // struct object_subpic *obj_subpic = (struct object_subpic *)obj;
1748 object_heap_free(heap, obj);
1752 i965_CreateSubpicture(VADriverContextP ctx,
1754 VASubpictureID *subpicture) /* out */
1756 struct i965_driver_data *i965 = i965_driver_data(ctx);
1757 VASubpictureID subpicID = NEW_SUBPIC_ID()
1758 struct object_subpic *obj_subpic = SUBPIC(subpicID);
1761 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1763 struct object_image *obj_image = IMAGE(image);
1765 return VA_STATUS_ERROR_INVALID_IMAGE;
1767 const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
1769 return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
1771 *subpicture = subpicID;
1772 obj_subpic->image = image;
1773 obj_subpic->obj_image = obj_image;
1774 obj_subpic->format = m->format;
1775 obj_subpic->width = obj_image->image.width;
1776 obj_subpic->height = obj_image->image.height;
1777 obj_subpic->pitch = obj_image->image.pitches[0];
1778 obj_subpic->bo = obj_image->bo;
1779 obj_subpic->global_alpha = 1.0;
1781 return VA_STATUS_SUCCESS;
1785 i965_DestroySubpicture(VADriverContextP ctx,
1786 VASubpictureID subpicture)
1788 struct i965_driver_data *i965 = i965_driver_data(ctx);
1789 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1792 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1794 ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
1795 i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
1796 return VA_STATUS_SUCCESS;
1800 i965_SetSubpictureImage(VADriverContextP ctx,
1801 VASubpictureID subpicture,
1805 return VA_STATUS_ERROR_UNIMPLEMENTED;
1809 i965_SetSubpictureChromakey(VADriverContextP ctx,
1810 VASubpictureID subpicture,
1811 unsigned int chromakey_min,
1812 unsigned int chromakey_max,
1813 unsigned int chromakey_mask)
1816 return VA_STATUS_ERROR_UNIMPLEMENTED;
1820 i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
1821 VASubpictureID subpicture,
1824 struct i965_driver_data *i965 = i965_driver_data(ctx);
1825 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1827 if(global_alpha > 1.0 || global_alpha < 0.0){
1828 return VA_STATUS_ERROR_INVALID_PARAMETER;
1832 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1834 obj_subpic->global_alpha = global_alpha;
1836 return VA_STATUS_SUCCESS;
1840 i965_AssociateSubpicture(VADriverContextP ctx,
1841 VASubpictureID subpicture,
1842 VASurfaceID *target_surfaces,
1844 short src_x, /* upper left offset in subpicture */
1846 unsigned short src_width,
1847 unsigned short src_height,
1848 short dest_x, /* upper left offset in surface */
1850 unsigned short dest_width,
1851 unsigned short dest_height,
1853 * whether to enable chroma-keying or global-alpha
1854 * see VA_SUBPICTURE_XXX values
1858 struct i965_driver_data *i965 = i965_driver_data(ctx);
1859 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1863 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1865 ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
1867 obj_subpic->src_rect.x = src_x;
1868 obj_subpic->src_rect.y = src_y;
1869 obj_subpic->src_rect.width = src_width;
1870 obj_subpic->src_rect.height = src_height;
1871 obj_subpic->dst_rect.x = dest_x;
1872 obj_subpic->dst_rect.y = dest_y;
1873 obj_subpic->dst_rect.width = dest_width;
1874 obj_subpic->dst_rect.height = dest_height;
1875 obj_subpic->flags = flags;
1877 for (i = 0; i < num_surfaces; i++) {
1878 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1880 return VA_STATUS_ERROR_INVALID_SURFACE;
1882 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1883 if(obj_surface->subpic[j] == VA_INVALID_ID){
1884 assert(obj_surface->obj_subpic[j] == NULL);
1885 obj_surface->subpic[j] = subpicture;
1886 obj_surface->obj_subpic[j] = obj_subpic;
1891 if(j == I965_MAX_SUBPIC_SUM){
1892 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1896 return VA_STATUS_SUCCESS;
1901 i965_DeassociateSubpicture(VADriverContextP ctx,
1902 VASubpictureID subpicture,
1903 VASurfaceID *target_surfaces,
1906 struct i965_driver_data *i965 = i965_driver_data(ctx);
1907 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1911 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1913 for (i = 0; i < num_surfaces; i++) {
1914 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1916 return VA_STATUS_ERROR_INVALID_SURFACE;
1918 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1919 if (obj_surface->subpic[j] == subpicture) {
1920 assert(obj_surface->obj_subpic[j] == obj_subpic);
1921 obj_surface->subpic[j] = VA_INVALID_ID;
1922 obj_surface->obj_subpic[j] = NULL;
1927 if(j == I965_MAX_SUBPIC_SUM){
1928 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1931 return VA_STATUS_SUCCESS;
1935 i965_reference_buffer_store(struct buffer_store **ptr,
1936 struct buffer_store *buffer_store)
1938 assert(*ptr == NULL);
1941 buffer_store->ref_count++;
1942 *ptr = buffer_store;
1947 i965_release_buffer_store(struct buffer_store **ptr)
1949 struct buffer_store *buffer_store = *ptr;
1951 if (buffer_store == NULL)
1954 assert(buffer_store->bo || buffer_store->buffer);
1955 assert(!(buffer_store->bo && buffer_store->buffer));
1956 buffer_store->ref_count--;
1958 if (buffer_store->ref_count == 0) {
1959 dri_bo_unreference(buffer_store->bo);
1960 free(buffer_store->buffer);
1961 buffer_store->bo = NULL;
1962 buffer_store->buffer = NULL;
1970 i965_destroy_context(struct object_heap *heap, struct object_base *obj)
1972 struct object_context *obj_context = (struct object_context *)obj;
1975 if (obj_context->hw_context) {
1976 obj_context->hw_context->destroy(obj_context->hw_context);
1977 obj_context->hw_context = NULL;
1980 if (obj_context->codec_type == CODEC_PROC) {
1981 i965_release_buffer_store(&obj_context->codec_state.proc.pipeline_param);
1983 } else if (obj_context->codec_type == CODEC_ENC) {
1984 assert(obj_context->codec_state.encode.num_slice_params <= obj_context->codec_state.encode.max_slice_params);
1985 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
1986 i965_release_buffer_store(&obj_context->codec_state.encode.seq_param);
1988 for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++)
1989 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
1991 free(obj_context->codec_state.encode.slice_params);
1993 assert(obj_context->codec_state.encode.num_slice_params_ext <= obj_context->codec_state.encode.max_slice_params_ext);
1994 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
1995 i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
1997 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
1998 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
2000 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
2001 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
2003 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
2004 i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i]);
2006 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
2007 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
2009 free(obj_context->codec_state.encode.slice_params_ext);
2010 if (obj_context->codec_state.encode.slice_rawdata_index) {
2011 free(obj_context->codec_state.encode.slice_rawdata_index);
2012 obj_context->codec_state.encode.slice_rawdata_index = NULL;
2014 if (obj_context->codec_state.encode.slice_rawdata_count) {
2015 free(obj_context->codec_state.encode.slice_rawdata_count);
2016 obj_context->codec_state.encode.slice_rawdata_count = NULL;
2019 if (obj_context->codec_state.encode.slice_header_index) {
2020 free(obj_context->codec_state.encode.slice_header_index);
2021 obj_context->codec_state.encode.slice_header_index = NULL;
2024 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
2025 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
2026 free(obj_context->codec_state.encode.packed_header_params_ext);
2028 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
2029 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
2030 free(obj_context->codec_state.encode.packed_header_data_ext);
2033 assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
2034 assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
2036 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
2037 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
2038 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
2040 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++)
2041 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
2043 for (i = 0; i < obj_context->codec_state.decode.num_slice_datas; i++)
2044 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
2046 free(obj_context->codec_state.decode.slice_params);
2047 free(obj_context->codec_state.decode.slice_datas);
2050 free(obj_context->render_targets);
2051 object_heap_free(heap, obj);
2055 i965_CreateContext(VADriverContextP ctx,
2056 VAConfigID config_id,
2060 VASurfaceID *render_targets,
2061 int num_render_targets,
2062 VAContextID *context) /* out */
2064 struct i965_driver_data *i965 = i965_driver_data(ctx);
2065 struct object_config *obj_config = CONFIG(config_id);
2066 struct object_context *obj_context = NULL;
2067 VAConfigAttrib *attrib;
2068 VAStatus vaStatus = VA_STATUS_SUCCESS;
2072 if (NULL == obj_config) {
2073 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
2077 if (picture_width > i965->codec_info->max_width ||
2078 picture_height > i965->codec_info->max_height) {
2079 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
2084 /* Validate picture dimensions */
2085 contextID = NEW_CONTEXT_ID();
2086 obj_context = CONTEXT(contextID);
2088 if (NULL == obj_context) {
2089 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2093 *context = contextID;
2094 obj_context->flags = flag;
2095 obj_context->context_id = contextID;
2096 obj_context->obj_config = obj_config;
2097 obj_context->picture_width = picture_width;
2098 obj_context->picture_height = picture_height;
2099 obj_context->num_render_targets = num_render_targets;
2100 obj_context->render_targets =
2101 (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
2102 obj_context->hw_context = NULL;
2103 obj_context->wrapper_context = VA_INVALID_ID;
2105 if (!obj_context->render_targets)
2106 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2108 for(i = 0; i < num_render_targets; i++) {
2109 if (NULL == SURFACE(render_targets[i])) {
2110 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
2114 obj_context->render_targets[i] = render_targets[i];
2117 if (VA_STATUS_SUCCESS == vaStatus) {
2118 if (VAEntrypointVideoProc == obj_config->entrypoint) {
2119 obj_context->codec_type = CODEC_PROC;
2120 memset(&obj_context->codec_state.proc, 0, sizeof(obj_context->codec_state.proc));
2121 obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
2122 assert(i965->codec_info->proc_hw_context_init);
2123 obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
2124 } else if ((VAEntrypointEncSlice == obj_config->entrypoint) ||
2125 (VAEntrypointEncPicture == obj_config->entrypoint)) { /*encode routine only*/
2126 VAConfigAttrib *packed_attrib;
2127 obj_context->codec_type = CODEC_ENC;
2128 memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
2129 obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
2130 obj_context->codec_state.encode.max_slice_params = NUM_SLICES;
2131 obj_context->codec_state.encode.slice_params = calloc(obj_context->codec_state.encode.max_slice_params,
2132 sizeof(*obj_context->codec_state.encode.slice_params));
2133 obj_context->codec_state.encode.max_packed_header_params_ext = NUM_SLICES;
2134 obj_context->codec_state.encode.packed_header_params_ext =
2135 calloc(obj_context->codec_state.encode.max_packed_header_params_ext,
2136 sizeof(struct buffer_store *));
2138 obj_context->codec_state.encode.max_packed_header_data_ext = NUM_SLICES;
2139 obj_context->codec_state.encode.packed_header_data_ext =
2140 calloc(obj_context->codec_state.encode.max_packed_header_data_ext,
2141 sizeof(struct buffer_store *));
2143 obj_context->codec_state.encode.max_slice_num = NUM_SLICES;
2144 obj_context->codec_state.encode.slice_rawdata_index =
2145 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
2146 obj_context->codec_state.encode.slice_rawdata_count =
2147 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
2149 obj_context->codec_state.encode.slice_header_index =
2150 calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int));
2152 obj_context->codec_state.encode.vps_sps_seq_index = 0;
2154 obj_context->codec_state.encode.slice_index = 0;
2155 packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders);
2157 obj_context->codec_state.encode.packed_header_flag = packed_attrib->value;
2159 /* use the default value. SPS/PPS/RAWDATA is passed from user
2160 * while Slice_header data is generated by driver.
2162 obj_context->codec_state.encode.packed_header_flag =
2163 VA_ENC_PACKED_HEADER_SEQUENCE |
2164 VA_ENC_PACKED_HEADER_PICTURE |
2165 VA_ENC_PACKED_HEADER_RAW_DATA;
2167 assert(i965->codec_info->enc_hw_context_init);
2168 obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
2170 obj_context->codec_type = CODEC_DEC;
2171 memset(&obj_context->codec_state.decode, 0, sizeof(obj_context->codec_state.decode));
2172 obj_context->codec_state.decode.current_render_target = -1;
2173 obj_context->codec_state.decode.max_slice_params = NUM_SLICES;
2174 obj_context->codec_state.decode.max_slice_datas = NUM_SLICES;
2175 obj_context->codec_state.decode.slice_params = calloc(obj_context->codec_state.decode.max_slice_params,
2176 sizeof(*obj_context->codec_state.decode.slice_params));
2177 obj_context->codec_state.decode.slice_datas = calloc(obj_context->codec_state.decode.max_slice_datas,
2178 sizeof(*obj_context->codec_state.decode.slice_datas));
2180 assert(i965->codec_info->dec_hw_context_init);
2181 obj_context->hw_context = i965->codec_info->dec_hw_context_init(ctx, obj_config);
2185 attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribRTFormat);
2187 return VA_STATUS_ERROR_INVALID_CONFIG;
2188 obj_context->codec_state.base.chroma_formats = attrib->value;
2190 if (obj_config->wrapper_config != VA_INVALID_ID) {
2191 /* The wrapper_pdrvctx should exist when wrapper_config is valid.
2192 * So it won't check i965->wrapper_pdrvctx again.
2193 * Fixme if it is incorrect.
2195 VAGenericID wrapper_context;
2198 * The render_surface is not passed when calling
2200 * If it is needed, we must get the wrapped surface
2201 * for the corresponding Surface_list.
2202 * So the wrapped surface conversion is deferred.
2204 CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
2205 vaCreateContext(i965->wrapper_pdrvctx,
2206 obj_config->wrapper_config,
2207 picture_width, picture_height,
2211 if (vaStatus == VA_STATUS_SUCCESS)
2212 obj_context->wrapper_context = wrapper_context;
2214 /* Error recovery */
2215 if (VA_STATUS_SUCCESS != vaStatus) {
2216 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
2219 i965->current_context_id = contextID;
2225 i965_DestroyContext(VADriverContextP ctx, VAContextID context)
2227 struct i965_driver_data *i965 = i965_driver_data(ctx);
2228 struct object_context *obj_context = CONTEXT(context);
2229 VAStatus va_status = VA_STATUS_SUCCESS;
2231 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2233 if (i965->current_context_id == context)
2234 i965->current_context_id = VA_INVALID_ID;
2236 if ((obj_context->wrapper_context != VA_INVALID_ID) &&
2237 i965->wrapper_pdrvctx) {
2238 CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
2239 vaDestroyContext(i965->wrapper_pdrvctx,
2240 obj_context->wrapper_context));
2242 obj_context->wrapper_context = VA_INVALID_ID;
2245 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
2251 i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
2253 struct object_buffer *obj_buffer = (struct object_buffer *)obj;
2255 assert(obj_buffer->buffer_store);
2256 i965_release_buffer_store(&obj_buffer->buffer_store);
2257 object_heap_free(heap, obj);
2261 i965_create_buffer_internal(VADriverContextP ctx,
2262 VAContextID context,
2265 unsigned int num_elements,
2270 struct i965_driver_data *i965 = i965_driver_data(ctx);
2271 struct object_buffer *obj_buffer = NULL;
2272 struct buffer_store *buffer_store = NULL;
2274 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2275 struct object_context *obj_context = CONTEXT(context);
2276 int wrapper_flag = 0;
2280 case VAPictureParameterBufferType:
2281 case VAIQMatrixBufferType:
2282 case VAQMatrixBufferType:
2283 case VABitPlaneBufferType:
2284 case VASliceGroupMapBufferType:
2285 case VASliceParameterBufferType:
2286 case VASliceDataBufferType:
2287 case VAMacroblockParameterBufferType:
2288 case VAResidualDataBufferType:
2289 case VADeblockingParameterBufferType:
2290 case VAImageBufferType:
2291 case VAEncCodedBufferType:
2292 case VAEncSequenceParameterBufferType:
2293 case VAEncPictureParameterBufferType:
2294 case VAEncSliceParameterBufferType:
2295 case VAEncPackedHeaderParameterBufferType:
2296 case VAEncPackedHeaderDataBufferType:
2297 case VAEncMiscParameterBufferType:
2298 case VAProcPipelineParameterBufferType:
2299 case VAProcFilterParameterBufferType:
2300 case VAHuffmanTableBufferType:
2301 case VAProbabilityBufferType:
2306 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2309 bufferID = NEW_BUFFER_ID();
2310 obj_buffer = BUFFER(bufferID);
2312 if (NULL == obj_buffer) {
2313 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2316 if (type == VAEncCodedBufferType) {
2317 size += I965_CODEDBUFFER_HEADER_SIZE;
2318 size += 0x1000; /* for upper bound check */
2321 obj_buffer->max_num_elements = num_elements;
2322 obj_buffer->num_elements = num_elements;
2323 obj_buffer->size_element = size;
2324 obj_buffer->type = type;
2325 obj_buffer->export_refcount = 0;
2326 obj_buffer->buffer_store = NULL;
2327 obj_buffer->wrapper_buffer = VA_INVALID_ID;
2329 buffer_store = calloc(1, sizeof(struct buffer_store));
2330 assert(buffer_store);
2331 buffer_store->ref_count = 1;
2334 (obj_context->wrapper_context != VA_INVALID_ID) &&
2335 i965->wrapper_pdrvctx) {
2336 VAGenericID wrapper_buffer;
2337 VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
2339 CALL_VTABLE(pdrvctx, vaStatus,
2340 vaCreateBuffer(pdrvctx, obj_context->wrapper_context, type, size, num_elements,
2341 data, &wrapper_buffer));
2342 if (vaStatus == VA_STATUS_SUCCESS) {
2343 obj_buffer->wrapper_buffer = wrapper_buffer;
2351 if (store_bo != NULL) {
2352 buffer_store->bo = store_bo;
2353 dri_bo_reference(buffer_store->bo);
2355 /* If the buffer is wrapped, the buffer_store is bogus. Unnecessary to copy it */
2356 if (data && !wrapper_flag)
2357 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
2358 } else if (type == VASliceDataBufferType ||
2359 type == VAImageBufferType ||
2360 type == VAEncCodedBufferType ||
2361 type == VAProbabilityBufferType) {
2363 /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
2364 * So it is enough to allocate one 64 byte bo
2367 buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr, "Bogus buffer",
2370 buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
2372 size * num_elements, 64);
2373 assert(buffer_store->bo);
2375 /* If the buffer is wrapped, the bo/buffer of buffer_store is bogus.
2376 * In fact it can be skipped. But it is still allocated and it is
2377 * only to follow the normal flowchart of buffer_allocation/release.
2379 if (!wrapper_flag) {
2380 if (type == VAEncCodedBufferType) {
2381 struct i965_coded_buffer_segment *coded_buffer_segment;
2383 dri_bo_map(buffer_store->bo, 1);
2384 coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual;
2385 coded_buffer_segment->base.size = size - I965_CODEDBUFFER_HEADER_SIZE;
2386 coded_buffer_segment->base.bit_offset = 0;
2387 coded_buffer_segment->base.status = 0;
2388 coded_buffer_segment->base.buf = NULL;
2389 coded_buffer_segment->base.next = NULL;
2390 coded_buffer_segment->mapped = 0;
2391 coded_buffer_segment->codec = 0;
2392 dri_bo_unmap(buffer_store->bo);
2394 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
2401 if (type == VAEncPackedHeaderDataBufferType) {
2402 msize = ALIGN(size, 4);
2405 /* If the buffer is wrapped, it is enough to allocate 4 bytes */
2407 buffer_store->buffer = malloc(4);
2409 buffer_store->buffer = malloc(msize * num_elements);
2410 assert(buffer_store->buffer);
2412 if (data && (!wrapper_flag))
2413 memcpy(buffer_store->buffer, data, size * num_elements);
2416 buffer_store->num_elements = obj_buffer->num_elements;
2417 i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
2418 i965_release_buffer_store(&buffer_store);
2421 return VA_STATUS_SUCCESS;
2425 i965_CreateBuffer(VADriverContextP ctx,
2426 VAContextID context, /* in */
2427 VABufferType type, /* in */
2428 unsigned int size, /* in */
2429 unsigned int num_elements, /* in */
2430 void *data, /* in */
2431 VABufferID *buf_id) /* out */
2433 return i965_create_buffer_internal(ctx, context, type, size, num_elements, data, NULL, buf_id);
2438 i965_BufferSetNumElements(VADriverContextP ctx,
2439 VABufferID buf_id, /* in */
2440 unsigned int num_elements) /* in */
2442 struct i965_driver_data *i965 = i965_driver_data(ctx);
2443 struct object_buffer *obj_buffer = BUFFER(buf_id);
2444 VAStatus vaStatus = VA_STATUS_SUCCESS;
2446 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2448 /* When the wrapper_buffer exists, it will wrapper to the
2449 * buffer allocated from backend driver.
2451 if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
2452 i965->wrapper_pdrvctx) {
2453 VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
2455 CALL_VTABLE(pdrvctx, vaStatus,
2456 vaBufferSetNumElements(pdrvctx, obj_buffer->wrapper_buffer,
2461 if ((num_elements < 0) ||
2462 (num_elements > obj_buffer->max_num_elements)) {
2463 vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2465 obj_buffer->num_elements = num_elements;
2466 if (obj_buffer->buffer_store != NULL) {
2467 obj_buffer->buffer_store->num_elements = num_elements;
2475 i965_MapBuffer(VADriverContextP ctx,
2476 VABufferID buf_id, /* in */
2477 void **pbuf) /* out */
2479 struct i965_driver_data *i965 = i965_driver_data(ctx);
2480 struct object_buffer *obj_buffer = BUFFER(buf_id);
2481 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2483 ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
2485 /* When the wrapper_buffer exists, it will wrapper to the
2486 * buffer allocated from backend driver.
2488 if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
2489 i965->wrapper_pdrvctx) {
2490 VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
2492 CALL_VTABLE(pdrvctx, vaStatus,
2493 vaMapBuffer(pdrvctx, obj_buffer->wrapper_buffer, pbuf));
2497 ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2498 ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_INVALID_BUFFER);
2500 if (obj_buffer->export_refcount > 0)
2501 return VA_STATUS_ERROR_INVALID_BUFFER;
2503 if (NULL != obj_buffer->buffer_store->bo) {
2504 unsigned int tiling, swizzle;
2506 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
2508 if (tiling != I915_TILING_NONE)
2509 drm_intel_gem_bo_map_gtt(obj_buffer->buffer_store->bo);
2511 dri_bo_map(obj_buffer->buffer_store->bo, 1);
2513 ASSERT_RET(obj_buffer->buffer_store->bo->virtual, VA_STATUS_ERROR_OPERATION_FAILED);
2514 *pbuf = obj_buffer->buffer_store->bo->virtual;
2516 if (obj_buffer->type == VAEncCodedBufferType) {
2518 unsigned char *buffer = NULL;
2519 unsigned int header_offset = I965_CODEDBUFFER_HEADER_SIZE;
2520 struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual);
2522 if (!coded_buffer_segment->mapped) {
2523 unsigned char delimiter0, delimiter1, delimiter2, delimiter3, delimiter4;
2525 coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
2527 if (coded_buffer_segment->codec == CODEC_H264 ||
2528 coded_buffer_segment->codec == CODEC_H264_MVC) {
2529 delimiter0 = H264_DELIMITER0;
2530 delimiter1 = H264_DELIMITER1;
2531 delimiter2 = H264_DELIMITER2;
2532 delimiter3 = H264_DELIMITER3;
2533 delimiter4 = H264_DELIMITER4;
2534 } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
2535 delimiter0 = MPEG2_DELIMITER0;
2536 delimiter1 = MPEG2_DELIMITER1;
2537 delimiter2 = MPEG2_DELIMITER2;
2538 delimiter3 = MPEG2_DELIMITER3;
2539 delimiter4 = MPEG2_DELIMITER4;
2540 } else if(coded_buffer_segment->codec == CODEC_JPEG) {
2541 //In JPEG End of Image (EOI = 0xDDF9) marker can be used for delimiter.
2544 } else if (coded_buffer_segment->codec == CODEC_HEVC) {
2545 delimiter0 = HEVC_DELIMITER0;
2546 delimiter1 = HEVC_DELIMITER1;
2547 delimiter2 = HEVC_DELIMITER2;
2548 delimiter3 = HEVC_DELIMITER3;
2549 delimiter4 = HEVC_DELIMITER4;
2550 } else if (coded_buffer_segment->codec != CODEC_VP8) {
2551 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
2554 if(coded_buffer_segment->codec == CODEC_JPEG) {
2555 for(i = 0; i < obj_buffer->size_element - header_offset - 1 - 0x1000; i++) {
2556 if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) {
2560 coded_buffer_segment->base.size = i + 2;
2561 } else if (coded_buffer_segment->codec != CODEC_VP8) {
2562 /* vp8 coded buffer size can be told by vp8 internal statistics buffer,
2563 so it don't need to traversal the coded buffer */
2564 for (i = 0; i < obj_buffer->size_element - header_offset - 3 - 0x1000; i++) {
2565 if ((buffer[i] == delimiter0) &&
2566 (buffer[i + 1] == delimiter1) &&
2567 (buffer[i + 2] == delimiter2) &&
2568 (buffer[i + 3] == delimiter3) &&
2569 (buffer[i + 4] == delimiter4))
2573 if (i == obj_buffer->size_element - header_offset - 3 - 0x1000) {
2574 coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
2576 coded_buffer_segment->base.size = i;
2579 if (coded_buffer_segment->base.size >= obj_buffer->size_element - header_offset - 0x1000) {
2580 coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
2583 coded_buffer_segment->mapped = 1;
2585 assert(coded_buffer_segment->base.buf);
2589 vaStatus = VA_STATUS_SUCCESS;
2590 } else if (NULL != obj_buffer->buffer_store->buffer) {
2591 *pbuf = obj_buffer->buffer_store->buffer;
2592 vaStatus = VA_STATUS_SUCCESS;
2599 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
2601 struct i965_driver_data *i965 = i965_driver_data(ctx);
2602 struct object_buffer *obj_buffer = BUFFER(buf_id);
2603 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2605 if ((buf_id & OBJECT_HEAP_OFFSET_MASK) != BUFFER_ID_OFFSET)
2606 return VA_STATUS_ERROR_INVALID_BUFFER;
2608 ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
2609 /* When the wrapper_buffer exists, it will wrapper to the
2610 * buffer allocated from backend driver.
2612 if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
2613 i965->wrapper_pdrvctx) {
2614 VADriverContextP pdrvctx = i965->wrapper_pdrvctx;
2616 CALL_VTABLE(pdrvctx, vaStatus,
2617 vaUnmapBuffer(pdrvctx, obj_buffer->wrapper_buffer));
2621 ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_OPERATION_FAILED);
2622 ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_OPERATION_FAILED);
2624 if (NULL != obj_buffer->buffer_store->bo) {
2625 unsigned int tiling, swizzle;
2627 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
2629 if (tiling != I915_TILING_NONE)
2630 drm_intel_gem_bo_unmap_gtt(obj_buffer->buffer_store->bo);
2632 dri_bo_unmap(obj_buffer->buffer_store->bo);
2634 vaStatus = VA_STATUS_SUCCESS;
2635 } else if (NULL != obj_buffer->buffer_store->buffer) {
2637 vaStatus = VA_STATUS_SUCCESS;
2644 i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
2646 struct i965_driver_data *i965 = i965_driver_data(ctx);
2647 struct object_buffer *obj_buffer = BUFFER(buffer_id);
2648 VAStatus va_status = VA_STATUS_SUCCESS;
2650 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2652 if ((obj_buffer->wrapper_buffer != VA_INVALID_ID) &&
2653 i965->wrapper_pdrvctx) {
2654 CALL_VTABLE(i965->wrapper_pdrvctx, va_status,
2655 vaDestroyBuffer(i965->wrapper_pdrvctx,
2656 obj_buffer->wrapper_buffer));
2657 obj_buffer->wrapper_buffer = VA_INVALID_ID;
2660 i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
2666 i965_BeginPicture(VADriverContextP ctx,
2667 VAContextID context,
2668 VASurfaceID render_target)
2670 struct i965_driver_data *i965 = i965_driver_data(ctx);
2671 struct object_context *obj_context = CONTEXT(context);
2672 struct object_surface *obj_surface = SURFACE(render_target);
2673 struct object_config *obj_config;
2674 VAStatus vaStatus = VA_STATUS_SUCCESS;
2677 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2678 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2679 obj_config = obj_context->obj_config;
2680 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2682 if (is_surface_busy(i965, obj_surface))
2683 return VA_STATUS_ERROR_SURFACE_BUSY;
2685 if (obj_context->codec_type == CODEC_PROC) {
2686 obj_context->codec_state.proc.current_render_target = render_target;
2687 } else if (obj_context->codec_type == CODEC_ENC) {
2688 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
2690 for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++) {
2691 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
2694 obj_context->codec_state.encode.num_slice_params = 0;
2697 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
2699 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
2700 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
2702 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
2703 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
2705 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
2706 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
2708 obj_context->codec_state.encode.num_slice_params_ext = 0;
2709 obj_context->codec_state.encode.current_render_target = render_target; /*This is input new frame*/
2710 obj_context->codec_state.encode.last_packed_header_type = 0;
2711 memset(obj_context->codec_state.encode.slice_rawdata_index, 0,
2712 sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2713 memset(obj_context->codec_state.encode.slice_rawdata_count, 0,
2714 sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2715 memset(obj_context->codec_state.encode.slice_header_index, 0,
2716 sizeof(int) * obj_context->codec_state.encode.max_slice_num);
2718 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
2719 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
2720 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
2721 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
2722 obj_context->codec_state.encode.num_packed_header_params_ext = 0;
2723 obj_context->codec_state.encode.num_packed_header_data_ext = 0;
2724 obj_context->codec_state.encode.slice_index = 0;
2725 obj_context->codec_state.encode.vps_sps_seq_index = 0;
2727 obj_context->codec_state.decode.current_render_target = render_target;
2728 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
2729 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
2730 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
2731 i965_release_buffer_store(&obj_context->codec_state.decode.huffman_table);
2733 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++) {
2734 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
2735 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
2738 obj_context->codec_state.decode.num_slice_params = 0;
2739 obj_context->codec_state.decode.num_slice_datas = 0;
2741 if ((obj_context->wrapper_context != VA_INVALID_ID) &&
2742 i965->wrapper_pdrvctx) {
2743 if (obj_surface->wrapper_surface == VA_INVALID_ID)
2744 vaStatus = i965_surface_wrapper(ctx, render_target);
2746 if (vaStatus != VA_STATUS_SUCCESS)
2749 CALL_VTABLE(i965->wrapper_pdrvctx, vaStatus,
2750 vaBeginPicture(i965->wrapper_pdrvctx,
2751 obj_context->wrapper_context,
2752 obj_surface->wrapper_surface));
2759 #define I965_RENDER_BUFFER(category, name) i965_render_##category##_##name##_buffer(ctx, obj_context, obj_buffer)
2761 #define DEF_RENDER_SINGLE_BUFFER_FUNC(category, name, member) \
2763 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
2764 struct object_context *obj_context, \
2765 struct object_buffer *obj_buffer) \
2767 struct category##_state *category = &obj_context->codec_state.category; \
2768 i965_release_buffer_store(&category->member); \
2769 i965_reference_buffer_store(&category->member, obj_buffer->buffer_store); \
2770 return VA_STATUS_SUCCESS; \
2773 #define DEF_RENDER_MULTI_BUFFER_FUNC(category, name, member) \
2775 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
2776 struct object_context *obj_context, \
2777 struct object_buffer *obj_buffer) \
2779 struct category##_state *category = &obj_context->codec_state.category; \
2780 if (category->num_##member == category->max_##member) { \
2781 category->member = realloc(category->member, (category->max_##member + NUM_SLICES) * sizeof(*category->member)); \
2782 memset(category->member + category->max_##member, 0, NUM_SLICES * sizeof(*category->member)); \
2783 category->max_##member += NUM_SLICES; \
2785 i965_release_buffer_store(&category->member[category->num_##member]); \
2786 i965_reference_buffer_store(&category->member[category->num_##member], obj_buffer->buffer_store); \
2787 category->num_##member++; \
2788 return VA_STATUS_SUCCESS; \
2791 #define I965_RENDER_DECODE_BUFFER(name) I965_RENDER_BUFFER(decode, name)
2793 #define DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(decode, name, member)
2794 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2795 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(iq_matrix, iq_matrix)
2796 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(bit_plane, bit_plane)
2797 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
2798 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(probability_data, probability_data)
2800 #define DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(decode, name, member)
2801 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2802 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_data, slice_datas)
2806 i965_decoder_vp9_wrapper_picture(VADriverContextP ctx,
2807 VABufferID *buffers,
2810 struct i965_driver_data *i965 = i965_driver_data(ctx);
2811 VAStatus vaStatus = VA_STATUS_SUCCESS;
2813 VADecPictureParameterBufferVP9 *pVp9PicParams;
2814 VADriverContextP pdrvctx;
2815 struct object_buffer *obj_buffer;
2817 pdrvctx = i965->wrapper_pdrvctx;
2818 /* do the conversion of VADecPictureParameterBufferVP9 */
2819 for (i = 0; i < num_buffers; i++) {
2820 obj_buffer = BUFFER(buffers[i]);
2825 if (obj_buffer->wrapper_buffer == VA_INVALID_ID)
2828 if (obj_buffer->type == VAPictureParameterBufferType) {
2830 VASurfaceID surface_id;
2831 struct object_surface *obj_surface;
2833 pdrvctx = i965->wrapper_pdrvctx;
2835 CALL_VTABLE(pdrvctx, vaStatus,
2836 vaMapBuffer(pdrvctx, obj_buffer->wrapper_buffer,
2837 (void **)(&pVp9PicParams)));
2839 if (vaStatus != VA_STATUS_SUCCESS)
2842 for (j = 0; j < 8; j++) {
2843 surface_id = pVp9PicParams->reference_frames[j];
2844 obj_surface = SURFACE(surface_id);
2849 if (obj_surface->wrapper_surface == VA_INVALID_ID) {
2850 vaStatus = i965_surface_wrapper(ctx, surface_id);
2851 if (vaStatus != VA_STATUS_SUCCESS) {
2852 pdrvctx->vtable->vaUnmapBuffer(pdrvctx,
2853 obj_buffer->wrapper_buffer);
2858 pVp9PicParams->reference_frames[j] = obj_surface->wrapper_surface;
2860 CALL_VTABLE(pdrvctx, vaStatus,
2861 vaUnmapBuffer(pdrvctx, obj_buffer->wrapper_buffer));
2866 return VA_STATUS_SUCCESS;
2873 i965_decoder_wrapper_picture(VADriverContextP ctx,
2874 VAContextID context,
2875 VABufferID *buffers,
2878 struct i965_driver_data *i965 = i965_driver_data(ctx);
2879 struct object_context *obj_context = CONTEXT(context);
2880 VAStatus vaStatus = VA_STATUS_SUCCESS;
2882 VADriverContextP pdrvctx;
2883 struct object_buffer *obj_buffer;
2885 if (obj_context == NULL)
2886 return VA_STATUS_ERROR_INVALID_CONTEXT;
2888 /* When it is not wrapped context, continue the normal flowchart */
2889 if (obj_context->wrapper_context == VA_INVALID_ID)
2892 if (obj_context->obj_config &&
2893 (obj_context->obj_config->profile == VAProfileVP9Profile0)) {
2894 vaStatus = i965_decoder_vp9_wrapper_picture(ctx, buffers, num_buffers);
2896 return VA_STATUS_ERROR_INVALID_PARAMETER;
2898 pdrvctx = i965->wrapper_pdrvctx;
2900 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2901 obj_buffer = BUFFER(buffers[i]);
2906 if (obj_buffer->wrapper_buffer == VA_INVALID_ID) {
2907 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER;
2911 CALL_VTABLE(pdrvctx, vaStatus,
2912 vaRenderPicture(pdrvctx, obj_context->wrapper_context,
2913 &(obj_buffer->wrapper_buffer), 1));
2919 i965_decoder_render_picture(VADriverContextP ctx,
2920 VAContextID context,
2921 VABufferID *buffers,
2924 struct i965_driver_data *i965 = i965_driver_data(ctx);
2925 struct object_context *obj_context = CONTEXT(context);
2926 VAStatus vaStatus = VA_STATUS_SUCCESS;
2929 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2931 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2932 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2935 return VA_STATUS_ERROR_INVALID_BUFFER;
2937 switch (obj_buffer->type) {
2938 case VAPictureParameterBufferType:
2939 vaStatus = I965_RENDER_DECODE_BUFFER(picture_parameter);
2942 case VAIQMatrixBufferType:
2943 vaStatus = I965_RENDER_DECODE_BUFFER(iq_matrix);
2946 case VABitPlaneBufferType:
2947 vaStatus = I965_RENDER_DECODE_BUFFER(bit_plane);
2950 case VASliceParameterBufferType:
2951 vaStatus = I965_RENDER_DECODE_BUFFER(slice_parameter);
2954 case VASliceDataBufferType:
2955 vaStatus = I965_RENDER_DECODE_BUFFER(slice_data);
2958 case VAHuffmanTableBufferType:
2959 vaStatus = I965_RENDER_DECODE_BUFFER(huffman_table);
2962 case VAProbabilityBufferType:
2963 vaStatus = I965_RENDER_DECODE_BUFFER(probability_data);
2967 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2972 if ((vaStatus == VA_STATUS_SUCCESS) &&
2973 (obj_context->wrapper_context != VA_INVALID_ID))
2974 vaStatus = i965_decoder_wrapper_picture(ctx, context, buffers, num_buffers);
2979 #define I965_RENDER_ENCODE_BUFFER(name) I965_RENDER_BUFFER(encode, name)
2981 #define DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(encode, name, member)
2982 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter, seq_param)
2983 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2984 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_control, pic_control)
2985 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(qmatrix, q_matrix)
2986 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(iqmatrix, iq_matrix)
2987 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
2988 /* extended buffer */
2989 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
2990 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
2992 #define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
2993 // DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2994 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter_ext, slice_params_ext)
2996 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_params_ext, packed_header_params_ext)
2997 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_data_ext, packed_header_data_ext)
3000 i965_encoder_render_packed_header_parameter_buffer(VADriverContextP ctx,
3001 struct object_context *obj_context,
3002 struct object_buffer *obj_buffer,
3005 struct encode_state *encode = &obj_context->codec_state.encode;
3007 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
3008 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
3009 i965_release_buffer_store(&encode->packed_header_param[type_index]);
3010 i965_reference_buffer_store(&encode->packed_header_param[type_index], obj_buffer->buffer_store);
3012 return VA_STATUS_SUCCESS;
3016 i965_encoder_render_packed_header_data_buffer(VADriverContextP ctx,
3017 struct object_context *obj_context,
3018 struct object_buffer *obj_buffer,
3021 struct encode_state *encode = &obj_context->codec_state.encode;
3023 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
3024 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
3025 i965_release_buffer_store(&encode->packed_header_data[type_index]);
3026 i965_reference_buffer_store(&encode->packed_header_data[type_index], obj_buffer->buffer_store);
3028 return VA_STATUS_SUCCESS;
3032 i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
3033 struct object_context *obj_context,
3034 struct object_buffer *obj_buffer)
3036 struct encode_state *encode = &obj_context->codec_state.encode;
3037 VAEncMiscParameterBuffer *param = NULL;
3039 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
3040 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
3042 param = (VAEncMiscParameterBuffer *)obj_buffer->buffer_store->buffer;
3044 if (param->type >= ARRAY_ELEMS(encode->misc_param))
3045 return VA_STATUS_ERROR_INVALID_PARAMETER;
3047 i965_release_buffer_store(&encode->misc_param[param->type]);
3048 i965_reference_buffer_store(&encode->misc_param[param->type], obj_buffer->buffer_store);
3050 return VA_STATUS_SUCCESS;
3054 i965_encoder_render_picture(VADriverContextP ctx,
3055 VAContextID context,
3056 VABufferID *buffers,
3059 struct i965_driver_data *i965 = i965_driver_data(ctx);
3060 struct object_context *obj_context = CONTEXT(context);
3061 struct object_config *obj_config;
3062 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
3063 struct encode_state *encode;
3066 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
3067 obj_config = obj_context->obj_config;
3068 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
3070 encode = &obj_context->codec_state.encode;
3071 for (i = 0; i < num_buffers; i++) {
3072 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
3075 return VA_STATUS_ERROR_INVALID_BUFFER;
3077 switch (obj_buffer->type) {
3078 case VAQMatrixBufferType:
3079 vaStatus = I965_RENDER_ENCODE_BUFFER(qmatrix);
3082 case VAIQMatrixBufferType:
3083 vaStatus = I965_RENDER_ENCODE_BUFFER(iqmatrix);
3086 case VAEncSequenceParameterBufferType:
3087 vaStatus = I965_RENDER_ENCODE_BUFFER(sequence_parameter_ext);
3090 case VAEncPictureParameterBufferType:
3091 vaStatus = I965_RENDER_ENCODE_BUFFER(picture_parameter_ext);
3094 case VAHuffmanTableBufferType:
3095 vaStatus = I965_RENDER_ENCODE_BUFFER(huffman_table);
3098 case VAEncSliceParameterBufferType:
3099 vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
3100 if (vaStatus == VA_STATUS_SUCCESS) {
3101 /* When the max number of slices is updated, it also needs
3102 * to reallocate the arrays that is used to store
3103 * the packed data index/count for the slice
3105 if (!(encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE)) {
3106 encode->slice_index++;
3108 if (encode->slice_index == encode->max_slice_num) {
3109 int slice_num = encode->max_slice_num;
3110 encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
3111 (slice_num + NUM_SLICES) * sizeof(int));
3112 encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
3113 (slice_num + NUM_SLICES) * sizeof(int));
3114 encode->slice_header_index = realloc(encode->slice_header_index,
3115 (slice_num + NUM_SLICES) * sizeof(int));
3116 memset(encode->slice_rawdata_index + slice_num, 0,
3117 sizeof(int) * NUM_SLICES);
3118 memset(encode->slice_rawdata_count + slice_num, 0,
3119 sizeof(int) * NUM_SLICES);
3120 memset(encode->slice_header_index + slice_num, 0,
3121 sizeof(int) * NUM_SLICES);
3123 encode->max_slice_num += NUM_SLICES;
3124 if ((encode->slice_rawdata_index == NULL) ||
3125 (encode->slice_header_index == NULL) ||
3126 (encode->slice_rawdata_count == NULL)) {
3127 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
3134 case VAEncPackedHeaderParameterBufferType:
3136 VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer;
3137 encode->last_packed_header_type = param->type;
3139 if ((param->type == VAEncPackedHeaderRawData) ||
3140 (param->type == VAEncPackedHeaderSlice)) {
3141 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext);
3142 } else if((obj_config->profile == VAProfileHEVCMain) &&
3143 (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
3144 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
3147 va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index);
3149 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
3152 va_enc_packed_type_to_idx(encode->last_packed_header_type));
3157 case VAEncPackedHeaderDataBufferType:
3159 if (encode->last_packed_header_type == 0) {
3160 WARN_ONCE("the packed header data is passed without type!\n");
3161 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
3164 if (encode->last_packed_header_type == VAEncPackedHeaderRawData ||
3165 encode->last_packed_header_type == VAEncPackedHeaderSlice) {
3166 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext);
3168 /* When the PACKED_SLICE_HEADER flag is passed, it will use
3169 * the packed_slice_header as the delimeter to decide how
3170 * the packed rawdata is inserted for the given slice.
3171 * Otherwise it will use the VAEncSequenceParameterBuffer
3174 if (encode->packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) {
3175 /* store the first index of the packed header data for current slice */
3176 if (encode->slice_rawdata_index[encode->slice_index] == 0) {
3177 encode->slice_rawdata_index[encode->slice_index] =
3178 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
3180 encode->slice_rawdata_count[encode->slice_index]++;
3181 if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
3182 /* find one packed slice_header delimeter. And the following
3183 * packed data is for the next slice
3185 encode->slice_header_index[encode->slice_index] =
3186 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
3187 encode->slice_index++;
3188 /* Reallocate the buffer to record the index/count of
3189 * packed_data for one slice.
3191 if (encode->slice_index == encode->max_slice_num) {
3192 int slice_num = encode->max_slice_num;
3194 encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
3195 (slice_num + NUM_SLICES) * sizeof(int));
3196 encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
3197 (slice_num + NUM_SLICES) * sizeof(int));
3198 encode->slice_header_index = realloc(encode->slice_header_index,
3199 (slice_num + NUM_SLICES) * sizeof(int));
3200 memset(encode->slice_rawdata_index + slice_num, 0,
3201 sizeof(int) * NUM_SLICES);
3202 memset(encode->slice_rawdata_count + slice_num, 0,
3203 sizeof(int) * NUM_SLICES);
3204 memset(encode->slice_header_index + slice_num, 0,
3205 sizeof(int) * NUM_SLICES);
3206 encode->max_slice_num += NUM_SLICES;
3210 if (vaStatus == VA_STATUS_SUCCESS) {
3211 /* store the first index of the packed header data for current slice */
3212 if (encode->slice_rawdata_index[encode->slice_index] == 0) {
3213 encode->slice_rawdata_index[encode->slice_index] =
3214 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
3216 encode->slice_rawdata_count[encode->slice_index]++;
3217 if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
3218 if (encode->slice_header_index[encode->slice_index] == 0) {
3219 encode->slice_header_index[encode->slice_index] =
3220 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
3222 WARN_ONCE("Multi slice header data is passed for"
3223 " slice %d!\n", encode->slice_index);
3229 ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
3230 encode->last_packed_header_type == VAEncPackedHeaderPicture ||
3231 encode->last_packed_header_type == VAEncPackedHeaderSlice ||
3232 (((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) &&
3233 ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)),
3234 VA_STATUS_ERROR_ENCODING_ERROR);
3236 if((obj_config->profile == VAProfileHEVCMain) &&
3237 (encode->last_packed_header_type == VAEncPackedHeaderSequence)) {
3239 vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
3242 va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index);
3243 encode->vps_sps_seq_index = (encode->vps_sps_seq_index + 1) % I965_SEQ_PACKED_HEADER_END;
3245 vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
3248 va_enc_packed_type_to_idx(encode->last_packed_header_type));
3252 encode->last_packed_header_type = 0;
3256 case VAEncMiscParameterBufferType:
3257 vaStatus = i965_encoder_render_misc_parameter_buffer(ctx,
3263 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
3271 #define I965_RENDER_PROC_BUFFER(name) I965_RENDER_BUFFER(proc, name)
3273 #define DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(proc, name, member)
3274 DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(pipeline_parameter, pipeline_param)
3277 i965_proc_render_picture(VADriverContextP ctx,
3278 VAContextID context,
3279 VABufferID *buffers,
3282 struct i965_driver_data *i965 = i965_driver_data(ctx);
3283 struct object_context *obj_context = CONTEXT(context);
3284 VAStatus vaStatus = VA_STATUS_SUCCESS;
3287 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
3289 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
3290 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
3293 return VA_STATUS_ERROR_INVALID_BUFFER;
3295 switch (obj_buffer->type) {
3296 case VAProcPipelineParameterBufferType:
3297 vaStatus = I965_RENDER_PROC_BUFFER(pipeline_parameter);
3301 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
3310 i965_RenderPicture(VADriverContextP ctx,
3311 VAContextID context,
3312 VABufferID *buffers,
3315 struct i965_driver_data *i965 = i965_driver_data(ctx);
3316 struct object_context *obj_context;
3317 struct object_config *obj_config;
3318 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
3320 obj_context = CONTEXT(context);
3321 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
3323 if (num_buffers <= 0)
3324 return VA_STATUS_ERROR_INVALID_PARAMETER;
3326 obj_config = obj_context->obj_config;
3327 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
3329 if (VAEntrypointVideoProc == obj_config->entrypoint) {
3330 vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
3331 } else if ((VAEntrypointEncSlice == obj_config->entrypoint ) ||
3332 (VAEntrypointEncPicture == obj_config->entrypoint)) {
3333 vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
3335 vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
3342 i965_EndPicture(VADriverContextP ctx, VAContextID context)
3344 struct i965_driver_data *i965 = i965_driver_data(ctx);
3345 struct object_context *obj_context = CONTEXT(context);
3346 struct object_config *obj_config;
3348 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
3349 obj_config = obj_context->obj_config;
3350 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
3352 if (obj_context->codec_type == CODEC_PROC) {
3353 ASSERT_RET(VAEntrypointVideoProc == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
3354 } else if (obj_context->codec_type == CODEC_ENC) {
3355 ASSERT_RET(((VAEntrypointEncSlice == obj_config->entrypoint) || (VAEntrypointEncPicture == obj_config->entrypoint)), VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
3357 if (obj_context->codec_state.encode.num_packed_header_params_ext !=
3358 obj_context->codec_state.encode.num_packed_header_data_ext) {
3359 WARN_ONCE("the packed header/data is not paired for encoding!\n");
3360 return VA_STATUS_ERROR_INVALID_PARAMETER;
3362 if (!(obj_context->codec_state.encode.pic_param ||
3363 obj_context->codec_state.encode.pic_param_ext)) {
3364 return VA_STATUS_ERROR_INVALID_PARAMETER;
3366 if (!(obj_context->codec_state.encode.seq_param ||
3367 obj_context->codec_state.encode.seq_param_ext) &&
3368 (VAEntrypointEncPicture != obj_config->entrypoint)) {
3369 return VA_STATUS_ERROR_INVALID_PARAMETER;
3371 if ((obj_context->codec_state.encode.num_slice_params <=0) &&
3372 (obj_context->codec_state.encode.num_slice_params_ext <=0) &&
3373 (obj_config->profile != VAProfileVP8Version0_3)) {
3374 return VA_STATUS_ERROR_INVALID_PARAMETER;
3377 if ((obj_context->codec_state.encode.packed_header_flag & VA_ENC_PACKED_HEADER_SLICE) &&
3378 (obj_context->codec_state.encode.num_slice_params_ext !=
3379 obj_context->codec_state.encode.slice_index)) {
3380 WARN_ONCE("packed slice_header data is missing for some slice"
3381 " under packed SLICE_HEADER mode\n");
3382 return VA_STATUS_ERROR_INVALID_PARAMETER;
3385 if (obj_context->codec_state.decode.pic_param == NULL) {
3386 return VA_STATUS_ERROR_INVALID_PARAMETER;
3388 if (obj_context->codec_state.decode.num_slice_params <=0) {
3389 return VA_STATUS_ERROR_INVALID_PARAMETER;
3391 if (obj_context->codec_state.decode.num_slice_datas <=0) {
3392 return VA_STATUS_ERROR_INVALID_PARAMETER;
3395 if (obj_context->codec_state.decode.num_slice_params !=
3396 obj_context->codec_state.decode.num_slice_datas) {
3397 return VA_STATUS_ERROR_INVALID_PARAMETER;
3400 if (obj_context->wrapper_context != VA_INVALID_ID) {
3401 /* call the vaEndPicture of wrapped driver */
3402 VADriverContextP pdrvctx;
3405 pdrvctx = i965->wrapper_pdrvctx;
3406 CALL_VTABLE(pdrvctx, va_status,
3407 vaEndPicture(pdrvctx, obj_context->wrapper_context));
3413 ASSERT_RET(obj_context->hw_context->run, VA_STATUS_ERROR_OPERATION_FAILED);
3414 return obj_context->hw_context->run(ctx, obj_config->profile, &obj_context->codec_state, obj_context->hw_context);
3418 i965_SyncSurface(VADriverContextP ctx,
3419 VASurfaceID render_target)
3421 struct i965_driver_data *i965 = i965_driver_data(ctx);
3422 struct object_surface *obj_surface = SURFACE(render_target);
3424 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
3427 drm_intel_bo_wait_rendering(obj_surface->bo);
3429 return VA_STATUS_SUCCESS;
3433 i965_QuerySurfaceStatus(VADriverContextP ctx,
3434 VASurfaceID render_target,
3435 VASurfaceStatus *status) /* out */
3437 struct i965_driver_data *i965 = i965_driver_data(ctx);
3438 struct object_surface *obj_surface = SURFACE(render_target);
3440 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
3442 if (obj_surface->bo) {
3443 if (drm_intel_bo_busy(obj_surface->bo)){
3444 *status = VASurfaceRendering;
3447 *status = VASurfaceReady;
3450 *status = VASurfaceReady;
3453 return VA_STATUS_SUCCESS;
3456 static VADisplayAttribute *
3457 get_display_attribute(VADriverContextP ctx, VADisplayAttribType type)
3459 struct i965_driver_data * const i965 = i965_driver_data(ctx);
3462 if (!i965->display_attributes)
3465 for (i = 0; i < i965->num_display_attributes; i++) {
3466 if (i965->display_attributes[i].type == type)
3467 return &i965->display_attributes[i];
3473 i965_display_attributes_terminate(VADriverContextP ctx)
3475 struct i965_driver_data * const i965 = i965_driver_data(ctx);
3477 if (i965->display_attributes) {
3478 free(i965->display_attributes);
3479 i965->display_attributes = NULL;
3480 i965->num_display_attributes = 0;
3485 i965_display_attributes_init(VADriverContextP ctx)
3487 struct i965_driver_data * const i965 = i965_driver_data(ctx);
3489 i965->num_display_attributes = ARRAY_ELEMS(i965_display_attributes);
3490 i965->display_attributes = malloc(
3491 i965->num_display_attributes * sizeof(i965->display_attributes[0]));
3492 if (!i965->display_attributes)
3496 i965->display_attributes,
3497 i965_display_attributes,
3498 sizeof(i965_display_attributes)
3501 i965->rotation_attrib = get_display_attribute(ctx, VADisplayAttribRotation);
3502 i965->brightness_attrib = get_display_attribute(ctx, VADisplayAttribBrightness);
3503 i965->contrast_attrib = get_display_attribute(ctx, VADisplayAttribContrast);
3504 i965->hue_attrib = get_display_attribute(ctx, VADisplayAttribHue);
3505 i965->saturation_attrib = get_display_attribute(ctx, VADisplayAttribSaturation);
3507 if (!i965->rotation_attrib ||
3508 !i965->brightness_attrib ||
3509 !i965->contrast_attrib ||
3510 !i965->hue_attrib ||
3511 !i965->saturation_attrib) {
3517 i965_display_attributes_terminate(ctx);
3522 * Query display attributes
3523 * The caller must provide a "attr_list" array that can hold at
3524 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
3525 * returned in "attr_list" is returned in "num_attributes".
3528 i965_QueryDisplayAttributes(
3529 VADriverContextP ctx,
3530 VADisplayAttribute *attribs, /* out */
3531 int *num_attribs_ptr /* out */
3534 const int num_attribs = ARRAY_ELEMS(i965_display_attributes);
3536 if (attribs && num_attribs > 0)
3537 memcpy(attribs, i965_display_attributes, sizeof(i965_display_attributes));
3539 if (num_attribs_ptr)
3540 *num_attribs_ptr = num_attribs;
3542 return VA_STATUS_SUCCESS;
3546 * Get display attributes
3547 * This function returns the current attribute values in "attr_list".
3548 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
3549 * from vaQueryDisplayAttributes() can have their values retrieved.
3552 i965_GetDisplayAttributes(
3553 VADriverContextP ctx,
3554 VADisplayAttribute *attribs, /* inout */
3555 int num_attribs /* in */
3560 for (i = 0; i < num_attribs; i++) {
3561 VADisplayAttribute *src_attrib, * const dst_attrib = &attribs[i];
3563 src_attrib = get_display_attribute(ctx, dst_attrib->type);
3564 if (src_attrib && (src_attrib->flags & VA_DISPLAY_ATTRIB_GETTABLE)) {
3565 dst_attrib->min_value = src_attrib->min_value;
3566 dst_attrib->max_value = src_attrib->max_value;
3567 dst_attrib->value = src_attrib->value;
3570 dst_attrib->flags = VA_DISPLAY_ATTRIB_NOT_SUPPORTED;
3572 return VA_STATUS_SUCCESS;
3576 * Set display attributes
3577 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
3578 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
3579 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
3582 i965_SetDisplayAttributes(
3583 VADriverContextP ctx,
3584 VADisplayAttribute *attribs, /* in */
3585 int num_attribs /* in */
3590 for (i = 0; i < num_attribs; i++) {
3591 VADisplayAttribute *dst_attrib, * const src_attrib = &attribs[i];
3593 dst_attrib = get_display_attribute(ctx, src_attrib->type);
3595 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
3597 if (!(dst_attrib->flags & VA_DISPLAY_ATTRIB_SETTABLE))
3600 if (src_attrib->value < dst_attrib->min_value ||
3601 src_attrib->value > dst_attrib->max_value)
3602 return VA_STATUS_ERROR_INVALID_PARAMETER;
3604 dst_attrib->value = src_attrib->value;
3605 /* XXX: track modified attributes through timestamps */
3607 return VA_STATUS_SUCCESS;
3611 i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
3612 VASurfaceID surface,
3613 void **buffer, /* out */
3614 unsigned int *stride) /* out */
3617 return VA_STATUS_ERROR_UNIMPLEMENTED;
3621 i965_destroy_heap(struct object_heap *heap,
3622 void (*func)(struct object_heap *heap, struct object_base *object))
3624 struct object_base *object;
3625 object_heap_iterator iter;
3627 object = object_heap_first(heap, &iter);
3633 object = object_heap_next(heap, &iter);
3636 object_heap_destroy(heap);
3641 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
3644 i965_CreateImage(VADriverContextP ctx,
3645 VAImageFormat *format,
3648 VAImage *out_image) /* out */
3650 struct i965_driver_data *i965 = i965_driver_data(ctx);
3651 struct object_image *obj_image;
3652 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3654 unsigned int size2, size, awidth, aheight;
3656 out_image->image_id = VA_INVALID_ID;
3657 out_image->buf = VA_INVALID_ID;
3659 image_id = NEW_IMAGE_ID();
3660 if (image_id == VA_INVALID_ID)
3661 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3663 obj_image = IMAGE(image_id);
3665 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3666 obj_image->bo = NULL;
3667 obj_image->palette = NULL;
3668 obj_image->derived_surface = VA_INVALID_ID;
3670 VAImage * const image = &obj_image->image;
3671 image->image_id = image_id;
3672 image->buf = VA_INVALID_ID;
3674 awidth = ALIGN(width, i965->codec_info->min_linear_wpitch);
3676 if ((format->fourcc == VA_FOURCC_YV12) ||
3677 (format->fourcc == VA_FOURCC_I420)) {
3678 if (awidth % 128 != 0) {
3679 awidth = ALIGN(width, 128);
3683 aheight = ALIGN(height, i965->codec_info->min_linear_hpitch);
3684 size = awidth * aheight;
3685 size2 = (awidth / 2) * (aheight / 2);
3687 image->num_palette_entries = 0;
3688 image->entry_bytes = 0;
3689 memset(image->component_order, 0, sizeof(image->component_order));
3691 switch (format->fourcc) {
3692 case VA_FOURCC_IA44:
3693 case VA_FOURCC_AI44:
3694 image->num_planes = 1;
3695 image->pitches[0] = awidth;
3696 image->offsets[0] = 0;
3697 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
3698 image->num_palette_entries = 16;
3699 image->entry_bytes = 3;
3700 image->component_order[0] = 'R';
3701 image->component_order[1] = 'G';
3702 image->component_order[2] = 'B';
3704 case VA_FOURCC_IA88:
3705 case VA_FOURCC_AI88:
3706 image->num_planes = 1;
3707 image->pitches[0] = awidth * 2;
3708 image->offsets[0] = 0;
3709 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
3710 image->num_palette_entries = 256;
3711 image->entry_bytes = 3;
3712 image->component_order[0] = 'R';
3713 image->component_order[1] = 'G';
3714 image->component_order[2] = 'B';
3716 case VA_FOURCC_ARGB:
3717 case VA_FOURCC_ABGR:
3718 case VA_FOURCC_BGRA:
3719 case VA_FOURCC_RGBA:
3720 case VA_FOURCC_BGRX:
3721 case VA_FOURCC_RGBX:
3722 image->num_planes = 1;
3723 image->pitches[0] = awidth * 4;
3724 image->offsets[0] = 0;
3725 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
3727 case VA_FOURCC_YV12:
3728 image->num_planes = 3;
3729 image->pitches[0] = awidth;
3730 image->offsets[0] = 0;
3731 image->pitches[1] = awidth / 2;
3732 image->offsets[1] = size;
3733 image->pitches[2] = awidth / 2;
3734 image->offsets[2] = size + size2;
3735 image->data_size = size + 2 * size2;
3737 case VA_FOURCC_I420:
3738 image->num_planes = 3;
3739 image->pitches[0] = awidth;
3740 image->offsets[0] = 0;
3741 image->pitches[1] = awidth / 2;
3742 image->offsets[1] = size;
3743 image->pitches[2] = awidth / 2;
3744 image->offsets[2] = size + size2;
3745 image->data_size = size + 2 * size2;
3747 case VA_FOURCC_422H:
3748 image->num_planes = 3;
3749 image->pitches[0] = awidth;
3750 image->offsets[0] = 0;
3751 image->pitches[1] = awidth / 2;
3752 image->offsets[1] = size;
3753 image->pitches[2] = awidth / 2;
3754 image->offsets[2] = size + (awidth / 2) * aheight;
3755 image->data_size = size + 2 * ((awidth / 2) * aheight);
3757 case VA_FOURCC_NV12:
3758 image->num_planes = 2;
3759 image->pitches[0] = awidth;
3760 image->offsets[0] = 0;
3761 image->pitches[1] = awidth;
3762 image->offsets[1] = size;
3763 image->data_size = size + 2 * size2;
3765 case VA_FOURCC_YUY2:
3766 case VA_FOURCC_UYVY:
3767 image->num_planes = 1;
3768 image->pitches[0] = awidth * 2;
3769 image->offsets[0] = 0;
3770 image->data_size = size * 2;
3772 case VA_FOURCC_P010:
3773 image->num_planes = 2;
3774 image->pitches[0] = awidth * 2;
3775 image->offsets[0] = 0;
3776 image->pitches[1] = awidth * 2;
3777 image->offsets[1] = size * 2;
3778 image->data_size = size * 2 + 2 * size2 * 2;
3784 va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
3785 image->data_size, 1, NULL, &image->buf);
3786 if (va_status != VA_STATUS_SUCCESS)
3789 struct object_buffer *obj_buffer = BUFFER(image->buf);
3792 !obj_buffer->buffer_store ||
3793 !obj_buffer->buffer_store->bo)
3794 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3796 obj_image->bo = obj_buffer->buffer_store->bo;
3797 dri_bo_reference(obj_image->bo);
3799 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
3800 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
3801 if (!obj_image->palette)
3805 image->image_id = image_id;
3806 image->format = *format;
3807 image->width = width;
3808 image->height = height;
3810 *out_image = *image;
3811 return VA_STATUS_SUCCESS;
3814 i965_DestroyImage(ctx, image_id);
3819 i965_check_alloc_surface_bo(VADriverContextP ctx,
3820 struct object_surface *obj_surface,
3822 unsigned int fourcc,
3823 unsigned int subsampling)
3825 struct i965_driver_data *i965 = i965_driver_data(ctx);
3826 int region_width, region_height;
3828 if (obj_surface->bo) {
3829 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3830 ASSERT_RET(obj_surface->fourcc == fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3831 ASSERT_RET(obj_surface->subsampling == subsampling, VA_STATUS_ERROR_INVALID_SURFACE);
3832 return VA_STATUS_SUCCESS;
3835 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
3836 obj_surface->x_cr_offset = 0;
3838 int bpp_1stplane = bpp_1stplane_by_fourcc(fourcc);
3840 if ((tiled && !obj_surface->user_disable_tiling)) {
3841 ASSERT_RET(fourcc != VA_FOURCC_I420 &&
3842 fourcc != VA_FOURCC_IYUV &&
3843 fourcc != VA_FOURCC_YV12,
3844 VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3846 if (obj_surface->user_h_stride_set) {
3847 ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
3849 obj_surface->width = ALIGN(obj_surface->orig_width * bpp_1stplane, 128);
3851 if (obj_surface->user_v_stride_set) {
3852 ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
3854 obj_surface->height = ALIGN(obj_surface->orig_height, 32);
3856 region_height = obj_surface->height;
3859 case VA_FOURCC_NV12:
3860 case VA_FOURCC_P010:
3861 assert(subsampling == SUBSAMPLE_YUV420);
3862 obj_surface->cb_cr_pitch = obj_surface->width;
3863 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3864 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3865 obj_surface->y_cb_offset = obj_surface->height;
3866 obj_surface->y_cr_offset = obj_surface->height;
3867 region_width = obj_surface->width;
3868 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
3872 case VA_FOURCC_IMC1:
3873 assert(subsampling == SUBSAMPLE_YUV420);
3874 obj_surface->cb_cr_pitch = obj_surface->width;
3875 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3876 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3877 obj_surface->y_cr_offset = obj_surface->height;
3878 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32);
3879 region_width = obj_surface->width;
3880 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3884 case VA_FOURCC_IMC3:
3885 assert(subsampling == SUBSAMPLE_YUV420);
3886 obj_surface->cb_cr_pitch = obj_surface->width;
3887 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3888 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3889 obj_surface->y_cb_offset = obj_surface->height;
3890 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3891 region_width = obj_surface->width;
3892 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3896 case VA_FOURCC_422H:
3897 assert(subsampling == SUBSAMPLE_YUV422H);
3898 obj_surface->cb_cr_pitch = obj_surface->width;
3899 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3900 obj_surface->cb_cr_height = obj_surface->orig_height;
3901 obj_surface->y_cb_offset = obj_surface->height;
3902 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3903 region_width = obj_surface->width;
3904 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3908 case VA_FOURCC_422V:
3909 assert(subsampling == SUBSAMPLE_YUV422V);
3910 obj_surface->cb_cr_pitch = obj_surface->width;
3911 obj_surface->cb_cr_width = obj_surface->orig_width;
3912 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3913 obj_surface->y_cb_offset = obj_surface->height;
3914 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3915 region_width = obj_surface->width;
3916 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3920 case VA_FOURCC_411P:
3921 assert(subsampling == SUBSAMPLE_YUV411);
3922 obj_surface->cb_cr_pitch = obj_surface->width;
3923 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
3924 obj_surface->cb_cr_height = obj_surface->orig_height;
3925 obj_surface->y_cb_offset = obj_surface->height;
3926 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3927 region_width = obj_surface->width;
3928 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3932 case VA_FOURCC_444P:
3933 assert(subsampling == SUBSAMPLE_YUV444);
3934 obj_surface->cb_cr_pitch = obj_surface->width;
3935 obj_surface->cb_cr_width = obj_surface->orig_width;
3936 obj_surface->cb_cr_height = obj_surface->orig_height;
3937 obj_surface->y_cb_offset = obj_surface->height;
3938 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3939 region_width = obj_surface->width;
3940 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3944 case VA_FOURCC_Y800:
3945 assert(subsampling == SUBSAMPLE_YUV400);
3946 obj_surface->cb_cr_pitch = 0;
3947 obj_surface->cb_cr_width = 0;
3948 obj_surface->cb_cr_height = 0;
3949 obj_surface->y_cb_offset = 0;
3950 obj_surface->y_cr_offset = 0;
3951 region_width = obj_surface->width;
3952 region_height = obj_surface->height;
3956 case VA_FOURCC_YUY2:
3957 case VA_FOURCC_UYVY:
3958 assert(subsampling == SUBSAMPLE_YUV422H);
3959 obj_surface->width = ALIGN(obj_surface->orig_width * 2, 128);
3960 obj_surface->cb_cr_pitch = obj_surface->width;
3961 obj_surface->y_cb_offset = 0;
3962 obj_surface->y_cr_offset = 0;
3963 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3964 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3965 region_width = obj_surface->width;
3966 region_height = obj_surface->height;
3970 case VA_FOURCC_RGBA:
3971 case VA_FOURCC_RGBX:
3972 case VA_FOURCC_BGRA:
3973 case VA_FOURCC_BGRX:
3974 assert(subsampling == SUBSAMPLE_RGBX);
3976 obj_surface->width = ALIGN(obj_surface->orig_width * 4, 128);
3977 region_width = obj_surface->width;
3978 region_height = obj_surface->height;
3982 /* Never get here */
3983 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3987 assert(subsampling == SUBSAMPLE_YUV420 ||
3988 subsampling == SUBSAMPLE_YUV422H ||
3989 subsampling == SUBSAMPLE_YUV422V ||
3990 subsampling == SUBSAMPLE_RGBX);
3992 region_width = obj_surface->width;
3993 region_height = obj_surface->height;
3996 case VA_FOURCC_NV12:
3997 case VA_FOURCC_P010:
3998 obj_surface->y_cb_offset = obj_surface->height;
3999 obj_surface->y_cr_offset = obj_surface->height;
4000 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4001 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
4002 obj_surface->cb_cr_pitch = obj_surface->width;
4003 region_height = obj_surface->height + obj_surface->height / 2;
4006 case VA_FOURCC_YV16:
4007 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4008 obj_surface->cb_cr_height = obj_surface->orig_height;
4009 obj_surface->y_cr_offset = obj_surface->height;
4010 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32) / 2;
4011 obj_surface->cb_cr_pitch = obj_surface->width / 2;
4012 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
4015 case VA_FOURCC_YV12:
4016 case VA_FOURCC_I420:
4017 if (fourcc == VA_FOURCC_YV12) {
4018 obj_surface->y_cr_offset = obj_surface->height;
4019 obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4;
4021 obj_surface->y_cb_offset = obj_surface->height;
4022 obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
4025 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4026 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
4027 obj_surface->cb_cr_pitch = obj_surface->width / 2;
4028 region_height = obj_surface->height + obj_surface->height / 2;
4031 case VA_FOURCC_YUY2:
4032 case VA_FOURCC_UYVY:
4033 obj_surface->width = ALIGN(obj_surface->orig_width * 2, i965->codec_info->min_linear_wpitch);
4034 obj_surface->y_cb_offset = 0;
4035 obj_surface->y_cr_offset = 0;
4036 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
4037 obj_surface->cb_cr_height = obj_surface->orig_height;
4038 obj_surface->cb_cr_pitch = obj_surface->width;
4039 region_width = obj_surface->width;
4040 region_height = obj_surface->height;
4042 case VA_FOURCC_RGBA:
4043 case VA_FOURCC_RGBX:
4044 case VA_FOURCC_BGRA:
4045 case VA_FOURCC_BGRX:
4046 obj_surface->width = ALIGN(obj_surface->orig_width * 4, i965->codec_info->min_linear_wpitch);
4047 region_width = obj_surface->width;
4048 region_height = obj_surface->height;
4052 /* Never get here */
4053 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
4058 obj_surface->size = ALIGN(region_width * region_height, 0x1000);
4060 if ((tiled && !obj_surface->user_disable_tiling)) {
4061 uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
4062 unsigned long pitch;
4064 obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr,
4072 assert(tiling_mode == I915_TILING_Y);
4073 assert(pitch == obj_surface->width);
4075 obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
4081 obj_surface->fourcc = fourcc;
4082 obj_surface->subsampling = subsampling;
4083 assert(obj_surface->bo);
4084 return VA_STATUS_SUCCESS;
4087 VAStatus i965_DeriveImage(VADriverContextP ctx,
4088 VASurfaceID surface,
4089 VAImage *out_image) /* out */
4091 struct i965_driver_data *i965 = i965_driver_data(ctx);
4092 struct object_image *obj_image;
4093 struct object_surface *obj_surface;
4095 unsigned int w_pitch;
4096 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
4098 out_image->image_id = VA_INVALID_ID;
4099 obj_surface = SURFACE(surface);
4102 return VA_STATUS_ERROR_INVALID_SURFACE;
4104 if (!obj_surface->bo) {
4105 unsigned int is_tiled = 0;
4106 unsigned int fourcc = VA_FOURCC_YV12;
4107 i965_guess_surface_format(ctx, surface, &fourcc, &is_tiled);
4108 int sampling = get_sampling_from_fourcc(fourcc);
4109 va_status = i965_check_alloc_surface_bo(ctx, obj_surface, is_tiled, fourcc, sampling);
4110 if (va_status != VA_STATUS_SUCCESS)
4114 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4116 w_pitch = obj_surface->width;
4118 image_id = NEW_IMAGE_ID();
4120 if (image_id == VA_INVALID_ID)
4121 return VA_STATUS_ERROR_ALLOCATION_FAILED;
4123 obj_image = IMAGE(image_id);
4126 return VA_STATUS_ERROR_ALLOCATION_FAILED;
4128 obj_image->bo = NULL;
4129 obj_image->palette = NULL;
4130 obj_image->derived_surface = VA_INVALID_ID;
4132 VAImage * const image = &obj_image->image;
4134 memset(image, 0, sizeof(*image));
4135 image->image_id = image_id;
4136 image->buf = VA_INVALID_ID;
4137 image->num_palette_entries = 0;
4138 image->entry_bytes = 0;
4139 image->width = obj_surface->orig_width;
4140 image->height = obj_surface->orig_height;
4141 image->data_size = obj_surface->size;
4143 image->format.fourcc = obj_surface->fourcc;
4144 image->format.byte_order = VA_LSB_FIRST;
4145 image->format.bits_per_pixel = get_bpp_from_fourcc(obj_surface->fourcc);
4147 if (!image->format.bits_per_pixel)
4150 switch (image->format.fourcc) {
4151 case VA_FOURCC_YV12:
4152 image->num_planes = 3;
4153 image->pitches[0] = w_pitch; /* Y */
4154 image->offsets[0] = 0;
4155 image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
4156 image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
4157 image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
4158 image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
4161 case VA_FOURCC_YV16:
4162 image->num_planes = 3;
4163 image->pitches[0] = w_pitch; /* Y */
4164 image->offsets[0] = 0;
4165 image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
4166 image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
4167 image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
4168 image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
4171 case VA_FOURCC_NV12:
4172 case VA_FOURCC_P010:
4173 image->num_planes = 2;
4174 image->pitches[0] = w_pitch; /* Y */
4175 image->offsets[0] = 0;
4176 image->pitches[1] = obj_surface->cb_cr_pitch; /* UV */
4177 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
4180 case VA_FOURCC_I420:
4181 case VA_FOURCC_422H:
4182 case VA_FOURCC_IMC3:
4183 case VA_FOURCC_444P:
4184 case VA_FOURCC_422V:
4185 case VA_FOURCC_411P:
4186 image->num_planes = 3;
4187 image->pitches[0] = w_pitch; /* Y */
4188 image->offsets[0] = 0;
4189 image->pitches[1] = obj_surface->cb_cr_pitch; /* U */
4190 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
4191 image->pitches[2] = obj_surface->cb_cr_pitch; /* V */
4192 image->offsets[2] = w_pitch * obj_surface->y_cr_offset;
4195 case VA_FOURCC_YUY2:
4196 case VA_FOURCC_UYVY:
4197 case VA_FOURCC_Y800:
4198 image->num_planes = 1;
4199 image->pitches[0] = obj_surface->width; /* Y, width is aligned already */
4200 image->offsets[0] = 0;
4202 case VA_FOURCC_RGBA:
4203 case VA_FOURCC_RGBX:
4204 case VA_FOURCC_BGRA:
4205 case VA_FOURCC_BGRX:
4206 image->num_planes = 1;
4207 image->pitches[0] = obj_surface->width;
4209 switch (image->format.fourcc) {
4210 case VA_FOURCC_RGBA:
4211 case VA_FOURCC_RGBX:
4212 image->format.red_mask = 0x000000ff;
4213 image->format.green_mask = 0x0000ff00;
4214 image->format.blue_mask = 0x00ff0000;
4215 image->format.alpha_mask = 0x00000000;
4217 case VA_FOURCC_BGRA:
4218 case VA_FOURCC_BGRX:
4219 image->format.red_mask = 0x00ff0000;
4220 image->format.green_mask = 0x0000ff00;
4221 image->format.blue_mask = 0x000000ff;
4222 image->format.alpha_mask = 0x00000000;
4228 switch (image->format.fourcc) {
4229 case VA_FOURCC_RGBA:
4230 case VA_FOURCC_BGRA:
4231 image->format.depth = 32;
4233 case VA_FOURCC_RGBX:
4234 case VA_FOURCC_BGRX:
4235 image->format.depth = 24;
4246 va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType,
4247 obj_surface->size, 1, NULL, obj_surface->bo, &image->buf);
4248 if (va_status != VA_STATUS_SUCCESS)
4251 struct object_buffer *obj_buffer = BUFFER(image->buf);
4254 !obj_buffer->buffer_store ||
4255 !obj_buffer->buffer_store->bo)
4256 return VA_STATUS_ERROR_ALLOCATION_FAILED;
4258 obj_image->bo = obj_buffer->buffer_store->bo;
4259 dri_bo_reference(obj_image->bo);
4261 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
4262 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
4263 if (!obj_image->palette) {
4264 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
4269 *out_image = *image;
4270 obj_surface->flags |= SURFACE_DERIVED;
4271 obj_surface->derived_image_id = image_id;
4272 obj_image->derived_surface = surface;
4274 return VA_STATUS_SUCCESS;
4277 i965_DestroyImage(ctx, image_id);
4282 i965_destroy_image(struct object_heap *heap, struct object_base *obj)
4284 object_heap_free(heap, obj);
4289 i965_DestroyImage(VADriverContextP ctx, VAImageID image)
4291 struct i965_driver_data *i965 = i965_driver_data(ctx);
4292 struct object_image *obj_image = IMAGE(image);
4293 struct object_surface *obj_surface;
4296 return VA_STATUS_SUCCESS;
4298 dri_bo_unreference(obj_image->bo);
4299 obj_image->bo = NULL;
4301 if (obj_image->image.buf != VA_INVALID_ID) {
4302 i965_DestroyBuffer(ctx, obj_image->image.buf);
4303 obj_image->image.buf = VA_INVALID_ID;
4306 if (obj_image->palette) {
4307 free(obj_image->palette);
4308 obj_image->palette = NULL;
4311 obj_surface = SURFACE(obj_image->derived_surface);
4314 obj_surface->flags &= ~SURFACE_DERIVED;
4315 obj_surface->derived_image_id = VA_INVALID_ID;
4318 i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
4320 return VA_STATUS_SUCCESS;
4324 * pointer to an array holding the palette data. The size of the array is
4325 * num_palette_entries * entry_bytes in size. The order of the components
4326 * in the palette is described by the component_order in VASubpicture struct
4329 i965_SetImagePalette(VADriverContextP ctx,
4331 unsigned char *palette)
4333 struct i965_driver_data *i965 = i965_driver_data(ctx);
4336 struct object_image *obj_image = IMAGE(image);
4338 return VA_STATUS_ERROR_INVALID_IMAGE;
4340 if (!obj_image->palette)
4341 return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
4343 for (i = 0; i < obj_image->image.num_palette_entries; i++)
4344 obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
4345 ((unsigned int)palette[3*i + 1] << 8) |
4346 (unsigned int)palette[3*i + 2]);
4347 return VA_STATUS_SUCCESS;
4351 get_sampling_from_fourcc(unsigned int fourcc)
4353 const i965_fourcc_info *info = get_fourcc_info(fourcc);
4355 if (info && (info->flag & I_S))
4356 return info->subsampling;
4362 memcpy_pic(uint8_t *dst, unsigned int dst_stride,
4363 const uint8_t *src, unsigned int src_stride,
4364 unsigned int len, unsigned int height)
4368 for (i = 0; i < height; i++) {
4369 memcpy(dst, src, len);
4376 get_image_i420(struct object_image *obj_image, uint8_t *image_data,
4377 struct object_surface *obj_surface,
4378 const VARectangle *rect)
4380 uint8_t *dst[3], *src[3];
4382 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
4383 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
4384 unsigned int tiling, swizzle;
4385 VAStatus va_status = VA_STATUS_SUCCESS;
4387 if (!obj_surface->bo)
4388 return VA_STATUS_ERROR_INVALID_SURFACE;
4390 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4391 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4393 if (tiling != I915_TILING_NONE)
4394 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4396 dri_bo_map(obj_surface->bo, 0);
4398 if (!obj_surface->bo->virtual)
4399 return VA_STATUS_ERROR_INVALID_SURFACE;
4401 /* Dest VA image has either I420 or YV12 format.
4402 Source VA surface alway has I420 format */
4403 dst[Y] = image_data + obj_image->image.offsets[Y];
4404 src[0] = (uint8_t *)obj_surface->bo->virtual;
4405 dst[U] = image_data + obj_image->image.offsets[U];
4406 src[1] = src[0] + obj_surface->width * obj_surface->height;
4407 dst[V] = image_data + obj_image->image.offsets[V];
4408 src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
4411 dst[Y] += rect->y * obj_image->image.pitches[Y] + rect->x;
4412 src[0] += rect->y * obj_surface->width + rect->x;
4413 memcpy_pic(dst[Y], obj_image->image.pitches[Y],
4414 src[0], obj_surface->width,
4415 rect->width, rect->height);
4418 dst[U] += (rect->y / 2) * obj_image->image.pitches[U] + rect->x / 2;
4419 src[1] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
4420 memcpy_pic(dst[U], obj_image->image.pitches[U],
4421 src[1], obj_surface->width / 2,
4422 rect->width / 2, rect->height / 2);
4425 dst[V] += (rect->y / 2) * obj_image->image.pitches[V] + rect->x / 2;
4426 src[2] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
4427 memcpy_pic(dst[V], obj_image->image.pitches[V],
4428 src[2], obj_surface->width / 2,
4429 rect->width / 2, rect->height / 2);
4431 if (tiling != I915_TILING_NONE)
4432 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4434 dri_bo_unmap(obj_surface->bo);
4440 get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
4441 struct object_surface *obj_surface,
4442 const VARectangle *rect)
4444 uint8_t *dst[2], *src[2];
4445 unsigned int tiling, swizzle;
4446 VAStatus va_status = VA_STATUS_SUCCESS;
4448 if (!obj_surface->bo)
4449 return VA_STATUS_ERROR_INVALID_SURFACE;
4451 assert(obj_surface->fourcc);
4452 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4454 if (tiling != I915_TILING_NONE)
4455 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4457 dri_bo_map(obj_surface->bo, 0);
4459 if (!obj_surface->bo->virtual)
4460 return VA_STATUS_ERROR_INVALID_SURFACE;
4462 /* Both dest VA image and source surface have NV12 format */
4463 dst[0] = image_data + obj_image->image.offsets[0];
4464 src[0] = (uint8_t *)obj_surface->bo->virtual;
4465 dst[1] = image_data + obj_image->image.offsets[1];
4466 src[1] = src[0] + obj_surface->width * obj_surface->height;
4469 dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
4470 src[0] += rect->y * obj_surface->width + rect->x;
4471 memcpy_pic(dst[0], obj_image->image.pitches[0],
4472 src[0], obj_surface->width,
4473 rect->width, rect->height);
4476 dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + (rect->x & -2);
4477 src[1] += (rect->y / 2) * obj_surface->width + (rect->x & -2);
4478 memcpy_pic(dst[1], obj_image->image.pitches[1],
4479 src[1], obj_surface->width,
4480 rect->width, rect->height / 2);
4482 if (tiling != I915_TILING_NONE)
4483 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4485 dri_bo_unmap(obj_surface->bo);
4491 get_image_yuy2(struct object_image *obj_image, uint8_t *image_data,
4492 struct object_surface *obj_surface,
4493 const VARectangle *rect)
4496 unsigned int tiling, swizzle;
4497 VAStatus va_status = VA_STATUS_SUCCESS;
4499 if (!obj_surface->bo)
4500 return VA_STATUS_ERROR_INVALID_SURFACE;
4502 assert(obj_surface->fourcc);
4503 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4505 if (tiling != I915_TILING_NONE)
4506 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4508 dri_bo_map(obj_surface->bo, 0);
4510 if (!obj_surface->bo->virtual)
4511 return VA_STATUS_ERROR_INVALID_SURFACE;
4513 /* Both dest VA image and source surface have YUYV format */
4514 dst = image_data + obj_image->image.offsets[0];
4515 src = (uint8_t *)obj_surface->bo->virtual;
4518 dst += rect->y * obj_image->image.pitches[0] + rect->x*2;
4519 src += rect->y * obj_surface->width + rect->x*2;
4520 memcpy_pic(dst, obj_image->image.pitches[0],
4521 src, obj_surface->width*2,
4522 rect->width*2, rect->height);
4524 if (tiling != I915_TILING_NONE)
4525 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4527 dri_bo_unmap(obj_surface->bo);
4533 i965_sw_getimage(VADriverContextP ctx,
4534 struct object_surface *obj_surface, struct object_image *obj_image,
4535 const VARectangle *rect)
4537 void *image_data = NULL;
4540 if (obj_surface->fourcc != obj_image->image.format.fourcc)
4541 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
4543 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
4544 if (va_status != VA_STATUS_SUCCESS)
4547 switch (obj_image->image.format.fourcc) {
4548 case VA_FOURCC_YV12:
4549 case VA_FOURCC_I420:
4550 get_image_i420(obj_image, image_data, obj_surface, rect);
4552 case VA_FOURCC_NV12:
4553 get_image_nv12(obj_image, image_data, obj_surface, rect);
4555 case VA_FOURCC_YUY2:
4556 /* YUY2 is the format supported by overlay plane */
4557 get_image_yuy2(obj_image, image_data, obj_surface, rect);
4560 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
4563 if (va_status != VA_STATUS_SUCCESS)
4566 va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
4571 i965_hw_getimage(VADriverContextP ctx,
4572 struct object_surface *obj_surface, struct object_image *obj_image,
4573 const VARectangle *rect)
4575 struct i965_surface src_surface;
4576 struct i965_surface dst_surface;
4578 src_surface.base = (struct object_base *)obj_surface;
4579 src_surface.type = I965_SURFACE_TYPE_SURFACE;
4580 src_surface.flags = I965_SURFACE_FLAG_FRAME;
4582 dst_surface.base = (struct object_base *)obj_image;
4583 dst_surface.type = I965_SURFACE_TYPE_IMAGE;
4584 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4586 return i965_image_processing(ctx, &src_surface, rect, &dst_surface, rect);
4590 i965_GetImage(VADriverContextP ctx,
4591 VASurfaceID surface,
4592 int x, /* coordinates of the upper left source pixel */
4594 unsigned int width, /* width and height of the region */
4595 unsigned int height,
4598 struct i965_driver_data * const i965 = i965_driver_data(ctx);
4599 struct object_surface * const obj_surface = SURFACE(surface);
4600 struct object_image * const obj_image = IMAGE(image);
4605 return VA_STATUS_ERROR_INVALID_SURFACE;
4606 if (!obj_surface->bo) /* don't get anything, keep previous data */
4607 return VA_STATUS_SUCCESS;
4608 if (is_surface_busy(i965, obj_surface))
4609 return VA_STATUS_ERROR_SURFACE_BUSY;
4611 if (!obj_image || !obj_image->bo)
4612 return VA_STATUS_ERROR_INVALID_IMAGE;
4613 if (is_image_busy(i965, obj_image, surface))
4614 return VA_STATUS_ERROR_SURFACE_BUSY;
4617 return VA_STATUS_ERROR_INVALID_PARAMETER;
4618 if (x + width > obj_surface->orig_width ||
4619 y + height > obj_surface->orig_height)
4620 return VA_STATUS_ERROR_INVALID_PARAMETER;
4621 if (x + width > obj_image->image.width ||
4622 y + height > obj_image->image.height)
4623 return VA_STATUS_ERROR_INVALID_PARAMETER;
4628 rect.height = height;
4630 if (HAS_ACCELERATED_GETIMAGE(i965))
4631 va_status = i965_hw_getimage(ctx, obj_surface, obj_image, &rect);
4633 va_status = i965_sw_getimage(ctx, obj_surface, obj_image, &rect);
4639 put_image_i420(struct object_surface *obj_surface,
4640 const VARectangle *dst_rect,
4641 struct object_image *obj_image, uint8_t *image_data,
4642 const VARectangle *src_rect)
4644 uint8_t *dst[3], *src[3];
4646 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
4647 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
4648 unsigned int tiling, swizzle;
4649 VAStatus va_status = VA_STATUS_SUCCESS;
4651 ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
4653 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4654 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
4655 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
4656 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4658 if (tiling != I915_TILING_NONE)
4659 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4661 dri_bo_map(obj_surface->bo, 0);
4663 if (!obj_surface->bo->virtual)
4664 return VA_STATUS_ERROR_INVALID_SURFACE;
4666 /* Dest VA image has either I420 or YV12 format.
4667 Source VA surface alway has I420 format */
4668 dst[0] = (uint8_t *)obj_surface->bo->virtual;
4669 src[Y] = image_data + obj_image->image.offsets[Y];
4670 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
4671 src[U] = image_data + obj_image->image.offsets[U];
4672 dst[2] = dst[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
4673 src[V] = image_data + obj_image->image.offsets[V];
4676 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
4677 src[Y] += src_rect->y * obj_image->image.pitches[Y] + src_rect->x;
4678 memcpy_pic(dst[0], obj_surface->width,
4679 src[Y], obj_image->image.pitches[Y],
4680 src_rect->width, src_rect->height);
4683 dst[1] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
4684 src[U] += (src_rect->y / 2) * obj_image->image.pitches[U] + src_rect->x / 2;
4685 memcpy_pic(dst[1], obj_surface->width / 2,
4686 src[U], obj_image->image.pitches[U],
4687 src_rect->width / 2, src_rect->height / 2);
4690 dst[2] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
4691 src[V] += (src_rect->y / 2) * obj_image->image.pitches[V] + src_rect->x / 2;
4692 memcpy_pic(dst[2], obj_surface->width / 2,
4693 src[V], obj_image->image.pitches[V],
4694 src_rect->width / 2, src_rect->height / 2);
4696 if (tiling != I915_TILING_NONE)
4697 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4699 dri_bo_unmap(obj_surface->bo);
4705 put_image_nv12(struct object_surface *obj_surface,
4706 const VARectangle *dst_rect,
4707 struct object_image *obj_image, uint8_t *image_data,
4708 const VARectangle *src_rect)
4710 uint8_t *dst[2], *src[2];
4711 unsigned int tiling, swizzle;
4712 VAStatus va_status = VA_STATUS_SUCCESS;
4714 if (!obj_surface->bo)
4715 return VA_STATUS_ERROR_INVALID_SURFACE;
4717 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4718 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
4719 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
4720 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4722 if (tiling != I915_TILING_NONE)
4723 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4725 dri_bo_map(obj_surface->bo, 0);
4727 if (!obj_surface->bo->virtual)
4728 return VA_STATUS_ERROR_INVALID_SURFACE;
4730 /* Both dest VA image and source surface have NV12 format */
4731 dst[0] = (uint8_t *)obj_surface->bo->virtual;
4732 src[0] = image_data + obj_image->image.offsets[0];
4733 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
4734 src[1] = image_data + obj_image->image.offsets[1];
4737 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
4738 src[0] += src_rect->y * obj_image->image.pitches[0] + src_rect->x;
4739 memcpy_pic(dst[0], obj_surface->width,
4740 src[0], obj_image->image.pitches[0],
4741 src_rect->width, src_rect->height);
4744 dst[1] += (dst_rect->y / 2) * obj_surface->width + (dst_rect->x & -2);
4745 src[1] += (src_rect->y / 2) * obj_image->image.pitches[1] + (src_rect->x & -2);
4746 memcpy_pic(dst[1], obj_surface->width,
4747 src[1], obj_image->image.pitches[1],
4748 src_rect->width, src_rect->height / 2);
4750 if (tiling != I915_TILING_NONE)
4751 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4753 dri_bo_unmap(obj_surface->bo);
4759 put_image_yuy2(struct object_surface *obj_surface,
4760 const VARectangle *dst_rect,
4761 struct object_image *obj_image, uint8_t *image_data,
4762 const VARectangle *src_rect)
4765 unsigned int tiling, swizzle;
4766 VAStatus va_status = VA_STATUS_SUCCESS;
4768 ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
4769 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4770 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
4771 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
4772 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4774 if (tiling != I915_TILING_NONE)
4775 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4777 dri_bo_map(obj_surface->bo, 0);
4779 if (!obj_surface->bo->virtual)
4780 return VA_STATUS_ERROR_INVALID_SURFACE;
4782 /* Both dest VA image and source surface have YUY2 format */
4783 dst = (uint8_t *)obj_surface->bo->virtual;
4784 src = image_data + obj_image->image.offsets[0];
4786 /* YUYV packed plane */
4787 dst += dst_rect->y * obj_surface->width + dst_rect->x*2;
4788 src += src_rect->y * obj_image->image.pitches[0] + src_rect->x*2;
4789 memcpy_pic(dst, obj_surface->width*2,
4790 src, obj_image->image.pitches[0],
4791 src_rect->width*2, src_rect->height);
4793 if (tiling != I915_TILING_NONE)
4794 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4796 dri_bo_unmap(obj_surface->bo);
4802 i965_sw_putimage(VADriverContextP ctx,
4803 struct object_surface *obj_surface, struct object_image *obj_image,
4804 const VARectangle *src_rect, const VARectangle *dst_rect)
4806 VAStatus va_status = VA_STATUS_SUCCESS;
4807 void *image_data = NULL;
4809 /* XXX: don't allow scaling */
4810 if (src_rect->width != dst_rect->width ||
4811 src_rect->height != dst_rect->height)
4812 return VA_STATUS_ERROR_INVALID_PARAMETER;
4814 if (obj_surface->fourcc) {
4815 /* Don't allow format mismatch */
4816 if (obj_surface->fourcc != obj_image->image.format.fourcc)
4817 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
4821 /* VA is surface not used for decoding, use same VA image format */
4822 va_status = i965_check_alloc_surface_bo(
4825 0, /* XXX: don't use tiled surface */
4826 obj_image->image.format.fourcc,
4827 get_sampling_from_fourcc (obj_image->image.format.fourcc));
4830 if (va_status != VA_STATUS_SUCCESS)
4833 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
4834 if (va_status != VA_STATUS_SUCCESS)
4837 switch (obj_image->image.format.fourcc) {
4838 case VA_FOURCC_YV12:
4839 case VA_FOURCC_I420:
4840 va_status = put_image_i420(obj_surface, dst_rect, obj_image, image_data, src_rect);
4842 case VA_FOURCC_NV12:
4843 va_status = put_image_nv12(obj_surface, dst_rect, obj_image, image_data, src_rect);
4845 case VA_FOURCC_YUY2:
4846 va_status = put_image_yuy2(obj_surface, dst_rect, obj_image, image_data, src_rect);
4849 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
4852 if (va_status != VA_STATUS_SUCCESS)
4855 va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
4860 i965_hw_putimage(VADriverContextP ctx,
4861 struct object_surface *obj_surface, struct object_image *obj_image,
4862 const VARectangle *src_rect, const VARectangle *dst_rect)
4864 struct i965_surface src_surface, dst_surface;
4865 VAStatus va_status = VA_STATUS_SUCCESS;
4867 if (!obj_surface->bo) {
4868 unsigned int tiling, swizzle;
4869 int surface_sampling = get_sampling_from_fourcc (obj_image->image.format.fourcc);;
4870 dri_bo_get_tiling(obj_image->bo, &tiling, &swizzle);
4872 i965_check_alloc_surface_bo(ctx,
4875 obj_image->image.format.fourcc,
4879 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4881 src_surface.base = (struct object_base *)obj_image;
4882 src_surface.type = I965_SURFACE_TYPE_IMAGE;
4883 src_surface.flags = I965_SURFACE_FLAG_FRAME;
4885 dst_surface.base = (struct object_base *)obj_surface;
4886 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4887 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4889 va_status = i965_image_processing(ctx,
4899 i965_PutImage(VADriverContextP ctx,
4900 VASurfaceID surface,
4904 unsigned int src_width,
4905 unsigned int src_height,
4908 unsigned int dest_width,
4909 unsigned int dest_height)
4911 struct i965_driver_data * const i965 = i965_driver_data(ctx);
4912 struct object_surface * const obj_surface = SURFACE(surface);
4913 struct object_image * const obj_image = IMAGE(image);
4914 VARectangle src_rect, dst_rect;
4918 return VA_STATUS_ERROR_INVALID_SURFACE;
4919 if (is_surface_busy(i965, obj_surface))
4920 return VA_STATUS_ERROR_SURFACE_BUSY;
4922 if (!obj_image || !obj_image->bo)
4923 return VA_STATUS_ERROR_INVALID_IMAGE;
4924 if (is_image_busy(i965, obj_image, surface))
4925 return VA_STATUS_ERROR_SURFACE_BUSY;
4929 src_x + src_width > obj_image->image.width ||
4930 src_y + src_height > obj_image->image.height)
4931 return VA_STATUS_ERROR_INVALID_PARAMETER;
4935 src_rect.width = src_width;
4936 src_rect.height = src_height;
4940 dest_x + dest_width > obj_surface->orig_width ||
4941 dest_y + dest_height > obj_surface->orig_height)
4942 return VA_STATUS_ERROR_INVALID_PARAMETER;
4944 dst_rect.x = dest_x;
4945 dst_rect.y = dest_y;
4946 dst_rect.width = dest_width;
4947 dst_rect.height = dest_height;
4949 if (HAS_ACCELERATED_PUTIMAGE(i965))
4950 va_status = i965_hw_putimage(ctx, obj_surface, obj_image,
4951 &src_rect, &dst_rect);
4953 va_status = i965_sw_putimage(ctx, obj_surface, obj_image,
4954 &src_rect, &dst_rect);
4960 i965_PutSurface(VADriverContextP ctx,
4961 VASurfaceID surface,
4962 void *draw, /* X Drawable */
4965 unsigned short srcw,
4966 unsigned short srch,
4969 unsigned short destw,
4970 unsigned short desth,
4971 VARectangle *cliprects, /* client supplied clip list */
4972 unsigned int number_cliprects, /* number of clip rects in the clip list */
4973 unsigned int flags) /* de-interlacing flags */
4976 if (IS_VA_X11(ctx)) {
4977 VARectangle src_rect, dst_rect;
4981 src_rect.width = srcw;
4982 src_rect.height = srch;
4986 dst_rect.width = destw;
4987 dst_rect.height = desth;
4989 return i965_put_surface_dri(ctx, surface, draw, &src_rect, &dst_rect,
4990 cliprects, number_cliprects, flags);
4993 return VA_STATUS_ERROR_UNIMPLEMENTED;
4998 VADriverContextP ctx, /* in */
4999 VABufferID buf_id, /* in */
5000 VABufferType *type, /* out */
5001 unsigned int *size, /* out */
5002 unsigned int *num_elements /* out */
5005 struct i965_driver_data *i965 = NULL;
5006 struct object_buffer *obj_buffer = NULL;
5008 i965 = i965_driver_data(ctx);
5009 obj_buffer = BUFFER(buf_id);
5011 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
5013 *type = obj_buffer->type;
5014 *size = obj_buffer->size_element;
5015 *num_elements = obj_buffer->num_elements;
5017 return VA_STATUS_SUCCESS;
5022 VADriverContextP ctx, /* in */
5023 VASurfaceID surface, /* in */
5024 unsigned int *fourcc, /* out */
5025 unsigned int *luma_stride, /* out */
5026 unsigned int *chroma_u_stride, /* out */
5027 unsigned int *chroma_v_stride, /* out */
5028 unsigned int *luma_offset, /* out */
5029 unsigned int *chroma_u_offset, /* out */
5030 unsigned int *chroma_v_offset, /* out */
5031 unsigned int *buffer_name, /* out */
5032 void **buffer /* out */
5035 VAStatus vaStatus = VA_STATUS_SUCCESS;
5036 struct i965_driver_data *i965 = i965_driver_data(ctx);
5037 struct object_surface *obj_surface = NULL;
5040 ASSERT_RET(fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
5041 ASSERT_RET(luma_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
5042 ASSERT_RET(chroma_u_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
5043 ASSERT_RET(chroma_v_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
5044 ASSERT_RET(luma_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
5045 ASSERT_RET(chroma_u_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
5046 ASSERT_RET(chroma_v_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
5047 ASSERT_RET(buffer_name, VA_STATUS_ERROR_INVALID_PARAMETER);
5048 ASSERT_RET(buffer, VA_STATUS_ERROR_INVALID_PARAMETER);
5050 tmpImage.image_id = VA_INVALID_ID;
5052 obj_surface = SURFACE(surface);
5053 if (obj_surface == NULL) {
5054 // Surface is absent.
5055 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
5059 // Lock functionality is absent now.
5060 if (obj_surface->locked_image_id != VA_INVALID_ID) {
5061 // Surface is locked already.
5062 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
5066 vaStatus = i965_DeriveImage(
5070 if (vaStatus != VA_STATUS_SUCCESS) {
5074 obj_surface->locked_image_id = tmpImage.image_id;
5076 vaStatus = i965_MapBuffer(
5080 if (vaStatus != VA_STATUS_SUCCESS) {
5084 *fourcc = tmpImage.format.fourcc;
5085 *luma_offset = tmpImage.offsets[0];
5086 *luma_stride = tmpImage.pitches[0];
5087 *chroma_u_offset = tmpImage.offsets[1];
5088 *chroma_u_stride = tmpImage.pitches[1];
5089 *chroma_v_offset = tmpImage.offsets[2];
5090 *chroma_v_stride = tmpImage.pitches[2];
5091 *buffer_name = tmpImage.buf;
5094 if (vaStatus != VA_STATUS_SUCCESS) {
5103 VADriverContextP ctx, /* in */
5104 VASurfaceID surface /* in */
5107 VAStatus vaStatus = VA_STATUS_SUCCESS;
5108 struct i965_driver_data *i965 = i965_driver_data(ctx);
5109 struct object_image *locked_img = NULL;
5110 struct object_surface *obj_surface = NULL;
5112 obj_surface = SURFACE(surface);
5114 if (obj_surface == NULL) {
5115 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is absent
5118 if (obj_surface->locked_image_id == VA_INVALID_ID) {
5119 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is not locked
5123 locked_img = IMAGE(obj_surface->locked_image_id);
5124 if (locked_img == NULL || (locked_img->image.image_id == VA_INVALID_ID)) {
5125 // Work image was deallocated before i965_UnlockSurface()
5126 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
5130 vaStatus = i965_UnmapBuffer(
5132 locked_img->image.buf);
5133 if (vaStatus != VA_STATUS_SUCCESS) {
5137 vaStatus = i965_DestroyImage(
5139 locked_img->image.image_id);
5140 if (vaStatus != VA_STATUS_SUCCESS) {
5144 locked_img->image.image_id = VA_INVALID_ID;
5147 obj_surface->locked_image_id = VA_INVALID_ID;
5153 i965_GetSurfaceAttributes(
5154 VADriverContextP ctx,
5156 VASurfaceAttrib *attrib_list,
5157 unsigned int num_attribs
5160 VAStatus vaStatus = VA_STATUS_SUCCESS;
5161 struct i965_driver_data *i965 = i965_driver_data(ctx);
5162 struct object_config *obj_config;
5165 if (config == VA_INVALID_ID)
5166 return VA_STATUS_ERROR_INVALID_CONFIG;
5168 obj_config = CONFIG(config);
5170 if (obj_config == NULL)
5171 return VA_STATUS_ERROR_INVALID_CONFIG;
5173 if (attrib_list == NULL || num_attribs == 0)
5174 return VA_STATUS_ERROR_INVALID_PARAMETER;
5176 for (i = 0; i < num_attribs; i++) {
5177 switch (attrib_list[i].type) {
5178 case VASurfaceAttribPixelFormat:
5179 attrib_list[i].value.type = VAGenericValueTypeInteger;
5180 attrib_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5182 if (attrib_list[i].value.value.i == 0) {
5183 if (IS_G4X(i965->intel.device_info)) {
5184 if (obj_config->profile == VAProfileMPEG2Simple ||
5185 obj_config->profile == VAProfileMPEG2Main) {
5186 attrib_list[i].value.value.i = VA_FOURCC_I420;
5189 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5191 } else if (IS_IRONLAKE(i965->intel.device_info)) {
5192 if (obj_config->profile == VAProfileMPEG2Simple ||
5193 obj_config->profile == VAProfileMPEG2Main) {
5194 attrib_list[i].value.value.i = VA_FOURCC_I420;
5195 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
5196 obj_config->profile == VAProfileH264Main ||
5197 obj_config->profile == VAProfileH264High) {
5198 attrib_list[i].value.value.i = VA_FOURCC_NV12;
5199 } else if (obj_config->profile == VAProfileNone) {
5200 attrib_list[i].value.value.i = VA_FOURCC_NV12;
5203 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5205 } else if (IS_GEN6(i965->intel.device_info)) {
5206 attrib_list[i].value.value.i = VA_FOURCC_NV12;
5207 } else if (IS_GEN7(i965->intel.device_info) ||
5208 IS_GEN8(i965->intel.device_info) ||
5209 IS_GEN9(i965->intel.device_info)) {
5210 if (obj_config->profile == VAProfileJPEGBaseline)
5211 attrib_list[i].value.value.i = 0; /* internal format */
5213 attrib_list[i].value.value.i = VA_FOURCC_NV12;
5216 if (IS_G4X(i965->intel.device_info)) {
5217 if (obj_config->profile == VAProfileMPEG2Simple ||
5218 obj_config->profile == VAProfileMPEG2Main) {
5219 if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
5220 attrib_list[i].value.value.i = 0;
5221 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5225 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5227 } else if (IS_IRONLAKE(i965->intel.device_info)) {
5228 if (obj_config->profile == VAProfileMPEG2Simple ||
5229 obj_config->profile == VAProfileMPEG2Main) {
5230 if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
5231 attrib_list[i].value.value.i = 0;
5232 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5234 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
5235 obj_config->profile == VAProfileH264Main ||
5236 obj_config->profile == VAProfileH264High) {
5237 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
5238 attrib_list[i].value.value.i = 0;
5239 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5241 } else if (obj_config->profile == VAProfileNone) {
5242 switch (attrib_list[i].value.value.i) {
5243 case VA_FOURCC_NV12:
5244 case VA_FOURCC_I420:
5245 case VA_FOURCC_YV12:
5246 case VA_FOURCC_YUY2:
5247 case VA_FOURCC_BGRA:
5248 case VA_FOURCC_BGRX:
5249 case VA_FOURCC_RGBX:
5250 case VA_FOURCC_RGBA:
5253 attrib_list[i].value.value.i = 0;
5254 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5259 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5261 } else if (IS_GEN6(i965->intel.device_info)) {
5262 if (obj_config->entrypoint == VAEntrypointEncSlice ||
5263 obj_config->entrypoint == VAEntrypointVideoProc) {
5264 switch (attrib_list[i].value.value.i) {
5265 case VA_FOURCC_NV12:
5266 case VA_FOURCC_I420:
5267 case VA_FOURCC_YV12:
5268 case VA_FOURCC_YUY2:
5269 case VA_FOURCC_BGRA:
5270 case VA_FOURCC_BGRX:
5271 case VA_FOURCC_RGBX:
5272 case VA_FOURCC_RGBA:
5275 attrib_list[i].value.value.i = 0;
5276 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5280 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
5281 attrib_list[i].value.value.i = 0;
5282 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5285 } else if (IS_GEN7(i965->intel.device_info) ||
5286 IS_GEN8(i965->intel.device_info) ||
5287 IS_GEN9(i965->intel.device_info)) {
5288 if (obj_config->entrypoint == VAEntrypointEncSlice ||
5289 obj_config->entrypoint == VAEntrypointVideoProc) {
5290 switch (attrib_list[i].value.value.i) {
5291 case VA_FOURCC_NV12:
5292 case VA_FOURCC_I420:
5293 case VA_FOURCC_YV12:
5296 attrib_list[i].value.value.i = 0;
5297 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5301 if (obj_config->profile == VAProfileJPEGBaseline) {
5302 attrib_list[i].value.value.i = 0; /* JPEG decoding always uses an internal format */
5303 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5305 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
5306 attrib_list[i].value.value.i = 0;
5307 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
5315 case VASurfaceAttribMinWidth:
5316 /* FIXME: add support for it later */
5317 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5319 case VASurfaceAttribMaxWidth:
5320 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5322 case VASurfaceAttribMinHeight:
5323 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5325 case VASurfaceAttribMaxHeight:
5326 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5329 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
5338 i965_QuerySurfaceAttributes(VADriverContextP ctx,
5340 VASurfaceAttrib *attrib_list,
5341 unsigned int *num_attribs)
5343 VAStatus vaStatus = VA_STATUS_SUCCESS;
5344 struct i965_driver_data *i965 = i965_driver_data(ctx);
5345 struct object_config *obj_config;
5347 VASurfaceAttrib *attribs = NULL;
5349 if (config == VA_INVALID_ID)
5350 return VA_STATUS_ERROR_INVALID_CONFIG;
5352 obj_config = CONFIG(config);
5354 if (obj_config == NULL)
5355 return VA_STATUS_ERROR_INVALID_CONFIG;
5357 if (!attrib_list && !num_attribs)
5358 return VA_STATUS_ERROR_INVALID_PARAMETER;
5360 if (attrib_list == NULL) {
5361 *num_attribs = I965_MAX_SURFACE_ATTRIBUTES;
5362 return VA_STATUS_SUCCESS;
5365 attribs = malloc(I965_MAX_SURFACE_ATTRIBUTES *sizeof(*attribs));
5367 if (attribs == NULL)
5368 return VA_STATUS_ERROR_ALLOCATION_FAILED;
5370 if (IS_G4X(i965->intel.device_info)) {
5371 if (obj_config->profile == VAProfileMPEG2Simple ||
5372 obj_config->profile == VAProfileMPEG2Main) {
5373 attribs[i].type = VASurfaceAttribPixelFormat;
5374 attribs[i].value.type = VAGenericValueTypeInteger;
5375 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5376 attribs[i].value.value.i = VA_FOURCC_I420;
5379 } else if (IS_IRONLAKE(i965->intel.device_info)) {
5380 switch (obj_config->profile) {
5381 case VAProfileMPEG2Simple:
5382 case VAProfileMPEG2Main:
5383 attribs[i].type = VASurfaceAttribPixelFormat;
5384 attribs[i].value.type = VAGenericValueTypeInteger;
5385 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5386 attribs[i].value.value.i = VA_FOURCC_I420;
5391 case VAProfileH264ConstrainedBaseline:
5392 case VAProfileH264Main:
5393 case VAProfileH264High:
5394 attribs[i].type = VASurfaceAttribPixelFormat;
5395 attribs[i].value.type = VAGenericValueTypeInteger;
5396 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5397 attribs[i].value.value.i = VA_FOURCC_NV12;
5401 attribs[i].type = VASurfaceAttribPixelFormat;
5402 attribs[i].value.type = VAGenericValueTypeInteger;
5403 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5404 attribs[i].value.value.i = VA_FOURCC_NV12;
5407 attribs[i].type = VASurfaceAttribPixelFormat;
5408 attribs[i].value.type = VAGenericValueTypeInteger;
5409 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5410 attribs[i].value.value.i = VA_FOURCC_I420;
5418 } else if (IS_GEN6(i965->intel.device_info)) {
5419 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
5420 attribs[i].type = VASurfaceAttribPixelFormat;
5421 attribs[i].value.type = VAGenericValueTypeInteger;
5422 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5423 attribs[i].value.value.i = VA_FOURCC_NV12;
5425 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
5426 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
5427 attribs[i].type = VASurfaceAttribPixelFormat;
5428 attribs[i].value.type = VAGenericValueTypeInteger;
5429 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5430 attribs[i].value.value.i = VA_FOURCC_NV12;
5433 attribs[i].type = VASurfaceAttribPixelFormat;
5434 attribs[i].value.type = VAGenericValueTypeInteger;
5435 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5436 attribs[i].value.value.i = VA_FOURCC_I420;
5439 attribs[i].type = VASurfaceAttribPixelFormat;
5440 attribs[i].value.type = VAGenericValueTypeInteger;
5441 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5442 attribs[i].value.value.i = VA_FOURCC_YV12;
5445 if (obj_config->entrypoint == VAEntrypointVideoProc) {
5446 attribs[i].type = VASurfaceAttribPixelFormat;
5447 attribs[i].value.type = VAGenericValueTypeInteger;
5448 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5449 attribs[i].value.value.i = VA_FOURCC_YUY2;
5452 attribs[i].type = VASurfaceAttribPixelFormat;
5453 attribs[i].value.type = VAGenericValueTypeInteger;
5454 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5455 attribs[i].value.value.i = VA_FOURCC_RGBA;
5458 attribs[i].type = VASurfaceAttribPixelFormat;
5459 attribs[i].value.type = VAGenericValueTypeInteger;
5460 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5461 attribs[i].value.value.i = VA_FOURCC_RGBX;
5465 } else if (IS_GEN7(i965->intel.device_info)) {
5466 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
5467 if (obj_config->profile == VAProfileJPEGBaseline) {
5468 attribs[i].type = VASurfaceAttribPixelFormat;
5469 attribs[i].value.type = VAGenericValueTypeInteger;
5470 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5471 attribs[i].value.value.i = VA_FOURCC_IMC3;
5474 attribs[i].type = VASurfaceAttribPixelFormat;
5475 attribs[i].value.type = VAGenericValueTypeInteger;
5476 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5477 attribs[i].value.value.i = VA_FOURCC_IMC1;
5480 attribs[i].type = VASurfaceAttribPixelFormat;
5481 attribs[i].value.type = VAGenericValueTypeInteger;
5482 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5483 attribs[i].value.value.i = VA_FOURCC_Y800;
5486 attribs[i].type = VASurfaceAttribPixelFormat;
5487 attribs[i].value.type = VAGenericValueTypeInteger;
5488 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5489 attribs[i].value.value.i = VA_FOURCC_411P;
5492 attribs[i].type = VASurfaceAttribPixelFormat;
5493 attribs[i].value.type = VAGenericValueTypeInteger;
5494 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5495 attribs[i].value.value.i = VA_FOURCC_422H;
5498 attribs[i].type = VASurfaceAttribPixelFormat;
5499 attribs[i].value.type = VAGenericValueTypeInteger;
5500 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5501 attribs[i].value.value.i = VA_FOURCC_422V;
5504 attribs[i].type = VASurfaceAttribPixelFormat;
5505 attribs[i].value.type = VAGenericValueTypeInteger;
5506 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5507 attribs[i].value.value.i = VA_FOURCC_444P;
5509 } else if (obj_config->profile == VAProfileHEVCMain10) {
5510 attribs[i].type = VASurfaceAttribPixelFormat;
5511 attribs[i].value.type = VAGenericValueTypeInteger;
5512 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5513 attribs[i].value.value.i = VA_FOURCC_P010;
5516 attribs[i].type = VASurfaceAttribPixelFormat;
5517 attribs[i].value.type = VAGenericValueTypeInteger;
5518 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5519 attribs[i].value.value.i = VA_FOURCC_NV12;
5522 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
5523 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
5524 attribs[i].type = VASurfaceAttribPixelFormat;
5525 attribs[i].value.type = VAGenericValueTypeInteger;
5526 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5527 attribs[i].value.value.i = VA_FOURCC_NV12;
5530 attribs[i].type = VASurfaceAttribPixelFormat;
5531 attribs[i].value.type = VAGenericValueTypeInteger;
5532 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5533 attribs[i].value.value.i = VA_FOURCC_I420;
5536 attribs[i].type = VASurfaceAttribPixelFormat;
5537 attribs[i].value.type = VAGenericValueTypeInteger;
5538 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5539 attribs[i].value.value.i = VA_FOURCC_YV12;
5542 attribs[i].type = VASurfaceAttribPixelFormat;
5543 attribs[i].value.type = VAGenericValueTypeInteger;
5544 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5545 attribs[i].value.value.i = VA_FOURCC_IMC3;
5548 if (obj_config->entrypoint == VAEntrypointVideoProc) {
5549 attribs[i].type = VASurfaceAttribPixelFormat;
5550 attribs[i].value.type = VAGenericValueTypeInteger;
5551 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5552 attribs[i].value.value.i = VA_FOURCC_YUY2;
5555 attribs[i].type = VASurfaceAttribPixelFormat;
5556 attribs[i].value.type = VAGenericValueTypeInteger;
5557 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5558 attribs[i].value.value.i = VA_FOURCC_RGBA;
5561 attribs[i].type = VASurfaceAttribPixelFormat;
5562 attribs[i].value.type = VAGenericValueTypeInteger;
5563 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5564 attribs[i].value.value.i = VA_FOURCC_RGBX;
5567 attribs[i].type = VASurfaceAttribPixelFormat;
5568 attribs[i].value.type = VAGenericValueTypeInteger;
5569 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5570 attribs[i].value.value.i = VA_FOURCC_BGRA;
5573 attribs[i].type = VASurfaceAttribPixelFormat;
5574 attribs[i].value.type = VAGenericValueTypeInteger;
5575 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5576 attribs[i].value.value.i = VA_FOURCC_BGRX;
5579 attribs[i].type = VASurfaceAttribPixelFormat;
5580 attribs[i].value.type = VAGenericValueTypeInteger;
5581 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5582 attribs[i].value.value.i = VA_FOURCC_YV16;
5586 } else if (IS_GEN8(i965->intel.device_info) ||
5587 IS_GEN9(i965->intel.device_info)) {
5588 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
5589 if (obj_config->profile == VAProfileJPEGBaseline) {
5590 attribs[i].type = VASurfaceAttribPixelFormat;
5591 attribs[i].value.type = VAGenericValueTypeInteger;
5592 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5593 attribs[i].value.value.i = VA_FOURCC_IMC3;
5596 attribs[i].type = VASurfaceAttribPixelFormat;
5597 attribs[i].value.type = VAGenericValueTypeInteger;
5598 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5599 attribs[i].value.value.i = VA_FOURCC_IMC1;
5602 attribs[i].type = VASurfaceAttribPixelFormat;
5603 attribs[i].value.type = VAGenericValueTypeInteger;
5604 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5605 attribs[i].value.value.i = VA_FOURCC_Y800;
5608 attribs[i].type = VASurfaceAttribPixelFormat;
5609 attribs[i].value.type = VAGenericValueTypeInteger;
5610 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5611 attribs[i].value.value.i = VA_FOURCC_411P;
5614 attribs[i].type = VASurfaceAttribPixelFormat;
5615 attribs[i].value.type = VAGenericValueTypeInteger;
5616 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5617 attribs[i].value.value.i = VA_FOURCC_422H;
5620 attribs[i].type = VASurfaceAttribPixelFormat;
5621 attribs[i].value.type = VAGenericValueTypeInteger;
5622 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5623 attribs[i].value.value.i = VA_FOURCC_422V;
5626 attribs[i].type = VASurfaceAttribPixelFormat;
5627 attribs[i].value.type = VAGenericValueTypeInteger;
5628 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5629 attribs[i].value.value.i = VA_FOURCC_444P;
5632 attribs[i].type = VASurfaceAttribPixelFormat;
5633 attribs[i].value.type = VAGenericValueTypeInteger;
5634 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5635 attribs[i].value.value.i = VA_FOURCC_NV12;
5638 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
5639 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
5641 if (obj_config->profile == VAProfileHEVCMain10) {
5642 attribs[i].type = VASurfaceAttribPixelFormat;
5643 attribs[i].value.type = VAGenericValueTypeInteger;
5644 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5645 attribs[i].value.value.i = VA_FOURCC_P010;
5648 attribs[i].type = VASurfaceAttribPixelFormat;
5649 attribs[i].value.type = VAGenericValueTypeInteger;
5650 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5651 attribs[i].value.value.i = VA_FOURCC_NV12;
5654 attribs[i].type = VASurfaceAttribPixelFormat;
5655 attribs[i].value.type = VAGenericValueTypeInteger;
5656 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5657 attribs[i].value.value.i = VA_FOURCC_I420;
5660 attribs[i].type = VASurfaceAttribPixelFormat;
5661 attribs[i].value.type = VAGenericValueTypeInteger;
5662 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5663 attribs[i].value.value.i = VA_FOURCC_YV12;
5666 attribs[i].type = VASurfaceAttribPixelFormat;
5667 attribs[i].value.type = VAGenericValueTypeInteger;
5668 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5669 attribs[i].value.value.i = VA_FOURCC_IMC3;
5673 if (obj_config->entrypoint == VAEntrypointVideoProc) {
5674 attribs[i].type = VASurfaceAttribPixelFormat;
5675 attribs[i].value.type = VAGenericValueTypeInteger;
5676 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5677 attribs[i].value.value.i = VA_FOURCC_YUY2;
5680 attribs[i].type = VASurfaceAttribPixelFormat;
5681 attribs[i].value.type = VAGenericValueTypeInteger;
5682 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5683 attribs[i].value.value.i = VA_FOURCC_RGBA;
5686 attribs[i].type = VASurfaceAttribPixelFormat;
5687 attribs[i].value.type = VAGenericValueTypeInteger;
5688 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5689 attribs[i].value.value.i = VA_FOURCC_RGBX;
5692 attribs[i].type = VASurfaceAttribPixelFormat;
5693 attribs[i].value.type = VAGenericValueTypeInteger;
5694 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5695 attribs[i].value.value.i = VA_FOURCC_BGRA;
5698 attribs[i].type = VASurfaceAttribPixelFormat;
5699 attribs[i].value.type = VAGenericValueTypeInteger;
5700 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5701 attribs[i].value.value.i = VA_FOURCC_BGRX;
5704 attribs[i].type = VASurfaceAttribPixelFormat;
5705 attribs[i].value.type = VAGenericValueTypeInteger;
5706 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5707 attribs[i].value.value.i = VA_FOURCC_YV16;
5710 if(HAS_VPP_P010(i965)) {
5711 attribs[i].type = VASurfaceAttribPixelFormat;
5712 attribs[i].value.type = VAGenericValueTypeInteger;
5713 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5714 attribs[i].value.value.i = VA_FOURCC_P010;
5721 attribs[i].type = VASurfaceAttribMemoryType;
5722 attribs[i].value.type = VAGenericValueTypeInteger;
5723 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5724 attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
5725 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
5726 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
5729 attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
5730 attribs[i].value.type = VAGenericValueTypePointer;
5731 attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
5732 attribs[i].value.value.p = NULL; /* ignore */
5735 attribs[i].type = VASurfaceAttribMaxWidth;
5736 attribs[i].value.type = VAGenericValueTypeInteger;
5737 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
5738 attribs[i].value.value.i = i965->codec_info->max_width;
5741 attribs[i].type = VASurfaceAttribMaxHeight;
5742 attribs[i].value.type = VAGenericValueTypeInteger;
5743 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
5744 attribs[i].value.value.i = i965->codec_info->max_height;
5747 if (i > *num_attribs) {
5750 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5754 memcpy(attrib_list, attribs, i * sizeof(*attribs));
5760 /* Acquires buffer handle for external API usage (internal implementation) */
5762 i965_acquire_buffer_handle(struct object_buffer *obj_buffer,
5763 uint32_t mem_type, VABufferInfo *out_buf_info)
5765 struct buffer_store *buffer_store;
5767 buffer_store = obj_buffer->buffer_store;
5768 if (!buffer_store || !buffer_store->bo)
5769 return VA_STATUS_ERROR_INVALID_BUFFER;
5771 /* Synchronization point */
5772 drm_intel_bo_wait_rendering(buffer_store->bo);
5774 if (obj_buffer->export_refcount > 0) {
5775 if (obj_buffer->export_state.mem_type != mem_type)
5776 return VA_STATUS_ERROR_INVALID_PARAMETER;
5779 VABufferInfo * const buf_info = &obj_buffer->export_state;
5782 case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: {
5784 if (drm_intel_bo_flink(buffer_store->bo, &name) != 0)
5785 return VA_STATUS_ERROR_INVALID_BUFFER;
5786 buf_info->handle = name;
5789 case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
5791 if (drm_intel_bo_gem_export_to_prime(buffer_store->bo, &fd) != 0)
5792 return VA_STATUS_ERROR_INVALID_BUFFER;
5793 buf_info->handle = (intptr_t)fd;
5798 buf_info->type = obj_buffer->type;
5799 buf_info->mem_type = mem_type;
5800 buf_info->mem_size =
5801 obj_buffer->num_elements * obj_buffer->size_element;
5804 obj_buffer->export_refcount++;
5805 *out_buf_info = obj_buffer->export_state;
5806 return VA_STATUS_SUCCESS;
5809 /* Releases buffer handle after usage (internal implementation) */
5811 i965_release_buffer_handle(struct object_buffer *obj_buffer)
5813 if (obj_buffer->export_refcount == 0)
5814 return VA_STATUS_ERROR_INVALID_BUFFER;
5816 if (--obj_buffer->export_refcount == 0) {
5817 VABufferInfo * const buf_info = &obj_buffer->export_state;
5819 switch (buf_info->mem_type) {
5820 case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
5821 close((intptr_t)buf_info->handle);
5825 buf_info->mem_type = 0;
5827 return VA_STATUS_SUCCESS;
5830 /** Acquires buffer handle for external API usage */
5832 i965_AcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
5833 VABufferInfo *buf_info)
5835 struct i965_driver_data * const i965 = i965_driver_data(ctx);
5836 struct object_buffer * const obj_buffer = BUFFER(buf_id);
5837 uint32_t i, mem_type;
5839 /* List of supported memory types, in preferred order */
5840 static const uint32_t mem_types[] = {
5841 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
5842 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM,
5847 return VA_STATUS_ERROR_INVALID_BUFFER;
5848 /* XXX: only VA surface|image like buffers are supported for now */
5849 if (obj_buffer->type != VAImageBufferType)
5850 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
5853 * As the allocated buffer by calling vaCreateBuffer is related with
5854 * the specific context, it is unnecessary to export it.
5855 * So it is not supported when the buffer is allocated from wrapped
5858 if (obj_buffer->wrapper_buffer != VA_INVALID_ID) {
5859 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
5863 return VA_STATUS_ERROR_INVALID_PARAMETER;
5865 if (!buf_info->mem_type)
5866 mem_type = mem_types[0];
5869 for (i = 0; mem_types[i] != 0; i++) {
5870 if (buf_info->mem_type & mem_types[i]) {
5871 mem_type = buf_info->mem_type;
5876 return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
5878 return i965_acquire_buffer_handle(obj_buffer, mem_type, buf_info);
5881 /** Releases buffer handle after usage from external API */
5883 i965_ReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id)
5885 struct i965_driver_data * const i965 = i965_driver_data(ctx);
5886 struct object_buffer * const obj_buffer = BUFFER(buf_id);
5889 return VA_STATUS_ERROR_INVALID_BUFFER;
5891 if (obj_buffer->wrapper_buffer != VA_INVALID_ID) {
5892 return VA_STATUS_ERROR_INVALID_BUFFER;
5895 return i965_release_buffer_handle(obj_buffer);
5899 i965_os_has_ring_support(VADriverContextP ctx,
5902 struct i965_driver_data *const i965 = i965_driver_data(ctx);
5906 return i965->intel.has_bsd;
5909 return i965->intel.has_blt;
5911 case I965_RING_VEBOX:
5912 return i965->intel.has_vebox;
5914 case I965_RING_NULL:
5915 return 1; /* Always support */
5918 /* should never get here */
5927 * Query video processing pipeline
5929 VAStatus i965_QueryVideoProcFilters(
5930 VADriverContextP ctx,
5931 VAContextID context,
5932 VAProcFilterType *filters,
5933 unsigned int *num_filters
5936 struct i965_driver_data *const i965 = i965_driver_data(ctx);
5937 unsigned int i = 0, num = 0;
5939 if (!num_filters || !filters)
5940 return VA_STATUS_ERROR_INVALID_PARAMETER;
5942 for (i = 0; i < i965->codec_info->num_filters; i++) {
5943 if (i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring)) {
5944 if (num == *num_filters) {
5945 *num_filters = i965->codec_info->num_filters;
5947 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5950 filters[num++] = i965->codec_info->filters[i].type;
5956 return VA_STATUS_SUCCESS;
5959 VAStatus i965_QueryVideoProcFilterCaps(
5960 VADriverContextP ctx,
5961 VAContextID context,
5962 VAProcFilterType type,
5964 unsigned int *num_filter_caps
5968 struct i965_driver_data *const i965 = i965_driver_data(ctx);
5970 if (!filter_caps || !num_filter_caps)
5971 return VA_STATUS_ERROR_INVALID_PARAMETER;
5973 for (i = 0; i < i965->codec_info->num_filters; i++) {
5974 if (type == i965->codec_info->filters[i].type &&
5975 i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring))
5979 if (i == i965->codec_info->num_filters)
5980 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
5985 case VAProcFilterNoiseReduction:
5986 case VAProcFilterSharpening:
5988 VAProcFilterCap *cap = filter_caps;
5990 if (*num_filter_caps < 1) {
5991 *num_filter_caps = 1;
5992 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5995 cap->range.min_value = 0.0;
5996 cap->range.max_value = 1.0;
5997 cap->range.default_value = 0.5;
5998 cap->range.step = 0.03125; /* 1.0 / 32 */
6004 case VAProcFilterDeinterlacing:
6006 VAProcFilterCapDeinterlacing *cap = filter_caps;
6008 if (*num_filter_caps < VAProcDeinterlacingCount) {
6009 *num_filter_caps = VAProcDeinterlacingCount;
6010 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
6013 cap->type = VAProcDeinterlacingBob;
6018 if (i965->codec_info->has_di_motion_adptive) {
6019 cap->type = VAProcDeinterlacingMotionAdaptive;
6024 if (i965->codec_info->has_di_motion_compensated) {
6025 cap->type = VAProcDeinterlacingMotionCompensated;
6033 case VAProcFilterColorBalance:
6035 VAProcFilterCapColorBalance *cap = filter_caps;
6037 if (*num_filter_caps < VAProcColorBalanceCount) {
6038 *num_filter_caps = VAProcColorBalanceCount;
6039 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
6042 cap->type = VAProcColorBalanceHue;
6043 cap->range.min_value = -180.0;
6044 cap->range.max_value = 180.0;
6045 cap->range.default_value = 0.0;
6046 cap->range.step = 1.0;
6050 cap->type = VAProcColorBalanceSaturation;
6051 cap->range.min_value = 0.0;
6052 cap->range.max_value = 10.0;
6053 cap->range.default_value = 1.0;
6054 cap->range.step = 0.1;
6058 cap->type = VAProcColorBalanceBrightness;
6059 cap->range.min_value = -100.0;
6060 cap->range.max_value = 100.0;
6061 cap->range.default_value = 0.0;
6062 cap->range.step = 1.0;
6066 cap->type = VAProcColorBalanceContrast;
6067 cap->range.min_value = 0.0;
6068 cap->range.max_value = 10.0;
6069 cap->range.default_value = 1.0;
6070 cap->range.step = 0.1;
6082 *num_filter_caps = i;
6084 return VA_STATUS_SUCCESS;
6087 static VAProcColorStandardType vpp_input_color_standards[VAProcColorStandardCount] = {
6088 VAProcColorStandardBT601,
6091 static VAProcColorStandardType vpp_output_color_standards[VAProcColorStandardCount] = {
6092 VAProcColorStandardBT601,
6095 VAStatus i965_QueryVideoProcPipelineCaps(
6096 VADriverContextP ctx,
6097 VAContextID context,
6098 VABufferID *filters,
6099 unsigned int num_filters,
6100 VAProcPipelineCaps *pipeline_cap /* out */
6103 struct i965_driver_data * const i965 = i965_driver_data(ctx);
6106 pipeline_cap->pipeline_flags = 0;
6107 pipeline_cap->filter_flags = 0;
6108 pipeline_cap->num_forward_references = 0;
6109 pipeline_cap->num_backward_references = 0;
6110 pipeline_cap->num_input_color_standards = 1;
6111 pipeline_cap->input_color_standards = vpp_input_color_standards;
6112 pipeline_cap->num_output_color_standards = 1;
6113 pipeline_cap->output_color_standards = vpp_output_color_standards;
6115 for (i = 0; i < num_filters; i++) {
6116 struct object_buffer *obj_buffer = BUFFER(filters[i]);
6119 !obj_buffer->buffer_store ||
6120 !obj_buffer->buffer_store->buffer)
6121 return VA_STATUS_ERROR_INVALID_BUFFER;
6123 VAProcFilterParameterBufferBase *base = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
6125 if (base->type == VAProcFilterNoiseReduction) {
6126 VAProcFilterParameterBuffer *denoise = (VAProcFilterParameterBuffer *)base;
6128 } else if (base->type == VAProcFilterDeinterlacing) {
6129 VAProcFilterParameterBufferDeinterlacing *deint = (VAProcFilterParameterBufferDeinterlacing *)base;
6131 ASSERT_RET(deint->algorithm == VAProcDeinterlacingBob ||
6132 deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
6133 deint->algorithm == VAProcDeinterlacingMotionCompensated,
6134 VA_STATUS_ERROR_INVALID_PARAMETER);
6136 if (deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
6137 deint->algorithm == VAProcDeinterlacingMotionCompensated)
6138 pipeline_cap->num_forward_references++;
6139 } else if (base->type == VAProcFilterSkinToneEnhancement) {
6140 VAProcFilterParameterBuffer *stde = (VAProcFilterParameterBuffer *)base;
6145 return VA_STATUS_SUCCESS;
6148 extern struct hw_codec_info *i965_get_codec_info(int devid);
6151 i965_driver_data_init(VADriverContextP ctx)
6153 struct i965_driver_data *i965 = i965_driver_data(ctx);
6155 i965->codec_info = i965_get_codec_info(i965->intel.device_id);
6157 if (!i965->codec_info)
6160 if (object_heap_init(&i965->config_heap,
6161 sizeof(struct object_config),
6163 goto err_config_heap;
6164 if (object_heap_init(&i965->context_heap,
6165 sizeof(struct object_context),
6167 goto err_context_heap;
6169 if (object_heap_init(&i965->surface_heap,
6170 sizeof(struct object_surface),
6172 goto err_surface_heap;
6173 if (object_heap_init(&i965->buffer_heap,
6174 sizeof(struct object_buffer),
6176 goto err_buffer_heap;
6177 if (object_heap_init(&i965->image_heap,
6178 sizeof(struct object_image),
6180 goto err_image_heap;
6181 if (object_heap_init(&i965->subpic_heap,
6182 sizeof(struct object_subpic),
6184 goto err_subpic_heap;
6186 i965->batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
6187 i965->pp_batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
6188 _i965InitMutex(&i965->render_mutex);
6189 _i965InitMutex(&i965->pp_mutex);
6194 object_heap_destroy(&i965->image_heap);
6196 object_heap_destroy(&i965->buffer_heap);
6198 object_heap_destroy(&i965->surface_heap);
6200 object_heap_destroy(&i965->context_heap);
6202 object_heap_destroy(&i965->config_heap);
6209 i965_driver_data_terminate(VADriverContextP ctx)
6211 struct i965_driver_data *i965 = i965_driver_data(ctx);
6213 _i965DestroyMutex(&i965->pp_mutex);
6214 _i965DestroyMutex(&i965->render_mutex);
6217 intel_batchbuffer_free(i965->batch);
6220 intel_batchbuffer_free(i965->pp_batch);
6222 i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
6223 i965_destroy_heap(&i965->image_heap, i965_destroy_image);
6224 i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
6225 i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
6226 i965_destroy_heap(&i965->context_heap, i965_destroy_context);
6227 i965_destroy_heap(&i965->config_heap, i965_destroy_config);
6231 bool (*init)(VADriverContextP ctx);
6232 void (*terminate)(VADriverContextP ctx);
6234 } i965_sub_ops[] = {
6237 intel_driver_terminate,
6242 i965_driver_data_init,
6243 i965_driver_data_terminate,
6248 i965_display_attributes_init,
6249 i965_display_attributes_terminate,
6254 i965_post_processing_init,
6255 i965_post_processing_terminate,
6261 i965_render_terminate,
6265 #ifdef HAVE_VA_WAYLAND
6267 i965_output_wayland_init,
6268 i965_output_wayland_terminate,
6275 i965_output_dri_init,
6276 i965_output_dri_terminate,
6283 ensure_vendor_string(struct i965_driver_data *i965, const char *chipset)
6287 if (i965->va_vendor[0] != '\0')
6291 ret = snprintf(i965->va_vendor, sizeof(i965->va_vendor),
6292 "%s %s driver for %s - %d.%d.%d",
6293 INTEL_STR_DRIVER_VENDOR, INTEL_STR_DRIVER_NAME, chipset,
6294 INTEL_DRIVER_MAJOR_VERSION, INTEL_DRIVER_MINOR_VERSION,
6295 INTEL_DRIVER_MICRO_VERSION);
6296 if (ret < 0 || ret >= sizeof(i965->va_vendor))
6300 if (INTEL_DRIVER_PRE_VERSION > 0) {
6301 ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
6302 ".pre%d", INTEL_DRIVER_PRE_VERSION);
6303 if (ret < 0 || ret >= sizeof(i965->va_vendor))
6307 ret = snprintf(&i965->va_vendor[len], sizeof(i965->va_vendor) - len,
6308 " (%s)", INTEL_DRIVER_GIT_VERSION);
6309 if (ret < 0 || ret >= sizeof(i965->va_vendor))
6316 i965->va_vendor[0] = '\0';
6317 ASSERT_RET(ret > 0 && len < sizeof(i965->va_vendor), false);
6321 /* Only when the option of "enable-wrapper" is passed, it is possible
6322 * to initialize/load the wrapper context of backend driver.
6323 * Otherwise it is not loaded.
6325 #if HAVE_HYBRID_CODEC
6328 i965_initialize_wrapper(VADriverContextP ctx, const char *driver_name)
6330 #define DRIVER_EXTENSION "_drv_video.so"
6332 struct i965_driver_data *i965 = i965_driver_data(ctx);
6334 VADriverContextP wrapper_pdrvctx;
6335 struct VADriverVTable *vtable;
6336 char *search_path, *driver_dir;
6338 char driver_path[256];
6339 void *handle = NULL;
6340 VAStatus va_status = VA_STATUS_SUCCESS;
6341 bool driver_loaded = false;
6343 wrapper_pdrvctx = calloc(1, sizeof(*wrapper_pdrvctx));
6344 vtable = calloc(1, sizeof(*vtable));
6346 if (!wrapper_pdrvctx || !vtable) {
6347 fprintf(stderr, "Failed to allocate memory for wrapper \n");
6348 free(wrapper_pdrvctx);
6350 return VA_STATUS_ERROR_ALLOCATION_FAILED;
6353 /* use the same drm_state with CTX */
6354 wrapper_pdrvctx->drm_state = ctx->drm_state;
6355 wrapper_pdrvctx->display_type = ctx->display_type;
6356 wrapper_pdrvctx->vtable = vtable;
6358 search_path = VA_DRIVERS_PATH;
6359 search_path = strdup((const char *)search_path);
6361 driver_dir = strtok_r(search_path, ":", &saveptr);
6362 while (driver_dir && !driver_loaded) {
6363 memset(driver_path, 0, sizeof(driver_path));
6364 sprintf(driver_path, "%s/%s%s", driver_dir, driver_name, DRIVER_EXTENSION);
6366 handle = dlopen(driver_path, RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
6368 fprintf(stderr, "failed to open %s\n", driver_path);
6369 driver_dir = strtok_r(NULL, ":", &saveptr);
6373 VADriverInit init_func = NULL;
6374 char init_func_s[256];
6377 static const struct {
6380 } compatible_versions[] = {
6381 { VA_MAJOR_VERSION, VA_MINOR_VERSION },
6390 for (i = 0; compatible_versions[i].major >= 0; i++) {
6391 snprintf(init_func_s, sizeof(init_func_s),
6392 "__vaDriverInit_%d_%d",
6393 compatible_versions[i].major,
6394 compatible_versions[i].minor);
6395 init_func = (VADriverInit)dlsym(handle, init_func_s);
6400 if (compatible_versions[i].major < 0) {
6402 fprintf(stderr, "%s has no function %s\n",
6403 driver_path, init_func_s);
6404 driver_dir = strtok_r(NULL, ":", &saveptr);
6409 va_status = (*init_func)(wrapper_pdrvctx);
6411 if (va_status != VA_STATUS_SUCCESS) {
6413 fprintf(stderr, "%s init failed\n", driver_path);
6414 driver_dir = strtok_r(NULL, ":", &saveptr);
6418 wrapper_pdrvctx->handle = handle;
6419 driver_loaded = true;
6425 if (driver_loaded) {
6426 i965->wrapper_pdrvctx = wrapper_pdrvctx;
6427 return VA_STATUS_SUCCESS;
6429 fprintf(stderr, "Failed to wrapper %s%s\n", driver_name, DRIVER_EXTENSION);
6431 free(wrapper_pdrvctx);
6432 return VA_STATUS_ERROR_OPERATION_FAILED;
6438 i965_Init(VADriverContextP ctx)
6440 struct i965_driver_data *i965 = i965_driver_data(ctx);
6442 const char *chipset;
6444 for (i = 0; i < ARRAY_ELEMS(i965_sub_ops); i++) {
6445 if ((i965_sub_ops[i].display_type == 0 ||
6446 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) &&
6447 !i965_sub_ops[i].init(ctx))
6451 if (i == ARRAY_ELEMS(i965_sub_ops)) {
6452 switch (i965->intel.device_id) {
6454 #define CHIPSET(id, family, dev, str) case id: chipset = str; break;
6455 #include "i965_pciids.h"
6457 chipset = "Unknown Intel Chipset";
6461 if (!ensure_vendor_string(i965, chipset))
6462 return VA_STATUS_ERROR_ALLOCATION_FAILED;
6464 i965->current_context_id = VA_INVALID_ID;
6466 if (i965->codec_info && i965->codec_info->preinit_hw_codec)
6467 i965->codec_info->preinit_hw_codec(ctx, i965->codec_info);
6469 #if HAVE_HYBRID_CODEC
6470 i965_initialize_wrapper(ctx, "hybrid");
6473 return VA_STATUS_SUCCESS;
6477 for (; i >= 0; i--) {
6478 if (i965_sub_ops[i].display_type == 0 ||
6479 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
6480 i965_sub_ops[i].terminate(ctx);
6484 return VA_STATUS_ERROR_UNKNOWN;
6489 i965_Terminate(VADriverContextP ctx)
6491 struct i965_driver_data *i965 = i965_driver_data(ctx);
6495 if (i965->wrapper_pdrvctx) {
6496 VADriverContextP pdrvctx;
6497 pdrvctx = i965->wrapper_pdrvctx;
6498 if (pdrvctx->handle) {
6499 pdrvctx->vtable->vaTerminate(pdrvctx);
6500 dlclose(pdrvctx->handle);
6501 pdrvctx->handle = NULL;
6503 free(pdrvctx->vtable);
6505 i965->wrapper_pdrvctx = NULL;
6508 for (i = ARRAY_ELEMS(i965_sub_ops); i > 0; i--)
6509 if (i965_sub_ops[i - 1].display_type == 0 ||
6510 i965_sub_ops[i - 1].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
6511 i965_sub_ops[i - 1].terminate(ctx);
6515 ctx->pDriverData = NULL;
6518 return VA_STATUS_SUCCESS;
6522 VA_DRIVER_INIT_FUNC(VADriverContextP ctx);
6525 VA_DRIVER_INIT_FUNC( VADriverContextP ctx )
6527 struct VADriverVTable * const vtable = ctx->vtable;
6528 struct VADriverVTableVPP * const vtable_vpp = ctx->vtable_vpp;
6530 struct i965_driver_data *i965;
6531 VAStatus ret = VA_STATUS_ERROR_UNKNOWN;
6533 ctx->version_major = VA_MAJOR_VERSION;
6534 ctx->version_minor = VA_MINOR_VERSION;
6535 ctx->max_profiles = I965_MAX_PROFILES;
6536 ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
6537 ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
6538 ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
6539 ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
6540 ctx->max_display_attributes = 1 + ARRAY_ELEMS(i965_display_attributes);
6542 vtable->vaTerminate = i965_Terminate;
6543 vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
6544 vtable->vaQueryConfigProfiles = i965_QueryConfigProfiles;
6545 vtable->vaQueryConfigAttributes = i965_QueryConfigAttributes;
6546 vtable->vaCreateConfig = i965_CreateConfig;
6547 vtable->vaDestroyConfig = i965_DestroyConfig;
6548 vtable->vaGetConfigAttributes = i965_GetConfigAttributes;
6549 vtable->vaCreateSurfaces = i965_CreateSurfaces;
6550 vtable->vaDestroySurfaces = i965_DestroySurfaces;
6551 vtable->vaCreateContext = i965_CreateContext;
6552 vtable->vaDestroyContext = i965_DestroyContext;
6553 vtable->vaCreateBuffer = i965_CreateBuffer;
6554 vtable->vaBufferSetNumElements = i965_BufferSetNumElements;
6555 vtable->vaMapBuffer = i965_MapBuffer;
6556 vtable->vaUnmapBuffer = i965_UnmapBuffer;
6557 vtable->vaDestroyBuffer = i965_DestroyBuffer;
6558 vtable->vaBeginPicture = i965_BeginPicture;
6559 vtable->vaRenderPicture = i965_RenderPicture;
6560 vtable->vaEndPicture = i965_EndPicture;
6561 vtable->vaSyncSurface = i965_SyncSurface;
6562 vtable->vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
6563 vtable->vaPutSurface = i965_PutSurface;
6564 vtable->vaQueryImageFormats = i965_QueryImageFormats;
6565 vtable->vaCreateImage = i965_CreateImage;
6566 vtable->vaDeriveImage = i965_DeriveImage;
6567 vtable->vaDestroyImage = i965_DestroyImage;
6568 vtable->vaSetImagePalette = i965_SetImagePalette;
6569 vtable->vaGetImage = i965_GetImage;
6570 vtable->vaPutImage = i965_PutImage;
6571 vtable->vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
6572 vtable->vaCreateSubpicture = i965_CreateSubpicture;
6573 vtable->vaDestroySubpicture = i965_DestroySubpicture;
6574 vtable->vaSetSubpictureImage = i965_SetSubpictureImage;
6575 vtable->vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
6576 vtable->vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
6577 vtable->vaAssociateSubpicture = i965_AssociateSubpicture;
6578 vtable->vaDeassociateSubpicture = i965_DeassociateSubpicture;
6579 vtable->vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
6580 vtable->vaGetDisplayAttributes = i965_GetDisplayAttributes;
6581 vtable->vaSetDisplayAttributes = i965_SetDisplayAttributes;
6582 vtable->vaBufferInfo = i965_BufferInfo;
6583 vtable->vaLockSurface = i965_LockSurface;
6584 vtable->vaUnlockSurface = i965_UnlockSurface;
6585 vtable->vaGetSurfaceAttributes = i965_GetSurfaceAttributes;
6586 vtable->vaQuerySurfaceAttributes = i965_QuerySurfaceAttributes;
6587 vtable->vaCreateSurfaces2 = i965_CreateSurfaces2;
6590 vtable->vaAcquireBufferHandle = i965_AcquireBufferHandle;
6591 vtable->vaReleaseBufferHandle = i965_ReleaseBufferHandle;
6593 vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters;
6594 vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps;
6595 vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;
6597 i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
6600 ctx->pDriverData = NULL;
6602 return VA_STATUS_ERROR_ALLOCATION_FAILED;
6605 i965->wrapper_pdrvctx = NULL;
6606 ctx->pDriverData = (void *)i965;
6607 ret = i965_Init(ctx);
6609 if (ret == VA_STATUS_SUCCESS) {
6610 ctx->str_vendor = i965->va_vendor;
6613 ctx->pDriverData = NULL;