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