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