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