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_YV12, VA_LSB_FIRST, 12, } },
147 { I965_SURFACETYPE_YUV,
148 { VA_FOURCC_I420, VA_LSB_FIRST, 12, } },
149 { I965_SURFACETYPE_YUV,
150 { VA_FOURCC_NV12, VA_LSB_FIRST, 12, } },
151 { I965_SURFACETYPE_YUV,
152 { VA_FOURCC_YUY2, VA_LSB_FIRST, 16, } },
153 { I965_SURFACETYPE_YUV,
154 { VA_FOURCC_UYVY, VA_LSB_FIRST, 16, } },
155 { I965_SURFACETYPE_YUV,
156 { VA_FOURCC_422H, VA_LSB_FIRST, 16, } },
157 { I965_SURFACETYPE_RGBA,
158 { VA_FOURCC_RGBX, VA_LSB_FIRST, 32, 24, 0x000000ff, 0x0000ff00, 0x00ff0000 } },
159 { I965_SURFACETYPE_RGBA,
160 { VA_FOURCC_BGRX, VA_LSB_FIRST, 32, 24, 0x00ff0000, 0x0000ff00, 0x000000ff } },
163 /* List of supported subpicture formats */
167 VAImageFormat va_format;
168 unsigned int va_flags;
169 } i965_subpic_format_map_t;
171 #define COMMON_SUBPICTURE_FLAGS \
172 (VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD| \
173 VA_SUBPICTURE_GLOBAL_ALPHA)
175 static const i965_subpic_format_map_t
176 i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
177 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
178 { VA_FOURCC_IA44, VA_MSB_FIRST, 8, },
179 COMMON_SUBPICTURE_FLAGS },
180 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
181 { VA_FOURCC_AI44, VA_MSB_FIRST, 8, },
182 COMMON_SUBPICTURE_FLAGS },
183 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P8A8_UNORM,
184 { VA_FOURCC_IA88, VA_MSB_FIRST, 16, },
185 COMMON_SUBPICTURE_FLAGS },
186 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A8P8_UNORM,
187 { VA_FOURCC_AI88, VA_MSB_FIRST, 16, },
188 COMMON_SUBPICTURE_FLAGS },
189 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_B8G8R8A8_UNORM,
190 { VA_FOURCC_BGRA, VA_LSB_FIRST, 32,
191 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
192 COMMON_SUBPICTURE_FLAGS },
193 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_R8G8B8A8_UNORM,
194 { VA_FOURCC_RGBA, VA_LSB_FIRST, 32,
195 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
196 COMMON_SUBPICTURE_FLAGS },
199 static const i965_subpic_format_map_t *
200 get_subpic_format(const VAImageFormat *va_format)
203 for (i = 0; i965_subpic_formats_map[i].type != 0; i++) {
204 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
205 if (m->va_format.fourcc == va_format->fourcc &&
206 (m->type == I965_SURFACETYPE_RGBA ?
207 (m->va_format.byte_order == va_format->byte_order &&
208 m->va_format.red_mask == va_format->red_mask &&
209 m->va_format.green_mask == va_format->green_mask &&
210 m->va_format.blue_mask == va_format->blue_mask &&
211 m->va_format.alpha_mask == va_format->alpha_mask) : 1))
217 #define I965_PACKED_HEADER_BASE 0
218 #define I965_PACKED_MISC_HEADER_BASE 3
221 va_enc_packed_type_to_idx(int packed_type)
225 if (packed_type & VAEncPackedHeaderMiscMask) {
226 idx = I965_PACKED_MISC_HEADER_BASE;
227 packed_type = (~VAEncPackedHeaderMiscMask & packed_type);
228 ASSERT_RET(packed_type > 0, 0);
229 idx += (packed_type - 1);
231 idx = I965_PACKED_HEADER_BASE;
233 switch (packed_type) {
234 case VAEncPackedHeaderSequence:
235 idx = I965_PACKED_HEADER_BASE + 0;
238 case VAEncPackedHeaderPicture:
239 idx = I965_PACKED_HEADER_BASE + 1;
242 case VAEncPackedHeaderSlice:
243 idx = I965_PACKED_HEADER_BASE + 2;
247 /* Should not get here */
253 ASSERT_RET(idx < 4, 0);
258 i965_QueryConfigProfiles(VADriverContextP ctx,
259 VAProfile *profile_list, /* out */
260 int *num_profiles) /* out */
262 struct i965_driver_data * const i965 = i965_driver_data(ctx);
265 if (HAS_MPEG2_DECODING(i965) ||
266 HAS_MPEG2_ENCODING(i965)) {
267 profile_list[i++] = VAProfileMPEG2Simple;
268 profile_list[i++] = VAProfileMPEG2Main;
271 if (HAS_H264_DECODING(i965) ||
272 HAS_H264_ENCODING(i965)) {
273 profile_list[i++] = VAProfileH264ConstrainedBaseline;
274 profile_list[i++] = VAProfileH264Main;
275 profile_list[i++] = VAProfileH264High;
278 if (HAS_VC1_DECODING(i965)) {
279 profile_list[i++] = VAProfileVC1Simple;
280 profile_list[i++] = VAProfileVC1Main;
281 profile_list[i++] = VAProfileVC1Advanced;
285 profile_list[i++] = VAProfileNone;
288 if (HAS_JPEG_DECODING(i965)) {
289 profile_list[i++] = VAProfileJPEGBaseline;
292 if (HAS_VP8_DECODING(i965) ||
293 HAS_VP8_ENCODING(i965)) {
294 profile_list[i++] = VAProfileVP8Version0_3;
297 /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
298 ASSERT_RET(i <= I965_MAX_PROFILES, VA_STATUS_ERROR_OPERATION_FAILED);
301 return VA_STATUS_SUCCESS;
305 i965_QueryConfigEntrypoints(VADriverContextP ctx,
307 VAEntrypoint *entrypoint_list, /* out */
308 int *num_entrypoints) /* out */
310 struct i965_driver_data * const i965 = i965_driver_data(ctx);
314 case VAProfileMPEG2Simple:
315 case VAProfileMPEG2Main:
316 if (HAS_MPEG2_DECODING(i965))
317 entrypoint_list[n++] = VAEntrypointVLD;
319 if (HAS_MPEG2_ENCODING(i965))
320 entrypoint_list[n++] = VAEntrypointEncSlice;
324 case VAProfileH264ConstrainedBaseline:
325 case VAProfileH264Main:
326 case VAProfileH264High:
327 if (HAS_H264_DECODING(i965))
328 entrypoint_list[n++] = VAEntrypointVLD;
330 if (HAS_H264_ENCODING(i965))
331 entrypoint_list[n++] = VAEntrypointEncSlice;
335 case VAProfileVC1Simple:
336 case VAProfileVC1Main:
337 case VAProfileVC1Advanced:
338 if (HAS_VC1_DECODING(i965))
339 entrypoint_list[n++] = VAEntrypointVLD;
344 entrypoint_list[n++] = VAEntrypointVideoProc;
347 case VAProfileJPEGBaseline:
348 if (HAS_JPEG_DECODING(i965))
349 entrypoint_list[n++] = VAEntrypointVLD;
352 case VAProfileVP8Version0_3:
353 if (HAS_VP8_DECODING(i965))
354 entrypoint_list[n++] = VAEntrypointVLD;
356 if (HAS_VP8_ENCODING(i965))
357 entrypoint_list[n++] = VAEntrypointEncSlice;
363 /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
364 ASSERT_RET(n <= I965_MAX_ENTRYPOINTS, VA_STATUS_ERROR_OPERATION_FAILED);
365 *num_entrypoints = n;
366 return n > 0 ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
370 i965_validate_config(VADriverContextP ctx, VAProfile profile,
371 VAEntrypoint entrypoint)
373 struct i965_driver_data * const i965 = i965_driver_data(ctx);
376 /* Validate profile & entrypoint */
378 case VAProfileMPEG2Simple:
379 case VAProfileMPEG2Main:
380 if ((HAS_MPEG2_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
381 (HAS_MPEG2_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
382 va_status = VA_STATUS_SUCCESS;
384 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
388 case VAProfileH264ConstrainedBaseline:
389 case VAProfileH264Main:
390 case VAProfileH264High:
391 if ((HAS_H264_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
392 (HAS_H264_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
393 va_status = VA_STATUS_SUCCESS;
395 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
399 case VAProfileVC1Simple:
400 case VAProfileVC1Main:
401 case VAProfileVC1Advanced:
402 if (HAS_VC1_DECODING(i965) && entrypoint == VAEntrypointVLD) {
403 va_status = VA_STATUS_SUCCESS;
405 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
410 if (HAS_VPP(i965) && VAEntrypointVideoProc == entrypoint) {
411 va_status = VA_STATUS_SUCCESS;
413 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
417 case VAProfileJPEGBaseline:
418 if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) {
419 va_status = VA_STATUS_SUCCESS;
421 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
425 case VAProfileVP8Version0_3:
426 if ((HAS_VP8_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
427 (HAS_VP8_ENCODING(i965) && entrypoint == VAEntrypointEncSlice)) {
428 va_status = VA_STATUS_SUCCESS;
430 va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
435 va_status = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
442 i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
443 VAEntrypoint entrypoint)
445 struct i965_driver_data * const i965 = i965_driver_data(ctx);
446 uint32_t chroma_formats = VA_RT_FORMAT_YUV420;
452 return chroma_formats;
456 i965_GetConfigAttributes(VADriverContextP ctx,
458 VAEntrypoint entrypoint,
459 VAConfigAttrib *attrib_list, /* in/out */
465 va_status = i965_validate_config(ctx, profile, entrypoint);
466 if (va_status != VA_STATUS_SUCCESS)
469 /* Other attributes don't seem to be defined */
470 /* What to do if we don't know the attribute? */
471 for (i = 0; i < num_attribs; i++) {
472 switch (attrib_list[i].type) {
473 case VAConfigAttribRTFormat:
474 attrib_list[i].value = i965_get_default_chroma_formats(ctx,
475 profile, entrypoint);
478 case VAConfigAttribRateControl:
479 if (entrypoint == VAEntrypointEncSlice) {
480 attrib_list[i].value = VA_RC_CQP;
482 if (profile != VAProfileMPEG2Main &&
483 profile != VAProfileMPEG2Simple)
484 attrib_list[i].value |= VA_RC_CBR;
488 case VAConfigAttribEncPackedHeaders:
489 if (entrypoint == VAEntrypointEncSlice) {
490 attrib_list[i].value = VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_PICTURE | VA_ENC_PACKED_HEADER_MISC;
494 case VAConfigAttribEncMaxRefFrames:
495 if (entrypoint == VAEntrypointEncSlice) {
496 attrib_list[i].value = (1 << 16) | (1 << 0);
502 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
507 return VA_STATUS_SUCCESS;
511 i965_destroy_config(struct object_heap *heap, struct object_base *obj)
513 object_heap_free(heap, obj);
516 static VAConfigAttrib *
517 i965_lookup_config_attribute(struct object_config *obj_config,
518 VAConfigAttribType type)
522 for (i = 0; i < obj_config->num_attribs; i++) {
523 VAConfigAttrib * const attrib = &obj_config->attrib_list[i];
524 if (attrib->type == type)
531 i965_append_config_attribute(struct object_config *obj_config,
532 const VAConfigAttrib *new_attrib)
534 VAConfigAttrib *attrib;
536 if (obj_config->num_attribs >= I965_MAX_CONFIG_ATTRIBUTES)
537 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
539 attrib = &obj_config->attrib_list[obj_config->num_attribs++];
540 attrib->type = new_attrib->type;
541 attrib->value = new_attrib->value;
542 return VA_STATUS_SUCCESS;
546 i965_ensure_config_attribute(struct object_config *obj_config,
547 const VAConfigAttrib *new_attrib)
549 VAConfigAttrib *attrib;
551 /* Check for existing attributes */
552 attrib = i965_lookup_config_attribute(obj_config, new_attrib->type);
554 /* Update existing attribute */
555 attrib->value = new_attrib->value;
556 return VA_STATUS_SUCCESS;
558 return i965_append_config_attribute(obj_config, new_attrib);
562 i965_CreateConfig(VADriverContextP ctx,
564 VAEntrypoint entrypoint,
565 VAConfigAttrib *attrib_list,
567 VAConfigID *config_id) /* out */
569 struct i965_driver_data * const i965 = i965_driver_data(ctx);
570 struct object_config *obj_config;
575 vaStatus = i965_validate_config(ctx, profile, entrypoint);
576 if (VA_STATUS_SUCCESS != vaStatus) {
580 configID = NEW_CONFIG_ID();
581 obj_config = CONFIG(configID);
583 if (NULL == obj_config) {
584 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
588 obj_config->profile = profile;
589 obj_config->entrypoint = entrypoint;
590 obj_config->num_attribs = 0;
592 for (i = 0; i < num_attribs; i++) {
593 vaStatus = i965_ensure_config_attribute(obj_config, &attrib_list[i]);
594 if (vaStatus != VA_STATUS_SUCCESS)
598 if (vaStatus == VA_STATUS_SUCCESS) {
599 VAConfigAttrib attrib, *attrib_found;
600 attrib.type = VAConfigAttribRTFormat;
601 attrib.value = i965_get_default_chroma_formats(ctx, profile, entrypoint);
602 attrib_found = i965_lookup_config_attribute(obj_config, attrib.type);
603 if (!attrib_found || !attrib_found->value)
604 vaStatus = i965_append_config_attribute(obj_config, &attrib);
605 else if (!(attrib_found->value & attrib.value))
606 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
610 if (VA_STATUS_SUCCESS != vaStatus) {
611 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
613 *config_id = configID;
620 i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
622 struct i965_driver_data *i965 = i965_driver_data(ctx);
623 struct object_config *obj_config = CONFIG(config_id);
626 if (NULL == obj_config) {
627 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
631 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
632 return VA_STATUS_SUCCESS;
635 VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
636 VAConfigID config_id,
637 VAProfile *profile, /* out */
638 VAEntrypoint *entrypoint, /* out */
639 VAConfigAttrib *attrib_list, /* out */
640 int *num_attribs) /* out */
642 struct i965_driver_data *i965 = i965_driver_data(ctx);
643 struct object_config *obj_config = CONFIG(config_id);
644 VAStatus vaStatus = VA_STATUS_SUCCESS;
647 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
648 *profile = obj_config->profile;
649 *entrypoint = obj_config->entrypoint;
650 *num_attribs = obj_config->num_attribs;
652 for(i = 0; i < obj_config->num_attribs; i++) {
653 attrib_list[i] = obj_config->attrib_list[i];
660 i965_destroy_surface_storage(struct object_surface *obj_surface)
665 dri_bo_unreference(obj_surface->bo);
666 obj_surface->bo = NULL;
668 if (obj_surface->free_private_data != NULL) {
669 obj_surface->free_private_data(&obj_surface->private_data);
670 obj_surface->private_data = NULL;
675 i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
677 struct object_surface *obj_surface = (struct object_surface *)obj;
679 i965_destroy_surface_storage(obj_surface);
680 object_heap_free(heap, obj);
684 i965_surface_native_memory(VADriverContextP ctx,
685 struct object_surface *obj_surface,
689 struct i965_driver_data *i965 = i965_driver_data(ctx);
690 int tiling = HAS_TILED_SURFACE(i965);
692 if (!expected_fourcc)
693 return VA_STATUS_SUCCESS;
695 // todo, should we disable tiling for 422 format?
696 if (expected_fourcc == VA_FOURCC_I420 ||
697 expected_fourcc == VA_FOURCC_IYUV ||
698 expected_fourcc == VA_FOURCC_YV12 ||
699 expected_fourcc == VA_FOURCC_YV16)
702 i965_check_alloc_surface_bo(ctx, obj_surface, tiling, expected_fourcc, get_sampling_from_fourcc(expected_fourcc));
704 return VA_STATUS_SUCCESS;
708 i965_suface_external_memory(VADriverContextP ctx,
709 struct object_surface *obj_surface,
710 int external_memory_type,
711 VASurfaceAttribExternalBuffers *memory_attibute,
714 struct i965_driver_data *i965 = i965_driver_data(ctx);
716 if (!memory_attibute ||
717 !memory_attibute->buffers ||
718 index > memory_attibute->num_buffers)
719 return VA_STATUS_ERROR_INVALID_PARAMETER;
721 ASSERT_RET(obj_surface->orig_width == memory_attibute->width, VA_STATUS_ERROR_INVALID_PARAMETER);
722 ASSERT_RET(obj_surface->orig_height == memory_attibute->height, VA_STATUS_ERROR_INVALID_PARAMETER);
723 ASSERT_RET(memory_attibute->num_planes >= 1, VA_STATUS_ERROR_INVALID_PARAMETER);
725 obj_surface->fourcc = memory_attibute->pixel_format;
726 obj_surface->width = memory_attibute->pitches[0];
727 obj_surface->size = memory_attibute->data_size;
729 if (memory_attibute->num_planes == 1)
730 obj_surface->height = memory_attibute->data_size / obj_surface->width;
732 obj_surface->height = memory_attibute->offsets[1] / obj_surface->width;
734 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
735 obj_surface->x_cr_offset = 0;
737 switch (obj_surface->fourcc) {
739 ASSERT_RET(memory_attibute->num_planes == 2, VA_STATUS_ERROR_INVALID_PARAMETER);
740 ASSERT_RET(memory_attibute->pitches[0] == memory_attibute->pitches[1], VA_STATUS_ERROR_INVALID_PARAMETER);
742 obj_surface->subsampling = SUBSAMPLE_YUV420;
743 obj_surface->y_cb_offset = obj_surface->height;
744 obj_surface->y_cr_offset = obj_surface->height;
745 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
746 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
747 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
753 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
754 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
756 obj_surface->subsampling = SUBSAMPLE_YUV420;
757 obj_surface->y_cr_offset = obj_surface->height;
758 obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
759 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
760 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
761 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
768 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
769 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
771 obj_surface->subsampling = SUBSAMPLE_YUV420;
772 obj_surface->y_cb_offset = obj_surface->height;
773 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
774 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
775 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
776 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
782 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
784 obj_surface->subsampling = SUBSAMPLE_YUV422H;
785 obj_surface->y_cb_offset = 0;
786 obj_surface->y_cr_offset = 0;
787 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
788 obj_surface->cb_cr_height = obj_surface->orig_height;
789 obj_surface->cb_cr_pitch = memory_attibute->pitches[0];
797 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
799 obj_surface->subsampling = SUBSAMPLE_RGBX;
800 obj_surface->y_cb_offset = 0;
801 obj_surface->y_cr_offset = 0;
802 obj_surface->cb_cr_width = 0;
803 obj_surface->cb_cr_height = 0;
804 obj_surface->cb_cr_pitch = 0;
808 case VA_FOURCC_Y800: /* monochrome surface */
809 ASSERT_RET(memory_attibute->num_planes == 1, VA_STATUS_ERROR_INVALID_PARAMETER);
811 obj_surface->subsampling = SUBSAMPLE_YUV400;
812 obj_surface->y_cb_offset = 0;
813 obj_surface->y_cr_offset = 0;
814 obj_surface->cb_cr_width = 0;
815 obj_surface->cb_cr_height = 0;
816 obj_surface->cb_cr_pitch = 0;
821 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
822 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
824 obj_surface->subsampling = SUBSAMPLE_YUV411;
825 obj_surface->y_cb_offset = 0;
826 obj_surface->y_cr_offset = 0;
827 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
828 obj_surface->cb_cr_height = obj_surface->orig_height;
829 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
834 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
835 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
837 obj_surface->subsampling = SUBSAMPLE_YUV422H;
838 obj_surface->y_cb_offset = obj_surface->height;
839 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
840 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
841 obj_surface->cb_cr_height = obj_surface->orig_height;
842 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
847 assert(memory_attibute->num_planes == 3);
848 assert(memory_attibute->pitches[1] == memory_attibute->pitches[2]);
850 obj_surface->subsampling = SUBSAMPLE_YUV422H;
851 obj_surface->y_cr_offset = memory_attibute->offsets[1] / obj_surface->width;
852 obj_surface->y_cb_offset = memory_attibute->offsets[2] / obj_surface->width;
853 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
854 obj_surface->cb_cr_height = obj_surface->orig_height;
855 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
860 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
861 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
863 obj_surface->subsampling = SUBSAMPLE_YUV422H;
864 obj_surface->y_cb_offset = obj_surface->height;
865 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
866 obj_surface->cb_cr_width = obj_surface->orig_width;
867 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
868 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
873 ASSERT_RET(memory_attibute->num_planes == 3, VA_STATUS_ERROR_INVALID_PARAMETER);
874 ASSERT_RET(memory_attibute->pitches[1] == memory_attibute->pitches[2], VA_STATUS_ERROR_INVALID_PARAMETER);
876 obj_surface->subsampling = SUBSAMPLE_YUV444;
877 obj_surface->y_cb_offset = obj_surface->height;
878 obj_surface->y_cr_offset = memory_attibute->offsets[2] / obj_surface->width;
879 obj_surface->cb_cr_width = obj_surface->orig_width;
880 obj_surface->cb_cr_height = obj_surface->orig_height;
881 obj_surface->cb_cr_pitch = memory_attibute->pitches[1];
887 return VA_STATUS_ERROR_INVALID_PARAMETER;
890 if (external_memory_type == I965_SURFACE_MEM_GEM_FLINK)
891 obj_surface->bo = drm_intel_bo_gem_create_from_name(i965->intel.bufmgr,
892 "gem flinked vaapi surface",
893 memory_attibute->buffers[index]);
894 else if (external_memory_type == I965_SURFACE_MEM_DRM_PRIME)
895 obj_surface->bo = drm_intel_bo_gem_create_from_prime(i965->intel.bufmgr,
896 memory_attibute->buffers[index],
899 if (!obj_surface->bo)
900 return VA_STATUS_ERROR_INVALID_PARAMETER;
902 return VA_STATUS_SUCCESS;
905 /* byte-per-pixel of the first plane */
907 bpp_1stplane_by_fourcc(unsigned int fourcc)
941 i965_CreateSurfaces2(
942 VADriverContextP ctx,
946 VASurfaceID *surfaces,
947 unsigned int num_surfaces,
948 VASurfaceAttrib *attrib_list,
949 unsigned int num_attribs
952 struct i965_driver_data *i965 = i965_driver_data(ctx);
954 VAStatus vaStatus = VA_STATUS_SUCCESS;
955 int expected_fourcc = 0;
956 int memory_type = I965_SURFACE_MEM_NATIVE; /* native */
957 VASurfaceAttribExternalBuffers *memory_attibute = NULL;
959 for (i = 0; i < num_attribs && attrib_list; i++) {
960 if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
961 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
962 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
963 expected_fourcc = attrib_list[i].value.value.i;
966 if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&
967 (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
969 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypeInteger, VA_STATUS_ERROR_INVALID_PARAMETER);
971 if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM)
972 memory_type = I965_SURFACE_MEM_GEM_FLINK; /* flinked GEM handle */
973 else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME)
974 memory_type = I965_SURFACE_MEM_DRM_PRIME; /* drm prime fd */
975 else if (attrib_list[i].value.value.i == VA_SURFACE_ATTRIB_MEM_TYPE_VA)
976 memory_type = I965_SURFACE_MEM_NATIVE; /* va native memory, to be allocated */
979 if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&
980 (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {
981 ASSERT_RET(attrib_list[i].value.type == VAGenericValueTypePointer, VA_STATUS_ERROR_INVALID_PARAMETER);
982 memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;
986 /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used
987 * for post-processing (including color conversion) */
988 if (VA_RT_FORMAT_YUV420 != format &&
989 VA_RT_FORMAT_YUV422 != format &&
990 VA_RT_FORMAT_YUV444 != format &&
991 VA_RT_FORMAT_YUV411 != format &&
992 VA_RT_FORMAT_YUV400 != format &&
993 VA_RT_FORMAT_RGB32 != format) {
994 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
997 for (i = 0; i < num_surfaces; i++) {
998 int surfaceID = NEW_SURFACE_ID();
999 struct object_surface *obj_surface = SURFACE(surfaceID);
1001 if (NULL == obj_surface) {
1002 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1006 surfaces[i] = surfaceID;
1007 obj_surface->status = VASurfaceReady;
1008 obj_surface->orig_width = width;
1009 obj_surface->orig_height = height;
1010 obj_surface->user_disable_tiling = false;
1011 obj_surface->user_h_stride_set = false;
1012 obj_surface->user_v_stride_set = false;
1014 obj_surface->subpic_render_idx = 0;
1015 for(j = 0; j < I965_MAX_SUBPIC_SUM; j++){
1016 obj_surface->subpic[j] = VA_INVALID_ID;
1017 obj_surface->obj_subpic[j] = NULL;
1020 assert(i965->codec_info->min_linear_wpitch);
1021 assert(i965->codec_info->min_linear_hpitch);
1022 obj_surface->width = ALIGN(width, i965->codec_info->min_linear_wpitch);
1023 obj_surface->height = ALIGN(height, i965->codec_info->min_linear_hpitch);
1024 obj_surface->flags = SURFACE_REFERENCED;
1025 obj_surface->fourcc = 0;
1026 obj_surface->bo = NULL;
1027 obj_surface->locked_image_id = VA_INVALID_ID;
1028 obj_surface->private_data = NULL;
1029 obj_surface->free_private_data = NULL;
1030 obj_surface->subsampling = SUBSAMPLE_YUV420;
1032 switch (memory_type) {
1033 case I965_SURFACE_MEM_NATIVE:
1034 if (memory_attibute) {
1035 if (!(memory_attibute->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING))
1036 obj_surface->user_disable_tiling = true;
1038 if (memory_attibute->pixel_format) {
1039 if (expected_fourcc)
1040 ASSERT_RET(memory_attibute->pixel_format == expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1042 expected_fourcc = memory_attibute->pixel_format;
1044 ASSERT_RET(expected_fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
1045 if (memory_attibute->pitches[0]) {
1046 int bpp_1stplane = bpp_1stplane_by_fourcc(expected_fourcc);
1047 ASSERT_RET(bpp_1stplane, VA_STATUS_ERROR_INVALID_PARAMETER);
1048 obj_surface->width = memory_attibute->pitches[0]/bpp_1stplane;
1049 obj_surface->user_h_stride_set = true;
1050 ASSERT_RET(IS_ALIGNED(obj_surface->width, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1051 ASSERT_RET(obj_surface->width >= width, VA_STATUS_ERROR_INVALID_PARAMETER);
1053 if (memory_attibute->offsets[1]) {
1054 ASSERT_RET(!memory_attibute->offsets[0], VA_STATUS_ERROR_INVALID_PARAMETER);
1055 obj_surface->height = memory_attibute->offsets[1]/memory_attibute->pitches[0];
1056 obj_surface->user_v_stride_set = true;
1057 ASSERT_RET(IS_ALIGNED(obj_surface->height, 16), VA_STATUS_ERROR_INVALID_PARAMETER);
1058 ASSERT_RET(obj_surface->height >= height, VA_STATUS_ERROR_INVALID_PARAMETER);
1062 i965_surface_native_memory(ctx,
1068 case I965_SURFACE_MEM_GEM_FLINK:
1069 case I965_SURFACE_MEM_DRM_PRIME:
1070 i965_suface_external_memory(ctx,
1079 /* Error recovery */
1080 if (VA_STATUS_SUCCESS != vaStatus) {
1081 /* surfaces[i-1] was the last successful allocation */
1083 struct object_surface *obj_surface = SURFACE(surfaces[i]);
1085 surfaces[i] = VA_INVALID_SURFACE;
1086 assert(obj_surface);
1087 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1095 i965_CreateSurfaces(VADriverContextP ctx,
1100 VASurfaceID *surfaces) /* out */
1102 return i965_CreateSurfaces2(ctx,
1113 i965_DestroySurfaces(VADriverContextP ctx,
1114 VASurfaceID *surface_list,
1117 struct i965_driver_data *i965 = i965_driver_data(ctx);
1120 for (i = num_surfaces; i--; ) {
1121 struct object_surface *obj_surface = SURFACE(surface_list[i]);
1123 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
1124 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
1127 return VA_STATUS_SUCCESS;
1131 i965_QueryImageFormats(VADriverContextP ctx,
1132 VAImageFormat *format_list, /* out */
1133 int *num_formats) /* out */
1137 for (n = 0; i965_image_formats_map[n].va_format.fourcc != 0; n++) {
1138 const i965_image_format_map_t * const m = &i965_image_formats_map[n];
1140 format_list[n] = m->va_format;
1146 return VA_STATUS_SUCCESS;
1150 * Guess the format when the usage of a VA surface is unknown
1151 * 1. Without a valid context: YV12
1152 * 2. The current context is valid:
1153 * a) always NV12 on GEN6 and later
1154 * b) I420 for MPEG-2 and NV12 for other codec on GEN4 & GEN5
1157 i965_guess_surface_format(VADriverContextP ctx,
1158 VASurfaceID surface,
1159 unsigned int *fourcc,
1160 unsigned int *is_tiled)
1162 struct i965_driver_data *i965 = i965_driver_data(ctx);
1163 struct object_context *obj_context = NULL;
1164 struct object_config *obj_config = NULL;
1166 *fourcc = VA_FOURCC_YV12;
1169 if (i965->current_context_id == VA_INVALID_ID)
1172 obj_context = CONTEXT(i965->current_context_id);
1177 obj_config = obj_context->obj_config;
1183 if (IS_GEN6(i965->intel.device_info) ||
1184 IS_GEN7(i965->intel.device_info) ||
1185 IS_GEN8(i965->intel.device_info)) {
1186 *fourcc = VA_FOURCC_NV12;
1191 switch (obj_config->profile) {
1192 case VAProfileMPEG2Simple:
1193 case VAProfileMPEG2Main:
1194 *fourcc = VA_FOURCC_I420;
1199 *fourcc = VA_FOURCC_NV12;
1206 i965_QuerySubpictureFormats(VADriverContextP ctx,
1207 VAImageFormat *format_list, /* out */
1208 unsigned int *flags, /* out */
1209 unsigned int *num_formats) /* out */
1213 for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
1214 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
1216 format_list[n] = m->va_format;
1218 flags[n] = m->va_flags;
1224 return VA_STATUS_SUCCESS;
1228 i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
1230 // struct object_subpic *obj_subpic = (struct object_subpic *)obj;
1232 object_heap_free(heap, obj);
1236 i965_CreateSubpicture(VADriverContextP ctx,
1238 VASubpictureID *subpicture) /* out */
1240 struct i965_driver_data *i965 = i965_driver_data(ctx);
1241 VASubpictureID subpicID = NEW_SUBPIC_ID()
1242 struct object_subpic *obj_subpic = SUBPIC(subpicID);
1245 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1247 struct object_image *obj_image = IMAGE(image);
1249 return VA_STATUS_ERROR_INVALID_IMAGE;
1251 const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
1253 return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
1255 *subpicture = subpicID;
1256 obj_subpic->image = image;
1257 obj_subpic->obj_image = obj_image;
1258 obj_subpic->format = m->format;
1259 obj_subpic->width = obj_image->image.width;
1260 obj_subpic->height = obj_image->image.height;
1261 obj_subpic->pitch = obj_image->image.pitches[0];
1262 obj_subpic->bo = obj_image->bo;
1263 obj_subpic->global_alpha = 1.0;
1265 return VA_STATUS_SUCCESS;
1269 i965_DestroySubpicture(VADriverContextP ctx,
1270 VASubpictureID subpicture)
1272 struct i965_driver_data *i965 = i965_driver_data(ctx);
1273 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1276 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1278 ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
1279 i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
1280 return VA_STATUS_SUCCESS;
1284 i965_SetSubpictureImage(VADriverContextP ctx,
1285 VASubpictureID subpicture,
1289 return VA_STATUS_ERROR_UNIMPLEMENTED;
1293 i965_SetSubpictureChromakey(VADriverContextP ctx,
1294 VASubpictureID subpicture,
1295 unsigned int chromakey_min,
1296 unsigned int chromakey_max,
1297 unsigned int chromakey_mask)
1300 return VA_STATUS_ERROR_UNIMPLEMENTED;
1304 i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
1305 VASubpictureID subpicture,
1308 struct i965_driver_data *i965 = i965_driver_data(ctx);
1309 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1311 if(global_alpha > 1.0 || global_alpha < 0.0){
1312 return VA_STATUS_ERROR_INVALID_PARAMETER;
1316 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1318 obj_subpic->global_alpha = global_alpha;
1320 return VA_STATUS_SUCCESS;
1324 i965_AssociateSubpicture(VADriverContextP ctx,
1325 VASubpictureID subpicture,
1326 VASurfaceID *target_surfaces,
1328 short src_x, /* upper left offset in subpicture */
1330 unsigned short src_width,
1331 unsigned short src_height,
1332 short dest_x, /* upper left offset in surface */
1334 unsigned short dest_width,
1335 unsigned short dest_height,
1337 * whether to enable chroma-keying or global-alpha
1338 * see VA_SUBPICTURE_XXX values
1342 struct i965_driver_data *i965 = i965_driver_data(ctx);
1343 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1347 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1349 ASSERT_RET(obj_subpic->obj_image, VA_STATUS_ERROR_INVALID_SUBPICTURE);
1351 obj_subpic->src_rect.x = src_x;
1352 obj_subpic->src_rect.y = src_y;
1353 obj_subpic->src_rect.width = src_width;
1354 obj_subpic->src_rect.height = src_height;
1355 obj_subpic->dst_rect.x = dest_x;
1356 obj_subpic->dst_rect.y = dest_y;
1357 obj_subpic->dst_rect.width = dest_width;
1358 obj_subpic->dst_rect.height = dest_height;
1359 obj_subpic->flags = flags;
1361 for (i = 0; i < num_surfaces; i++) {
1362 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1364 return VA_STATUS_ERROR_INVALID_SURFACE;
1366 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1367 if(obj_surface->subpic[j] == VA_INVALID_ID){
1368 assert(obj_surface->obj_subpic[j] == NULL);
1369 obj_surface->subpic[j] = subpicture;
1370 obj_surface->obj_subpic[j] = obj_subpic;
1375 if(j == I965_MAX_SUBPIC_SUM){
1376 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1380 return VA_STATUS_SUCCESS;
1385 i965_DeassociateSubpicture(VADriverContextP ctx,
1386 VASubpictureID subpicture,
1387 VASurfaceID *target_surfaces,
1390 struct i965_driver_data *i965 = i965_driver_data(ctx);
1391 struct object_subpic *obj_subpic = SUBPIC(subpicture);
1395 return VA_STATUS_ERROR_INVALID_SUBPICTURE;
1397 for (i = 0; i < num_surfaces; i++) {
1398 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
1400 return VA_STATUS_ERROR_INVALID_SURFACE;
1402 for(j = 0; j < I965_MAX_SUBPIC_SUM; j ++){
1403 if (obj_surface->subpic[j] == subpicture) {
1404 assert(obj_surface->obj_subpic[j] == obj_subpic);
1405 obj_surface->subpic[j] = VA_INVALID_ID;
1406 obj_surface->obj_subpic[j] = NULL;
1411 if(j == I965_MAX_SUBPIC_SUM){
1412 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1415 return VA_STATUS_SUCCESS;
1419 i965_reference_buffer_store(struct buffer_store **ptr,
1420 struct buffer_store *buffer_store)
1422 assert(*ptr == NULL);
1425 buffer_store->ref_count++;
1426 *ptr = buffer_store;
1431 i965_release_buffer_store(struct buffer_store **ptr)
1433 struct buffer_store *buffer_store = *ptr;
1435 if (buffer_store == NULL)
1438 assert(buffer_store->bo || buffer_store->buffer);
1439 assert(!(buffer_store->bo && buffer_store->buffer));
1440 buffer_store->ref_count--;
1442 if (buffer_store->ref_count == 0) {
1443 dri_bo_unreference(buffer_store->bo);
1444 free(buffer_store->buffer);
1445 buffer_store->bo = NULL;
1446 buffer_store->buffer = NULL;
1454 i965_destroy_context(struct object_heap *heap, struct object_base *obj)
1456 struct object_context *obj_context = (struct object_context *)obj;
1459 if (obj_context->hw_context) {
1460 obj_context->hw_context->destroy(obj_context->hw_context);
1461 obj_context->hw_context = NULL;
1464 if (obj_context->codec_type == CODEC_PROC) {
1465 i965_release_buffer_store(&obj_context->codec_state.proc.pipeline_param);
1467 } else if (obj_context->codec_type == CODEC_ENC) {
1468 assert(obj_context->codec_state.encode.num_slice_params <= obj_context->codec_state.encode.max_slice_params);
1469 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
1470 i965_release_buffer_store(&obj_context->codec_state.encode.seq_param);
1472 for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++)
1473 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
1475 free(obj_context->codec_state.encode.slice_params);
1477 assert(obj_context->codec_state.encode.num_slice_params_ext <= obj_context->codec_state.encode.max_slice_params_ext);
1478 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
1479 i965_release_buffer_store(&obj_context->codec_state.encode.seq_param_ext);
1481 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
1482 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
1484 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
1485 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
1487 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.misc_param); i++)
1488 i965_release_buffer_store(&obj_context->codec_state.encode.misc_param[i]);
1490 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
1491 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
1493 free(obj_context->codec_state.encode.slice_params_ext);
1495 assert(obj_context->codec_state.decode.num_slice_params <= obj_context->codec_state.decode.max_slice_params);
1496 assert(obj_context->codec_state.decode.num_slice_datas <= obj_context->codec_state.decode.max_slice_datas);
1498 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
1499 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
1500 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
1502 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++)
1503 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
1505 for (i = 0; i < obj_context->codec_state.decode.num_slice_datas; i++)
1506 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
1508 free(obj_context->codec_state.decode.slice_params);
1509 free(obj_context->codec_state.decode.slice_datas);
1512 free(obj_context->render_targets);
1513 object_heap_free(heap, obj);
1517 i965_CreateContext(VADriverContextP ctx,
1518 VAConfigID config_id,
1522 VASurfaceID *render_targets,
1523 int num_render_targets,
1524 VAContextID *context) /* out */
1526 struct i965_driver_data *i965 = i965_driver_data(ctx);
1527 struct i965_render_state *render_state = &i965->render_state;
1528 struct object_config *obj_config = CONFIG(config_id);
1529 struct object_context *obj_context = NULL;
1530 VAStatus vaStatus = VA_STATUS_SUCCESS;
1534 if (NULL == obj_config) {
1535 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
1539 if (picture_width > i965->codec_info->max_width ||
1540 picture_height > i965->codec_info->max_height) {
1541 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
1546 /* Validate picture dimensions */
1547 contextID = NEW_CONTEXT_ID();
1548 obj_context = CONTEXT(contextID);
1550 if (NULL == obj_context) {
1551 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1555 render_state->inited = 1;
1557 switch (obj_config->profile) {
1558 case VAProfileH264ConstrainedBaseline:
1559 case VAProfileH264Main:
1560 case VAProfileH264High:
1561 if (!HAS_H264_DECODING(i965) &&
1562 !HAS_H264_ENCODING(i965))
1563 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
1564 render_state->interleaved_uv = 1;
1567 render_state->interleaved_uv = !!(IS_GEN6(i965->intel.device_info) || IS_GEN7(i965->intel.device_info) || IS_GEN8(i965->intel.device_info));
1571 *context = contextID;
1572 obj_context->flags = flag;
1573 obj_context->context_id = contextID;
1574 obj_context->obj_config = obj_config;
1575 obj_context->picture_width = picture_width;
1576 obj_context->picture_height = picture_height;
1577 obj_context->num_render_targets = num_render_targets;
1578 obj_context->render_targets =
1579 (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
1580 obj_context->hw_context = NULL;
1582 for(i = 0; i < num_render_targets; i++) {
1583 if (NULL == SURFACE(render_targets[i])) {
1584 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1588 obj_context->render_targets[i] = render_targets[i];
1591 if (VA_STATUS_SUCCESS == vaStatus) {
1592 if (VAEntrypointVideoProc == obj_config->entrypoint) {
1593 obj_context->codec_type = CODEC_PROC;
1594 memset(&obj_context->codec_state.proc, 0, sizeof(obj_context->codec_state.proc));
1595 obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
1596 assert(i965->codec_info->proc_hw_context_init);
1597 obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
1598 } else if (VAEntrypointEncSlice == obj_config->entrypoint) { /*encode routin only*/
1599 obj_context->codec_type = CODEC_ENC;
1600 memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
1601 obj_context->codec_state.encode.current_render_target = VA_INVALID_ID;
1602 obj_context->codec_state.encode.max_slice_params = NUM_SLICES;
1603 obj_context->codec_state.encode.slice_params = calloc(obj_context->codec_state.encode.max_slice_params,
1604 sizeof(*obj_context->codec_state.encode.slice_params));
1605 assert(i965->codec_info->enc_hw_context_init);
1606 obj_context->hw_context = i965->codec_info->enc_hw_context_init(ctx, obj_config);
1608 obj_context->codec_type = CODEC_DEC;
1609 memset(&obj_context->codec_state.decode, 0, sizeof(obj_context->codec_state.decode));
1610 obj_context->codec_state.decode.current_render_target = -1;
1611 obj_context->codec_state.decode.max_slice_params = NUM_SLICES;
1612 obj_context->codec_state.decode.max_slice_datas = NUM_SLICES;
1613 obj_context->codec_state.decode.slice_params = calloc(obj_context->codec_state.decode.max_slice_params,
1614 sizeof(*obj_context->codec_state.decode.slice_params));
1615 obj_context->codec_state.decode.slice_datas = calloc(obj_context->codec_state.decode.max_slice_datas,
1616 sizeof(*obj_context->codec_state.decode.slice_datas));
1618 assert(i965->codec_info->dec_hw_context_init);
1619 obj_context->hw_context = i965->codec_info->dec_hw_context_init(ctx, obj_config);
1623 /* Error recovery */
1624 if (VA_STATUS_SUCCESS != vaStatus) {
1625 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1628 i965->current_context_id = contextID;
1634 i965_DestroyContext(VADriverContextP ctx, VAContextID context)
1636 struct i965_driver_data *i965 = i965_driver_data(ctx);
1637 struct object_context *obj_context = CONTEXT(context);
1639 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
1641 if (i965->current_context_id == context)
1642 i965->current_context_id = VA_INVALID_ID;
1644 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
1646 return VA_STATUS_SUCCESS;
1650 i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
1652 struct object_buffer *obj_buffer = (struct object_buffer *)obj;
1654 assert(obj_buffer->buffer_store);
1655 i965_release_buffer_store(&obj_buffer->buffer_store);
1656 object_heap_free(heap, obj);
1660 i965_create_buffer_internal(VADriverContextP ctx,
1661 VAContextID context,
1664 unsigned int num_elements,
1669 struct i965_driver_data *i965 = i965_driver_data(ctx);
1670 struct object_buffer *obj_buffer = NULL;
1671 struct buffer_store *buffer_store = NULL;
1676 case VAPictureParameterBufferType:
1677 case VAIQMatrixBufferType:
1678 case VAQMatrixBufferType:
1679 case VABitPlaneBufferType:
1680 case VASliceGroupMapBufferType:
1681 case VASliceParameterBufferType:
1682 case VASliceDataBufferType:
1683 case VAMacroblockParameterBufferType:
1684 case VAResidualDataBufferType:
1685 case VADeblockingParameterBufferType:
1686 case VAImageBufferType:
1687 case VAEncCodedBufferType:
1688 case VAEncSequenceParameterBufferType:
1689 case VAEncPictureParameterBufferType:
1690 case VAEncSliceParameterBufferType:
1691 case VAEncPackedHeaderParameterBufferType:
1692 case VAEncPackedHeaderDataBufferType:
1693 case VAEncMiscParameterBufferType:
1694 case VAProcPipelineParameterBufferType:
1695 case VAProcFilterParameterBufferType:
1696 case VAHuffmanTableBufferType:
1697 case VAProbabilityBufferType:
1702 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1705 bufferID = NEW_BUFFER_ID();
1706 obj_buffer = BUFFER(bufferID);
1708 if (NULL == obj_buffer) {
1709 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1712 if (type == VAEncCodedBufferType) {
1713 size += I965_CODEDBUFFER_HEADER_SIZE;
1714 size += 0x1000; /* for upper bound check */
1717 obj_buffer->max_num_elements = num_elements;
1718 obj_buffer->num_elements = num_elements;
1719 obj_buffer->size_element = size;
1720 obj_buffer->type = type;
1721 obj_buffer->buffer_store = NULL;
1722 buffer_store = calloc(1, sizeof(struct buffer_store));
1723 assert(buffer_store);
1724 buffer_store->ref_count = 1;
1726 if (store_bo != NULL) {
1727 buffer_store->bo = store_bo;
1728 dri_bo_reference(buffer_store->bo);
1731 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
1732 } else if (type == VASliceDataBufferType ||
1733 type == VAImageBufferType ||
1734 type == VAEncCodedBufferType ||
1735 type == VAProbabilityBufferType) {
1736 buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
1738 size * num_elements, 64);
1739 assert(buffer_store->bo);
1741 if (type == VAEncCodedBufferType) {
1742 struct i965_coded_buffer_segment *coded_buffer_segment;
1744 dri_bo_map(buffer_store->bo, 1);
1745 coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual;
1746 coded_buffer_segment->base.size = size - I965_CODEDBUFFER_HEADER_SIZE;
1747 coded_buffer_segment->base.bit_offset = 0;
1748 coded_buffer_segment->base.status = 0;
1749 coded_buffer_segment->base.buf = NULL;
1750 coded_buffer_segment->base.next = NULL;
1751 coded_buffer_segment->mapped = 0;
1752 coded_buffer_segment->codec = 0;
1753 dri_bo_unmap(buffer_store->bo);
1755 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
1761 if (type == VAEncPackedHeaderDataBufferType) {
1762 msize = ALIGN(size, 4);
1765 buffer_store->buffer = malloc(msize * num_elements);
1766 assert(buffer_store->buffer);
1769 memcpy(buffer_store->buffer, data, size * num_elements);
1772 buffer_store->num_elements = obj_buffer->num_elements;
1773 i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
1774 i965_release_buffer_store(&buffer_store);
1777 return VA_STATUS_SUCCESS;
1781 i965_CreateBuffer(VADriverContextP ctx,
1782 VAContextID context, /* in */
1783 VABufferType type, /* in */
1784 unsigned int size, /* in */
1785 unsigned int num_elements, /* in */
1786 void *data, /* in */
1787 VABufferID *buf_id) /* out */
1789 return i965_create_buffer_internal(ctx, context, type, size, num_elements, data, NULL, buf_id);
1794 i965_BufferSetNumElements(VADriverContextP ctx,
1795 VABufferID buf_id, /* in */
1796 unsigned int num_elements) /* in */
1798 struct i965_driver_data *i965 = i965_driver_data(ctx);
1799 struct object_buffer *obj_buffer = BUFFER(buf_id);
1800 VAStatus vaStatus = VA_STATUS_SUCCESS;
1802 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
1804 if ((num_elements < 0) ||
1805 (num_elements > obj_buffer->max_num_elements)) {
1806 vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1808 obj_buffer->num_elements = num_elements;
1809 if (obj_buffer->buffer_store != NULL) {
1810 obj_buffer->buffer_store->num_elements = num_elements;
1818 i965_MapBuffer(VADriverContextP ctx,
1819 VABufferID buf_id, /* in */
1820 void **pbuf) /* out */
1822 struct i965_driver_data *i965 = i965_driver_data(ctx);
1823 struct object_buffer *obj_buffer = BUFFER(buf_id);
1824 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1826 ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
1827 ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
1828 ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_INVALID_BUFFER);
1830 if (NULL != obj_buffer->buffer_store->bo) {
1831 unsigned int tiling, swizzle;
1833 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
1835 if (tiling != I915_TILING_NONE)
1836 drm_intel_gem_bo_map_gtt(obj_buffer->buffer_store->bo);
1838 dri_bo_map(obj_buffer->buffer_store->bo, 1);
1840 ASSERT_RET(obj_buffer->buffer_store->bo->virtual, VA_STATUS_ERROR_OPERATION_FAILED);
1841 *pbuf = obj_buffer->buffer_store->bo->virtual;
1843 if (obj_buffer->type == VAEncCodedBufferType) {
1845 unsigned char *buffer = NULL;
1846 struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual);
1848 if (!coded_buffer_segment->mapped) {
1849 unsigned char delimiter0, delimiter1, delimiter2, delimiter3, delimiter4;
1851 coded_buffer_segment->base.buf = buffer = (unsigned char *)(obj_buffer->buffer_store->bo->virtual) + I965_CODEDBUFFER_HEADER_SIZE;
1853 if (coded_buffer_segment->codec == CODEC_H264) {
1854 delimiter0 = H264_DELIMITER0;
1855 delimiter1 = H264_DELIMITER1;
1856 delimiter2 = H264_DELIMITER2;
1857 delimiter3 = H264_DELIMITER3;
1858 delimiter4 = H264_DELIMITER4;
1859 } else if (coded_buffer_segment->codec == CODEC_MPEG2) {
1860 delimiter0 = MPEG2_DELIMITER0;
1861 delimiter1 = MPEG2_DELIMITER1;
1862 delimiter2 = MPEG2_DELIMITER2;
1863 delimiter3 = MPEG2_DELIMITER3;
1864 delimiter4 = MPEG2_DELIMITER4;
1866 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
1869 for (i = 0; i < obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000; i++) {
1870 if ((buffer[i] == delimiter0) &&
1871 (buffer[i + 1] == delimiter1) &&
1872 (buffer[i + 2] == delimiter2) &&
1873 (buffer[i + 3] == delimiter3) &&
1874 (buffer[i + 4] == delimiter4))
1878 if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000) {
1879 coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
1882 coded_buffer_segment->base.size = i;
1883 coded_buffer_segment->mapped = 1;
1885 assert(coded_buffer_segment->base.buf);
1889 vaStatus = VA_STATUS_SUCCESS;
1890 } else if (NULL != obj_buffer->buffer_store->buffer) {
1891 *pbuf = obj_buffer->buffer_store->buffer;
1892 vaStatus = VA_STATUS_SUCCESS;
1899 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
1901 struct i965_driver_data *i965 = i965_driver_data(ctx);
1902 struct object_buffer *obj_buffer = BUFFER(buf_id);
1903 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1905 if ((buf_id & OBJECT_HEAP_OFFSET_MASK) != BUFFER_ID_OFFSET)
1906 return VA_STATUS_ERROR_INVALID_BUFFER;
1908 ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER);
1909 ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_OPERATION_FAILED);
1910 ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_OPERATION_FAILED);
1912 if (NULL != obj_buffer->buffer_store->bo) {
1913 unsigned int tiling, swizzle;
1915 dri_bo_get_tiling(obj_buffer->buffer_store->bo, &tiling, &swizzle);
1917 if (tiling != I915_TILING_NONE)
1918 drm_intel_gem_bo_unmap_gtt(obj_buffer->buffer_store->bo);
1920 dri_bo_unmap(obj_buffer->buffer_store->bo);
1922 vaStatus = VA_STATUS_SUCCESS;
1923 } else if (NULL != obj_buffer->buffer_store->buffer) {
1925 vaStatus = VA_STATUS_SUCCESS;
1932 i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
1934 struct i965_driver_data *i965 = i965_driver_data(ctx);
1935 struct object_buffer *obj_buffer = BUFFER(buffer_id);
1937 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
1939 i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
1941 return VA_STATUS_SUCCESS;
1945 i965_BeginPicture(VADriverContextP ctx,
1946 VAContextID context,
1947 VASurfaceID render_target)
1949 struct i965_driver_data *i965 = i965_driver_data(ctx);
1950 struct object_context *obj_context = CONTEXT(context);
1951 struct object_surface *obj_surface = SURFACE(render_target);
1952 struct object_config *obj_config;
1956 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
1957 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
1958 obj_config = obj_context->obj_config;
1959 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
1961 switch (obj_config->profile) {
1962 case VAProfileMPEG2Simple:
1963 case VAProfileMPEG2Main:
1964 vaStatus = VA_STATUS_SUCCESS;
1967 case VAProfileH264ConstrainedBaseline:
1968 case VAProfileH264Main:
1969 case VAProfileH264High:
1970 vaStatus = VA_STATUS_SUCCESS;
1973 case VAProfileVC1Simple:
1974 case VAProfileVC1Main:
1975 case VAProfileVC1Advanced:
1976 vaStatus = VA_STATUS_SUCCESS;
1979 case VAProfileJPEGBaseline:
1980 vaStatus = VA_STATUS_SUCCESS;
1984 vaStatus = VA_STATUS_SUCCESS;
1987 case VAProfileVP8Version0_3:
1988 vaStatus = VA_STATUS_SUCCESS;
1992 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
1996 if (obj_context->codec_type == CODEC_PROC) {
1997 obj_context->codec_state.proc.current_render_target = render_target;
1998 } else if (obj_context->codec_type == CODEC_ENC) {
1999 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param);
2001 for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++) {
2002 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params[i]);
2005 obj_context->codec_state.encode.num_slice_params = 0;
2008 i965_release_buffer_store(&obj_context->codec_state.encode.pic_param_ext);
2010 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_param); i++)
2011 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_param[i]);
2013 for (i = 0; i < ARRAY_ELEMS(obj_context->codec_state.encode.packed_header_data); i++)
2014 i965_release_buffer_store(&obj_context->codec_state.encode.packed_header_data[i]);
2016 for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++)
2017 i965_release_buffer_store(&obj_context->codec_state.encode.slice_params_ext[i]);
2019 obj_context->codec_state.encode.num_slice_params_ext = 0;
2020 obj_context->codec_state.encode.current_render_target = render_target; /*This is input new frame*/
2021 obj_context->codec_state.encode.last_packed_header_type = 0;
2023 obj_context->codec_state.decode.current_render_target = render_target;
2024 i965_release_buffer_store(&obj_context->codec_state.decode.pic_param);
2025 i965_release_buffer_store(&obj_context->codec_state.decode.iq_matrix);
2026 i965_release_buffer_store(&obj_context->codec_state.decode.bit_plane);
2027 i965_release_buffer_store(&obj_context->codec_state.decode.huffman_table);
2029 for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++) {
2030 i965_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]);
2031 i965_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]);
2034 obj_context->codec_state.decode.num_slice_params = 0;
2035 obj_context->codec_state.decode.num_slice_datas = 0;
2041 #define I965_RENDER_BUFFER(category, name) i965_render_##category##_##name##_buffer(ctx, obj_context, obj_buffer)
2043 #define DEF_RENDER_SINGLE_BUFFER_FUNC(category, name, member) \
2045 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
2046 struct object_context *obj_context, \
2047 struct object_buffer *obj_buffer) \
2049 struct category##_state *category = &obj_context->codec_state.category; \
2050 i965_release_buffer_store(&category->member); \
2051 i965_reference_buffer_store(&category->member, obj_buffer->buffer_store); \
2052 return VA_STATUS_SUCCESS; \
2055 #define DEF_RENDER_MULTI_BUFFER_FUNC(category, name, member) \
2057 i965_render_##category##_##name##_buffer(VADriverContextP ctx, \
2058 struct object_context *obj_context, \
2059 struct object_buffer *obj_buffer) \
2061 struct category##_state *category = &obj_context->codec_state.category; \
2062 if (category->num_##member == category->max_##member) { \
2063 category->member = realloc(category->member, (category->max_##member + NUM_SLICES) * sizeof(*category->member)); \
2064 memset(category->member + category->max_##member, 0, NUM_SLICES * sizeof(*category->member)); \
2065 category->max_##member += NUM_SLICES; \
2067 i965_release_buffer_store(&category->member[category->num_##member]); \
2068 i965_reference_buffer_store(&category->member[category->num_##member], obj_buffer->buffer_store); \
2069 category->num_##member++; \
2070 return VA_STATUS_SUCCESS; \
2073 #define I965_RENDER_DECODE_BUFFER(name) I965_RENDER_BUFFER(decode, name)
2075 #define DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(decode, name, member)
2076 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2077 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(iq_matrix, iq_matrix)
2078 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(bit_plane, bit_plane)
2079 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
2080 DEF_RENDER_DECODE_SINGLE_BUFFER_FUNC(probability_data, probability_data)
2082 #define DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(decode, name, member)
2083 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2084 DEF_RENDER_DECODE_MULTI_BUFFER_FUNC(slice_data, slice_datas)
2087 i965_decoder_render_picture(VADriverContextP ctx,
2088 VAContextID context,
2089 VABufferID *buffers,
2092 struct i965_driver_data *i965 = i965_driver_data(ctx);
2093 struct object_context *obj_context = CONTEXT(context);
2094 VAStatus vaStatus = VA_STATUS_SUCCESS;
2097 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2099 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2100 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2103 return VA_STATUS_ERROR_INVALID_BUFFER;
2105 switch (obj_buffer->type) {
2106 case VAPictureParameterBufferType:
2107 vaStatus = I965_RENDER_DECODE_BUFFER(picture_parameter);
2110 case VAIQMatrixBufferType:
2111 vaStatus = I965_RENDER_DECODE_BUFFER(iq_matrix);
2114 case VABitPlaneBufferType:
2115 vaStatus = I965_RENDER_DECODE_BUFFER(bit_plane);
2118 case VASliceParameterBufferType:
2119 vaStatus = I965_RENDER_DECODE_BUFFER(slice_parameter);
2122 case VASliceDataBufferType:
2123 vaStatus = I965_RENDER_DECODE_BUFFER(slice_data);
2126 case VAHuffmanTableBufferType:
2127 vaStatus = I965_RENDER_DECODE_BUFFER(huffman_table);
2130 case VAProbabilityBufferType:
2131 vaStatus = I965_RENDER_DECODE_BUFFER(probability_data);
2135 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2143 #define I965_RENDER_ENCODE_BUFFER(name) I965_RENDER_BUFFER(encode, name)
2145 #define DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(encode, name, member)
2146 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter, seq_param)
2147 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter, pic_param)
2148 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_control, pic_control)
2149 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(qmatrix, q_matrix)
2150 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(iqmatrix, iq_matrix)
2151 /* extended buffer */
2152 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
2153 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
2155 #define DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(name, member) DEF_RENDER_MULTI_BUFFER_FUNC(encode, name, member)
2156 // DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter, slice_params)
2157 DEF_RENDER_ENCODE_MULTI_BUFFER_FUNC(slice_parameter_ext, slice_params_ext)
2160 i965_encoder_render_packed_header_parameter_buffer(VADriverContextP ctx,
2161 struct object_context *obj_context,
2162 struct object_buffer *obj_buffer,
2165 struct encode_state *encode = &obj_context->codec_state.encode;
2167 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2168 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2169 i965_release_buffer_store(&encode->packed_header_param[type_index]);
2170 i965_reference_buffer_store(&encode->packed_header_param[type_index], obj_buffer->buffer_store);
2172 return VA_STATUS_SUCCESS;
2176 i965_encoder_render_packed_header_data_buffer(VADriverContextP ctx,
2177 struct object_context *obj_context,
2178 struct object_buffer *obj_buffer,
2181 struct encode_state *encode = &obj_context->codec_state.encode;
2183 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2184 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2185 i965_release_buffer_store(&encode->packed_header_data[type_index]);
2186 i965_reference_buffer_store(&encode->packed_header_data[type_index], obj_buffer->buffer_store);
2188 return VA_STATUS_SUCCESS;
2192 i965_encoder_render_misc_parameter_buffer(VADriverContextP ctx,
2193 struct object_context *obj_context,
2194 struct object_buffer *obj_buffer)
2196 struct encode_state *encode = &obj_context->codec_state.encode;
2197 VAEncMiscParameterBuffer *param = NULL;
2199 ASSERT_RET(obj_buffer->buffer_store->bo == NULL, VA_STATUS_ERROR_INVALID_BUFFER);
2200 ASSERT_RET(obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER);
2202 param = (VAEncMiscParameterBuffer *)obj_buffer->buffer_store->buffer;
2204 if (param->type >= ARRAY_ELEMS(encode->misc_param))
2205 return VA_STATUS_ERROR_INVALID_PARAMETER;
2207 i965_release_buffer_store(&encode->misc_param[param->type]);
2208 i965_reference_buffer_store(&encode->misc_param[param->type], obj_buffer->buffer_store);
2210 return VA_STATUS_SUCCESS;
2214 i965_encoder_render_picture(VADriverContextP ctx,
2215 VAContextID context,
2216 VABufferID *buffers,
2219 struct i965_driver_data *i965 = i965_driver_data(ctx);
2220 struct object_context *obj_context = CONTEXT(context);
2221 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2224 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2226 for (i = 0; i < num_buffers; i++) {
2227 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2230 return VA_STATUS_ERROR_INVALID_BUFFER;
2232 switch (obj_buffer->type) {
2233 case VAQMatrixBufferType:
2234 vaStatus = I965_RENDER_ENCODE_BUFFER(qmatrix);
2237 case VAIQMatrixBufferType:
2238 vaStatus = I965_RENDER_ENCODE_BUFFER(iqmatrix);
2241 case VAEncSequenceParameterBufferType:
2242 vaStatus = I965_RENDER_ENCODE_BUFFER(sequence_parameter_ext);
2245 case VAEncPictureParameterBufferType:
2246 vaStatus = I965_RENDER_ENCODE_BUFFER(picture_parameter_ext);
2249 case VAEncSliceParameterBufferType:
2250 vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
2253 case VAEncPackedHeaderParameterBufferType:
2255 struct encode_state *encode = &obj_context->codec_state.encode;
2256 VAEncPackedHeaderParameterBuffer *param = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_store->buffer;
2257 encode->last_packed_header_type = param->type;
2259 vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx,
2262 va_enc_packed_type_to_idx(encode->last_packed_header_type));
2266 case VAEncPackedHeaderDataBufferType:
2268 struct encode_state *encode = &obj_context->codec_state.encode;
2270 ASSERT_RET(encode->last_packed_header_type == VAEncPackedHeaderSequence ||
2271 encode->last_packed_header_type == VAEncPackedHeaderPicture ||
2272 encode->last_packed_header_type == VAEncPackedHeaderSlice ||
2273 (((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) &&
2274 ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)),
2275 VA_STATUS_ERROR_ENCODING_ERROR);
2276 vaStatus = i965_encoder_render_packed_header_data_buffer(ctx,
2279 va_enc_packed_type_to_idx(encode->last_packed_header_type));
2283 case VAEncMiscParameterBufferType:
2284 vaStatus = i965_encoder_render_misc_parameter_buffer(ctx,
2290 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2298 #define I965_RENDER_PROC_BUFFER(name) I965_RENDER_BUFFER(proc, name)
2300 #define DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(name, member) DEF_RENDER_SINGLE_BUFFER_FUNC(proc, name, member)
2301 DEF_RENDER_PROC_SINGLE_BUFFER_FUNC(pipeline_parameter, pipeline_param)
2304 i965_proc_render_picture(VADriverContextP ctx,
2305 VAContextID context,
2306 VABufferID *buffers,
2309 struct i965_driver_data *i965 = i965_driver_data(ctx);
2310 struct object_context *obj_context = CONTEXT(context);
2311 VAStatus vaStatus = VA_STATUS_SUCCESS;
2314 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2316 for (i = 0; i < num_buffers && vaStatus == VA_STATUS_SUCCESS; i++) {
2317 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
2320 return VA_STATUS_ERROR_INVALID_BUFFER;
2322 switch (obj_buffer->type) {
2323 case VAProcPipelineParameterBufferType:
2324 vaStatus = I965_RENDER_PROC_BUFFER(pipeline_parameter);
2328 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2337 i965_RenderPicture(VADriverContextP ctx,
2338 VAContextID context,
2339 VABufferID *buffers,
2342 struct i965_driver_data *i965 = i965_driver_data(ctx);
2343 struct object_context *obj_context;
2344 struct object_config *obj_config;
2345 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
2347 obj_context = CONTEXT(context);
2348 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2350 if (num_buffers <= 0)
2351 return VA_STATUS_ERROR_INVALID_PARAMETER;
2353 obj_config = obj_context->obj_config;
2354 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2356 if (VAEntrypointVideoProc == obj_config->entrypoint) {
2357 vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
2358 } else if (VAEntrypointEncSlice == obj_config->entrypoint ) {
2359 vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
2361 vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
2368 i965_EndPicture(VADriverContextP ctx, VAContextID context)
2370 struct i965_driver_data *i965 = i965_driver_data(ctx);
2371 struct object_context *obj_context = CONTEXT(context);
2372 struct object_config *obj_config;
2374 ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT);
2375 obj_config = obj_context->obj_config;
2376 ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG);
2378 if (obj_context->codec_type == CODEC_PROC) {
2379 ASSERT_RET(VAEntrypointVideoProc == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
2380 } else if (obj_context->codec_type == CODEC_ENC) {
2381 ASSERT_RET(VAEntrypointEncSlice == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
2383 if (!(obj_context->codec_state.encode.pic_param ||
2384 obj_context->codec_state.encode.pic_param_ext)) {
2385 return VA_STATUS_ERROR_INVALID_PARAMETER;
2387 if (!(obj_context->codec_state.encode.seq_param ||
2388 obj_context->codec_state.encode.seq_param_ext)) {
2389 return VA_STATUS_ERROR_INVALID_PARAMETER;
2391 if ((obj_context->codec_state.encode.num_slice_params <=0) &&
2392 (obj_context->codec_state.encode.num_slice_params_ext <=0)) {
2393 return VA_STATUS_ERROR_INVALID_PARAMETER;
2396 if (obj_context->codec_state.decode.pic_param == NULL) {
2397 return VA_STATUS_ERROR_INVALID_PARAMETER;
2399 if (obj_context->codec_state.decode.num_slice_params <=0) {
2400 return VA_STATUS_ERROR_INVALID_PARAMETER;
2402 if (obj_context->codec_state.decode.num_slice_datas <=0) {
2403 return VA_STATUS_ERROR_INVALID_PARAMETER;
2406 if (obj_context->codec_state.decode.num_slice_params !=
2407 obj_context->codec_state.decode.num_slice_datas) {
2408 return VA_STATUS_ERROR_INVALID_PARAMETER;
2412 ASSERT_RET(obj_context->hw_context->run, VA_STATUS_ERROR_OPERATION_FAILED);
2413 return obj_context->hw_context->run(ctx, obj_config->profile, &obj_context->codec_state, obj_context->hw_context);
2417 i965_SyncSurface(VADriverContextP ctx,
2418 VASurfaceID render_target)
2420 struct i965_driver_data *i965 = i965_driver_data(ctx);
2421 struct object_surface *obj_surface = SURFACE(render_target);
2423 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2426 drm_intel_bo_wait_rendering(obj_surface->bo);
2428 return VA_STATUS_SUCCESS;
2432 i965_QuerySurfaceStatus(VADriverContextP ctx,
2433 VASurfaceID render_target,
2434 VASurfaceStatus *status) /* out */
2436 struct i965_driver_data *i965 = i965_driver_data(ctx);
2437 struct object_surface *obj_surface = SURFACE(render_target);
2439 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
2441 if (obj_surface->bo) {
2442 if (drm_intel_bo_busy(obj_surface->bo)){
2443 *status = VASurfaceRendering;
2446 *status = VASurfaceReady;
2449 *status = VASurfaceReady;
2452 return VA_STATUS_SUCCESS;
2455 static VADisplayAttribute *
2456 get_display_attribute(VADriverContextP ctx, VADisplayAttribType type)
2458 struct i965_driver_data * const i965 = i965_driver_data(ctx);
2461 if (!i965->display_attributes)
2464 for (i = 0; i < i965->num_display_attributes; i++) {
2465 if (i965->display_attributes[i].type == type)
2466 return &i965->display_attributes[i];
2472 i965_display_attributes_terminate(VADriverContextP ctx)
2474 struct i965_driver_data * const i965 = i965_driver_data(ctx);
2476 if (i965->display_attributes) {
2477 free(i965->display_attributes);
2478 i965->display_attributes = NULL;
2479 i965->num_display_attributes = 0;
2484 i965_display_attributes_init(VADriverContextP ctx)
2486 struct i965_driver_data * const i965 = i965_driver_data(ctx);
2488 i965->num_display_attributes = ARRAY_ELEMS(i965_display_attributes);
2489 i965->display_attributes = malloc(
2490 i965->num_display_attributes * sizeof(i965->display_attributes[0]));
2491 if (!i965->display_attributes)
2495 i965->display_attributes,
2496 i965_display_attributes,
2497 sizeof(i965_display_attributes)
2500 i965->rotation_attrib = get_display_attribute(ctx, VADisplayAttribRotation);
2501 i965->brightness_attrib = get_display_attribute(ctx, VADisplayAttribBrightness);
2502 i965->contrast_attrib = get_display_attribute(ctx, VADisplayAttribContrast);
2503 i965->hue_attrib = get_display_attribute(ctx, VADisplayAttribHue);
2504 i965->saturation_attrib = get_display_attribute(ctx, VADisplayAttribSaturation);
2506 if (!i965->rotation_attrib ||
2507 !i965->brightness_attrib ||
2508 !i965->contrast_attrib ||
2509 !i965->hue_attrib ||
2510 !i965->saturation_attrib) {
2516 i965_display_attributes_terminate(ctx);
2521 * Query display attributes
2522 * The caller must provide a "attr_list" array that can hold at
2523 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
2524 * returned in "attr_list" is returned in "num_attributes".
2527 i965_QueryDisplayAttributes(
2528 VADriverContextP ctx,
2529 VADisplayAttribute *attribs, /* out */
2530 int *num_attribs_ptr /* out */
2533 const int num_attribs = ARRAY_ELEMS(i965_display_attributes);
2535 if (attribs && num_attribs > 0)
2536 memcpy(attribs, i965_display_attributes, sizeof(i965_display_attributes));
2538 if (num_attribs_ptr)
2539 *num_attribs_ptr = num_attribs;
2541 return VA_STATUS_SUCCESS;
2545 * Get display attributes
2546 * This function returns the current attribute values in "attr_list".
2547 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
2548 * from vaQueryDisplayAttributes() can have their values retrieved.
2551 i965_GetDisplayAttributes(
2552 VADriverContextP ctx,
2553 VADisplayAttribute *attribs, /* inout */
2554 int num_attribs /* in */
2559 for (i = 0; i < num_attribs; i++) {
2560 VADisplayAttribute *src_attrib, * const dst_attrib = &attribs[i];
2562 src_attrib = get_display_attribute(ctx, dst_attrib->type);
2563 if (src_attrib && (src_attrib->flags & VA_DISPLAY_ATTRIB_GETTABLE)) {
2564 dst_attrib->min_value = src_attrib->min_value;
2565 dst_attrib->max_value = src_attrib->max_value;
2566 dst_attrib->value = src_attrib->value;
2569 dst_attrib->flags = VA_DISPLAY_ATTRIB_NOT_SUPPORTED;
2571 return VA_STATUS_SUCCESS;
2575 * Set display attributes
2576 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
2577 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
2578 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
2581 i965_SetDisplayAttributes(
2582 VADriverContextP ctx,
2583 VADisplayAttribute *attribs, /* in */
2584 int num_attribs /* in */
2589 for (i = 0; i < num_attribs; i++) {
2590 VADisplayAttribute *dst_attrib, * const src_attrib = &attribs[i];
2592 dst_attrib = get_display_attribute(ctx, src_attrib->type);
2594 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
2596 if (!(dst_attrib->flags & VA_DISPLAY_ATTRIB_SETTABLE))
2599 if (src_attrib->value < dst_attrib->min_value ||
2600 src_attrib->value > dst_attrib->max_value)
2601 return VA_STATUS_ERROR_INVALID_PARAMETER;
2603 dst_attrib->value = src_attrib->value;
2604 /* XXX: track modified attributes through timestamps */
2606 return VA_STATUS_SUCCESS;
2610 i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
2611 VASurfaceID surface,
2612 void **buffer, /* out */
2613 unsigned int *stride) /* out */
2616 return VA_STATUS_ERROR_UNIMPLEMENTED;
2620 i965_destroy_heap(struct object_heap *heap,
2621 void (*func)(struct object_heap *heap, struct object_base *object))
2623 struct object_base *object;
2624 object_heap_iterator iter;
2626 object = object_heap_first(heap, &iter);
2632 object = object_heap_next(heap, &iter);
2635 object_heap_destroy(heap);
2640 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
2643 i965_CreateImage(VADriverContextP ctx,
2644 VAImageFormat *format,
2647 VAImage *out_image) /* out */
2649 struct i965_driver_data *i965 = i965_driver_data(ctx);
2650 struct object_image *obj_image;
2651 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
2653 unsigned int size2, size, awidth, aheight;
2655 out_image->image_id = VA_INVALID_ID;
2656 out_image->buf = VA_INVALID_ID;
2658 image_id = NEW_IMAGE_ID();
2659 if (image_id == VA_INVALID_ID)
2660 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2662 obj_image = IMAGE(image_id);
2664 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2665 obj_image->bo = NULL;
2666 obj_image->palette = NULL;
2667 obj_image->derived_surface = VA_INVALID_ID;
2669 VAImage * const image = &obj_image->image;
2670 image->image_id = image_id;
2671 image->buf = VA_INVALID_ID;
2673 awidth = ALIGN(width, i965->codec_info->min_linear_wpitch);
2675 if ((format->fourcc == VA_FOURCC_YV12) ||
2676 (format->fourcc == VA_FOURCC_I420)) {
2677 if (awidth % 128 != 0) {
2678 awidth = ALIGN(width, 128);
2682 aheight = ALIGN(height, i965->codec_info->min_linear_hpitch);
2683 size = awidth * aheight;
2684 size2 = (awidth / 2) * (aheight / 2);
2686 image->num_palette_entries = 0;
2687 image->entry_bytes = 0;
2688 memset(image->component_order, 0, sizeof(image->component_order));
2690 switch (format->fourcc) {
2691 case VA_FOURCC_IA44:
2692 case VA_FOURCC_AI44:
2693 image->num_planes = 1;
2694 image->pitches[0] = awidth;
2695 image->offsets[0] = 0;
2696 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
2697 image->num_palette_entries = 16;
2698 image->entry_bytes = 3;
2699 image->component_order[0] = 'R';
2700 image->component_order[1] = 'G';
2701 image->component_order[2] = 'B';
2703 case VA_FOURCC_IA88:
2704 case VA_FOURCC_AI88:
2705 image->num_planes = 1;
2706 image->pitches[0] = awidth * 2;
2707 image->offsets[0] = 0;
2708 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
2709 image->num_palette_entries = 256;
2710 image->entry_bytes = 3;
2711 image->component_order[0] = 'R';
2712 image->component_order[1] = 'G';
2713 image->component_order[2] = 'B';
2715 case VA_FOURCC_ARGB:
2716 case VA_FOURCC_ABGR:
2717 case VA_FOURCC_BGRA:
2718 case VA_FOURCC_RGBA:
2719 case VA_FOURCC_BGRX:
2720 case VA_FOURCC_RGBX:
2721 image->num_planes = 1;
2722 image->pitches[0] = awidth * 4;
2723 image->offsets[0] = 0;
2724 image->data_size = image->offsets[0] + image->pitches[0] * aheight;
2726 case VA_FOURCC_YV12:
2727 image->num_planes = 3;
2728 image->pitches[0] = awidth;
2729 image->offsets[0] = 0;
2730 image->pitches[1] = awidth / 2;
2731 image->offsets[1] = size;
2732 image->pitches[2] = awidth / 2;
2733 image->offsets[2] = size + size2;
2734 image->data_size = size + 2 * size2;
2736 case VA_FOURCC_I420:
2737 image->num_planes = 3;
2738 image->pitches[0] = awidth;
2739 image->offsets[0] = 0;
2740 image->pitches[1] = awidth / 2;
2741 image->offsets[1] = size;
2742 image->pitches[2] = awidth / 2;
2743 image->offsets[2] = size + size2;
2744 image->data_size = size + 2 * size2;
2746 case VA_FOURCC_422H:
2747 image->num_planes = 3;
2748 image->pitches[0] = awidth;
2749 image->offsets[0] = 0;
2750 image->pitches[1] = awidth / 2;
2751 image->offsets[1] = size;
2752 image->pitches[2] = awidth / 2;
2753 image->offsets[2] = size + (awidth / 2) * aheight;
2754 image->data_size = size + 2 * ((awidth / 2) * aheight);
2756 case VA_FOURCC_NV12:
2757 image->num_planes = 2;
2758 image->pitches[0] = awidth;
2759 image->offsets[0] = 0;
2760 image->pitches[1] = awidth;
2761 image->offsets[1] = size;
2762 image->data_size = size + 2 * size2;
2764 case VA_FOURCC_YUY2:
2765 case VA_FOURCC_UYVY:
2766 image->num_planes = 1;
2767 image->pitches[0] = awidth * 2;
2768 image->offsets[0] = 0;
2769 image->data_size = size * 2;
2775 va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
2776 image->data_size, 1, NULL, &image->buf);
2777 if (va_status != VA_STATUS_SUCCESS)
2780 struct object_buffer *obj_buffer = BUFFER(image->buf);
2783 !obj_buffer->buffer_store ||
2784 !obj_buffer->buffer_store->bo)
2785 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2787 obj_image->bo = obj_buffer->buffer_store->bo;
2788 dri_bo_reference(obj_image->bo);
2790 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
2791 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
2792 if (!obj_image->palette)
2796 image->image_id = image_id;
2797 image->format = *format;
2798 image->width = width;
2799 image->height = height;
2801 *out_image = *image;
2802 return VA_STATUS_SUCCESS;
2805 i965_DestroyImage(ctx, image_id);
2810 i965_check_alloc_surface_bo(VADriverContextP ctx,
2811 struct object_surface *obj_surface,
2813 unsigned int fourcc,
2814 unsigned int subsampling)
2816 struct i965_driver_data *i965 = i965_driver_data(ctx);
2817 int region_width, region_height;
2819 if (obj_surface->bo) {
2820 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
2821 ASSERT_RET(obj_surface->fourcc == fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
2822 ASSERT_RET(obj_surface->subsampling == subsampling, VA_STATUS_ERROR_INVALID_SURFACE);
2823 return VA_STATUS_SUCCESS;
2826 obj_surface->x_cb_offset = 0; /* X offset is always 0 */
2827 obj_surface->x_cr_offset = 0;
2829 if ((tiled && !obj_surface->user_disable_tiling)) {
2830 ASSERT_RET(fourcc != VA_FOURCC_I420 &&
2831 fourcc != VA_FOURCC_IYUV &&
2832 fourcc != VA_FOURCC_YV12,
2833 VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
2834 if (obj_surface->user_h_stride_set) {
2835 ASSERT_RET(IS_ALIGNED(obj_surface->width, 128), VA_STATUS_ERROR_INVALID_PARAMETER);
2837 obj_surface->width = ALIGN(obj_surface->orig_width, 128);
2839 if (obj_surface->user_v_stride_set) {
2840 ASSERT_RET(IS_ALIGNED(obj_surface->height, 32), VA_STATUS_ERROR_INVALID_PARAMETER);
2842 obj_surface->height = ALIGN(obj_surface->orig_height, 32);
2844 region_height = obj_surface->height;
2847 case VA_FOURCC_NV12:
2848 assert(subsampling == SUBSAMPLE_YUV420);
2849 obj_surface->cb_cr_pitch = obj_surface->width;
2850 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2851 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2852 obj_surface->y_cb_offset = obj_surface->height;
2853 obj_surface->y_cr_offset = obj_surface->height;
2854 region_width = obj_surface->width;
2855 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
2859 case VA_FOURCC_IMC1:
2860 assert(subsampling == SUBSAMPLE_YUV420);
2861 obj_surface->cb_cr_pitch = obj_surface->width;
2862 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2863 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2864 obj_surface->y_cr_offset = obj_surface->height;
2865 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32);
2866 region_width = obj_surface->width;
2867 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2871 case VA_FOURCC_IMC3:
2872 assert(subsampling == SUBSAMPLE_YUV420);
2873 obj_surface->cb_cr_pitch = obj_surface->width;
2874 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2875 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2876 obj_surface->y_cb_offset = obj_surface->height;
2877 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2878 region_width = obj_surface->width;
2879 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2883 case VA_FOURCC_422H:
2884 assert(subsampling == SUBSAMPLE_YUV422H);
2885 obj_surface->cb_cr_pitch = obj_surface->width;
2886 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2887 obj_surface->cb_cr_height = obj_surface->orig_height;
2888 obj_surface->y_cb_offset = obj_surface->height;
2889 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2890 region_width = obj_surface->width;
2891 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2895 case VA_FOURCC_422V:
2896 assert(subsampling == SUBSAMPLE_YUV422V);
2897 obj_surface->cb_cr_pitch = obj_surface->width;
2898 obj_surface->cb_cr_width = obj_surface->orig_width;
2899 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2900 obj_surface->y_cb_offset = obj_surface->height;
2901 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2902 region_width = obj_surface->width;
2903 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2907 case VA_FOURCC_411P:
2908 assert(subsampling == SUBSAMPLE_YUV411);
2909 obj_surface->cb_cr_pitch = obj_surface->width;
2910 obj_surface->cb_cr_width = obj_surface->orig_width / 4;
2911 obj_surface->cb_cr_height = obj_surface->orig_height;
2912 obj_surface->y_cb_offset = obj_surface->height;
2913 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2914 region_width = obj_surface->width;
2915 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2919 case VA_FOURCC_444P:
2920 assert(subsampling == SUBSAMPLE_YUV444);
2921 obj_surface->cb_cr_pitch = obj_surface->width;
2922 obj_surface->cb_cr_width = obj_surface->orig_width;
2923 obj_surface->cb_cr_height = obj_surface->orig_height;
2924 obj_surface->y_cb_offset = obj_surface->height;
2925 obj_surface->y_cr_offset = obj_surface->y_cb_offset + ALIGN(obj_surface->cb_cr_height, 32);
2926 region_width = obj_surface->width;
2927 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32) * 2;
2931 case VA_FOURCC_Y800:
2932 assert(subsampling == SUBSAMPLE_YUV400);
2933 obj_surface->cb_cr_pitch = 0;
2934 obj_surface->cb_cr_width = 0;
2935 obj_surface->cb_cr_height = 0;
2936 obj_surface->y_cb_offset = 0;
2937 obj_surface->y_cr_offset = 0;
2938 region_width = obj_surface->width;
2939 region_height = obj_surface->height;
2943 case VA_FOURCC_YUY2:
2944 case VA_FOURCC_UYVY:
2945 assert(subsampling == SUBSAMPLE_YUV422H);
2946 obj_surface->width = ALIGN(obj_surface->orig_width * 2, 128);
2947 obj_surface->cb_cr_pitch = obj_surface->width;
2948 obj_surface->y_cb_offset = 0;
2949 obj_surface->y_cr_offset = 0;
2950 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2951 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2952 region_width = obj_surface->width;
2953 region_height = obj_surface->height;
2957 case VA_FOURCC_RGBA:
2958 case VA_FOURCC_RGBX:
2959 case VA_FOURCC_BGRA:
2960 case VA_FOURCC_BGRX:
2961 assert(subsampling == SUBSAMPLE_RGBX);
2963 obj_surface->width = ALIGN(obj_surface->orig_width * 4, 128);
2964 region_width = obj_surface->width;
2965 region_height = obj_surface->height;
2969 /* Never get here */
2970 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
2974 assert(subsampling == SUBSAMPLE_YUV420 ||
2975 subsampling == SUBSAMPLE_YUV422H ||
2976 subsampling == SUBSAMPLE_YUV422V ||
2977 subsampling == SUBSAMPLE_RGBX);
2979 region_width = obj_surface->width;
2980 region_height = obj_surface->height;
2983 case VA_FOURCC_NV12:
2984 obj_surface->y_cb_offset = obj_surface->height;
2985 obj_surface->y_cr_offset = obj_surface->height;
2986 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2987 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
2988 obj_surface->cb_cr_pitch = obj_surface->width;
2989 region_height = obj_surface->height + obj_surface->height / 2;
2992 case VA_FOURCC_YV16:
2993 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
2994 obj_surface->cb_cr_height = obj_surface->orig_height;
2995 obj_surface->y_cr_offset = obj_surface->height;
2996 obj_surface->y_cb_offset = obj_surface->y_cr_offset + ALIGN(obj_surface->cb_cr_height, 32) / 2;
2997 obj_surface->cb_cr_pitch = obj_surface->width / 2;
2998 region_height = obj_surface->height + ALIGN(obj_surface->cb_cr_height, 32);
3001 case VA_FOURCC_YV12:
3002 case VA_FOURCC_I420:
3003 if (fourcc == VA_FOURCC_YV12) {
3004 obj_surface->y_cr_offset = obj_surface->height;
3005 obj_surface->y_cb_offset = obj_surface->height + obj_surface->height / 4;
3007 obj_surface->y_cb_offset = obj_surface->height;
3008 obj_surface->y_cr_offset = obj_surface->height + obj_surface->height / 4;
3011 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3012 obj_surface->cb_cr_height = obj_surface->orig_height / 2;
3013 obj_surface->cb_cr_pitch = obj_surface->width / 2;
3014 region_height = obj_surface->height + obj_surface->height / 2;
3017 case VA_FOURCC_YUY2:
3018 case VA_FOURCC_UYVY:
3019 obj_surface->width = ALIGN(obj_surface->orig_width * 2, i965->codec_info->min_linear_wpitch);
3020 obj_surface->y_cb_offset = 0;
3021 obj_surface->y_cr_offset = 0;
3022 obj_surface->cb_cr_width = obj_surface->orig_width / 2;
3023 obj_surface->cb_cr_height = obj_surface->orig_height;
3024 obj_surface->cb_cr_pitch = obj_surface->width;
3025 region_width = obj_surface->width;
3026 region_height = obj_surface->height;
3028 case VA_FOURCC_RGBA:
3029 case VA_FOURCC_RGBX:
3030 case VA_FOURCC_BGRA:
3031 case VA_FOURCC_BGRX:
3032 obj_surface->width = ALIGN(obj_surface->orig_width * 4, i965->codec_info->min_linear_wpitch);
3033 region_width = obj_surface->width;
3034 region_height = obj_surface->height;
3038 /* Never get here */
3039 ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT);
3044 obj_surface->size = ALIGN(region_width * region_height, 0x1000);
3046 if ((tiled && !obj_surface->user_disable_tiling)) {
3047 uint32_t tiling_mode = I915_TILING_Y; /* always uses Y-tiled format */
3048 unsigned long pitch;
3050 obj_surface->bo = drm_intel_bo_alloc_tiled(i965->intel.bufmgr,
3058 assert(tiling_mode == I915_TILING_Y);
3059 assert(pitch == obj_surface->width);
3061 obj_surface->bo = dri_bo_alloc(i965->intel.bufmgr,
3067 obj_surface->fourcc = fourcc;
3068 obj_surface->subsampling = subsampling;
3069 assert(obj_surface->bo);
3070 return VA_STATUS_SUCCESS;
3073 VAStatus i965_DeriveImage(VADriverContextP ctx,
3074 VASurfaceID surface,
3075 VAImage *out_image) /* out */
3077 struct i965_driver_data *i965 = i965_driver_data(ctx);
3078 struct object_image *obj_image;
3079 struct object_surface *obj_surface;
3081 unsigned int w_pitch;
3082 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3084 out_image->image_id = VA_INVALID_ID;
3085 obj_surface = SURFACE(surface);
3088 return VA_STATUS_ERROR_INVALID_SURFACE;
3090 if (!obj_surface->bo) {
3091 unsigned int is_tiled = 0;
3092 unsigned int fourcc = VA_FOURCC_YV12;
3093 i965_guess_surface_format(ctx, surface, &fourcc, &is_tiled);
3094 int sampling = get_sampling_from_fourcc(fourcc);
3095 va_status = i965_check_alloc_surface_bo(ctx, obj_surface, is_tiled, fourcc, sampling);
3096 if (va_status != VA_STATUS_SUCCESS)
3100 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3102 w_pitch = obj_surface->width;
3104 image_id = NEW_IMAGE_ID();
3106 if (image_id == VA_INVALID_ID)
3107 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3109 obj_image = IMAGE(image_id);
3112 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3114 obj_image->bo = NULL;
3115 obj_image->palette = NULL;
3116 obj_image->derived_surface = VA_INVALID_ID;
3118 VAImage * const image = &obj_image->image;
3120 memset(image, 0, sizeof(*image));
3121 image->image_id = image_id;
3122 image->buf = VA_INVALID_ID;
3123 image->num_palette_entries = 0;
3124 image->entry_bytes = 0;
3125 image->width = obj_surface->orig_width;
3126 image->height = obj_surface->orig_height;
3127 image->data_size = obj_surface->size;
3129 image->format.fourcc = obj_surface->fourcc;
3130 image->format.byte_order = VA_LSB_FIRST;
3131 image->format.bits_per_pixel = 12;
3133 switch (image->format.fourcc) {
3134 case VA_FOURCC_YV12:
3135 image->num_planes = 3;
3136 image->pitches[0] = w_pitch; /* Y */
3137 image->offsets[0] = 0;
3138 image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
3139 image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
3140 image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
3141 image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
3144 case VA_FOURCC_YV16:
3145 image->num_planes = 3;
3146 image->pitches[0] = w_pitch; /* Y */
3147 image->offsets[0] = 0;
3148 image->pitches[1] = obj_surface->cb_cr_pitch; /* V */
3149 image->offsets[1] = w_pitch * obj_surface->y_cr_offset;
3150 image->pitches[2] = obj_surface->cb_cr_pitch; /* U */
3151 image->offsets[2] = w_pitch * obj_surface->y_cb_offset;
3154 case VA_FOURCC_NV12:
3155 image->num_planes = 2;
3156 image->pitches[0] = w_pitch; /* Y */
3157 image->offsets[0] = 0;
3158 image->pitches[1] = obj_surface->cb_cr_pitch; /* UV */
3159 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
3162 case VA_FOURCC_I420:
3163 case VA_FOURCC_422H:
3164 case VA_FOURCC_IMC3:
3165 case VA_FOURCC_444P:
3166 case VA_FOURCC_422V:
3167 case VA_FOURCC_411P:
3168 image->num_planes = 3;
3169 image->pitches[0] = w_pitch; /* Y */
3170 image->offsets[0] = 0;
3171 image->pitches[1] = obj_surface->cb_cr_pitch; /* U */
3172 image->offsets[1] = w_pitch * obj_surface->y_cb_offset;
3173 image->pitches[2] = obj_surface->cb_cr_pitch; /* V */
3174 image->offsets[2] = w_pitch * obj_surface->y_cr_offset;
3177 case VA_FOURCC_YUY2:
3178 case VA_FOURCC_UYVY:
3179 case VA_FOURCC_Y800:
3180 image->num_planes = 1;
3181 image->pitches[0] = obj_surface->width; /* Y, width is aligned already */
3182 image->offsets[0] = 0;
3184 case VA_FOURCC_RGBA:
3185 case VA_FOURCC_RGBX:
3186 case VA_FOURCC_BGRA:
3187 case VA_FOURCC_BGRX:
3188 image->num_planes = 1;
3189 image->pitches[0] = obj_surface->width;
3195 va_status = i965_create_buffer_internal(ctx, 0, VAImageBufferType,
3196 obj_surface->size, 1, NULL, obj_surface->bo, &image->buf);
3197 if (va_status != VA_STATUS_SUCCESS)
3200 struct object_buffer *obj_buffer = BUFFER(image->buf);
3203 !obj_buffer->buffer_store ||
3204 !obj_buffer->buffer_store->bo)
3205 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3207 obj_image->bo = obj_buffer->buffer_store->bo;
3208 dri_bo_reference(obj_image->bo);
3210 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
3211 obj_image->palette = malloc(image->num_palette_entries * sizeof(*obj_image->palette));
3212 if (!obj_image->palette) {
3213 va_status = VA_STATUS_ERROR_ALLOCATION_FAILED;
3218 *out_image = *image;
3219 obj_surface->flags |= SURFACE_DERIVED;
3220 obj_image->derived_surface = surface;
3222 return VA_STATUS_SUCCESS;
3225 i965_DestroyImage(ctx, image_id);
3230 i965_destroy_image(struct object_heap *heap, struct object_base *obj)
3232 object_heap_free(heap, obj);
3237 i965_DestroyImage(VADriverContextP ctx, VAImageID image)
3239 struct i965_driver_data *i965 = i965_driver_data(ctx);
3240 struct object_image *obj_image = IMAGE(image);
3241 struct object_surface *obj_surface;
3244 return VA_STATUS_SUCCESS;
3246 dri_bo_unreference(obj_image->bo);
3247 obj_image->bo = NULL;
3249 if (obj_image->image.buf != VA_INVALID_ID) {
3250 i965_DestroyBuffer(ctx, obj_image->image.buf);
3251 obj_image->image.buf = VA_INVALID_ID;
3254 if (obj_image->palette) {
3255 free(obj_image->palette);
3256 obj_image->palette = NULL;
3259 obj_surface = SURFACE(obj_image->derived_surface);
3262 obj_surface->flags &= ~SURFACE_DERIVED;
3265 i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
3267 return VA_STATUS_SUCCESS;
3271 * pointer to an array holding the palette data. The size of the array is
3272 * num_palette_entries * entry_bytes in size. The order of the components
3273 * in the palette is described by the component_order in VASubpicture struct
3276 i965_SetImagePalette(VADriverContextP ctx,
3278 unsigned char *palette)
3280 struct i965_driver_data *i965 = i965_driver_data(ctx);
3283 struct object_image *obj_image = IMAGE(image);
3285 return VA_STATUS_ERROR_INVALID_IMAGE;
3287 if (!obj_image->palette)
3288 return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
3290 for (i = 0; i < obj_image->image.num_palette_entries; i++)
3291 obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
3292 ((unsigned int)palette[3*i + 1] << 8) |
3293 (unsigned int)palette[3*i + 2]);
3294 return VA_STATUS_SUCCESS;
3298 get_sampling_from_fourcc(unsigned int fourcc)
3300 int surface_sampling = -1;
3303 case VA_FOURCC_NV12:
3304 case VA_FOURCC_YV12:
3305 case VA_FOURCC_I420:
3306 case VA_FOURCC_IYUV:
3307 case VA_FOURCC_IMC1:
3308 case VA_FOURCC_IMC3:
3309 surface_sampling = SUBSAMPLE_YUV420;
3311 case VA_FOURCC_YUY2:
3312 case VA_FOURCC_UYVY:
3313 case VA_FOURCC_422H:
3314 case VA_FOURCC_YV16:
3315 surface_sampling = SUBSAMPLE_YUV422H;
3317 case VA_FOURCC_422V:
3318 surface_sampling = SUBSAMPLE_YUV422V;
3321 case VA_FOURCC_444P:
3322 surface_sampling = SUBSAMPLE_YUV444;
3325 case VA_FOURCC_411P:
3326 surface_sampling = SUBSAMPLE_YUV411;
3329 case VA_FOURCC_Y800:
3330 surface_sampling = SUBSAMPLE_YUV400;
3332 case VA_FOURCC_RGBA:
3333 case VA_FOURCC_RGBX:
3334 case VA_FOURCC_BGRA:
3335 case VA_FOURCC_BGRX:
3336 surface_sampling = SUBSAMPLE_RGBX;
3339 /* Never get here */
3345 return surface_sampling;
3349 memcpy_pic(uint8_t *dst, unsigned int dst_stride,
3350 const uint8_t *src, unsigned int src_stride,
3351 unsigned int len, unsigned int height)
3355 for (i = 0; i < height; i++) {
3356 memcpy(dst, src, len);
3363 get_image_i420(struct object_image *obj_image, uint8_t *image_data,
3364 struct object_surface *obj_surface,
3365 const VARectangle *rect)
3367 uint8_t *dst[3], *src[3];
3369 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
3370 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
3371 unsigned int tiling, swizzle;
3372 VAStatus va_status = VA_STATUS_SUCCESS;
3374 if (!obj_surface->bo)
3375 return VA_STATUS_ERROR_INVALID_SURFACE;
3377 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3378 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3380 if (tiling != I915_TILING_NONE)
3381 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3383 dri_bo_map(obj_surface->bo, 0);
3385 if (!obj_surface->bo->virtual)
3386 return VA_STATUS_ERROR_INVALID_SURFACE;
3388 /* Dest VA image has either I420 or YV12 format.
3389 Source VA surface alway has I420 format */
3390 dst[Y] = image_data + obj_image->image.offsets[Y];
3391 src[0] = (uint8_t *)obj_surface->bo->virtual;
3392 dst[U] = image_data + obj_image->image.offsets[U];
3393 src[1] = src[0] + obj_surface->width * obj_surface->height;
3394 dst[V] = image_data + obj_image->image.offsets[V];
3395 src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
3398 dst[Y] += rect->y * obj_image->image.pitches[Y] + rect->x;
3399 src[0] += rect->y * obj_surface->width + rect->x;
3400 memcpy_pic(dst[Y], obj_image->image.pitches[Y],
3401 src[0], obj_surface->width,
3402 rect->width, rect->height);
3405 dst[U] += (rect->y / 2) * obj_image->image.pitches[U] + rect->x / 2;
3406 src[1] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
3407 memcpy_pic(dst[U], obj_image->image.pitches[U],
3408 src[1], obj_surface->width / 2,
3409 rect->width / 2, rect->height / 2);
3412 dst[V] += (rect->y / 2) * obj_image->image.pitches[V] + rect->x / 2;
3413 src[2] += (rect->y / 2) * obj_surface->width / 2 + rect->x / 2;
3414 memcpy_pic(dst[V], obj_image->image.pitches[V],
3415 src[2], obj_surface->width / 2,
3416 rect->width / 2, rect->height / 2);
3418 if (tiling != I915_TILING_NONE)
3419 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3421 dri_bo_unmap(obj_surface->bo);
3427 get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
3428 struct object_surface *obj_surface,
3429 const VARectangle *rect)
3431 uint8_t *dst[2], *src[2];
3432 unsigned int tiling, swizzle;
3433 VAStatus va_status = VA_STATUS_SUCCESS;
3435 if (!obj_surface->bo)
3436 return VA_STATUS_ERROR_INVALID_SURFACE;
3438 assert(obj_surface->fourcc);
3439 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3441 if (tiling != I915_TILING_NONE)
3442 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3444 dri_bo_map(obj_surface->bo, 0);
3446 if (!obj_surface->bo->virtual)
3447 return VA_STATUS_ERROR_INVALID_SURFACE;
3449 /* Both dest VA image and source surface have NV12 format */
3450 dst[0] = image_data + obj_image->image.offsets[0];
3451 src[0] = (uint8_t *)obj_surface->bo->virtual;
3452 dst[1] = image_data + obj_image->image.offsets[1];
3453 src[1] = src[0] + obj_surface->width * obj_surface->height;
3456 dst[0] += rect->y * obj_image->image.pitches[0] + rect->x;
3457 src[0] += rect->y * obj_surface->width + rect->x;
3458 memcpy_pic(dst[0], obj_image->image.pitches[0],
3459 src[0], obj_surface->width,
3460 rect->width, rect->height);
3463 dst[1] += (rect->y / 2) * obj_image->image.pitches[1] + (rect->x & -2);
3464 src[1] += (rect->y / 2) * obj_surface->width + (rect->x & -2);
3465 memcpy_pic(dst[1], obj_image->image.pitches[1],
3466 src[1], obj_surface->width,
3467 rect->width, rect->height / 2);
3469 if (tiling != I915_TILING_NONE)
3470 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3472 dri_bo_unmap(obj_surface->bo);
3478 get_image_yuy2(struct object_image *obj_image, uint8_t *image_data,
3479 struct object_surface *obj_surface,
3480 const VARectangle *rect)
3483 unsigned int tiling, swizzle;
3484 VAStatus va_status = VA_STATUS_SUCCESS;
3486 if (!obj_surface->bo)
3487 return VA_STATUS_ERROR_INVALID_SURFACE;
3489 assert(obj_surface->fourcc);
3490 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3492 if (tiling != I915_TILING_NONE)
3493 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3495 dri_bo_map(obj_surface->bo, 0);
3497 if (!obj_surface->bo->virtual)
3498 return VA_STATUS_ERROR_INVALID_SURFACE;
3500 /* Both dest VA image and source surface have YUYV format */
3501 dst = image_data + obj_image->image.offsets[0];
3502 src = (uint8_t *)obj_surface->bo->virtual;
3505 dst += rect->y * obj_image->image.pitches[0] + rect->x*2;
3506 src += rect->y * obj_surface->width + rect->x*2;
3507 memcpy_pic(dst, obj_image->image.pitches[0],
3508 src, obj_surface->width*2,
3509 rect->width*2, rect->height);
3511 if (tiling != I915_TILING_NONE)
3512 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3514 dri_bo_unmap(obj_surface->bo);
3520 i965_sw_getimage(VADriverContextP ctx,
3521 VASurfaceID surface,
3522 int x, /* coordinates of the upper left source pixel */
3524 unsigned int width, /* width and height of the region */
3525 unsigned int height,
3528 struct i965_driver_data *i965 = i965_driver_data(ctx);
3529 struct i965_render_state *render_state = &i965->render_state;
3530 VAStatus va_status = VA_STATUS_SUCCESS;
3532 struct object_surface *obj_surface = SURFACE(surface);
3534 return VA_STATUS_ERROR_INVALID_SURFACE;
3536 struct object_image *obj_image = IMAGE(image);
3538 return VA_STATUS_ERROR_INVALID_IMAGE;
3541 return VA_STATUS_ERROR_INVALID_PARAMETER;
3542 if (x + width > obj_surface->orig_width ||
3543 y + height > obj_surface->orig_height)
3544 return VA_STATUS_ERROR_INVALID_PARAMETER;
3545 if (x + width > obj_image->image.width ||
3546 y + height > obj_image->image.height)
3547 return VA_STATUS_ERROR_INVALID_PARAMETER;
3549 if (obj_surface->fourcc != obj_image->image.format.fourcc)
3550 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
3552 void *image_data = NULL;
3554 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
3555 if (va_status != VA_STATUS_SUCCESS)
3562 rect.height = height;
3564 switch (obj_image->image.format.fourcc) {
3565 case VA_FOURCC_YV12:
3566 case VA_FOURCC_I420:
3567 /* I420 is native format for MPEG-2 decoded surfaces */
3568 if (render_state->interleaved_uv)
3569 goto operation_failed;
3570 get_image_i420(obj_image, image_data, obj_surface, &rect);
3572 case VA_FOURCC_NV12:
3573 /* NV12 is native format for H.264 decoded surfaces */
3574 if (!render_state->interleaved_uv)
3575 goto operation_failed;
3576 get_image_nv12(obj_image, image_data, obj_surface, &rect);
3578 case VA_FOURCC_YUY2:
3579 /* YUY2 is the format supported by overlay plane */
3580 get_image_yuy2(obj_image, image_data, obj_surface, &rect);
3584 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3588 if (va_status != VA_STATUS_SUCCESS)
3591 va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
3596 i965_hw_getimage(VADriverContextP ctx,
3597 VASurfaceID surface,
3598 int x, /* coordinates of the upper left source pixel */
3600 unsigned int width, /* width and height of the region */
3601 unsigned int height,
3604 struct i965_driver_data *i965 = i965_driver_data(ctx);
3605 struct i965_surface src_surface;
3606 struct i965_surface dst_surface;
3607 VAStatus va_status = VA_STATUS_SUCCESS;
3609 struct object_surface *obj_surface = SURFACE(surface);
3610 struct object_image *obj_image = IMAGE(image);
3613 return VA_STATUS_ERROR_INVALID_SURFACE;
3616 return VA_STATUS_ERROR_INVALID_IMAGE;
3619 return VA_STATUS_ERROR_INVALID_PARAMETER;
3620 if (x + width > obj_surface->orig_width ||
3621 y + height > obj_surface->orig_height)
3622 return VA_STATUS_ERROR_INVALID_PARAMETER;
3623 if (x + width > obj_image->image.width ||
3624 y + height > obj_image->image.height)
3625 return VA_STATUS_ERROR_INVALID_PARAMETER;
3627 if (!obj_surface->bo)
3628 return VA_STATUS_SUCCESS;
3629 assert(obj_image->bo); // image bo is always created, see i965_CreateImage()
3634 rect.height = height;
3636 src_surface.base = (struct object_base *)obj_surface;
3637 src_surface.type = I965_SURFACE_TYPE_SURFACE;
3638 src_surface.flags = I965_SURFACE_FLAG_FRAME;
3640 dst_surface.base = (struct object_base *)obj_image;
3641 dst_surface.type = I965_SURFACE_TYPE_IMAGE;
3642 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3644 va_status = i965_image_processing(ctx,
3655 i965_GetImage(VADriverContextP ctx,
3656 VASurfaceID surface,
3657 int x, /* coordinates of the upper left source pixel */
3659 unsigned int width, /* width and height of the region */
3660 unsigned int height,
3663 struct i965_driver_data * const i965 = i965_driver_data(ctx);
3664 VAStatus va_status = VA_STATUS_SUCCESS;
3666 if (HAS_ACCELERATED_GETIMAGE(i965))
3667 va_status = i965_hw_getimage(ctx,
3673 va_status = i965_sw_getimage(ctx,
3683 put_image_i420(struct object_surface *obj_surface,
3684 const VARectangle *dst_rect,
3685 struct object_image *obj_image, uint8_t *image_data,
3686 const VARectangle *src_rect)
3688 uint8_t *dst[3], *src[3];
3690 const int U = obj_image->image.format.fourcc == obj_surface->fourcc ? 1 : 2;
3691 const int V = obj_image->image.format.fourcc == obj_surface->fourcc ? 2 : 1;
3692 unsigned int tiling, swizzle;
3693 VAStatus va_status = VA_STATUS_SUCCESS;
3695 ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
3697 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3698 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
3699 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
3700 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3702 if (tiling != I915_TILING_NONE)
3703 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3705 dri_bo_map(obj_surface->bo, 0);
3707 if (!obj_surface->bo->virtual)
3708 return VA_STATUS_ERROR_INVALID_SURFACE;
3710 /* Dest VA image has either I420 or YV12 format.
3711 Source VA surface alway has I420 format */
3712 dst[0] = (uint8_t *)obj_surface->bo->virtual;
3713 src[Y] = image_data + obj_image->image.offsets[Y];
3714 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
3715 src[U] = image_data + obj_image->image.offsets[U];
3716 dst[2] = dst[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
3717 src[V] = image_data + obj_image->image.offsets[V];
3720 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
3721 src[Y] += src_rect->y * obj_image->image.pitches[Y] + src_rect->x;
3722 memcpy_pic(dst[0], obj_surface->width,
3723 src[Y], obj_image->image.pitches[Y],
3724 src_rect->width, src_rect->height);
3727 dst[1] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
3728 src[U] += (src_rect->y / 2) * obj_image->image.pitches[U] + src_rect->x / 2;
3729 memcpy_pic(dst[1], obj_surface->width / 2,
3730 src[U], obj_image->image.pitches[U],
3731 src_rect->width / 2, src_rect->height / 2);
3734 dst[2] += (dst_rect->y / 2) * obj_surface->width / 2 + dst_rect->x / 2;
3735 src[V] += (src_rect->y / 2) * obj_image->image.pitches[V] + src_rect->x / 2;
3736 memcpy_pic(dst[2], obj_surface->width / 2,
3737 src[V], obj_image->image.pitches[V],
3738 src_rect->width / 2, src_rect->height / 2);
3740 if (tiling != I915_TILING_NONE)
3741 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3743 dri_bo_unmap(obj_surface->bo);
3749 put_image_nv12(struct object_surface *obj_surface,
3750 const VARectangle *dst_rect,
3751 struct object_image *obj_image, uint8_t *image_data,
3752 const VARectangle *src_rect)
3754 uint8_t *dst[2], *src[2];
3755 unsigned int tiling, swizzle;
3756 VAStatus va_status = VA_STATUS_SUCCESS;
3758 if (!obj_surface->bo)
3759 return VA_STATUS_ERROR_INVALID_SURFACE;
3761 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3762 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
3763 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
3764 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3766 if (tiling != I915_TILING_NONE)
3767 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3769 dri_bo_map(obj_surface->bo, 0);
3771 if (!obj_surface->bo->virtual)
3772 return VA_STATUS_ERROR_INVALID_SURFACE;
3774 /* Both dest VA image and source surface have NV12 format */
3775 dst[0] = (uint8_t *)obj_surface->bo->virtual;
3776 src[0] = image_data + obj_image->image.offsets[0];
3777 dst[1] = dst[0] + obj_surface->width * obj_surface->height;
3778 src[1] = image_data + obj_image->image.offsets[1];
3781 dst[0] += dst_rect->y * obj_surface->width + dst_rect->x;
3782 src[0] += src_rect->y * obj_image->image.pitches[0] + src_rect->x;
3783 memcpy_pic(dst[0], obj_surface->width,
3784 src[0], obj_image->image.pitches[0],
3785 src_rect->width, src_rect->height);
3788 dst[1] += (dst_rect->y / 2) * obj_surface->width + (dst_rect->x & -2);
3789 src[1] += (src_rect->y / 2) * obj_image->image.pitches[1] + (src_rect->x & -2);
3790 memcpy_pic(dst[1], obj_surface->width,
3791 src[1], obj_image->image.pitches[1],
3792 src_rect->width, src_rect->height / 2);
3794 if (tiling != I915_TILING_NONE)
3795 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3797 dri_bo_unmap(obj_surface->bo);
3803 put_image_yuy2(struct object_surface *obj_surface,
3804 const VARectangle *dst_rect,
3805 struct object_image *obj_image, uint8_t *image_data,
3806 const VARectangle *src_rect)
3809 unsigned int tiling, swizzle;
3810 VAStatus va_status = VA_STATUS_SUCCESS;
3812 ASSERT_RET(obj_surface->bo, VA_STATUS_ERROR_INVALID_SURFACE);
3813 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3814 ASSERT_RET(dst_rect->width == src_rect->width, VA_STATUS_ERROR_UNIMPLEMENTED);
3815 ASSERT_RET(dst_rect->height == src_rect->height, VA_STATUS_ERROR_UNIMPLEMENTED);
3816 dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
3818 if (tiling != I915_TILING_NONE)
3819 drm_intel_gem_bo_map_gtt(obj_surface->bo);
3821 dri_bo_map(obj_surface->bo, 0);
3823 if (!obj_surface->bo->virtual)
3824 return VA_STATUS_ERROR_INVALID_SURFACE;
3826 /* Both dest VA image and source surface have YUY2 format */
3827 dst = (uint8_t *)obj_surface->bo->virtual;
3828 src = image_data + obj_image->image.offsets[0];
3830 /* YUYV packed plane */
3831 dst += dst_rect->y * obj_surface->width + dst_rect->x*2;
3832 src += src_rect->y * obj_image->image.pitches[0] + src_rect->x*2;
3833 memcpy_pic(dst, obj_surface->width*2,
3834 src, obj_image->image.pitches[0],
3835 src_rect->width*2, src_rect->height);
3837 if (tiling != I915_TILING_NONE)
3838 drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
3840 dri_bo_unmap(obj_surface->bo);
3847 i965_sw_putimage(VADriverContextP ctx,
3848 VASurfaceID surface,
3852 unsigned int src_width,
3853 unsigned int src_height,
3856 unsigned int dest_width,
3857 unsigned int dest_height)
3859 struct i965_driver_data *i965 = i965_driver_data(ctx);
3860 struct object_surface *obj_surface = SURFACE(surface);
3861 struct object_image *obj_image = IMAGE(image);
3862 VAStatus va_status = VA_STATUS_SUCCESS;
3863 void *image_data = NULL;
3865 ASSERT_RET(obj_surface, VA_STATUS_ERROR_INVALID_SURFACE);
3866 ASSERT_RET(obj_image, VA_STATUS_ERROR_INVALID_IMAGE);
3868 if (src_x < 0 || src_y < 0)
3869 return VA_STATUS_ERROR_INVALID_PARAMETER;
3870 if (src_x + src_width > obj_image->image.width ||
3871 src_y + src_height > obj_image->image.height)
3872 return VA_STATUS_ERROR_INVALID_PARAMETER;
3873 if (dest_x < 0 || dest_y < 0)
3874 return VA_STATUS_ERROR_INVALID_PARAMETER;
3875 if (dest_x + dest_width > obj_surface->orig_width ||
3876 dest_y + dest_height > obj_surface->orig_height)
3877 return VA_STATUS_ERROR_INVALID_PARAMETER;
3879 /* XXX: don't allow scaling */
3880 if (src_width != dest_width || src_height != dest_height)
3881 return VA_STATUS_ERROR_INVALID_PARAMETER;
3883 if (obj_surface->fourcc) {
3884 /* Don't allow format mismatch */
3885 if (obj_surface->fourcc != obj_image->image.format.fourcc)
3886 return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
3890 /* VA is surface not used for decoding, use same VA image format */
3891 va_status = i965_check_alloc_surface_bo(
3894 0, /* XXX: don't use tiled surface */
3895 obj_image->image.format.fourcc,
3896 get_sampling_from_fourcc (obj_image->image.format.fourcc));
3899 if (va_status != VA_STATUS_SUCCESS)
3902 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
3903 if (va_status != VA_STATUS_SUCCESS)
3906 VARectangle src_rect, dest_rect;
3909 src_rect.width = src_width;
3910 src_rect.height = src_height;
3911 dest_rect.x = dest_x;
3912 dest_rect.y = dest_y;
3913 dest_rect.width = dest_width;
3914 dest_rect.height = dest_height;
3916 switch (obj_image->image.format.fourcc) {
3917 case VA_FOURCC_YV12:
3918 case VA_FOURCC_I420:
3919 va_status = put_image_i420(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
3921 case VA_FOURCC_NV12:
3922 va_status = put_image_nv12(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
3924 case VA_FOURCC_YUY2:
3925 va_status = put_image_yuy2(obj_surface, &dest_rect, obj_image, image_data, &src_rect);
3928 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
3931 if (va_status != VA_STATUS_SUCCESS)
3934 va_status = i965_UnmapBuffer(ctx, obj_image->image.buf);
3939 i965_hw_putimage(VADriverContextP ctx,
3940 VASurfaceID surface,
3944 unsigned int src_width,
3945 unsigned int src_height,
3948 unsigned int dest_width,
3949 unsigned int dest_height)
3951 struct i965_driver_data *i965 = i965_driver_data(ctx);
3952 struct object_surface *obj_surface = SURFACE(surface);
3953 struct object_image *obj_image = IMAGE(image);
3954 struct i965_surface src_surface, dst_surface;
3955 VAStatus va_status = VA_STATUS_SUCCESS;
3956 VARectangle src_rect, dst_rect;
3958 ASSERT_RET(obj_surface,VA_STATUS_ERROR_INVALID_SURFACE);
3959 ASSERT_RET(obj_image && obj_image->bo, VA_STATUS_ERROR_INVALID_IMAGE);
3963 src_x + src_width > obj_image->image.width ||
3964 src_y + src_height > obj_image->image.height)
3965 return VA_STATUS_ERROR_INVALID_PARAMETER;
3969 dest_x + dest_width > obj_surface->orig_width ||
3970 dest_y + dest_height > obj_surface->orig_height)
3971 return VA_STATUS_ERROR_INVALID_PARAMETER;
3973 if (!obj_surface->bo) {
3974 unsigned int tiling, swizzle;
3975 int surface_sampling = get_sampling_from_fourcc (obj_image->image.format.fourcc);;
3976 dri_bo_get_tiling(obj_image->bo, &tiling, &swizzle);
3978 i965_check_alloc_surface_bo(ctx,
3981 obj_image->image.format.fourcc,
3985 ASSERT_RET(obj_surface->fourcc, VA_STATUS_ERROR_INVALID_SURFACE);
3987 src_surface.base = (struct object_base *)obj_image;
3988 src_surface.type = I965_SURFACE_TYPE_IMAGE;
3989 src_surface.flags = I965_SURFACE_FLAG_FRAME;
3992 src_rect.width = src_width;
3993 src_rect.height = src_height;
3995 dst_surface.base = (struct object_base *)obj_surface;
3996 dst_surface.type = I965_SURFACE_TYPE_SURFACE;
3997 dst_surface.flags = I965_SURFACE_FLAG_FRAME;
3998 dst_rect.x = dest_x;
3999 dst_rect.y = dest_y;
4000 dst_rect.width = dest_width;
4001 dst_rect.height = dest_height;
4003 va_status = i965_image_processing(ctx,
4013 i965_PutImage(VADriverContextP ctx,
4014 VASurfaceID surface,
4018 unsigned int src_width,
4019 unsigned int src_height,
4022 unsigned int dest_width,
4023 unsigned int dest_height)
4025 struct i965_driver_data *i965 = i965_driver_data(ctx);
4026 VAStatus va_status = VA_STATUS_SUCCESS;
4028 if (HAS_ACCELERATED_PUTIMAGE(i965))
4029 va_status = i965_hw_putimage(ctx,
4041 va_status = i965_sw_putimage(ctx,
4057 i965_PutSurface(VADriverContextP ctx,
4058 VASurfaceID surface,
4059 void *draw, /* X Drawable */
4062 unsigned short srcw,
4063 unsigned short srch,
4066 unsigned short destw,
4067 unsigned short desth,
4068 VARectangle *cliprects, /* client supplied clip list */
4069 unsigned int number_cliprects, /* number of clip rects in the clip list */
4070 unsigned int flags) /* de-interlacing flags */
4073 if (IS_VA_X11(ctx)) {
4074 VARectangle src_rect, dst_rect;
4078 src_rect.width = srcw;
4079 src_rect.height = srch;
4083 dst_rect.width = destw;
4084 dst_rect.height = desth;
4086 return i965_put_surface_dri(ctx, surface, draw, &src_rect, &dst_rect,
4087 cliprects, number_cliprects, flags);
4090 return VA_STATUS_ERROR_UNIMPLEMENTED;
4095 VADriverContextP ctx, /* in */
4096 VABufferID buf_id, /* in */
4097 VABufferType *type, /* out */
4098 unsigned int *size, /* out */
4099 unsigned int *num_elements /* out */
4102 struct i965_driver_data *i965 = NULL;
4103 struct object_buffer *obj_buffer = NULL;
4105 i965 = i965_driver_data(ctx);
4106 obj_buffer = BUFFER(buf_id);
4108 ASSERT_RET(obj_buffer, VA_STATUS_ERROR_INVALID_BUFFER);
4110 *type = obj_buffer->type;
4111 *size = obj_buffer->size_element;
4112 *num_elements = obj_buffer->num_elements;
4114 return VA_STATUS_SUCCESS;
4119 VADriverContextP ctx, /* in */
4120 VASurfaceID surface, /* in */
4121 unsigned int *fourcc, /* out */
4122 unsigned int *luma_stride, /* out */
4123 unsigned int *chroma_u_stride, /* out */
4124 unsigned int *chroma_v_stride, /* out */
4125 unsigned int *luma_offset, /* out */
4126 unsigned int *chroma_u_offset, /* out */
4127 unsigned int *chroma_v_offset, /* out */
4128 unsigned int *buffer_name, /* out */
4129 void **buffer /* out */
4132 VAStatus vaStatus = VA_STATUS_SUCCESS;
4133 struct i965_driver_data *i965 = i965_driver_data(ctx);
4134 struct object_surface *obj_surface = NULL;
4137 ASSERT_RET(fourcc, VA_STATUS_ERROR_INVALID_PARAMETER);
4138 ASSERT_RET(luma_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4139 ASSERT_RET(chroma_u_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4140 ASSERT_RET(chroma_v_stride, VA_STATUS_ERROR_INVALID_PARAMETER);
4141 ASSERT_RET(luma_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4142 ASSERT_RET(chroma_u_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4143 ASSERT_RET(chroma_v_offset, VA_STATUS_ERROR_INVALID_PARAMETER);
4144 ASSERT_RET(buffer_name, VA_STATUS_ERROR_INVALID_PARAMETER);
4145 ASSERT_RET(buffer, VA_STATUS_ERROR_INVALID_PARAMETER);
4147 tmpImage.image_id = VA_INVALID_ID;
4149 obj_surface = SURFACE(surface);
4150 if (obj_surface == NULL) {
4151 // Surface is absent.
4152 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4156 // Lock functionality is absent now.
4157 if (obj_surface->locked_image_id != VA_INVALID_ID) {
4158 // Surface is locked already.
4159 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4163 vaStatus = i965_DeriveImage(
4167 if (vaStatus != VA_STATUS_SUCCESS) {
4171 obj_surface->locked_image_id = tmpImage.image_id;
4173 vaStatus = i965_MapBuffer(
4177 if (vaStatus != VA_STATUS_SUCCESS) {
4181 *fourcc = tmpImage.format.fourcc;
4182 *luma_offset = tmpImage.offsets[0];
4183 *luma_stride = tmpImage.pitches[0];
4184 *chroma_u_offset = tmpImage.offsets[1];
4185 *chroma_u_stride = tmpImage.pitches[1];
4186 *chroma_v_offset = tmpImage.offsets[2];
4187 *chroma_v_stride = tmpImage.pitches[2];
4188 *buffer_name = tmpImage.buf;
4191 if (vaStatus != VA_STATUS_SUCCESS) {
4200 VADriverContextP ctx, /* in */
4201 VASurfaceID surface /* in */
4204 VAStatus vaStatus = VA_STATUS_SUCCESS;
4205 struct i965_driver_data *i965 = i965_driver_data(ctx);
4206 struct object_image *locked_img = NULL;
4207 struct object_surface *obj_surface = NULL;
4209 obj_surface = SURFACE(surface);
4211 if (obj_surface == NULL) {
4212 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is absent
4215 if (obj_surface->locked_image_id == VA_INVALID_ID) {
4216 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; // Surface is not locked
4220 locked_img = IMAGE(obj_surface->locked_image_id);
4221 if (locked_img == NULL || (locked_img->image.image_id == VA_INVALID_ID)) {
4222 // Work image was deallocated before i965_UnlockSurface()
4223 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
4227 vaStatus = i965_UnmapBuffer(
4229 locked_img->image.buf);
4230 if (vaStatus != VA_STATUS_SUCCESS) {
4234 vaStatus = i965_DestroyImage(
4236 locked_img->image.image_id);
4237 if (vaStatus != VA_STATUS_SUCCESS) {
4241 locked_img->image.image_id = VA_INVALID_ID;
4244 obj_surface->locked_image_id = VA_INVALID_ID;
4250 i965_GetSurfaceAttributes(
4251 VADriverContextP ctx,
4253 VASurfaceAttrib *attrib_list,
4254 unsigned int num_attribs
4257 VAStatus vaStatus = VA_STATUS_SUCCESS;
4258 struct i965_driver_data *i965 = i965_driver_data(ctx);
4259 struct object_config *obj_config;
4262 if (config == VA_INVALID_ID)
4263 return VA_STATUS_ERROR_INVALID_CONFIG;
4265 obj_config = CONFIG(config);
4267 if (obj_config == NULL)
4268 return VA_STATUS_ERROR_INVALID_CONFIG;
4270 if (attrib_list == NULL || num_attribs == 0)
4271 return VA_STATUS_ERROR_INVALID_PARAMETER;
4273 for (i = 0; i < num_attribs; i++) {
4274 switch (attrib_list[i].type) {
4275 case VASurfaceAttribPixelFormat:
4276 attrib_list[i].value.type = VAGenericValueTypeInteger;
4277 attrib_list[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4279 if (attrib_list[i].value.value.i == 0) {
4280 if (IS_G4X(i965->intel.device_info)) {
4281 if (obj_config->profile == VAProfileMPEG2Simple ||
4282 obj_config->profile == VAProfileMPEG2Main) {
4283 attrib_list[i].value.value.i = VA_FOURCC_I420;
4286 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4288 } else if (IS_IRONLAKE(i965->intel.device_info)) {
4289 if (obj_config->profile == VAProfileMPEG2Simple ||
4290 obj_config->profile == VAProfileMPEG2Main) {
4291 attrib_list[i].value.value.i = VA_FOURCC_I420;
4292 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
4293 obj_config->profile == VAProfileH264Main ||
4294 obj_config->profile == VAProfileH264High) {
4295 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4296 } else if (obj_config->profile == VAProfileNone) {
4297 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4300 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4302 } else if (IS_GEN6(i965->intel.device_info)) {
4303 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4304 } else if (IS_GEN7(i965->intel.device_info) ||
4305 IS_GEN8(i965->intel.device_info)) {
4306 if (obj_config->profile == VAProfileJPEGBaseline)
4307 attrib_list[i].value.value.i = 0; /* internal format */
4309 attrib_list[i].value.value.i = VA_FOURCC_NV12;
4312 if (IS_G4X(i965->intel.device_info)) {
4313 if (obj_config->profile == VAProfileMPEG2Simple ||
4314 obj_config->profile == VAProfileMPEG2Main) {
4315 if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
4316 attrib_list[i].value.value.i = 0;
4317 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4321 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4323 } else if (IS_IRONLAKE(i965->intel.device_info)) {
4324 if (obj_config->profile == VAProfileMPEG2Simple ||
4325 obj_config->profile == VAProfileMPEG2Main) {
4326 if (attrib_list[i].value.value.i != VA_FOURCC_I420) {
4327 attrib_list[i].value.value.i = 0;
4328 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4330 } else if (obj_config->profile == VAProfileH264ConstrainedBaseline ||
4331 obj_config->profile == VAProfileH264Main ||
4332 obj_config->profile == VAProfileH264High) {
4333 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4334 attrib_list[i].value.value.i = 0;
4335 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4337 } else if (obj_config->profile == VAProfileNone) {
4338 switch (attrib_list[i].value.value.i) {
4339 case VA_FOURCC_NV12:
4340 case VA_FOURCC_I420:
4341 case VA_FOURCC_YV12:
4342 case VA_FOURCC_YUY2:
4343 case VA_FOURCC_BGRA:
4344 case VA_FOURCC_BGRX:
4345 case VA_FOURCC_RGBX:
4346 case VA_FOURCC_RGBA:
4349 attrib_list[i].value.value.i = 0;
4350 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4355 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4357 } else if (IS_GEN6(i965->intel.device_info)) {
4358 if (obj_config->entrypoint == VAEntrypointEncSlice ||
4359 obj_config->entrypoint == VAEntrypointVideoProc) {
4360 switch (attrib_list[i].value.value.i) {
4361 case VA_FOURCC_NV12:
4362 case VA_FOURCC_I420:
4363 case VA_FOURCC_YV12:
4364 case VA_FOURCC_YUY2:
4365 case VA_FOURCC_BGRA:
4366 case VA_FOURCC_BGRX:
4367 case VA_FOURCC_RGBX:
4368 case VA_FOURCC_RGBA:
4371 attrib_list[i].value.value.i = 0;
4372 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4376 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4377 attrib_list[i].value.value.i = 0;
4378 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4381 } else if (IS_GEN7(i965->intel.device_info) ||
4382 IS_GEN8(i965->intel.device_info)) {
4383 if (obj_config->entrypoint == VAEntrypointEncSlice ||
4384 obj_config->entrypoint == VAEntrypointVideoProc) {
4385 switch (attrib_list[i].value.value.i) {
4386 case VA_FOURCC_NV12:
4387 case VA_FOURCC_I420:
4388 case VA_FOURCC_YV12:
4391 attrib_list[i].value.value.i = 0;
4392 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4396 if (obj_config->profile == VAProfileJPEGBaseline) {
4397 attrib_list[i].value.value.i = 0; /* JPEG decoding always uses an internal format */
4398 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4400 if (attrib_list[i].value.value.i != VA_FOURCC_NV12) {
4401 attrib_list[i].value.value.i = 0;
4402 attrib_list[i].flags &= ~VA_SURFACE_ATTRIB_SETTABLE;
4410 case VASurfaceAttribMinWidth:
4411 /* FIXME: add support for it later */
4412 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4414 case VASurfaceAttribMaxWidth:
4415 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4417 case VASurfaceAttribMinHeight:
4418 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4420 case VASurfaceAttribMaxHeight:
4421 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4424 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
4433 i965_QuerySurfaceAttributes(VADriverContextP ctx,
4435 VASurfaceAttrib *attrib_list,
4436 unsigned int *num_attribs)
4438 VAStatus vaStatus = VA_STATUS_SUCCESS;
4439 struct i965_driver_data *i965 = i965_driver_data(ctx);
4440 struct object_config *obj_config;
4442 VASurfaceAttrib *attribs = NULL;
4444 if (config == VA_INVALID_ID)
4445 return VA_STATUS_ERROR_INVALID_CONFIG;
4447 obj_config = CONFIG(config);
4449 if (obj_config == NULL)
4450 return VA_STATUS_ERROR_INVALID_CONFIG;
4452 if (!attrib_list && !num_attribs)
4453 return VA_STATUS_ERROR_INVALID_PARAMETER;
4455 if (attrib_list == NULL) {
4456 *num_attribs = I965_MAX_SURFACE_ATTRIBUTES;
4457 return VA_STATUS_SUCCESS;
4460 attribs = malloc(I965_MAX_SURFACE_ATTRIBUTES *sizeof(*attribs));
4462 if (attribs == NULL)
4463 return VA_STATUS_ERROR_ALLOCATION_FAILED;
4465 if (IS_G4X(i965->intel.device_info)) {
4466 if (obj_config->profile == VAProfileMPEG2Simple ||
4467 obj_config->profile == VAProfileMPEG2Main) {
4468 attribs[i].type = VASurfaceAttribPixelFormat;
4469 attribs[i].value.type = VAGenericValueTypeInteger;
4470 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4471 attribs[i].value.value.i = VA_FOURCC_I420;
4474 } else if (IS_IRONLAKE(i965->intel.device_info)) {
4475 switch (obj_config->profile) {
4476 case VAProfileMPEG2Simple:
4477 case VAProfileMPEG2Main:
4478 attribs[i].type = VASurfaceAttribPixelFormat;
4479 attribs[i].value.type = VAGenericValueTypeInteger;
4480 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4481 attribs[i].value.value.i = VA_FOURCC_I420;
4486 case VAProfileH264ConstrainedBaseline:
4487 case VAProfileH264Main:
4488 case VAProfileH264High:
4489 attribs[i].type = VASurfaceAttribPixelFormat;
4490 attribs[i].value.type = VAGenericValueTypeInteger;
4491 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4492 attribs[i].value.value.i = VA_FOURCC_NV12;
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_NV12;
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_I420;
4513 } else if (IS_GEN6(i965->intel.device_info)) {
4514 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
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_NV12;
4520 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
4521 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4522 attribs[i].type = VASurfaceAttribPixelFormat;
4523 attribs[i].value.type = VAGenericValueTypeInteger;
4524 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4525 attribs[i].value.value.i = VA_FOURCC_NV12;
4528 attribs[i].type = VASurfaceAttribPixelFormat;
4529 attribs[i].value.type = VAGenericValueTypeInteger;
4530 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4531 attribs[i].value.value.i = VA_FOURCC_I420;
4534 attribs[i].type = VASurfaceAttribPixelFormat;
4535 attribs[i].value.type = VAGenericValueTypeInteger;
4536 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4537 attribs[i].value.value.i = VA_FOURCC_YV12;
4540 if (obj_config->entrypoint == VAEntrypointVideoProc) {
4541 attribs[i].type = VASurfaceAttribPixelFormat;
4542 attribs[i].value.type = VAGenericValueTypeInteger;
4543 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4544 attribs[i].value.value.i = VA_FOURCC_YUY2;
4547 attribs[i].type = VASurfaceAttribPixelFormat;
4548 attribs[i].value.type = VAGenericValueTypeInteger;
4549 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4550 attribs[i].value.value.i = VA_FOURCC_RGBA;
4553 attribs[i].type = VASurfaceAttribPixelFormat;
4554 attribs[i].value.type = VAGenericValueTypeInteger;
4555 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4556 attribs[i].value.value.i = VA_FOURCC_RGBX;
4560 } else if (IS_GEN7(i965->intel.device_info)) {
4561 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4562 if (obj_config->profile == VAProfileJPEGBaseline) {
4563 attribs[i].type = VASurfaceAttribPixelFormat;
4564 attribs[i].value.type = VAGenericValueTypeInteger;
4565 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4566 attribs[i].value.value.i = VA_FOURCC_IMC3;
4569 attribs[i].type = VASurfaceAttribPixelFormat;
4570 attribs[i].value.type = VAGenericValueTypeInteger;
4571 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4572 attribs[i].value.value.i = VA_FOURCC_IMC1;
4575 attribs[i].type = VASurfaceAttribPixelFormat;
4576 attribs[i].value.type = VAGenericValueTypeInteger;
4577 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4578 attribs[i].value.value.i = VA_FOURCC_Y800;
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_411P;
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_422H;
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_422V;
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_444P;
4605 attribs[i].type = VASurfaceAttribPixelFormat;
4606 attribs[i].value.type = VAGenericValueTypeInteger;
4607 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4608 attribs[i].value.value.i = VA_FOURCC_NV12;
4611 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
4612 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4613 attribs[i].type = VASurfaceAttribPixelFormat;
4614 attribs[i].value.type = VAGenericValueTypeInteger;
4615 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4616 attribs[i].value.value.i = VA_FOURCC_NV12;
4619 attribs[i].type = VASurfaceAttribPixelFormat;
4620 attribs[i].value.type = VAGenericValueTypeInteger;
4621 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4622 attribs[i].value.value.i = VA_FOURCC_I420;
4625 attribs[i].type = VASurfaceAttribPixelFormat;
4626 attribs[i].value.type = VAGenericValueTypeInteger;
4627 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4628 attribs[i].value.value.i = VA_FOURCC_YV12;
4631 attribs[i].type = VASurfaceAttribPixelFormat;
4632 attribs[i].value.type = VAGenericValueTypeInteger;
4633 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4634 attribs[i].value.value.i = VA_FOURCC_IMC3;
4637 if (obj_config->entrypoint == VAEntrypointVideoProc) {
4638 attribs[i].type = VASurfaceAttribPixelFormat;
4639 attribs[i].value.type = VAGenericValueTypeInteger;
4640 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4641 attribs[i].value.value.i = VA_FOURCC_YUY2;
4644 attribs[i].type = VASurfaceAttribPixelFormat;
4645 attribs[i].value.type = VAGenericValueTypeInteger;
4646 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4647 attribs[i].value.value.i = VA_FOURCC_RGBA;
4650 attribs[i].type = VASurfaceAttribPixelFormat;
4651 attribs[i].value.type = VAGenericValueTypeInteger;
4652 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4653 attribs[i].value.value.i = VA_FOURCC_RGBX;
4656 attribs[i].type = VASurfaceAttribPixelFormat;
4657 attribs[i].value.type = VAGenericValueTypeInteger;
4658 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4659 attribs[i].value.value.i = VA_FOURCC_YV16;
4663 } else if (IS_GEN8(i965->intel.device_info)) {
4664 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
4665 if (obj_config->profile == VAProfileJPEGBaseline) {
4666 attribs[i].type = VASurfaceAttribPixelFormat;
4667 attribs[i].value.type = VAGenericValueTypeInteger;
4668 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4669 attribs[i].value.value.i = VA_FOURCC_IMC3;
4672 attribs[i].type = VASurfaceAttribPixelFormat;
4673 attribs[i].value.type = VAGenericValueTypeInteger;
4674 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4675 attribs[i].value.value.i = VA_FOURCC_IMC1;
4678 attribs[i].type = VASurfaceAttribPixelFormat;
4679 attribs[i].value.type = VAGenericValueTypeInteger;
4680 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4681 attribs[i].value.value.i = VA_FOURCC_Y800;
4684 attribs[i].type = VASurfaceAttribPixelFormat;
4685 attribs[i].value.type = VAGenericValueTypeInteger;
4686 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4687 attribs[i].value.value.i = VA_FOURCC_411P;
4690 attribs[i].type = VASurfaceAttribPixelFormat;
4691 attribs[i].value.type = VAGenericValueTypeInteger;
4692 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4693 attribs[i].value.value.i = VA_FOURCC_422H;
4696 attribs[i].type = VASurfaceAttribPixelFormat;
4697 attribs[i].value.type = VAGenericValueTypeInteger;
4698 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4699 attribs[i].value.value.i = VA_FOURCC_422V;
4702 attribs[i].type = VASurfaceAttribPixelFormat;
4703 attribs[i].value.type = VAGenericValueTypeInteger;
4704 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4705 attribs[i].value.value.i = VA_FOURCC_444P;
4708 attribs[i].type = VASurfaceAttribPixelFormat;
4709 attribs[i].value.type = VAGenericValueTypeInteger;
4710 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4711 attribs[i].value.value.i = VA_FOURCC_NV12;
4714 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
4715 obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
4717 attribs[i].type = VASurfaceAttribPixelFormat;
4718 attribs[i].value.type = VAGenericValueTypeInteger;
4719 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4720 attribs[i].value.value.i = VA_FOURCC_NV12;
4723 attribs[i].type = VASurfaceAttribPixelFormat;
4724 attribs[i].value.type = VAGenericValueTypeInteger;
4725 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4726 attribs[i].value.value.i = VA_FOURCC_I420;
4729 attribs[i].type = VASurfaceAttribPixelFormat;
4730 attribs[i].value.type = VAGenericValueTypeInteger;
4731 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4732 attribs[i].value.value.i = VA_FOURCC_YV12;
4735 attribs[i].type = VASurfaceAttribPixelFormat;
4736 attribs[i].value.type = VAGenericValueTypeInteger;
4737 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4738 attribs[i].value.value.i = VA_FOURCC_IMC3;
4741 if (obj_config->entrypoint == VAEntrypointVideoProc) {
4742 attribs[i].type = VASurfaceAttribPixelFormat;
4743 attribs[i].value.type = VAGenericValueTypeInteger;
4744 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4745 attribs[i].value.value.i = VA_FOURCC_YUY2;
4748 attribs[i].type = VASurfaceAttribPixelFormat;
4749 attribs[i].value.type = VAGenericValueTypeInteger;
4750 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4751 attribs[i].value.value.i = VA_FOURCC_RGBA;
4754 attribs[i].type = VASurfaceAttribPixelFormat;
4755 attribs[i].value.type = VAGenericValueTypeInteger;
4756 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4757 attribs[i].value.value.i = VA_FOURCC_RGBX;
4760 attribs[i].type = VASurfaceAttribPixelFormat;
4761 attribs[i].value.type = VAGenericValueTypeInteger;
4762 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4763 attribs[i].value.value.i = VA_FOURCC_BGRA;
4766 attribs[i].type = VASurfaceAttribPixelFormat;
4767 attribs[i].value.type = VAGenericValueTypeInteger;
4768 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4769 attribs[i].value.value.i = VA_FOURCC_BGRX;
4772 attribs[i].type = VASurfaceAttribPixelFormat;
4773 attribs[i].value.type = VAGenericValueTypeInteger;
4774 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4775 attribs[i].value.value.i = VA_FOURCC_YV16;
4781 attribs[i].type = VASurfaceAttribMemoryType;
4782 attribs[i].value.type = VAGenericValueTypeInteger;
4783 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
4784 attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
4785 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
4786 VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
4789 attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
4790 attribs[i].value.type = VAGenericValueTypePointer;
4791 attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
4792 attribs[i].value.value.p = NULL; /* ignore */
4795 if (i > *num_attribs) {
4798 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4802 memcpy(attrib_list, attribs, i * sizeof(*attribs));
4809 i965_os_has_ring_support(VADriverContextP ctx,
4812 struct i965_driver_data *const i965 = i965_driver_data(ctx);
4816 return i965->intel.has_bsd;
4819 return i965->intel.has_blt;
4821 case I965_RING_VEBOX:
4822 return i965->intel.has_vebox;
4824 case I965_RING_NULL:
4825 return 1; /* Always support */
4828 /* should never get here */
4837 * Query video processing pipeline
4839 VAStatus i965_QueryVideoProcFilters(
4840 VADriverContextP ctx,
4841 VAContextID context,
4842 VAProcFilterType *filters,
4843 unsigned int *num_filters
4846 struct i965_driver_data *const i965 = i965_driver_data(ctx);
4847 unsigned int i = 0, num = 0;
4849 if (!num_filters || !filters)
4850 return VA_STATUS_ERROR_INVALID_PARAMETER;
4852 for (i = 0; i < i965->codec_info->num_filters; i++) {
4853 if (i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring)) {
4854 if (num == *num_filters) {
4855 *num_filters = i965->codec_info->num_filters;
4857 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4860 filters[num++] = i965->codec_info->filters[i].type;
4866 return VA_STATUS_SUCCESS;
4869 VAStatus i965_QueryVideoProcFilterCaps(
4870 VADriverContextP ctx,
4871 VAContextID context,
4872 VAProcFilterType type,
4874 unsigned int *num_filter_caps
4878 struct i965_driver_data *const i965 = i965_driver_data(ctx);
4880 if (!filter_caps || !num_filter_caps)
4881 return VA_STATUS_ERROR_INVALID_PARAMETER;
4883 for (i = 0; i < i965->codec_info->num_filters; i++) {
4884 if (type == i965->codec_info->filters[i].type &&
4885 i965_os_has_ring_support(ctx, i965->codec_info->filters[i].ring))
4889 if (i == i965->codec_info->num_filters)
4890 return VA_STATUS_ERROR_UNSUPPORTED_FILTER;
4895 case VAProcFilterNoiseReduction:
4896 case VAProcFilterSharpening:
4898 VAProcFilterCap *cap = filter_caps;
4900 if (*num_filter_caps < 1) {
4901 *num_filter_caps = 1;
4902 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4905 cap->range.min_value = 0.0;
4906 cap->range.max_value = 1.0;
4907 cap->range.default_value = 0.5;
4908 cap->range.step = 0.03125; /* 1.0 / 32 */
4914 case VAProcFilterDeinterlacing:
4916 VAProcFilterCapDeinterlacing *cap = filter_caps;
4918 if (*num_filter_caps < VAProcDeinterlacingCount) {
4919 *num_filter_caps = VAProcDeinterlacingCount;
4920 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4923 cap->type = VAProcDeinterlacingBob;
4928 if (i965->codec_info->has_di_motion_adptive) {
4929 cap->type = VAProcDeinterlacingMotionAdaptive;
4934 if (i965->codec_info->has_di_motion_compensated) {
4935 cap->type = VAProcDeinterlacingMotionCompensated;
4943 case VAProcFilterColorBalance:
4945 VAProcFilterCapColorBalance *cap = filter_caps;
4947 if (*num_filter_caps < VAProcColorBalanceCount) {
4948 *num_filter_caps = VAProcColorBalanceCount;
4949 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
4952 cap->type = VAProcColorBalanceHue;
4953 cap->range.min_value = -180.0;
4954 cap->range.max_value = 180.0;
4955 cap->range.default_value = 0.0;
4956 cap->range.step = 1.0;
4960 cap->type = VAProcColorBalanceSaturation;
4961 cap->range.min_value = 0.0;
4962 cap->range.max_value = 10.0;
4963 cap->range.default_value = 1.0;
4964 cap->range.step = 0.1;
4968 cap->type = VAProcColorBalanceBrightness;
4969 cap->range.min_value = -100.0;
4970 cap->range.max_value = 100.0;
4971 cap->range.default_value = 0.0;
4972 cap->range.step = 1.0;
4976 cap->type = VAProcColorBalanceContrast;
4977 cap->range.min_value = 0.0;
4978 cap->range.max_value = 10.0;
4979 cap->range.default_value = 1.0;
4980 cap->range.step = 0.1;
4992 *num_filter_caps = i;
4994 return VA_STATUS_SUCCESS;
4997 static VAProcColorStandardType vpp_input_color_standards[VAProcColorStandardCount] = {
4998 VAProcColorStandardBT601,
5001 static VAProcColorStandardType vpp_output_color_standards[VAProcColorStandardCount] = {
5002 VAProcColorStandardBT601,
5005 VAStatus i965_QueryVideoProcPipelineCaps(
5006 VADriverContextP ctx,
5007 VAContextID context,
5008 VABufferID *filters,
5009 unsigned int num_filters,
5010 VAProcPipelineCaps *pipeline_cap /* out */
5013 struct i965_driver_data * const i965 = i965_driver_data(ctx);
5016 pipeline_cap->pipeline_flags = 0;
5017 pipeline_cap->filter_flags = 0;
5018 pipeline_cap->num_forward_references = 0;
5019 pipeline_cap->num_backward_references = 0;
5020 pipeline_cap->num_input_color_standards = 1;
5021 pipeline_cap->input_color_standards = vpp_input_color_standards;
5022 pipeline_cap->num_output_color_standards = 1;
5023 pipeline_cap->output_color_standards = vpp_output_color_standards;
5025 for (i = 0; i < num_filters; i++) {
5026 struct object_buffer *obj_buffer = BUFFER(filters[i]);
5029 !obj_buffer->buffer_store ||
5030 !obj_buffer->buffer_store->buffer)
5031 return VA_STATUS_ERROR_INVALID_BUFFER;
5033 VAProcFilterParameterBufferBase *base = (VAProcFilterParameterBufferBase *)obj_buffer->buffer_store->buffer;
5035 if (base->type == VAProcFilterNoiseReduction) {
5036 VAProcFilterParameterBuffer *denoise = (VAProcFilterParameterBuffer *)base;
5038 } else if (base->type == VAProcFilterDeinterlacing) {
5039 VAProcFilterParameterBufferDeinterlacing *deint = (VAProcFilterParameterBufferDeinterlacing *)base;
5041 ASSERT_RET(deint->algorithm == VAProcDeinterlacingBob ||
5042 deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
5043 deint->algorithm == VAProcDeinterlacingMotionCompensated,
5044 VA_STATUS_ERROR_INVALID_PARAMETER);
5046 if (deint->algorithm == VAProcDeinterlacingMotionAdaptive ||
5047 deint->algorithm == VAProcDeinterlacingMotionCompensated);
5048 pipeline_cap->num_forward_references++;
5049 } else if (base->type == VAProcFilterSkinToneEnhancement) {
5050 VAProcFilterParameterBuffer *stde = (VAProcFilterParameterBuffer *)base;
5055 return VA_STATUS_SUCCESS;
5058 extern const struct hw_codec_info *i965_get_codec_info(int devid);
5061 i965_driver_data_init(VADriverContextP ctx)
5063 struct i965_driver_data *i965 = i965_driver_data(ctx);
5065 i965->codec_info = i965_get_codec_info(i965->intel.device_id);
5067 if (!i965->codec_info)
5070 if (object_heap_init(&i965->config_heap,
5071 sizeof(struct object_config),
5073 goto err_config_heap;
5074 if (object_heap_init(&i965->context_heap,
5075 sizeof(struct object_context),
5077 goto err_context_heap;
5079 if (object_heap_init(&i965->surface_heap,
5080 sizeof(struct object_surface),
5082 goto err_surface_heap;
5083 if (object_heap_init(&i965->buffer_heap,
5084 sizeof(struct object_buffer),
5086 goto err_buffer_heap;
5087 if (object_heap_init(&i965->image_heap,
5088 sizeof(struct object_image),
5090 goto err_image_heap;
5091 if (object_heap_init(&i965->subpic_heap,
5092 sizeof(struct object_subpic),
5094 goto err_subpic_heap;
5096 i965->batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
5097 i965->pp_batch = intel_batchbuffer_new(&i965->intel, I915_EXEC_RENDER, 0);
5098 _i965InitMutex(&i965->render_mutex);
5099 _i965InitMutex(&i965->pp_mutex);
5104 object_heap_destroy(&i965->image_heap);
5106 object_heap_destroy(&i965->buffer_heap);
5108 object_heap_destroy(&i965->surface_heap);
5110 object_heap_destroy(&i965->context_heap);
5112 object_heap_destroy(&i965->config_heap);
5119 i965_driver_data_terminate(VADriverContextP ctx)
5121 struct i965_driver_data *i965 = i965_driver_data(ctx);
5123 _i965DestroyMutex(&i965->pp_mutex);
5124 _i965DestroyMutex(&i965->render_mutex);
5127 intel_batchbuffer_free(i965->batch);
5130 intel_batchbuffer_free(i965->pp_batch);
5132 i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
5133 i965_destroy_heap(&i965->image_heap, i965_destroy_image);
5134 i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
5135 i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
5136 i965_destroy_heap(&i965->context_heap, i965_destroy_context);
5137 i965_destroy_heap(&i965->config_heap, i965_destroy_config);
5141 bool (*init)(VADriverContextP ctx);
5142 void (*terminate)(VADriverContextP ctx);
5144 } i965_sub_ops[] = {
5147 intel_driver_terminate,
5152 i965_driver_data_init,
5153 i965_driver_data_terminate,
5158 i965_display_attributes_init,
5159 i965_display_attributes_terminate,
5164 i965_post_processing_init,
5165 i965_post_processing_terminate,
5171 i965_render_terminate,
5175 #ifdef HAVE_VA_WAYLAND
5177 i965_output_wayland_init,
5178 i965_output_wayland_terminate,
5185 i965_output_dri_init,
5186 i965_output_dri_terminate,
5193 i965_Init(VADriverContextP ctx)
5195 struct i965_driver_data *i965 = i965_driver_data(ctx);
5197 const char *chipset;
5199 for (i = 0; i < ARRAY_ELEMS(i965_sub_ops); i++) {
5200 if ((i965_sub_ops[i].display_type == 0 ||
5201 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) &&
5202 !i965_sub_ops[i].init(ctx))
5206 if (i == ARRAY_ELEMS(i965_sub_ops)) {
5207 switch (i965->intel.device_id) {
5209 #define CHIPSET(id, family, dev, str) case id: chipset = str; break;
5210 #include "i965_pciids.h"
5212 chipset = "Unknown Intel Chipset";
5216 sprintf(i965->va_vendor, "%s %s driver for %s - %d.%d.%d",
5217 INTEL_STR_DRIVER_VENDOR,
5218 INTEL_STR_DRIVER_NAME,
5220 INTEL_DRIVER_MAJOR_VERSION,
5221 INTEL_DRIVER_MINOR_VERSION,
5222 INTEL_DRIVER_MICRO_VERSION);
5224 if (INTEL_DRIVER_PRE_VERSION > 0) {
5225 const int len = strlen(i965->va_vendor);
5226 sprintf(&i965->va_vendor[len], ".pre%d", INTEL_DRIVER_PRE_VERSION);
5229 i965->current_context_id = VA_INVALID_ID;
5231 return VA_STATUS_SUCCESS;
5235 for (; i >= 0; i--) {
5236 if (i965_sub_ops[i].display_type == 0 ||
5237 i965_sub_ops[i].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
5238 i965_sub_ops[i].terminate(ctx);
5242 return VA_STATUS_ERROR_UNKNOWN;
5247 i965_Terminate(VADriverContextP ctx)
5249 struct i965_driver_data *i965 = i965_driver_data(ctx);
5253 for (i = ARRAY_ELEMS(i965_sub_ops); i > 0; i--)
5254 if (i965_sub_ops[i - 1].display_type == 0 ||
5255 i965_sub_ops[i - 1].display_type == (ctx->display_type & VA_DISPLAY_MAJOR_MASK)) {
5256 i965_sub_ops[i - 1].terminate(ctx);
5260 ctx->pDriverData = NULL;
5263 return VA_STATUS_SUCCESS;
5267 VA_DRIVER_INIT_FUNC(VADriverContextP ctx);
5270 VA_DRIVER_INIT_FUNC( VADriverContextP ctx )
5272 struct VADriverVTable * const vtable = ctx->vtable;
5273 struct VADriverVTableVPP * const vtable_vpp = ctx->vtable_vpp;
5275 struct i965_driver_data *i965;
5276 VAStatus ret = VA_STATUS_ERROR_UNKNOWN;
5278 ctx->version_major = VA_MAJOR_VERSION;
5279 ctx->version_minor = VA_MINOR_VERSION;
5280 ctx->max_profiles = I965_MAX_PROFILES;
5281 ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
5282 ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
5283 ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
5284 ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
5285 ctx->max_display_attributes = 1 + ARRAY_ELEMS(i965_display_attributes);
5287 vtable->vaTerminate = i965_Terminate;
5288 vtable->vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
5289 vtable->vaQueryConfigProfiles = i965_QueryConfigProfiles;
5290 vtable->vaQueryConfigAttributes = i965_QueryConfigAttributes;
5291 vtable->vaCreateConfig = i965_CreateConfig;
5292 vtable->vaDestroyConfig = i965_DestroyConfig;
5293 vtable->vaGetConfigAttributes = i965_GetConfigAttributes;
5294 vtable->vaCreateSurfaces = i965_CreateSurfaces;
5295 vtable->vaDestroySurfaces = i965_DestroySurfaces;
5296 vtable->vaCreateContext = i965_CreateContext;
5297 vtable->vaDestroyContext = i965_DestroyContext;
5298 vtable->vaCreateBuffer = i965_CreateBuffer;
5299 vtable->vaBufferSetNumElements = i965_BufferSetNumElements;
5300 vtable->vaMapBuffer = i965_MapBuffer;
5301 vtable->vaUnmapBuffer = i965_UnmapBuffer;
5302 vtable->vaDestroyBuffer = i965_DestroyBuffer;
5303 vtable->vaBeginPicture = i965_BeginPicture;
5304 vtable->vaRenderPicture = i965_RenderPicture;
5305 vtable->vaEndPicture = i965_EndPicture;
5306 vtable->vaSyncSurface = i965_SyncSurface;
5307 vtable->vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
5308 vtable->vaPutSurface = i965_PutSurface;
5309 vtable->vaQueryImageFormats = i965_QueryImageFormats;
5310 vtable->vaCreateImage = i965_CreateImage;
5311 vtable->vaDeriveImage = i965_DeriveImage;
5312 vtable->vaDestroyImage = i965_DestroyImage;
5313 vtable->vaSetImagePalette = i965_SetImagePalette;
5314 vtable->vaGetImage = i965_GetImage;
5315 vtable->vaPutImage = i965_PutImage;
5316 vtable->vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
5317 vtable->vaCreateSubpicture = i965_CreateSubpicture;
5318 vtable->vaDestroySubpicture = i965_DestroySubpicture;
5319 vtable->vaSetSubpictureImage = i965_SetSubpictureImage;
5320 vtable->vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
5321 vtable->vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
5322 vtable->vaAssociateSubpicture = i965_AssociateSubpicture;
5323 vtable->vaDeassociateSubpicture = i965_DeassociateSubpicture;
5324 vtable->vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
5325 vtable->vaGetDisplayAttributes = i965_GetDisplayAttributes;
5326 vtable->vaSetDisplayAttributes = i965_SetDisplayAttributes;
5327 vtable->vaBufferInfo = i965_BufferInfo;
5328 vtable->vaLockSurface = i965_LockSurface;
5329 vtable->vaUnlockSurface = i965_UnlockSurface;
5330 vtable->vaGetSurfaceAttributes = i965_GetSurfaceAttributes;
5331 vtable->vaQuerySurfaceAttributes = i965_QuerySurfaceAttributes;
5332 vtable->vaCreateSurfaces2 = i965_CreateSurfaces2;
5334 vtable_vpp->vaQueryVideoProcFilters = i965_QueryVideoProcFilters;
5335 vtable_vpp->vaQueryVideoProcFilterCaps = i965_QueryVideoProcFilterCaps;
5336 vtable_vpp->vaQueryVideoProcPipelineCaps = i965_QueryVideoProcPipelineCaps;
5338 i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
5341 ctx->pDriverData = NULL;
5343 return VA_STATUS_ERROR_ALLOCATION_FAILED;
5346 ctx->pDriverData = (void *)i965;
5347 ret = i965_Init(ctx);
5349 if (ret == VA_STATUS_SUCCESS) {
5350 ctx->str_vendor = i965->va_vendor;
5353 ctx->pDriverData = NULL;