1 /*
2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3 * Copyright (c) Imagination Technologies Limited, UK
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Waldo Bastian <waldo.bastian@intel.com>
27 *
28 */
29
30 #include <va/va_backend.h>
31 #include <va/va_backend_tpi.h>
32 #include <va/va_backend_egl.h>
33 #ifdef PSBVIDEO_MRFL_VPP
34 #include <va/va_backend_vpp.h>
35 #endif
36 #ifdef PSBVIDEO_MFLD
37 #include <va/va_backend_vpp.h>
38 #endif
39 #include <va/va_drmcommon.h>
40 #include <va/va_android.h>
41 #include <va/va_tpi.h>
42
43 #include "psb_drv_video.h"
44 #include "psb_texture.h"
45 #include "psb_cmdbuf.h"
46 #ifndef BAYTRAIL
47 #include "pnw_cmdbuf.h"
48 #include "tng_cmdbuf.h"
49 #endif
50 #ifdef PSBVIDEO_MRFL_VPP
51 #include "vsp_cmdbuf.h"
52 #endif
53 #include "psb_surface.h"
54
55 #include "pnw_MPEG2.h"
56 #include "pnw_MPEG4.h"
57 #include "pnw_H264.h"
58 #include "pnw_VC1.h"
59 #include "tng_jpegdec.h"
60 #include "tng_VP8.h"
61 #include "tng_yuv_processor.h"
62
63 #ifdef PSBVIDEO_MFLD
64 #include "pnw_MPEG4ES.h"
65 #include "pnw_H264ES.h"
66 #include "pnw_H263ES.h"
67 #include "pnw_jpeg.h"
68 #endif
69 #ifdef PSBVIDEO_MRFL
70 #include "tng_H264ES.h"
71 #include "tng_H263ES.h"
72 #include "tng_MPEG4ES.h"
73 #include "tng_jpegES.h"
74 #endif
75 #ifdef PSBVIDEO_MRFL_VPP
76 #include "vsp_VPP.h"
77 #include "vsp_vp8.h"
78 #endif
79 #include "psb_output.h"
80 #include <stdio.h>
81 #include <string.h>
82 #include <stdarg.h>
83 #include <time.h>
84 #include <unistd.h>
85 #include <wsbm/wsbm_pool.h>
86 #include <wsbm/wsbm_manager.h>
87 #include <wsbm/wsbm_util.h>
88 #include <wsbm/wsbm_fencemgr.h>
89 #include <linux/videodev2.h>
90 #include <errno.h>
91
92 #include "psb_def.h"
93 #include "psb_drv_debug.h"
94 #ifndef BAYTRAIL
95 #include "psb_ws_driver.h"
96 #endif
97 #include "pnw_rotate.h"
98 #include "psb_surface_attrib.h"
99 #include "android/psb_gralloc.h"
100
101 #ifndef PSB_PACKAGE_VERSION
102 #define PSB_PACKAGE_VERSION "Undefined"
103 #endif
104
105 #define PSB_DRV_VERSION PSB_PACKAGE_VERSION
106 #define PSB_CHG_REVISION "(0X00000071)"
107
108 #define PSB_STR_VENDOR_MRST "Intel GMA500-MRST-" PSB_DRV_VERSION " " PSB_CHG_REVISION
109 #define PSB_STR_VENDOR_MFLD "Intel GMA500-MFLD-" PSB_DRV_VERSION " " PSB_CHG_REVISION
110 #define PSB_STR_VENDOR_MRFL "Intel GMA500-MRFL-" PSB_DRV_VERSION " " PSB_CHG_REVISION
111 #define PSB_STR_VENDOR_BAYTRAIL "Intel GMA500-BAYTRAIL-" PSB_DRV_VERSION " " PSB_CHG_REVISION
112 #define PSB_STR_VENDOR_LEXINGTON "Intel GMA500-LEXINGTON-" PSB_DRV_VERSION " " PSB_CHG_REVISION
113
114 #define MAX_UNUSED_BUFFERS 16
115
116 #define PSB_SURFACE_UNAVAILABLE 0x40000000
117
118 #define PSB_MAX_FLIP_DELAY (1000/30/10)
119
120 #define PSB_SURFACE_UNAVAILABLE 0x40000000
121
122 #include <signal.h>
123
124 #define EXPORT __attribute__ ((visibility("default")))
125
126 #define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
127
128 #ifdef PSBVIDEO_MRFL_VPP
129 #define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? (profile == VAProfileNone? driver_data->vpp_profile : driver_data->profile2Format[profile][entrypoint]) : NULL;
130 #endif
131 #ifdef PSBVIDEO_MFLD
132 #define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? (profile == VAProfileNone? driver_data->vpp_profile : driver_data->profile2Format[profile][entrypoint]) : NULL;
133 #endif
134
135 #define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
136 #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
137 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id ))
138 #define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
139
140 #define CONFIG_ID_OFFSET 0x01000000
141 #define CONTEXT_ID_OFFSET 0x02000000
142 #define SURFACE_ID_OFFSET 0x03000000
143 #define BUFFER_ID_OFFSET 0x04000000
144 #define IMAGE_ID_OFFSET 0x05000000
145 #define SUBPIC_ID_OFFSET 0x06000000
146
147 static int psb_get_device_info(VADriverContextP ctx);
148
149
150 void psb_init_surface_pvr2dbuf(psb_driver_data_p driver_data);
151 void psb_free_surface_pvr2dbuf(psb_driver_data_p driver_data);
152
psb_QueryConfigProfiles(VADriverContextP ctx,VAProfile * profile_list,int * num_profiles)153 VAStatus psb_QueryConfigProfiles(
154 VADriverContextP ctx,
155 VAProfile *profile_list, /* out */
156 int *num_profiles /* out */
157 )
158 {
159 DEBUG_FUNC_ENTER
160 (void) ctx; /* unused */
161 int i = 0;
162 VAStatus vaStatus = VA_STATUS_SUCCESS;
163 INIT_DRIVER_DATA
164
165 CHECK_INVALID_PARAM(profile_list == NULL);
166 CHECK_INVALID_PARAM(num_profiles == NULL);
167
168 #ifdef PSBVIDEO_MRFL_VPP
169 profile_list[i++] = VAProfileNone;
170 #endif
171 // profile_list[i++] = VAProfileMPEG2Simple;
172 profile_list[i++] = VAProfileMPEG2Main;
173 profile_list[i++] = VAProfileMPEG4Simple;
174 profile_list[i++] = VAProfileMPEG4AdvancedSimple;
175 // profile_list[i++] = VAProfileMPEG4Main;
176 profile_list[i++] = VAProfileH264Baseline;
177 profile_list[i++] = VAProfileH264Main;
178 profile_list[i++] = VAProfileH264High;
179 profile_list[i++] = VAProfileH264StereoHigh;
180 profile_list[i++] = VAProfileVC1Simple;
181 profile_list[i++] = VAProfileVC1Main;
182 profile_list[i++] = VAProfileVC1Advanced;
183
184 if (IS_MRFL(driver_data) || IS_BAYTRAIL(driver_data)) {
185 profile_list[i++] = VAProfileH263Baseline;
186 profile_list[i++] = VAProfileJPEGBaseline;
187 profile_list[i++] = VAProfileVP8Version0_3;
188 } else if (IS_MFLD(driver_data)) {
189 profile_list[i++] = VAProfileH263Baseline;
190 profile_list[i++] = VAProfileJPEGBaseline;
191 }
192 profile_list[i++] = VAProfileH264ConstrainedBaseline;
193
194 /* If the assert fails then PSB_MAX_PROFILES needs to be bigger */
195 ASSERT(i <= PSB_MAX_PROFILES);
196 *num_profiles = i;
197 DEBUG_FUNC_EXIT
198 return VA_STATUS_SUCCESS;
199 }
200
psb_QueryConfigEntrypoints(VADriverContextP ctx,VAProfile profile,VAEntrypoint * entrypoint_list,int * num_entrypoints)201 VAStatus psb_QueryConfigEntrypoints(
202 VADriverContextP ctx,
203 VAProfile profile,
204 VAEntrypoint *entrypoint_list, /* out */
205 int *num_entrypoints /* out */
206 )
207 {
208 DEBUG_FUNC_ENTER
209 INIT_DRIVER_DATA
210 VAStatus vaStatus = VA_STATUS_SUCCESS;
211 int entrypoints = 0;
212 int i;
213
214 CHECK_INVALID_PARAM(entrypoint_list == NULL);
215 CHECK_INVALID_PARAM((num_entrypoints == NULL) || (profile >= PSB_MAX_PROFILES));
216
217 for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) {
218 #ifndef BAYTRAIL
219 #ifdef PSBVIDEO_MRFL_VPP
220 if (profile == VAProfileNone && driver_data->vpp_profile &&
221 i == VAEntrypointVideoProc) {
222 entrypoints++;
223 *entrypoint_list++ = i;
224 } else
225 #endif
226 #endif
227 if (profile != VAProfileNone && driver_data->profile2Format[profile][i]) {
228 entrypoints++;
229 *entrypoint_list++ = i;
230 }
231 }
232
233 /* If the assert fails then PSB_MAX_ENTRYPOINTS needs to be bigger */
234 ASSERT(entrypoints <= PSB_MAX_ENTRYPOINTS);
235
236 if (0 == entrypoints) {
237 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
238 }
239
240 *num_entrypoints = entrypoints;
241 DEBUG_FUNC_EXIT
242 return VA_STATUS_SUCCESS;
243 }
244
245 /*
246 * Figure out if we should return VA_STATUS_ERROR_UNSUPPORTED_PROFILE
247 * or VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT
248 */
psb__error_unsupported_profile_entrypoint(psb_driver_data_p driver_data,VAProfile profile,VAEntrypoint __maybe_unused entrypoint)249 static VAStatus psb__error_unsupported_profile_entrypoint(psb_driver_data_p driver_data, VAProfile profile, VAEntrypoint __maybe_unused entrypoint)
250 {
251 /* Does the driver support _any_ entrypoint for this profile? */
252 if (profile < PSB_MAX_PROFILES) {
253 int i;
254
255 /* Do the parameter check for MFLD and MRFLD */
256 if (profile == VAProfileNone)
257 return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
258
259 for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) {
260 if (driver_data->profile2Format[profile][i]) {
261 /* There is an entrypoint, so the profile is supported */
262 return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
263 }
264 }
265 }
266 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
267 }
268
psb_GetConfigAttributes(VADriverContextP ctx,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs)269 VAStatus psb_GetConfigAttributes(
270 VADriverContextP ctx,
271 VAProfile profile,
272 VAEntrypoint entrypoint,
273 VAConfigAttrib *attrib_list, /* in/out */
274 int num_attribs
275 )
276 {
277 DEBUG_FUNC_ENTER
278 INIT_DRIVER_DATA
279
280 #if defined(BAYTRAIL)
281 format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
282 #elif defined(PSBVIDEO_MRFL_VPP)
283 INIT_FORMAT_VTABLE
284 #else
285 format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
286 #endif
287 int i;
288 VAStatus vaStatus = VA_STATUS_SUCCESS;
289 if (NULL == format_vtable) {
290 return psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint);
291 }
292
293 CHECK_INVALID_PARAM(attrib_list == NULL);
294 CHECK_INVALID_PARAM(num_attribs <= 0);
295
296 /* Generic attributes */
297 for (i = 0; i < num_attribs; i++) {
298 switch (attrib_list[i].type) {
299 case VAConfigAttribRTFormat:
300 attrib_list[i].value = VA_RT_FORMAT_YUV420;
301 if (entrypoint == VAEntrypointEncPicture)
302 attrib_list[i].value |= VA_RT_FORMAT_YUV422;
303 if ((profile == VAProfileJPEGBaseline) && (entrypoint == VAEntrypointVLD))
304 attrib_list[i].value |= VA_RT_FORMAT_YUV444;
305 break;
306
307 default:
308 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
309 break;
310 }
311 }
312 /* format specific attributes */
313 format_vtable->queryConfigAttributes(profile, entrypoint, attrib_list, num_attribs);
314 DEBUG_FUNC_EXIT
315 return VA_STATUS_SUCCESS;
316 }
317
psb__update_attribute(object_config_p obj_config,VAConfigAttrib * attrib)318 static VAStatus psb__update_attribute(object_config_p obj_config, VAConfigAttrib *attrib)
319 {
320 int i;
321 /* Check existing attributes */
322 for (i = 0; i < obj_config->attrib_count; i++) {
323 if (obj_config->attrib_list[i].type == attrib->type) {
324 /* Update existing attribute */
325 obj_config->attrib_list[i].value = attrib->value;
326 return VA_STATUS_SUCCESS;
327 }
328 }
329 if (obj_config->attrib_count < PSB_MAX_CONFIG_ATTRIBUTES) {
330 i = obj_config->attrib_count;
331 obj_config->attrib_list[i].type = attrib->type;
332 obj_config->attrib_list[i].value = attrib->value;
333 obj_config->attrib_count++;
334 return VA_STATUS_SUCCESS;
335 }
336 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
337 }
338
psb__validate_config(object_config_p obj_config)339 static VAStatus psb__validate_config(object_config_p obj_config)
340 {
341 int i;
342 /* Check all attributes */
343 for (i = 0; i < obj_config->attrib_count; i++) {
344 switch (obj_config->attrib_list[i].type) {
345 case VAConfigAttribRTFormat:
346 if (!(obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV420
347 || (obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV422 &&
348 obj_config->entrypoint == VAEntrypointEncPicture)
349 || (obj_config->attrib_list[i].value == (VA_RT_FORMAT_YUV444 | VA_RT_FORMAT_YUV420 )))) {
350 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
351 }
352 break;
353
354 default:
355 /*
356 * Ignore unknown attributes here, it
357 * may be format specific.
358 */
359 break;
360 }
361 }
362 return VA_STATUS_SUCCESS;
363 }
364
psb_get_active_entrypoint_number(VADriverContextP ctx,unsigned int entrypoint)365 static int psb_get_active_entrypoint_number(
366 VADriverContextP ctx,
367 unsigned int entrypoint)
368 {
369 INIT_DRIVER_DATA;
370 struct drm_lnc_video_getparam_arg arg;
371 int count = 0;
372 int ret;
373
374 if (VAEntrypointVLD > entrypoint ||
375 entrypoint > VAEntrypointEncPicture) {
376 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s :Invalid entrypoint %d.\n",
377 __FUNCTION__, entrypoint);
378 return -1;
379 }
380
381 arg.key = PNW_VIDEO_QUERY_ENTRY;
382 arg.value = (uint64_t)((unsigned long) &count);
383 arg.arg = (uint64_t)((unsigned int)&entrypoint);
384 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
385 &arg, sizeof(arg));
386 if (ret) {
387 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s drmCommandWriteRead fails %d.\n",
388 __FUNCTION__, ret);
389 return -1;
390 }
391
392 return count;
393 }
394
psb_CreateConfig(VADriverContextP ctx,VAProfile profile,VAEntrypoint entrypoint,VAConfigAttrib * attrib_list,int num_attribs,VAConfigID * config_id)395 VAStatus psb_CreateConfig(
396 VADriverContextP ctx,
397 VAProfile profile,
398 VAEntrypoint entrypoint,
399 VAConfigAttrib *attrib_list,
400 int num_attribs,
401 VAConfigID *config_id /* out */
402 )
403 {
404 DEBUG_FUNC_ENTER
405 INIT_DRIVER_DATA
406 #if defined(BAYTRAIL)
407 format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
408 #elif defined(PSBVIDEO_MRFL_VPP)
409 INIT_FORMAT_VTABLE
410 #else
411 format_vtable_p format_vtable = driver_data->profile2Format[profile][entrypoint];
412 #endif
413 VAStatus vaStatus = VA_STATUS_SUCCESS;
414 int configID;
415 object_config_p obj_config;
416 int i;
417
418 drv_debug_msg(VIDEO_DEBUG_INIT, "CreateConfig profile:%d, entrypoint:%d, num_attribs:%d.\n",
419 profile, entrypoint, num_attribs);
420 /*echo 8 > /sys/module/pvrsrvkm/parameters/no_ec will disable error concealment*/
421 if ((profile == VAProfileH264ConstrainedBaseline) && (VAEntrypointVLD == entrypoint)) {
422 char ec_disable[2];
423 FILE *ec_fp = fopen("/sys/module/pvrsrvkm/parameters/no_ec", "r");
424 if (ec_fp) {
425 if (fgets(ec_disable, 2, ec_fp) != NULL) {
426 /* force profile to VAProfileH264High */
427 if (strcmp(ec_disable, "8") == 0) {
428 drv_debug_msg(VIDEO_DEBUG_INIT, "disabled error concealment by setting profile to VAProfileH264High\n");
429 profile = VAProfileH264High;
430 }
431 }
432 fclose(ec_fp);
433 }
434 }
435
436 CHECK_INVALID_PARAM(config_id == NULL);
437 CHECK_INVALID_PARAM(num_attribs < 0);
438 CHECK_INVALID_PARAM(attrib_list == NULL);
439
440 if (NULL == format_vtable) {
441 vaStatus = psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint);
442 }
443
444 CHECK_VASTATUS();
445
446 if ((IS_MFLD(driver_data)) &&
447 ((VAEntrypointEncPicture == entrypoint)
448 || (VAEntrypointEncSlice == entrypoint))) {
449 int active_slc, active_pic;
450 /* Only allow one encoding entrypoint at the sametime.
451 * But if video encoding request comes when process JPEG encoding,
452 * it will wait until current JPEG picture encoding finish.
453 * Further JPEG encoding should fall back to software path.*/
454 active_slc = psb_get_active_entrypoint_number(ctx, VAEntrypointEncSlice);
455 active_pic = psb_get_active_entrypoint_number(ctx, VAEntrypointEncPicture);
456
457 if (active_slc > 0) {
458 drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active video encoding entrypoint."
459 "Entrypoint %d isn't available.\n", entrypoint);
460 return VA_STATUS_ERROR_HW_BUSY;
461 }
462 else if (active_pic > 0 && VAEntrypointEncPicture == entrypoint) {
463 drv_debug_msg(VIDEO_DEBUG_ERROR, "There already is a active picture encoding entrypoint."
464 "Entrypoint %d isn't available.\n", entrypoint);
465 return VA_STATUS_ERROR_HW_BUSY;
466 }
467 }
468
469 configID = object_heap_allocate(&driver_data->config_heap);
470 obj_config = CONFIG(configID);
471 CHECK_ALLOCATION(obj_config);
472
473 MEMSET_OBJECT(obj_config, struct object_config_s);
474
475 obj_config->profile = profile;
476 obj_config->format_vtable = format_vtable;
477 obj_config->entrypoint = entrypoint;
478 obj_config->attrib_list[0].type = VAConfigAttribRTFormat;
479 obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420;
480 obj_config->attrib_count = 1;
481
482 for (i = 0; i < num_attribs; i++) {
483 if (attrib_list[i].type > VAConfigAttribTypeMax)
484 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
485
486 vaStatus = psb__update_attribute(obj_config, &(attrib_list[i]));
487 if (VA_STATUS_SUCCESS != vaStatus) {
488 break;
489 }
490 }
491
492 if (VA_STATUS_SUCCESS == vaStatus) {
493 vaStatus = psb__validate_config(obj_config);
494 }
495
496 if (VA_STATUS_SUCCESS == vaStatus) {
497 vaStatus = format_vtable->validateConfig(obj_config);
498 }
499
500 /* Error recovery */
501 if (VA_STATUS_SUCCESS != vaStatus) {
502 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
503 } else {
504 *config_id = configID;
505 }
506
507 #ifdef PSBVIDEO_MSVDX_EC
508 if((getenv("PSB_VIDEO_NOEC") == NULL)
509 && (profile == VAProfileH264ConstrainedBaseline)) {
510 drv_debug_msg(VIDEO_DEBUG_INIT, "profile is VAProfileH264ConstrainedBaseline, error concealment is enabled. \n");
511 driver_data->ec_enabled = 1;
512 } else {
513 driver_data->ec_enabled = 0;
514 }
515
516 if (profile == VAProfileVP8Version0_3 ||
517 profile == VAProfileH264Baseline ||
518 profile == VAProfileH264Main ||
519 profile == VAProfileH264High ||
520 profile == VAProfileH264ConstrainedBaseline)
521 driver_data->ec_enabled = 1;
522
523 if (!IS_MRFL(driver_data)) {
524 if (profile == VAProfileMPEG4Simple ||
525 profile == VAProfileMPEG4AdvancedSimple ||
526 profile == VAProfileMPEG4Main)
527 driver_data->ec_enabled = 1;
528 }
529
530 #else
531 driver_data->ec_enabled = 0;
532 #endif
533
534 DEBUG_FUNC_EXIT
535 return vaStatus;
536 }
537
psb_DestroyConfig(VADriverContextP ctx,VAConfigID config_id)538 VAStatus psb_DestroyConfig(
539 VADriverContextP ctx,
540 VAConfigID config_id
541 )
542 {
543 DEBUG_FUNC_ENTER
544 INIT_DRIVER_DATA
545 VAStatus vaStatus = VA_STATUS_SUCCESS;
546 object_config_p obj_config;
547
548 obj_config = CONFIG(config_id);
549 CHECK_CONFIG(obj_config);
550
551 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
552 DEBUG_FUNC_EXIT
553 return vaStatus;
554 }
555
psb_QueryConfigAttributes(VADriverContextP ctx,VAConfigID config_id,VAProfile * profile,VAEntrypoint * entrypoint,VAConfigAttrib * attrib_list,int * num_attribs)556 VAStatus psb_QueryConfigAttributes(
557 VADriverContextP ctx,
558 VAConfigID config_id,
559 VAProfile *profile, /* out */
560 VAEntrypoint *entrypoint, /* out */
561 VAConfigAttrib *attrib_list, /* out */
562 int *num_attribs /* out */
563 )
564 {
565 DEBUG_FUNC_ENTER
566 INIT_DRIVER_DATA
567 VAStatus vaStatus = VA_STATUS_SUCCESS;
568 object_config_p obj_config;
569 int i;
570
571 CHECK_INVALID_PARAM(profile == NULL);
572 CHECK_INVALID_PARAM(entrypoint == NULL);
573 CHECK_INVALID_PARAM(attrib_list == NULL);
574 CHECK_INVALID_PARAM(num_attribs == NULL);
575
576 obj_config = CONFIG(config_id);
577 CHECK_CONFIG(obj_config);
578
579 *profile = obj_config->profile;
580 *entrypoint = obj_config->entrypoint;
581 *num_attribs = obj_config->attrib_count;
582 for (i = 0; i < obj_config->attrib_count; i++) {
583 attrib_list[i] = obj_config->attrib_list[i];
584 }
585
586 DEBUG_FUNC_EXIT
587 return vaStatus;
588 }
589
psb__destroy_surface(psb_driver_data_p driver_data,object_surface_p obj_surface)590 void psb__destroy_surface(psb_driver_data_p driver_data, object_surface_p obj_surface)
591 {
592 if (NULL != obj_surface) {
593 /* delete subpicture association */
594 psb_SurfaceDeassociateSubpict(driver_data, obj_surface);
595
596 obj_surface->is_ref_surface = 0;
597
598 psb_surface_sync(obj_surface->psb_surface);
599 psb_surface_destroy(obj_surface->psb_surface);
600
601 if (obj_surface->out_loop_surface) {
602 psb_surface_destroy(obj_surface->out_loop_surface);
603 }
604
605 if (obj_surface->scaling_surface) {
606 psb_surface_destroy(obj_surface->scaling_surface);
607 }
608
609 free(obj_surface->psb_surface);
610 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
611 }
612 }
613
psb__checkSurfaceDimensions(psb_driver_data_p driver_data,int width,int height)614 VAStatus psb__checkSurfaceDimensions(psb_driver_data_p driver_data, int width, int height)
615 {
616 if (driver_data->video_sd_disabled) {
617 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
618 }
619 if ((width <= 0) || (width * height > 5120 * 5120) || (height <= 0)) {
620 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
621 }
622 if (driver_data->video_hd_disabled) {
623 if ((width > 1024) || (height > 576)) {
624 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
625 }
626 }
627
628 return VA_STATUS_SUCCESS;
629 }
630
psb_GetSurfaceAttributes(VADriverContextP __maybe_unused ctx,VAConfigID __maybe_unused config,VASurfaceAttrib * attrib_list,unsigned int num_attribs)631 VAStatus psb_GetSurfaceAttributes(
632 VADriverContextP __maybe_unused ctx,
633 VAConfigID __maybe_unused config,
634 VASurfaceAttrib *attrib_list,
635 unsigned int num_attribs
636 )
637 {
638 DEBUG_FUNC_ENTER
639
640 uint32_t i;
641 VAStatus vaStatus = VA_STATUS_SUCCESS;
642
643 CHECK_INVALID_PARAM(attrib_list == NULL);
644 CHECK_INVALID_PARAM(num_attribs <= 0);
645
646 /* Generic attributes */
647 for (i = 0; i < num_attribs; i++) {
648 switch (attrib_list[i].type) {
649 case VASurfaceAttribMemoryType:
650 attrib_list[i].flags = VA_SURFACE_ATTRIB_SETTABLE | VA_SURFACE_ATTRIB_GETTABLE;
651 attrib_list[i].value.type = VAGenericValueTypeInteger;
652 attrib_list[i].value.value.i =
653 VA_SURFACE_ATTRIB_MEM_TYPE_VA |
654 VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR |
655 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
656 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
657 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
658 break;
659
660 case VASurfaceAttribExternalBufferDescriptor:
661 attrib_list[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
662 attrib_list[i].value.type = VAGenericValueTypePointer;
663 break;
664
665 default:
666 attrib_list[i].flags = VA_SURFACE_ATTRIB_NOT_SUPPORTED;
667 break;
668 }
669 }
670
671 DEBUG_FUNC_EXIT
672 return VA_STATUS_SUCCESS;
673
674 }
675
676 #ifdef PSBVIDEO_MSVDX_DEC_TILING
psb__tile_stride_log2_256(int w)677 unsigned long psb__tile_stride_log2_256(int w)
678 {
679 int stride_mode = 0;
680
681 if (512 >= w)
682 stride_mode = 1;
683 else if (1024 >= w)
684 stride_mode = 2;
685 else if (2048 >= w)
686 stride_mode = 3;
687 else if (4096 >= w)
688 stride_mode = 4;
689
690 return stride_mode;
691 }
692
psb__tile_stride_log2_512(int w)693 unsigned long psb__tile_stride_log2_512(int w)
694 {
695 int stride_mode = 0;
696
697 if (512 >= w)
698 stride_mode = 0;
699 else if (1024 >= w)
700 stride_mode = 1;
701 else if (2048 >= w)
702 stride_mode = 2;
703 else if (4096 >= w)
704 stride_mode = 3;
705
706 return stride_mode;
707 }
708 #endif
709
psb_CreateSurfaces(VADriverContextP __maybe_unused ctx,int __maybe_unused width,int __maybe_unused height,int __maybe_unused format,int __maybe_unused num_surfaces,VASurfaceID __maybe_unused * surface_list)710 VAStatus psb_CreateSurfaces(
711 VADriverContextP __maybe_unused ctx,
712 int __maybe_unused width,
713 int __maybe_unused height,
714 int __maybe_unused format,
715 int __maybe_unused num_surfaces,
716 VASurfaceID __maybe_unused * surface_list /* out */
717 )
718 {
719 return VA_STATUS_ERROR_UNIMPLEMENTED;
720 }
721
psb_CreateSurfaces2(VADriverContextP ctx,unsigned int format,unsigned int width,unsigned int height,VASurfaceID * surface_list,unsigned int num_surfaces,VASurfaceAttrib * attrib_list,unsigned int num_attribs)722 VAStatus psb_CreateSurfaces2(
723 VADriverContextP ctx,
724 unsigned int format,
725 unsigned int width,
726 unsigned int height,
727 VASurfaceID *surface_list, /* out */
728 unsigned int num_surfaces,
729 VASurfaceAttrib *attrib_list,
730 unsigned int num_attribs
731 )
732 {
733 DEBUG_FUNC_ENTER
734 INIT_DRIVER_DATA
735 VAStatus vaStatus = VA_STATUS_SUCCESS;
736 unsigned int i;
737 int height_origin, buffer_stride = 0;
738 driver_data->protected = (VA_RT_FORMAT_PROTECTED & format);
739 unsigned long fourcc;
740 unsigned int flags = 0;
741 int memory_type = -1;
742 unsigned int initalized_info_flag = 1;
743 VASurfaceAttribExternalBuffers *pExternalBufDesc = NULL;
744 PsbSurfaceAttributeTPI attribute_tpi;
745 attribute_tpi.buffers = NULL;
746 bool attribute_tpi_buffersAlloced = false;
747
748 CHECK_INVALID_PARAM(num_surfaces <= 0);
749 CHECK_SURFACE(surface_list);
750
751 if ((attrib_list != NULL) && (num_attribs > 0)) {
752 for (i = 0; i < num_attribs; i++, attrib_list++) {
753 if (!attrib_list) {
754 if(attribute_tpi.buffers != NULL)
755 free(attribute_tpi.buffers);
756 return VA_STATUS_ERROR_INVALID_PARAMETER;
757 }
758 switch (attrib_list->type) {
759 case VASurfaceAttribExternalBufferDescriptor:
760 {
761 pExternalBufDesc = (VASurfaceAttribExternalBuffers *)attrib_list->value.value.p;
762 if (pExternalBufDesc == NULL) {
763 if(attribute_tpi.buffers != NULL)
764 free(attribute_tpi.buffers);
765 drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid VASurfaceAttribExternalBuffers.\n");
766 return VA_STATUS_ERROR_INVALID_PARAMETER;
767 }
768 attribute_tpi.type = memory_type;
769 if (attribute_tpi_buffersAlloced == true && attribute_tpi.buffers != NULL) {
770 free(attribute_tpi.buffers);
771 attribute_tpi.buffers = NULL;
772 }
773 attribute_tpi.buffers = malloc(sizeof(long) * pExternalBufDesc->num_buffers);
774 attribute_tpi_buffersAlloced = true;
775 attribute_tpi.width = pExternalBufDesc->width;
776 attribute_tpi.height = pExternalBufDesc->height;
777 attribute_tpi.count = pExternalBufDesc->num_buffers;
778 memcpy((void*)attribute_tpi.buffers, (void*)pExternalBufDesc->buffers,
779 sizeof(pExternalBufDesc->buffers[0]) *
780 pExternalBufDesc->num_buffers);
781 attribute_tpi.pixel_format = pExternalBufDesc->pixel_format;
782 attribute_tpi.size = pExternalBufDesc->data_size;
783 attribute_tpi.luma_stride = pExternalBufDesc->pitches[0];
784 attribute_tpi.chroma_u_stride = pExternalBufDesc->pitches[1];
785 attribute_tpi.chroma_v_stride = pExternalBufDesc->pitches[2];
786 attribute_tpi.luma_offset = pExternalBufDesc->offsets[0];
787 attribute_tpi.chroma_u_offset = pExternalBufDesc->offsets[1];
788 attribute_tpi.chroma_v_offset = pExternalBufDesc->offsets[2];
789 attribute_tpi.reserved[0] = (unsigned long) pExternalBufDesc->private_data;
790 if (pExternalBufDesc->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING)
791 attribute_tpi.tiling = 1;
792 else
793 attribute_tpi.tiling = 0;
794 }
795 break;
796 case VASurfaceAttribMemoryType:
797 {
798 switch (attrib_list->value.value.i) {
799 case VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR:
800 memory_type = VAExternalMemoryUserPointer;
801 break;
802 case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM:
803 memory_type = VAExternalMemoryKernelDRMBufffer;
804 break;
805 case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC:
806 memory_type = VAExternalMemoryAndroidGrallocBuffer;
807 break;
808 case VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION:
809 memory_type = VAExternalMemoryIONSharedFD;
810 break;
811 case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
812 memory_type = VAExternalMemoryNULL;
813 break;
814 default:
815 if (attribute_tpi.buffers != NULL)
816 free(attribute_tpi.buffers);
817 drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported memory type.\n");
818 return VA_STATUS_ERROR_INVALID_PARAMETER;
819
820 }
821 }
822 break;
823 case VASurfaceAttribUsageHint:
824 {
825 /* Share info is to be initialized when created sufaces by default (for the data producer)
826 * VPP Read indicate we do not NOT touch share info (for data consumer, which share buffer with data
827 * producer, such as of VPP).
828 */
829 drv_debug_msg(VIDEO_DEBUG_GENERAL, "VASurfaceAttribUsageHint.\n");
830 if ((attrib_list->value.value.i & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ)!= 0){
831 initalized_info_flag = 0;
832 drv_debug_msg(VIDEO_DEBUG_GENERAL, "explicat not initialized share info.\n");
833 }
834 }
835 break;
836 default:
837 if (attribute_tpi.buffers != NULL)
838 free(attribute_tpi.buffers);
839 drv_debug_msg(VIDEO_DEBUG_ERROR, "Unsupported attribute.\n");
840 return VA_STATUS_ERROR_INVALID_PARAMETER;
841 }
842 }
843 }
844
845 if ((memory_type == -1 && pExternalBufDesc != NULL) ||
846 (memory_type != -1 && pExternalBufDesc == NULL)) {
847 return VA_STATUS_ERROR_INVALID_PARAMETER;
848 }
849 else if(memory_type !=-1 && pExternalBufDesc != NULL) {
850 attribute_tpi.type = memory_type;
851 //set initialized share info in reserverd 1, by default we will initialized share_info
852 attribute_tpi.reserved[2] = (unsigned int)initalized_info_flag;
853 vaStatus = psb_CreateSurfacesWithAttribute(ctx, width, height, format, num_surfaces, surface_list, (VASurfaceAttributeTPI *)&attribute_tpi);
854 pExternalBufDesc->private_data = (void *)(attribute_tpi.reserved[1]);
855 if (attribute_tpi.buffers) free(attribute_tpi.buffers);
856 return vaStatus;
857 }
858
859 format = format & (~VA_RT_FORMAT_PROTECTED);
860
861 /* We only support one format */
862 if ((VA_RT_FORMAT_YUV420 != format)
863 && (VA_RT_FORMAT_YUV422 != format)
864 && (VA_RT_FORMAT_YUV444 != format)) {
865 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
866 DEBUG_FAILURE;
867 return vaStatus;
868 }
869
870 vaStatus = psb__checkSurfaceDimensions(driver_data, width, height);
871 CHECK_VASTATUS();
872
873 /* Adjust height to be a multiple of 32 (height of macroblock in interlaced mode) */
874 height_origin = height;
875 height = (height + 0x1f) & ~0x1f;
876
877
878 for (i = 0; i < num_surfaces; i++) {
879 int surfaceID;
880 object_surface_p obj_surface;
881 psb_surface_p psb_surface;
882
883 surfaceID = object_heap_allocate(&driver_data->surface_heap);
884 obj_surface = SURFACE(surfaceID);
885 if (NULL == obj_surface) {
886 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
887 DEBUG_FAILURE;
888 break;
889 }
890 MEMSET_OBJECT(obj_surface, struct object_surface_s);
891
892 obj_surface->surface_id = surfaceID;
893 surface_list[i] = surfaceID;
894 obj_surface->context_id = -1;
895 obj_surface->width = width;
896 obj_surface->height = height;
897 obj_surface->width_r = width;
898 obj_surface->height_r = height;
899 obj_surface->height_origin = height_origin;
900 obj_surface->share_info = NULL;
901
902 psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s));
903 if (NULL == psb_surface) {
904 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
905 obj_surface->surface_id = VA_INVALID_SURFACE;
906 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
907 DEBUG_FAILURE;
908 break;
909 }
910
911 switch (format) {
912 case VA_RT_FORMAT_YUV444:
913 fourcc = VA_FOURCC_YV32; /* allocate 4 planar */
914 break;
915 case VA_RT_FORMAT_YUV422:
916 fourcc = VA_FOURCC_YV16;
917 break;
918 case VA_RT_FORMAT_YUV420:
919 default:
920 fourcc = VA_FOURCC_NV12;
921 break;
922 }
923
924 flags |= driver_data->protected ? IS_PROTECTED : 0;
925 vaStatus = psb_surface_create(driver_data, width, height, fourcc,
926 flags, psb_surface);
927
928 if (VA_STATUS_SUCCESS != vaStatus) {
929 free(psb_surface);
930 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface);
931 obj_surface->surface_id = VA_INVALID_SURFACE;
932 DEBUG_FAILURE;
933 break;
934 }
935 buffer_stride = psb_surface->stride;
936 /* by default, surface fourcc is NV12 */
937 psb_surface->extra_info[4] = fourcc;
938 psb_surface->extra_info[8] = fourcc;
939 obj_surface->psb_surface = psb_surface;
940 }
941
942 /* Error recovery */
943 if (VA_STATUS_SUCCESS != vaStatus) {
944 /* surface_list[i-1] was the last successful allocation */
945 for (; i--;) {
946 object_surface_p obj_surface = SURFACE(surface_list[i]);
947 psb__destroy_surface(driver_data, obj_surface);
948 surface_list[i] = VA_INVALID_SURFACE;
949 }
950 drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateSurfaces failed\n");
951 return vaStatus;
952 }
953 DEBUG_FUNC_EXIT
954 return vaStatus;
955 }
956
psb_DestroySurfaces(VADriverContextP ctx,VASurfaceID * surface_list,int num_surfaces)957 VAStatus psb_DestroySurfaces(
958 VADriverContextP ctx,
959 VASurfaceID *surface_list,
960 int num_surfaces
961 )
962 {
963 INIT_DRIVER_DATA
964 int i, j;
965 object_context_p obj_context = NULL;
966 VAStatus vaStatus = VA_STATUS_SUCCESS;
967
968 if (num_surfaces <= 0) {
969 return VA_STATUS_ERROR_INVALID_PARAMETER;
970 }
971
972 CHECK_SURFACE(surface_list);
973
974 #if 0
975 /* Free PVR2D buffer wrapped from the surfaces */
976 psb_free_surface_pvr2dbuf(driver_data);
977 #endif
978
979 /* Make validation happy */
980 for (i = 0; i < num_surfaces; i++) {
981 object_surface_p obj_surface = SURFACE(surface_list[i]);
982 if (obj_surface == NULL) {
983 return VA_STATUS_ERROR_INVALID_SURFACE;
984 }
985 if (obj_surface->derived_imgcnt > 0) {
986 drv_debug_msg(VIDEO_DEBUG_ERROR, "Some surface is deriving by images\n");
987 return VA_STATUS_ERROR_OPERATION_FAILED;
988 }
989 }
990
991 for (i = 0; i < num_surfaces; i++) {
992 object_surface_p obj_surface = SURFACE(surface_list[i]);
993 if (obj_surface == NULL)
994 return VA_STATUS_ERROR_INVALID_SURFACE;
995
996 if (driver_data->cur_displaying_surface == surface_list[i]) {
997 /* Surface is being displaying. Need to stop overlay here */
998 psb_coverlay_stop(ctx);
999 }
1000
1001 obj_context = CONTEXT(obj_surface->context_id);
1002 if (obj_context != NULL) {
1003 for (j = 0; j < obj_context->num_render_targets; j++) {
1004 if (obj_context->render_targets[j] == obj_surface->surface_id) {
1005 obj_context->render_targets[j] = VA_INVALID_SURFACE;
1006 break;
1007 }
1008 }
1009 }
1010
1011 drv_debug_msg(VIDEO_DEBUG_INIT, "%s : obj_surface->surface_id = 0x%x\n",__FUNCTION__, obj_surface->surface_id);
1012 if (obj_surface->share_info) {
1013 psb_DestroySurfaceGralloc(obj_surface);
1014 }
1015 psb__destroy_surface(driver_data, obj_surface);
1016 surface_list[i] = VA_INVALID_SURFACE;
1017 }
1018
1019 DEBUG_FUNC_EXIT
1020 return VA_STATUS_SUCCESS;
1021 }
1022
psb_new_context(psb_driver_data_p driver_data,uint64_t ctx_type)1023 int psb_new_context(psb_driver_data_p driver_data, uint64_t ctx_type)
1024 {
1025 struct drm_lnc_video_getparam_arg arg;
1026 int ret = 0;
1027
1028 arg.key = IMG_VIDEO_NEW_CONTEXT;
1029 arg.value = (uint64_t)((unsigned long) & ctx_type);
1030 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
1031 &arg, sizeof(arg));
1032 if (ret != 0)
1033 drv_debug_msg(VIDEO_DEBUG_ERROR, "Set context %d failed\n", ctx_type);
1034
1035 return ret;
1036 }
1037
1038 #ifdef PSBVIDEO_MSVDX_DEC_TILING
psb_update_context(psb_driver_data_p driver_data,unsigned long ctx_type)1039 int psb_update_context(psb_driver_data_p driver_data, unsigned long ctx_type)
1040 {
1041 struct drm_lnc_video_getparam_arg arg;
1042 int ret = 0;
1043
1044 arg.key = IMG_VIDEO_UPDATE_CONTEXT;
1045 arg.value = (uint64_t)((unsigned long) & ctx_type);
1046 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
1047 &arg, sizeof(arg));
1048 if (ret != 0)
1049 drv_debug_msg(VIDEO_DEBUG_ERROR, "Update context %d failed\n", ctx_type);
1050
1051 return ret;
1052 }
1053 #endif
1054
psb_rm_context(psb_driver_data_p driver_data)1055 int psb_rm_context(psb_driver_data_p driver_data)
1056 {
1057 struct drm_lnc_video_getparam_arg arg;
1058 int tmp;
1059 int ret = 0;
1060
1061 arg.key = IMG_VIDEO_RM_CONTEXT;
1062 arg.value = (uint64_t)((unsigned long) & tmp); /* value is ignored */
1063 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
1064 &arg, sizeof(arg));
1065 if (ret != 0)
1066 drv_debug_msg(VIDEO_DEBUG_ERROR, "Remove context failed\n");
1067
1068 return ret;
1069 }
1070
psb_CreateContext(VADriverContextP ctx,VAConfigID config_id,int picture_width,int picture_height,int flag,VASurfaceID * render_targets,int num_render_targets,VAContextID * context)1071 VAStatus psb_CreateContext(
1072 VADriverContextP ctx,
1073 VAConfigID config_id,
1074 int picture_width,
1075 int picture_height,
1076 int flag,
1077 VASurfaceID *render_targets,
1078 int num_render_targets,
1079 VAContextID *context /* out */
1080 )
1081 {
1082 DEBUG_FUNC_ENTER
1083 INIT_DRIVER_DATA
1084 VAStatus vaStatus = VA_STATUS_SUCCESS;
1085 object_config_p obj_config;
1086 int cmdbuf_num, encode = 0, proc = 0;
1087 int i;
1088 drv_debug_msg(VIDEO_DEBUG_ERROR, "CreateContext config_id:%d, pic_w:%d, pic_h:%d, flag:%d, num_render_targets:%d, render_targets: %p.\n",
1089 config_id, picture_width, picture_height, flag, num_render_targets, render_targets);
1090
1091 CHECK_INVALID_PARAM(num_render_targets < 0);
1092
1093 //CHECK_SURFACE(render_targets);
1094 CHECK_CONTEXT(context);
1095
1096 vaStatus = psb__checkSurfaceDimensions(driver_data, picture_width, picture_height);
1097 CHECK_VASTATUS();
1098
1099 obj_config = CONFIG(config_id);
1100 CHECK_CONFIG(obj_config);
1101
1102 int contextID = object_heap_allocate(&driver_data->context_heap);
1103 object_context_p obj_context = CONTEXT(contextID);
1104 CHECK_ALLOCATION(obj_context);
1105
1106 *context = contextID;
1107
1108 MEMSET_OBJECT(obj_context, struct object_context_s);
1109
1110 obj_context->driver_data = driver_data;
1111 obj_context->current_render_target = NULL;
1112 obj_context->ec_target = NULL;
1113 obj_context->ec_candidate = NULL;
1114 obj_context->is_oold = driver_data->is_oold;
1115 obj_context->context_id = contextID;
1116 obj_context->config_id = config_id;
1117 obj_context->picture_width = picture_width;
1118 obj_context->picture_height = picture_height;
1119 obj_context->num_render_targets = num_render_targets;
1120 obj_context->msvdx_scaling = 0;
1121 #ifdef SLICE_HEADER_PARSING
1122 obj_context->msvdx_frame_end = 0;
1123 for (i = 0; i < obj_config->attrib_count; i++) {
1124 if ((obj_config->attrib_list[i].type == VAConfigAttribDecSliceMode) &&
1125 (obj_config->attrib_list[i].value == VA_DEC_SLICE_MODE_SUBSAMPLE)) {
1126 obj_context->modular_drm = 1;
1127 break;
1128 }
1129 }
1130 #endif
1131 obj_context->scaling_width = 0;
1132 obj_context->scaling_height = 0;
1133
1134 if (num_render_targets > 0) {
1135 obj_context->render_targets = (VASurfaceID *) calloc(1, num_render_targets * sizeof(VASurfaceID));
1136 if (obj_context->render_targets == NULL) {
1137 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1138 DEBUG_FAILURE;
1139
1140 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1141
1142 return vaStatus;
1143 }
1144 }
1145
1146 /* allocate buffer points for vaRenderPicture */
1147 obj_context->num_buffers = 10;
1148 obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * obj_context->num_buffers);
1149 if (obj_context->buffer_list == NULL) {
1150 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1151 DEBUG_FAILURE;
1152
1153 if (NULL != obj_context->render_targets)
1154 free(obj_context->render_targets);
1155 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1156
1157 return vaStatus;
1158 }
1159
1160 memset(obj_context->buffers_unused, 0, sizeof(obj_context->buffers_unused));
1161 memset(obj_context->buffers_unused_count, 0, sizeof(obj_context->buffers_unused_count));
1162 memset(obj_context->buffers_unused_tail, 0, sizeof(obj_context->buffers_unused_tail));
1163 memset(obj_context->buffers_active, 0, sizeof(obj_context->buffers_active));
1164
1165 if (obj_config->entrypoint == VAEntrypointEncSlice
1166 || obj_config->entrypoint == VAEntrypointEncPicture) {
1167 encode = 1;
1168 }
1169 #ifdef PSBVIDEO_MRFL_VPP
1170 if (obj_config->entrypoint == VAEntrypointVideoProc)
1171 proc = 1;
1172
1173 //todo: fixme
1174 if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3){
1175 proc = 1;
1176 encode = 0;
1177 }
1178 #endif
1179
1180 if (encode)
1181 cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE;
1182 else if (proc)
1183 cmdbuf_num = VSP_MAX_CMDBUFS;
1184 else
1185 cmdbuf_num = PSB_MAX_CMDBUFS;
1186
1187 if (num_render_targets > 0 && (render_targets != NULL)) {
1188 for (i = 0; i < num_render_targets; i++) {
1189 object_surface_p obj_surface = SURFACE(render_targets[i]);
1190 psb_surface_p psb_surface;
1191
1192 if (NULL == obj_surface) {
1193 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE;
1194 DEBUG_FAILURE;
1195 break;
1196 }
1197
1198 if (!driver_data->protected && obj_surface->share_info)
1199 obj_surface->share_info->force_output_method = 0;
1200
1201 psb_surface = obj_surface->psb_surface;
1202
1203 /* Clear format specific surface info */
1204 obj_context->render_targets[i] = render_targets[i];
1205 obj_surface->context_id = contextID; /* Claim ownership of surface */
1206 #ifdef PSBVIDEO_MSVDX_DEC_TILING
1207 if (GET_SURFACE_INFO_tiling(psb_surface)) {
1208 #ifdef BAYTRAIL
1209 obj_context->msvdx_tile = psb__tile_stride_log2_512(obj_surface->width);
1210 #else
1211 if (obj_config->entrypoint == VAEntrypointVideoProc && obj_config->profile == VAProfileNone)
1212 // It's for two pass rotation case
1213 // Need the source surface width for tile stride setting
1214 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_context->picture_width);
1215 else
1216 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_surface->width);
1217 #endif
1218 }
1219 #endif
1220 #if 0
1221 /* for decode, move the surface into |TT */
1222 if ((encode == 0) && /* decode */
1223 ((psb_surface->buf.pl_flags & DRM_PSB_FLAG_MEM_RAR) == 0)) /* surface not in RAR */
1224 psb_buffer_setstatus(&obj_surface->psb_surface->buf,
1225 WSBM_PL_FLAG_TT | WSBM_PL_FLAG_SHARED, DRM_PSB_FLAG_MEM_MMU);
1226 #endif
1227 }
1228 } else if (num_render_targets > 0) {
1229 for (i = 0; i < num_render_targets; i++) {
1230 obj_context->render_targets[i] = VA_INVALID_SURFACE;
1231 }
1232 }
1233
1234 obj_context->va_flags = flag;
1235 obj_context->format_vtable = obj_config->format_vtable;
1236 obj_context->format_data = NULL;
1237
1238 if (VA_STATUS_SUCCESS == vaStatus) {
1239 vaStatus = obj_context->format_vtable->createContext(obj_context, obj_config);
1240 }
1241
1242 /* Error recovery */
1243 if (VA_STATUS_SUCCESS != vaStatus) {
1244 obj_context->context_id = -1;
1245 obj_context->config_id = -1;
1246 obj_context->picture_width = 0;
1247 obj_context->picture_height = 0;
1248 if (NULL != obj_context->render_targets)
1249 free(obj_context->render_targets);
1250 free(obj_context->buffer_list);
1251 obj_context->num_buffers = 0;
1252 obj_context->render_targets = NULL;
1253 obj_context->num_render_targets = 0;
1254 obj_context->va_flags = 0;
1255 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1256
1257 return vaStatus;
1258 }
1259
1260 /* initialize cmdbuf */
1261 for (i = 0; i < PNW_MAX_CMDBUFS_ENCODE; i++) {
1262 obj_context->pnw_cmdbuf_list[i] = NULL;
1263 }
1264
1265 #ifdef PSBVIDEO_MRFL
1266 for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) {
1267 obj_context->tng_cmdbuf_list[i] = NULL;
1268 }
1269 #endif
1270
1271 #ifdef PSBVIDEO_MRFL_VPP
1272 for (i = 0; i < VSP_MAX_CMDBUFS; i++) {
1273 obj_context->vsp_cmdbuf_list[i] = NULL;
1274 }
1275 #endif
1276
1277 for (i = 0; i < PSB_MAX_CMDBUFS; i++) {
1278 obj_context->cmdbuf_list[i] = NULL;
1279 }
1280
1281 for (i = 0; i < cmdbuf_num; i++) {
1282 #ifndef BAYTRAIL
1283 if (encode) { /* Topaz encode context */
1284 #ifdef PSBVIDEO_MRFL
1285 if (IS_MRFL(obj_context->driver_data)) {
1286 obj_context->tng_cmdbuf_list[i] = calloc(1, sizeof(struct tng_cmdbuf_s));
1287 if (NULL == obj_context->tng_cmdbuf_list[i]) {
1288 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1289 DEBUG_FAILURE;
1290 break;
1291 }
1292 }
1293 #endif
1294 #ifdef PSBVIDEO_MFLD
1295 if (IS_MFLD(obj_context->driver_data)) {
1296 obj_context->pnw_cmdbuf_list[i] = calloc(1, sizeof(struct pnw_cmdbuf_s));
1297 if (NULL == obj_context->pnw_cmdbuf_list[i]) {
1298 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1299 DEBUG_FAILURE;
1300 break;
1301 }
1302 }
1303 #endif
1304 } else if (proc) { /* VSP VPP context */
1305 /* VED two pass rotation under VPP API */
1306 if (driver_data->ved_vpp) {
1307 obj_context->cmdbuf_list[i] = calloc(1, sizeof(struct psb_cmdbuf_s));
1308 if (NULL == obj_context->cmdbuf_list[i]) {
1309 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1310 DEBUG_FAILURE;
1311 break;
1312 }
1313 }
1314 #ifdef PSBVIDEO_MRFL_VPP
1315 else if (IS_MRFL(obj_context->driver_data)) {
1316 obj_context->vsp_cmdbuf_list[i] = calloc(1, sizeof(struct vsp_cmdbuf_s));
1317 if (NULL == obj_context->vsp_cmdbuf_list[i]) {
1318 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1319 DEBUG_FAILURE;
1320 break;
1321 }
1322 }
1323 #endif
1324 } else /* MSVDX decode context */ {
1325 #endif
1326 obj_context->cmdbuf_list[i] = calloc(1, sizeof(struct psb_cmdbuf_s));
1327 if (NULL == obj_context->cmdbuf_list[i]) {
1328 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1329 DEBUG_FAILURE;
1330 break;
1331 }
1332 }
1333
1334 #ifndef BAYTRAIL
1335 if (encode) { /* Topaz encode context */
1336
1337 #ifdef PSBVIDEO_MRFL
1338 if (IS_MRFL(obj_context->driver_data)) {
1339 vaStatus = tng_cmdbuf_create(obj_context, driver_data, (tng_cmdbuf_p)obj_context->tng_cmdbuf_list[i]);
1340 if (VA_STATUS_SUCCESS != vaStatus) {
1341 free(obj_context->tng_cmdbuf_list[i]);
1342 DEBUG_FAILURE;
1343 break;
1344 }
1345 }
1346 #endif
1347 #ifdef PSBVIDEO_MFLD
1348 if (IS_MFLD(obj_context->driver_data)) {
1349 vaStatus = pnw_cmdbuf_create(obj_context, driver_data, (pnw_cmdbuf_p)obj_context->pnw_cmdbuf_list[i]);
1350 if (VA_STATUS_SUCCESS != vaStatus) {
1351 free(obj_context->pnw_cmdbuf_list[i]);
1352 DEBUG_FAILURE;
1353 break;
1354 }
1355 }
1356 #endif
1357 } else if (proc) { /* VSP VPP context */
1358 if (driver_data->ved_vpp) {
1359 vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)obj_context->cmdbuf_list[i]);
1360 if (VA_STATUS_SUCCESS != vaStatus) {
1361 free(obj_context->cmdbuf_list[i]);
1362 DEBUG_FAILURE;
1363 break;
1364 }
1365 }
1366 #ifdef PSBVIDEO_MRFL_VPP
1367 else if (IS_MRFL(obj_context->driver_data)) {
1368 vaStatus = vsp_cmdbuf_create(obj_context, driver_data, (vsp_cmdbuf_p)obj_context->vsp_cmdbuf_list[i]);
1369 if (VA_STATUS_SUCCESS != vaStatus) {
1370 free(obj_context->vsp_cmdbuf_list[i]);
1371 DEBUG_FAILURE;
1372 break;
1373 }
1374 }
1375 #endif
1376 } else /* MSVDX decode context */ {
1377 #endif
1378 vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)obj_context->cmdbuf_list[i]);
1379 if (VA_STATUS_SUCCESS != vaStatus) {
1380 free(obj_context->cmdbuf_list[i]);
1381 DEBUG_FAILURE;
1382 break;
1383 }
1384 }
1385
1386 #ifndef BAYTRAIL
1387 if (encode) { /* Topaz encode context */
1388 if (i >= LNC_MAX_CMDBUFS_ENCODE) {
1389 #ifdef PSBVIDEO_MRFL
1390 tng_cmdbuf_destroy((tng_cmdbuf_p)obj_context->tng_cmdbuf_list[i]);
1391 free(obj_context->tng_cmdbuf_list[i]);
1392 #endif
1393 #ifdef PSBVIDEO_MFLD
1394 pnw_cmdbuf_destroy((pnw_cmdbuf_p)obj_context->pnw_cmdbuf_list[i]);
1395 free(obj_context->pnw_cmdbuf_list[i]);
1396 #endif
1397 DEBUG_FAILURE;
1398 break;
1399 }
1400 }
1401 #endif
1402 }
1403
1404 obj_context->cmdbuf_current = -1;
1405 obj_context->cmdbuf = NULL;
1406 obj_context->pnw_cmdbuf = NULL;
1407 obj_context->tng_cmdbuf = NULL;
1408 #ifdef PSBVIDEO_MRFL_VPP
1409 obj_context->vsp_cmdbuf = NULL;
1410 #endif
1411 obj_context->frame_count = 0;
1412 obj_context->slice_count = 0;
1413 obj_context->msvdx_context = ((driver_data->msvdx_context_base & 0xff0000) >> 16) |
1414 ((contextID & 0xff000000) >> 16);
1415 #ifdef ANDROID
1416 obj_context->msvdx_context = ((driver_data->drm_fd & 0xf) << 4) |
1417 ((unsigned int)gettid() & 0xf);
1418 #endif
1419 obj_context->profile = obj_config->profile;
1420 obj_context->entry_point = obj_config->entrypoint;
1421
1422 /* Error recovery */
1423 if (VA_STATUS_SUCCESS != vaStatus) {
1424 if (cmdbuf_num > LNC_MAX_CMDBUFS_ENCODE)
1425 cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE;
1426 for (i = 0; i < cmdbuf_num; i++) {
1427 #ifndef BAYTRAIL
1428 if (obj_context->pnw_cmdbuf_list[i]) {
1429 pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]);
1430 free(obj_context->pnw_cmdbuf_list[i]);
1431 obj_context->pnw_cmdbuf_list[i] = NULL;
1432 }
1433 #endif
1434 #ifdef PSBVIDEO_MRFL
1435 if (obj_context->tng_cmdbuf_list[i]) {
1436 tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]);
1437 free(obj_context->tng_cmdbuf_list[i]);
1438 obj_context->tng_cmdbuf_list[i] = NULL;
1439 }
1440 #endif
1441 if (obj_context->cmdbuf_list[i]) {
1442 psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]);
1443 free(obj_context->cmdbuf_list[i]);
1444 obj_context->cmdbuf_list[i] = NULL;
1445 }
1446 #ifdef PSBVIDEO_MRFL_VPP
1447 if (obj_context->vsp_cmdbuf_list[i]) {
1448 vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]);
1449 free(obj_context->vsp_cmdbuf_list[i]);
1450 obj_context->vsp_cmdbuf_list[i] = NULL;
1451 }
1452 #endif
1453 }
1454
1455 obj_context->cmdbuf = NULL;
1456 #ifdef PSBVIDEO_MRFL_VPP
1457 obj_context->vsp_cmdbuf = NULL;
1458 #endif
1459
1460 obj_context->context_id = -1;
1461 obj_context->config_id = -1;
1462 obj_context->picture_width = 0;
1463 obj_context->picture_height = 0;
1464 if (NULL != obj_context->render_targets)
1465 free(obj_context->render_targets);
1466 free(obj_context->buffer_list);
1467 obj_context->num_buffers = 0;
1468 obj_context->render_targets = NULL;
1469 obj_context->num_render_targets = 0;
1470 obj_context->va_flags = 0;
1471 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1472 }
1473 obj_context->ctp_type = (((obj_config->profile << 8) |
1474 obj_config->entrypoint | driver_data->protected) & 0xffff);
1475
1476 /* VSP's PM rely on VPP ctx, so ved vpp use diferent profile/level for ctx */
1477 if (driver_data->ved_vpp)
1478 obj_context->ctp_type = (((obj_config->profile << 8) |
1479 VAEntrypointVLD | driver_data->protected) & 0xffff);
1480
1481 if (!encode) {
1482 obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
1483 }
1484
1485 if (obj_context->ctp_type & VAEntrypointVLD) {
1486 if (render_targets == NULL) {
1487 obj_context->ctp_type |= PSB_SURFACE_UNAVAILABLE;
1488 }
1489 }
1490
1491 if (obj_context->ctp_type & VAEntrypointVLD) {
1492 if (render_targets == NULL) {
1493 obj_context->ctp_type |= PSB_SURFACE_UNAVAILABLE;
1494 }
1495 }
1496
1497 if (obj_config->profile == VAProfileVC1Simple ||
1498 obj_config->profile == VAProfileVC1Main ||
1499 obj_config->profile == VAProfileVC1Advanced ||
1500 obj_config->profile == VAProfileH264Baseline ||
1501 obj_config->profile == VAProfileH264Main ||
1502 obj_config->profile == VAProfileH264High ||
1503 obj_config->profile == VAProfileVP8Version0_3) {
1504 uint64_t width_in_mb = ((driver_data->render_rect.x + driver_data->render_rect.width + 15) / 16);
1505 uint64_t height_in_mb = ((driver_data->render_rect.y + driver_data->render_rect.height + 15) / 16);
1506 obj_context->ctp_type |= (width_in_mb << 32);
1507 obj_context->ctp_type |= (height_in_mb << 48);
1508 }
1509
1510 /* add ctx_num to save vp8 enc context num to support dual vp8 encoding */
1511 int ret = psb_new_context(driver_data, obj_context->ctp_type | driver_data->protected);
1512 if (ret)
1513 vaStatus = VA_STATUS_ERROR_UNKNOWN;
1514
1515 DEBUG_FUNC_EXIT
1516 return vaStatus;
1517 }
1518
psb__allocate_malloc_buffer(object_buffer_p obj_buffer,int size)1519 static VAStatus psb__allocate_malloc_buffer(object_buffer_p obj_buffer, int size)
1520 {
1521 VAStatus vaStatus = VA_STATUS_SUCCESS;
1522
1523 obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size);
1524 CHECK_ALLOCATION(obj_buffer->buffer_data);
1525
1526 return vaStatus;
1527 }
1528
1529 static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer);
1530
psb__allocate_BO_buffer(psb_driver_data_p driver_data,object_context_p __maybe_unused obj_context,object_buffer_p obj_buffer,int size,unsigned char * data,VABufferType type)1531 static VAStatus psb__allocate_BO_buffer(psb_driver_data_p driver_data, object_context_p __maybe_unused obj_context, object_buffer_p obj_buffer, int size, unsigned char *data, VABufferType type)
1532 {
1533 VAStatus vaStatus = VA_STATUS_SUCCESS;
1534
1535 ASSERT(NULL == obj_buffer->buffer_data);
1536
1537 if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) {
1538 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Abandoning BO for buffer %08x type %s\n", obj_buffer->base.id,
1539 buffer_type_to_string(obj_buffer->type));
1540 /* need to set psb_buffer aside and get another one */
1541 obj_buffer->psb_buffer->status = psb_bs_abandoned;
1542 obj_buffer->psb_buffer = NULL;
1543 obj_buffer->size = 0;
1544 obj_buffer->alloc_size = 0;
1545 }
1546
1547 if (type == VAProtectedSliceDataBufferType) {
1548 if (obj_buffer->psb_buffer) {
1549 drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: old RAR slice buffer with RAR handle 0%08x, current RAR handle 0x%08x\n",
1550 obj_buffer->psb_buffer->rar_handle, (uint32_t)data);
1551 drv_debug_msg(VIDEO_DEBUG_GENERAL, "RAR: force old RAR buffer destroy and new buffer re-allocation by set size=0\n");
1552 obj_buffer->alloc_size = 0;
1553 }
1554 }
1555
1556 if (obj_buffer->alloc_size < (unsigned int)size) {
1557 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Buffer size mismatch: Need %d, currently have %d\n", size, obj_buffer->alloc_size);
1558 if (obj_buffer->psb_buffer) {
1559 if (obj_buffer->buffer_data) {
1560 psb__unmap_buffer(obj_buffer);
1561 }
1562 psb_buffer_destroy(obj_buffer->psb_buffer);
1563 obj_buffer->alloc_size = 0;
1564 } else {
1565 obj_buffer->psb_buffer = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s));
1566 if (NULL == obj_buffer->psb_buffer) {
1567 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1568 DEBUG_FAILURE;
1569 }
1570 }
1571 if (VA_STATUS_SUCCESS == vaStatus) {
1572 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new GPU buffers for vaCreateBuffer:type=%s,size=%d.\n",
1573 buffer_type_to_string(obj_buffer->type), size);
1574
1575 size = (size + 0x7fff) & ~0x7fff; /* Round up */
1576 if (obj_buffer->type == VAImageBufferType) /* Xserver side PutSurface, Image/subpicture buffer
1577 * should be shared between two process
1578 */
1579 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu_shared, obj_buffer->psb_buffer);
1580 #ifndef BAYTRAIL
1581 else if (obj_buffer->type == VAProtectedSliceDataBufferType) {
1582 vaStatus = psb_buffer_reference_imr(driver_data, (uint32_t)data, obj_buffer->psb_buffer);
1583 }
1584 #endif
1585 else if (obj_buffer->type == VAEncCodedBufferType)
1586 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer);
1587 else
1588 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer);
1589
1590 if (VA_STATUS_SUCCESS != vaStatus) {
1591 free(obj_buffer->psb_buffer);
1592 obj_buffer->psb_buffer = NULL;
1593 DEBUG_FAILURE;
1594 } else {
1595 obj_buffer->alloc_size = size;
1596 }
1597 }
1598 }
1599 return vaStatus;
1600 }
1601
psb__map_buffer(object_buffer_p obj_buffer)1602 static VAStatus psb__map_buffer(object_buffer_p obj_buffer)
1603 {
1604 if (obj_buffer->psb_buffer) {
1605 return psb_buffer_map(obj_buffer->psb_buffer, &obj_buffer->buffer_data);
1606 }
1607 return VA_STATUS_SUCCESS;
1608 }
1609
psb__unmap_buffer(object_buffer_p obj_buffer)1610 static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer)
1611 {
1612 if (obj_buffer->psb_buffer) {
1613 obj_buffer->buffer_data = NULL;
1614 return psb_buffer_unmap(obj_buffer->psb_buffer);
1615 }
1616 return VA_STATUS_SUCCESS;
1617 }
1618
psb__destroy_buffer(psb_driver_data_p driver_data,object_buffer_p obj_buffer)1619 static void psb__destroy_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer)
1620 {
1621 if (obj_buffer->psb_buffer) {
1622 if (obj_buffer->buffer_data) {
1623 psb__unmap_buffer(obj_buffer);
1624 }
1625 psb_buffer_destroy(obj_buffer->psb_buffer);
1626 free(obj_buffer->psb_buffer);
1627 obj_buffer->psb_buffer = NULL;
1628 }
1629
1630 if (NULL != obj_buffer->buffer_data) {
1631 free(obj_buffer->buffer_data);
1632 obj_buffer->buffer_data = NULL;
1633 obj_buffer->size = 0;
1634 }
1635
1636 object_heap_free(&driver_data->buffer_heap, (object_base_p) obj_buffer);
1637 }
1638
psb__suspend_buffer(psb_driver_data_p driver_data,object_buffer_p obj_buffer)1639 void psb__suspend_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer)
1640 {
1641 if (obj_buffer->context) {
1642 VABufferType type = obj_buffer->type;
1643 object_context_p obj_context = obj_buffer->context;
1644
1645 if (type >= PSB_MAX_BUFFERTYPES) {
1646 drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid buffer type %d\n", type);
1647 return;
1648 }
1649
1650 /* Remove buffer from active list */
1651 *obj_buffer->pptr_prev_next = obj_buffer->ptr_next;
1652
1653 /* Add buffer to tail of unused list */
1654 obj_buffer->ptr_next = NULL;
1655 obj_buffer->last_used = obj_context->frame_count;
1656 if (obj_context->buffers_unused_tail[type]) {
1657 obj_buffer->pptr_prev_next = &(obj_context->buffers_unused_tail[type]->ptr_next);
1658 } else {
1659 obj_buffer->pptr_prev_next = &(obj_context->buffers_unused[type]);
1660 }
1661 *obj_buffer->pptr_prev_next = obj_buffer;
1662 obj_context->buffers_unused_tail[type] = obj_buffer;
1663 obj_context->buffers_unused_count[type]++;
1664
1665 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Adding buffer %08x type %s to unused list. unused count = %d\n", obj_buffer->base.id,
1666 buffer_type_to_string(obj_buffer->type), obj_context->buffers_unused_count[type]);
1667
1668 object_heap_suspend_object((object_base_p) obj_buffer, 1); /* suspend */
1669 return;
1670 }
1671
1672 if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) {
1673 /* need to set psb_buffer aside */
1674 obj_buffer->psb_buffer->status = psb_bs_abandoned;
1675 obj_buffer->psb_buffer = NULL;
1676 }
1677
1678 psb__destroy_buffer(driver_data, obj_buffer);
1679 }
1680
psb__destroy_context(psb_driver_data_p driver_data,object_context_p obj_context)1681 static void psb__destroy_context(psb_driver_data_p driver_data, object_context_p obj_context)
1682 {
1683 int encode, i;
1684
1685 if (obj_context->entry_point == VAEntrypointEncSlice)
1686 encode = 1;
1687 else
1688 encode = 0;
1689
1690 obj_context->format_vtable->destroyContext(obj_context);
1691
1692 for (i = 0; i < PSB_MAX_BUFFERTYPES; i++) {
1693 object_buffer_p obj_buffer;
1694 obj_buffer = obj_context->buffers_active[i];
1695 for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) {
1696 drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying active buffer %08x\n", __FUNCTION__, obj_buffer->base.id);
1697 psb__destroy_buffer(driver_data, obj_buffer);
1698 }
1699 obj_buffer = obj_context->buffers_unused[i];
1700 for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) {
1701 drv_debug_msg(VIDEO_DEBUG_INIT, "%s: destroying unused buffer %08x\n", __FUNCTION__, obj_buffer->base.id);
1702 psb__destroy_buffer(driver_data, obj_buffer);
1703 }
1704 obj_context->buffers_unused_count[i] = 0;
1705 }
1706 #ifndef BAYTRAIL
1707 for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) {
1708 if (obj_context->pnw_cmdbuf_list[i]) {
1709 pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]);
1710 free(obj_context->pnw_cmdbuf_list[i]);
1711 obj_context->pnw_cmdbuf_list[i] = NULL;
1712 }
1713 }
1714 #endif
1715 #ifdef PSBVIDEO_MRFL
1716 for (i = 0; i < TNG_MAX_CMDBUFS_ENCODE; i++) {
1717 if (obj_context->tng_cmdbuf_list[i]) {
1718 tng_cmdbuf_destroy(obj_context->tng_cmdbuf_list[i]);
1719 free(obj_context->tng_cmdbuf_list[i]);
1720 obj_context->tng_cmdbuf_list[i] = NULL;
1721 }
1722 }
1723 #endif
1724 #ifdef PSBVIDEO_MRFL_VPP
1725 for (i = 0; i < VSP_MAX_CMDBUFS; i++) {
1726 if (obj_context->vsp_cmdbuf_list[i]) {
1727 vsp_cmdbuf_destroy(obj_context->vsp_cmdbuf_list[i]);
1728 free(obj_context->vsp_cmdbuf_list[i]);
1729 obj_context->vsp_cmdbuf_list[i] = NULL;
1730 }
1731 }
1732 #endif
1733
1734 for (i = 0; i < PSB_MAX_CMDBUFS; i++) {
1735 if (obj_context->cmdbuf_list[i]) {
1736 psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]);
1737 free(obj_context->cmdbuf_list[i]);
1738 obj_context->cmdbuf_list[i] = NULL;
1739 }
1740 }
1741 obj_context->cmdbuf = NULL;
1742 #ifdef PSBVIDEO_MRFL_VPP
1743 obj_context->vsp_cmdbuf = NULL;
1744 #endif
1745
1746 obj_context->context_id = -1;
1747 obj_context->config_id = -1;
1748 obj_context->picture_width = 0;
1749 obj_context->picture_height = 0;
1750 if (obj_context->render_targets)
1751 free(obj_context->render_targets);
1752 obj_context->render_targets = NULL;
1753 obj_context->num_render_targets = 0;
1754 obj_context->va_flags = 0;
1755
1756 obj_context->current_render_target = NULL;
1757 obj_context->ec_target = NULL;
1758 obj_context->ec_candidate = NULL;
1759 if (obj_context->buffer_list)
1760 free(obj_context->buffer_list);
1761 obj_context->num_buffers = 0;
1762
1763 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context);
1764
1765 psb_rm_context(driver_data);
1766 }
1767
psb_DestroyContext(VADriverContextP ctx,VAContextID context)1768 VAStatus psb_DestroyContext(
1769 VADriverContextP ctx,
1770 VAContextID context
1771 )
1772 {
1773 DEBUG_FUNC_ENTER
1774 INIT_DRIVER_DATA
1775 VAStatus vaStatus = VA_STATUS_SUCCESS;
1776 object_context_p obj_context = CONTEXT(context);
1777 CHECK_CONTEXT(obj_context);
1778
1779 psb__destroy_context(driver_data, obj_context);
1780
1781 DEBUG_FUNC_EXIT
1782 return vaStatus;
1783 }
1784
psb__CreateBuffer(psb_driver_data_p driver_data,object_context_p obj_context,VABufferType type,unsigned int size,unsigned int num_elements,unsigned char * data,VABufferID * buf_desc)1785 VAStatus psb__CreateBuffer(
1786 psb_driver_data_p driver_data,
1787 object_context_p obj_context, /* in */
1788 VABufferType type, /* in */
1789 unsigned int size, /* in */
1790 unsigned int num_elements, /* in */
1791 unsigned char *data, /* in */
1792 VABufferID *buf_desc /* out */
1793 )
1794 {
1795 DEBUG_FUNC_ENTER
1796 VAStatus vaStatus = VA_STATUS_SUCCESS;
1797 int bufferID;
1798 object_buffer_p obj_buffer;
1799 int unused_count;
1800
1801 /*PSB_MAX_BUFFERTYPES is the size of array buffers_unused*/
1802 if (type >= PSB_MAX_BUFFERTYPES) {
1803 drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid buffer type %d\n", type);
1804 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1805 }
1806
1807
1808 obj_buffer = obj_context ? obj_context->buffers_unused[type] : NULL;
1809 unused_count = obj_context ? obj_context->buffers_unused_count[type] : 0;
1810
1811 /*
1812 * Buffer Management
1813 * For each buffer type, maintain
1814 * - a LRU sorted list of unused buffers
1815 * - a list of active buffers
1816 * We only create a new buffer when
1817 * - no unused buffers are available
1818 * - the last unused buffer is still queued
1819 * - the last unused buffer was used very recently and may still be fenced
1820 * - used recently is defined as within the current frame_count (subject to tweaks)
1821 *
1822 * The buffer that is returned will be moved to the list of active buffers
1823 * - vaDestroyBuffer and vaRenderPicture will move the active buffer back to the list of unused buffers
1824 */
1825 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Requesting buffer creation, size=%d,elements=%d,type=%s\n", size, num_elements,
1826 buffer_type_to_string(type));
1827
1828 /* on MFLD, data is IMR offset, and could be 0 */
1829 /*
1830 if ((type == VAProtectedSliceDataBufferType) && (data == NULL)) {
1831 drv_debug_msg(VIDEO_DEBUG_ERROR, "RAR: Create protected slice buffer, but RAR handle is NULL\n");
1832 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE ;
1833 }
1834 */
1835
1836 if (obj_buffer && obj_buffer->psb_buffer) {
1837 if (psb_bs_queued == obj_buffer->psb_buffer->status) {
1838 /* Buffer is still queued, allocate new buffer instead */
1839 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, still queued\n", obj_buffer->base.id);
1840 obj_buffer = NULL;
1841 } else if ((obj_buffer->last_used == obj_context->frame_count) && (unused_count < MAX_UNUSED_BUFFERS)) {
1842 /* Buffer was used for this frame, allocate new buffer instead */
1843 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x, recently used. Unused = %d\n", obj_buffer->base.id, unused_count);
1844 obj_buffer = NULL;
1845 } else if (obj_context->frame_count - obj_buffer->last_used < 5) {
1846 /* Buffer was used for previous frame, allocate new buffer instead */
1847 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Skipping idle buffer %08x used by frame %d. Unused = %d\n", obj_buffer->base.id, obj_buffer->last_used, unused_count);
1848 obj_buffer = NULL;
1849 }
1850 }
1851
1852 if (obj_buffer) {
1853 bufferID = obj_buffer->base.id;
1854 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Reusing buffer %08x type %s from unused list. Unused = %d\n", bufferID,
1855 buffer_type_to_string(type), unused_count);
1856
1857 /* Remove from unused list */
1858 obj_context->buffers_unused[type] = obj_buffer->ptr_next;
1859 if (obj_context->buffers_unused[type]) {
1860 obj_context->buffers_unused[type]->pptr_prev_next = &(obj_context->buffers_unused[type]);
1861 ASSERT(obj_context->buffers_unused_tail[type] != obj_buffer);
1862 } else {
1863 ASSERT(obj_context->buffers_unused_tail[type] == obj_buffer);
1864 obj_context->buffers_unused_tail[type] = 0;
1865 }
1866 obj_context->buffers_unused_count[type]--;
1867
1868 object_heap_suspend_object((object_base_p)obj_buffer, 0); /* Make BufferID valid again */
1869 ASSERT(type == obj_buffer->type);
1870 ASSERT(obj_context == obj_buffer->context);
1871 } else {
1872 bufferID = object_heap_allocate(&driver_data->buffer_heap);
1873 obj_buffer = BUFFER(bufferID);
1874 CHECK_ALLOCATION(obj_buffer);
1875
1876 MEMSET_OBJECT(obj_buffer, struct object_buffer_s);
1877
1878 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocating new buffer %08x type %s.\n", bufferID, buffer_type_to_string(type));
1879 obj_buffer->type = type;
1880 obj_buffer->buffer_data = NULL;
1881 obj_buffer->psb_buffer = NULL;
1882 obj_buffer->size = 0;
1883 obj_buffer->max_num_elements = 0;
1884 obj_buffer->alloc_size = 0;
1885 obj_buffer->context = obj_context;
1886 }
1887 if (obj_context) {
1888 /* Add to front of active list */
1889 obj_buffer->ptr_next = obj_context->buffers_active[type];
1890 if (obj_buffer->ptr_next) {
1891 obj_buffer->ptr_next->pptr_prev_next = &(obj_buffer->ptr_next);
1892 }
1893 obj_buffer->pptr_prev_next = &(obj_context->buffers_active[type]);
1894 *obj_buffer->pptr_prev_next = obj_buffer;
1895 }
1896
1897 switch (obj_buffer->type) {
1898 case VABitPlaneBufferType:
1899 case VASliceDataBufferType:
1900 case VAResidualDataBufferType:
1901 case VAImageBufferType:
1902 case VASliceGroupMapBufferType:
1903 case VAEncCodedBufferType:
1904 case VAProtectedSliceDataBufferType:
1905 #ifdef SLICE_HEADER_PARSING
1906 case VAParseSliceHeaderGroupBufferType:
1907 #endif
1908 vaStatus = psb__allocate_BO_buffer(driver_data, obj_context,obj_buffer, size * num_elements, data, obj_buffer->type);
1909 DEBUG_FAILURE;
1910 break;
1911 case VAPictureParameterBufferType:
1912 case VAIQMatrixBufferType:
1913 case VASliceParameterBufferType:
1914 case VAMacroblockParameterBufferType:
1915 case VADeblockingParameterBufferType:
1916 case VAEncPackedHeaderParameterBufferType:
1917 case VAEncPackedHeaderDataBufferType:
1918 case VAEncSequenceParameterBufferType:
1919 case VAEncPictureParameterBufferType:
1920 case VAEncSliceParameterBufferType:
1921 case VAQMatrixBufferType:
1922 case VAEncMiscParameterBufferType:
1923 case VAProbabilityBufferType:
1924 case VAHuffmanTableBufferType:
1925 case VAProcPipelineParameterBufferType:
1926 case VAProcFilterParameterBufferType:
1927 #ifdef SLICE_HEADER_PARSING
1928 case VAParsePictureParameterBufferType:
1929 #endif
1930 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate new malloc buffers for vaCreateBuffer:type=%s,size=%d, buffer_data=%p.\n",
1931 buffer_type_to_string(type), size, obj_buffer->buffer_data);
1932 vaStatus = psb__allocate_malloc_buffer(obj_buffer, size * num_elements);
1933 DEBUG_FAILURE;
1934 break;
1935
1936 default:
1937 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
1938 DEBUG_FAILURE;
1939 break;;
1940 }
1941
1942 if (VA_STATUS_SUCCESS == vaStatus) {
1943 obj_buffer->size = size;
1944 obj_buffer->max_num_elements = num_elements;
1945 obj_buffer->num_elements = num_elements;
1946 if (data && (obj_buffer->type != VAProtectedSliceDataBufferType)) {
1947 vaStatus = psb__map_buffer(obj_buffer);
1948 if (VA_STATUS_SUCCESS == vaStatus) {
1949 memcpy(obj_buffer->buffer_data, data, size * num_elements);
1950
1951 psb__unmap_buffer(obj_buffer);
1952 }
1953 }
1954 }
1955 if (VA_STATUS_SUCCESS == vaStatus) {
1956 *buf_desc = bufferID;
1957 } else {
1958 psb__destroy_buffer(driver_data, obj_buffer);
1959 }
1960
1961 DEBUG_FUNC_EXIT
1962 return vaStatus;
1963 }
1964
psb_CreateBuffer(VADriverContextP ctx,VAContextID context,VABufferType type,unsigned int size,unsigned int num_elements,void * data,VABufferID * buf_desc)1965 VAStatus psb_CreateBuffer(
1966 VADriverContextP ctx,
1967 VAContextID context, /* in */
1968 VABufferType type, /* in */
1969 unsigned int size, /* in */
1970 unsigned int num_elements, /* in */
1971 void *data, /* in */
1972 VABufferID *buf_desc /* out */
1973 )
1974 {
1975 DEBUG_FUNC_ENTER
1976 INIT_DRIVER_DATA
1977 VAStatus vaStatus = VA_STATUS_SUCCESS;
1978
1979 CHECK_INVALID_PARAM(num_elements <= 0);
1980
1981 switch (type) {
1982 case VABitPlaneBufferType:
1983 case VASliceDataBufferType:
1984 case VAProtectedSliceDataBufferType:
1985 case VAResidualDataBufferType:
1986 case VASliceGroupMapBufferType:
1987 case VAPictureParameterBufferType:
1988 case VAIQMatrixBufferType:
1989 case VASliceParameterBufferType:
1990 case VAMacroblockParameterBufferType:
1991 case VADeblockingParameterBufferType:
1992 case VAEncCodedBufferType:
1993 case VAEncSequenceParameterBufferType:
1994 case VAEncPictureParameterBufferType:
1995 case VAEncSliceParameterBufferType:
1996 case VAEncPackedHeaderParameterBufferType:
1997 case VAEncPackedHeaderDataBufferType:
1998 case VAQMatrixBufferType:
1999 case VAEncMiscParameterBufferType:
2000 case VAProbabilityBufferType:
2001 case VAHuffmanTableBufferType:
2002 case VAProcPipelineParameterBufferType:
2003 case VAProcFilterParameterBufferType:
2004 #ifdef SLICE_HEADER_PARSING
2005 case VAParsePictureParameterBufferType:
2006 case VAParseSliceHeaderGroupBufferType:
2007 #endif
2008 break;
2009
2010 default:
2011 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
2012 DEBUG_FAILURE;
2013 return vaStatus;
2014 }
2015
2016 object_context_p obj_context = CONTEXT(context);
2017 CHECK_CONTEXT(obj_context);
2018 CHECK_INVALID_PARAM(buf_desc == NULL);
2019
2020 vaStatus = psb__CreateBuffer(driver_data, obj_context, type, size, num_elements, data, buf_desc);
2021
2022 DEBUG_FUNC_EXIT
2023 return vaStatus;
2024 }
2025
2026
psb_BufferInfo(VADriverContextP ctx,VABufferID buf_id,VABufferType * type,unsigned int * size,unsigned int * num_elements)2027 VAStatus psb_BufferInfo(
2028 VADriverContextP ctx,
2029 VABufferID buf_id, /* in */
2030 VABufferType *type, /* out */
2031 unsigned int *size, /* out */
2032 unsigned int *num_elements /* out */
2033 )
2034 {
2035 DEBUG_FUNC_ENTER
2036 INIT_DRIVER_DATA
2037 VAStatus vaStatus = VA_STATUS_SUCCESS;
2038
2039 object_buffer_p obj_buffer = BUFFER(buf_id);
2040 CHECK_BUFFER(obj_buffer);
2041
2042 *type = obj_buffer->type;
2043 *size = obj_buffer->size;
2044 *num_elements = obj_buffer->num_elements;
2045 DEBUG_FUNC_EXIT
2046 return VA_STATUS_SUCCESS;
2047 }
2048
2049
psb_BufferSetNumElements(VADriverContextP ctx,VABufferID buf_id,unsigned int num_elements)2050 VAStatus psb_BufferSetNumElements(
2051 VADriverContextP ctx,
2052 VABufferID buf_id, /* in */
2053 unsigned int num_elements /* in */
2054 )
2055 {
2056 DEBUG_FUNC_ENTER
2057 INIT_DRIVER_DATA
2058 VAStatus vaStatus = VA_STATUS_SUCCESS;
2059 object_buffer_p obj_buffer = BUFFER(buf_id);
2060 CHECK_BUFFER(obj_buffer);
2061
2062 if ((num_elements <= 0) || (num_elements > obj_buffer->max_num_elements)) {
2063 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
2064 }
2065 if (VA_STATUS_SUCCESS == vaStatus) {
2066 obj_buffer->num_elements = num_elements;
2067 }
2068
2069 DEBUG_FUNC_EXIT
2070 return vaStatus;
2071 }
2072
psb_MapBuffer(VADriverContextP ctx,VABufferID buf_id,void ** pbuf)2073 VAStatus psb_MapBuffer(
2074 VADriverContextP ctx,
2075 VABufferID buf_id, /* in */
2076 void **pbuf /* out */
2077 )
2078 {
2079 DEBUG_FUNC_ENTER
2080 INIT_DRIVER_DATA
2081 VAStatus vaStatus = VA_STATUS_SUCCESS;
2082 object_buffer_p obj_buffer = BUFFER(buf_id);
2083 CHECK_BUFFER(obj_buffer);
2084
2085 CHECK_INVALID_PARAM(pbuf == NULL);
2086
2087 vaStatus = psb__map_buffer(obj_buffer);
2088 CHECK_VASTATUS();
2089
2090 if (NULL != obj_buffer->buffer_data) {
2091 *pbuf = obj_buffer->buffer_data;
2092
2093 /* specifically for Topaz encode
2094 * write validate coded data offset in CodedBuffer
2095 */
2096 if (obj_buffer->type == VAEncCodedBufferType)
2097 psb_codedbuf_map_mangle(ctx, obj_buffer, pbuf);
2098 /* *(IMG_UINT32 *)((unsigned char *)obj_buffer->buffer_data + 4) = 16; */
2099 } else {
2100 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2101 }
2102 DEBUG_FUNC_EXIT
2103 return vaStatus;
2104 }
2105
psb_UnmapBuffer(VADriverContextP ctx,VABufferID buf_id)2106 VAStatus psb_UnmapBuffer(
2107 VADriverContextP ctx,
2108 VABufferID buf_id /* in */
2109 )
2110 {
2111 DEBUG_FUNC_ENTER
2112 INIT_DRIVER_DATA
2113 VAStatus vaStatus = VA_STATUS_SUCCESS;
2114 object_buffer_p obj_buffer = BUFFER(buf_id);
2115 CHECK_BUFFER(obj_buffer);
2116
2117 vaStatus = psb__unmap_buffer(obj_buffer);
2118 DEBUG_FUNC_EXIT
2119 return vaStatus;
2120 }
2121
2122
psb_DestroyBuffer(VADriverContextP ctx,VABufferID buffer_id)2123 VAStatus psb_DestroyBuffer(
2124 VADriverContextP ctx,
2125 VABufferID buffer_id
2126 )
2127 {
2128 DEBUG_FUNC_ENTER
2129 INIT_DRIVER_DATA
2130 VAStatus vaStatus = VA_STATUS_SUCCESS;
2131 object_buffer_p obj_buffer = BUFFER(buffer_id);
2132 if (NULL == obj_buffer) {
2133 return vaStatus;
2134 }
2135 psb__suspend_buffer(driver_data, obj_buffer);
2136 DEBUG_FUNC_EXIT
2137 return vaStatus;
2138 }
2139
2140
psb_BeginPicture(VADriverContextP ctx,VAContextID context,VASurfaceID render_target)2141 VAStatus psb_BeginPicture(
2142 VADriverContextP ctx,
2143 VAContextID context,
2144 VASurfaceID render_target
2145 )
2146 {
2147 DEBUG_FUNC_ENTER
2148 INIT_DRIVER_DATA
2149 VAStatus vaStatus = VA_STATUS_SUCCESS;
2150 object_context_p obj_context;
2151 object_surface_p obj_surface;
2152 object_config_p obj_config;
2153 unsigned int i = 0, j = VA_INVALID_ID;
2154
2155 obj_context = CONTEXT(context);
2156 CHECK_CONTEXT(obj_context);
2157
2158 /* Must not be within BeginPicture / EndPicture already */
2159 ASSERT(obj_context->current_render_target == NULL);
2160
2161 obj_surface = SURFACE(render_target);
2162 CHECK_SURFACE(obj_surface);
2163
2164 obj_context->current_render_surface_id = render_target;
2165 obj_context->current_render_target = obj_surface;
2166 obj_context->slice_count = 0;
2167
2168 obj_config = CONFIG(obj_context->config_id);
2169 if (obj_config == NULL)
2170 return VA_STATUS_ERROR_INVALID_CONFIG;
2171
2172 for (i = 0; i < (unsigned int)obj_context->num_render_targets; i++) {
2173 if (obj_context->render_targets[i] == obj_surface->surface_id) {
2174 break;
2175 } else if (SURFACE(obj_context->render_targets[i]) == NULL) {
2176 j = (i < j) ? i : j;
2177 }
2178 }
2179
2180 if (i >= (unsigned int)obj_context->num_render_targets) {
2181 if (j < (unsigned int)obj_context->num_render_targets) {
2182 obj_context->render_targets[j] = obj_surface->surface_id;
2183 obj_surface->context_id = obj_context->context_id;
2184
2185 #ifdef PSBVIDEO_MSVDX_DEC_TILING
2186 if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface)) {
2187 #ifdef BAYTRAIL
2188 obj_context->msvdx_tile = psb__tile_stride_log2_512(obj_surface->width);
2189 #else
2190 if ( (obj_config != NULL) &&
2191 (obj_config->entrypoint == VAEntrypointVideoProc) &&
2192 (obj_config->profile == VAProfileNone)) {
2193 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_context->picture_width);
2194 } else {
2195 obj_context->msvdx_tile = psb__tile_stride_log2_256(obj_surface->width);
2196 }
2197 #endif
2198 }
2199
2200 obj_context->msvdx_tile &= 0xf; /* clear rotate tile */
2201 obj_context->ctp_type &= (~PSB_CTX_TILING_MASK); /* clear tile context */
2202 obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
2203 obj_context->ctp_type &= (~PSB_SURFACE_UNAVAILABLE);
2204 psb_update_context(driver_data, obj_context->ctp_type | driver_data->protected);
2205 #endif
2206 }
2207 }
2208
2209 if ((driver_data->protected & VA_RT_FORMAT_PROTECTED) &&
2210 !(obj_context->ctp_type & VA_RT_FORMAT_PROTECTED)) {
2211 obj_context->ctp_type |= VA_RT_FORMAT_PROTECTED;
2212 psb_update_context(driver_data, obj_context->ctp_type);
2213 }
2214
2215 /* if the surface is decode render target, and in displaying */
2216 if (obj_config &&
2217 (obj_config->entrypoint != VAEntrypointEncSlice) &&
2218 (driver_data->cur_displaying_surface == render_target))
2219 drv_debug_msg(VIDEO_DEBUG_ERROR, "WARNING: rendering a displaying surface, may see tearing\n");
2220
2221 if (VA_STATUS_SUCCESS == vaStatus) {
2222 vaStatus = obj_context->format_vtable->beginPicture(obj_context);
2223 }
2224
2225 #ifdef ANDROID
2226 /* want msvdx to do rotate
2227 * but check per-context stream type: interlace or not
2228 */
2229 if ((obj_config->entrypoint != VAEntrypointEncSlice) &&
2230 (obj_config->entrypoint != VAEntrypointEncPicture)) {
2231 psb_RecalcAlternativeOutput(obj_context);
2232 }
2233 #endif
2234 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2235 if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface))
2236 driver_data->disable_msvdx_rotate = 0;
2237 #endif
2238 if (obj_context->interlaced_stream || driver_data->disable_msvdx_rotate) {
2239 int i = 0;
2240 obj_context->msvdx_rotate = 0;
2241 if (obj_context->num_render_targets > 0) {
2242 for (i = 0; i < obj_context->num_render_targets; i++) {
2243 object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]);
2244 /*we invalidate all surfaces's rotate buffer share info here.*/
2245 if (obj_surface && obj_surface->share_info) {
2246 obj_surface->share_info->surface_rotate = 0;
2247 }
2248 }
2249 }
2250 }
2251 else
2252 obj_context->msvdx_rotate = driver_data->msvdx_rotate_want;
2253
2254 /* the main surface track current rotate information
2255 * try to reuse the allocated rotate surfaces and don't destroy them
2256 * thus the rotation info in obj_surface->out_loop_surface may not be updated
2257 */
2258
2259 SET_SURFACE_INFO_rotate(obj_surface->psb_surface, obj_context->msvdx_rotate);
2260
2261 if (CONTEXT_SCALING(obj_context) && obj_config->entrypoint != VAEntrypointEncSlice)
2262 if(VA_STATUS_SUCCESS != psb_CreateScalingSurface(obj_context, obj_surface)) {
2263 obj_context->msvdx_scaling = 0;
2264 ALOGE("%s: fail to allocate scaling surface", __func__);
2265 }
2266
2267 if (CONTEXT_ROTATE(obj_context)) {
2268 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2269 /* The VSP rotation is just for 1080P with tilling */
2270 if (driver_data->vpp_on && GET_SURFACE_INFO_tiling(obj_surface->psb_surface)) {
2271 if (obj_config->entrypoint == VAEntrypointVideoProc)
2272 vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate);
2273 else {
2274 SET_SURFACE_INFO_rotate(obj_surface->psb_surface, 0);
2275 obj_context->msvdx_rotate = 0;
2276 vaStatus = psb_DestroyRotateBuffer(obj_context, obj_surface);
2277 }
2278 } else
2279 #endif
2280 vaStatus = psb_CreateRotateSurface(obj_context, obj_surface, obj_context->msvdx_rotate);
2281 if (VA_STATUS_SUCCESS !=vaStatus)
2282 ALOGE("%s: fail to allocate out loop surface", __func__);
2283
2284 } else {
2285 if (obj_surface && obj_surface->share_info) {
2286 obj_surface->share_info->metadata_rotate = VAROTATION2HAL(driver_data->va_rotate);
2287 obj_surface->share_info->surface_rotate = VAROTATION2HAL(obj_context->msvdx_rotate);
2288 }
2289 }
2290
2291 if (obj_surface && obj_surface->share_info &&
2292 obj_config->entrypoint == VAEntrypointVLD) {
2293 obj_surface->share_info->crop_width = driver_data->render_rect.width;
2294 obj_surface->share_info->crop_height = driver_data->render_rect.height;
2295 }
2296
2297 if (driver_data->is_oold && !obj_surface->psb_surface->in_loop_buf) {
2298 psb_surface_p psb_surface = obj_surface->psb_surface;
2299
2300 psb_surface->in_loop_buf = calloc(1, sizeof(struct psb_buffer_s));
2301 CHECK_ALLOCATION(psb_surface->in_loop_buf);
2302
2303 /* FIXME: For RAR surface, need allocate RAR buffer */
2304 vaStatus = psb_buffer_create(obj_context->driver_data,
2305 psb_surface->size,
2306 psb_bt_surface,
2307 psb_surface->in_loop_buf);
2308 } else if (!driver_data->is_oold && obj_surface->psb_surface->in_loop_buf) {
2309 psb_surface_p psb_surface = obj_surface->psb_surface;
2310
2311 psb_buffer_destroy(psb_surface->in_loop_buf);
2312 free(psb_surface->in_loop_buf);
2313 psb_surface->in_loop_buf = NULL;
2314 }
2315 obj_context->is_oold = driver_data->is_oold;
2316
2317 drv_debug_msg(VIDEO_DEBUG_GENERAL, "---BeginPicture 0x%08x for frame %d --\n",
2318 render_target, obj_context->frame_count);
2319 psb__trace_message("------Trace frame %d------\n", obj_context->frame_count);
2320
2321 DEBUG_FUNC_EXIT
2322 return vaStatus;
2323 }
2324
psb_RenderPicture(VADriverContextP ctx,VAContextID context,VABufferID * buffers,int num_buffers)2325 VAStatus psb_RenderPicture(
2326 VADriverContextP ctx,
2327 VAContextID context,
2328 VABufferID *buffers,
2329 int num_buffers
2330 )
2331 {
2332 DEBUG_FUNC_ENTER
2333 INIT_DRIVER_DATA
2334 VAStatus vaStatus = VA_STATUS_SUCCESS;
2335 object_context_p obj_context;
2336 object_buffer_p *buffer_list;
2337 int i;
2338
2339 obj_context = CONTEXT(context);
2340 CHECK_CONTEXT(obj_context);
2341
2342 CHECK_INVALID_PARAM(num_buffers <= 0);
2343 /* Don't crash on NULL pointers */
2344 CHECK_BUFFER(buffers);
2345 /* Must be within BeginPicture / EndPicture */
2346 ASSERT(obj_context->current_render_target != NULL);
2347
2348 if (num_buffers > obj_context->num_buffers) {
2349 free(obj_context->buffer_list);
2350
2351 obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * num_buffers);
2352 if (obj_context->buffer_list == NULL) {
2353 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
2354 obj_context->num_buffers = 0;
2355 }
2356
2357 obj_context->num_buffers = num_buffers;
2358 }
2359 buffer_list = obj_context->buffer_list;
2360
2361 if (VA_STATUS_SUCCESS == vaStatus) {
2362 /* Lookup buffer references */
2363 for (i = 0; i < num_buffers; i++) {
2364 object_buffer_p obj_buffer = BUFFER(buffers[i]);
2365 CHECK_BUFFER(obj_buffer);
2366
2367 buffer_list[i] = obj_buffer;
2368 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Render buffer %08x type %s\n", obj_buffer->base.id,
2369 buffer_type_to_string(obj_buffer->type));
2370 }
2371 }
2372
2373 if (VA_STATUS_SUCCESS == vaStatus) {
2374 vaStatus = obj_context->format_vtable->renderPicture(obj_context, buffer_list, num_buffers);
2375 }
2376
2377 if (buffer_list) {
2378 /* Release buffers */
2379 for (i = 0; i < num_buffers; i++) {
2380 if (buffer_list[i]) {
2381 psb__suspend_buffer(driver_data, buffer_list[i]);
2382 }
2383 }
2384 }
2385
2386 DEBUG_FUNC_EXIT
2387 return vaStatus;
2388 }
2389
psb_EndPicture(VADriverContextP ctx,VAContextID context)2390 VAStatus psb_EndPicture(
2391 VADriverContextP ctx,
2392 VAContextID context
2393 )
2394 {
2395 DEBUG_FUNC_ENTER
2396 INIT_DRIVER_DATA
2397 VAStatus vaStatus;
2398 object_context_p obj_context;
2399
2400 obj_context = CONTEXT(context);
2401 CHECK_CONTEXT(obj_context);
2402
2403 vaStatus = obj_context->format_vtable->endPicture(obj_context);
2404
2405 drv_debug_msg(VIDEO_DEBUG_GENERAL, "---EndPicture for frame %d --\n", obj_context->frame_count);
2406
2407 obj_context->current_render_target = NULL;
2408 obj_context->frame_count++;
2409
2410 psb__trace_message("FrameCount = %03d\n", obj_context->frame_count);
2411 drv_debug_msg(VIDEO_DEBUG_GENERAL, "FrameCount = %03d\n", obj_context->frame_count);
2412 psb__trace_message(NULL);
2413
2414
2415 //psb_SyncSurface(ctx, obj_context->current_render_surface_id);
2416 DEBUG_FUNC_EXIT
2417 return vaStatus;
2418 }
2419
2420
psb__surface_usage(psb_driver_data_p driver_data,object_surface_p obj_surface,int * decode,int * encode,int * rc_enable,int * proc)2421 static void psb__surface_usage(
2422 psb_driver_data_p driver_data,
2423 object_surface_p obj_surface,
2424 int *decode, int *encode, int *rc_enable, int *proc
2425 )
2426 {
2427 object_context_p obj_context;
2428 object_config_p obj_config;
2429 VAEntrypoint tmp;
2430 unsigned int eRCmode;
2431 int i;
2432
2433
2434 *decode = 0;
2435 *encode = 0;
2436 *rc_enable = 0;
2437 *proc = 0;
2438
2439 obj_context = CONTEXT(obj_surface->context_id);
2440 if (NULL == obj_context) /* not associate with a context */
2441 return;
2442
2443 obj_config = CONFIG(obj_context->config_id);
2444 if (NULL == obj_config) /* not have a validate context */
2445 return;
2446
2447 tmp = obj_config->entrypoint;
2448
2449 *encode = (tmp == VAEntrypointEncSlice) || (tmp == VAEntrypointEncPicture);
2450 *decode = (VAEntrypointVLD <= tmp) && (tmp <= VAEntrypointDeblocking);
2451 #ifdef PSBVIDEO_MRFL_VPP
2452 *proc = (VAEntrypointVideoProc == tmp);
2453 #endif
2454
2455 if (*encode) {
2456 for (i = 0; i < obj_config->attrib_count; i++) {
2457 if (obj_config->attrib_list[i].type == VAConfigAttribRateControl)
2458 break;
2459 }
2460
2461 if (i >= obj_config->attrib_count)
2462 eRCmode = VA_RC_NONE;
2463 else
2464 eRCmode = obj_config->attrib_list[i].value;
2465
2466 if (eRCmode == VA_RC_NONE)
2467 *rc_enable = 0;
2468 else
2469 *rc_enable = 1;
2470 }
2471 }
2472
psb_SyncSurface(VADriverContextP ctx,VASurfaceID render_target)2473 VAStatus psb_SyncSurface(
2474 VADriverContextP ctx,
2475 VASurfaceID render_target
2476 )
2477 {
2478 DEBUG_FUNC_ENTER
2479 INIT_DRIVER_DATA
2480 VAStatus vaStatus = VA_STATUS_SUCCESS;
2481 object_surface_p obj_surface;
2482 int decode = 0, encode = 0, rc_enable = 0, proc = 0;
2483 object_context_p obj_context = NULL;
2484 object_config_p obj_config = NULL;
2485
2486 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_SyncSurface: 0x%08x\n", render_target);
2487
2488 obj_surface = SURFACE(render_target);
2489 CHECK_SURFACE(obj_surface);
2490
2491 obj_context = CONTEXT(obj_surface->context_id);
2492 if (obj_context) {
2493 obj_config = CONFIG(obj_context->config_id);
2494 }
2495
2496 /* The cur_displaying_surface indicates the surface being displayed by overlay.
2497 * The diaplay_timestamp records the time point of put surface, which would
2498 * be set to zero while using texture blit.*/
2499
2500 /* don't use mutex here for performance concern... */
2501 //pthread_mutex_lock(&output->output_mutex);
2502 if (render_target == driver_data->cur_displaying_surface)
2503 vaStatus = VA_STATUS_ERROR_SURFACE_IN_DISPLAYING;
2504 else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface) /* use overlay */
2505 && (render_target == driver_data->last_displaying_surface)) { /* It's the last displaying surface*/
2506 object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface);
2507 /* The flip operation on current displaying surface could be delayed to
2508 * next VBlank and hadn't been finished yet. Then, the last displaying
2509 * surface shouldn't be freed, because the hardware may not
2510 * complete loading data of it. Any change of the last surface could
2511 * have a impect on the scrren.*/
2512 if (NULL != cur_obj_surface) {
2513 while ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)
2514 usleep(PSB_MAX_FLIP_DELAY * 1000);
2515 }
2516 }
2517 //pthread_mutex_unlock(&output->output_mutex);
2518
2519 if (vaStatus != VA_STATUS_ERROR_SURFACE_IN_DISPLAYING) {
2520 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2521 /* For VPP buffer, will sync the rotated buffer */
2522 if (obj_config && obj_config->entrypoint == VAEntrypointVideoProc) {
2523 if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) &&
2524 (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) &&
2525 obj_surface->out_loop_surface)
2526 vaStatus = psb_surface_sync(obj_surface->out_loop_surface);
2527 else
2528 vaStatus = psb_surface_sync(obj_surface->psb_surface);
2529 } else
2530 #endif
2531 vaStatus = psb_surface_sync(obj_surface->psb_surface);
2532 }
2533
2534 /* report any error of decode for Android */
2535 psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc);
2536 #if 0
2537 if (decode && IS_MRST(driver_data)) {
2538 struct drm_lnc_video_getparam_arg arg;
2539 uint32_t ret, handle, fw_status = 0;
2540 handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf));
2541 arg.key = IMG_VIDEO_DECODE_STATUS;
2542 arg.arg = (uint64_t)((unsigned long) & handle);
2543 arg.value = (uint64_t)((unsigned long) & fw_status);
2544 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
2545 &arg, sizeof(arg));
2546 if (ret == 0) {
2547 if (fw_status != 0)
2548 vaStatus = VA_STATUS_ERROR_DECODING_ERROR;
2549 } else {
2550 drv_debug_msg(VIDEO_DEBUG_GENERAL, "IMG_VIDEO_DECODE_STATUS ioctl return failed.\n");
2551 vaStatus = VA_STATUS_ERROR_UNKNOWN;
2552 }
2553 } else if (proc && IS_MRFL(driver_data)) {
2554 /* FIXME: does it need a new surface sync mechanism for FRC? */
2555 }
2556 #endif
2557 if (proc && IS_MRFL(driver_data)) {
2558 /* FIXME: does it need a new surface sync mechanism for FRC? */
2559 }
2560
2561 //psb__dump_NV_buffers(obj_surface->psb_surface, 0, 0, obj_surface->width, obj_surface->height);
2562 //psb__dump_NV_buffers(obj_surface->psb_surface_rotate, 0, 0, obj_surface->height, ((obj_surface->width + 0x1f) & (~0x1f)));
2563 if (obj_surface->scaling_surface)
2564 psb__dump_NV12_buffers(obj_surface->scaling_surface, 0, 0, obj_surface->width_s, obj_surface->height_s);
2565 DEBUG_FAILURE;
2566 DEBUG_FUNC_EXIT
2567 return vaStatus;
2568 }
2569
2570
psb_QuerySurfaceStatus(VADriverContextP ctx,VASurfaceID render_target,VASurfaceStatus * status)2571 VAStatus psb_QuerySurfaceStatus(
2572 VADriverContextP ctx,
2573 VASurfaceID render_target,
2574 VASurfaceStatus *status /* out */
2575 )
2576 {
2577 DEBUG_FUNC_ENTER
2578 INIT_DRIVER_DATA
2579 VAStatus vaStatus = VA_STATUS_SUCCESS;
2580 object_surface_p obj_surface;
2581 VASurfaceStatus surface_status;
2582 int frame_skip = 0, encode = 0, decode = 0, rc_enable = 0, proc = 0;
2583 object_context_p obj_context = NULL;
2584
2585 obj_surface = SURFACE(render_target);
2586 CHECK_SURFACE(obj_surface);
2587
2588 CHECK_INVALID_PARAM(status == NULL);
2589
2590 psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable, &proc);
2591 #ifdef PSBVIDEO_MRFL_VPP_ROTATE
2592 /* For VPP 1080P, will query the rotated buffer */
2593 if (proc) {
2594 obj_context = CONTEXT(obj_surface->context_id);
2595 CHECK_CONTEXT(obj_context);
2596 if (GET_SURFACE_INFO_tiling(obj_surface->psb_surface) &&
2597 (obj_context->msvdx_rotate == VA_ROTATION_90 || obj_context->msvdx_rotate == VA_ROTATION_270) &&
2598 obj_surface->out_loop_surface)
2599 vaStatus = psb_surface_query_status(obj_surface->out_loop_surface, &surface_status);
2600 else
2601 vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status);
2602 } else
2603 #endif
2604 vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status);
2605
2606 /* The cur_displaying_surface indicates the surface being displayed by overlay.
2607 * The diaplay_timestamp records the time point of put surface, which would
2608 * be set to zero while using texture blit.*/
2609 pthread_mutex_lock(&driver_data->output_mutex);
2610 if (render_target == driver_data->cur_displaying_surface)
2611 surface_status = VASurfaceDisplaying;
2612 else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface) /* use overlay */
2613 && (render_target == driver_data->last_displaying_surface)) { /* It's the last displaying surface*/
2614 object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface);
2615 /*The flip operation on current displaying surface could be delayed to
2616 * next VBlank and hadn't been finished yet. Then, the last displaying
2617 * surface shouldn't be freed, because the hardware may not
2618 * complete loading data of it. Any change of the last surface could
2619 * have a impect on the scrren.*/
2620 if ((NULL != cur_obj_surface)
2621 && ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)) {
2622 surface_status = VASurfaceDisplaying;
2623 }
2624 }
2625 pthread_mutex_unlock(&driver_data->output_mutex);
2626
2627 /* try to get frameskip flag for encode */
2628 #ifndef BAYTRAIL
2629 if (!decode) {
2630 /* The rendering surface may not be associated with any context. So driver should
2631 check the frame skip flag even variable encode is 0 */
2632 #ifdef PSBVIDEO_MRFL
2633 if (IS_MRFL(driver_data))
2634 tng_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip);
2635 else
2636 #endif
2637 pnw_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip);
2638
2639 if (frame_skip == 1) {
2640 surface_status = surface_status | VASurfaceSkipped;
2641 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s next frame of 0x%08x is skipped",
2642 __FUNCTION__, render_target);
2643 }
2644 } else
2645 #endif
2646 if (decode) {
2647 #ifdef ANDROID
2648 if (obj_surface->psb_surface->buf.handle) {
2649 buffer_handle_t handle = obj_surface->psb_surface->buf.handle;
2650 int display_status;
2651 int err;
2652 err = gralloc_getdisplaystatus(handle, &display_status);
2653 if (!err) {
2654 if (display_status)
2655 surface_status = VASurfaceDisplaying;
2656 else
2657 surface_status = VASurfaceReady;
2658 } else {
2659 surface_status = VASurfaceReady;
2660 }
2661
2662 /* if not used by display, then check whether surface used by widi */
2663 if (surface_status == VASurfaceReady && obj_surface->share_info) {
2664 if (obj_surface->share_info->renderStatus == 1) {
2665 surface_status = VASurfaceDisplaying;
2666 }
2667 }
2668 }
2669 #endif
2670 } else if (proc) {
2671 /* FIXME: does it need a new surface sync mechanism for FRC? */
2672 }
2673
2674 *status = surface_status;
2675 DEBUG_FUNC_EXIT
2676 return vaStatus;
2677 }
2678
psb_QuerySurfaceError(VADriverContextP ctx,VASurfaceID render_target,VAStatus error_status,void ** error_info)2679 VAStatus psb_QuerySurfaceError(
2680 VADriverContextP ctx,
2681 VASurfaceID render_target,
2682 VAStatus error_status,
2683 void **error_info /*out*/
2684 )
2685 {
2686 DEBUG_FUNC_ENTER
2687 INIT_DRIVER_DATA
2688 VAStatus vaStatus = VA_STATUS_SUCCESS;
2689 object_surface_p obj_surface;
2690 uint32_t i;
2691
2692 obj_surface = SURFACE(render_target);
2693 CHECK_SURFACE(obj_surface);
2694
2695 #ifdef PSBVIDEO_MSVDX_EC
2696 if (driver_data->ec_enabled == 0) {
2697 #else
2698 {
2699 #endif
2700 drv_debug_msg(VIDEO_DEBUG_GENERAL, "error concealment is not supported for this profile.\n");
2701 error_info = NULL;
2702 return VA_STATUS_ERROR_UNKNOWN;
2703 }
2704
2705 if (error_status == VA_STATUS_ERROR_DECODING_ERROR) {
2706 drm_psb_msvdx_decode_status_t *decode_status = driver_data->msvdx_decode_status;
2707 struct drm_lnc_video_getparam_arg arg;
2708 uint32_t ret, handle;
2709 handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf));
2710
2711 arg.key = IMG_VIDEO_MB_ERROR;
2712 arg.arg = (uint64_t)((unsigned long) & handle);
2713 arg.value = (uint64_t)((unsigned long)decode_status);
2714 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
2715 &arg, sizeof(arg));
2716 if (ret != 0) {
2717 drv_debug_msg(VIDEO_DEBUG_GENERAL,"return value is %d drmCommandWriteRead\n",ret);
2718 return VA_STATUS_ERROR_UNKNOWN;
2719 }
2720 #ifndef _FOR_FPGA_
2721 if (decode_status->num_region > MAX_MB_ERRORS) {
2722 drv_debug_msg(VIDEO_DEBUG_GENERAL, "too much mb errors are reported.\n");
2723 return VA_STATUS_ERROR_UNKNOWN;
2724 }
2725 i = 0;
2726 for (i = 0; i < decode_status->num_region; ++i) {
2727 driver_data->surface_mb_error[i].status = 1;
2728 driver_data->surface_mb_error[i].start_mb = decode_status->mb_regions[i].start;
2729 driver_data->surface_mb_error[i].end_mb = decode_status->mb_regions[i].end;
2730 //driver_data->surface_mb_error[i].start_mb = decode_status->start_error_mb_list[i];
2731 //driver_data->surface_mb_error[i].end_mb = decode_status->end_error_mb_list[i];
2732 //driver_data->surface_mb_error[i].decode_error_type = decode_status->slice_missing_or_error[i];
2733 }
2734 #endif
2735 driver_data->surface_mb_error[i].status = -1;
2736 *error_info = driver_data->surface_mb_error;
2737 } else {
2738 error_info = NULL;
2739 return VA_STATUS_ERROR_UNKNOWN;
2740 }
2741 DEBUG_FUNC_EXIT
2742 return vaStatus;
2743 }
2744
2745 #define PSB_MAX_SURFACE_ATTRIBUTES 16
2746
2747 VAStatus psb_QuerySurfaceAttributes(VADriverContextP ctx,
2748 VAConfigID config,
2749 VASurfaceAttrib *attrib_list,
2750 unsigned int *num_attribs)
2751 {
2752 DEBUG_FUNC_ENTER
2753 INIT_DRIVER_DATA
2754
2755 VAStatus vaStatus = VA_STATUS_SUCCESS;
2756 object_config_p obj_config;
2757 unsigned int i = 0;
2758
2759 CHECK_INVALID_PARAM(num_attribs == NULL);
2760
2761 if (attrib_list == NULL) {
2762 *num_attribs = PSB_MAX_SURFACE_ATTRIBUTES;
2763 return VA_STATUS_SUCCESS;
2764 }
2765
2766 obj_config = CONFIG(config);
2767 CHECK_CONFIG(obj_config);
2768
2769 VASurfaceAttrib *attribs = NULL;
2770 attribs = malloc(PSB_MAX_SURFACE_ATTRIBUTES *sizeof(VASurfaceAttrib));
2771 if (attribs == NULL)
2772 return VA_STATUS_ERROR_ALLOCATION_FAILED;
2773
2774 attribs[i].type = VASurfaceAttribPixelFormat;
2775 attribs[i].value.type = VAGenericValueTypeInteger;
2776 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
2777 attribs[i].value.value.i = VA_FOURCC('N', 'V', '1', '2');
2778 i++;
2779
2780 attribs[i].type = VASurfaceAttribMemoryType;
2781 attribs[i].value.type = VAGenericValueTypeInteger;
2782 attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
2783 if (obj_config->entrypoint == VAEntrypointEncSlice && obj_config->profile == VAProfileVP8Version0_3) {
2784 attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
2785 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
2786 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
2787 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
2788 } else {
2789 attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
2790 VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM |
2791 VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR |
2792 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC |
2793 VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_ION;
2794 }
2795 i++;
2796
2797 attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
2798 attribs[i].value.type = VAGenericValueTypePointer;
2799 attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
2800 attribs[i].value.value.p = NULL;
2801 i++;
2802
2803 //modules have speical formats to support
2804 if (obj_config->entrypoint == VAEntrypointVLD) { /* decode */
2805
2806 } else if (obj_config->entrypoint == VAEntrypointEncSlice || /* encode */
2807 obj_config->entrypoint == VAEntrypointEncPicture) {
2808 #ifdef PSBVIDEO_MFLD
2809 if (IS_MFLD(driver_data)) {}
2810 #endif
2811 #ifdef PSBVIDEO_MRFL
2812 if (IS_MRFL(driver_data)) {}
2813 #endif
2814 #ifdef BAYTRAIL
2815 if (IS_BAYTRAIL(driver_data)) {}
2816 #endif
2817 }
2818 else if (obj_config->entrypoint == VAEntrypointVideoProc) { /* vpp */
2819
2820 }
2821
2822 if (i > *num_attribs) {
2823 *num_attribs = i;
2824 if (attribs != NULL)
2825 free(attribs);
2826 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
2827 }
2828
2829 *num_attribs = i;
2830 memcpy(attrib_list, attribs, i * sizeof(*attribs));
2831 free(attribs);
2832
2833 DEBUG_FUNC_EXIT
2834 return vaStatus;
2835 }
2836
2837 VAStatus psb_LockSurface(
2838 VADriverContextP ctx,
2839 VASurfaceID surface,
2840 unsigned int *fourcc, /* following are output argument */
2841 unsigned int *luma_stride,
2842 unsigned int *chroma_u_stride,
2843 unsigned int *chroma_v_stride,
2844 unsigned int *luma_offset,
2845 unsigned int *chroma_u_offset,
2846 unsigned int *chroma_v_offset,
2847 unsigned int *buffer_name,
2848 void **buffer
2849 )
2850 {
2851 DEBUG_FUNC_ENTER
2852 INIT_DRIVER_DATA
2853 VAStatus vaStatus = VA_STATUS_SUCCESS;
2854 unsigned char *surface_data;
2855 int ret;
2856
2857 object_surface_p obj_surface = SURFACE(surface);
2858 psb_surface_p psb_surface;
2859 CHECK_SURFACE(obj_surface);
2860
2861 psb_surface = obj_surface->psb_surface;
2862 if (buffer_name)
2863 *buffer_name = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf)));
2864
2865 if (buffer) { /* map the surface buffer */
2866 uint32_t srf_buf_ofs = 0;
2867 ret = psb_buffer_map(&psb_surface->buf, &surface_data);
2868 if (ret) {
2869 *buffer = NULL;
2870 vaStatus = VA_STATUS_ERROR_UNKNOWN;
2871 DEBUG_FAILURE;
2872 return vaStatus;
2873 }
2874 srf_buf_ofs = psb_surface->buf.buffer_ofs;
2875 *buffer = surface_data + srf_buf_ofs;
2876 }
2877
2878 *fourcc = VA_FOURCC_NV12;
2879 *luma_stride = psb_surface->stride;
2880 *chroma_u_stride = psb_surface->stride;
2881 *chroma_v_stride = psb_surface->stride;
2882 *luma_offset = 0;
2883 *chroma_u_offset = obj_surface->height * psb_surface->stride;
2884 *chroma_v_offset = obj_surface->height * psb_surface->stride + 1;
2885 DEBUG_FUNC_EXIT
2886 return vaStatus;
2887 }
2888
2889
2890 VAStatus psb_UnlockSurface(
2891 VADriverContextP ctx,
2892 VASurfaceID surface
2893 )
2894 {
2895 DEBUG_FUNC_ENTER
2896 INIT_DRIVER_DATA
2897 VAStatus vaStatus = VA_STATUS_SUCCESS;
2898
2899 object_surface_p obj_surface = SURFACE(surface);
2900 CHECK_SURFACE(obj_surface);
2901
2902 psb_surface_p psb_surface = obj_surface->psb_surface;
2903
2904 psb_buffer_unmap(&psb_surface->buf);
2905
2906 DEBUG_FUNC_EXIT
2907 return VA_STATUS_SUCCESS;
2908 }
2909
2910 VAStatus psb_GetEGLClientBufferFromSurface(
2911 VADriverContextP ctx,
2912 VASurfaceID surface,
2913 void **buffer
2914 )
2915 {
2916 DEBUG_FUNC_ENTER
2917 INIT_DRIVER_DATA
2918 VAStatus vaStatus = VA_STATUS_SUCCESS;
2919
2920 object_surface_p obj_surface = SURFACE(surface);
2921 CHECK_SURFACE(obj_surface);
2922
2923 psb_surface_p psb_surface = obj_surface->psb_surface;
2924 *buffer = (unsigned char *)psb_surface->bc_buffer;
2925
2926 DEBUG_FUNC_EXIT
2927 return vaStatus;
2928 }
2929
2930 VAStatus psb_PutSurfaceBuf(
2931 VADriverContextP ctx,
2932 VASurfaceID surface,
2933 unsigned char __maybe_unused * data,
2934 int __maybe_unused * data_len,
2935 short __maybe_unused srcx,
2936 short __maybe_unused srcy,
2937 unsigned short __maybe_unused srcw,
2938 unsigned short __maybe_unused srch,
2939 short __maybe_unused destx,
2940 short __maybe_unused desty,
2941 unsigned short __maybe_unused destw,
2942 unsigned short __maybe_unused desth,
2943 VARectangle __maybe_unused * cliprects, /* client supplied clip list */
2944 unsigned int __maybe_unused number_cliprects, /* number of clip rects in the clip list */
2945 unsigned int __maybe_unused flags /* de-interlacing flags */
2946 )
2947 {
2948 DEBUG_FUNC_ENTER
2949 INIT_DRIVER_DATA;
2950 object_surface_p obj_surface = SURFACE(surface);
2951 psb_surface_p psb_surface;
2952
2953 obj_surface = SURFACE(surface);
2954 if (obj_surface == NULL)
2955 return VA_STATUS_ERROR_INVALID_SURFACE;
2956
2957 psb_surface = obj_surface->psb_surface;
2958
2959 #if 0
2960 psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1, /* check subpicture */
2961 obj_surface->width, obj_surface->height,
2962 psb_surface->stride, psb_surface->buf.drm_buf,
2963 psb_surface->buf.pl_flags, 1 /* wrap dst */);
2964 #endif
2965
2966 DEBUG_FUNC_EXIT
2967 return VA_STATUS_SUCCESS;
2968 }
2969
2970 VAStatus psb_SetTimestampForSurface(
2971 VADriverContextP ctx,
2972 VASurfaceID surface,
2973 long long timestamp
2974 )
2975 {
2976 INIT_DRIVER_DATA;
2977 VAStatus vaStatus = VA_STATUS_SUCCESS;
2978 object_surface_p obj_surface = SURFACE(surface);
2979
2980 obj_surface = SURFACE(surface);
2981 CHECK_SURFACE(obj_surface);
2982
2983 if (obj_surface->share_info) {
2984 obj_surface->share_info->timestamp = timestamp;
2985 return VA_STATUS_SUCCESS;
2986 } else {
2987 return VA_STATUS_ERROR_UNKNOWN;
2988 }
2989 }
2990
2991 int LOCK_HARDWARE(psb_driver_data_p driver_data)
2992 {
2993 char ret = 0;
2994
2995 if (driver_data->dri2 || driver_data->dri_dummy)
2996 return 0;
2997
2998 pthread_mutex_lock(&driver_data->drm_mutex);
2999 DRM_CAS(driver_data->drm_lock, driver_data->drm_context,
3000 (DRM_LOCK_HELD | driver_data->drm_context), ret);
3001 if (ret) {
3002 ret = drmGetLock(driver_data->drm_fd, driver_data->drm_context, 0);
3003 /* driver_data->contended_lock=1; */
3004 }
3005
3006 return ret;
3007 }
3008
3009 int UNLOCK_HARDWARE(psb_driver_data_p driver_data)
3010 {
3011 /* driver_data->contended_lock=0; */
3012 if (driver_data->dri2 || driver_data->dri_dummy)
3013 return 0;
3014
3015 DRM_UNLOCK(driver_data->drm_fd, driver_data->drm_lock, driver_data->drm_context);
3016 pthread_mutex_unlock(&driver_data->drm_mutex);
3017
3018 return 0;
3019 }
3020
3021
3022 static void psb__deinitDRM(VADriverContextP ctx)
3023 {
3024 INIT_DRIVER_DATA
3025
3026 if (driver_data->main_pool) {
3027 driver_data->main_pool->takeDown(driver_data->main_pool);
3028 driver_data->main_pool = NULL;
3029 }
3030 if (driver_data->fence_mgr) {
3031 wsbmFenceMgrTTMTakedown(driver_data->fence_mgr);
3032 driver_data->fence_mgr = NULL;
3033 }
3034
3035 if (wsbmIsInitialized())
3036 wsbmTakedown();
3037
3038 driver_data->drm_fd = -1;
3039 }
3040
3041
3042 static VAStatus psb__initDRI(VADriverContextP ctx)
3043 {
3044 INIT_DRIVER_DATA
3045 struct drm_state *drm_state = (struct drm_state *)ctx->drm_state;
3046
3047 assert(dri_state);
3048 #ifdef _FOR_FPGA_
3049 dri_state->driConnectedFlag = VA_DUMMY;
3050 /* ON FPGA machine, psb may co-exist with gfx's drm driver */
3051 dri_state->fd = open("/dev/dri/card1", O_RDWR);
3052 if (dri_state->fd < 0)
3053 dri_state->fd = open("/dev/dri/card0", O_RDWR);
3054 assert(dri_state->fd >= 0);
3055 #endif
3056 assert(dri_state->driConnectedFlag == VA_DRI2 ||
3057 dri_state->driConnectedFlag == VA_DUMMY);
3058
3059 driver_data->drm_fd = drm_state->fd;
3060 driver_data->dri_dummy = 1;
3061 driver_data->dri2 = 0;
3062 driver_data->ws_priv = NULL;
3063 driver_data->bus_id = NULL;
3064
3065 return VA_STATUS_SUCCESS;
3066 }
3067
3068
3069 static VAStatus psb__initTTM(VADriverContextP ctx)
3070 {
3071 INIT_DRIVER_DATA
3072
3073 const char drm_ext[] = "psb_ttm_placement_alphadrop";
3074 union drm_psb_extension_arg arg;
3075 struct _WsbmBufferPool *pool;
3076 int ret;
3077 const char exec_ext[] = "psb_ttm_execbuf_alphadrop";
3078 union drm_psb_extension_arg exec_arg;
3079 const char lncvideo_getparam_ext[] = "lnc_video_getparam";
3080 union drm_psb_extension_arg lncvideo_getparam_arg;
3081
3082 /* init wsbm
3083 * WSBM node is not used in driver, thus can pass NULL Node callback
3084 */
3085 ret = wsbmInit(wsbmNullThreadFuncs(), NULL/*psbVNodeFuncs()*/);
3086 if (ret) {
3087 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed initializing libwsbm.\n");
3088 return VA_STATUS_ERROR_UNKNOWN;
3089 }
3090
3091 strncpy(arg.extension, drm_ext, sizeof(arg.extension));
3092 /* FIXME: should check dri enabled?
3093 * it seems not init dri here at all
3094 */
3095 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION,
3096 &arg, sizeof(arg));
3097 if (ret != 0 || !arg.rep.exists) {
3098 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\", fd=%d\n",
3099 drm_ext, driver_data->drm_fd);
3100 drv_debug_msg(VIDEO_DEBUG_ERROR, "found error %s (ret=%d), arg.rep.exists=%d",
3101 strerror(errno), ret, arg.rep.exists);
3102
3103 driver_data->main_pool = NULL;
3104 return VA_STATUS_ERROR_UNKNOWN;
3105 } else {
3106 pool = wsbmTTMPoolInit(driver_data->drm_fd,
3107 arg.rep.driver_ioctl_offset);
3108 if (pool == NULL) {
3109 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get ttm pool\n");
3110 return VA_STATUS_ERROR_UNKNOWN;
3111 }
3112 driver_data->main_pool = pool;
3113 }
3114
3115 strncpy(exec_arg.extension, exec_ext, sizeof(exec_arg.extension));
3116 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &exec_arg,
3117 sizeof(exec_arg));
3118 if (ret != 0 || !exec_arg.rep.exists) {
3119 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n",
3120 exec_ext);
3121 return FALSE;
3122 }
3123 driver_data->execIoctlOffset = exec_arg.rep.driver_ioctl_offset;
3124
3125 strncpy(lncvideo_getparam_arg.extension, lncvideo_getparam_ext, sizeof(lncvideo_getparam_arg.extension));
3126 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &lncvideo_getparam_arg,
3127 sizeof(lncvideo_getparam_arg));
3128 if (ret != 0 || !lncvideo_getparam_arg.rep.exists) {
3129 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to detect DRM extension \"%s\".\n",
3130 lncvideo_getparam_ext);
3131 /* return FALSE; */ /* not reture FALSE, so it still can run */
3132 }
3133 driver_data->getParamIoctlOffset = lncvideo_getparam_arg.rep.driver_ioctl_offset;
3134 return VA_STATUS_SUCCESS;
3135 }
3136
3137 static VAStatus psb__initDRM(VADriverContextP ctx)
3138 {
3139 VAStatus vaStatus;
3140
3141 vaStatus = psb__initDRI(ctx);
3142
3143 if (vaStatus == VA_STATUS_SUCCESS)
3144 return psb__initTTM(ctx);
3145 else
3146 return vaStatus;
3147 }
3148
3149 VAStatus psb_Terminate(VADriverContextP ctx)
3150 {
3151 DEBUG_FUNC_ENTER
3152 INIT_DRIVER_DATA
3153 object_subpic_p obj_subpic;
3154 object_image_p obj_image;
3155 object_buffer_p obj_buffer;
3156 object_surface_p obj_surface;
3157 object_context_p obj_context;
3158 object_config_p obj_config;
3159 object_heap_iterator iter;
3160
3161 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: begin to tear down\n");
3162
3163 /* Clean up left over contexts */
3164 obj_context = (object_context_p) object_heap_first(&driver_data->context_heap, &iter);
3165 while (obj_context) {
3166 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: contextID %08x still allocated, destroying\n", obj_context->base.id);
3167 psb__destroy_context(driver_data, obj_context);
3168 obj_context = (object_context_p) object_heap_next(&driver_data->context_heap, &iter);
3169 }
3170 object_heap_destroy(&driver_data->context_heap);
3171
3172 /* Clean up SubpicIDs */
3173 obj_subpic = (object_subpic_p) object_heap_first(&driver_data->subpic_heap, &iter);
3174 while (obj_subpic) {
3175 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: subpictureID %08x still allocated, destroying\n", obj_subpic->base.id);
3176 psb__destroy_subpicture(driver_data, obj_subpic);
3177 obj_subpic = (object_subpic_p) object_heap_next(&driver_data->subpic_heap, &iter);
3178 }
3179 object_heap_destroy(&driver_data->subpic_heap);
3180
3181 /* Clean up ImageIDs */
3182 obj_image = (object_image_p) object_heap_first(&driver_data->image_heap, &iter);
3183 while (obj_image) {
3184 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: imageID %08x still allocated, destroying\n", obj_image->base.id);
3185 psb__destroy_image(driver_data, obj_image);
3186 obj_image = (object_image_p) object_heap_next(&driver_data->image_heap, &iter);
3187 }
3188 object_heap_destroy(&driver_data->image_heap);
3189
3190 /* Clean up left over buffers */
3191 obj_buffer = (object_buffer_p) object_heap_first(&driver_data->buffer_heap, &iter);
3192 while (obj_buffer) {
3193 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: bufferID %08x still allocated, destroying\n", obj_buffer->base.id);
3194 psb__destroy_buffer(driver_data, obj_buffer);
3195 obj_buffer = (object_buffer_p) object_heap_next(&driver_data->buffer_heap, &iter);
3196 }
3197 object_heap_destroy(&driver_data->buffer_heap);
3198
3199 /* Clean up left over surfaces */
3200
3201 #if 0
3202 /* Free PVR2D buffer wrapped from the surfaces */
3203 psb_free_surface_pvr2dbuf(driver_data);
3204 #endif
3205 obj_surface = (object_surface_p) object_heap_first(&driver_data->surface_heap, &iter);
3206 while (obj_surface) {
3207 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: surfaceID %08x still allocated, destroying\n", obj_surface->base.id);
3208 psb__destroy_surface(driver_data, obj_surface);
3209 obj_surface = (object_surface_p) object_heap_next(&driver_data->surface_heap, &iter);
3210 }
3211 object_heap_destroy(&driver_data->surface_heap);
3212
3213 /* Clean up configIDs */
3214 obj_config = (object_config_p) object_heap_first(&driver_data->config_heap, &iter);
3215 while (obj_config) {
3216 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config);
3217 obj_config = (object_config_p) object_heap_next(&driver_data->config_heap, &iter);
3218 }
3219 object_heap_destroy(&driver_data->config_heap);
3220
3221 if (driver_data->camera_bo) {
3222 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup camera global BO\n");
3223
3224 psb_buffer_destroy((psb_buffer_p)driver_data->camera_bo);
3225 free(driver_data->camera_bo);
3226 driver_data->camera_bo = NULL;
3227 }
3228
3229 if (driver_data->rar_bo) {
3230 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: clearup RAR global BO\n");
3231
3232 psb_buffer_destroy((psb_buffer_p)driver_data->rar_bo);
3233 free(driver_data->rar_bo);
3234 driver_data->rar_bo = NULL;
3235 }
3236
3237 if (driver_data->ws_priv) {
3238 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: tear down output portion\n");
3239
3240 psb_deinitOutput(ctx);
3241 driver_data->ws_priv = NULL;
3242 }
3243
3244 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: de-initialized DRM\n");
3245
3246 psb__deinitDRM(ctx);
3247
3248 if (driver_data->msvdx_decode_status)
3249 free(driver_data->msvdx_decode_status);
3250
3251 if (driver_data->surface_mb_error)
3252 free(driver_data->surface_mb_error);
3253
3254 pthread_mutex_destroy(&driver_data->drm_mutex);
3255 free(ctx->pDriverData);
3256 free(ctx->vtable_egl);
3257 free(ctx->vtable_tpi);
3258
3259 ctx->pDriverData = NULL;
3260 drv_debug_msg(VIDEO_DEBUG_INIT, "vaTerminate: goodbye\n\n");
3261
3262 psb__close_log();
3263 DEBUG_FUNC_EXIT
3264 return VA_STATUS_SUCCESS;
3265 }
3266
3267 EXPORT VAStatus __vaDriverInit_0_31(VADriverContextP ctx)
3268 {
3269 psb_driver_data_p driver_data;
3270 struct VADriverVTableTPI *tpi;
3271 struct VADriverVTableEGL *va_egl;
3272 int result;
3273 if (psb_video_trace_fp) {
3274 /* make gdb always stop here */
3275 signal(SIGUSR1, SIG_IGN);
3276 kill(getpid(), SIGUSR1);
3277 }
3278
3279 psb__open_log();
3280
3281 drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: start the journey\n");
3282
3283 ctx->version_major = 0;
3284 ctx->version_minor = 31;
3285
3286 ctx->max_profiles = PSB_MAX_PROFILES;
3287 ctx->max_entrypoints = PSB_MAX_ENTRYPOINTS;
3288 ctx->max_attributes = PSB_MAX_CONFIG_ATTRIBUTES;
3289 ctx->max_image_formats = PSB_MAX_IMAGE_FORMATS;
3290 ctx->max_subpic_formats = PSB_MAX_SUBPIC_FORMATS;
3291 ctx->max_display_attributes = PSB_MAX_DISPLAY_ATTRIBUTES;
3292
3293 ctx->vtable->vaTerminate = psb_Terminate;
3294 ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints;
3295 ctx->vtable->vaTerminate = psb_Terminate;
3296 ctx->vtable->vaQueryConfigProfiles = psb_QueryConfigProfiles;
3297 ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints;
3298 ctx->vtable->vaQueryConfigAttributes = psb_QueryConfigAttributes;
3299 ctx->vtable->vaCreateConfig = psb_CreateConfig;
3300 ctx->vtable->vaDestroyConfig = psb_DestroyConfig;
3301 ctx->vtable->vaGetConfigAttributes = psb_GetConfigAttributes;
3302 ctx->vtable->vaCreateSurfaces2 = psb_CreateSurfaces2;
3303 ctx->vtable->vaCreateSurfaces = psb_CreateSurfaces;
3304 ctx->vtable->vaGetSurfaceAttributes = psb_GetSurfaceAttributes;
3305 ctx->vtable->vaDestroySurfaces = psb_DestroySurfaces;
3306 ctx->vtable->vaCreateContext = psb_CreateContext;
3307 ctx->vtable->vaDestroyContext = psb_DestroyContext;
3308 ctx->vtable->vaCreateBuffer = psb_CreateBuffer;
3309 ctx->vtable->vaBufferSetNumElements = psb_BufferSetNumElements;
3310 ctx->vtable->vaMapBuffer = psb_MapBuffer;
3311 ctx->vtable->vaUnmapBuffer = psb_UnmapBuffer;
3312 ctx->vtable->vaDestroyBuffer = psb_DestroyBuffer;
3313 ctx->vtable->vaBeginPicture = psb_BeginPicture;
3314 ctx->vtable->vaRenderPicture = psb_RenderPicture;
3315 ctx->vtable->vaEndPicture = psb_EndPicture;
3316 ctx->vtable->vaSyncSurface = psb_SyncSurface;
3317 ctx->vtable->vaQuerySurfaceStatus = psb_QuerySurfaceStatus;
3318 ctx->vtable->vaQuerySurfaceError = psb_QuerySurfaceError;
3319 ctx->vtable->vaPutSurface = psb_PutSurface;
3320 ctx->vtable->vaQueryImageFormats = psb_QueryImageFormats;
3321 ctx->vtable->vaCreateImage = psb_CreateImage;
3322 ctx->vtable->vaDeriveImage = psb_DeriveImage;
3323 ctx->vtable->vaDestroyImage = psb_DestroyImage;
3324 ctx->vtable->vaSetImagePalette = psb_SetImagePalette;
3325 ctx->vtable->vaGetImage = psb_GetImage;
3326 ctx->vtable->vaPutImage = psb_PutImage;
3327 ctx->vtable->vaQuerySubpictureFormats = psb_QuerySubpictureFormats;
3328 ctx->vtable->vaCreateSubpicture = psb_CreateSubpicture;
3329 ctx->vtable->vaDestroySubpicture = psb_DestroySubpicture;
3330 ctx->vtable->vaSetSubpictureImage = psb_SetSubpictureImage;
3331 ctx->vtable->vaSetSubpictureChromakey = psb_SetSubpictureChromakey;
3332 ctx->vtable->vaSetSubpictureGlobalAlpha = psb_SetSubpictureGlobalAlpha;
3333 ctx->vtable->vaAssociateSubpicture = psb_AssociateSubpicture;
3334 ctx->vtable->vaDeassociateSubpicture = psb_DeassociateSubpicture;
3335 ctx->vtable->vaQueryDisplayAttributes = psb_QueryDisplayAttributes;
3336 ctx->vtable->vaGetDisplayAttributes = psb_GetDisplayAttributes;
3337 ctx->vtable->vaSetDisplayAttributes = psb_SetDisplayAttributes;
3338 ctx->vtable->vaQuerySurfaceAttributes = psb_QuerySurfaceAttributes;
3339 ctx->vtable->vaBufferInfo = psb_BufferInfo;
3340 ctx->vtable->vaLockSurface = psb_LockSurface;
3341 ctx->vtable->vaUnlockSurface = psb_UnlockSurface;
3342 #ifdef PSBVIDEO_MRFL_VPP
3343 ctx->vtable_vpp->vaQueryVideoProcFilters = vsp_QueryVideoProcFilters;
3344 ctx->vtable_vpp->vaQueryVideoProcFilterCaps = vsp_QueryVideoProcFilterCaps;
3345 ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = vsp_QueryVideoProcPipelineCaps;
3346 #endif
3347
3348 #ifdef PSBVIDEO_MFLD
3349 ctx->vtable_vpp->vaQueryVideoProcFilters = ved_QueryVideoProcFilters;
3350 ctx->vtable_vpp->vaQueryVideoProcFilterCaps = ved_QueryVideoProcFilterCaps;
3351 ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = ved_QueryVideoProcPipelineCaps;
3352 #endif
3353
3354 ctx->vtable_tpi = calloc(1, sizeof(struct VADriverVTableTPI));
3355 if (NULL == ctx->vtable_tpi)
3356 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3357
3358 tpi = (struct VADriverVTableTPI *)ctx->vtable_tpi;
3359 tpi->vaCreateSurfacesWithAttribute = psb_CreateSurfacesWithAttribute;
3360 tpi->vaPutSurfaceBuf = psb_PutSurfaceBuf;
3361 tpi->vaSetTimestampForSurface = psb_SetTimestampForSurface;
3362
3363 ctx->vtable_egl = calloc(1, sizeof(struct VADriverVTableEGL));
3364 if (NULL == ctx->vtable_egl)
3365 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3366
3367 va_egl = (struct VADriverVTableEGL *)ctx->vtable_egl;
3368 va_egl->vaGetEGLClientBufferFromSurface = psb_GetEGLClientBufferFromSurface;
3369
3370 driver_data = (psb_driver_data_p) calloc(1, sizeof(*driver_data));
3371 ctx->pDriverData = (unsigned char *) driver_data;
3372 if (NULL == driver_data) {
3373 if (ctx->vtable_tpi)
3374 free(ctx->vtable_tpi);
3375 if (ctx->vtable_egl)
3376 free(ctx->vtable_egl);
3377 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3378 }
3379
3380 if (VA_STATUS_SUCCESS != psb__initDRM(ctx)) {
3381 free(ctx->pDriverData);
3382 ctx->pDriverData = NULL;
3383 return VA_STATUS_ERROR_UNKNOWN;
3384 }
3385
3386 pthread_mutex_init(&driver_data->drm_mutex, NULL);
3387
3388 /*
3389 * To read PBO.MSR.CCF Mode and Status Register C-Spec -p112
3390 */
3391 #define PCI_PORT5_REG80_VIDEO_SD_DISABLE 0x0008
3392 #define PCI_PORT5_REG80_VIDEO_HD_DISABLE 0x0010
3393
3394 #if 0
3395 struct drm_psb_hw_info hw_info;
3396 do {
3397 result = drmCommandRead(driver_data->drm_fd, DRM_PSB_HW_INFO, &hw_info, sizeof(hw_info));
3398 } while (result == EAGAIN);
3399
3400 if (result != 0) {
3401 psb__deinitDRM(ctx);
3402 free(ctx->pDriverData);
3403 ctx->pDriverData = NULL;
3404 return VA_STATUS_ERROR_UNKNOWN;
3405 }
3406
3407 driver_data->video_sd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_SD_DISABLE);
3408 driver_data->video_hd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_HD_DISABLE);
3409 drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: rev_id = %08x capabilities = %08x\n", hw_info.rev_id, hw_info.caps);
3410 drv_debug_msg(VIDEO_DEBUG_GENERAL, "hw_info: video_sd_disable=%d,video_hd_disable=%d\n",
3411 driver_data->video_sd_disabled, driver_data->video_hd_disabled);
3412 if (driver_data->video_sd_disabled != 0) {
3413 drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_sd_disable is true,fix it manually\n");
3414 driver_data->video_sd_disabled = 0;
3415 }
3416 if (driver_data->video_hd_disabled != 0) {
3417 drv_debug_msg(VIDEO_DEBUG_ERROR, "MRST: hw_info shows video_hd_disable is true,fix it manually\n");
3418 driver_data->video_hd_disabled = 0;
3419 }
3420 #endif
3421
3422 if (0 != psb_get_device_info(ctx)) {
3423 drv_debug_msg(VIDEO_DEBUG_ERROR, "ERROR: failed to get video device info\n");
3424 driver_data->encode_supported = 1;
3425 driver_data->decode_supported = 1;
3426 driver_data->hd_encode_supported = 1;
3427 driver_data->hd_decode_supported = 1;
3428 }
3429
3430 #if 0
3431 psb_init_surface_pvr2dbuf(driver_data);
3432 #endif
3433
3434 if (VA_STATUS_SUCCESS != psb_initOutput(ctx)) {
3435 pthread_mutex_destroy(&driver_data->drm_mutex);
3436 psb__deinitDRM(ctx);
3437 free(ctx->pDriverData);
3438 ctx->pDriverData = NULL;
3439 return VA_STATUS_ERROR_UNKNOWN;
3440 }
3441
3442 driver_data->msvdx_context_base = (((unsigned int) getpid()) & 0xffff) << 16;
3443 #ifdef PSBVIDEO_MRFL
3444 if (IS_MRFL(driver_data)) {
3445 drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield topazhp encoder\n");
3446 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3447 driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3448 driver_data->profile2Format[VAProfileH264High][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3449 driver_data->profile2Format[VAProfileH264StereoHigh][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3450 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &tng_H263ES_vtable;
3451 driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &tng_JPEGES_vtable;
3452 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable;
3453 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &tng_MPEG4ES_vtable;
3454 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointEncSlice] = &tng_H264ES_vtable;
3455 }
3456 #endif
3457 #ifdef PSBVIDEO_MRFL_VPP
3458 if (IS_MRFL(driver_data)) {
3459 drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield vsp vpp\n");
3460 driver_data->vpp_profile = &vsp_VPP_vtable;
3461 driver_data->profile2Format[VAProfileVP8Version0_3][VAEntrypointEncSlice] = &vsp_VP8_vtable;
3462 }
3463 #endif
3464
3465 #ifdef PSBVIDEO_VXD392
3466 if (IS_MRFL(driver_data) || IS_BAYTRAIL(driver_data)) {
3467 drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield VXD392 decoder\n");
3468 driver_data->profile2Format[VAProfileVP8Version0_3][VAEntrypointVLD] = &tng_VP8_vtable;
3469 driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointVLD] = &tng_JPEG_vtable;
3470
3471 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3472 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3473
3474 driver_data->profile2Format[VAProfileMPEG2Simple][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3475 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3476
3477 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3478
3479 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;
3480 driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable;
3481 driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable;
3482
3483 driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable;
3484 driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable;
3485 driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable;
3486 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable;
3487 }
3488 #endif
3489
3490 #ifdef PSBVIDEO_MRFL_VPP
3491 if (IS_MRFL(driver_data)) {
3492 if (*((unsigned int *)ctx->native_dpy) == 0x56454450 /* VEDP */) {
3493
3494 drv_debug_msg(VIDEO_DEBUG_GENERAL, "merrifield ved vpp\n");
3495 driver_data->vpp_profile = &tng_yuv_processor_vtable;
3496 ctx->vtable_vpp->vaQueryVideoProcFilters = ved_QueryVideoProcFilters;
3497 ctx->vtable_vpp->vaQueryVideoProcFilterCaps = ved_QueryVideoProcFilterCaps;
3498 ctx->vtable_vpp->vaQueryVideoProcPipelineCaps = ved_QueryVideoProcPipelineCaps;
3499 driver_data->ved_vpp = 1;
3500 }
3501 }
3502 #endif
3503
3504 #ifdef PSBVIDEO_MFLD
3505 if (IS_MFLD(driver_data)) {
3506 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &pnw_H263ES_vtable;
3507 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &pnw_H264ES_vtable;
3508 driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &pnw_H264ES_vtable;
3509 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable;
3510 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable;
3511 driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &pnw_JPEG_vtable;
3512
3513 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3514
3515 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3516 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3517
3518 driver_data->profile2Format[VAProfileMPEG2Simple][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3519 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable;
3520
3521 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
3522
3523 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;
3524 driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable;
3525 driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable;
3526
3527 driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable;
3528 driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable;
3529 driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable;
3530 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable;
3531
3532 driver_data->vpp_profile = &tng_yuv_processor_vtable;
3533 driver_data->ved_vpp = 1;
3534 }
3535 #endif
3536
3537 result = object_heap_init(&driver_data->config_heap, sizeof(struct object_config_s), CONFIG_ID_OFFSET);
3538 ASSERT(result == 0);
3539
3540 result = object_heap_init(&driver_data->context_heap, sizeof(struct object_context_s), CONTEXT_ID_OFFSET);
3541 ASSERT(result == 0);
3542
3543 result = object_heap_init(&driver_data->surface_heap, sizeof(struct object_surface_s), SURFACE_ID_OFFSET);
3544 ASSERT(result == 0);
3545
3546 result = object_heap_init(&driver_data->buffer_heap, sizeof(struct object_buffer_s), BUFFER_ID_OFFSET);
3547 ASSERT(result == 0);
3548
3549 result = object_heap_init(&driver_data->image_heap, sizeof(struct object_image_s), IMAGE_ID_OFFSET);
3550 ASSERT(result == 0);
3551
3552 result = object_heap_init(&driver_data->subpic_heap, sizeof(struct object_subpic_s), SUBPIC_ID_OFFSET);
3553 ASSERT(result == 0);
3554
3555 driver_data->cur_displaying_surface = VA_INVALID_SURFACE;
3556 driver_data->last_displaying_surface = VA_INVALID_SURFACE;
3557
3558 driver_data->clear_color = 0;
3559 driver_data->blend_color = 0;
3560 driver_data->blend_mode = 0;
3561 driver_data->overlay_auto_paint_color_key = 0;
3562
3563 if (IS_BAYTRAIL(driver_data))
3564 ctx->str_vendor = PSB_STR_VENDOR_BAYTRAIL;
3565 if (IS_MRFL(driver_data))
3566 ctx->str_vendor = PSB_STR_VENDOR_MRFL;
3567 else if (IS_MFLD(driver_data))
3568 {
3569 if (IS_LEXINGTON(driver_data))
3570 ctx->str_vendor = PSB_STR_VENDOR_LEXINGTON;
3571 else
3572 ctx->str_vendor = PSB_STR_VENDOR_MFLD;
3573 }
3574 else
3575 ctx->str_vendor = PSB_STR_VENDOR_MRST;
3576
3577 driver_data->msvdx_decode_status = calloc(1, sizeof(drm_psb_msvdx_decode_status_t));
3578 if (NULL == driver_data->msvdx_decode_status) {
3579 pthread_mutex_destroy(&driver_data->drm_mutex);
3580 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3581 }
3582 driver_data->surface_mb_error = calloc(MAX_MB_ERRORS, sizeof(VASurfaceDecodeMBErrors));
3583 if (NULL == driver_data->surface_mb_error) {
3584 pthread_mutex_destroy(&driver_data->drm_mutex);
3585 return VA_STATUS_ERROR_ALLOCATION_FAILED;
3586 }
3587
3588 drv_debug_msg(VIDEO_DEBUG_INIT, "vaInitilize: succeeded!\n\n");
3589
3590 #ifdef ANDROID
3591 #ifndef PSBVIDEO_VXD392
3592 gralloc_init();
3593 #endif
3594 #endif
3595
3596 return VA_STATUS_SUCCESS;
3597 }
3598
3599
3600 EXPORT VAStatus __vaDriverInit_0_32(VADriverContextP ctx)
3601 {
3602 return __vaDriverInit_0_31(ctx);
3603 }
3604
3605
3606
3607 static int psb_get_device_info(VADriverContextP ctx)
3608 {
3609 INIT_DRIVER_DATA;
3610 struct drm_lnc_video_getparam_arg arg;
3611 unsigned long device_info;
3612 int ret = 0;
3613 unsigned long video_capability;
3614 unsigned long pci_device;
3615
3616 driver_data->dev_id = 0x4100; /* by default MRST */
3617
3618 arg.key = LNC_VIDEO_DEVICE_INFO;
3619 arg.value = (uint64_t)((unsigned long) & device_info);
3620 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset,
3621 &arg, sizeof(arg));
3622 if (ret != 0) {
3623 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get video device info\n");
3624 return ret;
3625 }
3626
3627 pci_device = (device_info >> 16) & 0xffff;
3628 video_capability = device_info & 0xffff;
3629
3630 driver_data->dev_id = pci_device;
3631 drv_debug_msg(VIDEO_DEBUG_INIT, "Retrieve Device ID 0x%08x\n", driver_data->dev_id);
3632
3633 if (IS_MFLD(driver_data) || IS_MRFL(driver_data))
3634 driver_data->encode_supported = 1;
3635 else /* 0x4101 or other device hasn't encode support */
3636 driver_data->encode_supported = 0;
3637
3638 driver_data->decode_supported = 1;
3639 driver_data->hd_decode_supported = 1;
3640 driver_data->hd_encode_supported = 1;
3641
3642 return ret;
3643 }
3644