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 && \
88 static int get_sampling_from_fourcc(unsigned int fourcc);
90 /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */
91 #define IS_VA_X11(ctx) \
92 (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_X11)
94 /* Check whether we are rendering to Wayland */
95 #define IS_VA_WAYLAND(ctx) \
96 (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_WAYLAND)
99 I965_SURFACETYPE_RGBA = 1,
100 I965_SURFACETYPE_YUV,
101 I965_SURFACETYPE_INDEXED
104 /* List of supported display attributes */
105 static const VADisplayAttribute i965_display_attributes[] = {
107 VADisplayAttribBrightness,
108 -100, 100, DEFAULT_BRIGHTNESS,
109 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
113 VADisplayAttribContrast,
114 0, 100, DEFAULT_CONTRAST,
115 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
120 -180, 180, DEFAULT_HUE,
121 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
125 VADisplayAttribSaturation,
126 0, 100, DEFAULT_SATURATION,
127 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE
131 VADisplayAttribRotation,
132 0, 3, VA_ROTATION_NONE,
133 VA_DISPLAY_ATTRIB_GETTABLE|VA_DISPLAY_ATTRIB_SETTABLE
137 /* List of supported image formats */
140 VAImageFormat va_format;
141 } i965_image_format_map_t;
143 static const i965_image_format_map_t
144 i965_image_formats_map[I965_MAX_IMAGE_FORMATS + 1] = {
145 { I965_SURFACETYPE_YUV,
146 { VA_FOURCC('Y','V','1','2'), VA_LSB_FIRST, 12, } },
147 { I965_SURFACETYPE_YUV,
148 { VA_FOURCC('I','4','2','0'), VA_LSB_FIRST, 12, } },
149 { I965_SURFACETYPE_YUV,
150 { VA_FOURCC('N','V','1','2'), VA_LSB_FIRST, 12, } },
151 { I965_SURFACETYPE_YUV,
152 { VA_FOURCC('Y','U','Y','2'), VA_LSB_FIRST, 16, } },
153 { I965_SURFACETYPE_YUV,
154 { VA_FOURCC('U','Y','V','Y'), VA_LSB_FIRST, 16, } },
155 { I965_SURFACETYPE_RGBA,
156 { VA_FOURCC('R','G','B','X'), VA_LSB_FIRST, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000 } },
157 { I965_SURFACETYPE_RGBA,
158 { VA_FOURCC('B','G','R','X'), VA_LSB_FIRST, 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff } },
161 /* List of supported subpicture formats */
165 VAImageFormat va_format;
166 unsigned int va_flags;
167 } i965_subpic_format_map_t;
169 #define COMMON_SUBPICTURE_FLAGS \
170 (VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD| \
171 VA_SUBPICTURE_GLOBAL_ALPHA)
173 static const i965_subpic_format_map_t
174 i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
175 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
176 { VA_FOURCC('I','A','4','4'), VA_MSB_FIRST, 8, },
177 COMMON_SUBPICTURE_FLAGS },
178 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
179 { VA_FOURCC('A','I','4','4'), VA_MSB_FIRST, 8, },
180 COMMON_SUBPICTURE_FLAGS },
181 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P8A8_UNORM,
182 { VA_FOURCC('I','A','8','8'), VA_MSB_FIRST, 16, },
183 COMMON_SUBPICTURE_FLAGS },
184 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A8P8_UNORM,
185 { VA_FOURCC('A','I','8','8'), VA_MSB_FIRST, 16, },
186 COMMON_SUBPICTURE_FLAGS },
187 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_B8G8R8A8_UNORM,
188 { VA_FOURCC('B','G','R','A'), VA_LSB_FIRST, 32,
189 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
190 COMMON_SUBPICTURE_FLAGS },
191 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_R8G8B8A8_UNORM,
192 { VA_FOURCC('R','G','B','A'), VA_LSB_FIRST, 32,
193 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
194 COMMON_SUBPICTURE_FLAGS },
197 static const i965_subpic_format_map_t *
198 get_subpic_format(const VAImageFormat *va_format)
201 for (i = 0; i965_subpic_formats_map[i].type != 0; i++) {
202 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
203 if (m->va_format.fourcc == va_format->fourcc &&
204 (m->type == I965_SURFACETYPE_RGBA ?
205 (m->va_format.byte_order == va_format->byte_order &&
206 m->va_format.red_mask == va_format->red_mask &&
207 m->va_format.green_mask == va_format->green_mask &&
208 m->va_format.blue_mask == va_format->blue_mask &&
209 m->va_format.alpha_mask == va_format->alpha_mask) : 1))
215 extern struct hw_context *i965_proc_context_init(VADriverContextP, struct object_config *);
216 extern struct hw_context *g4x_dec_hw_context_init(VADriverContextP, struct object_config *);
217 static struct hw_codec_info g4x_hw_codec_info = {
218 .dec_hw_context_init = g4x_dec_hw_context_init,
219 .enc_hw_context_init = NULL,
220 .proc_hw_context_init = NULL,
224 .has_mpeg2_decoding = 1,
229 extern struct hw_context *ironlake_dec_hw_context_init(VADriverContextP, struct object_config *);
230 static struct hw_codec_info ironlake_hw_codec_info = {
231 .dec_hw_context_init = ironlake_dec_hw_context_init,
232 .enc_hw_context_init = NULL,
233 .proc_hw_context_init = i965_proc_context_init,
237 .has_mpeg2_decoding = 1,
238 .has_h264_decoding = 1,
240 .has_accelerated_putimage = 1,
245 extern struct hw_context *gen6_dec_hw_context_init(VADriverContextP, struct object_config *);
246 extern struct hw_context *gen6_enc_hw_context_init(VADriverContextP, struct object_config *);
247 static struct hw_codec_info gen6_hw_codec_info = {
248 .dec_hw_context_init = gen6_dec_hw_context_init,
249 .enc_hw_context_init = gen6_enc_hw_context_init,
250 .proc_hw_context_init = i965_proc_context_init,
254 .has_mpeg2_decoding = 1,
255 .has_h264_decoding = 1,
256 .has_h264_encoding = 1,
257 .has_vc1_decoding = 1,
259 .has_accelerated_getimage = 1,
260 .has_accelerated_putimage = 1,
261 .has_tiled_surface = 1,
265 { VAProcFilterNoiseReduction, I965_RING_NULL },
266 { VAProcFilterDeinterlacing, I965_RING_NULL },
270 extern struct hw_context *gen7_dec_hw_context_init(VADriverContextP, struct object_config *);
271 extern struct hw_context *gen7_enc_hw_context_init(VADriverContextP, struct object_config *);
272 static struct hw_codec_info gen7_hw_codec_info = {
273 .dec_hw_context_init = gen7_dec_hw_context_init,
274 .enc_hw_context_init = gen7_enc_hw_context_init,
275 .proc_hw_context_init = i965_proc_context_init,
279 .has_mpeg2_decoding = 1,
280 .has_mpeg2_encoding = 1,
281 .has_h264_decoding = 1,
282 .has_h264_encoding = 1,
283 .has_vc1_decoding = 1,
284 .has_jpeg_decoding = 1,
286 .has_accelerated_getimage = 1,
287 .has_accelerated_putimage = 1,
288 .has_tiled_surface = 1,
289 .has_di_motion_adptive = 1,
293 { VAProcFilterNoiseReduction, I965_RING_NULL },
294 { VAProcFilterDeinterlacing, I965_RING_NULL },
298 extern struct hw_context *gen75_proc_context_init(VADriverContextP, struct object_config *);
299 static struct hw_codec_info gen75_hw_codec_info = {
300 .dec_hw_context_init = gen75_dec_hw_context_init,
301 .enc_hw_context_init = gen75_enc_hw_context_init,
302 .proc_hw_context_init = gen75_proc_context_init,
306 .has_mpeg2_decoding = 1,
307 .has_mpeg2_encoding = 1,
308 .has_h264_decoding = 1,
309 .has_h264_encoding = 1,
310 .has_vc1_decoding = 1,
311 .has_jpeg_decoding = 1,
313 .has_accelerated_getimage = 1,
314 .has_accelerated_putimage = 1,
315 .has_tiled_surface = 1,
316 .has_di_motion_adptive = 1,
317 .has_di_motion_compensated = 1,
321 { VAProcFilterNoiseReduction, I965_RING_VEBOX },
322 { VAProcFilterDeinterlacing, I965_RING_VEBOX },
323 { VAProcFilterSharpening, I965_RING_NULL },
324 { VAProcFilterColorBalance, I965_RING_VEBOX},
328 /* TODO: Add the separate call back function for Gen8 */
329 static struct hw_codec_info gen8_hw_codec_info = {
330 .dec_hw_context_init = gen8_dec_hw_context_init,
331 .enc_hw_context_init = gen8_enc_hw_context_init,
332 .proc_hw_context_init = gen75_proc_context_init,
336 .has_mpeg2_decoding = 1,
337 .has_mpeg2_encoding = 1,
338 .has_h264_decoding = 1,
339 .has_h264_encoding = 1,
340 .has_vc1_decoding = 1,
341 .has_jpeg_decoding = 1,
343 .has_accelerated_getimage = 1,
344 .has_accelerated_putimage = 1,
345 .has_tiled_surface = 1,
346 .has_di_motion_adptive = 1,
347 .has_di_motion_compensated = 1,
348 .has_vp8_decoding = 1,
352 { VAProcFilterNoiseReduction, I965_RING_VEBOX },
353 { VAProcFilterDeinterlacing, I965_RING_VEBOX },
354 { VAProcFilterSharpening, I965_RING_NULL }, /* need to rebuild the shader for BDW */
355 { VAProcFilterColorBalance, I965_RING_VEBOX},
359 #define I965_PACKED_HEADER_BASE 0
360 #define I965_PACKED_MISC_HEADER_BASE 3
363 va_enc_packed_type_to_idx(int packed_type)
367 if (packed_type & VAEncPackedHeaderMiscMask) {
368 idx = I965_PACKED_MISC_HEADER_BASE;
369 packed_type = (~VAEncPackedHeaderMiscMask & packed_type);
370 assert(packed_type > 0);
371 idx += (packed_type - 1);
373 idx = I965_PACKED_HEADER_BASE;
375 switch (packed_type) {
376 case VAEncPackedHeaderSequence:
377 idx = I965_PACKED_HEADER_BASE + 0;
380 case VAEncPackedHeaderPicture:
381 idx = I965_PACKED_HEADER_BASE + 1;
384 case VAEncPackedHeaderSlice:
385 idx = I965_PACKED_HEADER_BASE + 2;
389 /* Should not get here */
400 i965_QueryConfigProfiles(VADriverContextP ctx,
401 VAProfile *profile_list, /* out */
402 int *num_profiles) /* out */
404 struct i965_driver_data * const i965 = i965_driver_data(ctx);
407 if (HAS_MPEG2_DECODING(i965) ||
408 HAS_MPEG2_ENCODING(i965)) {
409 profile_list[i++] = VAProfileMPEG2Simple;
410 profile_list[i++] = VAProfileMPEG2Main;
413 if (HAS_H264_DECODING(i965) ||
414 HAS_H264_ENCODING(i965)) {
415 profile_list[i++] = VAProfileH264ConstrainedBaseline;
416 profile_list[i++] = VAProfileH264Main;
417 profile_list[i++] = VAProfileH264High;
420 if (HAS_VC1_DECODING(i965)) {
421 profile_list[i++] = VAProfileVC1Simple;
422 profile_list[i++] = VAProfileVC1Main;
423 profile_list[i++] = VAProfileVC1Advanced;
427 profile_list[i++] = VAProfileNone;
430 if (HAS_JPEG_DECODING(i965)) {
431 profile_list[i++] = VAProfileJPEGBaseline;
434 if (HAS_VP8_DECODING(i965) ||
435 HAS_VP8_ENCODING(i965)) {
436 profile_list[i++] = VAProfileVP8Version0_3;
439 /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
440 assert(i <= I965_MAX_PROFILES);
443 return VA_STATUS_SUCCESS;
447 i965_QueryConfigEntrypoints(VADriverContextP ctx,
449 VAEntrypoint *entrypoint_list, /* out */
450 int *num_entrypoints) /* out */
452 struct i965_driver_data * const i965 = i965_driver_data(ctx);
456 case VAProfileMPEG2Simple:
457 case VAProfileMPEG2Main:
458 if (HAS_MPEG2_DECODING(i965))
459 entrypoint_list[n++] = VAEntrypointVLD;
461 if (HAS_MPEG2_ENCODING(i965))
462 entrypoint_list[n++] = VAEntrypointEncSlice;
466 case VAProfileH264ConstrainedBaseline:
467 case VAProfileH264Main:
468 case VAProfileH264High:
469 if (HAS_H264_DECODING(i965))
470 entrypoint_list[n++] = VAEntrypointVLD;
472 if (HAS_H264_ENCODING(i965))
473 entrypoint_list[n++] = VAEntrypointEncSlice;
477 case VAProfileVC1Simple:
478 case VAProfileVC1Main:
479 case VAProfileVC1Advanced:
480 if (HAS_VC1_DECODING(i965))
481 entrypoint_list[n++] = VAEntrypointVLD;
486 entrypoint_list[n++] = VAEntrypointVideoProc;
489 case VAProfileJPEGBaseline:
490 if (HAS_JPEG_DECODING(i965))
491 entrypoint_list[n++] = VAEntrypointVLD;
494 case VAProfileVP8Version0_3:
495 if (HAS_VP8_DECODING(i965))
496 entrypoint_list[n++] = VAEntrypointVLD;
498 if (HAS_VP8_ENCODING(i965))
499 entrypoint_list[n++] = VAEntrypointEncSlice;
505 /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
506 assert(n <= I965_MAX_ENTRYPOINTS);
507 *num_entrypoints = n;
508 return n > 0 ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
512 i965_GetConfigAttributes(VADriverContextP ctx,
514 VAEntrypoint entrypoint,
515 VAConfigAttrib *attrib_list, /* in/out */
520 /* Other attributes don't seem to be defined */
521 /* What to do if we don't know the attribute? */
522 for (i = 0; i < num_attribs; i++) {
523 switch (attrib_list[i].type) {
524 case VAConfigAttribRTFormat:
525 attrib_list[i].value = VA_RT_FORMAT_YUV420;
528 case VAConfigAttribRateControl:
529 if (entrypoint == VAEntrypointEncSlice) {
530 attrib_list[i].value = VA_RC_CBR | VA_RC_CQP;
534 case VAConfigAttribEncPackedHeaders:
535 if (entrypoint == VAEntrypointEncSlice) {
536 attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
540 case VAConfigAttribEncMaxRefFrames:
541 if (entrypoint == VAEntrypointEncSlice) {
542 attrib_list[i].value = (1 << 16) | (1 << 0);
548 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
553 return VA_STATUS_SUCCESS;
557 i965_destroy_config(struct object_heap *heap, struct object_base *obj)
559 object_heap_free(heap, obj);
563 i965_update_attribute(struct object_config *obj_config, VAConfigAttrib *attrib)
567 /* Check existing attrbiutes */
568 for (i = 0; i < obj_config->num_attribs; i++) {
569 if (obj_config->attrib_list[i].type == attrib->type) {
570 /* Update existing attribute */
571 obj_config->attrib_list[i].value = attrib->value;
572 return VA_STATUS_SUCCESS;
576 if (obj_config->num_attribs < I965_MAX_CONFIG_ATTRIBUTES) {
577 i = obj_config->num_attribs;
578 obj_config->attrib_list[i].type = attrib->type;
579 obj_config->attrib_list[i].value = attrib->value;
580 obj_config->num_attribs++;
581 return VA_STATUS_SUCCESS;
584 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
588 i965_CreateConfig(VADriverContextP ctx,
590 VAEntrypoint entrypoint,
591 VAConfigAttrib *attrib_list,
593 VAConfigID *config_id) /* out */
595 struct i965_driver_data * const i965 = i965_driver_data(ctx);
596 struct object_config *obj_config;
601 /* Validate profile & entrypoint */
603 case VAProfileMPEG2Simple:
604 case VAProfileMPEG2Main:
605 if ((HAS_MPEG2_DECODING(i965) && VAEntrypointVLD == entrypoint) ||
606 (HAS_MPEG2_ENCODING(i965) && VAEntrypointEncSlice == entrypoint)) {
607 vaStatus = VA_STATUS_SUCCESS;
609 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
613 case VAProfileH264ConstrainedBaseline:
614 case VAProfileH264Main:
615 case VAProfileH264High:
616 if ((HAS_H264_DECODING(i965) && VAEntrypointVLD == entrypoint) ||
617 (HAS_H264_ENCODING(i965) && VAEntrypointEncSlice == entrypoint)) {
618 vaStatus = VA_STATUS_SUCCESS;
620 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
625 case VAProfileVC1Simple:
626 case VAProfileVC1Main:
627 case VAProfileVC1Advanced:
628 if (HAS_VC1_DECODING(i965) && VAEntrypointVLD == entrypoint) {
629 vaStatus = VA_STATUS_SUCCESS;
631 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
637 if (HAS_VPP(i965) && VAEntrypointVideoProc == entrypoint) {
638 vaStatus = VA_STATUS_SUCCESS;
640 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
645 case VAProfileJPEGBaseline:
646 if (HAS_JPEG_DECODING(i965) && VAEntrypointVLD == entrypoint) {
647 vaStatus = VA_STATUS_SUCCESS;
649 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
654 case VAProfileVP8Version0_3:
655 if ((HAS_VP8_DECODING(i965) && VAEntrypointVLD == entrypoint) ||
656 (HAS_VP8_ENCODING(i965) && VAEntrypointEncSlice == entrypoint))
657 vaStatus = VA_STATUS_SUCCESS;
659 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
664 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
668 if (VA_STATUS_SUCCESS != vaStatus) {
672 configID = NEW_CONFIG_ID();
673 obj_config = CONFIG(configID);
675 if (NULL == obj_config) {
676 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
680 obj_config->profile = profile;
681 obj_config->entrypoint = entrypoint;
682 obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
683 obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
684 obj_config->num_attribs = 1;
686 for(i = 0; i < num_attribs; i++) {
687 vaStatus = i965_update_attribute(obj_config, &(attrib_list[i]));
689 if (VA_STATUS_SUCCESS != vaStatus) {
695 if (VA_STATUS_SUCCESS != vaStatus) {
696 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
698 *config_id = configID;
705 i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
707 struct i965_driver_data *i965 = i965_driver_data(ctx);
708 struct object_config *obj_config = CONFIG(config_id);
711 if (NULL == obj_config) {
712 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
716 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
717 return VA_STATUS_SUCCESS;
720 VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
721 VAConfigID config_id,
722 VAProfile *profile, /* out */
723 VAEntrypoint *entrypoint, /* out */
724 VAConfigAttrib *attrib_list, /* out */
725 int *num_attribs) /* out */
727 struct i965_driver_data *i965 = i965_driver_data(ctx);
728 struct object_config *obj_config = CONFIG(config_id);
729 VAStatus vaStatus = VA_STATUS_SUCCESS;
733 *profile = obj_config->profile;
734 *entrypoint = obj_config->entrypoint;
735 *num_attribs = obj_config->num_attribs;
737 for(i = 0; i < obj_config->num_attribs; i++) {
738 attrib_list[i] = obj_config->attrib_list[i];
745 i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
747 struct object_surface *obj_surface = (struct object_surface *)obj;
749 dri_bo_unreference(obj_surface->bo);
750 obj_surface->bo = NULL;
752 if (obj_surface->free_private_data != NULL) {
753 obj_surface->free_private_data(&obj_surface->private_data);
754 obj_surface->private_data = NULL;
757 object_heap_free(heap, obj);
761 i965_surface_native_memory(VADriverContextP ctx,
762 struct object_surface *obj_surface,
766 struct i965_driver_data *i965 = i965_driver_data(ctx);
767 int tiling = HAS_TILED_SURFACE(i965);
769 if (!expected_fourcc)
770 return VA_STATUS_SUCCESS;
772 // todo, should we disable tiling for 422 format?
773 if (expected_fourcc == VA_FOURCC('I', '4', '2', '0') ||
774 expected_fourcc == VA_FOURCC('I', 'Y', 'U', 'V') ||
775 expected_fourcc == VA_FOURCC('Y', 'V', '1', '2'))
778 i965_check_alloc_surface_bo(ctx, obj_surface, tiling, expected_fourcc, get_sampling_from_fourcc(expected_fourcc));
780 return VA_STATUS_SUCCESS;
784 i965_suface_external_memory(VADriverContextP ctx,
785 struct object_surface *obj_surface,
786 int external_memory_type,
787 VASurfaceAttribExternalBuffers *memory_attibute,
790 struct i965_driver_data *i965 = i965_driver_data(ctx);
792 if (!memory_attibute ||
793 !memory_attibute->buffers ||
794 index > memory_attibute->num_buffers)
795 return VA_STATUS_ERROR_INVALID_PARAMETER;
797 assert(obj_surface->orig_width == memory_attibute->width);
798 assert(obj_surface->orig_height == memory_attibute->height);
799 assert(memory_attibute->num_planes >= 1);
801 obj_surface->fourcc = memory_attibute->pixel_format;
802 obj_surface->width = memory_attibute->pitches[0];
803 obj_surface->size = memory_attibute->data_size;
805 if (memory_attibute->num_planes == 1)
806 obj_surface->height = memory_attibute->data_size / obj_surface->width;
808 obj_surface->height = memory_attibute->offsets[1] / obj_surface->width;
810 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
811 obj_surface->x_cr_offset = 0;
813 switch (obj_surface->fourcc) {
814 case VA_FOURCC('N', 'V', '1', '2'):
815 assert(memory_attibute->num_planes == 2);
816 assert(memory_attibute->pitches[0] == memory_attibute->pitches[1]);
818 obj_surface->subsampling = SUBSAMPLE_YUV420;
819 obj_surface->y_cb_offset = obj_surface->height;
820 obj_surface->y_cr_offset = obj_surface->height;
821 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
822 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
823 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
827 case VA_FOURCC('Y', 'V', '1', '2'):
828 case VA_FOURCC('I', 'M', 'C', '1'):
829 assert(memory_attibute->num_planes == 3);
830 assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
832 obj_surface->subsampling = SUBSAMPLE_YUV420;
833 obj_surface->y_cr_offset = obj_surface->height;
834 obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
835 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
836 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
837 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
841 case VA_FOURCC('I', '4', '2', '0'):
842 case VA_FOURCC('I', 'Y', 'U', 'V'):
843 case VA_FOURCC('I', 'M', 'C', '3'):
844 assert(memory_attibute->num_planes == 3);
845 assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
847 obj_surface->subsampling = SUBSAMPLE_YUV420;
848 obj_surface->y_cb_offset = obj_surface->height;
849 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
850 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
851 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
852 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
856 case VA_FOURCC('Y', 'U', 'Y', '2'):
857 case VA_FOURCC('U', 'Y', 'V', 'Y'):
858 assert(memory_attibute->num_planes == 1);
860 obj_surface->subsampling = SUBSAMPLE_YUV422H;
861 obj_surface->y_cb_offset = 0;
862 obj_surface->y_cr_offset = 0;
863 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
864 obj_surface->cb_cr_height = obj_surface->orig_height;
865 obj_surface->cb_cr_pitch = memory_attibute->pitches[0];
869 case VA_FOURCC('R', 'G', 'B', 'A'):
870 case VA_FOURCC('R', 'G', 'B', 'X'):
871 case VA_FOURCC('B', 'G', 'R', 'A'):
872 case VA_FOURCC('B', 'G', 'R', 'X'):
873 assert(memory_attibute->num_planes == 1);
875 obj_surface->subsampling = SUBSAMPLE_RGBX;
876 obj_surface->y_cb_offset = 0;
877 obj_surface->y_cr_offset = 0;
878 obj_surface->cb_cr_width = 0;
879 obj_surface->cb_cr_height = 0;
880 obj_surface->cb_cr_pitch = 0;
884 case VA_FOURCC('Y', '8', '0', '0'): /* monochrome surface */
885 assert(memory_attibute->num_planes == 1);
887 obj_surface->subsampling = SUBSAMPLE_YUV400;
888 obj_surface->y_cb_offset = 0;
889 obj_surface->y_cr_offset = 0;
890 obj_surface->cb_cr_width = 0;
891 obj_surface->cb_cr_height = 0;
892 obj_surface->cb_cr_pitch = 0;
896 case VA_FOURCC('4', '1', '1', 'P'):
897 assert(memory_attibute->num_planes == 3);
898 assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
900 obj_surface->subsampling = SUBSAMPLE_YUV411;
901 obj_surface->y_cb_offset = 0;
902 obj_surface->y_cr_offset = 0;
903 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
904 obj_surface->cb_cr_height = obj_surface->orig_height;
905 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
909 case VA_FOURCC('4', '2', '2', 'H'):
910 assert(memory_attibute->num_planes == 3);
911 assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
913 obj_surface->subsampling = SUBSAMPLE_YUV422H;
914 obj_surface->y_cb_offset = obj_surface->height;
915 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
916 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
917 obj_surface->cb_cr_height = obj_surface->orig_height;
918 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
922 case VA_FOURCC('4', '2', '2', 'V'):
923 assert(memory_attibute->num_planes == 3);
924 assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
926 obj_surface->subsampling = SUBSAMPLE_YUV422H;
927 obj_surface->y_cb_offset = obj_surface->height;
928 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
929 obj_surface->cb_cr_width = obj_surface->orig_width;
930 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
931 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
935 case VA_FOURCC('4', '4', '4', 'P'):
936 assert(memory_attibute->num_planes == 3);
937 assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
939 obj_surface->subsampling = SUBSAMPLE_YUV444;
940 obj_surface->y_cb_offset = obj_surface->height;
941 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
942 obj_surface->cb_cr_width = obj_surface->orig_width;
943 obj_surface->cb_cr_height = obj_surface->orig_height;
944 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
950 return VA_STATUS_ERROR_INVALID_PARAMETER;
953 if (external_memory_type == I965_SURFACE_MEM_GEM_FLINK)
954 obj_surface->bo = drm_intel_bo_gem_create_from_name(i965->intel.bufmgr,
955 "gem flinked vaapi surface",
956 memory_attibute->buffers[index]);
957 else if (external_memory_type == I965_SURFACE_MEM_DRM_PRIME)
958 obj_surface->bo = drm_intel_bo_gem_create_from_prime(i965->intel.bufmgr,
959 memory_attibute->buffers[index],
962 if (!obj_surface->bo)
963 return VA_STATUS_ERROR_INVALID_PARAMETER;
965 return VA_STATUS_SUCCESS;
969 i965_CreateSurfaces2(
970 VADriverContextP ctx,
974 VASurfaceID *surfaces,
975 unsigned int num_surfaces,
976 VASurfaceAttrib *attrib_list,
977 unsigned int num_attribs
980 struct i965_driver_data *i965 = i965_driver_data(ctx);
982 VAStatus vaStatus = VA_STATUS_SUCCESS;
983 int expected_fourcc = 0;
984 int memory_type = I965_SURFACE_MEM_NATIVE; /* native */
985 VASurfaceAttribExternalBuffers *memory_attibute = NULL;
987 for (i = 0; i < num_attribs && attrib_list; i++) {
988 if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
989 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
990 assert(attrib_list[i].value.type == VAGenericValueTypeInteger);
991 expected_fourcc = attrib_list[i].value.value.i;
994 if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&
995 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
997 assert(attrib_list[i].value.type == VAGenericValueTypeInteger);
999 if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
1000 memory_type = I965_SURFACE_MEM_GEM_FLINK; /* flinked GEM handle */
1001 else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)
1002 memory_type = I965_SURFACE_MEM_DRM_PRIME; /* drm prime fd */
1005 if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&
1006 (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {
1007 assert(attrib_list[i].value.type == VAGenericValueTypePointer);
1008 memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;
1012 /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used
1013 * for post-processing (including color conversion) */
1014 if (VA_RT_FORMAT_YUV420 != format &&
1015 VA_RT_FORMAT_YUV422 != format &&
1016 VA_RT_FORMAT_YUV444 != format &&
1017 VA_RT_FORMAT_YUV411 != format &&
1018 VA_RT_FORMAT_YUV400 != format &&
1019 VA_RT_FORMAT_RGB32 != format) {
1020 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
1023 for (i = 0; i < num_surfaces; i++) {
1024 int surfaceID = NEW_SURFACE_ID();
1025 struct object_surface *obj_surface = SURFACE(surfaceID);
1027 if (NULL == obj_surface) {
1028 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1032 surfaces[i] = surfaceID;
1033 obj_surface->status = VASurfaceReady;
1034 obj_surface->orig_width = width;
1035 obj_surface->orig_height = height;
1037 obj_surface->subpic_render_idx = 0;
1038 for(j = 0; j < I965_MAX_SUBPIC_SUM; j++){
1039 obj_surface->subpic[j] = VA_INVALID_ID;
1040 obj_surface->obj_subpic[j] = NULL;
1043 obj_surface->width = ALIGN(width, 16);
1044 obj_surface->height = ALIGN(height, 16);
1045 obj_surface->flags = SURFACE_REFERENCED;
1046 obj_surface->fourcc = 0;
1047 obj_surface->bo = NULL;
1048 obj_surface->locked_image_id = VA_INVALID_ID;
1049 obj_surface->private_data = NULL;
1050 obj_surface->free_private_data = NULL;
1051 obj_surface->subsampling = SUBSAMPLE_YUV420;
1053 switch (memory_type) {
1054 case I965_SURFACE_MEM_NATIVE:
1055 i965_surface_native_memory(ctx,
1061 case I965_SURFACE_MEM_GEM_FLINK:
1062 case I965_SURFACE_MEM_DRM_PRIME:
1063 i965_suface_external_memory(ctx,
1072 /* Error recovery */
1073 if (VA_STATUS_SUCCESS != vaStatus) {
1074 /* surfaces[i-1] was the last successful allocation */
1076 struct object_surface *obj_surface = SURFACE(surfaces[i]);
1078 surfaces[i] = VA_INVALID_SURFACE;
1079 assert(obj_surface);
1080 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1088 i965_CreateSurfaces(VADriverContextP ctx,
1093 VASurfaceID *surfaces) /* out */
1095 return i965_CreateSurfaces2(ctx,
1106 i965_DestroySurfaces(VADriverContextP ctx,
1107 VASurfaceID *surface_list,
1110 struct i965_driver_data *i965 = i965_driver_data(ctx);
1113 for (i = num_surfaces; i--; ) {
1114 struct object_surface *obj_surface = SURFACE(surface_list[i]);
1116 assert(obj_surface);
1117 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1120 return VA_STATUS_SUCCESS;
1124 i965_QueryImageFormats(VADriverContextP ctx,
1125 VAImageFormat *format_list, /* out */
1126 int *num_formats) /* out */
1130 for (n = 0; i965_image_formats_map[n].va_format.fourcc != 0; n++) {
1131 const i965_image_format_map_t * const m = &i965_image_formats_map[n];
1133 format_list[n] = m->va_format;
1139 return VA_STATUS_SUCCESS;
1143 * Guess the format when the usage of a VA surface is unknown
1144 * 1. Without a valid context: YV12
1145 * 2. The current context is valid:
1146 * a) always NV12 on GEN6 and later
1147 * b) I420 for MPEG-2 and NV12 for other codec on GEN4 & GEN5
1150 i965_guess_surface_format(VADriverContextP ctx,
1151 VASurfaceID surface,
1152 unsigned int *fourcc,
1153 unsigned int *is_tiled)
1155 struct i965_driver_data *i965 = i965_driver_data(ctx);
1156 struct object_context *obj_context = NULL;
1157 struct object_config *obj_config = NULL;
1159 *fourcc = VA_FOURCC('Y', 'V', '1', '2');
1162 if (i965->current_context_id == VA_INVALID_ID)
1165 obj_context = CONTEXT(i965->current_context_id);
1170 obj_config = obj_context->obj_config;
1176 if (IS_GEN6(i965->intel.device_id) ||
1177 IS_GEN7(i965->intel.device_id) ||
1178 IS_GEN8(i965->intel.device_id)) {
1179 *fourcc = VA_FOURCC('N', 'V', '1', '2');
1184 switch (obj_config->profile) {
1185 case VAProfileMPEG2Simple:
1186 case VAProfileMPEG2Main:
1187 *fourcc = VA_FOURCC('I', '4', '2', '0');
1192 *fourcc = VA_FOURCC('N', 'V', '1', '2');
1199 i965_QuerySubpictureFormats(VADriverContextP ctx,
1200 VAImageFormat *format_list, /* out */
1201 unsigned int *flags, /* out */
1202 unsigned int *num_formats) /* out */
1206 for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
1207 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
1209 format_list[n] = m->va_format;
1211 flags[n] = m->va_flags;
1217 return VA_STATUS_SUCCESS;
1221 i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
1223 // struct object_subpic *obj_subpic = (struct object_subpic *)obj;
1225 object_heap_free(heap, obj);
1229 i965_CreateSubpicture(VADriverContextP ctx,
1231 VASubpictureID *subpicture) /* out */
1233 struct i965_driver_data *i965 = i965_driver_data(ctx);
1234 VASubpictureID subpicID = NEW_SUBPIC_ID()
1235 struct object_subpic *obj_subpic = SUBPIC(subpicID);
1238 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1240 struct object_image *obj_image = IMAGE(image);
1242 return VA_STATUS_ERROR_INVALID_IMAGE;
1244 const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
1246 return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
1248 *subpicture = subpicID;
1249 obj_subpic->image = image;
1250 obj_subpic->obj_image = obj_image;
1251 obj_subpic->format = m->format;
1252 obj_subpic->width = obj_image->image.width;
1253 obj_subpic->height = obj_image->image.height;
1254 obj_subpic->pitch = obj_image->image.pitches[0];
1255 obj_subpic->bo = obj_image->bo;
1256 obj_subpic->global_alpha = 1.0;
1258 return VA_STATUS_SUCCESS;
1262 i965_DestroySubpicture(VADriverContextP ctx,
1263 VASubpictureID subpicture)
1265 struct i965_driver_data *i965 = i965_driver_data(ctx);
1266 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1269 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1271 assert(obj_subpic->obj_image);
1272 i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
1273 return VA_STATUS_SUCCESS;
1277 i965_SetSubpictureImage(VADriverContextP ctx,
1278 VASubpictureID subpicture,
1282 return VA_STATUS_ERROR_UNIMPLEMENTED;
1286 i965_SetSubpictureChromakey(VADriverContextP ctx,
1287 VASubpictureID subpicture,
1288 unsigned int chromakey_min,
1289 unsigned int chromakey_max,
1290 unsigned int chromakey_mask)
1293 return VA_STATUS_ERROR_UNIMPLEMENTED;
1297 i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
1298 VASubpictureID subpicture,
1301 struct i965_driver_data *i965 = i965_driver_data(ctx);
1302 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1304 if(global_alpha > 1.0 || global_alpha < 0.0){
1305 return VA_STATUS_ERROR_INVALID_PARAMETER;
1309 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1311 obj_subpic->global_alpha = global_alpha;
1313 return VA_STATUS_SUCCESS;
1317 i965_AssociateSubpicture(VADriverContextP ctx,
1318 VASubpictureID subpicture,
1319 VASurfaceID *target_surfaces,
1321 short src_x, /* upper left offset in subpicture */
1323 unsigned short src_width,
1324 unsigned short src_height,
1325 short dest_x, /* upper left offset in surface */
1327 unsigned short dest_width,
1328 unsigned short dest_height,
1330 * whether to enable chroma-keying or global-alpha
1331 * see VA_SUBPICTURE_XXX values
1335 struct i965_driver_data *i965 = i965_driver_data(ctx);
1336 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1340 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1342 assert(obj_subpic->obj_image);
1344 obj_subpic->src_rect.x = src_x;
1345 obj_subpic->src_rect.y = src_y;
1346 obj_subpic->src_rect.width = src_width;
1347 obj_subpic->src_rect.height = src_height;
1348 obj_subpic->dst_rect.x = dest_x;
1349 obj_subpic->dst_rect.y = dest_y;
1350 obj_subpic->dst_rect.width = dest_width;
1351 obj_subpic->dst_rect.height = dest_height;
1352 obj_subpic->flags = flags;
1354 for (i = 0; i < num_surfaces; i++) {
1355 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1357 return VA_STATUS_ERROR_INVALID_SURFACE;
1359 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1360 if(obj_surface->subpic[j] == VA_INVALID_ID){
1361 assert(obj_surface->obj_subpic[j] == NULL);
1362 obj_surface->subpic[j] = subpicture;
1363 obj_surface->obj_subpic[j] = obj_subpic;
1368 if(j == I965_MAX_SUBPIC_SUM){
1369 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1373 return VA_STATUS_SUCCESS;
1378 i965_DeassociateSubpicture(VADriverContextP ctx,
1379 VASubpictureID subpicture,
1380 VASurfaceID *target_surfaces,
1383 struct i965_driver_data *i965 = i965_driver_data(ctx);
1384 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1388 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1390 for (i = 0; i < num_surfaces; i++) {
1391 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1393 return VA_STATUS_ERROR_INVALID_SURFACE;
1395 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1396 if (obj_surface->subpic[j] == subpicture) {
1397 assert(obj_surface->obj_subpic[j] == obj_subpic);
1398 obj_surface->subpic[j] = VA_INVALID_ID;
1399 obj_surface->obj_subpic[j] = NULL;
1404 if(j == I965_MAX_SUBPIC_SUM){
1405 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1408 return VA_STATUS_SUCCESS;
1412 i965_reference_buffer_store(struct buffer_store **ptr,
1413 struct buffer_store *buffer_store)
1415 assert(*ptr == NULL);
1418 buffer_store->ref_count++;
1419 *ptr = buffer_store;
1424 i965_release_buffer_store(struct buffer_store **ptr)
1426 struct buffer_store *buffer_store = *ptr;
1428 if (buffer_store == NULL)
1431 assert(buffer_store->bo || buffer_store->buffer);
1432 assert(!(buffer_store->bo && buffer_store->buffer));
1433 buffer_store->ref_count--;
1435 if (buffer_store->ref_count == 0) {
1436 dri_bo_unreference(buffer_store->bo);
1437 free(buffer_store->buffer);
1438 buffer_store->bo = NULL;
1439 buffer_store->buffer = NULL;
1447 i965_destroy_context(struct object_heap *heap, struct object_base *obj)
1449 struct object_context *obj_context = (struct object_context *)obj;
1452 if (obj_context->hw_context) {
1453 obj_context->hw_context->destroy(obj_context->hw_context);
1454 obj_context->hw_context = NULL;
1457 if (obj_context->codec_type == CODEC_PROC) {
1458 i965_release_buffer_store(&obj_context->codec_state.proc.pipeline_param);
1460 } else if (obj_context->codec_type == CODEC_ENC) {
1461 assert(obj_context->codec_state.encode.num_slice_params <= obj_context->codec_state.encode.max_slice_params);
1462 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
1463 i965_release_buffer_store(&obj_context->codec_state.encode.seq_param);
1465 for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++)
1466 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
1468 free(obj_context->codec_state.encode.slice_params);
1470 assert(obj_context->codec_state.encode.num_slice_params_ext <= obj_context->codec_state.encode.max_slice_params_ext);
1471 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
1472 i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
1474 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
1475 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
1477 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
1478 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
1480 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
1481 i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i]);
1483 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
1484 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
1486 free(obj_context->codec_state.encode.slice_params_ext);
1488 assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
1489 assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
1491 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
1492 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
1493 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
1495 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++)
1496 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
1498 for (i = 0; i < obj_context->codec_state.decode.num_slice_datas; i++)
1499 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
1501 free(obj_context->codec_state.decode.slice_params);
1502 free(obj_context->codec_state.decode.slice_datas);
1505 free(obj_context->render_targets);
1506 object_heap_free(heap, obj);
1510 i965_CreateContext(VADriverContextP ctx,
1511 VAConfigID config_id,
1515 VASurfaceID *render_targets,
1516 int num_render_targets,
1517 VAContextID *context) /* out */
1519 struct i965_driver_data *i965 = i965_driver_data(ctx);
1520 struct i965_render_state *render_state = &i965->render_state;
1521 struct object_config *obj_config = CONFIG(config_id);
1522 struct object_context *obj_context = NULL;
1523 VAStatus vaStatus = VA_STATUS_SUCCESS;
1527 if (NULL == obj_config) {
1528 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
1532 if (picture_width > i965->codec_info->max_width ||
1533 picture_height > i965->codec_info->max_height) {
1534 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
1539 /* Validate picture dimensions */
1540 contextID = NEW_CONTEXT_ID();
1541 obj_context = CONTEXT(contextID);
1543 if (NULL == obj_context) {
1544 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1548 render_state->inited = 1;
1550 switch (obj_config->profile) {
1551 case VAProfileH264ConstrainedBaseline:
1552 case VAProfileH264Main:
1553 case VAProfileH264High:
1554 if (!HAS_H264_DECODING(i965) &&
1555 !HAS_H264_ENCODING(i965))
1556 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1557 render_state->interleaved_uv = 1;
1560 render_state->interleaved_uv = !!(IS_GEN6(i965->intel.device_id) || IS_GEN7(i965->intel.device_id) || IS_GEN8(i965->intel.device_id));
1564 *context = contextID;
1565 obj_context->flags = flag;
1566 obj_context->context_id = contextID;
1567 obj_context->obj_config = obj_config;
1568 obj_context->picture_width = picture_width;
1569 obj_context->picture_height = picture_height;
1570 obj_context->num_render_targets = num_render_targets;
1571 obj_context->render_targets =
1572 (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
1573 obj_context->hw_context = NULL;
1575 for(i = 0; i < num_render_targets; i++) {
1576 if (NULL == SURFACE(render_targets[i])) {
1577 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1581 obj_context->render_targets[i] = render_targets[i];
1584 if (VA_STATUS_SUCCESS == vaStatus) {
1585 if (VAEntrypointVideoProc == obj_config->entrypoint) {
1586 obj_context->codec_type = CODEC_PROC;
1587 memset(&obj_context->codec_state.proc, 0, sizeof(obj_context->codec_state.proc));
1588 obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
1589 assert(i965->codec_info->proc_hw_context_init);
1590 obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
1591 } else if (VAEntrypointEncSlice == obj_config->entrypoint) { /*encode routin only*/
1592 obj_context->codec_type = CODEC_ENC;
1593 memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
1594 obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
1595 obj_context->codec_state.encode.max_slice_params = NUM_SLICES;
1596 obj_context->codec_state.encode.slice_params = calloc(obj_context->codec_state.encode.max_slice_params,
1597 sizeof(*obj_context->codec_state.encode.slice_params));
1598 assert(i965->codec_info->enc_hw_context_init);
1599 obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
1601 obj_context->codec_type = CODEC_DEC;
1602 memset(&obj_context->codec_state.decode, 0, sizeof(obj_context->codec_state.decode));
1603 obj_context->codec_state.decode.current_render_target = -1;
1604 obj_context->codec_state.decode.max_slice_params = NUM_SLICES;
1605 obj_context->codec_state.decode.max_slice_datas = NUM_SLICES;
1606 obj_context->codec_state.decode.slice_params = calloc(obj_context->codec_state.decode.max_slice_params,
1607 sizeof(*obj_context->codec_state.decode.slice_params));
1608 obj_context->codec_state.decode.slice_datas = calloc(obj_context->codec_state.decode.max_slice_datas,
1609 sizeof(*obj_context->codec_state.decode.slice_datas));
1611 assert(i965->codec_info->dec_hw_context_init);
1612 obj_context->hw_context = i965->codec_info->dec_hw_context_init(ctx, obj_config);
1616 /* Error recovery */
1617 if (VA_STATUS_SUCCESS != vaStatus) {
1618 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1621 i965->current_context_id = contextID;
1627 i965_DestroyContext(VADriverContextP ctx, VAContextID context)
1629 struct i965_driver_data *i965 = i965_driver_data(ctx);
1630 struct object_context *obj_context = CONTEXT(context);
1632 assert(obj_context);
1634 if (i965->current_context_id == context)
1635 i965->current_context_id = VA_INVALID_ID;
1637 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1639 return VA_STATUS_SUCCESS;
1643 i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
1645 struct object_buffer *obj_buffer = (struct object_buffer *)obj;
1647 assert(obj_buffer->buffer_store);
1648 i965_release_buffer_store(&obj_buffer->buffer_store);
1649 object_heap_free(heap, obj);
1653 i965_create_buffer_internal(VADriverContextP ctx,
1654 VAContextID context,
1657 unsigned int num_elements,
1662 struct i965_driver_data *i965 = i965_driver_data(ctx);
1663 struct object_buffer *obj_buffer = NULL;
1664 struct buffer_store *buffer_store = NULL;
1669 case VAPictureParameterBufferType:
1670 case VAIQMatrixBufferType:
1671 case VAQMatrixBufferType:
1672 case VABitPlaneBufferType:
1673 case VASliceGroupMapBufferType:
1674 case VASliceParameterBufferType:
1675 case VASliceDataBufferType:
1676 case VAMacroblockParameterBufferType:
1677 case VAResidualDataBufferType:
1678 case VADeblockingParameterBufferType:
1679 case VAImageBufferType:
1680 case VAEncCodedBufferType:
1681 case VAEncSequenceParameterBufferType:
1682 case VAEncPictureParameterBufferType:
1683 case VAEncSliceParameterBufferType:
1684 case VAEncPackedHeaderParameterBufferType:
1685 case VAEncPackedHeaderDataBufferType:
1686 case VAEncMiscParameterBufferType:
1687 case VAProcPipelineParameterBufferType:
1688 case VAProcFilterParameterBufferType:
1689 case VAHuffmanTableBufferType:
1690 case VAProbabilityBufferType:
1695 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1698 bufferID = NEW_BUFFER_ID();
1699 obj_buffer = BUFFER(bufferID);
1701 if (NULL == obj_buffer) {
1702 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1705 if (type == VAEncCodedBufferType) {
1706 size += I965_CODEDBUFFER_HEADER_SIZE;
1707 size += 0x1000; /* for upper bound check */
1710 obj_buffer->max_num_elements = num_elements;
1711 obj_buffer->num_elements = num_elements;
1712 obj_buffer->size_element = size;
1713 obj_buffer->type = type;
1714 obj_buffer->buffer_store = NULL;
1715 buffer_store = calloc(1, sizeof(struct buffer_store));
1716 assert(buffer_store);
1717 buffer_store->ref_count = 1;
1719 if (store_bo != NULL) {
1720 buffer_store->bo = store_bo;
1721 dri_bo_reference(buffer_store->bo);
1724 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
1725 } else if (type == VASliceDataBufferType ||
1726 type == VAImageBufferType ||
1727 type == VAEncCodedBufferType ||
1728 type == VAProbabilityBufferType) {
1729 buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
1731 size * num_elements, 64);
1732 assert(buffer_store->bo);
1734 if (type == VAEncCodedBufferType) {
1735 struct i965_coded_buffer_segment *coded_buffer_segment;
1737 dri_bo_map(buffer_store->bo, 1);
1738 coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual;
1739 coded_buffer_segment->base.size = size - I965_CODEDBUFFER_HEADER_SIZE;
1740 coded_buffer_segment->base.bit_offset = 0;
1741 coded_buffer_segment->base.status = 0;
1742 coded_buffer_segment->base.buf = NULL;
1743 coded_buffer_segment->base.next = NULL;
1744 coded_buffer_segment->mapped = 0;
1745 coded_buffer_segment->codec = 0;
1746 dri_bo_unmap(buffer_store->bo);
1748 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
1754 if (type == VAEncPackedHeaderDataBufferType) {
1755 msize = ALIGN(size, 4);
1758 buffer_store->buffer = malloc(msize * num_elements);
1759 assert(buffer_store->buffer);
1762 memcpy(buffer_store->buffer, data, size * num_elements);
1765 buffer_store->num_elements = obj_buffer->num_elements;
1766 i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
1767 i965_release_buffer_store(&buffer_store);
1770 return VA_STATUS_SUCCESS;
1774 i965_CreateBuffer(VADriverContextP ctx,
1775 VAContextID context, /* in */
1776 VABufferType type, /* in */
1777 unsigned int size, /* in */
1778 unsigned int num_elements, /* in */
1779 void *data, /* in */
1780 VABufferID *buf_id) /* out */
1782 return i965_create_buffer_internal(ctx, context, type, size, num_elements, data, NULL, buf_id);
1787 i965_BufferSetNumElements(VADriverContextP ctx,
1788 VABufferID buf_id, /* in */
1789 unsigned int num_elements) /* in */
1791 struct i965_driver_data *i965 = i965_driver_data(ctx);
1792 struct object_buffer *obj_buffer = BUFFER(buf_id);
1793 VAStatus vaStatus = VA_STATUS_SUCCESS;
1798 return VA_STATUS_ERROR_INVALID_BUFFER;
1800 if ((num_elements < 0) ||
1801 (num_elements > obj_buffer->max_num_elements)) {
1802 vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1804 obj_buffer->num_elements = num_elements;
1805 if (obj_buffer->buffer_store != NULL) {
1806 obj_buffer->buffer_store->num_elements = num_elements;
1814 i965_MapBuffer(VADriverContextP ctx,
1815 VABufferID buf_id, /* in */
1816 void **pbuf) /* out */
1818 struct i965_driver_data *i965 = i965_driver_data(ctx);
1819 struct object_buffer *obj_buffer = BUFFER(buf_id);
1820 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1822 assert(obj_buffer && obj_buffer->buffer_store);
1823 assert(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer);
1824 assert(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer));
1826 if (!obj_buffer || !obj_buffer->buffer_store)
1827 return VA_STATUS_ERROR_INVALID_BUFFER;
1829 if (NULL != obj_buffer->buffer_store->bo) {
1830 unsigned int tiling, swizzle;
1832 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
1834 if (tiling != I915_TILING_NONE)
1835 drm_intel_gem_bo_map_gtt(obj_buffer->buffer_store->bo);
1837 dri_bo_map(obj_buffer->buffer_store->bo, 1);
1839 assert(obj_buffer->buffer_store->bo->virtual);
1840 *pbuf = obj_buffer->buffer_store->bo->virtual;
1842 if (obj_buffer->type == VAEncCodedBufferType) {
1844 unsigned char *buffer = NULL;
1845 struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual);
1847 if (!coded_buffer_segment->mapped) {
1848 unsigned char delimiter0, delimiter1, delimiter2, delimiter3, delimiter4;
1850 coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
1852 if (coded_buffer_segment->codec == CODEC_H264) {
1853 delimiter0 = H264_DELIMITER0;
1854 delimiter1 = H264_DELIMITER1;
1855 delimiter2 = H264_DELIMITER2;
1856 delimiter3 = H264_DELIMITER3;
1857 delimiter4 = H264_DELIMITER4;
1858 } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
1859 delimiter0 = MPEG2_DELIMITER0;
1860 delimiter1 = MPEG2_DELIMITER1;
1861 delimiter2 = MPEG2_DELIMITER2;
1862 delimiter3 = MPEG2_DELIMITER3;
1863 delimiter4 = MPEG2_DELIMITER4;
1868 for (i = 0; i < obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000; i++) {
1869 if ((buffer[i] == delimiter0) &&
1870 (buffer[i + 1] == delimiter1) &&
1871 (buffer[i + 2] == delimiter2) &&
1872 (buffer[i + 3] == delimiter3) &&
1873 (buffer[i + 4] == delimiter4))
1877 if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000) {
1878 coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
1881 coded_buffer_segment->base.size = i;
1882 coded_buffer_segment->mapped = 1;
1884 assert(coded_buffer_segment->base.buf);
1888 vaStatus = VA_STATUS_SUCCESS;
1889 } else if (NULL != obj_buffer->buffer_store->buffer) {
1890 *pbuf = obj_buffer->buffer_store->buffer;
1891 vaStatus = VA_STATUS_SUCCESS;
1898 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
1900 struct i965_driver_data *i965 = i965_driver_data(ctx);
1901 struct object_buffer *obj_buffer = BUFFER(buf_id);
1902 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1904 if ((buf_id & OBJECT_HEAP_OFFSET_MASK) != BUFFER_ID_OFFSET)
1905 return VA_STATUS_ERROR_INVALID_BUFFER;
1907 assert(obj_buffer && obj_buffer->buffer_store);
1908 assert(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer);
1909 assert(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer));
1911 if (!obj_buffer || !obj_buffer->buffer_store)
1912 return VA_STATUS_ERROR_INVALID_BUFFER;
1914 if (NULL != obj_buffer->buffer_store->bo) {
1915 unsigned int tiling, swizzle;
1917 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
1919 if (tiling != I915_TILING_NONE)
1920 drm_intel_gem_bo_unmap_gtt(obj_buffer->buffer_store->bo);
1922 dri_bo_unmap(obj_buffer->buffer_store->bo);
1924 vaStatus = VA_STATUS_SUCCESS;
1925 } else if (NULL != obj_buffer->buffer_store->buffer) {
1927 vaStatus = VA_STATUS_SUCCESS;
1934 i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
1936 struct i965_driver_data *i965 = i965_driver_data(ctx);
1937 struct object_buffer *obj_buffer = BUFFER(buffer_id);
1942 return VA_STATUS_ERROR_INVALID_BUFFER;
1944 i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
1946 return VA_STATUS_SUCCESS;
1950 i965_BeginPicture(VADriverContextP ctx,
1951 VAContextID context,
1952 VASurfaceID render_target)
1954 struct i965_driver_data *i965 = i965_driver_data(ctx);
1955 struct object_context *obj_context = CONTEXT(context);
1956 struct object_surface *obj_surface = SURFACE(render_target);
1957 struct object_config *obj_config;
1961 assert(obj_context);
1964 return VA_STATUS_ERROR_INVALID_CONTEXT;
1966 assert(obj_surface);
1969 return VA_STATUS_ERROR_INVALID_SURFACE;
1971 obj_config = obj_context->obj_config;
1974 switch (obj_config->profile) {
1975 case VAProfileMPEG2Simple:
1976 case VAProfileMPEG2Main:
1977 vaStatus = VA_STATUS_SUCCESS;
1980 case VAProfileH264ConstrainedBaseline:
1981 case VAProfileH264Main:
1982 case VAProfileH264High:
1983 vaStatus = VA_STATUS_SUCCESS;
1986 case VAProfileVC1Simple:
1987 case VAProfileVC1Main:
1988 case VAProfileVC1Advanced:
1989 vaStatus = VA_STATUS_SUCCESS;
1992 case VAProfileJPEGBaseline:
1993 vaStatus = VA_STATUS_SUCCESS;
1997 vaStatus = VA_STATUS_SUCCESS;
2000 case VAProfileVP8Version0_3:
2001 vaStatus = VA_STATUS_SUCCESS;
2006 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
2010 if (obj_context->codec_type == CODEC_PROC) {
2011 obj_context->codec_state.proc.current_render_target = render_target;
2012 } else if (obj_context->codec_type == CODEC_ENC) {
2013 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
2015 for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++) {
2016 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
2019 obj_context->codec_state.encode.num_slice_params = 0;
2022 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
2024 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
2025 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
2027 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
2028 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
2030 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
2031 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
2033 obj_context->codec_state.encode.num_slice_params_ext = 0;
2034 obj_context->codec_state.encode.current_render_target = render_target; /*This is input new frame*/
2035 obj_context->codec_state.encode.last_packed_header_type = 0;
2037 obj_context->codec_state.decode.current_render_target = render_target;
2038 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
2039 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
2040 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
2041 i965_release_buffer_store(&obj_context->codec_state.decode.huffman_table);
2043 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++) {
2044 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
2045 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
2048 obj_context->codec_state.decode.num_slice_params = 0;
2049 obj_context->codec_state.decode.num_slice_datas = 0;
2055 #define I965_RENDER_BUFFER(category, name) i965_render_##category##_##name##_buffer(ctx, obj_context, obj_buffer)
2057 #define DEF_RENDER_SINGLE_BUFFER_FUNC(category, name, member) \
2059 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
2060 struct object_context *obj_context, \
2061 struct object_buffer *obj_buffer) \
2063 struct category##_state *category = &obj_context->codec_state.category; \
2064 i965_release_buffer_store(&category->member); \
2065 i965_reference_buffer_store(&category->member, obj_buffer->buffer_store); \
2066 return VA_STATUS_SUCCESS; \
2069 #define DEF_RENDER_MULTI_BUFFER_FUNC(category, name, member) \
2071 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
2072 struct object_context *obj_context, \
2073 struct object_buffer *obj_buffer) \
2075 struct category##_state *category = &obj_context->codec_state.category; \
2076 if (category->num_##member == category->max_##member) { \
2077 category->member = realloc(category->member, (category->max_##member + NUM_SLICES) * sizeof(*category->member)); \
2078 memset(category->member + category->max_##member, 0, NUM_SLICES * sizeof(*category->member)); \
2079 category->max_##member += NUM_SLICES; \
2081 i965_release_buffer_store(&category->member[category->num_##member]); \
2082 i965_reference_buffer_store(&category->member[category->num_##member], obj_buffer->buffer_store); \
2083 category->num_##member++; \
2084 return VA_STATUS_SUCCESS; \
2087 #define I965_RENDER_DECODE_BUFFER(name) I965_RENDER_BUFFER(decode, name)
2089 #define DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(decode, name, member)
2090 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2091 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(iq_matrix, iq_matrix)
2092 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(bit_plane, bit_plane)
2093 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
2094 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(probability_data, probability_data)
2096 #define DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(decode, name, member)
2097 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2098 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_data, slice_datas)
2101 i965_decoder_render_picture(VADriverContextP ctx,
2102 VAContextID context,
2103 VABufferID *buffers,
2106 struct i965_driver_data *i965 = i965_driver_data(ctx);
2107 struct object_context *obj_context = CONTEXT(context);
2108 VAStatus vaStatus = VA_STATUS_SUCCESS;
2111 assert(obj_context);
2114 return VA_STATUS_ERROR_INVALID_CONTEXT;
2116 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2117 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2120 return VA_STATUS_ERROR_INVALID_BUFFER;
2122 switch (obj_buffer->type) {
2123 case VAPictureParameterBufferType:
2124 vaStatus = I965_RENDER_DECODE_BUFFER(picture_parameter);
2127 case VAIQMatrixBufferType:
2128 vaStatus = I965_RENDER_DECODE_BUFFER(iq_matrix);
2131 case VABitPlaneBufferType:
2132 vaStatus = I965_RENDER_DECODE_BUFFER(bit_plane);
2135 case VASliceParameterBufferType:
2136 vaStatus = I965_RENDER_DECODE_BUFFER(slice_parameter);
2139 case VASliceDataBufferType:
2140 vaStatus = I965_RENDER_DECODE_BUFFER(slice_data);
2143 case VAHuffmanTableBufferType:
2144 vaStatus = I965_RENDER_DECODE_BUFFER(huffman_table);
2147 case VAProbabilityBufferType:
2148 vaStatus = I965_RENDER_DECODE_BUFFER(probability_data);
2152 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2160 #define I965_RENDER_ENCODE_BUFFER(name) I965_RENDER_BUFFER(encode, name)
2162 #define DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(encode, name, member)
2163 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter, seq_param)
2164 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2165 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_control, pic_control)
2166 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(qmatrix, q_matrix)
2167 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(iqmatrix, iq_matrix)
2168 /* extended buffer */
2169 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
2170 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
2172 #define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
2173 // DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2174 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter_ext, slice_params_ext)
2177 i965_encoder_render_packed_header_parameter_buffer(VADriverContextP ctx,
2178 struct object_context *obj_context,
2179 struct object_buffer *obj_buffer,
2182 struct encode_state *encode = &obj_context->codec_state.encode;
2184 assert(obj_buffer->buffer_store->bo == NULL);
2185 assert(obj_buffer->buffer_store->buffer);
2186 i965_release_buffer_store(&encode->packed_header_param[type_index]);
2187 i965_reference_buffer_store(&encode->packed_header_param[type_index], obj_buffer->buffer_store);
2189 return VA_STATUS_SUCCESS;
2193 i965_encoder_render_packed_header_data_buffer(VADriverContextP ctx,
2194 struct object_context *obj_context,
2195 struct object_buffer *obj_buffer,
2198 struct encode_state *encode = &obj_context->codec_state.encode;
2200 assert(obj_buffer->buffer_store->bo == NULL);
2201 assert(obj_buffer->buffer_store->buffer);
2202 i965_release_buffer_store(&encode->packed_header_data[type_index]);
2203 i965_reference_buffer_store(&encode->packed_header_data[type_index], obj_buffer->buffer_store);
2205 return VA_STATUS_SUCCESS;
2209 i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
2210 struct object_context *obj_context,
2211 struct object_buffer *obj_buffer)
2213 struct encode_state *encode = &obj_context->codec_state.encode;
2214 VAEncMiscParameterBuffer *param = NULL;
2216 assert(obj_buffer->buffer_store->bo == NULL);
2217 assert(obj_buffer->buffer_store->buffer);
2219 param = (VAEncMiscParameterBuffer *)obj_buffer->buffer_store->buffer;
2221 if (param->type > ARRAY_ELEMS(encode->misc_param))
2222 return VA_STATUS_ERROR_INVALID_PARAMETER;
2224 i965_release_buffer_store(&encode->misc_param[param->type]);
2225 i965_reference_buffer_store(&encode->misc_param[param->type], obj_buffer->buffer_store);
2227 return VA_STATUS_SUCCESS;
2231 i965_encoder_render_picture(VADriverContextP ctx,
2232 VAContextID context,
2233 VABufferID *buffers,
2236 struct i965_driver_data *i965 = i965_driver_data(ctx);
2237 struct object_context *obj_context = CONTEXT(context);
2238 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2241 assert(obj_context);
2244 return VA_STATUS_ERROR_INVALID_CONTEXT;
2246 for (i = 0; i < num_buffers; i++) {
2247 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2250 return VA_STATUS_ERROR_INVALID_BUFFER;
2252 switch (obj_buffer->type) {
2253 case VAQMatrixBufferType:
2254 vaStatus = I965_RENDER_ENCODE_BUFFER(qmatrix);
2257 case VAIQMatrixBufferType:
2258 vaStatus = I965_RENDER_ENCODE_BUFFER(iqmatrix);
2261 case VAEncSequenceParameterBufferType:
2262 vaStatus = I965_RENDER_ENCODE_BUFFER(sequence_parameter_ext);
2265 case VAEncPictureParameterBufferType:
2266 vaStatus = I965_RENDER_ENCODE_BUFFER(picture_parameter_ext);
2269 case VAEncSliceParameterBufferType:
2270 vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
2273 case VAEncPackedHeaderParameterBufferType:
2275 struct encode_state *encode = &obj_context->codec_state.encode;
2276 VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer;
2277 encode->last_packed_header_type = param->type;
2279 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
2282 va_enc_packed_type_to_idx(encode->last_packed_header_type));
2286 case VAEncPackedHeaderDataBufferType:
2288 struct encode_state *encode = &obj_context->codec_state.encode;
2290 assert(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
2291 encode->last_packed_header_type == VAEncPackedHeaderPicture ||
2292 encode->last_packed_header_type == VAEncPackedHeaderSlice ||
2293 (((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) &&
2294 ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)));
2295 vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
2298 va_enc_packed_type_to_idx(encode->last_packed_header_type));
2302 case VAEncMiscParameterBufferType:
2303 vaStatus = i965_encoder_render_misc_parameter_buffer(ctx,
2309 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2317 #define I965_RENDER_PROC_BUFFER(name) I965_RENDER_BUFFER(proc, name)
2319 #define DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(proc, name, member)
2320 DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(pipeline_parameter, pipeline_param)
2323 i965_proc_render_picture(VADriverContextP ctx,
2324 VAContextID context,
2325 VABufferID *buffers,
2328 struct i965_driver_data *i965 = i965_driver_data(ctx);
2329 struct object_context *obj_context = CONTEXT(context);
2330 VAStatus vaStatus = VA_STATUS_SUCCESS;
2333 assert(obj_context);
2336 return VA_STATUS_ERROR_INVALID_CONTEXT;
2338 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2339 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2342 return VA_STATUS_ERROR_INVALID_BUFFER;
2344 switch (obj_buffer->type) {
2345 case VAProcPipelineParameterBufferType:
2346 vaStatus = I965_RENDER_PROC_BUFFER(pipeline_parameter);
2350 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2359 i965_RenderPicture(VADriverContextP ctx,
2360 VAContextID context,
2361 VABufferID *buffers,
2364 struct i965_driver_data *i965 = i965_driver_data(ctx);
2365 struct object_context *obj_context;
2366 struct object_config *obj_config;
2367 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2369 obj_context = CONTEXT(context);
2370 assert(obj_context);
2373 return VA_STATUS_ERROR_INVALID_CONTEXT;
2375 if (num_buffers <= 0)
2376 return VA_STATUS_ERROR_INVALID_PARAMETER;
2378 obj_config = obj_context->obj_config;
2381 if (VAEntrypointVideoProc == obj_config->entrypoint) {
2382 vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
2383 } else if (VAEntrypointEncSlice == obj_config->entrypoint ) {
2384 vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
2386 vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
2393 i965_EndPicture(VADriverContextP ctx, VAContextID context)
2395 struct i965_driver_data *i965 = i965_driver_data(ctx);
2396 struct object_context *obj_context = CONTEXT(context);
2397 struct object_config *obj_config;
2399 assert(obj_context);
2402 return VA_STATUS_ERROR_INVALID_CONTEXT;
2404 obj_config = obj_context->obj_config;
2407 if (obj_context->codec_type == CODEC_PROC) {
2408 assert(VAEntrypointVideoProc == obj_config->entrypoint);
2409 } else if (obj_context->codec_type == CODEC_ENC) {
2410 assert(VAEntrypointEncSlice == obj_config->entrypoint);
2412 if (!(obj_context->codec_state.encode.pic_param ||
2413 obj_context->codec_state.encode.pic_param_ext)) {
2414 return VA_STATUS_ERROR_INVALID_PARAMETER;
2416 if (!(obj_context->codec_state.encode.seq_param ||
2417 obj_context->codec_state.encode.seq_param_ext)) {
2418 return VA_STATUS_ERROR_INVALID_PARAMETER;
2420 if ((obj_context->codec_state.encode.num_slice_params <=0) &&
2421 (obj_context->codec_state.encode.num_slice_params_ext <=0)) {
2422 return VA_STATUS_ERROR_INVALID_PARAMETER;
2425 if (obj_context->codec_state.decode.pic_param == NULL) {
2426 return VA_STATUS_ERROR_INVALID_PARAMETER;
2428 if (obj_context->codec_state.decode.num_slice_params <=0) {
2429 return VA_STATUS_ERROR_INVALID_PARAMETER;
2431 if (obj_context->codec_state.decode.num_slice_datas <=0) {
2432 return VA_STATUS_ERROR_INVALID_PARAMETER;
2435 if (obj_context->codec_state.decode.num_slice_params !=
2436 obj_context->codec_state.decode.num_slice_datas) {
2437 return VA_STATUS_ERROR_INVALID_PARAMETER;
2441 assert(obj_context->hw_context->run);
2442 return obj_context->hw_context->run(ctx, obj_config->profile, &obj_context->codec_state, obj_context->hw_context);
2446 i965_SyncSurface(VADriverContextP ctx,
2447 VASurfaceID render_target)
2449 struct i965_driver_data *i965 = i965_driver_data(ctx);
2450 struct object_surface *obj_surface = SURFACE(render_target);
2452 assert(obj_surface);
2455 drm_intel_bo_wait_rendering(obj_surface->bo);
2457 return VA_STATUS_SUCCESS;
2461 i965_QuerySurfaceStatus(VADriverContextP ctx,
2462 VASurfaceID render_target,
2463 VASurfaceStatus *status) /* out */
2465 struct i965_driver_data *i965 = i965_driver_data(ctx);
2466 struct object_surface *obj_surface = SURFACE(render_target);
2468 assert(obj_surface);
2470 if (obj_surface->bo) {
2471 if (drm_intel_bo_busy(obj_surface->bo)){
2472 *status = VASurfaceRendering;
2475 *status = VASurfaceReady;
2478 *status = VASurfaceReady;
2481 return VA_STATUS_SUCCESS;
2484 static VADisplayAttribute *
2485 get_display_attribute(VADriverContextP ctx, VADisplayAttribType type)
2487 struct i965_driver_data * const i965 = i965_driver_data(ctx);
2490 if (!i965->display_attributes)
2493 for (i = 0; i < i965->num_display_attributes; i++) {
2494 if (i965->display_attributes[i].type == type)
2495 return &i965->display_attributes[i];
2501 i965_display_attributes_terminate(VADriverContextP ctx)
2503 struct i965_driver_data * const i965 = i965_driver_data(ctx);
2505 if (i965->display_attributes) {
2506 free(i965->display_attributes);
2507 i965->display_attributes = NULL;
2508 i965->num_display_attributes = 0;
2513 i965_display_attributes_init(VADriverContextP ctx)
2515 struct i965_driver_data * const i965 = i965_driver_data(ctx);
2517 i965->num_display_attributes = ARRAY_ELEMS(i965_display_attributes);
2518 i965->display_attributes = malloc(
2519 i965->num_display_attributes * sizeof(i965->display_attributes[0]));
2520 if (!i965->display_attributes)
2524 i965->display_attributes,
2525 i965_display_attributes,
2526 sizeof(i965_display_attributes)
2529 i965->rotation_attrib = get_display_attribute(ctx, VADisplayAttribRotation);
2530 i965->brightness_attrib = get_display_attribute(ctx, VADisplayAttribBrightness);
2531 i965->contrast_attrib = get_display_attribute(ctx, VADisplayAttribContrast);
2532 i965->hue_attrib = get_display_attribute(ctx, VADisplayAttribHue);
2533 i965->saturation_attrib = get_display_attribute(ctx, VADisplayAttribSaturation);
2535 if (!i965->rotation_attrib ||
2536 !i965->brightness_attrib ||
2537 !i965->contrast_attrib ||
2538 !i965->hue_attrib ||
2539 !i965->saturation_attrib) {
2545 i965_display_attributes_terminate(ctx);
2550 * Query display attributes
2551 * The caller must provide a "attr_list" array that can hold at
2552 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
2553 * returned in "attr_list" is returned in "num_attributes".
2556 i965_QueryDisplayAttributes(
2557 VADriverContextP ctx,
2558 VADisplayAttribute *attribs, /* out */
2559 int *num_attribs_ptr /* out */
2562 const int num_attribs = ARRAY_ELEMS(i965_display_attributes);
2564 if (attribs && num_attribs > 0)
2565 memcpy(attribs, i965_display_attributes, sizeof(i965_display_attributes));
2567 if (num_attribs_ptr)
2568 *num_attribs_ptr = num_attribs;
2570 return VA_STATUS_SUCCESS;
2574 * Get display attributes
2575 * This function returns the current attribute values in "attr_list".
2576 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
2577 * from vaQueryDisplayAttributes() can have their values retrieved.
2580 i965_GetDisplayAttributes(
2581 VADriverContextP ctx,
2582 VADisplayAttribute *attribs, /* inout */
2583 int num_attribs /* in */
2588 for (i = 0; i < num_attribs; i++) {
2589 VADisplayAttribute *src_attrib, * const dst_attrib = &attribs[i];
2591 src_attrib = get_display_attribute(ctx, dst_attrib->type);
2592 if (src_attrib && (src_attrib->flags & VA_DISPLAY_ATTRIB_GETTABLE)) {
2593 dst_attrib->min_value = src_attrib->min_value;
2594 dst_attrib->max_value = src_attrib->max_value;
2595 dst_attrib->value = src_attrib->value;
2598 dst_attrib->flags = VA_DISPLAY_ATTRIB_NOT_SUPPORTED;
2600 return VA_STATUS_SUCCESS;
2604 * Set display attributes
2605 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
2606 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
2607 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
2610 i965_SetDisplayAttributes(
2611 VADriverContextP ctx,
2612 VADisplayAttribute *attribs, /* in */
2613 int num_attribs /* in */
2618 for (i = 0; i < num_attribs; i++) {
2619 VADisplayAttribute *dst_attrib, * const src_attrib = &attribs[i];
2621 dst_attrib = get_display_attribute(ctx, src_attrib->type);
2623 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
2625 if (!(dst_attrib->flags & VA_DISPLAY_ATTRIB_SETTABLE))
2628 if (src_attrib->value < dst_attrib->min_value ||
2629 src_attrib->value > dst_attrib->max_value)
2630 return VA_STATUS_ERROR_INVALID_PARAMETER;
2632 dst_attrib->value = src_attrib->value;
2633 /* XXX: track modified attributes through timestamps */
2635 return VA_STATUS_SUCCESS;
2639 i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
2640 VASurfaceID surface,
2641 void **buffer, /* out */
2642 unsigned int *stride) /* out */
2645 return VA_STATUS_ERROR_UNIMPLEMENTED;
2649 i965_destroy_heap(struct object_heap *heap,
2650 void (*func)(struct object_heap *heap, struct object_base *object))
2652 struct object_base *object;
2653 object_heap_iterator iter;
2655 object = object_heap_first(heap, &iter);
2661 object = object_heap_next(heap, &iter);
2664 object_heap_destroy(heap);
2669 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
2672 i965_CreateImage(VADriverContextP ctx,
2673 VAImageFormat *format,
2676 VAImage *out_image) /* out */
2678 struct i965_driver_data *i965 = i965_driver_data(ctx);
2679 struct object_image *obj_image;
2680 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
2682 unsigned int size2, size, awidth, aheight;
2684 out_image->image_id = VA_INVALID_ID;
2685 out_image->buf = VA_INVALID_ID;
2687 image_id = NEW_IMAGE_ID();
2688 if (image_id == VA_INVALID_ID)
2689 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2691 obj_image = IMAGE(image_id);
2693 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2694 obj_image->bo = NULL;
2695 obj_image->palette = NULL;
2696 obj_image->derived_surface = VA_INVALID_ID;
2698 VAImage * const image = &obj_image->image;
2699 image->image_id = image_id;
2700 image->buf = VA_INVALID_ID;
2702 awidth = ALIGN(width, 64);
2704 if ((format->fourcc == VA_FOURCC('Y','V','1','2')) ||
2705 (format->fourcc == VA_FOURCC('I','4','2','0'))) {
2706 if (awidth % 128 != 0) {
2707 awidth = ALIGN(width, 128);
2711 aheight = ALIGN(height, 16);
2712 size = awidth * aheight;
2713 size2 = (awidth / 2) * (aheight / 2);
2715 image->num_palette_entries = 0;
2716 image->entry_bytes = 0;
2717 memset(image->component_order, 0, sizeof(image->component_order));
2719 switch (format->fourcc) {
2720 case VA_FOURCC('I','A','4','4'):
2721 case VA_FOURCC('A','I','4','4'):
2722 image->num_planes = 1;
2723 image->pitches[0] = awidth;
2724 image->offsets[0] = 0;
2725 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
2726 image->num_palette_entries = 16;
2727 image->entry_bytes = 3;
2728 image->component_order[0] = 'R';
2729 image->component_order[1] = 'G';
2730 image->component_order[2] = 'B';
2732 case VA_FOURCC('I','A','8','8'):
2733 case VA_FOURCC('A','I','8','8'):
2734 image->num_planes = 1;
2735 image->pitches[0] = awidth * 2;
2736 image->offsets[0] = 0;
2737 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
2738 image->num_palette_entries = 256;
2739 image->entry_bytes = 3;
2740 image->component_order[0] = 'R';
2741 image->component_order[1] = 'G';
2742 image->component_order[2] = 'B';
2744 case VA_FOURCC('A','R','G','B'):
2745 case VA_FOURCC('A','B','G','R'):
2746 case VA_FOURCC('B','G','R','A'):
2747 case VA_FOURCC('R','G','B','A'):
2748 case VA_FOURCC('B','G','R','X'):
2749 case VA_FOURCC('R','G','B','X'):
2750 image->num_planes = 1;
2751 image->pitches[0] = awidth * 4;
2752 image->offsets[0] = 0;
2753 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
2755 case VA_FOURCC('Y','V','1','2'):
2756 image->num_planes = 3;
2757 image->pitches[0] = awidth;
2758 image->offsets[0] = 0;
2759 image->pitches[1] = awidth / 2;
2760 image->offsets[1] = size;
2761 image->pitches[2] = awidth / 2;
2762 image->offsets[2] = size + size2;
2763 image->data_size = size + 2 * size2;
2765 case VA_FOURCC('I','4','2','0'):
2766 image->num_planes = 3;
2767 image->pitches[0] = awidth;
2768 image->offsets[0] = 0;
2769 image->pitches[1] = awidth / 2;
2770 image->offsets[1] = size;
2771 image->pitches[2] = awidth / 2;
2772 image->offsets[2] = size + size2;
2773 image->data_size = size + 2 * size2;
2775 case VA_FOURCC('N','V','1','2'):
2776 image->num_planes = 2;
2777 image->pitches[0] = awidth;
2778 image->offsets[0] = 0;
2779 image->pitches[1] = awidth;
2780 image->offsets[1] = size;
2781 image->data_size = size + 2 * size2;
2783 case VA_FOURCC('Y','U','Y','2'):
2784 case VA_FOURCC('U','Y','V','Y'):
2785 image->num_planes = 1;
2786 image->pitches[0] = awidth * 2;
2787 image->offsets[0] = 0;
2788 image->data_size = size * 2;
2794 va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
2795 image->data_size, 1, NULL, &image->buf);
2796 if (va_status != VA_STATUS_SUCCESS)
2799 struct object_buffer *obj_buffer = BUFFER(image->buf);
2802 !obj_buffer->buffer_store ||
2803 !obj_buffer->buffer_store->bo)
2804 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2806 obj_image->bo = obj_buffer->buffer_store->bo;
2807 dri_bo_reference(obj_image->bo);
2809 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
2810 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
2811 if (!obj_image->palette)
2815 image->image_id = image_id;
2816 image->format = *format;
2817 image->width = width;
2818 image->height = height;
2820 *out_image = *image;
2821 return VA_STATUS_SUCCESS;
2824 i965_DestroyImage(ctx, image_id);
2829 i965_check_alloc_surface_bo(VADriverContextP ctx,
2830 struct object_surface *obj_surface,
2832 unsigned int fourcc,
2833 unsigned int subsampling)
2835 struct i965_driver_data *i965 = i965_driver_data(ctx);
2836 int region_width, region_height;
2838 if (obj_surface->bo) {
2839 assert(obj_surface->fourcc);
2840 assert(obj_surface->fourcc == fourcc);
2841 assert(obj_surface->subsampling == subsampling);
2845 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
2846 obj_surface->x_cr_offset = 0;
2849 assert(fourcc != VA_FOURCC('I', '4', '2', '0') &&
2850 fourcc != VA_FOURCC('I', 'Y', 'U', 'V') &&
2851 fourcc != VA_FOURCC('Y', 'V', '1', '2'));
2853 obj_surface->width = ALIGN(obj_surface->orig_width, 128);
2854 obj_surface->height = ALIGN(obj_surface->orig_height, 32);
2855 region_height = obj_surface->height;
2858 case VA_FOURCC('N', 'V', '1', '2'):
2859 assert(subsampling == SUBSAMPLE_YUV420);
2860 obj_surface->cb_cr_pitch = obj_surface->width;
2861 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2862 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2863 obj_surface->y_cb_offset = obj_surface->height;
2864 obj_surface->y_cr_offset = obj_surface->height;
2865 region_width = obj_surface->width;
2866 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
2870 case VA_FOURCC('I', 'M', 'C', '1'):
2871 assert(subsampling == SUBSAMPLE_YUV420);
2872 obj_surface->cb_cr_pitch = obj_surface->width;
2873 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2874 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2875 obj_surface->y_cr_offset = obj_surface->height;
2876 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32);
2877 region_width = obj_surface->width;
2878 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2882 case VA_FOURCC('I', 'M', 'C', '3'):
2883 assert(subsampling == SUBSAMPLE_YUV420);
2884 obj_surface->cb_cr_pitch = obj_surface->width;
2885 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2886 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2887 obj_surface->y_cb_offset = obj_surface->height;
2888 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2889 region_width = obj_surface->width;
2890 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2894 case VA_FOURCC('4', '2', '2', 'H'):
2895 assert(subsampling == SUBSAMPLE_YUV422H);
2896 obj_surface->cb_cr_pitch = obj_surface->width;
2897 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2898 obj_surface->cb_cr_height = obj_surface->orig_height;
2899 obj_surface->y_cb_offset = obj_surface->height;
2900 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2901 region_width = obj_surface->width;
2902 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2906 case VA_FOURCC('4', '2', '2', 'V'):
2907 assert(subsampling == SUBSAMPLE_YUV422V);
2908 obj_surface->cb_cr_pitch = obj_surface->width;
2909 obj_surface->cb_cr_width = obj_surface->orig_width;
2910 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2911 obj_surface->y_cb_offset = obj_surface->height;
2912 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2913 region_width = obj_surface->width;
2914 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2918 case VA_FOURCC('4', '1', '1', 'P'):
2919 assert(subsampling == SUBSAMPLE_YUV411);
2920 obj_surface->cb_cr_pitch = obj_surface->width;
2921 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
2922 obj_surface->cb_cr_height = obj_surface->orig_height;
2923 obj_surface->y_cb_offset = obj_surface->height;
2924 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2925 region_width = obj_surface->width;
2926 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2930 case VA_FOURCC('4', '4', '4', 'P'):
2931 assert(subsampling == SUBSAMPLE_YUV444);
2932 obj_surface->cb_cr_pitch = obj_surface->width;
2933 obj_surface->cb_cr_width = obj_surface->orig_width;
2934 obj_surface->cb_cr_height = obj_surface->orig_height;
2935 obj_surface->y_cb_offset = obj_surface->height;
2936 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2937 region_width = obj_surface->width;
2938 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2942 case VA_FOURCC('Y', '8', '0', '0'):
2943 assert(subsampling == SUBSAMPLE_YUV400);
2944 obj_surface->cb_cr_pitch = obj_surface->width;
2945 obj_surface->cb_cr_width = 0;
2946 obj_surface->cb_cr_height = 0;
2947 obj_surface->y_cb_offset = obj_surface->height;
2948 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2949 region_width = obj_surface->width;
2950 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2954 case VA_FOURCC('Y', 'U', 'Y', '2'):
2955 case VA_FOURCC('U', 'Y', 'V', 'Y'):
2956 assert(subsampling == SUBSAMPLE_YUV422H);
2957 obj_surface->width = ALIGN(obj_surface->orig_width * 2, 128);
2958 obj_surface->cb_cr_pitch = obj_surface->width;
2959 obj_surface->y_cb_offset = 0;
2960 obj_surface->y_cr_offset = 0;
2961 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2962 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2963 region_width = obj_surface->width;
2964 region_height = obj_surface->height;
2968 case VA_FOURCC('R', 'G', 'B', 'A'):
2969 case VA_FOURCC('R', 'G', 'B', 'X'):
2970 case VA_FOURCC('B', 'G', 'R', 'A'):
2971 case VA_FOURCC('B', 'G', 'R', 'X'):
2972 assert(subsampling == SUBSAMPLE_RGBX);
2974 obj_surface->width = ALIGN(obj_surface->orig_width * 4, 128);
2975 region_width = obj_surface->width;
2976 region_height = obj_surface->height;
2980 /* Never get here */
2985 assert(subsampling == SUBSAMPLE_YUV420 ||
2986 subsampling == SUBSAMPLE_YUV422H ||
2987 subsampling == SUBSAMPLE_YUV422V ||
2988 subsampling == SUBSAMPLE_RGBX);
2990 region_width = obj_surface->width;
2991 region_height = obj_surface->height;
2994 case VA_FOURCC('N', 'V', '1', '2'):
2995 obj_surface->y_cb_offset = obj_surface->height;
2996 obj_surface->y_cr_offset = obj_surface->height;
2997 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2998 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2999 obj_surface->cb_cr_pitch = obj_surface->width;
3000 region_height = obj_surface->height + obj_surface->height / 2;
3003 case VA_FOURCC('Y', 'V', '1', '2'):
3004 case VA_FOURCC('I', '4', '2', '0'):
3005 if (fourcc == VA_FOURCC('Y', 'V', '1', '2')) {
3006 obj_surface->y_cr_offset = obj_surface->height;
3007 obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4;
3009 obj_surface->y_cb_offset = obj_surface->height;
3010 obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
3013 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3014 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3015 obj_surface->cb_cr_pitch = obj_surface->width / 2;
3016 region_height = obj_surface->height + obj_surface->height / 2;
3019 case VA_FOURCC('Y', 'U', 'Y', '2'):
3020 case VA_FOURCC('U', 'Y', 'V', 'Y'):
3021 obj_surface->width = ALIGN(obj_surface->orig_width * 2, 16);
3022 obj_surface->y_cb_offset = 0;
3023 obj_surface->y_cr_offset = 0;
3024 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3025 obj_surface->cb_cr_height = obj_surface->orig_height;
3026 obj_surface->cb_cr_pitch = obj_surface->width;
3027 region_width = obj_surface->width;
3028 region_height = obj_surface->height;
3030 case VA_FOURCC('R', 'G', 'B', 'A'):
3031 case VA_FOURCC('R', 'G', 'B', 'X'):
3032 case VA_FOURCC('B', 'G', 'R', 'A'):
3033 case VA_FOURCC('B', 'G', 'R', 'X'):
3034 obj_surface->width = ALIGN(obj_surface->orig_width * 4, 16);
3035 region_width = obj_surface->width;
3036 region_height = obj_surface->height;
3040 /* Never get here */
3046 obj_surface->size = ALIGN(region_width * region_height, 0x1000);
3049 uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
3050 unsigned long pitch;
3052 obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr,
3060 assert(tiling_mode == I915_TILING_Y);
3061 assert(pitch == obj_surface->width);
3063 obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
3069 obj_surface->fourcc = fourcc;
3070 obj_surface->subsampling = subsampling;
3071 assert(obj_surface->bo);
3074 VAStatus i965_DeriveImage(VADriverContextP ctx,
3075 VASurfaceID surface,
3076 VAImage *out_image) /* out */
3078 struct i965_driver_data *i965 = i965_driver_data(ctx);
3079 struct object_image *obj_image;
3080 struct object_surface *obj_surface;
3082 unsigned int w_pitch;
3083 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3085 out_image->image_id = VA_INVALID_ID;
3086 obj_surface = SURFACE(surface);
3089 return VA_STATUS_ERROR_INVALID_SURFACE;
3091 if (!obj_surface->bo) {
3092 unsigned int is_tiled = 0;
3093 unsigned int fourcc = VA_FOURCC('Y', 'V', '1', '2');
3094 i965_guess_surface_format(ctx, surface, &fourcc, &is_tiled);
3095 int sampling = get_sampling_from_fourcc(fourcc);
3096 i965_check_alloc_surface_bo(ctx, obj_surface, is_tiled, fourcc, sampling);
3099 assert(obj_surface->fourcc);
3101 w_pitch = obj_surface->width;
3103 image_id = NEW_IMAGE_ID();
3105 if (image_id == VA_INVALID_ID)
3106 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3108 obj_image = IMAGE(image_id);
3111 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3113 obj_image->bo = NULL;
3114 obj_image->palette = NULL;
3115 obj_image->derived_surface = VA_INVALID_ID;
3117 VAImage * const image = &obj_image->image;
3119 memset(image, 0, sizeof(*image));
3120 image->image_id = image_id;
3121 image->buf = VA_INVALID_ID;
3122 image->num_palette_entries = 0;
3123 image->entry_bytes = 0;
3124 image->width = obj_surface->orig_width;
3125 image->height = obj_surface->orig_height;
3126 image->data_size = obj_surface->size;
3128 image->format.fourcc = obj_surface->fourcc;
3129 image->format.byte_order = VA_LSB_FIRST;
3130 image->format.bits_per_pixel = 12;
3132 switch (image->format.fourcc) {
3133 case VA_FOURCC('Y', 'V', '1', '2'):
3134 image->num_planes = 3;
3135 image->pitches[0] = w_pitch; /* Y */
3136 image->offsets[0] = 0;
3137 image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
3138 image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
3139 image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
3140 image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
3143 case VA_FOURCC('N', 'V', '1', '2'):
3144 image->num_planes = 2;
3145 image->pitches[0] = w_pitch; /* Y */
3146 image->offsets[0] = 0;
3147 image->pitches[1] = obj_surface->cb_cr_pitch; /* UV */
3148 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
3151 case VA_FOURCC('I', '4', '2', '0'):
3152 image->num_planes = 3;
3153 image->pitches[0] = w_pitch; /* Y */
3154 image->offsets[0] = 0;
3155 image->pitches[1] = obj_surface->cb_cr_pitch; /* U */
3156 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
3157 image->pitches[2] = obj_surface->cb_cr_pitch; /* V */
3158 image->offsets[2] = w_pitch * obj_surface->y_cr_offset;
3160 case VA_FOURCC('Y', 'U', 'Y', '2'):
3161 case VA_FOURCC('U', 'Y', 'V', 'Y'):
3162 image->num_planes = 1;
3163 image->pitches[0] = obj_surface->width; /* Y, width is aligned already */
3164 image->offsets[0] = 0;
3166 case VA_FOURCC('R', 'G', 'B', 'A'):
3167 case VA_FOURCC('R', 'G', 'B', 'X'):
3168 case VA_FOURCC('B', 'G', 'R', 'A'):
3169 case VA_FOURCC('B', 'G', 'R', 'X'):
3170 image->num_planes = 1;
3171 image->pitches[0] = obj_surface->width;
3177 va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType,
3178 obj_surface->size, 1, NULL, obj_surface->bo, &image->buf);
3179 if (va_status != VA_STATUS_SUCCESS)
3182 struct object_buffer *obj_buffer = BUFFER(image->buf);
3185 !obj_buffer->buffer_store ||
3186 !obj_buffer->buffer_store->bo)
3187 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3189 obj_image->bo = obj_buffer->buffer_store->bo;
3190 dri_bo_reference(obj_image->bo);
3192 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
3193 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
3194 if (!obj_image->palette) {
3195 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
3200 *out_image = *image;
3201 obj_surface->flags |= SURFACE_DERIVED;
3202 obj_image->derived_surface = surface;
3204 return VA_STATUS_SUCCESS;
3207 i965_DestroyImage(ctx, image_id);
3212 i965_destroy_image(struct object_heap *heap, struct object_base *obj)
3214 object_heap_free(heap, obj);
3219 i965_DestroyImage(VADriverContextP ctx, VAImageID image)
3221 struct i965_driver_data *i965 = i965_driver_data(ctx);
3222 struct object_image *obj_image = IMAGE(image);
3223 struct object_surface *obj_surface;
3226 return VA_STATUS_SUCCESS;
3228 dri_bo_unreference(obj_image->bo);
3229 obj_image->bo = NULL;
3231 if (obj_image->image.buf != VA_INVALID_ID) {
3232 i965_DestroyBuffer(ctx, obj_image->image.buf);
3233 obj_image->image.buf = VA_INVALID_ID;
3236 if (obj_image->palette) {
3237 free(obj_image->palette);
3238 obj_image->palette = NULL;
3241 obj_surface = SURFACE(obj_image->derived_surface);
3244 obj_surface->flags &= ~SURFACE_DERIVED;
3247 i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
3249 return VA_STATUS_SUCCESS;
3253 * pointer to an array holding the palette data. The size of the array is
3254 * num_palette_entries * entry_bytes in size. The order of the components
3255 * in the palette is described by the component_order in VASubpicture struct
3258 i965_SetImagePalette(VADriverContextP ctx,
3260 unsigned char *palette)
3262 struct i965_driver_data *i965 = i965_driver_data(ctx);
3265 struct object_image *obj_image = IMAGE(image);
3267 return VA_STATUS_ERROR_INVALID_IMAGE;
3269 if (!obj_image->palette)
3270 return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
3272 for (i = 0; i < obj_image->image.num_palette_entries; i++)
3273 obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
3274 ((unsigned int)palette[3*i + 1] << 8) |
3275 (unsigned int)palette[3*i + 2]);
3276 return VA_STATUS_SUCCESS;
3280 get_sampling_from_fourcc(unsigned int fourcc)
3282 int surface_sampling = -1;
3285 case VA_FOURCC('N', 'V', '1', '2'):
3286 case VA_FOURCC('Y', 'V', '1', '2'):
3287 case VA_FOURCC('I', '4', '2', '0'):
3288 case VA_FOURCC('I', 'Y', 'U', 'V'):
3289 case VA_FOURCC('I', 'M', 'C', '1'):
3290 case VA_FOURCC('I', 'M', 'C', '3'):
3291 surface_sampling = SUBSAMPLE_YUV420;
3293 case VA_FOURCC('Y', 'U', 'Y', '2'):
3294 case VA_FOURCC('U', 'Y', 'V', 'Y'):
3295 case VA_FOURCC('4', '2', '2', 'H'):
3296 surface_sampling = SUBSAMPLE_YUV422H;
3298 case VA_FOURCC('4', '2', '2', 'V'):
3299 surface_sampling = SUBSAMPLE_YUV422V;
3302 case VA_FOURCC('4', '4', '4', 'P'):
3303 surface_sampling = SUBSAMPLE_YUV444;
3306 case VA_FOURCC('4', '1', '1', 'P'):
3307 surface_sampling = SUBSAMPLE_YUV411;
3310 case VA_FOURCC('Y', '8', '0', '0'):
3311 surface_sampling = SUBSAMPLE_YUV400;
3313 case VA_FOURCC('R','G','B','A'):
3314 case VA_FOURCC('R','G','B','X'):
3315 case VA_FOURCC('B','G','R','A'):
3316 case VA_FOURCC('B','G','R','X'):
3317 surface_sampling = SUBSAMPLE_RGBX;
3320 /* Never get here */
3326 return surface_sampling;
3330 memcpy_pic(uint8_t *dst, unsigned int dst_stride,
3331 const uint8_t *src, unsigned int src_stride,
3332 unsigned int len, unsigned int height)
3336 for (i = 0; i < height; i++) {
3337 memcpy(dst, src, len);
3344 get_image_i420(struct object_image *obj_image, uint8_t *image_data,
3345 struct object_surface *obj_surface,
3346 const VARectangle *rect)
3348 uint8_t *dst[3], *src[3];
3350 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
3351 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
3352 unsigned int tiling, swizzle;
3354 if (!obj_surface->bo)
3357 assert(obj_surface->fourcc);
3358 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3360 if (tiling != I915_TILING_NONE)
3361 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3363 dri_bo_map(obj_surface->bo, 0);
3365 if (!obj_surface->bo->virtual)
3368 /* Dest VA image has either I420 or YV12 format.
3369 Source VA surface alway has I420 format */
3370 dst[Y] = image_data + obj_image->image.offsets[Y];
3371 src[0] = (uint8_t *)obj_surface->bo->virtual;
3372 dst[U] = image_data + obj_image->image.offsets[U];
3373 src[1] = src[0] + obj_surface->width * obj_surface->height;
3374 dst[V] = image_data + obj_image->image.offsets[V];
3375 src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
3378 dst[Y] += rect->y * obj_image->image.pitches[Y] + rect->x;
3379 src[0] += rect->y * obj_surface->width + rect->x;
3380 memcpy_pic(dst[Y], obj_image->image.pitches[Y],
3381 src[0], obj_surface->width,
3382 rect->width, rect->height);
3385 dst[U] += (rect->y / 2) * obj_image->image.pitches[U] + rect->x / 2;
3386 src[1] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
3387 memcpy_pic(dst[U], obj_image->image.pitches[U],
3388 src[1], obj_surface->width / 2,
3389 rect->width / 2, rect->height / 2);
3392 dst[V] += (rect->y / 2) * obj_image->image.pitches[V] + rect->x / 2;
3393 src[2] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
3394 memcpy_pic(dst[V], obj_image->image.pitches[V],
3395 src[2], obj_surface->width / 2,
3396 rect->width / 2, rect->height / 2);
3398 if (tiling != I915_TILING_NONE)
3399 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3401 dri_bo_unmap(obj_surface->bo);
3405 get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
3406 struct object_surface *obj_surface,
3407 const VARectangle *rect)
3409 uint8_t *dst[2], *src[2];
3410 unsigned int tiling, swizzle;
3412 if (!obj_surface->bo)
3415 assert(obj_surface->fourcc);
3416 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3418 if (tiling != I915_TILING_NONE)
3419 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3421 dri_bo_map(obj_surface->bo, 0);
3423 if (!obj_surface->bo->virtual)
3426 /* Both dest VA image and source surface have NV12 format */
3427 dst[0] = image_data + obj_image->image.offsets[0];
3428 src[0] = (uint8_t *)obj_surface->bo->virtual;
3429 dst[1] = image_data + obj_image->image.offsets[1];
3430 src[1] = src[0] + obj_surface->width * obj_surface->height;
3433 dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
3434 src[0] += rect->y * obj_surface->width + rect->x;
3435 memcpy_pic(dst[0], obj_image->image.pitches[0],
3436 src[0], obj_surface->width,
3437 rect->width, rect->height);
3440 dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + (rect->x & -2);
3441 src[1] += (rect->y / 2) * obj_surface->width + (rect->x & -2);
3442 memcpy_pic(dst[1], obj_image->image.pitches[1],
3443 src[1], obj_surface->width,
3444 rect->width, rect->height / 2);
3446 if (tiling != I915_TILING_NONE)
3447 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3449 dri_bo_unmap(obj_surface->bo);
3453 get_image_yuy2(struct object_image *obj_image, uint8_t *image_data,
3454 struct object_surface *obj_surface,
3455 const VARectangle *rect)
3458 unsigned int tiling, swizzle;
3460 if (!obj_surface->bo)
3463 assert(obj_surface->fourcc);
3464 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3466 if (tiling != I915_TILING_NONE)
3467 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3469 dri_bo_map(obj_surface->bo, 0);
3471 if (!obj_surface->bo->virtual)
3474 /* Both dest VA image and source surface have YUYV format */
3475 dst = image_data + obj_image->image.offsets[0];
3476 src = (uint8_t *)obj_surface->bo->virtual;
3479 dst += rect->y * obj_image->image.pitches[0] + rect->x*2;
3480 src += rect->y * obj_surface->width + rect->x*2;
3481 memcpy_pic(dst, obj_image->image.pitches[0],
3482 src, obj_surface->width*2,
3483 rect->width*2, rect->height);
3485 if (tiling != I915_TILING_NONE)
3486 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3488 dri_bo_unmap(obj_surface->bo);
3492 i965_sw_getimage(VADriverContextP ctx,
3493 VASurfaceID surface,
3494 int x, /* coordinates of the upper left source pixel */
3496 unsigned int width, /* width and height of the region */
3497 unsigned int height,
3500 struct i965_driver_data *i965 = i965_driver_data(ctx);
3501 struct i965_render_state *render_state = &i965->render_state;
3503 struct object_surface *obj_surface = SURFACE(surface);
3505 return VA_STATUS_ERROR_INVALID_SURFACE;
3507 struct object_image *obj_image = IMAGE(image);
3509 return VA_STATUS_ERROR_INVALID_IMAGE;
3512 return VA_STATUS_ERROR_INVALID_PARAMETER;
3513 if (x + width > obj_surface->orig_width ||
3514 y + height > obj_surface->orig_height)
3515 return VA_STATUS_ERROR_INVALID_PARAMETER;
3516 if (x + width > obj_image->image.width ||
3517 y + height > obj_image->image.height)
3518 return VA_STATUS_ERROR_INVALID_PARAMETER;
3520 if (obj_surface->fourcc != obj_image->image.format.fourcc)
3521 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
3524 void *image_data = NULL;
3526 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
3527 if (va_status != VA_STATUS_SUCCESS)
3534 rect.height = height;
3536 switch (obj_image->image.format.fourcc) {
3537 case VA_FOURCC('Y','V','1','2'):
3538 case VA_FOURCC('I','4','2','0'):
3539 /* I420 is native format for MPEG-2 decoded surfaces */
3540 if (render_state->interleaved_uv)
3541 goto operation_failed;
3542 get_image_i420(obj_image, image_data, obj_surface, &rect);
3544 case VA_FOURCC('N','V','1','2'):
3545 /* NV12 is native format for H.264 decoded surfaces */
3546 if (!render_state->interleaved_uv)
3547 goto operation_failed;
3548 get_image_nv12(obj_image, image_data, obj_surface, &rect);
3550 case VA_FOURCC('Y','U','Y','2'):
3551 /* YUY2 is the format supported by overlay plane */
3552 get_image_yuy2(obj_image, image_data, obj_surface, &rect);
3556 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3560 i965_UnmapBuffer(ctx, obj_image->image.buf);
3565 i965_hw_getimage(VADriverContextP ctx,
3566 VASurfaceID surface,
3567 int x, /* coordinates of the upper left source pixel */
3569 unsigned int width, /* width and height of the region */
3570 unsigned int height,
3573 struct i965_driver_data *i965 = i965_driver_data(ctx);
3574 struct i965_surface src_surface;
3575 struct i965_surface dst_surface;
3578 struct object_surface *obj_surface = SURFACE(surface);
3579 struct object_image *obj_image = IMAGE(image);
3582 return VA_STATUS_ERROR_INVALID_SURFACE;
3585 return VA_STATUS_ERROR_INVALID_IMAGE;
3588 return VA_STATUS_ERROR_INVALID_PARAMETER;
3589 if (x + width > obj_surface->orig_width ||
3590 y + height > obj_surface->orig_height)
3591 return VA_STATUS_ERROR_INVALID_PARAMETER;
3592 if (x + width > obj_image->image.width ||
3593 y + height > obj_image->image.height)
3594 return VA_STATUS_ERROR_INVALID_PARAMETER;
3596 if (!obj_surface->bo)
3597 return VA_STATUS_SUCCESS;
3598 assert(obj_image->bo); // image bo is always created, see i965_CreateImage()
3603 rect.height = height;
3605 src_surface.base = (struct object_base *)obj_surface;
3606 src_surface.type = I965_SURFACE_TYPE_SURFACE;
3607 src_surface.flags = I965_SURFACE_FLAG_FRAME;
3609 dst_surface.base = (struct object_base *)obj_image;
3610 dst_surface.type = I965_SURFACE_TYPE_IMAGE;
3611 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3613 va_status = i965_image_processing(ctx,
3624 i965_GetImage(VADriverContextP ctx,
3625 VASurfaceID surface,
3626 int x, /* coordinates of the upper left source pixel */
3628 unsigned int width, /* width and height of the region */
3629 unsigned int height,
3632 struct i965_driver_data * const i965 = i965_driver_data(ctx);
3635 if (HAS_ACCELERATED_GETIMAGE(i965))
3636 va_status = i965_hw_getimage(ctx,
3642 va_status = i965_sw_getimage(ctx,
3652 put_image_i420(struct object_surface *obj_surface,
3653 const VARectangle *dst_rect,
3654 struct object_image *obj_image, uint8_t *image_data,
3655 const VARectangle *src_rect)
3657 uint8_t *dst[3], *src[3];
3659 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
3660 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
3661 unsigned int tiling, swizzle;
3663 if (!obj_surface->bo)
3666 assert(obj_surface->fourcc);
3667 assert(dst_rect->width == src_rect->width);
3668 assert(dst_rect->height == src_rect->height);
3669 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3671 if (tiling != I915_TILING_NONE)
3672 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3674 dri_bo_map(obj_surface->bo, 0);
3676 if (!obj_surface->bo->virtual)
3679 /* Dest VA image has either I420 or YV12 format.
3680 Source VA surface alway has I420 format */
3681 dst[0] = (uint8_t *)obj_surface->bo->virtual;
3682 src[Y] = image_data + obj_image->image.offsets[Y];
3683 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
3684 src[U] = image_data + obj_image->image.offsets[U];
3685 dst[2] = dst[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
3686 src[V] = image_data + obj_image->image.offsets[V];
3689 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
3690 src[Y] += src_rect->y * obj_image->image.pitches[Y] + src_rect->x;
3691 memcpy_pic(dst[0], obj_surface->width,
3692 src[Y], obj_image->image.pitches[Y],
3693 src_rect->width, src_rect->height);
3696 dst[1] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
3697 src[U] += (src_rect->y / 2) * obj_image->image.pitches[U] + src_rect->x / 2;
3698 memcpy_pic(dst[1], obj_surface->width / 2,
3699 src[U], obj_image->image.pitches[U],
3700 src_rect->width / 2, src_rect->height / 2);
3703 dst[2] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
3704 src[V] += (src_rect->y / 2) * obj_image->image.pitches[V] + src_rect->x / 2;
3705 memcpy_pic(dst[2], obj_surface->width / 2,
3706 src[V], obj_image->image.pitches[V],
3707 src_rect->width / 2, src_rect->height / 2);
3709 if (tiling != I915_TILING_NONE)
3710 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3712 dri_bo_unmap(obj_surface->bo);
3716 put_image_nv12(struct object_surface *obj_surface,
3717 const VARectangle *dst_rect,
3718 struct object_image *obj_image, uint8_t *image_data,
3719 const VARectangle *src_rect)
3721 uint8_t *dst[2], *src[2];
3722 unsigned int tiling, swizzle;
3724 if (!obj_surface->bo)
3727 assert(obj_surface->fourcc);
3728 assert(dst_rect->width == src_rect->width);
3729 assert(dst_rect->height == src_rect->height);
3730 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3732 if (tiling != I915_TILING_NONE)
3733 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3735 dri_bo_map(obj_surface->bo, 0);
3737 if (!obj_surface->bo->virtual)
3740 /* Both dest VA image and source surface have NV12 format */
3741 dst[0] = (uint8_t *)obj_surface->bo->virtual;
3742 src[0] = image_data + obj_image->image.offsets[0];
3743 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
3744 src[1] = image_data + obj_image->image.offsets[1];
3747 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
3748 src[0] += src_rect->y * obj_image->image.pitches[0] + src_rect->x;
3749 memcpy_pic(dst[0], obj_surface->width,
3750 src[0], obj_image->image.pitches[0],
3751 src_rect->width, src_rect->height);
3754 dst[1] += (dst_rect->y / 2) * obj_surface->width + (dst_rect->x & -2);
3755 src[1] += (src_rect->y / 2) * obj_image->image.pitches[1] + (src_rect->x & -2);
3756 memcpy_pic(dst[1], obj_surface->width,
3757 src[1], obj_image->image.pitches[1],
3758 src_rect->width, src_rect->height / 2);
3760 if (tiling != I915_TILING_NONE)
3761 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3763 dri_bo_unmap(obj_surface->bo);
3767 put_image_yuy2(struct object_surface *obj_surface,
3768 const VARectangle *dst_rect,
3769 struct object_image *obj_image, uint8_t *image_data,
3770 const VARectangle *src_rect)
3773 unsigned int tiling, swizzle;
3775 if (!obj_surface->bo)
3778 assert(obj_surface->fourcc);
3779 assert(dst_rect->width == src_rect->width);
3780 assert(dst_rect->height == src_rect->height);
3781 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3783 if (tiling != I915_TILING_NONE)
3784 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3786 dri_bo_map(obj_surface->bo, 0);
3788 if (!obj_surface->bo->virtual)
3791 /* Both dest VA image and source surface have YUY2 format */
3792 dst = (uint8_t *)obj_surface->bo->virtual;
3793 src = image_data + obj_image->image.offsets[0];
3795 /* YUYV packed plane */
3796 dst += dst_rect->y * obj_surface->width + dst_rect->x*2;
3797 src += src_rect->y * obj_image->image.pitches[0] + src_rect->x*2;
3798 memcpy_pic(dst, obj_surface->width*2,
3799 src, obj_image->image.pitches[0],
3800 src_rect->width*2, src_rect->height);
3802 if (tiling != I915_TILING_NONE)
3803 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3805 dri_bo_unmap(obj_surface->bo);
3810 i965_sw_putimage(VADriverContextP ctx,
3811 VASurfaceID surface,
3815 unsigned int src_width,
3816 unsigned int src_height,
3819 unsigned int dest_width,
3820 unsigned int dest_height)
3822 struct i965_driver_data *i965 = i965_driver_data(ctx);
3823 struct object_surface *obj_surface = SURFACE(surface);
3826 return VA_STATUS_ERROR_INVALID_SURFACE;
3828 struct object_image *obj_image = IMAGE(image);
3830 return VA_STATUS_ERROR_INVALID_IMAGE;
3832 if (src_x < 0 || src_y < 0)
3833 return VA_STATUS_ERROR_INVALID_PARAMETER;
3834 if (src_x + src_width > obj_image->image.width ||
3835 src_y + src_height > obj_image->image.height)
3836 return VA_STATUS_ERROR_INVALID_PARAMETER;
3837 if (dest_x < 0 || dest_y < 0)
3838 return VA_STATUS_ERROR_INVALID_PARAMETER;
3839 if (dest_x + dest_width > obj_surface->orig_width ||
3840 dest_y + dest_height > obj_surface->orig_height)
3841 return VA_STATUS_ERROR_INVALID_PARAMETER;
3843 /* XXX: don't allow scaling */
3844 if (src_width != dest_width || src_height != dest_height)
3845 return VA_STATUS_ERROR_INVALID_PARAMETER;
3847 if (obj_surface->fourcc) {
3848 /* Don't allow format mismatch */
3849 if (obj_surface->fourcc != obj_image->image.format.fourcc)
3850 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
3854 /* VA is surface not used for decoding, use same VA image format */
3855 i965_check_alloc_surface_bo(
3858 0, /* XXX: don't use tiled surface */
3859 obj_image->image.format.fourcc,
3860 get_sampling_from_fourcc (obj_image->image.format.fourcc));
3864 void *image_data = NULL;
3866 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
3867 if (va_status != VA_STATUS_SUCCESS)
3870 VARectangle src_rect, dest_rect;
3873 src_rect.width = src_width;
3874 src_rect.height = src_height;
3875 dest_rect.x = dest_x;
3876 dest_rect.y = dest_y;
3877 dest_rect.width = dest_width;
3878 dest_rect.height = dest_height;
3880 switch (obj_image->image.format.fourcc) {
3881 case VA_FOURCC('Y','V','1','2'):
3882 case VA_FOURCC('I','4','2','0'):
3883 put_image_i420(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
3885 case VA_FOURCC('N','V','1','2'):
3886 put_image_nv12(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
3888 case VA_FOURCC('Y','U','Y','2'):
3889 put_image_yuy2(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
3892 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3896 i965_UnmapBuffer(ctx, obj_image->image.buf);
3901 i965_hw_putimage(VADriverContextP ctx,
3902 VASurfaceID surface,
3906 unsigned int src_width,
3907 unsigned int src_height,
3910 unsigned int dest_width,
3911 unsigned int dest_height)
3913 struct i965_driver_data *i965 = i965_driver_data(ctx);
3914 struct object_surface *obj_surface = SURFACE(surface);
3915 struct object_image *obj_image = IMAGE(image);
3916 struct i965_surface src_surface, dst_surface;
3917 VAStatus va_status = VA_STATUS_SUCCESS;
3918 VARectangle src_rect, dst_rect;
3921 return VA_STATUS_ERROR_INVALID_SURFACE;
3923 if (!obj_image || !obj_image->bo)
3924 return VA_STATUS_ERROR_INVALID_IMAGE;
3928 src_x + src_width > obj_image->image.width ||
3929 src_y + src_height > obj_image->image.height)
3930 return VA_STATUS_ERROR_INVALID_PARAMETER;
3934 dest_x + dest_width > obj_surface->orig_width ||
3935 dest_y + dest_height > obj_surface->orig_height)
3936 return VA_STATUS_ERROR_INVALID_PARAMETER;
3938 if (!obj_surface->bo) {
3939 unsigned int tiling, swizzle;
3940 int surface_sampling = get_sampling_from_fourcc (obj_image->image.format.fourcc);;
3941 dri_bo_get_tiling(obj_image->bo, &tiling, &swizzle);
3943 i965_check_alloc_surface_bo(ctx,
3946 obj_image->image.format.fourcc,
3950 assert(obj_surface->fourcc);
3952 src_surface.base = (struct object_base *)obj_image;
3953 src_surface.type = I965_SURFACE_TYPE_IMAGE;
3954 src_surface.flags = I965_SURFACE_FLAG_FRAME;
3957 src_rect.width = src_width;
3958 src_rect.height = src_height;
3960 dst_surface.base = (struct object_base *)obj_surface;
3961 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
3962 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3963 dst_rect.x = dest_x;
3964 dst_rect.y = dest_y;
3965 dst_rect.width = dest_width;
3966 dst_rect.height = dest_height;
3968 va_status = i965_image_processing(ctx,
3978 i965_PutImage(VADriverContextP ctx,
3979 VASurfaceID surface,
3983 unsigned int src_width,
3984 unsigned int src_height,
3987 unsigned int dest_width,
3988 unsigned int dest_height)
3990 struct i965_driver_data *i965 = i965_driver_data(ctx);
3991 VAStatus va_status = VA_STATUS_SUCCESS;
3993 if (HAS_ACCELERATED_PUTIMAGE(i965))
3994 va_status = i965_hw_putimage(ctx,
4006 va_status = i965_sw_putimage(ctx,
4022 i965_PutSurface(VADriverContextP ctx,
4023 VASurfaceID surface,
4024 void *draw, /* X Drawable */
4027 unsigned short srcw,
4028 unsigned short srch,
4031 unsigned short destw,
4032 unsigned short desth,
4033 VARectangle *cliprects, /* client supplied clip list */
4034 unsigned int number_cliprects, /* number of clip rects in the clip list */
4035 unsigned int flags) /* de-interlacing flags */
4038 if (IS_VA_X11(ctx)) {
4039 VARectangle src_rect, dst_rect;
4043 src_rect.width = srcw;
4044 src_rect.height = srch;
4048 dst_rect.width = destw;
4049 dst_rect.height = desth;
4051 return i965_put_surface_dri(ctx, surface, draw, &src_rect, &dst_rect,
4052 cliprects, number_cliprects, flags);
4055 return VA_STATUS_ERROR_UNIMPLEMENTED;
4060 VADriverContextP ctx, /* in */
4061 VABufferID buf_id, /* in */
4062 VABufferType *type, /* out */
4063 unsigned int *size, /* out */
4064 unsigned int *num_elements /* out */
4067 struct i965_driver_data *i965 = NULL;
4068 struct object_buffer *obj_buffer = NULL;
4070 i965 = i965_driver_data(ctx);
4071 obj_buffer = BUFFER(buf_id);
4076 return VA_STATUS_ERROR_INVALID_BUFFER;
4078 *type = obj_buffer->type;
4079 *size = obj_buffer->size_element;
4080 *num_elements = obj_buffer->num_elements;
4082 return VA_STATUS_SUCCESS;
4087 VADriverContextP ctx, /* in */
4088 VASurfaceID surface, /* in */
4089 unsigned int *fourcc, /* out */
4090 unsigned int *luma_stride, /* out */
4091 unsigned int *chroma_u_stride, /* out */
4092 unsigned int *chroma_v_stride, /* out */
4093 unsigned int *luma_offset, /* out */
4094 unsigned int *chroma_u_offset, /* out */
4095 unsigned int *chroma_v_offset, /* out */
4096 unsigned int *buffer_name, /* out */
4097 void **buffer /* out */
4100 VAStatus vaStatus = VA_STATUS_SUCCESS;
4101 struct i965_driver_data *i965 = i965_driver_data(ctx);
4102 struct object_surface *obj_surface = NULL;
4106 assert(luma_stride);
4107 assert(chroma_u_stride);
4108 assert(chroma_v_stride);
4109 assert(luma_offset);
4110 assert(chroma_u_offset);
4111 assert(chroma_v_offset);
4112 assert(buffer_name);
4115 tmpImage.image_id = VA_INVALID_ID;
4117 obj_surface = SURFACE(surface);
4118 if (obj_surface == NULL) {
4119 // Surface is absent.
4120 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4124 // Lock functionality is absent now.
4125 if (obj_surface->locked_image_id != VA_INVALID_ID) {
4126 // Surface is locked already.
4127 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4131 vaStatus = i965_DeriveImage(
4135 if (vaStatus != VA_STATUS_SUCCESS) {
4139 obj_surface->locked_image_id = tmpImage.image_id;
4141 vaStatus = i965_MapBuffer(
4145 if (vaStatus != VA_STATUS_SUCCESS) {
4149 *fourcc = tmpImage.format.fourcc;
4150 *luma_offset = tmpImage.offsets[0];
4151 *luma_stride = tmpImage.pitches[0];
4152 *chroma_u_offset = tmpImage.offsets[1];
4153 *chroma_u_stride = tmpImage.pitches[1];
4154 *chroma_v_offset = tmpImage.offsets[2];
4155 *chroma_v_stride = tmpImage.pitches[2];
4156 *buffer_name = tmpImage.buf;
4159 if (vaStatus != VA_STATUS_SUCCESS) {
4168 VADriverContextP ctx, /* in */
4169 VASurfaceID surface /* in */
4172 VAStatus vaStatus = VA_STATUS_SUCCESS;
4173 struct i965_driver_data *i965 = i965_driver_data(ctx);
4174 struct object_image *locked_img = NULL;
4175 struct object_surface *obj_surface = NULL;
4177 obj_surface = SURFACE(surface);
4179 if (obj_surface == NULL) {
4180 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is absent
4183 if (obj_surface->locked_image_id == VA_INVALID_ID) {
4184 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is not locked
4188 locked_img = IMAGE(obj_surface->locked_image_id);
4189 if (locked_img == NULL || (locked_img->image.image_id == VA_INVALID_ID)) {
4190 // Work image was deallocated before i965_UnlockSurface()
4191 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4195 vaStatus = i965_UnmapBuffer(
4197 locked_img->image.buf);
4198 if (vaStatus != VA_STATUS_SUCCESS) {
4202 vaStatus = i965_DestroyImage(
4204 locked_img->image.image_id);
4205 if (vaStatus != VA_STATUS_SUCCESS) {
4209 locked_img->image.image_id = VA_INVALID_ID;
4212 obj_surface->locked_image_id = VA_INVALID_ID;
4218 i965_GetSurfaceAttributes(
4219 VADriverContextP ctx,
4221 VASurfaceAttrib *attrib_list,
4222 unsigned int num_attribs
4225 VAStatus vaStatus = VA_STATUS_SUCCESS;
4226 struct i965_driver_data *i965 = i965_driver_data(ctx);
4227 struct object_config *obj_config;
4230 if (config == VA_INVALID_ID)
4231 return VA_STATUS_ERROR_INVALID_CONFIG;
4233 obj_config = CONFIG(config);
4235 if (obj_config == NULL)
4236 return VA_STATUS_ERROR_INVALID_CONFIG;
4238 if (attrib_list == NULL || num_attribs == 0)
4239 return VA_STATUS_ERROR_INVALID_PARAMETER;
4241 for (i = 0; i < num_attribs; i++) {
4242 switch (attrib_list[i].type) {
4243 case VASurfaceAttribPixelFormat:
4244 attrib_list[i].value.type = VAGenericValueTypeInteger;
4245 attrib_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4247 if (attrib_list[i].value.value.i == 0) {
4248 if (IS_G4X(i965->intel.device_id)) {
4249 if (obj_config->profile == VAProfileMPEG2Simple ||
4250 obj_config->profile == VAProfileMPEG2Main) {
4251 attrib_list[i].value.value.i = VA_FOURCC('I', '4', '2', '0');
4254 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4256 } else if (IS_IRONLAKE(i965->intel.device_id)) {
4257 if (obj_config->profile == VAProfileMPEG2Simple ||
4258 obj_config->profile == VAProfileMPEG2Main) {
4259 attrib_list[i].value.value.i = VA_FOURCC('I', '4', '2', '0');
4260 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
4261 obj_config->profile == VAProfileH264Main ||
4262 obj_config->profile == VAProfileH264High) {
4263 attrib_list[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4264 } else if (obj_config->profile == VAProfileNone) {
4265 attrib_list[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4268 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4270 } else if (IS_GEN6(i965->intel.device_id)) {
4271 attrib_list[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4272 } else if (IS_GEN7(i965->intel.device_id) ||
4273 IS_GEN8(i965->intel.device_id)) {
4274 if (obj_config->profile == VAProfileJPEGBaseline)
4275 attrib_list[i].value.value.i = 0; /* internal format */
4277 attrib_list[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4280 if (IS_G4X(i965->intel.device_id)) {
4281 if (obj_config->profile == VAProfileMPEG2Simple ||
4282 obj_config->profile == VAProfileMPEG2Main) {
4283 if (attrib_list[i].value.value.i != VA_FOURCC('I', '4', '2', '0')) {
4284 attrib_list[i].value.value.i = 0;
4285 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4289 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4291 } else if (IS_IRONLAKE(i965->intel.device_id)) {
4292 if (obj_config->profile == VAProfileMPEG2Simple ||
4293 obj_config->profile == VAProfileMPEG2Main) {
4294 if (attrib_list[i].value.value.i != VA_FOURCC('I', '4', '2', '0')) {
4295 attrib_list[i].value.value.i = 0;
4296 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4298 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
4299 obj_config->profile == VAProfileH264Main ||
4300 obj_config->profile == VAProfileH264High) {
4301 if (attrib_list[i].value.value.i != VA_FOURCC('N', 'V', '1', '2')) {
4302 attrib_list[i].value.value.i = 0;
4303 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4305 } else if (obj_config->profile == VAProfileNone) {
4306 switch (attrib_list[i].value.value.i) {
4307 case VA_FOURCC('N', 'V', '1', '2'):
4308 case VA_FOURCC('I', '4', '2', '0'):
4309 case VA_FOURCC('Y', 'V', '1', '2'):
4310 case VA_FOURCC('Y', 'U', 'Y', '2'):
4311 case VA_FOURCC('B', 'G', 'R', 'A'):
4312 case VA_FOURCC('B', 'G', 'R', 'X'):
4313 case VA_FOURCC('R', 'G', 'B', 'X'):
4314 case VA_FOURCC('R', 'G', 'B', 'A'):
4317 attrib_list[i].value.value.i = 0;
4318 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4323 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4325 } else if (IS_GEN6(i965->intel.device_id)) {
4326 if (obj_config->entrypoint == VAEntrypointEncSlice ||
4327 obj_config->entrypoint == VAEntrypointVideoProc) {
4328 switch (attrib_list[i].value.value.i) {
4329 case VA_FOURCC('N', 'V', '1', '2'):
4330 case VA_FOURCC('I', '4', '2', '0'):
4331 case VA_FOURCC('Y', 'V', '1', '2'):
4332 case VA_FOURCC('Y', 'U', 'Y', '2'):
4333 case VA_FOURCC('B', 'G', 'R', 'A'):
4334 case VA_FOURCC('B', 'G', 'R', 'X'):
4335 case VA_FOURCC('R', 'G', 'B', 'X'):
4336 case VA_FOURCC('R', 'G', 'B', 'A'):
4339 attrib_list[i].value.value.i = 0;
4340 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4344 if (attrib_list[i].value.value.i != VA_FOURCC('N', 'V', '1', '2')) {
4345 attrib_list[i].value.value.i = 0;
4346 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4349 } else if (IS_GEN7(i965->intel.device_id) ||
4350 IS_GEN8(i965->intel.device_id)) {
4351 if (obj_config->entrypoint == VAEntrypointEncSlice ||
4352 obj_config->entrypoint == VAEntrypointVideoProc) {
4353 switch (attrib_list[i].value.value.i) {
4354 case VA_FOURCC('N', 'V', '1', '2'):
4355 case VA_FOURCC('I', '4', '2', '0'):
4356 case VA_FOURCC('Y', 'V', '1', '2'):
4359 attrib_list[i].value.value.i = 0;
4360 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4364 if (obj_config->profile == VAProfileJPEGBaseline) {
4365 attrib_list[i].value.value.i = 0; /* JPEG decoding always uses an internal format */
4366 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4368 if (attrib_list[i].value.value.i != VA_FOURCC('N', 'V', '1', '2')) {
4369 attrib_list[i].value.value.i = 0;
4370 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4378 case VASurfaceAttribMinWidth:
4379 /* FIXME: add support for it later */
4380 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4382 case VASurfaceAttribMaxWidth:
4383 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4385 case VASurfaceAttribMinHeight:
4386 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4388 case VASurfaceAttribMaxHeight:
4389 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4392 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4401 i965_QuerySurfaceAttributes(VADriverContextP ctx,
4403 VASurfaceAttrib *attrib_list,
4404 unsigned int *num_attribs)
4406 VAStatus vaStatus = VA_STATUS_SUCCESS;
4407 struct i965_driver_data *i965 = i965_driver_data(ctx);
4408 struct object_config *obj_config;
4410 VASurfaceAttrib *attribs = NULL;
4412 if (config == VA_INVALID_ID)
4413 return VA_STATUS_ERROR_INVALID_CONFIG;
4415 obj_config = CONFIG(config);
4417 if (obj_config == NULL)
4418 return VA_STATUS_ERROR_INVALID_CONFIG;
4420 if (!attrib_list && !num_attribs)
4421 return VA_STATUS_ERROR_INVALID_PARAMETER;
4423 if (attrib_list == NULL) {
4424 *num_attribs = I965_MAX_SURFACE_ATTRIBUTES;
4425 return VA_STATUS_SUCCESS;
4428 attribs = malloc(I965_MAX_SURFACE_ATTRIBUTES *sizeof(*attribs));
4430 if (attribs == NULL)
4431 return VA_STATUS_ERROR_ALLOCATION_FAILED;
4433 if (IS_G4X(i965->intel.device_id)) {
4434 if (obj_config->profile == VAProfileMPEG2Simple ||
4435 obj_config->profile == VAProfileMPEG2Main) {
4436 attribs[i].type = VASurfaceAttribPixelFormat;
4437 attribs[i].value.type = VAGenericValueTypeInteger;
4438 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4439 attribs[i].value.value.i = VA_FOURCC('I', '4', '2', '0');
4442 } else if (IS_IRONLAKE(i965->intel.device_id)) {
4443 switch (obj_config->profile) {
4444 case VAProfileMPEG2Simple:
4445 case VAProfileMPEG2Main:
4446 attribs[i].type = VASurfaceAttribPixelFormat;
4447 attribs[i].value.type = VAGenericValueTypeInteger;
4448 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4449 attribs[i].value.value.i = VA_FOURCC('I', '4', '2', '0');
4454 case VAProfileH264ConstrainedBaseline:
4455 case VAProfileH264Main:
4456 case VAProfileH264High:
4457 attribs[i].type = VASurfaceAttribPixelFormat;
4458 attribs[i].value.type = VAGenericValueTypeInteger;
4459 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4460 attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4464 attribs[i].type = VASurfaceAttribPixelFormat;
4465 attribs[i].value.type = VAGenericValueTypeInteger;
4466 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4467 attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4470 attribs[i].type = VASurfaceAttribPixelFormat;
4471 attribs[i].value.type = VAGenericValueTypeInteger;
4472 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4473 attribs[i].value.value.i = VA_FOURCC('I', '4', '2', '0');
4481 } else if (IS_GEN6(i965->intel.device_id)) {
4482 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4483 attribs[i].type = VASurfaceAttribPixelFormat;
4484 attribs[i].value.type = VAGenericValueTypeInteger;
4485 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4486 attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4488 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
4489 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4490 attribs[i].type = VASurfaceAttribPixelFormat;
4491 attribs[i].value.type = VAGenericValueTypeInteger;
4492 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4493 attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4496 attribs[i].type = VASurfaceAttribPixelFormat;
4497 attribs[i].value.type = VAGenericValueTypeInteger;
4498 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4499 attribs[i].value.value.i = VA_FOURCC('I', '4', '2', '0');
4502 attribs[i].type = VASurfaceAttribPixelFormat;
4503 attribs[i].value.type = VAGenericValueTypeInteger;
4504 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4505 attribs[i].value.value.i = VA_FOURCC('Y', 'V', '1', '2');
4508 if (obj_config->entrypoint == VAEntrypointVideoProc) {
4509 attribs[i].type = VASurfaceAttribPixelFormat;
4510 attribs[i].value.type = VAGenericValueTypeInteger;
4511 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4512 attribs[i].value.value.i = VA_FOURCC('Y', 'U', 'Y', '2');
4515 attribs[i].type = VASurfaceAttribPixelFormat;
4516 attribs[i].value.type = VAGenericValueTypeInteger;
4517 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4518 attribs[i].value.value.i = VA_FOURCC('R', 'G', 'B', 'A');
4521 attribs[i].type = VASurfaceAttribPixelFormat;
4522 attribs[i].value.type = VAGenericValueTypeInteger;
4523 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4524 attribs[i].value.value.i = VA_FOURCC('R', 'G', 'B', 'X');
4528 } else if (IS_GEN7(i965->intel.device_id)) {
4529 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4530 if (obj_config->profile == VAProfileJPEGBaseline) {
4531 attribs[i].type = VASurfaceAttribPixelFormat;
4532 attribs[i].value.type = VAGenericValueTypeInteger;
4533 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4534 attribs[i].value.value.i = VA_FOURCC('I', 'M', 'C', '3');
4537 attribs[i].type = VASurfaceAttribPixelFormat;
4538 attribs[i].value.type = VAGenericValueTypeInteger;
4539 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4540 attribs[i].value.value.i = VA_FOURCC('I', 'M', 'C', '1');
4543 attribs[i].type = VASurfaceAttribPixelFormat;
4544 attribs[i].value.type = VAGenericValueTypeInteger;
4545 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4546 attribs[i].value.value.i = VA_FOURCC('Y', '8', '0', '0');
4549 attribs[i].type = VASurfaceAttribPixelFormat;
4550 attribs[i].value.type = VAGenericValueTypeInteger;
4551 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4552 attribs[i].value.value.i = VA_FOURCC('4', '1', '1', 'P');
4555 attribs[i].type = VASurfaceAttribPixelFormat;
4556 attribs[i].value.type = VAGenericValueTypeInteger;
4557 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4558 attribs[i].value.value.i = VA_FOURCC('4', '2', '2', 'H');
4561 attribs[i].type = VASurfaceAttribPixelFormat;
4562 attribs[i].value.type = VAGenericValueTypeInteger;
4563 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4564 attribs[i].value.value.i = VA_FOURCC('4', '2', '2', 'V');
4567 attribs[i].type = VASurfaceAttribPixelFormat;
4568 attribs[i].value.type = VAGenericValueTypeInteger;
4569 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4570 attribs[i].value.value.i = VA_FOURCC('4', '4', '4', 'P');
4573 attribs[i].type = VASurfaceAttribPixelFormat;
4574 attribs[i].value.type = VAGenericValueTypeInteger;
4575 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4576 attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4579 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
4580 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4581 attribs[i].type = VASurfaceAttribPixelFormat;
4582 attribs[i].value.type = VAGenericValueTypeInteger;
4583 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4584 attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4587 attribs[i].type = VASurfaceAttribPixelFormat;
4588 attribs[i].value.type = VAGenericValueTypeInteger;
4589 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4590 attribs[i].value.value.i = VA_FOURCC('I', '4', '2', '0');
4593 attribs[i].type = VASurfaceAttribPixelFormat;
4594 attribs[i].value.type = VAGenericValueTypeInteger;
4595 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4596 attribs[i].value.value.i = VA_FOURCC('Y', 'V', '1', '2');
4599 attribs[i].type = VASurfaceAttribPixelFormat;
4600 attribs[i].value.type = VAGenericValueTypeInteger;
4601 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4602 attribs[i].value.value.i = VA_FOURCC('I', 'M', 'C', '3');
4605 if (obj_config->entrypoint == VAEntrypointVideoProc) {
4606 attribs[i].type = VASurfaceAttribPixelFormat;
4607 attribs[i].value.type = VAGenericValueTypeInteger;
4608 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4609 attribs[i].value.value.i = VA_FOURCC('Y', 'U', 'Y', '2');
4612 attribs[i].type = VASurfaceAttribPixelFormat;
4613 attribs[i].value.type = VAGenericValueTypeInteger;
4614 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4615 attribs[i].value.value.i = VA_FOURCC('R', 'G', 'B', 'A');
4618 attribs[i].type = VASurfaceAttribPixelFormat;
4619 attribs[i].value.type = VAGenericValueTypeInteger;
4620 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4621 attribs[i].value.value.i = VA_FOURCC('R', 'G', 'B', 'X');
4625 } else if (IS_GEN8(i965->intel.device_id)) {
4626 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4627 if (obj_config->profile == VAProfileJPEGBaseline) {
4628 attribs[i].type = VASurfaceAttribPixelFormat;
4629 attribs[i].value.type = VAGenericValueTypeInteger;
4630 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4631 attribs[i].value.value.i = VA_FOURCC('I', 'M', 'C', '3');
4634 attribs[i].type = VASurfaceAttribPixelFormat;
4635 attribs[i].value.type = VAGenericValueTypeInteger;
4636 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4637 attribs[i].value.value.i = VA_FOURCC('I', 'M', 'C', '1');
4640 attribs[i].type = VASurfaceAttribPixelFormat;
4641 attribs[i].value.type = VAGenericValueTypeInteger;
4642 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4643 attribs[i].value.value.i = VA_FOURCC('Y', '8', '0', '0');
4646 attribs[i].type = VASurfaceAttribPixelFormat;
4647 attribs[i].value.type = VAGenericValueTypeInteger;
4648 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4649 attribs[i].value.value.i = VA_FOURCC('4', '1', '1', 'P');
4652 attribs[i].type = VASurfaceAttribPixelFormat;
4653 attribs[i].value.type = VAGenericValueTypeInteger;
4654 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4655 attribs[i].value.value.i = VA_FOURCC('4', '2', '2', 'H');
4658 attribs[i].type = VASurfaceAttribPixelFormat;
4659 attribs[i].value.type = VAGenericValueTypeInteger;
4660 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4661 attribs[i].value.value.i = VA_FOURCC('4', '2', '2', 'V');
4664 attribs[i].type = VASurfaceAttribPixelFormat;
4665 attribs[i].value.type = VAGenericValueTypeInteger;
4666 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4667 attribs[i].value.value.i = VA_FOURCC('4', '4', '4', 'P');
4670 attribs[i].type = VASurfaceAttribPixelFormat;
4671 attribs[i].value.type = VAGenericValueTypeInteger;
4672 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4673 attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4676 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
4677 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4679 attribs[i].type = VASurfaceAttribPixelFormat;
4680 attribs[i].value.type = VAGenericValueTypeInteger;
4681 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4682 attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
4685 attribs[i].type = VASurfaceAttribPixelFormat;
4686 attribs[i].value.type = VAGenericValueTypeInteger;
4687 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4688 attribs[i].value.value.i = VA_FOURCC('I', '4', '2', '0');
4691 attribs[i].type = VASurfaceAttribPixelFormat;
4692 attribs[i].value.type = VAGenericValueTypeInteger;
4693 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4694 attribs[i].value.value.i = VA_FOURCC('Y', 'V', '1', '2');
4697 attribs[i].type = VASurfaceAttribPixelFormat;
4698 attribs[i].value.type = VAGenericValueTypeInteger;
4699 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4700 attribs[i].value.value.i = VA_FOURCC('I', 'M', 'C', '3');
4703 if (obj_config->entrypoint == VAEntrypointVideoProc) {
4704 attribs[i].type = VASurfaceAttribPixelFormat;
4705 attribs[i].value.type = VAGenericValueTypeInteger;
4706 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4707 attribs[i].value.value.i = VA_FOURCC('Y', 'U', 'Y', '2');
4710 attribs[i].type = VASurfaceAttribPixelFormat;
4711 attribs[i].value.type = VAGenericValueTypeInteger;
4712 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4713 attribs[i].value.value.i = VA_FOURCC('R', 'G', 'B', 'A');
4716 attribs[i].type = VASurfaceAttribPixelFormat;
4717 attribs[i].value.type = VAGenericValueTypeInteger;
4718 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4719 attribs[i].value.value.i = VA_FOURCC('R', 'G', 'B', 'X');
4722 attribs[i].type = VASurfaceAttribPixelFormat;
4723 attribs[i].value.type = VAGenericValueTypeInteger;
4724 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4725 attribs[i].value.value.i = VA_FOURCC('B', 'G', 'R', 'A');
4728 attribs[i].type = VASurfaceAttribPixelFormat;
4729 attribs[i].value.type = VAGenericValueTypeInteger;
4730 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4731 attribs[i].value.value.i = VA_FOURCC('B', 'G', 'R', 'X');
4737 attribs[i].type = VASurfaceAttribMemoryType;
4738 attribs[i].value.type = VAGenericValueTypeInteger;
4739 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4740 attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
4741 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
4742 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
4745 attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
4746 attribs[i].value.type = VAGenericValueTypePointer;
4747 attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
4748 attribs[i].value.value.p = NULL; /* ignore */
4751 if (i > *num_attribs) {
4754 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4758 memcpy(attrib_list, attribs, i * sizeof(*attribs));
4765 i965_os_has_ring_support(VADriverContextP ctx,
4768 struct i965_driver_data *const i965 = i965_driver_data(ctx);
4772 return i965->intel.has_bsd;
4775 return i965->intel.has_blt;
4777 case I965_RING_VEBOX:
4778 return i965->intel.has_vebox;
4780 case I965_RING_NULL:
4781 return 1; /* Always support */
4784 /* should never get here */
4793 * Query video processing pipeline
4795 VAStatus i965_QueryVideoProcFilters(
4796 VADriverContextP ctx,
4797 VAContextID context,
4798 VAProcFilterType *filters,
4799 unsigned int *num_filters
4802 struct i965_driver_data *const i965 = i965_driver_data(ctx);
4803 unsigned int i = 0, num = 0;
4805 if (!num_filters || !filters)
4806 return VA_STATUS_ERROR_INVALID_PARAMETER;
4808 for (i = 0; i < i965->codec_info->num_filters; i++) {
4809 if (i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring)) {
4810 if (num == *num_filters) {
4811 *num_filters = i965->codec_info->num_filters;
4813 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4816 filters[num++] = i965->codec_info->filters[i].type;
4822 return VA_STATUS_SUCCESS;
4825 VAStatus i965_QueryVideoProcFilterCaps(
4826 VADriverContextP ctx,
4827 VAContextID context,
4828 VAProcFilterType type,
4830 unsigned int *num_filter_caps
4834 struct i965_driver_data *const i965 = i965_driver_data(ctx);
4836 if (!filter_caps || !num_filter_caps)
4837 return VA_STATUS_ERROR_INVALID_PARAMETER;
4839 for (i = 0; i < i965->codec_info->num_filters; i++) {
4840 if (type == i965->codec_info->filters[i].type &&
4841 i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring))
4845 if (i == i965->codec_info->num_filters)
4846 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
4851 case VAProcFilterNoiseReduction:
4852 case VAProcFilterSharpening:
4854 VAProcFilterCap *cap = filter_caps;
4856 if (*num_filter_caps < 1) {
4857 *num_filter_caps = 1;
4858 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4861 cap->range.min_value = 0.0;
4862 cap->range.max_value = 1.0;
4863 cap->range.default_value = 0.5;
4864 cap->range.step = 0.03125; /* 1.0 / 32 */
4870 case VAProcFilterDeinterlacing:
4872 VAProcFilterCapDeinterlacing *cap = filter_caps;
4874 if (*num_filter_caps < VAProcDeinterlacingCount) {
4875 *num_filter_caps = VAProcDeinterlacingCount;
4876 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4879 cap->type = VAProcDeinterlacingBob;
4884 if (i965->codec_info->has_di_motion_adptive) {
4885 cap->type = VAProcDeinterlacingMotionAdaptive;
4890 if (i965->codec_info->has_di_motion_compensated) {
4891 cap->type = VAProcDeinterlacingMotionCompensated;
4899 case VAProcFilterColorBalance:
4901 VAProcFilterCapColorBalance *cap = filter_caps;
4903 if (*num_filter_caps < VAProcColorBalanceCount) {
4904 *num_filter_caps = VAProcColorBalanceCount;
4905 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4908 cap->type = VAProcColorBalanceHue;
4909 cap->range.min_value = -180.0;
4910 cap->range.max_value = 180.0;
4911 cap->range.default_value = 0.0;
4912 cap->range.step = 1.0;
4916 cap->type = VAProcColorBalanceSaturation;
4917 cap->range.min_value = 0.0;
4918 cap->range.max_value = 10.0;
4919 cap->range.default_value = 1.0;
4920 cap->range.step = 0.1;
4924 cap->type = VAProcColorBalanceBrightness;
4925 cap->range.min_value = -100.0;
4926 cap->range.max_value = 100.0;
4927 cap->range.default_value = 0.0;
4928 cap->range.step = 1.0;
4932 cap->type = VAProcColorBalanceContrast;
4933 cap->range.min_value = 0.0;
4934 cap->range.max_value = 10.0;
4935 cap->range.default_value = 1.0;
4936 cap->range.step = 0.1;
4948 *num_filter_caps = i;
4950 return VA_STATUS_SUCCESS;
4953 static VAProcColorStandardType vpp_input_color_standards[VAProcColorStandardCount] = {
4954 VAProcColorStandardBT601,
4957 static VAProcColorStandardType vpp_output_color_standards[VAProcColorStandardCount] = {
4958 VAProcColorStandardBT601,
4961 VAStatus i965_QueryVideoProcPipelineCaps(
4962 VADriverContextP ctx,
4963 VAContextID context,
4964 VABufferID *filters,
4965 unsigned int num_filters,
4966 VAProcPipelineCaps *pipeline_cap /* out */
4969 struct i965_driver_data * const i965 = i965_driver_data(ctx);
4972 pipeline_cap->pipeline_flags = 0;
4973 pipeline_cap->filter_flags = 0;
4974 pipeline_cap->num_forward_references = 0;
4975 pipeline_cap->num_backward_references = 0;
4976 pipeline_cap->num_input_color_standards = 1;
4977 pipeline_cap->input_color_standards = vpp_input_color_standards;
4978 pipeline_cap->num_output_color_standards = 1;
4979 pipeline_cap->output_color_standards = vpp_output_color_standards;
4981 for (i = 0; i < num_filters; i++) {
4982 struct object_buffer *obj_buffer = BUFFER(filters[i]);
4985 !obj_buffer->buffer_store ||
4986 !obj_buffer->buffer_store->buffer)
4987 return VA_STATUS_ERROR_INVALID_BUFFER;
4989 VAProcFilterParameterBufferBase *base = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
4991 if (base->type == VAProcFilterNoiseReduction) {
4992 VAProcFilterParameterBuffer *denoise = (VAProcFilterParameterBuffer *)base;
4994 } else if (base->type == VAProcFilterDeinterlacing) {
4995 VAProcFilterParameterBufferDeinterlacing *deint = (VAProcFilterParameterBufferDeinterlacing *)base;
4997 assert(deint->algorithm == VAProcDeinterlacingBob ||
4998 deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
4999 deint->algorithm == VAProcDeinterlacingMotionCompensated);
5001 if (deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
5002 deint->algorithm == VAProcDeinterlacingMotionCompensated);
5003 pipeline_cap->num_forward_references++;
5007 return VA_STATUS_SUCCESS;
5011 i965_driver_data_init(VADriverContextP ctx)
5013 struct i965_driver_data *i965 = i965_driver_data(ctx);
5015 if (IS_GEN8(i965->intel.device_id))
5016 i965->codec_info = &gen8_hw_codec_info;
5017 else if (IS_HASWELL(i965->intel.device_id))
5018 i965->codec_info = &gen75_hw_codec_info;
5019 else if (IS_G4X(i965->intel.device_id))
5020 i965->codec_info = &g4x_hw_codec_info;
5021 else if (IS_IRONLAKE(i965->intel.device_id))
5022 i965->codec_info = &ironlake_hw_codec_info;
5023 else if (IS_GEN6(i965->intel.device_id))
5024 i965->codec_info = &gen6_hw_codec_info;
5025 else if (IS_GEN7(i965->intel.device_id))
5026 i965->codec_info = &gen7_hw_codec_info;
5030 if (object_heap_init(&i965->config_heap,
5031 sizeof(struct object_config),
5033 goto err_config_heap;
5034 if (object_heap_init(&i965->context_heap,
5035 sizeof(struct object_context),
5037 goto err_context_heap;
5039 if (object_heap_init(&i965->surface_heap,
5040 sizeof(struct object_surface),
5042 goto err_surface_heap;
5043 if (object_heap_init(&i965->buffer_heap,
5044 sizeof(struct object_buffer),
5046 goto err_buffer_heap;
5047 if (object_heap_init(&i965->image_heap,
5048 sizeof(struct object_image),
5050 goto err_image_heap;
5051 if (object_heap_init(&i965->subpic_heap,
5052 sizeof(struct object_subpic),
5054 goto err_subpic_heap;
5056 i965->batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
5057 i965->pp_batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
5058 _i965InitMutex(&i965->render_mutex);
5059 _i965InitMutex(&i965->pp_mutex);
5064 object_heap_destroy(&i965->image_heap);
5066 object_heap_destroy(&i965->buffer_heap);
5068 object_heap_destroy(&i965->surface_heap);
5070 object_heap_destroy(&i965->context_heap);
5072 object_heap_destroy(&i965->config_heap);
5079 i965_driver_data_terminate(VADriverContextP ctx)
5081 struct i965_driver_data *i965 = i965_driver_data(ctx);
5083 _i965DestroyMutex(&i965->pp_mutex);
5084 _i965DestroyMutex(&i965->render_mutex);
5087 intel_batchbuffer_free(i965->batch);
5090 intel_batchbuffer_free(i965->pp_batch);
5092 i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
5093 i965_destroy_heap(&i965->image_heap, i965_destroy_image);
5094 i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
5095 i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
5096 i965_destroy_heap(&i965->context_heap, i965_destroy_context);
5097 i965_destroy_heap(&i965->config_heap, i965_destroy_config);
5101 bool (*init)(VADriverContextP ctx);
5102 void (*terminate)(VADriverContextP ctx);
5104 } i965_sub_ops[] = {
5107 intel_driver_terminate,
5112 i965_driver_data_init,
5113 i965_driver_data_terminate,
5118 i965_display_attributes_init,
5119 i965_display_attributes_terminate,
5124 i965_post_processing_init,
5125 i965_post_processing_terminate,
5131 i965_render_terminate,
5135 #ifdef HAVE_VA_WAYLAND
5137 i965_output_wayland_init,
5138 i965_output_wayland_terminate,
5145 i965_output_dri_init,
5146 i965_output_dri_terminate,
5153 i965_Init(VADriverContextP ctx)
5155 struct i965_driver_data *i965 = i965_driver_data(ctx);
5158 for (i = 0; i < ARRAY_ELEMS(i965_sub_ops); i++) {
5159 if ((i965_sub_ops[i].display_type == 0 ||
5160 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) &&
5161 !i965_sub_ops[i].init(ctx))
5165 if (i == ARRAY_ELEMS(i965_sub_ops)) {
5166 sprintf(i965->va_vendor, "%s %s driver - %d.%d.%d",
5167 INTEL_STR_DRIVER_VENDOR,
5168 INTEL_STR_DRIVER_NAME,
5169 INTEL_DRIVER_MAJOR_VERSION,
5170 INTEL_DRIVER_MINOR_VERSION,
5171 INTEL_DRIVER_MICRO_VERSION);
5173 if (INTEL_DRIVER_PRE_VERSION > 0) {
5174 const int len = strlen(i965->va_vendor);
5175 sprintf(&i965->va_vendor[len], ".pre%d", INTEL_DRIVER_PRE_VERSION);
5178 i965->current_context_id = VA_INVALID_ID;
5180 return VA_STATUS_SUCCESS;
5184 for (; i >= 0; i--) {
5185 if (i965_sub_ops[i].display_type == 0 ||
5186 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
5187 i965_sub_ops[i].terminate(ctx);
5191 return VA_STATUS_ERROR_UNKNOWN;
5196 i965_Terminate(VADriverContextP ctx)
5198 struct i965_driver_data *i965 = i965_driver_data(ctx);
5202 for (i = ARRAY_ELEMS(i965_sub_ops); i > 0; i--)
5203 if (i965_sub_ops[i - 1].display_type == 0 ||
5204 i965_sub_ops[i - 1].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
5205 i965_sub_ops[i - 1].terminate(ctx);
5209 ctx->pDriverData = NULL;
5212 return VA_STATUS_SUCCESS;
5216 VA_DRIVER_INIT_FUNC(VADriverContextP ctx);
5219 VA_DRIVER_INIT_FUNC( VADriverContextP ctx )
5221 struct VADriverVTable * const vtable = ctx->vtable;
5222 struct VADriverVTableVPP * const vtable_vpp = ctx->vtable_vpp;
5224 struct i965_driver_data *i965;
5225 VAStatus ret = VA_STATUS_ERROR_UNKNOWN;
5227 ctx->version_major = VA_MAJOR_VERSION;
5228 ctx->version_minor = VA_MINOR_VERSION;
5229 ctx->max_profiles = I965_MAX_PROFILES;
5230 ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
5231 ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
5232 ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
5233 ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
5234 ctx->max_display_attributes = 1 + ARRAY_ELEMS(i965_display_attributes);
5236 vtable->vaTerminate = i965_Terminate;
5237 vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
5238 vtable->vaQueryConfigProfiles = i965_QueryConfigProfiles;
5239 vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
5240 vtable->vaQueryConfigAttributes = i965_QueryConfigAttributes;
5241 vtable->vaCreateConfig = i965_CreateConfig;
5242 vtable->vaDestroyConfig = i965_DestroyConfig;
5243 vtable->vaGetConfigAttributes = i965_GetConfigAttributes;
5244 vtable->vaCreateSurfaces = i965_CreateSurfaces;
5245 vtable->vaDestroySurfaces = i965_DestroySurfaces;
5246 vtable->vaCreateContext = i965_CreateContext;
5247 vtable->vaDestroyContext = i965_DestroyContext;
5248 vtable->vaCreateBuffer = i965_CreateBuffer;
5249 vtable->vaBufferSetNumElements = i965_BufferSetNumElements;
5250 vtable->vaMapBuffer = i965_MapBuffer;
5251 vtable->vaUnmapBuffer = i965_UnmapBuffer;
5252 vtable->vaDestroyBuffer = i965_DestroyBuffer;
5253 vtable->vaBeginPicture = i965_BeginPicture;
5254 vtable->vaRenderPicture = i965_RenderPicture;
5255 vtable->vaEndPicture = i965_EndPicture;
5256 vtable->vaSyncSurface = i965_SyncSurface;
5257 vtable->vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
5258 vtable->vaPutSurface = i965_PutSurface;
5259 vtable->vaQueryImageFormats = i965_QueryImageFormats;
5260 vtable->vaCreateImage = i965_CreateImage;
5261 vtable->vaDeriveImage = i965_DeriveImage;
5262 vtable->vaDestroyImage = i965_DestroyImage;
5263 vtable->vaSetImagePalette = i965_SetImagePalette;
5264 vtable->vaGetImage = i965_GetImage;
5265 vtable->vaPutImage = i965_PutImage;
5266 vtable->vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
5267 vtable->vaCreateSubpicture = i965_CreateSubpicture;
5268 vtable->vaDestroySubpicture = i965_DestroySubpicture;
5269 vtable->vaSetSubpictureImage = i965_SetSubpictureImage;
5270 vtable->vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
5271 vtable->vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
5272 vtable->vaAssociateSubpicture = i965_AssociateSubpicture;
5273 vtable->vaDeassociateSubpicture = i965_DeassociateSubpicture;
5274 vtable->vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
5275 vtable->vaGetDisplayAttributes = i965_GetDisplayAttributes;
5276 vtable->vaSetDisplayAttributes = i965_SetDisplayAttributes;
5277 vtable->vaBufferInfo = i965_BufferInfo;
5278 vtable->vaLockSurface = i965_LockSurface;
5279 vtable->vaUnlockSurface = i965_UnlockSurface;
5280 vtable->vaGetSurfaceAttributes = i965_GetSurfaceAttributes;
5281 vtable->vaQuerySurfaceAttributes = i965_QuerySurfaceAttributes;
5282 vtable->vaCreateSurfaces2 = i965_CreateSurfaces2;
5284 vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters;
5285 vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps;
5286 vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;
5288 i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
5291 ctx->pDriverData = NULL;
5293 return VA_STATUS_ERROR_ALLOCATION_FAILED;
5296 ctx->pDriverData = (void *)i965;
5297 ret = i965_Init(ctx);
5299 if (ret == VA_STATUS_SUCCESS) {
5300 ctx->str_vendor = i965->va_vendor;
5303 ctx->pDriverData = NULL;