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>
33 # include "i965_output_dri.h"
36 #ifdef HAVE_VA_WAYLAND
37 # include "i965_output_wayland.h"
40 #include "intel_driver.h"
41 #include "intel_memman.h"
42 #include "intel_batchbuffer.h"
43 #include "i965_defines.h"
44 #include "i965_drv_video.h"
45 #include "i965_decoder.h"
46 #include "i965_encoder.h"
48 #define CONFIG_ID_OFFSET 0x01000000
49 #define CONTEXT_ID_OFFSET 0x02000000
50 #define SURFACE_ID_OFFSET 0x04000000
51 #define BUFFER_ID_OFFSET 0x08000000
52 #define IMAGE_ID_OFFSET 0x0a000000
53 #define SUBPIC_ID_OFFSET 0x10000000
55 #define HAS_MPEG2_DECODING(ctx) ((ctx)->codec_info->has_mpeg2_decoding && \
58 #define HAS_MPEG2_ENCODING(ctx) ((ctx)->codec_info->has_mpeg2_encoding && \
61 #define HAS_H264_DECODING(ctx) ((ctx)->codec_info->has_h264_decoding && \
64 #define HAS_H264_ENCODING(ctx) ((ctx)->codec_info->has_h264_encoding && \
67 #define HAS_VC1_DECODING(ctx) ((ctx)->codec_info->has_vc1_decoding && \
70 #define HAS_JPEG_DECODING(ctx) ((ctx)->codec_info->has_jpeg_decoding && \
73 #define HAS_VPP(ctx) ((ctx)->codec_info->has_vpp)
75 #define HAS_ACCELERATED_GETIMAGE(ctx) ((ctx)->codec_info->has_accelerated_getimage)
77 #define HAS_ACCELERATED_PUTIMAGE(ctx) ((ctx)->codec_info->has_accelerated_putimage)
79 #define HAS_TILED_SURFACE(ctx) ((ctx)->codec_info->has_tiled_surface)
81 #define HAS_VP8_DECODING(ctx) ((ctx)->codec_info->has_vp8_decoding && \
84 #define HAS_VP8_ENCODING(ctx) ((ctx)->codec_info->has_vp8_encoding && \
87 #define HAS_H264_MVC_DECODING(ctx) \
88 (HAS_H264_DECODING(ctx) && (ctx)->codec_info->h264_mvc_dec_profiles)
90 #define HAS_H264_MVC_DECODING_PROFILE(ctx, profile) \
91 (HAS_H264_MVC_DECODING(ctx) && \
92 ((ctx)->codec_info->h264_mvc_dec_profiles & (1U << profile)))
94 #define HAS_H264_MVC_ENCODING(ctx) ((ctx)->codec_info->has_h264_mvc_encoding && \
97 static int get_sampling_from_fourcc(unsigned int fourcc);
99 /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */
100 #define IS_VA_X11(ctx) \
101 (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_X11)
103 /* Check whether we are rendering to Wayland */
104 #define IS_VA_WAYLAND(ctx) \
105 (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_WAYLAND)
108 #define I965_2BITS (I965_BIT << 1)
109 #define I965_4BITS (I965_BIT << 2)
110 #define I965_8BITS (I965_BIT << 3)
111 #define I965_16BITS (I965_BIT << 4)
112 #define I965_32BITS (I965_BIT << 5)
124 /* hfactor, vfactor, num_planes, bpp[], num_components, components[] */
125 #define I_NV12 2, 2, 2, {I965_8BITS, I965_4BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_1, OFFSET_8} }
126 #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} }
127 #define I_IYUV I_I420
128 #define I_IMC3 I_I420
129 #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} }
130 #define I_IMC1 I_YV12
132 #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} }
133 #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} }
134 #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} }
135 #define I_YUY2 2, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_24} }
136 #define I_UYVY 2, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16} }
138 #define I_444P 1, 1, 3, {I965_8BITS, I965_8BITS, I965_8BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
140 #define I_411P 4, 1, 3, {I965_8BITS, I965_2BITS, I965_2BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_1, OFFSET_0}, {PLANE_2, OFFSET_0} }
142 #define I_Y800 1, 1, 1, {I965_8BITS}, 1, { {PLANE_0, OFFSET_0} }
144 #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} }
145 #define I_RGBX 1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_16} }
146 #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} }
147 #define I_BGRX 1, 1, 1, {I965_32BITS}, 3, { {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
149 #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} }
150 #define I_ABGR 1, 1, 1, {I965_32BITS}, 4, { {PLANE_0, OFFSET_24}, {PLANE_0, OFFSET_16}, {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
152 #define I_IA88 1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_8} }
153 #define I_AI88 1, 1, 1, {I965_16BITS}, 2, { {PLANE_0, OFFSET_8}, {PLANE_0, OFFSET_0} }
155 #define I_IA44 1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_0}, {PLANE_0, OFFSET_4} }
156 #define I_AI44 1, 1, 1, {I965_8BITS}, 2, { {PLANE_0, OFFSET_4}, {PLANE_0, OFFSET_0} }
161 #define I_SI (I_S | I_I)
163 #define DEF_FOUCC_INFO(FOURCC, FORMAT, SUB, FLAG) { VA_FOURCC_##FOURCC, I965_COLOR_##FORMAT, SUBSAMPLE_##SUB, FLAG, I_##FOURCC }
164 #define DEF_YUV(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, YUV, SUB, FLAG)
165 #define DEF_RGB(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, RGB, SUB, FLAG)
166 #define DEF_INDEX(FOURCC, SUB, FLAG) DEF_FOUCC_INFO(FOURCC, INDEX, SUB, FLAG)
168 static const i965_fourcc_info i965_fourcc_infos[] = {
169 DEF_YUV(NV12, YUV420, I_SI),
170 DEF_YUV(I420, YUV420, I_SI),
171 DEF_YUV(IYUV, YUV420, I_S),
172 DEF_YUV(IMC3, YUV420, I_S),
173 DEF_YUV(YV12, YUV420, I_SI),
174 DEF_YUV(IMC1, YUV420, I_S),
176 DEF_YUV(422H, YUV422H, I_SI),
177 DEF_YUV(422V, YUV422V, I_S),
178 DEF_YUV(YV16, YUV422H, I_S),
179 DEF_YUV(YUY2, YUV422H, I_SI),
180 DEF_YUV(UYVY, YUV422H, I_SI),
182 DEF_YUV(444P, YUV444, I_S),
184 DEF_YUV(411P, YUV411, I_S),
186 DEF_YUV(Y800, YUV400, I_S),
188 DEF_RGB(RGBA, RGBX, I_SI),
189 DEF_RGB(RGBX, RGBX, I_SI),
190 DEF_RGB(BGRA, RGBX, I_SI),
191 DEF_RGB(BGRX, RGBX, I_SI),
193 DEF_RGB(ARGB, RGBX, I_I),
194 DEF_RGB(ABGR, RGBX, I_I),
196 DEF_INDEX(IA88, RGBX, I_I),
197 DEF_INDEX(AI88, RGBX, I_I),
199 DEF_INDEX(IA44, RGBX, I_I),
200 DEF_INDEX(AI44, RGBX, I_I)
203 const i965_fourcc_info *
204 get_fourcc_info(unsigned int fourcc)
208 for (i = 0; ARRAY_ELEMS(i965_fourcc_infos); i++) {
209 const i965_fourcc_info * const info = &i965_fourcc_infos[i];
211 if (info->fourcc == fourcc)
219 I965_SURFACETYPE_RGBA = 1,
220 I965_SURFACETYPE_YUV,
221 I965_SURFACETYPE_INDEXED
224 /* List of supported display attributes */
225 static const VADisplayAttribute i965_display_attributes[] = {
227 VADisplayAttribBrightness,
228 -100, 100, DEFAULT_BRIGHTNESS,
229 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
233 VADisplayAttribContrast,
234 0, 100, DEFAULT_CONTRAST,
235 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
240 -180, 180, DEFAULT_HUE,
241 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
245 VADisplayAttribSaturation,
246 0, 100, DEFAULT_SATURATION,
247 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
251 VADisplayAttribRotation,
252 0, 3, VA_ROTATION_NONE,
253 VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE
257 /* List of supported image formats */
260 VAImageFormat va_format;
261 } i965_image_format_map_t;
263 static const i965_image_format_map_t
264 i965_image_formats_map[I965_MAX_IMAGE_FORMATS + 1] = {
265 { I965_SURFACETYPE_YUV,
266 { VA_FOURCC_YV12, VA_LSB_FIRST, 12, } },
267 { I965_SURFACETYPE_YUV,
268 { VA_FOURCC_I420, VA_LSB_FIRST, 12, } },
269 { I965_SURFACETYPE_YUV,
270 { VA_FOURCC_NV12, VA_LSB_FIRST, 12, } },
271 { I965_SURFACETYPE_YUV,
272 { VA_FOURCC_YUY2, VA_LSB_FIRST, 16, } },
273 { I965_SURFACETYPE_YUV,
274 { VA_FOURCC_UYVY, VA_LSB_FIRST, 16, } },
275 { I965_SURFACETYPE_YUV,
276 { VA_FOURCC_422H, VA_LSB_FIRST, 16, } },
277 { I965_SURFACETYPE_RGBA,
278 { VA_FOURCC_RGBX, VA_LSB_FIRST, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000 } },
279 { I965_SURFACETYPE_RGBA,
280 { VA_FOURCC_BGRX, VA_LSB_FIRST, 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff } },
283 /* List of supported subpicture formats */
287 VAImageFormat va_format;
288 unsigned int va_flags;
289 } i965_subpic_format_map_t;
291 #define COMMON_SUBPICTURE_FLAGS \
292 (VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD| \
293 VA_SUBPICTURE_GLOBAL_ALPHA)
295 static const i965_subpic_format_map_t
296 i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
297 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
298 { VA_FOURCC_IA44, VA_MSB_FIRST, 8, },
299 COMMON_SUBPICTURE_FLAGS },
300 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
301 { VA_FOURCC_AI44, VA_MSB_FIRST, 8, },
302 COMMON_SUBPICTURE_FLAGS },
303 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P8A8_UNORM,
304 { VA_FOURCC_IA88, VA_MSB_FIRST, 16, },
305 COMMON_SUBPICTURE_FLAGS },
306 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A8P8_UNORM,
307 { VA_FOURCC_AI88, VA_MSB_FIRST, 16, },
308 COMMON_SUBPICTURE_FLAGS },
309 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_B8G8R8A8_UNORM,
310 { VA_FOURCC_BGRA, VA_LSB_FIRST, 32,
311 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
312 COMMON_SUBPICTURE_FLAGS },
313 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_R8G8B8A8_UNORM,
314 { VA_FOURCC_RGBA, VA_LSB_FIRST, 32,
315 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
316 COMMON_SUBPICTURE_FLAGS },
319 static const i965_subpic_format_map_t *
320 get_subpic_format(const VAImageFormat *va_format)
323 for (i = 0; i965_subpic_formats_map[i].type != 0; i++) {
324 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
325 if (m->va_format.fourcc == va_format->fourcc &&
326 (m->type == I965_SURFACETYPE_RGBA ?
327 (m->va_format.byte_order == va_format->byte_order &&
328 m->va_format.red_mask == va_format->red_mask &&
329 m->va_format.green_mask == va_format->green_mask &&
330 m->va_format.blue_mask == va_format->blue_mask &&
331 m->va_format.alpha_mask == va_format->alpha_mask) : 1))
337 #define I965_PACKED_HEADER_BASE 0
338 #define I965_PACKED_MISC_HEADER_BASE 3
341 va_enc_packed_type_to_idx(int packed_type)
345 if (packed_type & VAEncPackedHeaderMiscMask) {
346 idx = I965_PACKED_MISC_HEADER_BASE;
347 packed_type = (~VAEncPackedHeaderMiscMask & packed_type);
348 ASSERT_RET(packed_type > 0, 0);
349 idx += (packed_type - 1);
351 idx = I965_PACKED_HEADER_BASE;
353 switch (packed_type) {
354 case VAEncPackedHeaderSequence:
355 idx = I965_PACKED_HEADER_BASE + 0;
358 case VAEncPackedHeaderPicture:
359 idx = I965_PACKED_HEADER_BASE + 1;
362 case VAEncPackedHeaderSlice:
363 idx = I965_PACKED_HEADER_BASE + 2;
367 /* Should not get here */
373 ASSERT_RET(idx < 4, 0);
378 i965_QueryConfigProfiles(VADriverContextP ctx,
379 VAProfile *profile_list, /* out */
380 int *num_profiles) /* out */
382 struct i965_driver_data * const i965 = i965_driver_data(ctx);
385 if (HAS_MPEG2_DECODING(i965) ||
386 HAS_MPEG2_ENCODING(i965)) {
387 profile_list[i++] = VAProfileMPEG2Simple;
388 profile_list[i++] = VAProfileMPEG2Main;
391 if (HAS_H264_DECODING(i965) ||
392 HAS_H264_ENCODING(i965)) {
393 profile_list[i++] = VAProfileH264ConstrainedBaseline;
394 profile_list[i++] = VAProfileH264Main;
395 profile_list[i++] = VAProfileH264High;
397 if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264MultiviewHigh))
398 profile_list[i++] = VAProfileH264MultiviewHigh;
399 if (HAS_H264_MVC_DECODING_PROFILE(i965, VAProfileH264StereoHigh))
400 profile_list[i++] = VAProfileH264StereoHigh;
402 if (HAS_VC1_DECODING(i965)) {
403 profile_list[i++] = VAProfileVC1Simple;
404 profile_list[i++] = VAProfileVC1Main;
405 profile_list[i++] = VAProfileVC1Advanced;
409 profile_list[i++] = VAProfileNone;
412 if (HAS_JPEG_DECODING(i965)) {
413 profile_list[i++] = VAProfileJPEGBaseline;
416 if (HAS_VP8_DECODING(i965) ||
417 HAS_VP8_ENCODING(i965)) {
418 profile_list[i++] = VAProfileVP8Version0_3;
421 if (HAS_H264_MVC_ENCODING(i965)) {
422 profile_list[i++] = VAProfileH264MultiviewHigh;
423 profile_list[i++] = VAProfileH264StereoHigh;
426 /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
427 ASSERT_RET(i <= I965_MAX_PROFILES, VA_STATUS_ERROR_OPERATION_FAILED);
430 return VA_STATUS_SUCCESS;
434 i965_QueryConfigEntrypoints(VADriverContextP ctx,
436 VAEntrypoint *entrypoint_list, /* out */
437 int *num_entrypoints) /* out */
439 struct i965_driver_data * const i965 = i965_driver_data(ctx);
443 case VAProfileMPEG2Simple:
444 case VAProfileMPEG2Main:
445 if (HAS_MPEG2_DECODING(i965))
446 entrypoint_list[n++] = VAEntrypointVLD;
448 if (HAS_MPEG2_ENCODING(i965))
449 entrypoint_list[n++] = VAEntrypointEncSlice;
453 case VAProfileH264ConstrainedBaseline:
454 case VAProfileH264Main:
455 case VAProfileH264High:
456 if (HAS_H264_DECODING(i965))
457 entrypoint_list[n++] = VAEntrypointVLD;
459 if (HAS_H264_ENCODING(i965))
460 entrypoint_list[n++] = VAEntrypointEncSlice;
463 case VAProfileH264MultiviewHigh:
464 case VAProfileH264StereoHigh:
465 if (HAS_H264_MVC_DECODING_PROFILE(i965, profile))
466 entrypoint_list[n++] = VAEntrypointVLD;
468 if (HAS_H264_MVC_ENCODING(i965))
469 entrypoint_list[n++] = VAEntrypointEncSlice;
472 case VAProfileVC1Simple:
473 case VAProfileVC1Main:
474 case VAProfileVC1Advanced:
475 if (HAS_VC1_DECODING(i965))
476 entrypoint_list[n++] = VAEntrypointVLD;
481 entrypoint_list[n++] = VAEntrypointVideoProc;
484 case VAProfileJPEGBaseline:
485 if (HAS_JPEG_DECODING(i965))
486 entrypoint_list[n++] = VAEntrypointVLD;
489 case VAProfileVP8Version0_3:
490 if (HAS_VP8_DECODING(i965))
491 entrypoint_list[n++] = VAEntrypointVLD;
493 if (HAS_VP8_ENCODING(i965))
494 entrypoint_list[n++] = VAEntrypointEncSlice;
500 /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
501 ASSERT_RET(n <= I965_MAX_ENTRYPOINTS, VA_STATUS_ERROR_OPERATION_FAILED);
502 *num_entrypoints = n;
503 return n > 0 ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
507 i965_validate_config(VADriverContextP ctx, VAProfile profile,
508 VAEntrypoint entrypoint)
510 struct i965_driver_data * const i965 = i965_driver_data(ctx);
513 /* Validate profile & entrypoint */
515 case VAProfileMPEG2Simple:
516 case VAProfileMPEG2Main:
517 if ((HAS_MPEG2_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
518 (HAS_MPEG2_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
519 va_status = VA_STATUS_SUCCESS;
521 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
525 case VAProfileH264ConstrainedBaseline:
526 case VAProfileH264Main:
527 case VAProfileH264High:
528 if ((HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
529 (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
530 va_status = VA_STATUS_SUCCESS;
532 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
536 case VAProfileVC1Simple:
537 case VAProfileVC1Main:
538 case VAProfileVC1Advanced:
539 if (HAS_VC1_DECODING(i965) && entrypoint == VAEntrypointVLD) {
540 va_status = VA_STATUS_SUCCESS;
542 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
547 if (HAS_VPP(i965) && VAEntrypointVideoProc == entrypoint) {
548 va_status = VA_STATUS_SUCCESS;
550 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
554 case VAProfileJPEGBaseline:
555 if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) {
556 va_status = VA_STATUS_SUCCESS;
558 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
562 case VAProfileVP8Version0_3:
563 if ((HAS_VP8_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
564 (HAS_VP8_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
565 va_status = VA_STATUS_SUCCESS;
567 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
571 case VAProfileH264MultiviewHigh:
572 case VAProfileH264StereoHigh:
573 if ((HAS_H264_MVC_DECODING_PROFILE(i965, profile) &&
574 entrypoint == VAEntrypointVLD) ||
575 (HAS_H264_MVC_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
576 va_status = VA_STATUS_SUCCESS;
578 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
584 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
591 i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
592 VAEntrypoint entrypoint)
594 struct i965_driver_data * const i965 = i965_driver_data(ctx);
595 uint32_t chroma_formats = VA_RT_FORMAT_YUV420;
598 case VAProfileH264ConstrainedBaseline:
599 case VAProfileH264Main:
600 case VAProfileH264High:
601 if (HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD)
602 chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
605 case VAProfileH264MultiviewHigh:
606 case VAProfileH264StereoHigh:
607 if (HAS_H264_MVC_DECODING(i965) && entrypoint == VAEntrypointVLD)
608 chroma_formats |= i965->codec_info->h264_dec_chroma_formats;
611 case VAProfileJPEGBaseline:
612 if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD)
613 chroma_formats |= i965->codec_info->jpeg_dec_chroma_formats;
619 return chroma_formats;
623 i965_GetConfigAttributes(VADriverContextP ctx,
625 VAEntrypoint entrypoint,
626 VAConfigAttrib *attrib_list, /* in/out */
632 va_status = i965_validate_config(ctx, profile, entrypoint);
633 if (va_status != VA_STATUS_SUCCESS)
636 /* Other attributes don't seem to be defined */
637 /* What to do if we don't know the attribute? */
638 for (i = 0; i < num_attribs; i++) {
639 switch (attrib_list[i].type) {
640 case VAConfigAttribRTFormat:
641 attrib_list[i].value = i965_get_default_chroma_formats(ctx,
642 profile, entrypoint);
645 case VAConfigAttribRateControl:
646 if (entrypoint == VAEntrypointEncSlice) {
647 attrib_list[i].value = VA_RC_CQP;
649 if (profile != VAProfileMPEG2Main &&
650 profile != VAProfileMPEG2Simple)
651 attrib_list[i].value |= VA_RC_CBR;
655 case VAConfigAttribEncPackedHeaders:
656 if (entrypoint == VAEntrypointEncSlice) {
657 attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
658 if (profile == VAProfileH264ConstrainedBaseline ||
659 profile == VAProfileH264Main ||
660 profile == VAProfileH264High ||
661 profile == VAProfileH264StereoHigh ||
662 profile == VAProfileH264MultiviewHigh) {
663 attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA |
664 VA_ENC_PACKED_HEADER_SLICE);
669 case VAConfigAttribEncMaxRefFrames:
670 if (entrypoint == VAEntrypointEncSlice) {
671 attrib_list[i].value = (1 << 16) | (1 << 0);
677 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
682 return VA_STATUS_SUCCESS;
686 i965_destroy_config(struct object_heap *heap, struct object_base *obj)
688 object_heap_free(heap, obj);
691 static VAConfigAttrib *
692 i965_lookup_config_attribute(struct object_config *obj_config,
693 VAConfigAttribType type)
697 for (i = 0; i < obj_config->num_attribs; i++) {
698 VAConfigAttrib * const attrib = &obj_config->attrib_list[i];
699 if (attrib->type == type)
706 i965_append_config_attribute(struct object_config *obj_config,
707 const VAConfigAttrib *new_attrib)
709 VAConfigAttrib *attrib;
711 if (obj_config->num_attribs >= I965_MAX_CONFIG_ATTRIBUTES)
712 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
714 attrib = &obj_config->attrib_list[obj_config->num_attribs++];
715 attrib->type = new_attrib->type;
716 attrib->value = new_attrib->value;
717 return VA_STATUS_SUCCESS;
721 i965_ensure_config_attribute(struct object_config *obj_config,
722 const VAConfigAttrib *new_attrib)
724 VAConfigAttrib *attrib;
726 /* Check for existing attributes */
727 attrib = i965_lookup_config_attribute(obj_config, new_attrib->type);
729 /* Update existing attribute */
730 attrib->value = new_attrib->value;
731 return VA_STATUS_SUCCESS;
733 return i965_append_config_attribute(obj_config, new_attrib);
737 i965_CreateConfig(VADriverContextP ctx,
739 VAEntrypoint entrypoint,
740 VAConfigAttrib *attrib_list,
742 VAConfigID *config_id) /* out */
744 struct i965_driver_data * const i965 = i965_driver_data(ctx);
745 struct object_config *obj_config;
750 vaStatus = i965_validate_config(ctx, profile, entrypoint);
752 if (VA_STATUS_SUCCESS != vaStatus) {
756 configID = NEW_CONFIG_ID();
757 obj_config = CONFIG(configID);
759 if (NULL == obj_config) {
760 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
764 obj_config->profile = profile;
765 obj_config->entrypoint = entrypoint;
766 obj_config->num_attribs = 0;
768 for (i = 0; i < num_attribs; i++) {
769 vaStatus = i965_ensure_config_attribute(obj_config, &attrib_list[i]);
770 if (vaStatus != VA_STATUS_SUCCESS)
774 if (vaStatus == VA_STATUS_SUCCESS) {
775 VAConfigAttrib attrib, *attrib_found;
776 attrib.type = VAConfigAttribRTFormat;
777 attrib.value = i965_get_default_chroma_formats(ctx, profile, entrypoint);
778 attrib_found = i965_lookup_config_attribute(obj_config, attrib.type);
779 if (!attrib_found || !attrib_found->value)
780 vaStatus = i965_append_config_attribute(obj_config, &attrib);
781 else if (!(attrib_found->value & attrib.value))
782 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
786 if (VA_STATUS_SUCCESS != vaStatus) {
787 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
789 *config_id = configID;
796 i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
798 struct i965_driver_data *i965 = i965_driver_data(ctx);
799 struct object_config *obj_config = CONFIG(config_id);
802 if (NULL == obj_config) {
803 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
807 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
808 return VA_STATUS_SUCCESS;
811 VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
812 VAConfigID config_id,
813 VAProfile *profile, /* out */
814 VAEntrypoint *entrypoint, /* out */
815 VAConfigAttrib *attrib_list, /* out */
816 int *num_attribs) /* out */
818 struct i965_driver_data *i965 = i965_driver_data(ctx);
819 struct object_config *obj_config = CONFIG(config_id);
820 VAStatus vaStatus = VA_STATUS_SUCCESS;
823 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
824 *profile = obj_config->profile;
825 *entrypoint = obj_config->entrypoint;
826 *num_attribs = obj_config->num_attribs;
828 for(i = 0; i < obj_config->num_attribs; i++) {
829 attrib_list[i] = obj_config->attrib_list[i];
836 i965_destroy_surface_storage(struct object_surface *obj_surface)
841 dri_bo_unreference(obj_surface->bo);
842 obj_surface->bo = NULL;
844 if (obj_surface->free_private_data != NULL) {
845 obj_surface->free_private_data(&obj_surface->private_data);
846 obj_surface->private_data = NULL;
851 i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
853 struct object_surface *obj_surface = (struct object_surface *)obj;
855 i965_destroy_surface_storage(obj_surface);
856 object_heap_free(heap, obj);
860 i965_surface_native_memory(VADriverContextP ctx,
861 struct object_surface *obj_surface,
865 struct i965_driver_data *i965 = i965_driver_data(ctx);
866 int tiling = HAS_TILED_SURFACE(i965);
868 if (!expected_fourcc)
869 return VA_STATUS_SUCCESS;
871 // todo, should we disable tiling for 422 format?
872 if (expected_fourcc == VA_FOURCC_I420 ||
873 expected_fourcc == VA_FOURCC_IYUV ||
874 expected_fourcc == VA_FOURCC_YV12 ||
875 expected_fourcc == VA_FOURCC_YV16)
878 i965_check_alloc_surface_bo(ctx, obj_surface, tiling, expected_fourcc, get_sampling_from_fourcc(expected_fourcc));
880 return VA_STATUS_SUCCESS;
884 i965_suface_external_memory(VADriverContextP ctx,
885 struct object_surface *obj_surface,
886 int external_memory_type,
887 VASurfaceAttribExternalBuffers *memory_attibute,
890 struct i965_driver_data *i965 = i965_driver_data(ctx);
892 if (!memory_attibute ||
893 !memory_attibute->buffers ||
894 index > memory_attibute->num_buffers)
895 return VA_STATUS_ERROR_INVALID_PARAMETER;
897 ASSERT_RET(obj_surface->orig_width == memory_attibute->width, VA_STATUS_ERROR_INVALID_PARAMETER);
898 ASSERT_RET(obj_surface->orig_height == memory_attibute->height, VA_STATUS_ERROR_INVALID_PARAMETER);
899 ASSERT_RET(memory_attibute->num_planes >= 1, VA_STATUS_ERROR_INVALID_PARAMETER);
901 obj_surface->fourcc = memory_attibute->pixel_format;
902 obj_surface->width = memory_attibute->pitches[0];
903 obj_surface->size = memory_attibute->data_size;
905 if (memory_attibute->num_planes == 1)
906 obj_surface->height = memory_attibute->data_size / obj_surface->width;
908 obj_surface->height = memory_attibute->offsets[1] / obj_surface->width;
910 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
911 obj_surface->x_cr_offset = 0;
913 switch (obj_surface->fourcc) {
915 ASSERT_RET(memory_attibute->num_planes == 2, VA_STATUS_ERROR_INVALID_PARAMETER);
916 ASSERT_RET(memory_attibute->pitches[0] == memory_attibute->pitches[1], VA_STATUS_ERROR_INVALID_PARAMETER);
918 obj_surface->subsampling = SUBSAMPLE_YUV420;
919 obj_surface->y_cb_offset = obj_surface->height;
920 obj_surface->y_cr_offset = obj_surface->height;
921 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
922 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
923 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
929 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
930 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
932 obj_surface->subsampling = SUBSAMPLE_YUV420;
933 obj_surface->y_cr_offset = obj_surface->height;
934 obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
935 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
936 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
937 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
944 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
945 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
947 obj_surface->subsampling = SUBSAMPLE_YUV420;
948 obj_surface->y_cb_offset = obj_surface->height;
949 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
950 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
951 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
952 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
958 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
960 obj_surface->subsampling = SUBSAMPLE_YUV422H;
961 obj_surface->y_cb_offset = 0;
962 obj_surface->y_cr_offset = 0;
963 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
964 obj_surface->cb_cr_height = obj_surface->orig_height;
965 obj_surface->cb_cr_pitch = memory_attibute->pitches[0];
973 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
975 obj_surface->subsampling = SUBSAMPLE_RGBX;
976 obj_surface->y_cb_offset = 0;
977 obj_surface->y_cr_offset = 0;
978 obj_surface->cb_cr_width = 0;
979 obj_surface->cb_cr_height = 0;
980 obj_surface->cb_cr_pitch = 0;
984 case VA_FOURCC_Y800: /* monochrome surface */
985 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
987 obj_surface->subsampling = SUBSAMPLE_YUV400;
988 obj_surface->y_cb_offset = 0;
989 obj_surface->y_cr_offset = 0;
990 obj_surface->cb_cr_width = 0;
991 obj_surface->cb_cr_height = 0;
992 obj_surface->cb_cr_pitch = 0;
997 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
998 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1000 obj_surface->subsampling = SUBSAMPLE_YUV411;
1001 obj_surface->y_cb_offset = 0;
1002 obj_surface->y_cr_offset = 0;
1003 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
1004 obj_surface->cb_cr_height = obj_surface->orig_height;
1005 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1009 case VA_FOURCC_422H:
1010 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1011 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1013 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1014 obj_surface->y_cb_offset = obj_surface->height;
1015 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1016 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1017 obj_surface->cb_cr_height = obj_surface->orig_height;
1018 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1022 case VA_FOURCC_YV16:
1023 assert(memory_attibute->num_planes == 3);
1024 assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
1026 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1027 obj_surface->y_cr_offset = memory_attibute->offsets[1] / obj_surface->width;
1028 obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
1029 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
1030 obj_surface->cb_cr_height = obj_surface->orig_height;
1031 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1035 case VA_FOURCC_422V:
1036 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1037 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1039 obj_surface->subsampling = SUBSAMPLE_YUV422H;
1040 obj_surface->y_cb_offset = obj_surface->height;
1041 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1042 obj_surface->cb_cr_width = obj_surface->orig_width;
1043 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
1044 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1048 case VA_FOURCC_444P:
1049 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
1050 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
1052 obj_surface->subsampling = SUBSAMPLE_YUV444;
1053 obj_surface->y_cb_offset = obj_surface->height;
1054 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
1055 obj_surface->cb_cr_width = obj_surface->orig_width;
1056 obj_surface->cb_cr_height = obj_surface->orig_height;
1057 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
1063 return VA_STATUS_ERROR_INVALID_PARAMETER;
1066 if (external_memory_type == I965_SURFACE_MEM_GEM_FLINK)
1067 obj_surface->bo = drm_intel_bo_gem_create_from_name(i965->intel.bufmgr,
1068 "gem flinked vaapi surface",
1069 memory_attibute->buffers[index]);
1070 else if (external_memory_type == I965_SURFACE_MEM_DRM_PRIME)
1071 obj_surface->bo = drm_intel_bo_gem_create_from_prime(i965->intel.bufmgr,
1072 memory_attibute->buffers[index],
1075 if (!obj_surface->bo)
1076 return VA_STATUS_ERROR_INVALID_PARAMETER;
1078 return VA_STATUS_SUCCESS;
1081 /* byte-per-pixel of the first plane */
1083 bpp_1stplane_by_fourcc(unsigned int fourcc)
1085 const i965_fourcc_info *info = get_fourcc_info(fourcc);
1087 if (info && (info->flag & I_S))
1088 return info->bpp[0] / 8;
1094 i965_CreateSurfaces2(
1095 VADriverContextP ctx,
1096 unsigned int format,
1098 unsigned int height,
1099 VASurfaceID *surfaces,
1100 unsigned int num_surfaces,
1101 VASurfaceAttrib *attrib_list,
1102 unsigned int num_attribs
1105 struct i965_driver_data *i965 = i965_driver_data(ctx);
1107 VAStatus vaStatus = VA_STATUS_SUCCESS;
1108 int expected_fourcc = 0;
1109 int memory_type = I965_SURFACE_MEM_NATIVE; /* native */
1110 VASurfaceAttribExternalBuffers *memory_attibute = NULL;
1112 for (i = 0; i < num_attribs && attrib_list; i++) {
1113 if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
1114 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
1115 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
1116 expected_fourcc = attrib_list[i].value.value.i;
1119 if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&
1120 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
1122 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
1124 if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
1125 memory_type = I965_SURFACE_MEM_GEM_FLINK; /* flinked GEM handle */
1126 else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)
1127 memory_type = I965_SURFACE_MEM_DRM_PRIME; /* drm prime fd */
1128 else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_VA)
1129 memory_type = I965_SURFACE_MEM_NATIVE; /* va native memory, to be allocated */
1132 if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&
1133 (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {
1134 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypePointer, VA_STATUS_ERROR_INVALID_PARAMETER);
1135 memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;
1139 /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used
1140 * for post-processing (including color conversion) */
1141 if (VA_RT_FORMAT_YUV420 != format &&
1142 VA_RT_FORMAT_YUV422 != format &&
1143 VA_RT_FORMAT_YUV444 != format &&
1144 VA_RT_FORMAT_YUV411 != format &&
1145 VA_RT_FORMAT_YUV400 != format &&
1146 VA_RT_FORMAT_RGB32 != format) {
1147 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
1150 for (i = 0; i < num_surfaces; i++) {
1151 int surfaceID = NEW_SURFACE_ID();
1152 struct object_surface *obj_surface = SURFACE(surfaceID);
1154 if (NULL == obj_surface) {
1155 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1159 surfaces[i] = surfaceID;
1160 obj_surface->status = VASurfaceReady;
1161 obj_surface->orig_width = width;
1162 obj_surface->orig_height = height;
1163 obj_surface->user_disable_tiling = false;
1164 obj_surface->user_h_stride_set = false;
1165 obj_surface->user_v_stride_set = false;
1167 obj_surface->subpic_render_idx = 0;
1168 for(j = 0; j < I965_MAX_SUBPIC_SUM; j++){
1169 obj_surface->subpic[j] = VA_INVALID_ID;
1170 obj_surface->obj_subpic[j] = NULL;
1173 assert(i965->codec_info->min_linear_wpitch);
1174 assert(i965->codec_info->min_linear_hpitch);
1175 obj_surface->width = ALIGN(width, i965->codec_info->min_linear_wpitch);
1176 obj_surface->height = ALIGN(height, i965->codec_info->min_linear_hpitch);
1177 obj_surface->flags = SURFACE_REFERENCED;
1178 obj_surface->fourcc = 0;
1179 obj_surface->bo = NULL;
1180 obj_surface->locked_image_id = VA_INVALID_ID;
1181 obj_surface->private_data = NULL;
1182 obj_surface->free_private_data = NULL;
1183 obj_surface->subsampling = SUBSAMPLE_YUV420;
1185 switch (memory_type) {
1186 case I965_SURFACE_MEM_NATIVE:
1187 if (memory_attibute) {
1188 if (!(memory_attibute->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING))
1189 obj_surface->user_disable_tiling = true;
1191 if (memory_attibute->pixel_format) {
1192 if (expected_fourcc)
1193 ASSERT_RET(memory_attibute->pixel_format == expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1195 expected_fourcc = memory_attibute->pixel_format;
1197 ASSERT_RET(expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1198 if (memory_attibute->pitches[0]) {
1199 int bpp_1stplane = bpp_1stplane_by_fourcc(expected_fourcc);
1200 ASSERT_RET(bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
1201 obj_surface->width = memory_attibute->pitches[0]/bpp_1stplane;
1202 obj_surface->user_h_stride_set = true;
1203 ASSERT_RET(IS_ALIGNED(obj_surface->width, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1204 ASSERT_RET(obj_surface->width >= width, VA_STATUS_ERROR_INVALID_PARAMETER);
1206 if (memory_attibute->offsets[1]) {
1207 ASSERT_RET(!memory_attibute->offsets[0], VA_STATUS_ERROR_INVALID_PARAMETER);
1208 obj_surface->height = memory_attibute->offsets[1]/memory_attibute->pitches[0];
1209 obj_surface->user_v_stride_set = true;
1210 ASSERT_RET(IS_ALIGNED(obj_surface->height, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1211 ASSERT_RET(obj_surface->height >= height, VA_STATUS_ERROR_INVALID_PARAMETER);
1215 i965_surface_native_memory(ctx,
1221 case I965_SURFACE_MEM_GEM_FLINK:
1222 case I965_SURFACE_MEM_DRM_PRIME:
1223 i965_suface_external_memory(ctx,
1232 /* Error recovery */
1233 if (VA_STATUS_SUCCESS != vaStatus) {
1234 /* surfaces[i-1] was the last successful allocation */
1236 struct object_surface *obj_surface = SURFACE(surfaces[i]);
1238 surfaces[i] = VA_INVALID_SURFACE;
1239 assert(obj_surface);
1240 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1248 i965_CreateSurfaces(VADriverContextP ctx,
1253 VASurfaceID *surfaces) /* out */
1255 return i965_CreateSurfaces2(ctx,
1266 i965_DestroySurfaces(VADriverContextP ctx,
1267 VASurfaceID *surface_list,
1270 struct i965_driver_data *i965 = i965_driver_data(ctx);
1273 for (i = num_surfaces; i--; ) {
1274 struct object_surface *obj_surface = SURFACE(surface_list[i]);
1276 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
1277 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1280 return VA_STATUS_SUCCESS;
1284 i965_QueryImageFormats(VADriverContextP ctx,
1285 VAImageFormat *format_list, /* out */
1286 int *num_formats) /* out */
1290 for (n = 0; i965_image_formats_map[n].va_format.fourcc != 0; n++) {
1291 const i965_image_format_map_t * const m = &i965_image_formats_map[n];
1293 format_list[n] = m->va_format;
1299 return VA_STATUS_SUCCESS;
1303 * Guess the format when the usage of a VA surface is unknown
1304 * 1. Without a valid context: YV12
1305 * 2. The current context is valid:
1306 * a) always NV12 on GEN6 and later
1307 * b) I420 for MPEG-2 and NV12 for other codec on GEN4 & GEN5
1310 i965_guess_surface_format(VADriverContextP ctx,
1311 VASurfaceID surface,
1312 unsigned int *fourcc,
1313 unsigned int *is_tiled)
1315 struct i965_driver_data *i965 = i965_driver_data(ctx);
1316 struct object_context *obj_context = NULL;
1317 struct object_config *obj_config = NULL;
1319 *fourcc = VA_FOURCC_YV12;
1322 if (i965->current_context_id == VA_INVALID_ID)
1325 obj_context = CONTEXT(i965->current_context_id);
1330 obj_config = obj_context->obj_config;
1336 if (IS_GEN6(i965->intel.device_info) ||
1337 IS_GEN7(i965->intel.device_info) ||
1338 IS_GEN8(i965->intel.device_info)) {
1339 *fourcc = VA_FOURCC_NV12;
1344 switch (obj_config->profile) {
1345 case VAProfileMPEG2Simple:
1346 case VAProfileMPEG2Main:
1347 *fourcc = VA_FOURCC_I420;
1352 *fourcc = VA_FOURCC_NV12;
1359 i965_QuerySubpictureFormats(VADriverContextP ctx,
1360 VAImageFormat *format_list, /* out */
1361 unsigned int *flags, /* out */
1362 unsigned int *num_formats) /* out */
1366 for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
1367 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
1369 format_list[n] = m->va_format;
1371 flags[n] = m->va_flags;
1377 return VA_STATUS_SUCCESS;
1381 i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
1383 // struct object_subpic *obj_subpic = (struct object_subpic *)obj;
1385 object_heap_free(heap, obj);
1389 i965_CreateSubpicture(VADriverContextP ctx,
1391 VASubpictureID *subpicture) /* out */
1393 struct i965_driver_data *i965 = i965_driver_data(ctx);
1394 VASubpictureID subpicID = NEW_SUBPIC_ID()
1395 struct object_subpic *obj_subpic = SUBPIC(subpicID);
1398 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1400 struct object_image *obj_image = IMAGE(image);
1402 return VA_STATUS_ERROR_INVALID_IMAGE;
1404 const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
1406 return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
1408 *subpicture = subpicID;
1409 obj_subpic->image = image;
1410 obj_subpic->obj_image = obj_image;
1411 obj_subpic->format = m->format;
1412 obj_subpic->width = obj_image->image.width;
1413 obj_subpic->height = obj_image->image.height;
1414 obj_subpic->pitch = obj_image->image.pitches[0];
1415 obj_subpic->bo = obj_image->bo;
1416 obj_subpic->global_alpha = 1.0;
1418 return VA_STATUS_SUCCESS;
1422 i965_DestroySubpicture(VADriverContextP ctx,
1423 VASubpictureID subpicture)
1425 struct i965_driver_data *i965 = i965_driver_data(ctx);
1426 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1429 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1431 ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
1432 i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
1433 return VA_STATUS_SUCCESS;
1437 i965_SetSubpictureImage(VADriverContextP ctx,
1438 VASubpictureID subpicture,
1442 return VA_STATUS_ERROR_UNIMPLEMENTED;
1446 i965_SetSubpictureChromakey(VADriverContextP ctx,
1447 VASubpictureID subpicture,
1448 unsigned int chromakey_min,
1449 unsigned int chromakey_max,
1450 unsigned int chromakey_mask)
1453 return VA_STATUS_ERROR_UNIMPLEMENTED;
1457 i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
1458 VASubpictureID subpicture,
1461 struct i965_driver_data *i965 = i965_driver_data(ctx);
1462 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1464 if(global_alpha > 1.0 || global_alpha < 0.0){
1465 return VA_STATUS_ERROR_INVALID_PARAMETER;
1469 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1471 obj_subpic->global_alpha = global_alpha;
1473 return VA_STATUS_SUCCESS;
1477 i965_AssociateSubpicture(VADriverContextP ctx,
1478 VASubpictureID subpicture,
1479 VASurfaceID *target_surfaces,
1481 short src_x, /* upper left offset in subpicture */
1483 unsigned short src_width,
1484 unsigned short src_height,
1485 short dest_x, /* upper left offset in surface */
1487 unsigned short dest_width,
1488 unsigned short dest_height,
1490 * whether to enable chroma-keying or global-alpha
1491 * see VA_SUBPICTURE_XXX values
1495 struct i965_driver_data *i965 = i965_driver_data(ctx);
1496 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1500 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1502 ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
1504 obj_subpic->src_rect.x = src_x;
1505 obj_subpic->src_rect.y = src_y;
1506 obj_subpic->src_rect.width = src_width;
1507 obj_subpic->src_rect.height = src_height;
1508 obj_subpic->dst_rect.x = dest_x;
1509 obj_subpic->dst_rect.y = dest_y;
1510 obj_subpic->dst_rect.width = dest_width;
1511 obj_subpic->dst_rect.height = dest_height;
1512 obj_subpic->flags = flags;
1514 for (i = 0; i < num_surfaces; i++) {
1515 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1517 return VA_STATUS_ERROR_INVALID_SURFACE;
1519 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1520 if(obj_surface->subpic[j] == VA_INVALID_ID){
1521 assert(obj_surface->obj_subpic[j] == NULL);
1522 obj_surface->subpic[j] = subpicture;
1523 obj_surface->obj_subpic[j] = obj_subpic;
1528 if(j == I965_MAX_SUBPIC_SUM){
1529 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1533 return VA_STATUS_SUCCESS;
1538 i965_DeassociateSubpicture(VADriverContextP ctx,
1539 VASubpictureID subpicture,
1540 VASurfaceID *target_surfaces,
1543 struct i965_driver_data *i965 = i965_driver_data(ctx);
1544 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1548 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1550 for (i = 0; i < num_surfaces; i++) {
1551 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1553 return VA_STATUS_ERROR_INVALID_SURFACE;
1555 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1556 if (obj_surface->subpic[j] == subpicture) {
1557 assert(obj_surface->obj_subpic[j] == obj_subpic);
1558 obj_surface->subpic[j] = VA_INVALID_ID;
1559 obj_surface->obj_subpic[j] = NULL;
1564 if(j == I965_MAX_SUBPIC_SUM){
1565 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1568 return VA_STATUS_SUCCESS;
1572 i965_reference_buffer_store(struct buffer_store **ptr,
1573 struct buffer_store *buffer_store)
1575 assert(*ptr == NULL);
1578 buffer_store->ref_count++;
1579 *ptr = buffer_store;
1584 i965_release_buffer_store(struct buffer_store **ptr)
1586 struct buffer_store *buffer_store = *ptr;
1588 if (buffer_store == NULL)
1591 assert(buffer_store->bo || buffer_store->buffer);
1592 assert(!(buffer_store->bo && buffer_store->buffer));
1593 buffer_store->ref_count--;
1595 if (buffer_store->ref_count == 0) {
1596 dri_bo_unreference(buffer_store->bo);
1597 free(buffer_store->buffer);
1598 buffer_store->bo = NULL;
1599 buffer_store->buffer = NULL;
1607 i965_destroy_context(struct object_heap *heap, struct object_base *obj)
1609 struct object_context *obj_context = (struct object_context *)obj;
1612 if (obj_context->hw_context) {
1613 obj_context->hw_context->destroy(obj_context->hw_context);
1614 obj_context->hw_context = NULL;
1617 if (obj_context->codec_type == CODEC_PROC) {
1618 i965_release_buffer_store(&obj_context->codec_state.proc.pipeline_param);
1620 } else if (obj_context->codec_type == CODEC_ENC) {
1621 assert(obj_context->codec_state.encode.num_slice_params <= obj_context->codec_state.encode.max_slice_params);
1622 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
1623 i965_release_buffer_store(&obj_context->codec_state.encode.seq_param);
1625 for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++)
1626 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
1628 free(obj_context->codec_state.encode.slice_params);
1630 assert(obj_context->codec_state.encode.num_slice_params_ext <= obj_context->codec_state.encode.max_slice_params_ext);
1631 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
1632 i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
1634 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
1635 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
1637 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
1638 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
1640 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
1641 i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i]);
1643 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
1644 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
1646 free(obj_context->codec_state.encode.slice_params_ext);
1647 if (obj_context->codec_state.encode.slice_rawdata_index) {
1648 free(obj_context->codec_state.encode.slice_rawdata_index);
1649 obj_context->codec_state.encode.slice_rawdata_index = NULL;
1651 if (obj_context->codec_state.encode.slice_rawdata_count) {
1652 free(obj_context->codec_state.encode.slice_rawdata_count);
1653 obj_context->codec_state.encode.slice_rawdata_count = NULL;
1656 if (obj_context->codec_state.encode.slice_header_index) {
1657 free(obj_context->codec_state.encode.slice_header_index);
1658 obj_context->codec_state.encode.slice_header_index = NULL;
1661 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
1662 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
1663 free(obj_context->codec_state.encode.packed_header_params_ext);
1665 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
1666 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
1667 free(obj_context->codec_state.encode.packed_header_data_ext);
1670 assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
1671 assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
1673 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
1674 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
1675 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
1677 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++)
1678 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
1680 for (i = 0; i < obj_context->codec_state.decode.num_slice_datas; i++)
1681 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
1683 free(obj_context->codec_state.decode.slice_params);
1684 free(obj_context->codec_state.decode.slice_datas);
1687 free(obj_context->render_targets);
1688 object_heap_free(heap, obj);
1692 i965_CreateContext(VADriverContextP ctx,
1693 VAConfigID config_id,
1697 VASurfaceID *render_targets,
1698 int num_render_targets,
1699 VAContextID *context) /* out */
1701 struct i965_driver_data *i965 = i965_driver_data(ctx);
1702 struct i965_render_state *render_state = &i965->render_state;
1703 struct object_config *obj_config = CONFIG(config_id);
1704 struct object_context *obj_context = NULL;
1705 VAConfigAttrib *attrib;
1706 VAStatus vaStatus = VA_STATUS_SUCCESS;
1710 if (NULL == obj_config) {
1711 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
1715 if (picture_width > i965->codec_info->max_width ||
1716 picture_height > i965->codec_info->max_height) {
1717 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
1722 /* Validate picture dimensions */
1723 contextID = NEW_CONTEXT_ID();
1724 obj_context = CONTEXT(contextID);
1726 if (NULL == obj_context) {
1727 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1731 render_state->inited = 1;
1733 switch (obj_config->profile) {
1734 case VAProfileH264ConstrainedBaseline:
1735 case VAProfileH264Main:
1736 case VAProfileH264High:
1737 if (!HAS_H264_DECODING(i965) &&
1738 !HAS_H264_ENCODING(i965))
1739 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1740 render_state->interleaved_uv = 1;
1742 case VAProfileH264MultiviewHigh:
1743 case VAProfileH264StereoHigh:
1744 if (!HAS_H264_MVC_DECODING(i965))
1745 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1746 render_state->interleaved_uv = 1;
1749 render_state->interleaved_uv = !!(IS_GEN6(i965->intel.device_info) || IS_GEN7(i965->intel.device_info) || IS_GEN8(i965->intel.device_info));
1753 *context = contextID;
1754 obj_context->flags = flag;
1755 obj_context->context_id = contextID;
1756 obj_context->obj_config = obj_config;
1757 obj_context->picture_width = picture_width;
1758 obj_context->picture_height = picture_height;
1759 obj_context->num_render_targets = num_render_targets;
1760 obj_context->render_targets =
1761 (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
1762 obj_context->hw_context = NULL;
1764 for(i = 0; i < num_render_targets; i++) {
1765 if (NULL == SURFACE(render_targets[i])) {
1766 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1770 obj_context->render_targets[i] = render_targets[i];
1773 if (VA_STATUS_SUCCESS == vaStatus) {
1774 if (VAEntrypointVideoProc == obj_config->entrypoint) {
1775 obj_context->codec_type = CODEC_PROC;
1776 memset(&obj_context->codec_state.proc, 0, sizeof(obj_context->codec_state.proc));
1777 obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
1778 assert(i965->codec_info->proc_hw_context_init);
1779 obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
1780 } else if (VAEntrypointEncSlice == obj_config->entrypoint) { /*encode routin only*/
1781 obj_context->codec_type = CODEC_ENC;
1782 memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
1783 obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
1784 obj_context->codec_state.encode.max_slice_params = NUM_SLICES;
1785 obj_context->codec_state.encode.slice_params = calloc(obj_context->codec_state.encode.max_slice_params,
1786 sizeof(*obj_context->codec_state.encode.slice_params));
1787 obj_context->codec_state.encode.max_packed_header_params_ext = NUM_SLICES;
1788 obj_context->codec_state.encode.packed_header_params_ext =
1789 calloc(obj_context->codec_state.encode.max_packed_header_params_ext,
1790 sizeof(struct buffer_store *));
1792 obj_context->codec_state.encode.max_packed_header_data_ext = NUM_SLICES;
1793 obj_context->codec_state.encode.packed_header_data_ext =
1794 calloc(obj_context->codec_state.encode.max_packed_header_data_ext,
1795 sizeof(struct buffer_store *));
1797 obj_context->codec_state.encode.slice_num = NUM_SLICES;
1798 obj_context->codec_state.encode.slice_rawdata_index =
1799 calloc(obj_context->codec_state.encode.slice_num, sizeof(int));
1800 obj_context->codec_state.encode.slice_rawdata_count =
1801 calloc(obj_context->codec_state.encode.slice_num, sizeof(int));
1803 obj_context->codec_state.encode.slice_header_index =
1804 calloc(obj_context->codec_state.encode.slice_num, sizeof(int));
1806 assert(i965->codec_info->enc_hw_context_init);
1807 obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
1809 obj_context->codec_type = CODEC_DEC;
1810 memset(&obj_context->codec_state.decode, 0, sizeof(obj_context->codec_state.decode));
1811 obj_context->codec_state.decode.current_render_target = -1;
1812 obj_context->codec_state.decode.max_slice_params = NUM_SLICES;
1813 obj_context->codec_state.decode.max_slice_datas = NUM_SLICES;
1814 obj_context->codec_state.decode.slice_params = calloc(obj_context->codec_state.decode.max_slice_params,
1815 sizeof(*obj_context->codec_state.decode.slice_params));
1816 obj_context->codec_state.decode.slice_datas = calloc(obj_context->codec_state.decode.max_slice_datas,
1817 sizeof(*obj_context->codec_state.decode.slice_datas));
1819 assert(i965->codec_info->dec_hw_context_init);
1820 obj_context->hw_context = i965->codec_info->dec_hw_context_init(ctx, obj_config);
1824 attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribRTFormat);
1826 return VA_STATUS_ERROR_INVALID_CONFIG;
1827 obj_context->codec_state.base.chroma_formats = attrib->value;
1829 /* Error recovery */
1830 if (VA_STATUS_SUCCESS != vaStatus) {
1831 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1834 i965->current_context_id = contextID;
1840 i965_DestroyContext(VADriverContextP ctx, VAContextID context)
1842 struct i965_driver_data *i965 = i965_driver_data(ctx);
1843 struct object_context *obj_context = CONTEXT(context);
1845 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
1847 if (i965->current_context_id == context)
1848 i965->current_context_id = VA_INVALID_ID;
1850 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1852 return VA_STATUS_SUCCESS;
1856 i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
1858 struct object_buffer *obj_buffer = (struct object_buffer *)obj;
1860 assert(obj_buffer->buffer_store);
1861 i965_release_buffer_store(&obj_buffer->buffer_store);
1862 object_heap_free(heap, obj);
1866 i965_create_buffer_internal(VADriverContextP ctx,
1867 VAContextID context,
1870 unsigned int num_elements,
1875 struct i965_driver_data *i965 = i965_driver_data(ctx);
1876 struct object_buffer *obj_buffer = NULL;
1877 struct buffer_store *buffer_store = NULL;
1882 case VAPictureParameterBufferType:
1883 case VAIQMatrixBufferType:
1884 case VAQMatrixBufferType:
1885 case VABitPlaneBufferType:
1886 case VASliceGroupMapBufferType:
1887 case VASliceParameterBufferType:
1888 case VASliceDataBufferType:
1889 case VAMacroblockParameterBufferType:
1890 case VAResidualDataBufferType:
1891 case VADeblockingParameterBufferType:
1892 case VAImageBufferType:
1893 case VAEncCodedBufferType:
1894 case VAEncSequenceParameterBufferType:
1895 case VAEncPictureParameterBufferType:
1896 case VAEncSliceParameterBufferType:
1897 case VAEncPackedHeaderParameterBufferType:
1898 case VAEncPackedHeaderDataBufferType:
1899 case VAEncMiscParameterBufferType:
1900 case VAProcPipelineParameterBufferType:
1901 case VAProcFilterParameterBufferType:
1902 case VAHuffmanTableBufferType:
1903 case VAProbabilityBufferType:
1908 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1911 bufferID = NEW_BUFFER_ID();
1912 obj_buffer = BUFFER(bufferID);
1914 if (NULL == obj_buffer) {
1915 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1918 if (type == VAEncCodedBufferType) {
1919 size += I965_CODEDBUFFER_HEADER_SIZE;
1920 size += 0x1000; /* for upper bound check */
1923 obj_buffer->max_num_elements = num_elements;
1924 obj_buffer->num_elements = num_elements;
1925 obj_buffer->size_element = size;
1926 obj_buffer->type = type;
1927 obj_buffer->buffer_store = NULL;
1928 buffer_store = calloc(1, sizeof(struct buffer_store));
1929 assert(buffer_store);
1930 buffer_store->ref_count = 1;
1932 if (store_bo != NULL) {
1933 buffer_store->bo = store_bo;
1934 dri_bo_reference(buffer_store->bo);
1937 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
1938 } else if (type == VASliceDataBufferType ||
1939 type == VAImageBufferType ||
1940 type == VAEncCodedBufferType ||
1941 type == VAProbabilityBufferType) {
1942 buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
1944 size * num_elements, 64);
1945 assert(buffer_store->bo);
1947 if (type == VAEncCodedBufferType) {
1948 struct i965_coded_buffer_segment *coded_buffer_segment;
1950 dri_bo_map(buffer_store->bo, 1);
1951 coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual;
1952 coded_buffer_segment->base.size = size - I965_CODEDBUFFER_HEADER_SIZE;
1953 coded_buffer_segment->base.bit_offset = 0;
1954 coded_buffer_segment->base.status = 0;
1955 coded_buffer_segment->base.buf = NULL;
1956 coded_buffer_segment->base.next = NULL;
1957 coded_buffer_segment->mapped = 0;
1958 coded_buffer_segment->codec = 0;
1959 dri_bo_unmap(buffer_store->bo);
1961 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
1967 if (type == VAEncPackedHeaderDataBufferType) {
1968 msize = ALIGN(size, 4);
1971 buffer_store->buffer = malloc(msize * num_elements);
1972 assert(buffer_store->buffer);
1975 memcpy(buffer_store->buffer, data, size * num_elements);
1978 buffer_store->num_elements = obj_buffer->num_elements;
1979 i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
1980 i965_release_buffer_store(&buffer_store);
1983 return VA_STATUS_SUCCESS;
1987 i965_CreateBuffer(VADriverContextP ctx,
1988 VAContextID context, /* in */
1989 VABufferType type, /* in */
1990 unsigned int size, /* in */
1991 unsigned int num_elements, /* in */
1992 void *data, /* in */
1993 VABufferID *buf_id) /* out */
1995 return i965_create_buffer_internal(ctx, context, type, size, num_elements, data, NULL, buf_id);
2000 i965_BufferSetNumElements(VADriverContextP ctx,
2001 VABufferID buf_id, /* in */
2002 unsigned int num_elements) /* in */
2004 struct i965_driver_data *i965 = i965_driver_data(ctx);
2005 struct object_buffer *obj_buffer = BUFFER(buf_id);
2006 VAStatus vaStatus = VA_STATUS_SUCCESS;
2008 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2010 if ((num_elements < 0) ||
2011 (num_elements > obj_buffer->max_num_elements)) {
2012 vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2014 obj_buffer->num_elements = num_elements;
2015 if (obj_buffer->buffer_store != NULL) {
2016 obj_buffer->buffer_store->num_elements = num_elements;
2024 i965_MapBuffer(VADriverContextP ctx,
2025 VABufferID buf_id, /* in */
2026 void **pbuf) /* out */
2028 struct i965_driver_data *i965 = i965_driver_data(ctx);
2029 struct object_buffer *obj_buffer = BUFFER(buf_id);
2030 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2032 ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
2033 ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2034 ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_INVALID_BUFFER);
2036 if (NULL != obj_buffer->buffer_store->bo) {
2037 unsigned int tiling, swizzle;
2039 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
2041 if (tiling != I915_TILING_NONE)
2042 drm_intel_gem_bo_map_gtt(obj_buffer->buffer_store->bo);
2044 dri_bo_map(obj_buffer->buffer_store->bo, 1);
2046 ASSERT_RET(obj_buffer->buffer_store->bo->virtual, VA_STATUS_ERROR_OPERATION_FAILED);
2047 *pbuf = obj_buffer->buffer_store->bo->virtual;
2049 if (obj_buffer->type == VAEncCodedBufferType) {
2051 unsigned char *buffer = NULL;
2052 struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual);
2054 if (!coded_buffer_segment->mapped) {
2055 unsigned char delimiter0, delimiter1, delimiter2, delimiter3, delimiter4;
2057 coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
2059 if (coded_buffer_segment->codec == CODEC_H264 ||
2060 coded_buffer_segment->codec == CODEC_H264_MVC) {
2061 delimiter0 = H264_DELIMITER0;
2062 delimiter1 = H264_DELIMITER1;
2063 delimiter2 = H264_DELIMITER2;
2064 delimiter3 = H264_DELIMITER3;
2065 delimiter4 = H264_DELIMITER4;
2066 } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
2067 delimiter0 = MPEG2_DELIMITER0;
2068 delimiter1 = MPEG2_DELIMITER1;
2069 delimiter2 = MPEG2_DELIMITER2;
2070 delimiter3 = MPEG2_DELIMITER3;
2071 delimiter4 = MPEG2_DELIMITER4;
2073 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
2076 for (i = 0; i < obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000; i++) {
2077 if ((buffer[i] == delimiter0) &&
2078 (buffer[i + 1] == delimiter1) &&
2079 (buffer[i + 2] == delimiter2) &&
2080 (buffer[i + 3] == delimiter3) &&
2081 (buffer[i + 4] == delimiter4))
2085 if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000) {
2086 coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
2089 coded_buffer_segment->base.size = i;
2090 coded_buffer_segment->mapped = 1;
2092 assert(coded_buffer_segment->base.buf);
2096 vaStatus = VA_STATUS_SUCCESS;
2097 } else if (NULL != obj_buffer->buffer_store->buffer) {
2098 *pbuf = obj_buffer->buffer_store->buffer;
2099 vaStatus = VA_STATUS_SUCCESS;
2106 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
2108 struct i965_driver_data *i965 = i965_driver_data(ctx);
2109 struct object_buffer *obj_buffer = BUFFER(buf_id);
2110 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2112 if ((buf_id & OBJECT_HEAP_OFFSET_MASK) != BUFFER_ID_OFFSET)
2113 return VA_STATUS_ERROR_INVALID_BUFFER;
2115 ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
2116 ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_OPERATION_FAILED);
2117 ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_OPERATION_FAILED);
2119 if (NULL != obj_buffer->buffer_store->bo) {
2120 unsigned int tiling, swizzle;
2122 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
2124 if (tiling != I915_TILING_NONE)
2125 drm_intel_gem_bo_unmap_gtt(obj_buffer->buffer_store->bo);
2127 dri_bo_unmap(obj_buffer->buffer_store->bo);
2129 vaStatus = VA_STATUS_SUCCESS;
2130 } else if (NULL != obj_buffer->buffer_store->buffer) {
2132 vaStatus = VA_STATUS_SUCCESS;
2139 i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
2141 struct i965_driver_data *i965 = i965_driver_data(ctx);
2142 struct object_buffer *obj_buffer = BUFFER(buffer_id);
2144 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2146 i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
2148 return VA_STATUS_SUCCESS;
2152 i965_BeginPicture(VADriverContextP ctx,
2153 VAContextID context,
2154 VASurfaceID render_target)
2156 struct i965_driver_data *i965 = i965_driver_data(ctx);
2157 struct object_context *obj_context = CONTEXT(context);
2158 struct object_surface *obj_surface = SURFACE(render_target);
2159 struct object_config *obj_config;
2163 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2164 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2165 obj_config = obj_context->obj_config;
2166 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2168 switch (obj_config->profile) {
2169 case VAProfileMPEG2Simple:
2170 case VAProfileMPEG2Main:
2171 vaStatus = VA_STATUS_SUCCESS;
2174 case VAProfileH264ConstrainedBaseline:
2175 case VAProfileH264Main:
2176 case VAProfileH264High:
2177 vaStatus = VA_STATUS_SUCCESS;
2180 case VAProfileH264MultiviewHigh:
2181 case VAProfileH264StereoHigh:
2182 if (HAS_H264_MVC_DECODING_PROFILE(i965, obj_config->profile) ||
2183 HAS_H264_MVC_ENCODING(i965)) {
2184 vaStatus = VA_STATUS_SUCCESS;
2186 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
2190 case VAProfileVC1Simple:
2191 case VAProfileVC1Main:
2192 case VAProfileVC1Advanced:
2193 vaStatus = VA_STATUS_SUCCESS;
2196 case VAProfileJPEGBaseline:
2197 vaStatus = VA_STATUS_SUCCESS;
2201 vaStatus = VA_STATUS_SUCCESS;
2204 case VAProfileVP8Version0_3:
2205 vaStatus = VA_STATUS_SUCCESS;
2209 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
2213 if (obj_context->codec_type == CODEC_PROC) {
2214 obj_context->codec_state.proc.current_render_target = render_target;
2215 } else if (obj_context->codec_type == CODEC_ENC) {
2216 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
2218 for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++) {
2219 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
2222 obj_context->codec_state.encode.num_slice_params = 0;
2225 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
2227 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
2228 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
2230 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
2231 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
2233 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
2234 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
2236 obj_context->codec_state.encode.num_slice_params_ext = 0;
2237 obj_context->codec_state.encode.current_render_target = render_target; /*This is input new frame*/
2238 obj_context->codec_state.encode.last_packed_header_type = 0;
2239 memset(obj_context->codec_state.encode.slice_rawdata_index, 0,
2240 sizeof(int) * obj_context->codec_state.encode.slice_num);
2241 memset(obj_context->codec_state.encode.slice_rawdata_count, 0,
2242 sizeof(int) * obj_context->codec_state.encode.slice_num);
2243 memset(obj_context->codec_state.encode.slice_header_index, 0,
2244 sizeof(int) * obj_context->codec_state.encode.slice_num);
2246 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_params_ext; i++)
2247 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_params_ext[i]);
2248 for (i = 0; i < obj_context->codec_state.encode.num_packed_header_data_ext; i++)
2249 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data_ext[i]);
2250 obj_context->codec_state.encode.num_packed_header_params_ext = 0;
2251 obj_context->codec_state.encode.num_packed_header_data_ext = 0;
2253 obj_context->codec_state.decode.current_render_target = render_target;
2254 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
2255 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
2256 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
2257 i965_release_buffer_store(&obj_context->codec_state.decode.huffman_table);
2259 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++) {
2260 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
2261 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
2264 obj_context->codec_state.decode.num_slice_params = 0;
2265 obj_context->codec_state.decode.num_slice_datas = 0;
2271 #define I965_RENDER_BUFFER(category, name) i965_render_##category##_##name##_buffer(ctx, obj_context, obj_buffer)
2273 #define DEF_RENDER_SINGLE_BUFFER_FUNC(category, name, member) \
2275 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
2276 struct object_context *obj_context, \
2277 struct object_buffer *obj_buffer) \
2279 struct category##_state *category = &obj_context->codec_state.category; \
2280 i965_release_buffer_store(&category->member); \
2281 i965_reference_buffer_store(&category->member, obj_buffer->buffer_store); \
2282 return VA_STATUS_SUCCESS; \
2285 #define DEF_RENDER_MULTI_BUFFER_FUNC(category, name, member) \
2287 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
2288 struct object_context *obj_context, \
2289 struct object_buffer *obj_buffer) \
2291 struct category##_state *category = &obj_context->codec_state.category; \
2292 if (category->num_##member == category->max_##member) { \
2293 category->member = realloc(category->member, (category->max_##member + NUM_SLICES) * sizeof(*category->member)); \
2294 memset(category->member + category->max_##member, 0, NUM_SLICES * sizeof(*category->member)); \
2295 category->max_##member += NUM_SLICES; \
2297 i965_release_buffer_store(&category->member[category->num_##member]); \
2298 i965_reference_buffer_store(&category->member[category->num_##member], obj_buffer->buffer_store); \
2299 category->num_##member++; \
2300 return VA_STATUS_SUCCESS; \
2303 #define I965_RENDER_DECODE_BUFFER(name) I965_RENDER_BUFFER(decode, name)
2305 #define DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(decode, name, member)
2306 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2307 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(iq_matrix, iq_matrix)
2308 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(bit_plane, bit_plane)
2309 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
2310 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(probability_data, probability_data)
2312 #define DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(decode, name, member)
2313 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2314 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_data, slice_datas)
2317 i965_decoder_render_picture(VADriverContextP ctx,
2318 VAContextID context,
2319 VABufferID *buffers,
2322 struct i965_driver_data *i965 = i965_driver_data(ctx);
2323 struct object_context *obj_context = CONTEXT(context);
2324 VAStatus vaStatus = VA_STATUS_SUCCESS;
2327 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2329 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2330 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2333 return VA_STATUS_ERROR_INVALID_BUFFER;
2335 switch (obj_buffer->type) {
2336 case VAPictureParameterBufferType:
2337 vaStatus = I965_RENDER_DECODE_BUFFER(picture_parameter);
2340 case VAIQMatrixBufferType:
2341 vaStatus = I965_RENDER_DECODE_BUFFER(iq_matrix);
2344 case VABitPlaneBufferType:
2345 vaStatus = I965_RENDER_DECODE_BUFFER(bit_plane);
2348 case VASliceParameterBufferType:
2349 vaStatus = I965_RENDER_DECODE_BUFFER(slice_parameter);
2352 case VASliceDataBufferType:
2353 vaStatus = I965_RENDER_DECODE_BUFFER(slice_data);
2356 case VAHuffmanTableBufferType:
2357 vaStatus = I965_RENDER_DECODE_BUFFER(huffman_table);
2360 case VAProbabilityBufferType:
2361 vaStatus = I965_RENDER_DECODE_BUFFER(probability_data);
2365 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2373 #define I965_RENDER_ENCODE_BUFFER(name) I965_RENDER_BUFFER(encode, name)
2375 #define DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(encode, name, member)
2376 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter, seq_param)
2377 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2378 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_control, pic_control)
2379 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(qmatrix, q_matrix)
2380 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(iqmatrix, iq_matrix)
2381 /* extended buffer */
2382 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
2383 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
2385 #define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
2386 // DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2387 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter_ext, slice_params_ext)
2389 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_params_ext, packed_header_params_ext)
2390 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(packed_header_data_ext, packed_header_data_ext)
2393 i965_encoder_render_packed_header_parameter_buffer(VADriverContextP ctx,
2394 struct object_context *obj_context,
2395 struct object_buffer *obj_buffer,
2398 struct encode_state *encode = &obj_context->codec_state.encode;
2400 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2401 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2402 i965_release_buffer_store(&encode->packed_header_param[type_index]);
2403 i965_reference_buffer_store(&encode->packed_header_param[type_index], obj_buffer->buffer_store);
2405 return VA_STATUS_SUCCESS;
2409 i965_encoder_render_packed_header_data_buffer(VADriverContextP ctx,
2410 struct object_context *obj_context,
2411 struct object_buffer *obj_buffer,
2414 struct encode_state *encode = &obj_context->codec_state.encode;
2416 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2417 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2418 i965_release_buffer_store(&encode->packed_header_data[type_index]);
2419 i965_reference_buffer_store(&encode->packed_header_data[type_index], obj_buffer->buffer_store);
2421 return VA_STATUS_SUCCESS;
2425 i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
2426 struct object_context *obj_context,
2427 struct object_buffer *obj_buffer)
2429 struct encode_state *encode = &obj_context->codec_state.encode;
2430 VAEncMiscParameterBuffer *param = NULL;
2432 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2433 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2435 param = (VAEncMiscParameterBuffer *)obj_buffer->buffer_store->buffer;
2437 if (param->type >= ARRAY_ELEMS(encode->misc_param))
2438 return VA_STATUS_ERROR_INVALID_PARAMETER;
2440 i965_release_buffer_store(&encode->misc_param[param->type]);
2441 i965_reference_buffer_store(&encode->misc_param[param->type], obj_buffer->buffer_store);
2443 return VA_STATUS_SUCCESS;
2447 i965_encoder_render_picture(VADriverContextP ctx,
2448 VAContextID context,
2449 VABufferID *buffers,
2452 struct i965_driver_data *i965 = i965_driver_data(ctx);
2453 struct object_context *obj_context = CONTEXT(context);
2454 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2455 struct encode_state *encode;
2458 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2460 encode = &obj_context->codec_state.encode;
2461 for (i = 0; i < num_buffers; i++) {
2462 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2465 return VA_STATUS_ERROR_INVALID_BUFFER;
2467 switch (obj_buffer->type) {
2468 case VAQMatrixBufferType:
2469 vaStatus = I965_RENDER_ENCODE_BUFFER(qmatrix);
2472 case VAIQMatrixBufferType:
2473 vaStatus = I965_RENDER_ENCODE_BUFFER(iqmatrix);
2476 case VAEncSequenceParameterBufferType:
2477 vaStatus = I965_RENDER_ENCODE_BUFFER(sequence_parameter_ext);
2480 case VAEncPictureParameterBufferType:
2481 vaStatus = I965_RENDER_ENCODE_BUFFER(picture_parameter_ext);
2484 case VAEncSliceParameterBufferType:
2485 vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
2486 if (vaStatus == VA_STATUS_SUCCESS) {
2487 /* When the max number of slices is updated, it also needs
2488 * to reallocate the arrays that is used to store
2489 * the packed data index/count for the slice
2491 if (encode->max_slice_params_ext > encode->slice_num) {
2492 int slice_num = encode->slice_num;
2493 encode->slice_num = encode->max_slice_params_ext;
2494 encode->slice_rawdata_index = realloc(encode->slice_rawdata_index,
2495 encode->slice_num * sizeof(int));
2496 encode->slice_rawdata_count = realloc(encode->slice_rawdata_count,
2497 encode->slice_num * sizeof(int));
2498 encode->slice_header_index = realloc(encode->slice_header_index,
2499 encode->slice_num * sizeof(int));
2500 memset(encode->slice_rawdata_index + slice_num, 0,
2501 sizeof(int) * NUM_SLICES);
2502 memset(encode->slice_rawdata_count + slice_num, 0,
2503 sizeof(int) * NUM_SLICES);
2504 memset(encode->slice_header_index + slice_num, 0,
2505 sizeof(int) * NUM_SLICES);
2506 if ((encode->slice_rawdata_index == NULL) ||
2507 (encode->slice_header_index == NULL) ||
2508 (encode->slice_rawdata_count == NULL)) {
2509 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2516 case VAEncPackedHeaderParameterBufferType:
2518 VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer;
2519 encode->last_packed_header_type = param->type;
2521 if ((param->type == VAEncPackedHeaderRawData) ||
2522 (param->type == VAEncPackedHeaderSlice)) {
2523 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext);
2525 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
2528 va_enc_packed_type_to_idx(encode->last_packed_header_type));
2533 case VAEncPackedHeaderDataBufferType:
2535 if (encode->last_packed_header_type == 0) {
2536 WARN_ONCE("the packed header data is passed without type!\n");
2537 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
2540 if (encode->last_packed_header_type == VAEncPackedHeaderRawData ||
2541 encode->last_packed_header_type == VAEncPackedHeaderSlice) {
2542 vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_data_ext);
2543 if (vaStatus == VA_STATUS_SUCCESS) {
2544 /* store the first index of the packed header data for current slice */
2545 if (encode->slice_rawdata_index[encode->num_slice_params_ext] == 0) {
2546 encode->slice_rawdata_index[encode->num_slice_params_ext] =
2547 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
2549 encode->slice_rawdata_count[encode->num_slice_params_ext]++;
2550 if (encode->last_packed_header_type == VAEncPackedHeaderSlice) {
2551 if (encode->slice_header_index[encode->num_slice_params_ext] == 0) {
2552 encode->slice_header_index[encode->num_slice_params_ext] =
2553 SLICE_PACKED_DATA_INDEX_TYPE | (encode->num_packed_header_data_ext - 1);
2555 WARN_ONCE("Multi slice header data is passed for"
2556 " slice %d!\n", encode->num_slice_params_ext);
2561 ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
2562 encode->last_packed_header_type == VAEncPackedHeaderPicture ||
2563 encode->last_packed_header_type == VAEncPackedHeaderSlice ||
2564 (((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) &&
2565 ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)),
2566 VA_STATUS_ERROR_ENCODING_ERROR);
2567 vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
2570 va_enc_packed_type_to_idx(encode->last_packed_header_type));
2572 encode->last_packed_header_type = 0;
2576 case VAEncMiscParameterBufferType:
2577 vaStatus = i965_encoder_render_misc_parameter_buffer(ctx,
2583 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2591 #define I965_RENDER_PROC_BUFFER(name) I965_RENDER_BUFFER(proc, name)
2593 #define DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(proc, name, member)
2594 DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(pipeline_parameter, pipeline_param)
2597 i965_proc_render_picture(VADriverContextP ctx,
2598 VAContextID context,
2599 VABufferID *buffers,
2602 struct i965_driver_data *i965 = i965_driver_data(ctx);
2603 struct object_context *obj_context = CONTEXT(context);
2604 VAStatus vaStatus = VA_STATUS_SUCCESS;
2607 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2609 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2610 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2613 return VA_STATUS_ERROR_INVALID_BUFFER;
2615 switch (obj_buffer->type) {
2616 case VAProcPipelineParameterBufferType:
2617 vaStatus = I965_RENDER_PROC_BUFFER(pipeline_parameter);
2621 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2630 i965_RenderPicture(VADriverContextP ctx,
2631 VAContextID context,
2632 VABufferID *buffers,
2635 struct i965_driver_data *i965 = i965_driver_data(ctx);
2636 struct object_context *obj_context;
2637 struct object_config *obj_config;
2638 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2640 obj_context = CONTEXT(context);
2641 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2643 if (num_buffers <= 0)
2644 return VA_STATUS_ERROR_INVALID_PARAMETER;
2646 obj_config = obj_context->obj_config;
2647 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2649 if (VAEntrypointVideoProc == obj_config->entrypoint) {
2650 vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
2651 } else if (VAEntrypointEncSlice == obj_config->entrypoint ) {
2652 vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
2654 vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
2661 i965_EndPicture(VADriverContextP ctx, VAContextID context)
2663 struct i965_driver_data *i965 = i965_driver_data(ctx);
2664 struct object_context *obj_context = CONTEXT(context);
2665 struct object_config *obj_config;
2667 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2668 obj_config = obj_context->obj_config;
2669 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2671 if (obj_context->codec_type == CODEC_PROC) {
2672 ASSERT_RET(VAEntrypointVideoProc == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
2673 } else if (obj_context->codec_type == CODEC_ENC) {
2674 ASSERT_RET(VAEntrypointEncSlice == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
2676 if (obj_context->codec_state.encode.num_packed_header_params_ext !=
2677 obj_context->codec_state.encode.num_packed_header_data_ext) {
2678 WARN_ONCE("the packed header/data is not paired for encoding!\n");
2679 return VA_STATUS_ERROR_INVALID_PARAMETER;
2681 if (!(obj_context->codec_state.encode.pic_param ||
2682 obj_context->codec_state.encode.pic_param_ext)) {
2683 return VA_STATUS_ERROR_INVALID_PARAMETER;
2685 if (!(obj_context->codec_state.encode.seq_param ||
2686 obj_context->codec_state.encode.seq_param_ext)) {
2687 return VA_STATUS_ERROR_INVALID_PARAMETER;
2689 if ((obj_context->codec_state.encode.num_slice_params <=0) &&
2690 (obj_context->codec_state.encode.num_slice_params_ext <=0)) {
2691 return VA_STATUS_ERROR_INVALID_PARAMETER;
2694 if (obj_context->codec_state.decode.pic_param == NULL) {
2695 return VA_STATUS_ERROR_INVALID_PARAMETER;
2697 if (obj_context->codec_state.decode.num_slice_params <=0) {
2698 return VA_STATUS_ERROR_INVALID_PARAMETER;
2700 if (obj_context->codec_state.decode.num_slice_datas <=0) {
2701 return VA_STATUS_ERROR_INVALID_PARAMETER;
2704 if (obj_context->codec_state.decode.num_slice_params !=
2705 obj_context->codec_state.decode.num_slice_datas) {
2706 return VA_STATUS_ERROR_INVALID_PARAMETER;
2710 ASSERT_RET(obj_context->hw_context->run, VA_STATUS_ERROR_OPERATION_FAILED);
2711 return obj_context->hw_context->run(ctx, obj_config->profile, &obj_context->codec_state, obj_context->hw_context);
2715 i965_SyncSurface(VADriverContextP ctx,
2716 VASurfaceID render_target)
2718 struct i965_driver_data *i965 = i965_driver_data(ctx);
2719 struct object_surface *obj_surface = SURFACE(render_target);
2721 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2724 drm_intel_bo_wait_rendering(obj_surface->bo);
2726 return VA_STATUS_SUCCESS;
2730 i965_QuerySurfaceStatus(VADriverContextP ctx,
2731 VASurfaceID render_target,
2732 VASurfaceStatus *status) /* out */
2734 struct i965_driver_data *i965 = i965_driver_data(ctx);
2735 struct object_surface *obj_surface = SURFACE(render_target);
2737 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2739 if (obj_surface->bo) {
2740 if (drm_intel_bo_busy(obj_surface->bo)){
2741 *status = VASurfaceRendering;
2744 *status = VASurfaceReady;
2747 *status = VASurfaceReady;
2750 return VA_STATUS_SUCCESS;
2753 static VADisplayAttribute *
2754 get_display_attribute(VADriverContextP ctx, VADisplayAttribType type)
2756 struct i965_driver_data * const i965 = i965_driver_data(ctx);
2759 if (!i965->display_attributes)
2762 for (i = 0; i < i965->num_display_attributes; i++) {
2763 if (i965->display_attributes[i].type == type)
2764 return &i965->display_attributes[i];
2770 i965_display_attributes_terminate(VADriverContextP ctx)
2772 struct i965_driver_data * const i965 = i965_driver_data(ctx);
2774 if (i965->display_attributes) {
2775 free(i965->display_attributes);
2776 i965->display_attributes = NULL;
2777 i965->num_display_attributes = 0;
2782 i965_display_attributes_init(VADriverContextP ctx)
2784 struct i965_driver_data * const i965 = i965_driver_data(ctx);
2786 i965->num_display_attributes = ARRAY_ELEMS(i965_display_attributes);
2787 i965->display_attributes = malloc(
2788 i965->num_display_attributes * sizeof(i965->display_attributes[0]));
2789 if (!i965->display_attributes)
2793 i965->display_attributes,
2794 i965_display_attributes,
2795 sizeof(i965_display_attributes)
2798 i965->rotation_attrib = get_display_attribute(ctx, VADisplayAttribRotation);
2799 i965->brightness_attrib = get_display_attribute(ctx, VADisplayAttribBrightness);
2800 i965->contrast_attrib = get_display_attribute(ctx, VADisplayAttribContrast);
2801 i965->hue_attrib = get_display_attribute(ctx, VADisplayAttribHue);
2802 i965->saturation_attrib = get_display_attribute(ctx, VADisplayAttribSaturation);
2804 if (!i965->rotation_attrib ||
2805 !i965->brightness_attrib ||
2806 !i965->contrast_attrib ||
2807 !i965->hue_attrib ||
2808 !i965->saturation_attrib) {
2814 i965_display_attributes_terminate(ctx);
2819 * Query display attributes
2820 * The caller must provide a "attr_list" array that can hold at
2821 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
2822 * returned in "attr_list" is returned in "num_attributes".
2825 i965_QueryDisplayAttributes(
2826 VADriverContextP ctx,
2827 VADisplayAttribute *attribs, /* out */
2828 int *num_attribs_ptr /* out */
2831 const int num_attribs = ARRAY_ELEMS(i965_display_attributes);
2833 if (attribs && num_attribs > 0)
2834 memcpy(attribs, i965_display_attributes, sizeof(i965_display_attributes));
2836 if (num_attribs_ptr)
2837 *num_attribs_ptr = num_attribs;
2839 return VA_STATUS_SUCCESS;
2843 * Get display attributes
2844 * This function returns the current attribute values in "attr_list".
2845 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
2846 * from vaQueryDisplayAttributes() can have their values retrieved.
2849 i965_GetDisplayAttributes(
2850 VADriverContextP ctx,
2851 VADisplayAttribute *attribs, /* inout */
2852 int num_attribs /* in */
2857 for (i = 0; i < num_attribs; i++) {
2858 VADisplayAttribute *src_attrib, * const dst_attrib = &attribs[i];
2860 src_attrib = get_display_attribute(ctx, dst_attrib->type);
2861 if (src_attrib && (src_attrib->flags & VA_DISPLAY_ATTRIB_GETTABLE)) {
2862 dst_attrib->min_value = src_attrib->min_value;
2863 dst_attrib->max_value = src_attrib->max_value;
2864 dst_attrib->value = src_attrib->value;
2867 dst_attrib->flags = VA_DISPLAY_ATTRIB_NOT_SUPPORTED;
2869 return VA_STATUS_SUCCESS;
2873 * Set display attributes
2874 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
2875 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
2876 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
2879 i965_SetDisplayAttributes(
2880 VADriverContextP ctx,
2881 VADisplayAttribute *attribs, /* in */
2882 int num_attribs /* in */
2887 for (i = 0; i < num_attribs; i++) {
2888 VADisplayAttribute *dst_attrib, * const src_attrib = &attribs[i];
2890 dst_attrib = get_display_attribute(ctx, src_attrib->type);
2892 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
2894 if (!(dst_attrib->flags & VA_DISPLAY_ATTRIB_SETTABLE))
2897 if (src_attrib->value < dst_attrib->min_value ||
2898 src_attrib->value > dst_attrib->max_value)
2899 return VA_STATUS_ERROR_INVALID_PARAMETER;
2901 dst_attrib->value = src_attrib->value;
2902 /* XXX: track modified attributes through timestamps */
2904 return VA_STATUS_SUCCESS;
2908 i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
2909 VASurfaceID surface,
2910 void **buffer, /* out */
2911 unsigned int *stride) /* out */
2914 return VA_STATUS_ERROR_UNIMPLEMENTED;
2918 i965_destroy_heap(struct object_heap *heap,
2919 void (*func)(struct object_heap *heap, struct object_base *object))
2921 struct object_base *object;
2922 object_heap_iterator iter;
2924 object = object_heap_first(heap, &iter);
2930 object = object_heap_next(heap, &iter);
2933 object_heap_destroy(heap);
2938 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
2941 i965_CreateImage(VADriverContextP ctx,
2942 VAImageFormat *format,
2945 VAImage *out_image) /* out */
2947 struct i965_driver_data *i965 = i965_driver_data(ctx);
2948 struct object_image *obj_image;
2949 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
2951 unsigned int size2, size, awidth, aheight;
2953 out_image->image_id = VA_INVALID_ID;
2954 out_image->buf = VA_INVALID_ID;
2956 image_id = NEW_IMAGE_ID();
2957 if (image_id == VA_INVALID_ID)
2958 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2960 obj_image = IMAGE(image_id);
2962 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2963 obj_image->bo = NULL;
2964 obj_image->palette = NULL;
2965 obj_image->derived_surface = VA_INVALID_ID;
2967 VAImage * const image = &obj_image->image;
2968 image->image_id = image_id;
2969 image->buf = VA_INVALID_ID;
2971 awidth = ALIGN(width, i965->codec_info->min_linear_wpitch);
2973 if ((format->fourcc == VA_FOURCC_YV12) ||
2974 (format->fourcc == VA_FOURCC_I420)) {
2975 if (awidth % 128 != 0) {
2976 awidth = ALIGN(width, 128);
2980 aheight = ALIGN(height, i965->codec_info->min_linear_hpitch);
2981 size = awidth * aheight;
2982 size2 = (awidth / 2) * (aheight / 2);
2984 image->num_palette_entries = 0;
2985 image->entry_bytes = 0;
2986 memset(image->component_order, 0, sizeof(image->component_order));
2988 switch (format->fourcc) {
2989 case VA_FOURCC_IA44:
2990 case VA_FOURCC_AI44:
2991 image->num_planes = 1;
2992 image->pitches[0] = awidth;
2993 image->offsets[0] = 0;
2994 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
2995 image->num_palette_entries = 16;
2996 image->entry_bytes = 3;
2997 image->component_order[0] = 'R';
2998 image->component_order[1] = 'G';
2999 image->component_order[2] = 'B';
3001 case VA_FOURCC_IA88:
3002 case VA_FOURCC_AI88:
3003 image->num_planes = 1;
3004 image->pitches[0] = awidth * 2;
3005 image->offsets[0] = 0;
3006 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
3007 image->num_palette_entries = 256;
3008 image->entry_bytes = 3;
3009 image->component_order[0] = 'R';
3010 image->component_order[1] = 'G';
3011 image->component_order[2] = 'B';
3013 case VA_FOURCC_ARGB:
3014 case VA_FOURCC_ABGR:
3015 case VA_FOURCC_BGRA:
3016 case VA_FOURCC_RGBA:
3017 case VA_FOURCC_BGRX:
3018 case VA_FOURCC_RGBX:
3019 image->num_planes = 1;
3020 image->pitches[0] = awidth * 4;
3021 image->offsets[0] = 0;
3022 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
3024 case VA_FOURCC_YV12:
3025 image->num_planes = 3;
3026 image->pitches[0] = awidth;
3027 image->offsets[0] = 0;
3028 image->pitches[1] = awidth / 2;
3029 image->offsets[1] = size;
3030 image->pitches[2] = awidth / 2;
3031 image->offsets[2] = size + size2;
3032 image->data_size = size + 2 * size2;
3034 case VA_FOURCC_I420:
3035 image->num_planes = 3;
3036 image->pitches[0] = awidth;
3037 image->offsets[0] = 0;
3038 image->pitches[1] = awidth / 2;
3039 image->offsets[1] = size;
3040 image->pitches[2] = awidth / 2;
3041 image->offsets[2] = size + size2;
3042 image->data_size = size + 2 * size2;
3044 case VA_FOURCC_422H:
3045 image->num_planes = 3;
3046 image->pitches[0] = awidth;
3047 image->offsets[0] = 0;
3048 image->pitches[1] = awidth / 2;
3049 image->offsets[1] = size;
3050 image->pitches[2] = awidth / 2;
3051 image->offsets[2] = size + (awidth / 2) * aheight;
3052 image->data_size = size + 2 * ((awidth / 2) * aheight);
3054 case VA_FOURCC_NV12:
3055 image->num_planes = 2;
3056 image->pitches[0] = awidth;
3057 image->offsets[0] = 0;
3058 image->pitches[1] = awidth;
3059 image->offsets[1] = size;
3060 image->data_size = size + 2 * size2;
3062 case VA_FOURCC_YUY2:
3063 case VA_FOURCC_UYVY:
3064 image->num_planes = 1;
3065 image->pitches[0] = awidth * 2;
3066 image->offsets[0] = 0;
3067 image->data_size = size * 2;
3073 va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
3074 image->data_size, 1, NULL, &image->buf);
3075 if (va_status != VA_STATUS_SUCCESS)
3078 struct object_buffer *obj_buffer = BUFFER(image->buf);
3081 !obj_buffer->buffer_store ||
3082 !obj_buffer->buffer_store->bo)
3083 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3085 obj_image->bo = obj_buffer->buffer_store->bo;
3086 dri_bo_reference(obj_image->bo);
3088 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
3089 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
3090 if (!obj_image->palette)
3094 image->image_id = image_id;
3095 image->format = *format;
3096 image->width = width;
3097 image->height = height;
3099 *out_image = *image;
3100 return VA_STATUS_SUCCESS;
3103 i965_DestroyImage(ctx, image_id);
3108 i965_check_alloc_surface_bo(VADriverContextP ctx,
3109 struct object_surface *obj_surface,
3111 unsigned int fourcc,
3112 unsigned int subsampling)
3114 struct i965_driver_data *i965 = i965_driver_data(ctx);
3115 int region_width, region_height;
3117 if (obj_surface->bo) {
3118 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3119 ASSERT_RET(obj_surface->fourcc == fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3120 ASSERT_RET(obj_surface->subsampling == subsampling, VA_STATUS_ERROR_INVALID_SURFACE);
3121 return VA_STATUS_SUCCESS;
3124 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
3125 obj_surface->x_cr_offset = 0;
3127 if ((tiled && !obj_surface->user_disable_tiling)) {
3128 ASSERT_RET(fourcc != VA_FOURCC_I420 &&
3129 fourcc != VA_FOURCC_IYUV &&
3130 fourcc != VA_FOURCC_YV12,
3131 VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3132 if (obj_surface->user_h_stride_set) {
3133 ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
3135 obj_surface->width = ALIGN(obj_surface->orig_width, 128);
3137 if (obj_surface->user_v_stride_set) {
3138 ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
3140 obj_surface->height = ALIGN(obj_surface->orig_height, 32);
3142 region_height = obj_surface->height;
3145 case VA_FOURCC_NV12:
3146 assert(subsampling == SUBSAMPLE_YUV420);
3147 obj_surface->cb_cr_pitch = obj_surface->width;
3148 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3149 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3150 obj_surface->y_cb_offset = obj_surface->height;
3151 obj_surface->y_cr_offset = obj_surface->height;
3152 region_width = obj_surface->width;
3153 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
3157 case VA_FOURCC_IMC1:
3158 assert(subsampling == SUBSAMPLE_YUV420);
3159 obj_surface->cb_cr_pitch = obj_surface->width;
3160 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3161 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3162 obj_surface->y_cr_offset = obj_surface->height;
3163 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32);
3164 region_width = obj_surface->width;
3165 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3169 case VA_FOURCC_IMC3:
3170 assert(subsampling == SUBSAMPLE_YUV420);
3171 obj_surface->cb_cr_pitch = obj_surface->width;
3172 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3173 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3174 obj_surface->y_cb_offset = obj_surface->height;
3175 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3176 region_width = obj_surface->width;
3177 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3181 case VA_FOURCC_422H:
3182 assert(subsampling == SUBSAMPLE_YUV422H);
3183 obj_surface->cb_cr_pitch = obj_surface->width;
3184 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3185 obj_surface->cb_cr_height = obj_surface->orig_height;
3186 obj_surface->y_cb_offset = obj_surface->height;
3187 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3188 region_width = obj_surface->width;
3189 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3193 case VA_FOURCC_422V:
3194 assert(subsampling == SUBSAMPLE_YUV422V);
3195 obj_surface->cb_cr_pitch = obj_surface->width;
3196 obj_surface->cb_cr_width = obj_surface->orig_width;
3197 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3198 obj_surface->y_cb_offset = obj_surface->height;
3199 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3200 region_width = obj_surface->width;
3201 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3205 case VA_FOURCC_411P:
3206 assert(subsampling == SUBSAMPLE_YUV411);
3207 obj_surface->cb_cr_pitch = obj_surface->width;
3208 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
3209 obj_surface->cb_cr_height = obj_surface->orig_height;
3210 obj_surface->y_cb_offset = obj_surface->height;
3211 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3212 region_width = obj_surface->width;
3213 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3217 case VA_FOURCC_444P:
3218 assert(subsampling == SUBSAMPLE_YUV444);
3219 obj_surface->cb_cr_pitch = obj_surface->width;
3220 obj_surface->cb_cr_width = obj_surface->orig_width;
3221 obj_surface->cb_cr_height = obj_surface->orig_height;
3222 obj_surface->y_cb_offset = obj_surface->height;
3223 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
3224 region_width = obj_surface->width;
3225 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
3229 case VA_FOURCC_Y800:
3230 assert(subsampling == SUBSAMPLE_YUV400);
3231 obj_surface->cb_cr_pitch = 0;
3232 obj_surface->cb_cr_width = 0;
3233 obj_surface->cb_cr_height = 0;
3234 obj_surface->y_cb_offset = 0;
3235 obj_surface->y_cr_offset = 0;
3236 region_width = obj_surface->width;
3237 region_height = obj_surface->height;
3241 case VA_FOURCC_YUY2:
3242 case VA_FOURCC_UYVY:
3243 assert(subsampling == SUBSAMPLE_YUV422H);
3244 obj_surface->width = ALIGN(obj_surface->orig_width * 2, 128);
3245 obj_surface->cb_cr_pitch = obj_surface->width;
3246 obj_surface->y_cb_offset = 0;
3247 obj_surface->y_cr_offset = 0;
3248 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3249 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3250 region_width = obj_surface->width;
3251 region_height = obj_surface->height;
3255 case VA_FOURCC_RGBA:
3256 case VA_FOURCC_RGBX:
3257 case VA_FOURCC_BGRA:
3258 case VA_FOURCC_BGRX:
3259 assert(subsampling == SUBSAMPLE_RGBX);
3261 obj_surface->width = ALIGN(obj_surface->orig_width * 4, 128);
3262 region_width = obj_surface->width;
3263 region_height = obj_surface->height;
3267 /* Never get here */
3268 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3272 assert(subsampling == SUBSAMPLE_YUV420 ||
3273 subsampling == SUBSAMPLE_YUV422H ||
3274 subsampling == SUBSAMPLE_YUV422V ||
3275 subsampling == SUBSAMPLE_RGBX);
3277 region_width = obj_surface->width;
3278 region_height = obj_surface->height;
3281 case VA_FOURCC_NV12:
3282 obj_surface->y_cb_offset = obj_surface->height;
3283 obj_surface->y_cr_offset = obj_surface->height;
3284 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3285 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3286 obj_surface->cb_cr_pitch = obj_surface->width;
3287 region_height = obj_surface->height + obj_surface->height / 2;
3290 case VA_FOURCC_YV16:
3291 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3292 obj_surface->cb_cr_height = obj_surface->orig_height;
3293 obj_surface->y_cr_offset = obj_surface->height;
3294 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32) / 2;
3295 obj_surface->cb_cr_pitch = obj_surface->width / 2;
3296 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
3299 case VA_FOURCC_YV12:
3300 case VA_FOURCC_I420:
3301 if (fourcc == VA_FOURCC_YV12) {
3302 obj_surface->y_cr_offset = obj_surface->height;
3303 obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4;
3305 obj_surface->y_cb_offset = obj_surface->height;
3306 obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
3309 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3310 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3311 obj_surface->cb_cr_pitch = obj_surface->width / 2;
3312 region_height = obj_surface->height + obj_surface->height / 2;
3315 case VA_FOURCC_YUY2:
3316 case VA_FOURCC_UYVY:
3317 obj_surface->width = ALIGN(obj_surface->orig_width * 2, i965->codec_info->min_linear_wpitch);
3318 obj_surface->y_cb_offset = 0;
3319 obj_surface->y_cr_offset = 0;
3320 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3321 obj_surface->cb_cr_height = obj_surface->orig_height;
3322 obj_surface->cb_cr_pitch = obj_surface->width;
3323 region_width = obj_surface->width;
3324 region_height = obj_surface->height;
3326 case VA_FOURCC_RGBA:
3327 case VA_FOURCC_RGBX:
3328 case VA_FOURCC_BGRA:
3329 case VA_FOURCC_BGRX:
3330 obj_surface->width = ALIGN(obj_surface->orig_width * 4, i965->codec_info->min_linear_wpitch);
3331 region_width = obj_surface->width;
3332 region_height = obj_surface->height;
3336 /* Never get here */
3337 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3342 obj_surface->size = ALIGN(region_width * region_height, 0x1000);
3344 if ((tiled && !obj_surface->user_disable_tiling)) {
3345 uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
3346 unsigned long pitch;
3348 obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr,
3356 assert(tiling_mode == I915_TILING_Y);
3357 assert(pitch == obj_surface->width);
3359 obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
3365 obj_surface->fourcc = fourcc;
3366 obj_surface->subsampling = subsampling;
3367 assert(obj_surface->bo);
3368 return VA_STATUS_SUCCESS;
3371 VAStatus i965_DeriveImage(VADriverContextP ctx,
3372 VASurfaceID surface,
3373 VAImage *out_image) /* out */
3375 struct i965_driver_data *i965 = i965_driver_data(ctx);
3376 struct object_image *obj_image;
3377 struct object_surface *obj_surface;
3379 unsigned int w_pitch;
3380 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3382 out_image->image_id = VA_INVALID_ID;
3383 obj_surface = SURFACE(surface);
3386 return VA_STATUS_ERROR_INVALID_SURFACE;
3388 if (!obj_surface->bo) {
3389 unsigned int is_tiled = 0;
3390 unsigned int fourcc = VA_FOURCC_YV12;
3391 i965_guess_surface_format(ctx, surface, &fourcc, &is_tiled);
3392 int sampling = get_sampling_from_fourcc(fourcc);
3393 va_status = i965_check_alloc_surface_bo(ctx, obj_surface, is_tiled, fourcc, sampling);
3394 if (va_status != VA_STATUS_SUCCESS)
3398 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3400 w_pitch = obj_surface->width;
3402 image_id = NEW_IMAGE_ID();
3404 if (image_id == VA_INVALID_ID)
3405 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3407 obj_image = IMAGE(image_id);
3410 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3412 obj_image->bo = NULL;
3413 obj_image->palette = NULL;
3414 obj_image->derived_surface = VA_INVALID_ID;
3416 VAImage * const image = &obj_image->image;
3418 memset(image, 0, sizeof(*image));
3419 image->image_id = image_id;
3420 image->buf = VA_INVALID_ID;
3421 image->num_palette_entries = 0;
3422 image->entry_bytes = 0;
3423 image->width = obj_surface->orig_width;
3424 image->height = obj_surface->orig_height;
3425 image->data_size = obj_surface->size;
3427 image->format.fourcc = obj_surface->fourcc;
3428 image->format.byte_order = VA_LSB_FIRST;
3429 image->format.bits_per_pixel = 12;
3431 switch (image->format.fourcc) {
3432 case VA_FOURCC_YV12:
3433 image->num_planes = 3;
3434 image->pitches[0] = w_pitch; /* Y */
3435 image->offsets[0] = 0;
3436 image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
3437 image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
3438 image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
3439 image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
3442 case VA_FOURCC_YV16:
3443 image->num_planes = 3;
3444 image->pitches[0] = w_pitch; /* Y */
3445 image->offsets[0] = 0;
3446 image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
3447 image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
3448 image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
3449 image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
3452 case VA_FOURCC_NV12:
3453 image->num_planes = 2;
3454 image->pitches[0] = w_pitch; /* Y */
3455 image->offsets[0] = 0;
3456 image->pitches[1] = obj_surface->cb_cr_pitch; /* UV */
3457 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
3460 case VA_FOURCC_I420:
3461 case VA_FOURCC_422H:
3462 case VA_FOURCC_IMC3:
3463 case VA_FOURCC_444P:
3464 case VA_FOURCC_422V:
3465 case VA_FOURCC_411P:
3466 image->num_planes = 3;
3467 image->pitches[0] = w_pitch; /* Y */
3468 image->offsets[0] = 0;
3469 image->pitches[1] = obj_surface->cb_cr_pitch; /* U */
3470 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
3471 image->pitches[2] = obj_surface->cb_cr_pitch; /* V */
3472 image->offsets[2] = w_pitch * obj_surface->y_cr_offset;
3475 case VA_FOURCC_YUY2:
3476 case VA_FOURCC_UYVY:
3477 case VA_FOURCC_Y800:
3478 image->num_planes = 1;
3479 image->pitches[0] = obj_surface->width; /* Y, width is aligned already */
3480 image->offsets[0] = 0;
3482 case VA_FOURCC_RGBA:
3483 case VA_FOURCC_RGBX:
3484 case VA_FOURCC_BGRA:
3485 case VA_FOURCC_BGRX:
3486 image->num_planes = 1;
3487 image->pitches[0] = obj_surface->width;
3493 va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType,
3494 obj_surface->size, 1, NULL, obj_surface->bo, &image->buf);
3495 if (va_status != VA_STATUS_SUCCESS)
3498 struct object_buffer *obj_buffer = BUFFER(image->buf);
3501 !obj_buffer->buffer_store ||
3502 !obj_buffer->buffer_store->bo)
3503 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3505 obj_image->bo = obj_buffer->buffer_store->bo;
3506 dri_bo_reference(obj_image->bo);
3508 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
3509 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
3510 if (!obj_image->palette) {
3511 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
3516 *out_image = *image;
3517 obj_surface->flags |= SURFACE_DERIVED;
3518 obj_image->derived_surface = surface;
3520 return VA_STATUS_SUCCESS;
3523 i965_DestroyImage(ctx, image_id);
3528 i965_destroy_image(struct object_heap *heap, struct object_base *obj)
3530 object_heap_free(heap, obj);
3535 i965_DestroyImage(VADriverContextP ctx, VAImageID image)
3537 struct i965_driver_data *i965 = i965_driver_data(ctx);
3538 struct object_image *obj_image = IMAGE(image);
3539 struct object_surface *obj_surface;
3542 return VA_STATUS_SUCCESS;
3544 dri_bo_unreference(obj_image->bo);
3545 obj_image->bo = NULL;
3547 if (obj_image->image.buf != VA_INVALID_ID) {
3548 i965_DestroyBuffer(ctx, obj_image->image.buf);
3549 obj_image->image.buf = VA_INVALID_ID;
3552 if (obj_image->palette) {
3553 free(obj_image->palette);
3554 obj_image->palette = NULL;
3557 obj_surface = SURFACE(obj_image->derived_surface);
3560 obj_surface->flags &= ~SURFACE_DERIVED;
3563 i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
3565 return VA_STATUS_SUCCESS;
3569 * pointer to an array holding the palette data. The size of the array is
3570 * num_palette_entries * entry_bytes in size. The order of the components
3571 * in the palette is described by the component_order in VASubpicture struct
3574 i965_SetImagePalette(VADriverContextP ctx,
3576 unsigned char *palette)
3578 struct i965_driver_data *i965 = i965_driver_data(ctx);
3581 struct object_image *obj_image = IMAGE(image);
3583 return VA_STATUS_ERROR_INVALID_IMAGE;
3585 if (!obj_image->palette)
3586 return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
3588 for (i = 0; i < obj_image->image.num_palette_entries; i++)
3589 obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
3590 ((unsigned int)palette[3*i + 1] << 8) |
3591 (unsigned int)palette[3*i + 2]);
3592 return VA_STATUS_SUCCESS;
3596 get_sampling_from_fourcc(unsigned int fourcc)
3598 const i965_fourcc_info *info = get_fourcc_info(fourcc);
3600 if (info && (info->flag & I_S))
3601 return info->subsampling;
3607 memcpy_pic(uint8_t *dst, unsigned int dst_stride,
3608 const uint8_t *src, unsigned int src_stride,
3609 unsigned int len, unsigned int height)
3613 for (i = 0; i < height; i++) {
3614 memcpy(dst, src, len);
3621 get_image_i420(struct object_image *obj_image, uint8_t *image_data,
3622 struct object_surface *obj_surface,
3623 const VARectangle *rect)
3625 uint8_t *dst[3], *src[3];
3627 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
3628 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
3629 unsigned int tiling, swizzle;
3630 VAStatus va_status = VA_STATUS_SUCCESS;
3632 if (!obj_surface->bo)
3633 return VA_STATUS_ERROR_INVALID_SURFACE;
3635 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3636 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3638 if (tiling != I915_TILING_NONE)
3639 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3641 dri_bo_map(obj_surface->bo, 0);
3643 if (!obj_surface->bo->virtual)
3644 return VA_STATUS_ERROR_INVALID_SURFACE;
3646 /* Dest VA image has either I420 or YV12 format.
3647 Source VA surface alway has I420 format */
3648 dst[Y] = image_data + obj_image->image.offsets[Y];
3649 src[0] = (uint8_t *)obj_surface->bo->virtual;
3650 dst[U] = image_data + obj_image->image.offsets[U];
3651 src[1] = src[0] + obj_surface->width * obj_surface->height;
3652 dst[V] = image_data + obj_image->image.offsets[V];
3653 src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
3656 dst[Y] += rect->y * obj_image->image.pitches[Y] + rect->x;
3657 src[0] += rect->y * obj_surface->width + rect->x;
3658 memcpy_pic(dst[Y], obj_image->image.pitches[Y],
3659 src[0], obj_surface->width,
3660 rect->width, rect->height);
3663 dst[U] += (rect->y / 2) * obj_image->image.pitches[U] + rect->x / 2;
3664 src[1] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
3665 memcpy_pic(dst[U], obj_image->image.pitches[U],
3666 src[1], obj_surface->width / 2,
3667 rect->width / 2, rect->height / 2);
3670 dst[V] += (rect->y / 2) * obj_image->image.pitches[V] + rect->x / 2;
3671 src[2] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
3672 memcpy_pic(dst[V], obj_image->image.pitches[V],
3673 src[2], obj_surface->width / 2,
3674 rect->width / 2, rect->height / 2);
3676 if (tiling != I915_TILING_NONE)
3677 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3679 dri_bo_unmap(obj_surface->bo);
3685 get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
3686 struct object_surface *obj_surface,
3687 const VARectangle *rect)
3689 uint8_t *dst[2], *src[2];
3690 unsigned int tiling, swizzle;
3691 VAStatus va_status = VA_STATUS_SUCCESS;
3693 if (!obj_surface->bo)
3694 return VA_STATUS_ERROR_INVALID_SURFACE;
3696 assert(obj_surface->fourcc);
3697 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3699 if (tiling != I915_TILING_NONE)
3700 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3702 dri_bo_map(obj_surface->bo, 0);
3704 if (!obj_surface->bo->virtual)
3705 return VA_STATUS_ERROR_INVALID_SURFACE;
3707 /* Both dest VA image and source surface have NV12 format */
3708 dst[0] = image_data + obj_image->image.offsets[0];
3709 src[0] = (uint8_t *)obj_surface->bo->virtual;
3710 dst[1] = image_data + obj_image->image.offsets[1];
3711 src[1] = src[0] + obj_surface->width * obj_surface->height;
3714 dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
3715 src[0] += rect->y * obj_surface->width + rect->x;
3716 memcpy_pic(dst[0], obj_image->image.pitches[0],
3717 src[0], obj_surface->width,
3718 rect->width, rect->height);
3721 dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + (rect->x & -2);
3722 src[1] += (rect->y / 2) * obj_surface->width + (rect->x & -2);
3723 memcpy_pic(dst[1], obj_image->image.pitches[1],
3724 src[1], obj_surface->width,
3725 rect->width, rect->height / 2);
3727 if (tiling != I915_TILING_NONE)
3728 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3730 dri_bo_unmap(obj_surface->bo);
3736 get_image_yuy2(struct object_image *obj_image, uint8_t *image_data,
3737 struct object_surface *obj_surface,
3738 const VARectangle *rect)
3741 unsigned int tiling, swizzle;
3742 VAStatus va_status = VA_STATUS_SUCCESS;
3744 if (!obj_surface->bo)
3745 return VA_STATUS_ERROR_INVALID_SURFACE;
3747 assert(obj_surface->fourcc);
3748 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3750 if (tiling != I915_TILING_NONE)
3751 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3753 dri_bo_map(obj_surface->bo, 0);
3755 if (!obj_surface->bo->virtual)
3756 return VA_STATUS_ERROR_INVALID_SURFACE;
3758 /* Both dest VA image and source surface have YUYV format */
3759 dst = image_data + obj_image->image.offsets[0];
3760 src = (uint8_t *)obj_surface->bo->virtual;
3763 dst += rect->y * obj_image->image.pitches[0] + rect->x*2;
3764 src += rect->y * obj_surface->width + rect->x*2;
3765 memcpy_pic(dst, obj_image->image.pitches[0],
3766 src, obj_surface->width*2,
3767 rect->width*2, rect->height);
3769 if (tiling != I915_TILING_NONE)
3770 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3772 dri_bo_unmap(obj_surface->bo);
3778 i965_sw_getimage(VADriverContextP ctx,
3779 VASurfaceID surface,
3780 int x, /* coordinates of the upper left source pixel */
3782 unsigned int width, /* width and height of the region */
3783 unsigned int height,
3786 struct i965_driver_data *i965 = i965_driver_data(ctx);
3787 struct i965_render_state *render_state = &i965->render_state;
3788 VAStatus va_status = VA_STATUS_SUCCESS;
3790 struct object_surface *obj_surface = SURFACE(surface);
3792 return VA_STATUS_ERROR_INVALID_SURFACE;
3794 struct object_image *obj_image = IMAGE(image);
3796 return VA_STATUS_ERROR_INVALID_IMAGE;
3799 return VA_STATUS_ERROR_INVALID_PARAMETER;
3800 if (x + width > obj_surface->orig_width ||
3801 y + height > obj_surface->orig_height)
3802 return VA_STATUS_ERROR_INVALID_PARAMETER;
3803 if (x + width > obj_image->image.width ||
3804 y + height > obj_image->image.height)
3805 return VA_STATUS_ERROR_INVALID_PARAMETER;
3807 if (obj_surface->fourcc != obj_image->image.format.fourcc)
3808 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
3810 void *image_data = NULL;
3812 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
3813 if (va_status != VA_STATUS_SUCCESS)
3820 rect.height = height;
3822 switch (obj_image->image.format.fourcc) {
3823 case VA_FOURCC_YV12:
3824 case VA_FOURCC_I420:
3825 /* I420 is native format for MPEG-2 decoded surfaces */
3826 if (render_state->interleaved_uv)
3827 goto operation_failed;
3828 get_image_i420(obj_image, image_data, obj_surface, &rect);
3830 case VA_FOURCC_NV12:
3831 /* NV12 is native format for H.264 decoded surfaces */
3832 if (!render_state->interleaved_uv)
3833 goto operation_failed;
3834 get_image_nv12(obj_image, image_data, obj_surface, &rect);
3836 case VA_FOURCC_YUY2:
3837 /* YUY2 is the format supported by overlay plane */
3838 get_image_yuy2(obj_image, image_data, obj_surface, &rect);
3842 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3846 if (va_status != VA_STATUS_SUCCESS)
3849 va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
3854 i965_hw_getimage(VADriverContextP ctx,
3855 VASurfaceID surface,
3856 int x, /* coordinates of the upper left source pixel */
3858 unsigned int width, /* width and height of the region */
3859 unsigned int height,
3862 struct i965_driver_data *i965 = i965_driver_data(ctx);
3863 struct i965_surface src_surface;
3864 struct i965_surface dst_surface;
3865 VAStatus va_status = VA_STATUS_SUCCESS;
3867 struct object_surface *obj_surface = SURFACE(surface);
3868 struct object_image *obj_image = IMAGE(image);
3871 return VA_STATUS_ERROR_INVALID_SURFACE;
3874 return VA_STATUS_ERROR_INVALID_IMAGE;
3877 return VA_STATUS_ERROR_INVALID_PARAMETER;
3878 if (x + width > obj_surface->orig_width ||
3879 y + height > obj_surface->orig_height)
3880 return VA_STATUS_ERROR_INVALID_PARAMETER;
3881 if (x + width > obj_image->image.width ||
3882 y + height > obj_image->image.height)
3883 return VA_STATUS_ERROR_INVALID_PARAMETER;
3885 if (!obj_surface->bo)
3886 return VA_STATUS_SUCCESS;
3887 assert(obj_image->bo); // image bo is always created, see i965_CreateImage()
3892 rect.height = height;
3894 src_surface.base = (struct object_base *)obj_surface;
3895 src_surface.type = I965_SURFACE_TYPE_SURFACE;
3896 src_surface.flags = I965_SURFACE_FLAG_FRAME;
3898 dst_surface.base = (struct object_base *)obj_image;
3899 dst_surface.type = I965_SURFACE_TYPE_IMAGE;
3900 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3902 va_status = i965_image_processing(ctx,
3913 i965_GetImage(VADriverContextP ctx,
3914 VASurfaceID surface,
3915 int x, /* coordinates of the upper left source pixel */
3917 unsigned int width, /* width and height of the region */
3918 unsigned int height,
3921 struct i965_driver_data * const i965 = i965_driver_data(ctx);
3922 VAStatus va_status = VA_STATUS_SUCCESS;
3924 if (HAS_ACCELERATED_GETIMAGE(i965))
3925 va_status = i965_hw_getimage(ctx,
3931 va_status = i965_sw_getimage(ctx,
3941 put_image_i420(struct object_surface *obj_surface,
3942 const VARectangle *dst_rect,
3943 struct object_image *obj_image, uint8_t *image_data,
3944 const VARectangle *src_rect)
3946 uint8_t *dst[3], *src[3];
3948 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
3949 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
3950 unsigned int tiling, swizzle;
3951 VAStatus va_status = VA_STATUS_SUCCESS;
3953 ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
3955 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3956 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
3957 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
3958 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3960 if (tiling != I915_TILING_NONE)
3961 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3963 dri_bo_map(obj_surface->bo, 0);
3965 if (!obj_surface->bo->virtual)
3966 return VA_STATUS_ERROR_INVALID_SURFACE;
3968 /* Dest VA image has either I420 or YV12 format.
3969 Source VA surface alway has I420 format */
3970 dst[0] = (uint8_t *)obj_surface->bo->virtual;
3971 src[Y] = image_data + obj_image->image.offsets[Y];
3972 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
3973 src[U] = image_data + obj_image->image.offsets[U];
3974 dst[2] = dst[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
3975 src[V] = image_data + obj_image->image.offsets[V];
3978 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
3979 src[Y] += src_rect->y * obj_image->image.pitches[Y] + src_rect->x;
3980 memcpy_pic(dst[0], obj_surface->width,
3981 src[Y], obj_image->image.pitches[Y],
3982 src_rect->width, src_rect->height);
3985 dst[1] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
3986 src[U] += (src_rect->y / 2) * obj_image->image.pitches[U] + src_rect->x / 2;
3987 memcpy_pic(dst[1], obj_surface->width / 2,
3988 src[U], obj_image->image.pitches[U],
3989 src_rect->width / 2, src_rect->height / 2);
3992 dst[2] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
3993 src[V] += (src_rect->y / 2) * obj_image->image.pitches[V] + src_rect->x / 2;
3994 memcpy_pic(dst[2], obj_surface->width / 2,
3995 src[V], obj_image->image.pitches[V],
3996 src_rect->width / 2, src_rect->height / 2);
3998 if (tiling != I915_TILING_NONE)
3999 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4001 dri_bo_unmap(obj_surface->bo);
4007 put_image_nv12(struct object_surface *obj_surface,
4008 const VARectangle *dst_rect,
4009 struct object_image *obj_image, uint8_t *image_data,
4010 const VARectangle *src_rect)
4012 uint8_t *dst[2], *src[2];
4013 unsigned int tiling, swizzle;
4014 VAStatus va_status = VA_STATUS_SUCCESS;
4016 if (!obj_surface->bo)
4017 return VA_STATUS_ERROR_INVALID_SURFACE;
4019 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4020 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
4021 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
4022 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4024 if (tiling != I915_TILING_NONE)
4025 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4027 dri_bo_map(obj_surface->bo, 0);
4029 if (!obj_surface->bo->virtual)
4030 return VA_STATUS_ERROR_INVALID_SURFACE;
4032 /* Both dest VA image and source surface have NV12 format */
4033 dst[0] = (uint8_t *)obj_surface->bo->virtual;
4034 src[0] = image_data + obj_image->image.offsets[0];
4035 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
4036 src[1] = image_data + obj_image->image.offsets[1];
4039 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
4040 src[0] += src_rect->y * obj_image->image.pitches[0] + src_rect->x;
4041 memcpy_pic(dst[0], obj_surface->width,
4042 src[0], obj_image->image.pitches[0],
4043 src_rect->width, src_rect->height);
4046 dst[1] += (dst_rect->y / 2) * obj_surface->width + (dst_rect->x & -2);
4047 src[1] += (src_rect->y / 2) * obj_image->image.pitches[1] + (src_rect->x & -2);
4048 memcpy_pic(dst[1], obj_surface->width,
4049 src[1], obj_image->image.pitches[1],
4050 src_rect->width, src_rect->height / 2);
4052 if (tiling != I915_TILING_NONE)
4053 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4055 dri_bo_unmap(obj_surface->bo);
4061 put_image_yuy2(struct object_surface *obj_surface,
4062 const VARectangle *dst_rect,
4063 struct object_image *obj_image, uint8_t *image_data,
4064 const VARectangle *src_rect)
4067 unsigned int tiling, swizzle;
4068 VAStatus va_status = VA_STATUS_SUCCESS;
4070 ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
4071 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4072 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
4073 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
4074 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
4076 if (tiling != I915_TILING_NONE)
4077 drm_intel_gem_bo_map_gtt(obj_surface->bo);
4079 dri_bo_map(obj_surface->bo, 0);
4081 if (!obj_surface->bo->virtual)
4082 return VA_STATUS_ERROR_INVALID_SURFACE;
4084 /* Both dest VA image and source surface have YUY2 format */
4085 dst = (uint8_t *)obj_surface->bo->virtual;
4086 src = image_data + obj_image->image.offsets[0];
4088 /* YUYV packed plane */
4089 dst += dst_rect->y * obj_surface->width + dst_rect->x*2;
4090 src += src_rect->y * obj_image->image.pitches[0] + src_rect->x*2;
4091 memcpy_pic(dst, obj_surface->width*2,
4092 src, obj_image->image.pitches[0],
4093 src_rect->width*2, src_rect->height);
4095 if (tiling != I915_TILING_NONE)
4096 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
4098 dri_bo_unmap(obj_surface->bo);
4105 i965_sw_putimage(VADriverContextP ctx,
4106 VASurfaceID surface,
4110 unsigned int src_width,
4111 unsigned int src_height,
4114 unsigned int dest_width,
4115 unsigned int dest_height)
4117 struct i965_driver_data *i965 = i965_driver_data(ctx);
4118 struct object_surface *obj_surface = SURFACE(surface);
4119 struct object_image *obj_image = IMAGE(image);
4120 VAStatus va_status = VA_STATUS_SUCCESS;
4121 void *image_data = NULL;
4123 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
4124 ASSERT_RET(obj_image, VA_STATUS_ERROR_INVALID_IMAGE);
4126 if (src_x < 0 || src_y < 0)
4127 return VA_STATUS_ERROR_INVALID_PARAMETER;
4128 if (src_x + src_width > obj_image->image.width ||
4129 src_y + src_height > obj_image->image.height)
4130 return VA_STATUS_ERROR_INVALID_PARAMETER;
4131 if (dest_x < 0 || dest_y < 0)
4132 return VA_STATUS_ERROR_INVALID_PARAMETER;
4133 if (dest_x + dest_width > obj_surface->orig_width ||
4134 dest_y + dest_height > obj_surface->orig_height)
4135 return VA_STATUS_ERROR_INVALID_PARAMETER;
4137 /* XXX: don't allow scaling */
4138 if (src_width != dest_width || src_height != dest_height)
4139 return VA_STATUS_ERROR_INVALID_PARAMETER;
4141 if (obj_surface->fourcc) {
4142 /* Don't allow format mismatch */
4143 if (obj_surface->fourcc != obj_image->image.format.fourcc)
4144 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
4148 /* VA is surface not used for decoding, use same VA image format */
4149 va_status = i965_check_alloc_surface_bo(
4152 0, /* XXX: don't use tiled surface */
4153 obj_image->image.format.fourcc,
4154 get_sampling_from_fourcc (obj_image->image.format.fourcc));
4157 if (va_status != VA_STATUS_SUCCESS)
4160 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
4161 if (va_status != VA_STATUS_SUCCESS)
4164 VARectangle src_rect, dest_rect;
4167 src_rect.width = src_width;
4168 src_rect.height = src_height;
4169 dest_rect.x = dest_x;
4170 dest_rect.y = dest_y;
4171 dest_rect.width = dest_width;
4172 dest_rect.height = dest_height;
4174 switch (obj_image->image.format.fourcc) {
4175 case VA_FOURCC_YV12:
4176 case VA_FOURCC_I420:
4177 va_status = put_image_i420(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
4179 case VA_FOURCC_NV12:
4180 va_status = put_image_nv12(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
4182 case VA_FOURCC_YUY2:
4183 va_status = put_image_yuy2(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
4186 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
4189 if (va_status != VA_STATUS_SUCCESS)
4192 va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
4197 i965_hw_putimage(VADriverContextP ctx,
4198 VASurfaceID surface,
4202 unsigned int src_width,
4203 unsigned int src_height,
4206 unsigned int dest_width,
4207 unsigned int dest_height)
4209 struct i965_driver_data *i965 = i965_driver_data(ctx);
4210 struct object_surface *obj_surface = SURFACE(surface);
4211 struct object_image *obj_image = IMAGE(image);
4212 struct i965_surface src_surface, dst_surface;
4213 VAStatus va_status = VA_STATUS_SUCCESS;
4214 VARectangle src_rect, dst_rect;
4216 ASSERT_RET(obj_surface,VA_STATUS_ERROR_INVALID_SURFACE);
4217 ASSERT_RET(obj_image && obj_image->bo, VA_STATUS_ERROR_INVALID_IMAGE);
4221 src_x + src_width > obj_image->image.width ||
4222 src_y + src_height > obj_image->image.height)
4223 return VA_STATUS_ERROR_INVALID_PARAMETER;
4227 dest_x + dest_width > obj_surface->orig_width ||
4228 dest_y + dest_height > obj_surface->orig_height)
4229 return VA_STATUS_ERROR_INVALID_PARAMETER;
4231 if (!obj_surface->bo) {
4232 unsigned int tiling, swizzle;
4233 int surface_sampling = get_sampling_from_fourcc (obj_image->image.format.fourcc);;
4234 dri_bo_get_tiling(obj_image->bo, &tiling, &swizzle);
4236 i965_check_alloc_surface_bo(ctx,
4239 obj_image->image.format.fourcc,
4243 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
4245 src_surface.base = (struct object_base *)obj_image;
4246 src_surface.type = I965_SURFACE_TYPE_IMAGE;
4247 src_surface.flags = I965_SURFACE_FLAG_FRAME;
4250 src_rect.width = src_width;
4251 src_rect.height = src_height;
4253 dst_surface.base = (struct object_base *)obj_surface;
4254 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
4255 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
4256 dst_rect.x = dest_x;
4257 dst_rect.y = dest_y;
4258 dst_rect.width = dest_width;
4259 dst_rect.height = dest_height;
4261 va_status = i965_image_processing(ctx,
4271 i965_PutImage(VADriverContextP ctx,
4272 VASurfaceID surface,
4276 unsigned int src_width,
4277 unsigned int src_height,
4280 unsigned int dest_width,
4281 unsigned int dest_height)
4283 struct i965_driver_data *i965 = i965_driver_data(ctx);
4284 VAStatus va_status = VA_STATUS_SUCCESS;
4286 if (HAS_ACCELERATED_PUTIMAGE(i965))
4287 va_status = i965_hw_putimage(ctx,
4299 va_status = i965_sw_putimage(ctx,
4315 i965_PutSurface(VADriverContextP ctx,
4316 VASurfaceID surface,
4317 void *draw, /* X Drawable */
4320 unsigned short srcw,
4321 unsigned short srch,
4324 unsigned short destw,
4325 unsigned short desth,
4326 VARectangle *cliprects, /* client supplied clip list */
4327 unsigned int number_cliprects, /* number of clip rects in the clip list */
4328 unsigned int flags) /* de-interlacing flags */
4331 if (IS_VA_X11(ctx)) {
4332 VARectangle src_rect, dst_rect;
4336 src_rect.width = srcw;
4337 src_rect.height = srch;
4341 dst_rect.width = destw;
4342 dst_rect.height = desth;
4344 return i965_put_surface_dri(ctx, surface, draw, &src_rect, &dst_rect,
4345 cliprects, number_cliprects, flags);
4348 return VA_STATUS_ERROR_UNIMPLEMENTED;
4353 VADriverContextP ctx, /* in */
4354 VABufferID buf_id, /* in */
4355 VABufferType *type, /* out */
4356 unsigned int *size, /* out */
4357 unsigned int *num_elements /* out */
4360 struct i965_driver_data *i965 = NULL;
4361 struct object_buffer *obj_buffer = NULL;
4363 i965 = i965_driver_data(ctx);
4364 obj_buffer = BUFFER(buf_id);
4366 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
4368 *type = obj_buffer->type;
4369 *size = obj_buffer->size_element;
4370 *num_elements = obj_buffer->num_elements;
4372 return VA_STATUS_SUCCESS;
4377 VADriverContextP ctx, /* in */
4378 VASurfaceID surface, /* in */
4379 unsigned int *fourcc, /* out */
4380 unsigned int *luma_stride, /* out */
4381 unsigned int *chroma_u_stride, /* out */
4382 unsigned int *chroma_v_stride, /* out */
4383 unsigned int *luma_offset, /* out */
4384 unsigned int *chroma_u_offset, /* out */
4385 unsigned int *chroma_v_offset, /* out */
4386 unsigned int *buffer_name, /* out */
4387 void **buffer /* out */
4390 VAStatus vaStatus = VA_STATUS_SUCCESS;
4391 struct i965_driver_data *i965 = i965_driver_data(ctx);
4392 struct object_surface *obj_surface = NULL;
4395 ASSERT_RET(fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
4396 ASSERT_RET(luma_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4397 ASSERT_RET(chroma_u_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4398 ASSERT_RET(chroma_v_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4399 ASSERT_RET(luma_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4400 ASSERT_RET(chroma_u_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4401 ASSERT_RET(chroma_v_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4402 ASSERT_RET(buffer_name, VA_STATUS_ERROR_INVALID_PARAMETER);
4403 ASSERT_RET(buffer, VA_STATUS_ERROR_INVALID_PARAMETER);
4405 tmpImage.image_id = VA_INVALID_ID;
4407 obj_surface = SURFACE(surface);
4408 if (obj_surface == NULL) {
4409 // Surface is absent.
4410 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4414 // Lock functionality is absent now.
4415 if (obj_surface->locked_image_id != VA_INVALID_ID) {
4416 // Surface is locked already.
4417 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4421 vaStatus = i965_DeriveImage(
4425 if (vaStatus != VA_STATUS_SUCCESS) {
4429 obj_surface->locked_image_id = tmpImage.image_id;
4431 vaStatus = i965_MapBuffer(
4435 if (vaStatus != VA_STATUS_SUCCESS) {
4439 *fourcc = tmpImage.format.fourcc;
4440 *luma_offset = tmpImage.offsets[0];
4441 *luma_stride = tmpImage.pitches[0];
4442 *chroma_u_offset = tmpImage.offsets[1];
4443 *chroma_u_stride = tmpImage.pitches[1];
4444 *chroma_v_offset = tmpImage.offsets[2];
4445 *chroma_v_stride = tmpImage.pitches[2];
4446 *buffer_name = tmpImage.buf;
4449 if (vaStatus != VA_STATUS_SUCCESS) {
4458 VADriverContextP ctx, /* in */
4459 VASurfaceID surface /* in */
4462 VAStatus vaStatus = VA_STATUS_SUCCESS;
4463 struct i965_driver_data *i965 = i965_driver_data(ctx);
4464 struct object_image *locked_img = NULL;
4465 struct object_surface *obj_surface = NULL;
4467 obj_surface = SURFACE(surface);
4469 if (obj_surface == NULL) {
4470 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is absent
4473 if (obj_surface->locked_image_id == VA_INVALID_ID) {
4474 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is not locked
4478 locked_img = IMAGE(obj_surface->locked_image_id);
4479 if (locked_img == NULL || (locked_img->image.image_id == VA_INVALID_ID)) {
4480 // Work image was deallocated before i965_UnlockSurface()
4481 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4485 vaStatus = i965_UnmapBuffer(
4487 locked_img->image.buf);
4488 if (vaStatus != VA_STATUS_SUCCESS) {
4492 vaStatus = i965_DestroyImage(
4494 locked_img->image.image_id);
4495 if (vaStatus != VA_STATUS_SUCCESS) {
4499 locked_img->image.image_id = VA_INVALID_ID;
4502 obj_surface->locked_image_id = VA_INVALID_ID;
4508 i965_GetSurfaceAttributes(
4509 VADriverContextP ctx,
4511 VASurfaceAttrib *attrib_list,
4512 unsigned int num_attribs
4515 VAStatus vaStatus = VA_STATUS_SUCCESS;
4516 struct i965_driver_data *i965 = i965_driver_data(ctx);
4517 struct object_config *obj_config;
4520 if (config == VA_INVALID_ID)
4521 return VA_STATUS_ERROR_INVALID_CONFIG;
4523 obj_config = CONFIG(config);
4525 if (obj_config == NULL)
4526 return VA_STATUS_ERROR_INVALID_CONFIG;
4528 if (attrib_list == NULL || num_attribs == 0)
4529 return VA_STATUS_ERROR_INVALID_PARAMETER;
4531 for (i = 0; i < num_attribs; i++) {
4532 switch (attrib_list[i].type) {
4533 case VASurfaceAttribPixelFormat:
4534 attrib_list[i].value.type = VAGenericValueTypeInteger;
4535 attrib_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4537 if (attrib_list[i].value.value.i == 0) {
4538 if (IS_G4X(i965->intel.device_info)) {
4539 if (obj_config->profile == VAProfileMPEG2Simple ||
4540 obj_config->profile == VAProfileMPEG2Main) {
4541 attrib_list[i].value.value.i = VA_FOURCC_I420;
4544 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4546 } else if (IS_IRONLAKE(i965->intel.device_info)) {
4547 if (obj_config->profile == VAProfileMPEG2Simple ||
4548 obj_config->profile == VAProfileMPEG2Main) {
4549 attrib_list[i].value.value.i = VA_FOURCC_I420;
4550 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
4551 obj_config->profile == VAProfileH264Main ||
4552 obj_config->profile == VAProfileH264High) {
4553 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4554 } else if (obj_config->profile == VAProfileNone) {
4555 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4558 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4560 } else if (IS_GEN6(i965->intel.device_info)) {
4561 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4562 } else if (IS_GEN7(i965->intel.device_info) ||
4563 IS_GEN8(i965->intel.device_info)) {
4564 if (obj_config->profile == VAProfileJPEGBaseline)
4565 attrib_list[i].value.value.i = 0; /* internal format */
4567 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4570 if (IS_G4X(i965->intel.device_info)) {
4571 if (obj_config->profile == VAProfileMPEG2Simple ||
4572 obj_config->profile == VAProfileMPEG2Main) {
4573 if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
4574 attrib_list[i].value.value.i = 0;
4575 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4579 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4581 } else if (IS_IRONLAKE(i965->intel.device_info)) {
4582 if (obj_config->profile == VAProfileMPEG2Simple ||
4583 obj_config->profile == VAProfileMPEG2Main) {
4584 if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
4585 attrib_list[i].value.value.i = 0;
4586 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4588 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
4589 obj_config->profile == VAProfileH264Main ||
4590 obj_config->profile == VAProfileH264High) {
4591 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4592 attrib_list[i].value.value.i = 0;
4593 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4595 } else if (obj_config->profile == VAProfileNone) {
4596 switch (attrib_list[i].value.value.i) {
4597 case VA_FOURCC_NV12:
4598 case VA_FOURCC_I420:
4599 case VA_FOURCC_YV12:
4600 case VA_FOURCC_YUY2:
4601 case VA_FOURCC_BGRA:
4602 case VA_FOURCC_BGRX:
4603 case VA_FOURCC_RGBX:
4604 case VA_FOURCC_RGBA:
4607 attrib_list[i].value.value.i = 0;
4608 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4613 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4615 } else if (IS_GEN6(i965->intel.device_info)) {
4616 if (obj_config->entrypoint == VAEntrypointEncSlice ||
4617 obj_config->entrypoint == VAEntrypointVideoProc) {
4618 switch (attrib_list[i].value.value.i) {
4619 case VA_FOURCC_NV12:
4620 case VA_FOURCC_I420:
4621 case VA_FOURCC_YV12:
4622 case VA_FOURCC_YUY2:
4623 case VA_FOURCC_BGRA:
4624 case VA_FOURCC_BGRX:
4625 case VA_FOURCC_RGBX:
4626 case VA_FOURCC_RGBA:
4629 attrib_list[i].value.value.i = 0;
4630 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4634 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4635 attrib_list[i].value.value.i = 0;
4636 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4639 } else if (IS_GEN7(i965->intel.device_info) ||
4640 IS_GEN8(i965->intel.device_info)) {
4641 if (obj_config->entrypoint == VAEntrypointEncSlice ||
4642 obj_config->entrypoint == VAEntrypointVideoProc) {
4643 switch (attrib_list[i].value.value.i) {
4644 case VA_FOURCC_NV12:
4645 case VA_FOURCC_I420:
4646 case VA_FOURCC_YV12:
4649 attrib_list[i].value.value.i = 0;
4650 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4654 if (obj_config->profile == VAProfileJPEGBaseline) {
4655 attrib_list[i].value.value.i = 0; /* JPEG decoding always uses an internal format */
4656 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4658 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4659 attrib_list[i].value.value.i = 0;
4660 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4668 case VASurfaceAttribMinWidth:
4669 /* FIXME: add support for it later */
4670 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4672 case VASurfaceAttribMaxWidth:
4673 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4675 case VASurfaceAttribMinHeight:
4676 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4678 case VASurfaceAttribMaxHeight:
4679 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4682 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4691 i965_QuerySurfaceAttributes(VADriverContextP ctx,
4693 VASurfaceAttrib *attrib_list,
4694 unsigned int *num_attribs)
4696 VAStatus vaStatus = VA_STATUS_SUCCESS;
4697 struct i965_driver_data *i965 = i965_driver_data(ctx);
4698 struct object_config *obj_config;
4700 VASurfaceAttrib *attribs = NULL;
4702 if (config == VA_INVALID_ID)
4703 return VA_STATUS_ERROR_INVALID_CONFIG;
4705 obj_config = CONFIG(config);
4707 if (obj_config == NULL)
4708 return VA_STATUS_ERROR_INVALID_CONFIG;
4710 if (!attrib_list && !num_attribs)
4711 return VA_STATUS_ERROR_INVALID_PARAMETER;
4713 if (attrib_list == NULL) {
4714 *num_attribs = I965_MAX_SURFACE_ATTRIBUTES;
4715 return VA_STATUS_SUCCESS;
4718 attribs = malloc(I965_MAX_SURFACE_ATTRIBUTES *sizeof(*attribs));
4720 if (attribs == NULL)
4721 return VA_STATUS_ERROR_ALLOCATION_FAILED;
4723 if (IS_G4X(i965->intel.device_info)) {
4724 if (obj_config->profile == VAProfileMPEG2Simple ||
4725 obj_config->profile == VAProfileMPEG2Main) {
4726 attribs[i].type = VASurfaceAttribPixelFormat;
4727 attribs[i].value.type = VAGenericValueTypeInteger;
4728 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4729 attribs[i].value.value.i = VA_FOURCC_I420;
4732 } else if (IS_IRONLAKE(i965->intel.device_info)) {
4733 switch (obj_config->profile) {
4734 case VAProfileMPEG2Simple:
4735 case VAProfileMPEG2Main:
4736 attribs[i].type = VASurfaceAttribPixelFormat;
4737 attribs[i].value.type = VAGenericValueTypeInteger;
4738 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4739 attribs[i].value.value.i = VA_FOURCC_I420;
4744 case VAProfileH264ConstrainedBaseline:
4745 case VAProfileH264Main:
4746 case VAProfileH264High:
4747 attribs[i].type = VASurfaceAttribPixelFormat;
4748 attribs[i].value.type = VAGenericValueTypeInteger;
4749 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4750 attribs[i].value.value.i = VA_FOURCC_NV12;
4754 attribs[i].type = VASurfaceAttribPixelFormat;
4755 attribs[i].value.type = VAGenericValueTypeInteger;
4756 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4757 attribs[i].value.value.i = VA_FOURCC_NV12;
4760 attribs[i].type = VASurfaceAttribPixelFormat;
4761 attribs[i].value.type = VAGenericValueTypeInteger;
4762 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4763 attribs[i].value.value.i = VA_FOURCC_I420;
4771 } else if (IS_GEN6(i965->intel.device_info)) {
4772 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4773 attribs[i].type = VASurfaceAttribPixelFormat;
4774 attribs[i].value.type = VAGenericValueTypeInteger;
4775 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4776 attribs[i].value.value.i = VA_FOURCC_NV12;
4778 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
4779 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4780 attribs[i].type = VASurfaceAttribPixelFormat;
4781 attribs[i].value.type = VAGenericValueTypeInteger;
4782 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4783 attribs[i].value.value.i = VA_FOURCC_NV12;
4786 attribs[i].type = VASurfaceAttribPixelFormat;
4787 attribs[i].value.type = VAGenericValueTypeInteger;
4788 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4789 attribs[i].value.value.i = VA_FOURCC_I420;
4792 attribs[i].type = VASurfaceAttribPixelFormat;
4793 attribs[i].value.type = VAGenericValueTypeInteger;
4794 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4795 attribs[i].value.value.i = VA_FOURCC_YV12;
4798 if (obj_config->entrypoint == VAEntrypointVideoProc) {
4799 attribs[i].type = VASurfaceAttribPixelFormat;
4800 attribs[i].value.type = VAGenericValueTypeInteger;
4801 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4802 attribs[i].value.value.i = VA_FOURCC_YUY2;
4805 attribs[i].type = VASurfaceAttribPixelFormat;
4806 attribs[i].value.type = VAGenericValueTypeInteger;
4807 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4808 attribs[i].value.value.i = VA_FOURCC_RGBA;
4811 attribs[i].type = VASurfaceAttribPixelFormat;
4812 attribs[i].value.type = VAGenericValueTypeInteger;
4813 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4814 attribs[i].value.value.i = VA_FOURCC_RGBX;
4818 } else if (IS_GEN7(i965->intel.device_info)) {
4819 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4820 if (obj_config->profile == VAProfileJPEGBaseline) {
4821 attribs[i].type = VASurfaceAttribPixelFormat;
4822 attribs[i].value.type = VAGenericValueTypeInteger;
4823 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4824 attribs[i].value.value.i = VA_FOURCC_IMC3;
4827 attribs[i].type = VASurfaceAttribPixelFormat;
4828 attribs[i].value.type = VAGenericValueTypeInteger;
4829 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4830 attribs[i].value.value.i = VA_FOURCC_IMC1;
4833 attribs[i].type = VASurfaceAttribPixelFormat;
4834 attribs[i].value.type = VAGenericValueTypeInteger;
4835 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4836 attribs[i].value.value.i = VA_FOURCC_Y800;
4839 attribs[i].type = VASurfaceAttribPixelFormat;
4840 attribs[i].value.type = VAGenericValueTypeInteger;
4841 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4842 attribs[i].value.value.i = VA_FOURCC_411P;
4845 attribs[i].type = VASurfaceAttribPixelFormat;
4846 attribs[i].value.type = VAGenericValueTypeInteger;
4847 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4848 attribs[i].value.value.i = VA_FOURCC_422H;
4851 attribs[i].type = VASurfaceAttribPixelFormat;
4852 attribs[i].value.type = VAGenericValueTypeInteger;
4853 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4854 attribs[i].value.value.i = VA_FOURCC_422V;
4857 attribs[i].type = VASurfaceAttribPixelFormat;
4858 attribs[i].value.type = VAGenericValueTypeInteger;
4859 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4860 attribs[i].value.value.i = VA_FOURCC_444P;
4863 attribs[i].type = VASurfaceAttribPixelFormat;
4864 attribs[i].value.type = VAGenericValueTypeInteger;
4865 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4866 attribs[i].value.value.i = VA_FOURCC_NV12;
4869 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
4870 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4871 attribs[i].type = VASurfaceAttribPixelFormat;
4872 attribs[i].value.type = VAGenericValueTypeInteger;
4873 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4874 attribs[i].value.value.i = VA_FOURCC_NV12;
4877 attribs[i].type = VASurfaceAttribPixelFormat;
4878 attribs[i].value.type = VAGenericValueTypeInteger;
4879 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4880 attribs[i].value.value.i = VA_FOURCC_I420;
4883 attribs[i].type = VASurfaceAttribPixelFormat;
4884 attribs[i].value.type = VAGenericValueTypeInteger;
4885 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4886 attribs[i].value.value.i = VA_FOURCC_YV12;
4889 attribs[i].type = VASurfaceAttribPixelFormat;
4890 attribs[i].value.type = VAGenericValueTypeInteger;
4891 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4892 attribs[i].value.value.i = VA_FOURCC_IMC3;
4895 if (obj_config->entrypoint == VAEntrypointVideoProc) {
4896 attribs[i].type = VASurfaceAttribPixelFormat;
4897 attribs[i].value.type = VAGenericValueTypeInteger;
4898 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4899 attribs[i].value.value.i = VA_FOURCC_YUY2;
4902 attribs[i].type = VASurfaceAttribPixelFormat;
4903 attribs[i].value.type = VAGenericValueTypeInteger;
4904 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4905 attribs[i].value.value.i = VA_FOURCC_RGBA;
4908 attribs[i].type = VASurfaceAttribPixelFormat;
4909 attribs[i].value.type = VAGenericValueTypeInteger;
4910 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4911 attribs[i].value.value.i = VA_FOURCC_RGBX;
4914 attribs[i].type = VASurfaceAttribPixelFormat;
4915 attribs[i].value.type = VAGenericValueTypeInteger;
4916 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4917 attribs[i].value.value.i = VA_FOURCC_YV16;
4921 } else if (IS_GEN8(i965->intel.device_info)) {
4922 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4923 if (obj_config->profile == VAProfileJPEGBaseline) {
4924 attribs[i].type = VASurfaceAttribPixelFormat;
4925 attribs[i].value.type = VAGenericValueTypeInteger;
4926 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4927 attribs[i].value.value.i = VA_FOURCC_IMC3;
4930 attribs[i].type = VASurfaceAttribPixelFormat;
4931 attribs[i].value.type = VAGenericValueTypeInteger;
4932 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4933 attribs[i].value.value.i = VA_FOURCC_IMC1;
4936 attribs[i].type = VASurfaceAttribPixelFormat;
4937 attribs[i].value.type = VAGenericValueTypeInteger;
4938 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4939 attribs[i].value.value.i = VA_FOURCC_Y800;
4942 attribs[i].type = VASurfaceAttribPixelFormat;
4943 attribs[i].value.type = VAGenericValueTypeInteger;
4944 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4945 attribs[i].value.value.i = VA_FOURCC_411P;
4948 attribs[i].type = VASurfaceAttribPixelFormat;
4949 attribs[i].value.type = VAGenericValueTypeInteger;
4950 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4951 attribs[i].value.value.i = VA_FOURCC_422H;
4954 attribs[i].type = VASurfaceAttribPixelFormat;
4955 attribs[i].value.type = VAGenericValueTypeInteger;
4956 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4957 attribs[i].value.value.i = VA_FOURCC_422V;
4960 attribs[i].type = VASurfaceAttribPixelFormat;
4961 attribs[i].value.type = VAGenericValueTypeInteger;
4962 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4963 attribs[i].value.value.i = VA_FOURCC_444P;
4966 attribs[i].type = VASurfaceAttribPixelFormat;
4967 attribs[i].value.type = VAGenericValueTypeInteger;
4968 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4969 attribs[i].value.value.i = VA_FOURCC_NV12;
4972 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
4973 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4975 attribs[i].type = VASurfaceAttribPixelFormat;
4976 attribs[i].value.type = VAGenericValueTypeInteger;
4977 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4978 attribs[i].value.value.i = VA_FOURCC_NV12;
4981 attribs[i].type = VASurfaceAttribPixelFormat;
4982 attribs[i].value.type = VAGenericValueTypeInteger;
4983 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4984 attribs[i].value.value.i = VA_FOURCC_I420;
4987 attribs[i].type = VASurfaceAttribPixelFormat;
4988 attribs[i].value.type = VAGenericValueTypeInteger;
4989 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4990 attribs[i].value.value.i = VA_FOURCC_YV12;
4993 attribs[i].type = VASurfaceAttribPixelFormat;
4994 attribs[i].value.type = VAGenericValueTypeInteger;
4995 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4996 attribs[i].value.value.i = VA_FOURCC_IMC3;
4999 if (obj_config->entrypoint == VAEntrypointVideoProc) {
5000 attribs[i].type = VASurfaceAttribPixelFormat;
5001 attribs[i].value.type = VAGenericValueTypeInteger;
5002 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5003 attribs[i].value.value.i = VA_FOURCC_YUY2;
5006 attribs[i].type = VASurfaceAttribPixelFormat;
5007 attribs[i].value.type = VAGenericValueTypeInteger;
5008 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5009 attribs[i].value.value.i = VA_FOURCC_RGBA;
5012 attribs[i].type = VASurfaceAttribPixelFormat;
5013 attribs[i].value.type = VAGenericValueTypeInteger;
5014 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5015 attribs[i].value.value.i = VA_FOURCC_RGBX;
5018 attribs[i].type = VASurfaceAttribPixelFormat;
5019 attribs[i].value.type = VAGenericValueTypeInteger;
5020 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5021 attribs[i].value.value.i = VA_FOURCC_BGRA;
5024 attribs[i].type = VASurfaceAttribPixelFormat;
5025 attribs[i].value.type = VAGenericValueTypeInteger;
5026 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5027 attribs[i].value.value.i = VA_FOURCC_BGRX;
5030 attribs[i].type = VASurfaceAttribPixelFormat;
5031 attribs[i].value.type = VAGenericValueTypeInteger;
5032 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5033 attribs[i].value.value.i = VA_FOURCC_YV16;
5039 attribs[i].type = VASurfaceAttribMemoryType;
5040 attribs[i].value.type = VAGenericValueTypeInteger;
5041 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
5042 attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
5043 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
5044 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
5047 attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
5048 attribs[i].value.type = VAGenericValueTypePointer;
5049 attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
5050 attribs[i].value.value.p = NULL; /* ignore */
5053 if (i > *num_attribs) {
5056 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5060 memcpy(attrib_list, attribs, i * sizeof(*attribs));
5067 i965_os_has_ring_support(VADriverContextP ctx,
5070 struct i965_driver_data *const i965 = i965_driver_data(ctx);
5074 return i965->intel.has_bsd;
5077 return i965->intel.has_blt;
5079 case I965_RING_VEBOX:
5080 return i965->intel.has_vebox;
5082 case I965_RING_NULL:
5083 return 1; /* Always support */
5086 /* should never get here */
5095 * Query video processing pipeline
5097 VAStatus i965_QueryVideoProcFilters(
5098 VADriverContextP ctx,
5099 VAContextID context,
5100 VAProcFilterType *filters,
5101 unsigned int *num_filters
5104 struct i965_driver_data *const i965 = i965_driver_data(ctx);
5105 unsigned int i = 0, num = 0;
5107 if (!num_filters || !filters)
5108 return VA_STATUS_ERROR_INVALID_PARAMETER;
5110 for (i = 0; i < i965->codec_info->num_filters; i++) {
5111 if (i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring)) {
5112 if (num == *num_filters) {
5113 *num_filters = i965->codec_info->num_filters;
5115 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5118 filters[num++] = i965->codec_info->filters[i].type;
5124 return VA_STATUS_SUCCESS;
5127 VAStatus i965_QueryVideoProcFilterCaps(
5128 VADriverContextP ctx,
5129 VAContextID context,
5130 VAProcFilterType type,
5132 unsigned int *num_filter_caps
5136 struct i965_driver_data *const i965 = i965_driver_data(ctx);
5138 if (!filter_caps || !num_filter_caps)
5139 return VA_STATUS_ERROR_INVALID_PARAMETER;
5141 for (i = 0; i < i965->codec_info->num_filters; i++) {
5142 if (type == i965->codec_info->filters[i].type &&
5143 i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring))
5147 if (i == i965->codec_info->num_filters)
5148 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
5153 case VAProcFilterNoiseReduction:
5154 case VAProcFilterSharpening:
5156 VAProcFilterCap *cap = filter_caps;
5158 if (*num_filter_caps < 1) {
5159 *num_filter_caps = 1;
5160 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5163 cap->range.min_value = 0.0;
5164 cap->range.max_value = 1.0;
5165 cap->range.default_value = 0.5;
5166 cap->range.step = 0.03125; /* 1.0 / 32 */
5172 case VAProcFilterDeinterlacing:
5174 VAProcFilterCapDeinterlacing *cap = filter_caps;
5176 if (*num_filter_caps < VAProcDeinterlacingCount) {
5177 *num_filter_caps = VAProcDeinterlacingCount;
5178 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5181 cap->type = VAProcDeinterlacingBob;
5186 if (i965->codec_info->has_di_motion_adptive) {
5187 cap->type = VAProcDeinterlacingMotionAdaptive;
5192 if (i965->codec_info->has_di_motion_compensated) {
5193 cap->type = VAProcDeinterlacingMotionCompensated;
5201 case VAProcFilterColorBalance:
5203 VAProcFilterCapColorBalance *cap = filter_caps;
5205 if (*num_filter_caps < VAProcColorBalanceCount) {
5206 *num_filter_caps = VAProcColorBalanceCount;
5207 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
5210 cap->type = VAProcColorBalanceHue;
5211 cap->range.min_value = -180.0;
5212 cap->range.max_value = 180.0;
5213 cap->range.default_value = 0.0;
5214 cap->range.step = 1.0;
5218 cap->type = VAProcColorBalanceSaturation;
5219 cap->range.min_value = 0.0;
5220 cap->range.max_value = 10.0;
5221 cap->range.default_value = 1.0;
5222 cap->range.step = 0.1;
5226 cap->type = VAProcColorBalanceBrightness;
5227 cap->range.min_value = -100.0;
5228 cap->range.max_value = 100.0;
5229 cap->range.default_value = 0.0;
5230 cap->range.step = 1.0;
5234 cap->type = VAProcColorBalanceContrast;
5235 cap->range.min_value = 0.0;
5236 cap->range.max_value = 10.0;
5237 cap->range.default_value = 1.0;
5238 cap->range.step = 0.1;
5250 *num_filter_caps = i;
5252 return VA_STATUS_SUCCESS;
5255 static VAProcColorStandardType vpp_input_color_standards[VAProcColorStandardCount] = {
5256 VAProcColorStandardBT601,
5259 static VAProcColorStandardType vpp_output_color_standards[VAProcColorStandardCount] = {
5260 VAProcColorStandardBT601,
5263 VAStatus i965_QueryVideoProcPipelineCaps(
5264 VADriverContextP ctx,
5265 VAContextID context,
5266 VABufferID *filters,
5267 unsigned int num_filters,
5268 VAProcPipelineCaps *pipeline_cap /* out */
5271 struct i965_driver_data * const i965 = i965_driver_data(ctx);
5274 pipeline_cap->pipeline_flags = 0;
5275 pipeline_cap->filter_flags = 0;
5276 pipeline_cap->num_forward_references = 0;
5277 pipeline_cap->num_backward_references = 0;
5278 pipeline_cap->num_input_color_standards = 1;
5279 pipeline_cap->input_color_standards = vpp_input_color_standards;
5280 pipeline_cap->num_output_color_standards = 1;
5281 pipeline_cap->output_color_standards = vpp_output_color_standards;
5283 for (i = 0; i < num_filters; i++) {
5284 struct object_buffer *obj_buffer = BUFFER(filters[i]);
5287 !obj_buffer->buffer_store ||
5288 !obj_buffer->buffer_store->buffer)
5289 return VA_STATUS_ERROR_INVALID_BUFFER;
5291 VAProcFilterParameterBufferBase *base = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
5293 if (base->type == VAProcFilterNoiseReduction) {
5294 VAProcFilterParameterBuffer *denoise = (VAProcFilterParameterBuffer *)base;
5296 } else if (base->type == VAProcFilterDeinterlacing) {
5297 VAProcFilterParameterBufferDeinterlacing *deint = (VAProcFilterParameterBufferDeinterlacing *)base;
5299 ASSERT_RET(deint->algorithm == VAProcDeinterlacingBob ||
5300 deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
5301 deint->algorithm == VAProcDeinterlacingMotionCompensated,
5302 VA_STATUS_ERROR_INVALID_PARAMETER);
5304 if (deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
5305 deint->algorithm == VAProcDeinterlacingMotionCompensated);
5306 pipeline_cap->num_forward_references++;
5307 } else if (base->type == VAProcFilterSkinToneEnhancement) {
5308 VAProcFilterParameterBuffer *stde = (VAProcFilterParameterBuffer *)base;
5313 return VA_STATUS_SUCCESS;
5316 extern const struct hw_codec_info *i965_get_codec_info(int devid);
5319 i965_driver_data_init(VADriverContextP ctx)
5321 struct i965_driver_data *i965 = i965_driver_data(ctx);
5323 i965->codec_info = i965_get_codec_info(i965->intel.device_id);
5325 if (!i965->codec_info)
5328 if (object_heap_init(&i965->config_heap,
5329 sizeof(struct object_config),
5331 goto err_config_heap;
5332 if (object_heap_init(&i965->context_heap,
5333 sizeof(struct object_context),
5335 goto err_context_heap;
5337 if (object_heap_init(&i965->surface_heap,
5338 sizeof(struct object_surface),
5340 goto err_surface_heap;
5341 if (object_heap_init(&i965->buffer_heap,
5342 sizeof(struct object_buffer),
5344 goto err_buffer_heap;
5345 if (object_heap_init(&i965->image_heap,
5346 sizeof(struct object_image),
5348 goto err_image_heap;
5349 if (object_heap_init(&i965->subpic_heap,
5350 sizeof(struct object_subpic),
5352 goto err_subpic_heap;
5354 i965->batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
5355 i965->pp_batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
5356 _i965InitMutex(&i965->render_mutex);
5357 _i965InitMutex(&i965->pp_mutex);
5362 object_heap_destroy(&i965->image_heap);
5364 object_heap_destroy(&i965->buffer_heap);
5366 object_heap_destroy(&i965->surface_heap);
5368 object_heap_destroy(&i965->context_heap);
5370 object_heap_destroy(&i965->config_heap);
5377 i965_driver_data_terminate(VADriverContextP ctx)
5379 struct i965_driver_data *i965 = i965_driver_data(ctx);
5381 _i965DestroyMutex(&i965->pp_mutex);
5382 _i965DestroyMutex(&i965->render_mutex);
5385 intel_batchbuffer_free(i965->batch);
5388 intel_batchbuffer_free(i965->pp_batch);
5390 i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
5391 i965_destroy_heap(&i965->image_heap, i965_destroy_image);
5392 i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
5393 i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
5394 i965_destroy_heap(&i965->context_heap, i965_destroy_context);
5395 i965_destroy_heap(&i965->config_heap, i965_destroy_config);
5399 bool (*init)(VADriverContextP ctx);
5400 void (*terminate)(VADriverContextP ctx);
5402 } i965_sub_ops[] = {
5405 intel_driver_terminate,
5410 i965_driver_data_init,
5411 i965_driver_data_terminate,
5416 i965_display_attributes_init,
5417 i965_display_attributes_terminate,
5422 i965_post_processing_init,
5423 i965_post_processing_terminate,
5429 i965_render_terminate,
5433 #ifdef HAVE_VA_WAYLAND
5435 i965_output_wayland_init,
5436 i965_output_wayland_terminate,
5443 i965_output_dri_init,
5444 i965_output_dri_terminate,
5451 i965_Init(VADriverContextP ctx)
5453 struct i965_driver_data *i965 = i965_driver_data(ctx);
5455 const char *chipset;
5457 for (i = 0; i < ARRAY_ELEMS(i965_sub_ops); i++) {
5458 if ((i965_sub_ops[i].display_type == 0 ||
5459 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) &&
5460 !i965_sub_ops[i].init(ctx))
5464 if (i == ARRAY_ELEMS(i965_sub_ops)) {
5465 switch (i965->intel.device_id) {
5467 #define CHIPSET(id, family, dev, str) case id: chipset = str; break;
5468 #include "i965_pciids.h"
5470 chipset = "Unknown Intel Chipset";
5474 sprintf(i965->va_vendor, "%s %s driver for %s - %d.%d.%d",
5475 INTEL_STR_DRIVER_VENDOR,
5476 INTEL_STR_DRIVER_NAME,
5478 INTEL_DRIVER_MAJOR_VERSION,
5479 INTEL_DRIVER_MINOR_VERSION,
5480 INTEL_DRIVER_MICRO_VERSION);
5482 if (INTEL_DRIVER_PRE_VERSION > 0) {
5483 const int len = strlen(i965->va_vendor);
5484 sprintf(&i965->va_vendor[len], ".pre%d", INTEL_DRIVER_PRE_VERSION);
5487 i965->current_context_id = VA_INVALID_ID;
5489 return VA_STATUS_SUCCESS;
5493 for (; i >= 0; i--) {
5494 if (i965_sub_ops[i].display_type == 0 ||
5495 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
5496 i965_sub_ops[i].terminate(ctx);
5500 return VA_STATUS_ERROR_UNKNOWN;
5505 i965_Terminate(VADriverContextP ctx)
5507 struct i965_driver_data *i965 = i965_driver_data(ctx);
5511 for (i = ARRAY_ELEMS(i965_sub_ops); i > 0; i--)
5512 if (i965_sub_ops[i - 1].display_type == 0 ||
5513 i965_sub_ops[i - 1].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
5514 i965_sub_ops[i - 1].terminate(ctx);
5518 ctx->pDriverData = NULL;
5521 return VA_STATUS_SUCCESS;
5525 VA_DRIVER_INIT_FUNC(VADriverContextP ctx);
5528 VA_DRIVER_INIT_FUNC( VADriverContextP ctx )
5530 struct VADriverVTable * const vtable = ctx->vtable;
5531 struct VADriverVTableVPP * const vtable_vpp = ctx->vtable_vpp;
5533 struct i965_driver_data *i965;
5534 VAStatus ret = VA_STATUS_ERROR_UNKNOWN;
5536 ctx->version_major = VA_MAJOR_VERSION;
5537 ctx->version_minor = VA_MINOR_VERSION;
5538 ctx->max_profiles = I965_MAX_PROFILES;
5539 ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
5540 ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
5541 ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
5542 ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
5543 ctx->max_display_attributes = 1 + ARRAY_ELEMS(i965_display_attributes);
5545 vtable->vaTerminate = i965_Terminate;
5546 vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
5547 vtable->vaQueryConfigProfiles = i965_QueryConfigProfiles;
5548 vtable->vaQueryConfigAttributes = i965_QueryConfigAttributes;
5549 vtable->vaCreateConfig = i965_CreateConfig;
5550 vtable->vaDestroyConfig = i965_DestroyConfig;
5551 vtable->vaGetConfigAttributes = i965_GetConfigAttributes;
5552 vtable->vaCreateSurfaces = i965_CreateSurfaces;
5553 vtable->vaDestroySurfaces = i965_DestroySurfaces;
5554 vtable->vaCreateContext = i965_CreateContext;
5555 vtable->vaDestroyContext = i965_DestroyContext;
5556 vtable->vaCreateBuffer = i965_CreateBuffer;
5557 vtable->vaBufferSetNumElements = i965_BufferSetNumElements;
5558 vtable->vaMapBuffer = i965_MapBuffer;
5559 vtable->vaUnmapBuffer = i965_UnmapBuffer;
5560 vtable->vaDestroyBuffer = i965_DestroyBuffer;
5561 vtable->vaBeginPicture = i965_BeginPicture;
5562 vtable->vaRenderPicture = i965_RenderPicture;
5563 vtable->vaEndPicture = i965_EndPicture;
5564 vtable->vaSyncSurface = i965_SyncSurface;
5565 vtable->vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
5566 vtable->vaPutSurface = i965_PutSurface;
5567 vtable->vaQueryImageFormats = i965_QueryImageFormats;
5568 vtable->vaCreateImage = i965_CreateImage;
5569 vtable->vaDeriveImage = i965_DeriveImage;
5570 vtable->vaDestroyImage = i965_DestroyImage;
5571 vtable->vaSetImagePalette = i965_SetImagePalette;
5572 vtable->vaGetImage = i965_GetImage;
5573 vtable->vaPutImage = i965_PutImage;
5574 vtable->vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
5575 vtable->vaCreateSubpicture = i965_CreateSubpicture;
5576 vtable->vaDestroySubpicture = i965_DestroySubpicture;
5577 vtable->vaSetSubpictureImage = i965_SetSubpictureImage;
5578 vtable->vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
5579 vtable->vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
5580 vtable->vaAssociateSubpicture = i965_AssociateSubpicture;
5581 vtable->vaDeassociateSubpicture = i965_DeassociateSubpicture;
5582 vtable->vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
5583 vtable->vaGetDisplayAttributes = i965_GetDisplayAttributes;
5584 vtable->vaSetDisplayAttributes = i965_SetDisplayAttributes;
5585 vtable->vaBufferInfo = i965_BufferInfo;
5586 vtable->vaLockSurface = i965_LockSurface;
5587 vtable->vaUnlockSurface = i965_UnlockSurface;
5588 vtable->vaGetSurfaceAttributes = i965_GetSurfaceAttributes;
5589 vtable->vaQuerySurfaceAttributes = i965_QuerySurfaceAttributes;
5590 vtable->vaCreateSurfaces2 = i965_CreateSurfaces2;
5592 vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters;
5593 vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps;
5594 vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;
5596 i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
5599 ctx->pDriverData = NULL;
5601 return VA_STATUS_ERROR_ALLOCATION_FAILED;
5604 ctx->pDriverData = (void *)i965;
5605 ret = i965_Init(ctx);
5607 if (ret == VA_STATUS_SUCCESS) {
5608 ctx->str_vendor = i965->va_vendor;
5611 ctx->pDriverData = NULL;