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