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