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>
34 #include "va/x11/va_dricommon.h"
36 #include "intel_driver.h"
37 #include "intel_memman.h"
38 #include "intel_batchbuffer.h"
40 #include "i965_media.h"
41 #include "i965_drv_video.h"
42 #include "i965_defines.h"
44 #define CONFIG_ID_OFFSET 0x01000000
45 #define CONTEXT_ID_OFFSET 0x02000000
46 #define SURFACE_ID_OFFSET 0x04000000
47 #define BUFFER_ID_OFFSET 0x08000000
48 #define IMAGE_ID_OFFSET 0x0a000000
49 #define SUBPIC_ID_OFFSET 0x10000000
52 I965_SURFACETYPE_RGBA = 1,
54 I965_SURFACETYPE_INDEXED
57 /* List of supported image formats */
60 VAImageFormat va_format;
61 } i965_image_format_map_t;
63 static const i965_image_format_map_t
64 i965_image_formats_map[I965_MAX_IMAGE_FORMATS + 1] = {
65 { I965_SURFACETYPE_YUV,
66 { VA_FOURCC('Y','V','1','2'), VA_LSB_FIRST, 12, } },
67 { I965_SURFACETYPE_YUV,
68 { VA_FOURCC('I','4','2','0'), VA_LSB_FIRST, 12, } },
69 { I965_SURFACETYPE_YUV,
70 { VA_FOURCC('N','V','1','2'), VA_LSB_FIRST, 12, } },
73 /* List of supported subpicture formats */
77 VAImageFormat va_format;
78 unsigned int va_flags;
79 } i965_subpic_format_map_t;
81 static const i965_subpic_format_map_t
82 i965_subpic_formats_map[I965_MAX_SUBPIC_FORMATS + 1] = {
83 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_P4A4_UNORM,
84 { VA_FOURCC('I','A','4','4'), VA_MSB_FIRST, 8, },
86 { I965_SURFACETYPE_INDEXED, I965_SURFACEFORMAT_A4P4_UNORM,
87 { VA_FOURCC('A','I','4','4'), VA_MSB_FIRST, 8, },
89 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_B8G8R8A8_UNORM,
90 { VA_FOURCC('B','G','R','A'), VA_LSB_FIRST, 32,
91 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
93 { I965_SURFACETYPE_RGBA, I965_SURFACEFORMAT_R8G8B8A8_UNORM,
94 { VA_FOURCC('R','G','B','A'), VA_LSB_FIRST, 32,
95 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
99 static const i965_subpic_format_map_t *
100 get_subpic_format(const VAImageFormat *va_format)
103 for (i = 0; i965_subpic_formats_map[i].type != 0; i++) {
104 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[i];
105 if (m->va_format.fourcc == va_format->fourcc &&
106 (m->type == I965_SURFACETYPE_RGBA ?
107 (m->va_format.byte_order == va_format->byte_order &&
108 m->va_format.red_mask == va_format->red_mask &&
109 m->va_format.green_mask == va_format->green_mask &&
110 m->va_format.blue_mask == va_format->blue_mask &&
111 m->va_format.alpha_mask == va_format->alpha_mask) : 1))
118 i965_QueryConfigProfiles(VADriverContextP ctx,
119 VAProfile *profile_list, /* out */
120 int *num_profiles) /* out */
124 profile_list[i++] = VAProfileMPEG2Simple;
125 profile_list[i++] = VAProfileMPEG2Main;
126 profile_list[i++] = VAProfileH264Baseline;
127 profile_list[i++] = VAProfileH264Main;
128 profile_list[i++] = VAProfileH264High;
130 /* If the assert fails then I965_MAX_PROFILES needs to be bigger */
131 assert(i <= I965_MAX_PROFILES);
134 return VA_STATUS_SUCCESS;
138 i965_QueryConfigEntrypoints(VADriverContextP ctx,
140 VAEntrypoint *entrypoint_list, /* out */
141 int *num_entrypoints) /* out */
143 VAStatus vaStatus = VA_STATUS_SUCCESS;
146 case VAProfileMPEG2Simple:
147 case VAProfileMPEG2Main:
148 *num_entrypoints = 1;
149 entrypoint_list[0] = VAEntrypointVLD;
152 case VAProfileH264Baseline:
153 case VAProfileH264Main:
154 case VAProfileH264High:
155 *num_entrypoints = 1;
156 entrypoint_list[0] = VAEntrypointVLD;
160 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
161 *num_entrypoints = 0;
165 /* If the assert fails then I965_MAX_ENTRYPOINTS needs to be bigger */
166 assert(*num_entrypoints <= I965_MAX_ENTRYPOINTS);
172 i965_GetConfigAttributes(VADriverContextP ctx,
174 VAEntrypoint entrypoint,
175 VAConfigAttrib *attrib_list, /* in/out */
180 /* Other attributes don't seem to be defined */
181 /* What to do if we don't know the attribute? */
182 for (i = 0; i < num_attribs; i++) {
183 switch (attrib_list[i].type) {
184 case VAConfigAttribRTFormat:
185 attrib_list[i].value = VA_RT_FORMAT_YUV420;
190 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
195 return VA_STATUS_SUCCESS;
199 i965_destroy_config(struct object_heap *heap, struct object_base *obj)
201 object_heap_free(heap, obj);
205 i965_update_attribute(struct object_config *obj_config, VAConfigAttrib *attrib)
209 /* Check existing attrbiutes */
210 for (i = 0; obj_config->num_attribs < i; i++) {
211 if (obj_config->attrib_list[i].type == attrib->type) {
212 /* Update existing attribute */
213 obj_config->attrib_list[i].value = attrib->value;
214 return VA_STATUS_SUCCESS;
218 if (obj_config->num_attribs < I965_MAX_CONFIG_ATTRIBUTES) {
219 i = obj_config->num_attribs;
220 obj_config->attrib_list[i].type = attrib->type;
221 obj_config->attrib_list[i].value = attrib->value;
222 obj_config->num_attribs++;
223 return VA_STATUS_SUCCESS;
226 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
230 i965_CreateConfig(VADriverContextP ctx,
232 VAEntrypoint entrypoint,
233 VAConfigAttrib *attrib_list,
235 VAConfigID *config_id) /* out */
237 struct i965_driver_data *i965 = i965_driver_data(ctx);
238 struct object_config *obj_config;
243 /* Validate profile & entrypoint */
245 case VAProfileMPEG2Simple:
246 case VAProfileMPEG2Main:
247 if (VAEntrypointVLD == entrypoint) {
248 vaStatus = VA_STATUS_SUCCESS;
250 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
254 case VAProfileH264Baseline:
255 case VAProfileH264Main:
256 case VAProfileH264High:
257 if (VAEntrypointVLD == entrypoint) {
258 vaStatus = VA_STATUS_SUCCESS;
260 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
266 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
270 if (VA_STATUS_SUCCESS != vaStatus) {
274 configID = NEW_CONFIG_ID();
275 obj_config = CONFIG(configID);
277 if (NULL == obj_config) {
278 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
282 obj_config->profile = profile;
283 obj_config->entrypoint = entrypoint;
284 obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
285 obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
286 obj_config->num_attribs = 1;
288 for(i = 0; i < num_attribs; i++) {
289 vaStatus = i965_update_attribute(obj_config, &(attrib_list[i]));
291 if (VA_STATUS_SUCCESS != vaStatus) {
297 if (VA_STATUS_SUCCESS != vaStatus) {
298 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
300 *config_id = configID;
307 i965_DestroyConfig(VADriverContextP ctx, VAConfigID config_id)
309 struct i965_driver_data *i965 = i965_driver_data(ctx);
310 struct object_config *obj_config = CONFIG(config_id);
313 if (NULL == obj_config) {
314 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
318 i965_destroy_config(&i965->config_heap, (struct object_base *)obj_config);
319 return VA_STATUS_SUCCESS;
322 VAStatus i965_QueryConfigAttributes(VADriverContextP ctx,
323 VAConfigID config_id,
324 VAProfile *profile, /* out */
325 VAEntrypoint *entrypoint, /* out */
326 VAConfigAttrib *attrib_list, /* out */
327 int *num_attribs) /* out */
329 struct i965_driver_data *i965 = i965_driver_data(ctx);
330 struct object_config *obj_config = CONFIG(config_id);
331 VAStatus vaStatus = VA_STATUS_SUCCESS;
335 *profile = obj_config->profile;
336 *entrypoint = obj_config->entrypoint;
337 *num_attribs = obj_config->num_attribs;
339 for(i = 0; i < obj_config->num_attribs; i++) {
340 attrib_list[i] = obj_config->attrib_list[i];
347 i965_destroy_surface(struct object_heap *heap, struct object_base *obj)
349 struct object_surface *obj_surface = (struct object_surface *)obj;
351 dri_bo_unreference(obj_surface->bo);
352 obj_surface->bo = NULL;
354 if (obj_surface->free_private_data != NULL) {
355 obj_surface->free_private_data(&obj_surface->private_data);
356 obj_surface->private_data = NULL;
359 object_heap_free(heap, obj);
363 i965_CreateSurfaces(VADriverContextP ctx,
368 VASurfaceID *surfaces) /* out */
370 struct i965_driver_data *i965 = i965_driver_data(ctx);
372 VAStatus vaStatus = VA_STATUS_SUCCESS;
374 /* We only support one format */
375 if (VA_RT_FORMAT_YUV420 != format) {
376 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
379 for (i = 0; i < num_surfaces; i++) {
380 int surfaceID = NEW_SURFACE_ID();
381 struct object_surface *obj_surface = SURFACE(surfaceID);
383 if (NULL == obj_surface) {
384 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
388 surfaces[i] = surfaceID;
389 obj_surface->status = VASurfaceReady;
390 obj_surface->subpic = VA_INVALID_ID;
391 obj_surface->orig_width = width;
392 obj_surface->orig_height = height;
393 obj_surface->width = ALIGN(obj_surface->orig_width, 16);
394 obj_surface->height = ALIGN(obj_surface->orig_height, 16);
395 obj_surface->size = SIZE_YUV420(obj_surface->width, obj_surface->height);
396 obj_surface->flags = SURFACE_REFERENCED;
397 obj_surface->bo = NULL;
398 obj_surface->private_data = NULL;
399 obj_surface->free_private_data = NULL;
403 if (VA_STATUS_SUCCESS != vaStatus) {
404 /* surfaces[i-1] was the last successful allocation */
406 struct object_surface *obj_surface = SURFACE(surfaces[i]);
408 surfaces[i] = VA_INVALID_SURFACE;
410 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
418 i965_DestroySurfaces(VADriverContextP ctx,
419 VASurfaceID *surface_list,
422 struct i965_driver_data *i965 = i965_driver_data(ctx);
425 for (i = num_surfaces; i--; ) {
426 struct object_surface *obj_surface = SURFACE(surface_list[i]);
429 i965_destroy_surface(&i965->surface_heap, (struct object_base *)obj_surface);
432 return VA_STATUS_SUCCESS;
436 i965_QueryImageFormats(VADriverContextP ctx,
437 VAImageFormat *format_list, /* out */
438 int *num_formats) /* out */
442 for (n = 0; i965_image_formats_map[n].va_format.fourcc != 0; n++) {
443 const i965_image_format_map_t * const m = &i965_image_formats_map[n];
445 format_list[n] = m->va_format;
451 return VA_STATUS_SUCCESS;
455 i965_PutImage(VADriverContextP ctx,
460 unsigned int src_width,
461 unsigned int src_height,
464 unsigned int dest_width,
465 unsigned int dest_height)
467 return VA_STATUS_SUCCESS;
471 i965_QuerySubpictureFormats(VADriverContextP ctx,
472 VAImageFormat *format_list, /* out */
473 unsigned int *flags, /* out */
474 unsigned int *num_formats) /* out */
478 for (n = 0; i965_subpic_formats_map[n].va_format.fourcc != 0; n++) {
479 const i965_subpic_format_map_t * const m = &i965_subpic_formats_map[n];
481 format_list[n] = m->va_format;
483 flags[n] = m->va_flags;
489 return VA_STATUS_SUCCESS;
493 i965_destroy_subpic(struct object_heap *heap, struct object_base *obj)
495 // struct object_subpic *obj_subpic = (struct object_subpic *)obj;
497 object_heap_free(heap, obj);
501 i965_CreateSubpicture(VADriverContextP ctx,
503 VASubpictureID *subpicture) /* out */
505 struct i965_driver_data *i965 = i965_driver_data(ctx);
506 VASubpictureID subpicID = NEW_SUBPIC_ID()
508 struct object_subpic *obj_subpic = SUBPIC(subpicID);
510 return VA_STATUS_ERROR_ALLOCATION_FAILED;
512 struct object_image *obj_image = IMAGE(image);
514 return VA_STATUS_ERROR_INVALID_IMAGE;
516 const i965_subpic_format_map_t * const m = get_subpic_format(&obj_image->image.format);
518 return VA_STATUS_ERROR_UNKNOWN; /* XXX: VA_STATUS_ERROR_UNSUPPORTED_FORMAT? */
520 *subpicture = subpicID;
521 obj_subpic->image = image;
522 obj_subpic->format = m->format;
523 obj_subpic->width = obj_image->image.width;
524 obj_subpic->height = obj_image->image.height;
525 obj_subpic->pitch = obj_image->image.pitches[0];
526 obj_subpic->bo = obj_image->bo;
527 return VA_STATUS_SUCCESS;
531 i965_DestroySubpicture(VADriverContextP ctx,
532 VASubpictureID subpicture)
535 struct i965_driver_data *i965 = i965_driver_data(ctx);
536 struct object_subpic *obj_subpic = SUBPIC(subpicture);
537 i965_destroy_subpic(&i965->subpic_heap, (struct object_base *)obj_subpic);
538 return VA_STATUS_SUCCESS;
542 i965_SetSubpictureImage(VADriverContextP ctx,
543 VASubpictureID subpicture,
547 return VA_STATUS_ERROR_UNIMPLEMENTED;
551 i965_SetSubpictureChromakey(VADriverContextP ctx,
552 VASubpictureID subpicture,
553 unsigned int chromakey_min,
554 unsigned int chromakey_max,
555 unsigned int chromakey_mask)
558 return VA_STATUS_ERROR_UNIMPLEMENTED;
562 i965_SetSubpictureGlobalAlpha(VADriverContextP ctx,
563 VASubpictureID subpicture,
567 return VA_STATUS_ERROR_UNIMPLEMENTED;
571 i965_AssociateSubpicture(VADriverContextP ctx,
572 VASubpictureID subpicture,
573 VASurfaceID *target_surfaces,
575 short src_x, /* upper left offset in subpicture */
577 unsigned short src_width,
578 unsigned short src_height,
579 short dest_x, /* upper left offset in surface */
581 unsigned short dest_width,
582 unsigned short dest_height,
584 * whether to enable chroma-keying or global-alpha
585 * see VA_SUBPICTURE_XXX values
589 struct i965_driver_data *i965 = i965_driver_data(ctx);
590 struct object_subpic *obj_subpic = SUBPIC(subpicture);
593 obj_subpic->src_rect.x = src_x;
594 obj_subpic->src_rect.y = src_y;
595 obj_subpic->src_rect.width = src_width;
596 obj_subpic->src_rect.height = src_height;
597 obj_subpic->dst_rect.x = dest_x;
598 obj_subpic->dst_rect.y = dest_y;
599 obj_subpic->dst_rect.width = dest_width;
600 obj_subpic->dst_rect.height = dest_height;
602 for (i = 0; i < num_surfaces; i++) {
603 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
605 return VA_STATUS_ERROR_INVALID_SURFACE;
606 obj_surface->subpic = subpicture;
608 return VA_STATUS_SUCCESS;
613 i965_DeassociateSubpicture(VADriverContextP ctx,
614 VASubpictureID subpicture,
615 VASurfaceID *target_surfaces,
618 struct i965_driver_data *i965 = i965_driver_data(ctx);
621 for (i = 0; i < num_surfaces; i++) {
622 struct object_surface *obj_surface = SURFACE(target_surfaces[i]);
624 return VA_STATUS_ERROR_INVALID_SURFACE;
625 if (obj_surface->subpic == subpicture)
626 obj_surface->subpic = VA_INVALID_ID;
628 return VA_STATUS_SUCCESS;
632 i965_reference_buffer_store(struct buffer_store **ptr,
633 struct buffer_store *buffer_store)
635 assert(*ptr == NULL);
638 buffer_store->ref_count++;
644 i965_release_buffer_store(struct buffer_store **ptr)
646 struct buffer_store *buffer_store = *ptr;
648 if (buffer_store == NULL)
651 assert(buffer_store->bo || buffer_store->buffer);
652 assert(!(buffer_store->bo && buffer_store->buffer));
653 buffer_store->ref_count--;
655 if (buffer_store->ref_count == 0) {
656 dri_bo_unreference(buffer_store->bo);
657 free(buffer_store->buffer);
658 buffer_store->bo = NULL;
659 buffer_store->buffer = NULL;
667 i965_destroy_context(struct object_heap *heap, struct object_base *obj)
669 struct object_context *obj_context = (struct object_context *)obj;
672 assert(obj_context->decode_state.num_slice_params <= obj_context->decode_state.max_slice_params);
673 assert(obj_context->decode_state.num_slice_datas <= obj_context->decode_state.max_slice_datas);
675 i965_release_buffer_store(&obj_context->decode_state.pic_param);
676 i965_release_buffer_store(&obj_context->decode_state.iq_matrix);
677 i965_release_buffer_store(&obj_context->decode_state.bit_plane);
679 for (i = 0; i < obj_context->decode_state.num_slice_params; i++)
680 i965_release_buffer_store(&obj_context->decode_state.slice_params[i]);
682 for (i = 0; i < obj_context->decode_state.num_slice_datas; i++)
683 i965_release_buffer_store(&obj_context->decode_state.slice_datas[i]);
685 free(obj_context->decode_state.slice_params);
686 free(obj_context->decode_state.slice_datas);
687 free(obj_context->render_targets);
688 object_heap_free(heap, obj);
692 i965_CreateContext(VADriverContextP ctx,
693 VAConfigID config_id,
697 VASurfaceID *render_targets,
698 int num_render_targets,
699 VAContextID *context) /* out */
701 struct i965_driver_data *i965 = i965_driver_data(ctx);
702 struct i965_render_state *render_state = &i965->render_state;
703 struct object_config *obj_config = CONFIG(config_id);
704 struct object_context *obj_context = NULL;
705 VAStatus vaStatus = VA_STATUS_SUCCESS;
709 if (NULL == obj_config) {
710 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
715 /* Validate picture dimensions */
716 contextID = NEW_CONTEXT_ID();
717 obj_context = CONTEXT(contextID);
719 if (NULL == obj_context) {
720 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
724 switch (obj_config->profile) {
725 case VAProfileH264Baseline:
726 case VAProfileH264Main:
727 case VAProfileH264High:
728 render_state->interleaved_uv = 1;
731 render_state->interleaved_uv = 0;
734 obj_context->context_id = contextID;
735 *context = contextID;
736 memset(&obj_context->decode_state, 0, sizeof(obj_context->decode_state));
737 obj_context->decode_state.current_render_target = -1;
738 obj_context->decode_state.max_slice_params = NUM_SLICES;
739 obj_context->decode_state.max_slice_datas = NUM_SLICES;
740 obj_context->decode_state.slice_params = calloc(obj_context->decode_state.max_slice_params,
741 sizeof(*obj_context->decode_state.slice_params));
742 obj_context->decode_state.slice_datas = calloc(obj_context->decode_state.max_slice_datas,
743 sizeof(*obj_context->decode_state.slice_datas));
744 obj_context->config_id = config_id;
745 obj_context->picture_width = picture_width;
746 obj_context->picture_height = picture_height;
747 obj_context->num_render_targets = num_render_targets;
748 obj_context->render_targets =
749 (VASurfaceID *)calloc(num_render_targets, sizeof(VASurfaceID));
751 for(i = 0; i < num_render_targets; i++) {
752 if (NULL == SURFACE(render_targets[i])) {
753 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
757 obj_context->render_targets[i] = render_targets[i];
760 obj_context->flags = flag;
763 if (VA_STATUS_SUCCESS != vaStatus) {
764 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
771 i965_DestroyContext(VADriverContextP ctx, VAContextID context)
773 struct i965_driver_data *i965 = i965_driver_data(ctx);
774 struct object_context *obj_context = CONTEXT(context);
777 i965_destroy_context(&i965->context_heap, (struct object_base *)obj_context);
779 return VA_STATUS_SUCCESS;
783 i965_destroy_buffer(struct object_heap *heap, struct object_base *obj)
785 struct object_buffer *obj_buffer = (struct object_buffer *)obj;
787 assert(obj_buffer->buffer_store);
788 i965_release_buffer_store(&obj_buffer->buffer_store);
789 object_heap_free(heap, obj);
793 i965_CreateBuffer(VADriverContextP ctx,
794 VAContextID context, /* in */
795 VABufferType type, /* in */
796 unsigned int size, /* in */
797 unsigned int num_elements, /* in */
799 VABufferID *buf_id) /* out */
801 struct i965_driver_data *i965 = i965_driver_data(ctx);
802 struct object_buffer *obj_buffer = NULL;
803 struct buffer_store *buffer_store = NULL;
808 case VAPictureParameterBufferType:
809 case VAIQMatrixBufferType:
810 case VABitPlaneBufferType:
811 case VASliceGroupMapBufferType:
812 case VASliceParameterBufferType:
813 case VASliceDataBufferType:
814 case VAMacroblockParameterBufferType:
815 case VAResidualDataBufferType:
816 case VADeblockingParameterBufferType:
817 case VAImageBufferType:
822 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
825 bufferID = NEW_BUFFER_ID();
826 obj_buffer = BUFFER(bufferID);
828 if (NULL == obj_buffer) {
829 return VA_STATUS_ERROR_ALLOCATION_FAILED;
832 obj_buffer->max_num_elements = num_elements;
833 obj_buffer->num_elements = num_elements;
834 obj_buffer->size_element = size;
835 obj_buffer->type = type;
836 obj_buffer->buffer_store = NULL;
837 buffer_store = calloc(1, sizeof(struct buffer_store));
838 assert(buffer_store);
839 buffer_store->ref_count = 1;
841 if (type == VASliceDataBufferType || type == VAImageBufferType) {
842 buffer_store->bo = dri_bo_alloc(i965->intel.bufmgr,
844 size * num_elements, 64);
845 assert(buffer_store->bo);
848 dri_bo_subdata(buffer_store->bo, 0, size * num_elements, data);
850 buffer_store->buffer = malloc(size * num_elements);
851 assert(buffer_store->buffer);
854 memcpy(buffer_store->buffer, data, size * num_elements);
857 buffer_store->num_elements = obj_buffer->num_elements;
858 i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store);
859 i965_release_buffer_store(&buffer_store);
862 return VA_STATUS_SUCCESS;
867 i965_BufferSetNumElements(VADriverContextP ctx,
868 VABufferID buf_id, /* in */
869 unsigned int num_elements) /* in */
871 struct i965_driver_data *i965 = i965_driver_data(ctx);
872 struct object_buffer *obj_buffer = BUFFER(buf_id);
873 VAStatus vaStatus = VA_STATUS_SUCCESS;
877 if ((num_elements < 0) ||
878 (num_elements > obj_buffer->max_num_elements)) {
879 vaStatus = VA_STATUS_ERROR_UNKNOWN;
881 obj_buffer->num_elements = num_elements;
888 i965_MapBuffer(VADriverContextP ctx,
889 VABufferID buf_id, /* in */
890 void **pbuf) /* out */
892 struct i965_driver_data *i965 = i965_driver_data(ctx);
893 struct object_buffer *obj_buffer = BUFFER(buf_id);
894 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
896 assert(obj_buffer && obj_buffer->buffer_store);
897 assert(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer);
898 assert(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer));
900 if (NULL != obj_buffer->buffer_store->bo) {
901 dri_bo_map(obj_buffer->buffer_store->bo, 1);
902 assert(obj_buffer->buffer_store->bo->virtual);
903 *pbuf = obj_buffer->buffer_store->bo->virtual;
904 vaStatus = VA_STATUS_SUCCESS;
905 } else if (NULL != obj_buffer->buffer_store->buffer) {
906 *pbuf = obj_buffer->buffer_store->buffer;
907 vaStatus = VA_STATUS_SUCCESS;
914 i965_UnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
916 struct i965_driver_data *i965 = i965_driver_data(ctx);
917 struct object_buffer *obj_buffer = BUFFER(buf_id);
918 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
920 assert(obj_buffer && obj_buffer->buffer_store);
921 assert(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer);
922 assert(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer));
924 if (NULL != obj_buffer->buffer_store->bo) {
925 dri_bo_unmap(obj_buffer->buffer_store->bo);
926 vaStatus = VA_STATUS_SUCCESS;
927 } else if (NULL != obj_buffer->buffer_store->buffer) {
929 vaStatus = VA_STATUS_SUCCESS;
936 i965_DestroyBuffer(VADriverContextP ctx, VABufferID buffer_id)
938 struct i965_driver_data *i965 = i965_driver_data(ctx);
939 struct object_buffer *obj_buffer = BUFFER(buffer_id);
942 i965_destroy_buffer(&i965->buffer_heap, (struct object_base *)obj_buffer);
944 return VA_STATUS_SUCCESS;
948 i965_BeginPicture(VADriverContextP ctx,
950 VASurfaceID render_target)
952 struct i965_driver_data *i965 = i965_driver_data(ctx);
953 struct object_context *obj_context = CONTEXT(context);
954 struct object_surface *obj_surface = SURFACE(render_target);
955 struct object_config *obj_config;
962 config = obj_context->config_id;
963 obj_config = CONFIG(config);
966 switch (obj_config->profile) {
967 case VAProfileMPEG2Simple:
968 case VAProfileMPEG2Main:
969 vaStatus = VA_STATUS_SUCCESS;
972 case VAProfileH264Baseline:
973 case VAProfileH264Main:
974 case VAProfileH264High:
975 vaStatus = VA_STATUS_SUCCESS;
980 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
984 obj_context->decode_state.current_render_target = render_target;
990 i965_render_picture_parameter_buffer(VADriverContextP ctx,
991 struct object_context *obj_context,
992 struct object_buffer *obj_buffer)
994 assert(obj_buffer->buffer_store->bo == NULL);
995 assert(obj_buffer->buffer_store->buffer);
996 i965_release_buffer_store(&obj_context->decode_state.pic_param);
997 i965_reference_buffer_store(&obj_context->decode_state.pic_param,
998 obj_buffer->buffer_store);
1000 return VA_STATUS_SUCCESS;
1004 i965_render_iq_matrix_buffer(VADriverContextP ctx,
1005 struct object_context *obj_context,
1006 struct object_buffer *obj_buffer)
1008 assert(obj_buffer->buffer_store->bo == NULL);
1009 assert(obj_buffer->buffer_store->buffer);
1010 i965_release_buffer_store(&obj_context->decode_state.iq_matrix);
1011 i965_reference_buffer_store(&obj_context->decode_state.iq_matrix,
1012 obj_buffer->buffer_store);
1014 return VA_STATUS_SUCCESS;
1018 i965_render_bit_plane_buffer(VADriverContextP ctx,
1019 struct object_context *obj_context,
1020 struct object_buffer *obj_buffer)
1022 assert(obj_buffer->buffer_store->bo == NULL);
1023 assert(obj_buffer->buffer_store->buffer);
1024 i965_release_buffer_store(&obj_context->decode_state.bit_plane);
1025 i965_reference_buffer_store(&obj_context->decode_state.bit_plane,
1026 obj_buffer->buffer_store);
1028 return VA_STATUS_SUCCESS;
1032 i965_render_slice_parameter_buffer(VADriverContextP ctx,
1033 struct object_context *obj_context,
1034 struct object_buffer *obj_buffer)
1036 assert(obj_buffer->buffer_store->bo == NULL);
1037 assert(obj_buffer->buffer_store->buffer);
1039 if (obj_context->decode_state.num_slice_params == obj_context->decode_state.max_slice_params) {
1040 obj_context->decode_state.slice_params = realloc(obj_context->decode_state.slice_params,
1041 (obj_context->decode_state.max_slice_params + NUM_SLICES) * sizeof(*obj_context->decode_state.slice_params));
1042 memset(obj_context->decode_state.slice_params + obj_context->decode_state.max_slice_params, 0, NUM_SLICES * sizeof(*obj_context->decode_state.slice_params));
1043 obj_context->decode_state.max_slice_params += NUM_SLICES;
1046 i965_release_buffer_store(&obj_context->decode_state.slice_params[obj_context->decode_state.num_slice_params]);
1047 i965_reference_buffer_store(&obj_context->decode_state.slice_params[obj_context->decode_state.num_slice_params],
1048 obj_buffer->buffer_store);
1049 obj_context->decode_state.num_slice_params++;
1051 return VA_STATUS_SUCCESS;
1055 i965_render_slice_data_buffer(VADriverContextP ctx,
1056 struct object_context *obj_context,
1057 struct object_buffer *obj_buffer)
1059 assert(obj_buffer->buffer_store->buffer == NULL);
1060 assert(obj_buffer->buffer_store->bo);
1062 if (obj_context->decode_state.num_slice_datas == obj_context->decode_state.max_slice_datas) {
1063 obj_context->decode_state.slice_datas = realloc(obj_context->decode_state.slice_datas,
1064 (obj_context->decode_state.max_slice_datas + NUM_SLICES) * sizeof(*obj_context->decode_state.slice_datas));
1065 memset(obj_context->decode_state.slice_datas + obj_context->decode_state.max_slice_datas, 0, NUM_SLICES * sizeof(*obj_context->decode_state.slice_datas));
1066 obj_context->decode_state.max_slice_datas += NUM_SLICES;
1069 i965_release_buffer_store(&obj_context->decode_state.slice_datas[obj_context->decode_state.num_slice_datas]);
1070 i965_reference_buffer_store(&obj_context->decode_state.slice_datas[obj_context->decode_state.num_slice_datas],
1071 obj_buffer->buffer_store);
1072 obj_context->decode_state.num_slice_datas++;
1074 return VA_STATUS_SUCCESS;
1078 i965_RenderPicture(VADriverContextP ctx,
1079 VAContextID context,
1080 VABufferID *buffers,
1083 struct i965_driver_data *i965 = i965_driver_data(ctx);
1084 struct object_context *obj_context;
1086 VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
1088 obj_context = CONTEXT(context);
1089 assert(obj_context);
1091 for (i = 0; i < num_buffers; i++) {
1092 struct object_buffer *obj_buffer = BUFFER(buffers[i]);
1095 switch (obj_buffer->type) {
1096 case VAPictureParameterBufferType:
1097 vaStatus = i965_render_picture_parameter_buffer(ctx, obj_context, obj_buffer);
1100 case VAIQMatrixBufferType:
1101 vaStatus = i965_render_iq_matrix_buffer(ctx, obj_context, obj_buffer);
1104 case VABitPlaneBufferType:
1105 vaStatus = i965_render_bit_plane_buffer(ctx, obj_context, obj_buffer);
1108 case VASliceParameterBufferType:
1109 vaStatus = i965_render_slice_parameter_buffer(ctx, obj_context, obj_buffer);
1112 case VASliceDataBufferType:
1113 vaStatus = i965_render_slice_data_buffer(ctx, obj_context, obj_buffer);
1125 i965_EndPicture(VADriverContextP ctx, VAContextID context)
1127 struct i965_driver_data *i965 = i965_driver_data(ctx);
1128 struct object_context *obj_context = CONTEXT(context);
1129 struct object_config *obj_config;
1133 assert(obj_context);
1134 assert(obj_context->decode_state.pic_param);
1135 assert(obj_context->decode_state.num_slice_params >= 1);
1136 assert(obj_context->decode_state.num_slice_datas >= 1);
1137 assert(obj_context->decode_state.num_slice_params == obj_context->decode_state.num_slice_datas);
1139 config = obj_context->config_id;
1140 obj_config = CONFIG(config);
1143 i965_media_decode_picture(ctx, obj_config->profile, &obj_context->decode_state);
1144 obj_context->decode_state.current_render_target = -1;
1145 obj_context->decode_state.num_slice_params = 0;
1146 obj_context->decode_state.num_slice_datas = 0;
1147 i965_release_buffer_store(&obj_context->decode_state.pic_param);
1148 i965_release_buffer_store(&obj_context->decode_state.iq_matrix);
1149 i965_release_buffer_store(&obj_context->decode_state.bit_plane);
1151 for (i = 0; i < obj_context->decode_state.num_slice_params; i++) {
1152 i965_release_buffer_store(&obj_context->decode_state.slice_params[i]);
1153 i965_release_buffer_store(&obj_context->decode_state.slice_datas[i]);
1156 return VA_STATUS_SUCCESS;
1160 i965_SyncSurface(VADriverContextP ctx,
1161 VASurfaceID render_target)
1163 struct i965_driver_data *i965 = i965_driver_data(ctx);
1164 struct object_surface *obj_surface = SURFACE(render_target);
1166 assert(obj_surface);
1168 return VA_STATUS_SUCCESS;
1172 i965_QuerySurfaceStatus(VADriverContextP ctx,
1173 VASurfaceID render_target,
1174 VASurfaceStatus *status) /* out */
1176 struct i965_driver_data *i965 = i965_driver_data(ctx);
1177 struct object_surface *obj_surface = SURFACE(render_target);
1179 assert(obj_surface);
1180 *status = obj_surface->status;
1182 return VA_STATUS_SUCCESS;
1187 * Query display attributes
1188 * The caller must provide a "attr_list" array that can hold at
1189 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes
1190 * returned in "attr_list" is returned in "num_attributes".
1193 i965_QueryDisplayAttributes(VADriverContextP ctx,
1194 VADisplayAttribute *attr_list, /* out */
1195 int *num_attributes) /* out */
1198 *num_attributes = 0;
1200 return VA_STATUS_SUCCESS;
1204 * Get display attributes
1205 * This function returns the current attribute values in "attr_list".
1206 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field
1207 * from vaQueryDisplayAttributes() can have their values retrieved.
1210 i965_GetDisplayAttributes(VADriverContextP ctx,
1211 VADisplayAttribute *attr_list, /* in/out */
1215 return VA_STATUS_ERROR_UNIMPLEMENTED;
1219 * Set display attributes
1220 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field
1221 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or
1222 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED
1225 i965_SetDisplayAttributes(VADriverContextP ctx,
1226 VADisplayAttribute *attr_list,
1230 return VA_STATUS_ERROR_UNIMPLEMENTED;
1234 i965_DbgCopySurfaceToBuffer(VADriverContextP ctx,
1235 VASurfaceID surface,
1236 void **buffer, /* out */
1237 unsigned int *stride) /* out */
1240 return VA_STATUS_ERROR_UNIMPLEMENTED;
1244 i965_Init(VADriverContextP ctx)
1246 struct i965_driver_data *i965 = i965_driver_data(ctx);
1248 if (intel_driver_init(ctx) == False)
1249 return VA_STATUS_ERROR_UNKNOWN;
1251 if (!IS_G4X(i965->intel.device_id) &&
1252 !IS_IRONLAKE(i965->intel.device_id))
1253 return VA_STATUS_ERROR_UNKNOWN;
1255 if (i965_media_init(ctx) == False)
1256 return VA_STATUS_ERROR_UNKNOWN;
1258 if (i965_render_init(ctx) == False)
1259 return VA_STATUS_ERROR_UNKNOWN;
1261 return VA_STATUS_SUCCESS;
1265 i965_destroy_heap(struct object_heap *heap,
1266 void (*func)(struct object_heap *heap, struct object_base *object))
1268 struct object_base *object;
1269 object_heap_iterator iter;
1271 object = object_heap_first(heap, &iter);
1277 object = object_heap_next(heap, &iter);
1280 object_heap_destroy(heap);
1285 i965_DestroyImage(VADriverContextP ctx, VAImageID image);
1288 i965_CreateImage(VADriverContextP ctx,
1289 VAImageFormat *format,
1292 VAImage *out_image) /* out */
1294 struct i965_driver_data *i965 = i965_driver_data(ctx);
1295 struct object_image *obj_image;
1296 VAStatus va_status = VA_STATUS_ERROR_OPERATION_FAILED;
1298 unsigned int width2, height2, size2, size;
1300 out_image->image_id = VA_INVALID_ID;
1301 out_image->buf = VA_INVALID_ID;
1303 image_id = NEW_IMAGE_ID();
1304 if (image_id == VA_INVALID_ID)
1305 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1307 obj_image = IMAGE(image_id);
1309 return VA_STATUS_ERROR_ALLOCATION_FAILED;
1310 obj_image->bo = NULL;
1311 obj_image->palette = NULL;
1313 VAImage * const image = &obj_image->image;
1314 image->image_id = image_id;
1315 image->buf = VA_INVALID_ID;
1317 size = width * height;
1318 width2 = (width + 1) / 2;
1319 height2 = (height + 1) / 2;
1320 size2 = width2 * height2;
1322 image->num_palette_entries = 0;
1323 image->entry_bytes = 0;
1324 memset(image->component_order, 0, sizeof(image->component_order));
1326 switch (format->fourcc) {
1327 case VA_FOURCC('I','A','4','4'):
1328 case VA_FOURCC('A','I','4','4'):
1329 image->num_planes = 1;
1330 image->pitches[0] = width;
1331 image->offsets[0] = 0;
1332 image->data_size = image->offsets[0] + image->pitches[0] * height;
1333 image->num_palette_entries = 16;
1334 image->entry_bytes = 3;
1335 image->component_order[0] = 'R';
1336 image->component_order[1] = 'G';
1337 image->component_order[2] = 'B';
1339 case VA_FOURCC('A','R','G','B'):
1340 case VA_FOURCC('A','B','G','R'):
1341 case VA_FOURCC('B','G','R','A'):
1342 case VA_FOURCC('R','G','B','A'):
1343 image->num_planes = 1;
1344 image->pitches[0] = width * 4;
1345 image->offsets[0] = 0;
1346 image->data_size = image->offsets[0] + image->pitches[0] * height;
1348 case VA_FOURCC('Y','V','1','2'):
1349 image->num_planes = 3;
1350 image->pitches[0] = width;
1351 image->offsets[0] = 0;
1352 image->pitches[1] = width2;
1353 image->offsets[1] = size + size2;
1354 image->pitches[2] = width2;
1355 image->offsets[2] = size;
1356 image->data_size = size + 2 * size2;
1358 case VA_FOURCC('I','4','2','0'):
1359 image->num_planes = 3;
1360 image->pitches[0] = width;
1361 image->offsets[0] = 0;
1362 image->pitches[1] = width2;
1363 image->offsets[1] = size;
1364 image->pitches[2] = width2;
1365 image->offsets[2] = size + size2;
1366 image->data_size = size + 2 * size2;
1368 case VA_FOURCC('N','V','1','2'):
1369 image->num_planes = 2;
1370 image->pitches[0] = width;
1371 image->offsets[0] = 0;
1372 image->pitches[1] = width;
1373 image->offsets[1] = size;
1374 image->data_size = size + 2 * size2;
1380 va_status = i965_CreateBuffer(ctx, 0, VAImageBufferType,
1381 image->data_size, 1, NULL, &image->buf);
1382 if (va_status != VA_STATUS_SUCCESS)
1385 obj_image->bo = BUFFER(image->buf)->buffer_store->bo;
1387 if (image->num_palette_entries > 0 && image->entry_bytes > 0) {
1388 obj_image->palette = malloc(image->num_palette_entries * sizeof(obj_image->palette));
1389 if (!obj_image->palette)
1393 image->image_id = image_id;
1394 image->format = *format;
1395 image->width = width;
1396 image->height = height;
1398 *out_image = *image;
1399 return VA_STATUS_SUCCESS;
1402 i965_DestroyImage(ctx, image_id);
1406 VAStatus i965_DeriveImage(VADriverContextP ctx,
1407 VASurfaceID surface,
1408 VAImage *image) /* out */
1411 return VA_STATUS_ERROR_OPERATION_FAILED;
1415 i965_destroy_image(struct object_heap *heap, struct object_base *obj)
1417 object_heap_free(heap, obj);
1422 i965_DestroyImage(VADriverContextP ctx, VAImageID image)
1424 struct i965_driver_data *i965 = i965_driver_data(ctx);
1425 struct object_image *obj_image = IMAGE(image);
1428 return VA_STATUS_SUCCESS;
1430 if (obj_image->image.buf != VA_INVALID_ID) {
1431 i965_DestroyBuffer(ctx, obj_image->image.buf);
1432 obj_image->image.buf = VA_INVALID_ID;
1435 if (obj_image->palette) {
1436 free(obj_image->palette);
1437 obj_image->palette = NULL;
1440 i965_destroy_image(&i965->image_heap, (struct object_base *)obj_image);
1442 return VA_STATUS_SUCCESS;
1446 * pointer to an array holding the palette data. The size of the array is
1447 * num_palette_entries * entry_bytes in size. The order of the components
1448 * in the palette is described by the component_order in VASubpicture struct
1451 i965_SetImagePalette(VADriverContextP ctx,
1453 unsigned char *palette)
1455 struct i965_driver_data *i965 = i965_driver_data(ctx);
1458 struct object_image *obj_image = IMAGE(image);
1460 return VA_STATUS_ERROR_INVALID_IMAGE;
1462 if (!obj_image->palette)
1463 return VA_STATUS_ERROR_ALLOCATION_FAILED; /* XXX: unpaletted/error */
1465 for (i = 0; i < obj_image->image.num_palette_entries; i++)
1466 obj_image->palette[i] = (((unsigned int)palette[3*i + 0] << 16) |
1467 ((unsigned int)palette[3*i + 1] << 8) |
1468 (unsigned int)palette[3*i + 2]);
1469 return VA_STATUS_SUCCESS;
1473 get_image_yv12(struct object_image *obj_image, uint8_t *image_data,
1474 struct object_surface *obj_surface,
1475 const VARectangle *rect)
1477 uint8_t *dst[3], *src[3];
1480 if (!obj_surface->bo)
1483 dri_bo_map(obj_surface->bo, 0);
1485 if (!obj_surface->bo->virtual)
1493 dst[0] = image_data + obj_image->image.offsets[0];
1494 src[0] = (uint8_t *)obj_surface->bo->virtual;
1495 dst[1] = image_data + obj_image->image.offsets[1];
1496 src[1] = src[0] + obj_surface->width * obj_surface->height;
1497 dst[2] = image_data + obj_image->image.offsets[2];
1498 src[2] = src[1] + (obj_surface->width / 2) * (obj_surface->height / 2);
1500 dst[0] += y * obj_image->image.pitches[0] + x;
1501 src[0] += y * obj_surface->width + x;
1502 for (i = 0; i < h; i++) {
1503 memcpy(dst[0], src[0], w);
1504 dst[0] += obj_image->image.pitches[0];
1505 src[0] += obj_surface->width;
1513 dst[1] += y * obj_image->image.pitches[1] + x;
1514 src[1] += y * obj_surface->width / 2 + x;
1515 for (i = 0; i < h; i++) {
1516 memcpy(dst[1], src[1], w);
1517 dst[1] += obj_image->image.pitches[1];
1518 src[1] += obj_surface->width / 2;
1521 dst[2] += y * obj_image->image.pitches[2] + y;
1522 src[2] += y * obj_surface->width / 2 + x;
1523 for (i = 0; i < h; i++) {
1524 memcpy(dst[2], src[2], w);
1525 dst[2] += obj_image->image.pitches[2];
1526 src[2] += obj_surface->width / 2;
1529 dri_bo_unmap(obj_surface->bo);
1533 get_image_nv12(struct object_image *obj_image, uint8_t *image_data,
1534 struct object_surface *obj_surface,
1535 const VARectangle *rect)
1540 if (!obj_surface->bo)
1543 dri_bo_map(obj_surface->bo, 0);
1545 if (!obj_surface->bo->virtual)
1553 dst = image_data + obj_image->image.offsets[0] + y * obj_image->image.pitches[0] + x;
1554 src = (uint8_t *)obj_surface->bo->virtual + y * obj_surface->width + x;
1555 for (i = 0; i < h; i++) {
1556 memcpy(dst, src, w);
1557 dst += obj_image->image.pitches[0];
1558 src += obj_surface->width;
1565 dst = image_data + obj_image->image.offsets[1] + y * obj_image->image.pitches[1] + x * 2;
1566 src = (uint8_t *)obj_surface->bo->virtual + obj_surface->width * obj_surface->height + y * obj_surface->width + x * 2;
1567 for (i = 0; i < h; i++) {
1568 memcpy(dst, src, w);
1569 dst += obj_image->image.pitches[1];
1570 src += obj_surface->width;
1573 dri_bo_unmap(obj_surface->bo);
1577 i965_GetImage(VADriverContextP ctx,
1578 VASurfaceID surface,
1579 int x, /* coordinates of the upper left source pixel */
1581 unsigned int width, /* width and height of the region */
1582 unsigned int height,
1585 struct i965_driver_data *i965 = i965_driver_data(ctx);
1586 struct i965_render_state *render_state = &i965->render_state;
1588 struct object_surface *obj_surface = SURFACE(surface);
1590 return VA_STATUS_ERROR_INVALID_SURFACE;
1592 struct object_image *obj_image = IMAGE(image);
1594 return VA_STATUS_ERROR_INVALID_IMAGE;
1597 return VA_STATUS_ERROR_INVALID_PARAMETER;
1598 if (x + width > obj_surface->orig_width ||
1599 y + height > obj_surface->orig_height)
1600 return VA_STATUS_ERROR_INVALID_PARAMETER;
1601 if (x + width > obj_image->image.width ||
1602 y + height > obj_image->image.height)
1603 return VA_STATUS_ERROR_INVALID_PARAMETER;
1606 void *image_data = NULL;
1608 va_status = i965_MapBuffer(ctx, obj_image->image.buf, &image_data);
1609 if (va_status != VA_STATUS_SUCCESS)
1616 rect.height = height;
1618 switch (obj_image->image.format.fourcc) {
1619 case VA_FOURCC('Y','V','1','2'):
1620 case VA_FOURCC('I','4','2','0'):
1621 /* I420 is native format for MPEG-2 decoded surfaces */
1622 if (render_state->interleaved_uv)
1623 goto operation_failed;
1624 get_image_yv12(obj_image, image_data, obj_surface, &rect);
1626 case VA_FOURCC('N','V','1','2'):
1627 /* NV12 is native format for H.264 decoded surfaces */
1628 if (!render_state->interleaved_uv)
1629 goto operation_failed;
1630 get_image_nv12(obj_image, image_data, obj_surface, &rect);
1634 va_status = VA_STATUS_ERROR_OPERATION_FAILED;
1638 i965_UnmapBuffer(ctx, obj_image->image.buf);
1643 i965_PutSurface(VADriverContextP ctx,
1644 VASurfaceID surface,
1645 Drawable draw, /* X Drawable */
1648 unsigned short srcw,
1649 unsigned short srch,
1652 unsigned short destw,
1653 unsigned short desth,
1654 VARectangle *cliprects, /* client supplied clip list */
1655 unsigned int number_cliprects, /* number of clip rects in the clip list */
1656 unsigned int flags) /* de-interlacing flags */
1658 struct i965_driver_data *i965 = i965_driver_data(ctx);
1659 struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
1660 struct i965_render_state *render_state = &i965->render_state;
1661 struct dri_drawable *dri_drawable;
1662 union dri_buffer *buffer;
1663 struct intel_region *dest_region;
1664 struct object_surface *obj_surface;
1667 Bool new_region = False;
1668 /* Currently don't support DRI1 */
1669 if (dri_state->driConnectedFlag != VA_DRI2)
1670 return VA_STATUS_ERROR_UNKNOWN;
1672 /* Some broken sources such as H.264 conformance case FM2_SVA_C
1675 obj_surface = SURFACE(surface);
1676 if (obj_surface->bo == NULL)
1677 return VA_STATUS_SUCCESS;
1679 dri_drawable = dri_get_drawable(ctx, draw);
1680 assert(dri_drawable);
1682 buffer = dri_get_rendering_buffer(ctx, dri_drawable);
1685 dest_region = render_state->draw_region;
1688 assert(dest_region->bo);
1689 dri_bo_flink(dest_region->bo, &name);
1691 if (buffer->dri2.name != name) {
1693 dri_bo_unreference(dest_region->bo);
1696 dest_region = (struct intel_region *)calloc(1, sizeof(*dest_region));
1697 assert(dest_region);
1698 render_state->draw_region = dest_region;
1703 dest_region->x = dri_drawable->x;
1704 dest_region->y = dri_drawable->y;
1705 dest_region->width = dri_drawable->width;
1706 dest_region->height = dri_drawable->height;
1707 dest_region->cpp = buffer->dri2.cpp;
1708 dest_region->pitch = buffer->dri2.pitch;
1710 dest_region->bo = intel_bo_gem_create_from_name(i965->intel.bufmgr, "rendering buffer", buffer->dri2.name);
1711 assert(dest_region->bo);
1713 ret = dri_bo_get_tiling(dest_region->bo, &(dest_region->tiling), &(dest_region->swizzle));
1717 i965_render_put_surface(ctx, surface,
1718 srcx, srcy, srcw, srch,
1719 destx, desty, destw, desth);
1721 if(obj_surface->subpic != VA_INVALID_ID) {
1722 i965_render_put_subpic(ctx, surface,
1723 srcx, srcy, srcw, srch,
1724 destx, desty, destw, desth);
1727 dri_swap_buffer(ctx, dri_drawable);
1728 obj_surface->flags |= SURFACE_DISPLAYED;
1730 if (!(obj_surface->flags & SURFACE_REFERENCED)) {
1731 dri_bo_unreference(obj_surface->bo);
1732 obj_surface->bo = NULL;
1733 obj_surface->flags = 0;
1735 if (obj_surface->free_private_data)
1736 obj_surface->free_private_data(&obj_surface->private_data);
1739 return VA_STATUS_SUCCESS;
1743 i965_Terminate(VADriverContextP ctx)
1745 struct i965_driver_data *i965 = i965_driver_data(ctx);
1747 if (i965_render_terminate(ctx) == False)
1748 return VA_STATUS_ERROR_UNKNOWN;
1750 if (i965_media_terminate(ctx) == False)
1751 return VA_STATUS_ERROR_UNKNOWN;
1753 if (intel_driver_terminate(ctx) == False)
1754 return VA_STATUS_ERROR_UNKNOWN;
1756 i965_destroy_heap(&i965->buffer_heap, i965_destroy_buffer);
1757 i965_destroy_heap(&i965->image_heap, i965_destroy_image);
1758 i965_destroy_heap(&i965->subpic_heap, i965_destroy_subpic);
1759 i965_destroy_heap(&i965->surface_heap, i965_destroy_surface);
1760 i965_destroy_heap(&i965->context_heap, i965_destroy_context);
1761 i965_destroy_heap(&i965->config_heap, i965_destroy_config);
1763 free(ctx->pDriverData);
1764 ctx->pDriverData = NULL;
1766 return VA_STATUS_SUCCESS;
1770 __vaDriverInit_0_31( VADriverContextP ctx )
1772 struct i965_driver_data *i965;
1775 ctx->version_major = VA_MAJOR_VERSION;
1776 ctx->version_minor = VA_MINOR_VERSION;
1777 ctx->max_profiles = I965_MAX_PROFILES;
1778 ctx->max_entrypoints = I965_MAX_ENTRYPOINTS;
1779 ctx->max_attributes = I965_MAX_CONFIG_ATTRIBUTES;
1780 ctx->max_image_formats = I965_MAX_IMAGE_FORMATS;
1781 ctx->max_subpic_formats = I965_MAX_SUBPIC_FORMATS;
1782 ctx->max_display_attributes = I965_MAX_DISPLAY_ATTRIBUTES;
1783 ctx->str_vendor = I965_STR_VENDOR;
1785 ctx->vtable.vaTerminate = i965_Terminate;
1786 ctx->vtable.vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
1787 ctx->vtable.vaQueryConfigProfiles = i965_QueryConfigProfiles;
1788 ctx->vtable.vaQueryConfigEntrypoints = i965_QueryConfigEntrypoints;
1789 ctx->vtable.vaQueryConfigAttributes = i965_QueryConfigAttributes;
1790 ctx->vtable.vaCreateConfig = i965_CreateConfig;
1791 ctx->vtable.vaDestroyConfig = i965_DestroyConfig;
1792 ctx->vtable.vaGetConfigAttributes = i965_GetConfigAttributes;
1793 ctx->vtable.vaCreateSurfaces = i965_CreateSurfaces;
1794 ctx->vtable.vaDestroySurfaces = i965_DestroySurfaces;
1795 ctx->vtable.vaCreateContext = i965_CreateContext;
1796 ctx->vtable.vaDestroyContext = i965_DestroyContext;
1797 ctx->vtable.vaCreateBuffer = i965_CreateBuffer;
1798 ctx->vtable.vaBufferSetNumElements = i965_BufferSetNumElements;
1799 ctx->vtable.vaMapBuffer = i965_MapBuffer;
1800 ctx->vtable.vaUnmapBuffer = i965_UnmapBuffer;
1801 ctx->vtable.vaDestroyBuffer = i965_DestroyBuffer;
1802 ctx->vtable.vaBeginPicture = i965_BeginPicture;
1803 ctx->vtable.vaRenderPicture = i965_RenderPicture;
1804 ctx->vtable.vaEndPicture = i965_EndPicture;
1805 ctx->vtable.vaSyncSurface = i965_SyncSurface;
1806 ctx->vtable.vaQuerySurfaceStatus = i965_QuerySurfaceStatus;
1807 ctx->vtable.vaPutSurface = i965_PutSurface;
1808 ctx->vtable.vaQueryImageFormats = i965_QueryImageFormats;
1809 ctx->vtable.vaCreateImage = i965_CreateImage;
1810 ctx->vtable.vaDeriveImage = i965_DeriveImage;
1811 ctx->vtable.vaDestroyImage = i965_DestroyImage;
1812 ctx->vtable.vaSetImagePalette = i965_SetImagePalette;
1813 ctx->vtable.vaGetImage = i965_GetImage;
1814 ctx->vtable.vaPutImage = i965_PutImage;
1815 ctx->vtable.vaQuerySubpictureFormats = i965_QuerySubpictureFormats;
1816 ctx->vtable.vaCreateSubpicture = i965_CreateSubpicture;
1817 ctx->vtable.vaDestroySubpicture = i965_DestroySubpicture;
1818 ctx->vtable.vaSetSubpictureImage = i965_SetSubpictureImage;
1819 ctx->vtable.vaSetSubpictureChromakey = i965_SetSubpictureChromakey;
1820 ctx->vtable.vaSetSubpictureGlobalAlpha = i965_SetSubpictureGlobalAlpha;
1821 ctx->vtable.vaAssociateSubpicture = i965_AssociateSubpicture;
1822 ctx->vtable.vaDeassociateSubpicture = i965_DeassociateSubpicture;
1823 ctx->vtable.vaQueryDisplayAttributes = i965_QueryDisplayAttributes;
1824 ctx->vtable.vaGetDisplayAttributes = i965_GetDisplayAttributes;
1825 ctx->vtable.vaSetDisplayAttributes = i965_SetDisplayAttributes;
1826 // ctx->vtable.vaDbgCopySurfaceToBuffer = i965_DbgCopySurfaceToBuffer;
1828 i965 = (struct i965_driver_data *)calloc(1, sizeof(*i965));
1830 ctx->pDriverData = (void *)i965;
1832 result = object_heap_init(&i965->config_heap,
1833 sizeof(struct object_config),
1835 assert(result == 0);
1837 result = object_heap_init(&i965->context_heap,
1838 sizeof(struct object_context),
1840 assert(result == 0);
1842 result = object_heap_init(&i965->surface_heap,
1843 sizeof(struct object_surface),
1845 assert(result == 0);
1847 result = object_heap_init(&i965->buffer_heap,
1848 sizeof(struct object_buffer),
1850 assert(result == 0);
1852 result = object_heap_init(&i965->image_heap,
1853 sizeof(struct object_image),
1855 assert(result == 0);
1857 result = object_heap_init(&i965->subpic_heap,
1858 sizeof(struct object_subpic),
1860 assert(result == 0);
1862 return i965_Init(ctx);