1 /* 2 * Copyright (c) 2017, Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 23 #include "cm_device.h" 24 #include "drm_device.h" 25 #include <dlfcn.h> 26 #include <cstdio> 27 28 #include "cm_mem.h" 29 #include "cm_surface_manager.h" 30 #include "cm_queue.h" 31 #include "cm_timer.h" 32 #include "cm_debug.h" 33 #include "cm_extension_creator.h" 34 35 #if USE_EXTENSION_CODE 36 #include "cm_gtpin_external_interface.h" 37 #endif 38 39 #include <unistd.h> 40 #include <fcntl.h> 41 42 #define INTEL_VENDOR_ID 0x8086 43 44 // hold up to 32 GPU adapters 45 drmDevicePtr g_AdapterList[32]; 46 int32_t g_AdapterCount = 0; 47 int32_t g_supportedAdapterCount = 0; 48 49 #ifndef ANDROID 50 uint32_t CmDevice_RT::m_vaReferenceCount = 0; 51 CSync CmDevice_RT::m_vaReferenceCountCriticalSection; 52 void *CmDevice_RT::m_vaDrm = nullptr; 53 pfVAGetDisplayDRM CmDevice_RT::m_vaGetDisplayDrm = nullptr; 54 #endif 55 // current binary version, query by command "strings", 56 // e.g. "strings -a igfxcmrt64.so | grep current_version " 57 volatile static char cmrtCurrentVersion[] = "cmrt_current_version: " \ 58 "6.0.0.9010\0"; 59 CSync gDeviceCreationCriticalSection; 60 GetSupportedAdapters(uint32_t & count)61 int32_t CmDevice_RT::GetSupportedAdapters(uint32_t &count) 62 { 63 INSERT_PROFILER_RECORD(); 64 int32_t result = CM_SUCCESS; 65 uint32_t i = 0; 66 uint32_t k = 0; 67 68 if (!g_AdapterCount) 69 { 70 int max_device = 256; 71 drmDevicePtr devices[max_device]; 72 int node_count = drmGetDevices(devices, max_device); 73 int supported_adapter_count = 0; 74 for (int node_idx = 0; node_idx < node_count; ++node_idx) 75 { 76 char *card_name = strrchr(devices[node_idx]->nodes[0], '/'); 77 ++card_name; 78 size_t len = strlen(devices[node_idx]->deviceinfo.pci->driverInfo); 79 if (len > 0) 80 { 81 devices[node_idx]->deviceinfo.pci->driverInfo[len - 1] = ' '; 82 } 83 snprintf(devices[node_idx]->deviceinfo.pci->driverInfo + len, 84 (sizeof devices[node_idx]->deviceinfo.pci->driverInfo) - len, 85 " %s", card_name); 86 87 size_t render_name_length = strlen(devices[node_idx]->nodes[2]); 88 if (!render_name_length) 89 { 90 continue; 91 } 92 char *render_name = strrchr(devices[node_idx]->nodes[2], '/'); 93 if (!render_name) 94 { 95 continue; 96 } 97 ++render_name; 98 len = strlen(devices[node_idx]->deviceinfo.pci->driverInfo); 99 snprintf(devices[node_idx]->deviceinfo.pci->driverInfo + len, 100 (sizeof devices[node_idx]->deviceinfo.pci->driverInfo) - len, 101 " %s", render_name); 102 if (INTEL_VENDOR_ID == devices[node_idx]->deviceinfo.pci->vendor_id) 103 { 104 g_AdapterList[supported_adapter_count] = devices[node_idx]; 105 ++supported_adapter_count; 106 } 107 } 108 109 if (!node_count) 110 { 111 result = CM_NO_SUPPORTED_ADAPTER; 112 } 113 g_AdapterCount = node_count; 114 g_supportedAdapterCount = supported_adapter_count; 115 } 116 count = g_supportedAdapterCount; 117 return result; 118 } 119 CreateCmDeviceFromAdapter(CmDevice_RT * & pCmDev,int32_t adapterIndex,uint32_t CreateOption)120 int32_t CmDevice_RT::CreateCmDeviceFromAdapter(CmDevice_RT* &pCmDev, int32_t adapterIndex, uint32_t CreateOption) 121 { 122 INSERT_PROFILER_RECORD(); 123 124 int32_t result = CM_SUCCESS; 125 126 pCmDev = new CmDevice_RT(nullptr, CreateOption); 127 128 if (pCmDev) 129 { 130 result = pCmDev->Initialize(true, adapterIndex); 131 if (result != CM_SUCCESS) 132 { 133 CmAssert(0); 134 Destroy(pCmDev); 135 } 136 } 137 else 138 { 139 CmAssert(0); 140 result = CM_OUT_OF_HOST_MEMORY; 141 } 142 143 return result; 144 } 145 146 147 extern "C" CM_RT_API int32_t DestroyCmDevice(CmDevice* &device); 148 //! Helper function to get hardware platform specifc info from CM device APIs 149 GetPlatformInfo(uint32_t adapterIndex)150 int32_t CmDevice_RT::GetPlatformInfo(uint32_t adapterIndex) 151 { 152 uint32_t version = 0; 153 CmDevice_RT *pDev = nullptr; 154 CmDevice *pCmDev = nullptr; 155 // Create a CM Device 156 int32_t result = CreateCmDeviceFromAdapter(pDev, adapterIndex); 157 if ((result != CM_SUCCESS) || (pDev == nullptr)) 158 { 159 return CM_FAILURE; 160 } 161 162 pCmDev = static_cast<CmDevice*>(pDev); 163 uint32_t gpu_platform = 0; 164 uint32_t gt_platform = 0; 165 CM_PLATFORM_INFO platform_info; 166 uint32_t count; 167 uint32_t samplers; 168 size_t size = 4; 169 170 result = pCmDev->GetCaps(CAP_HW_THREAD_COUNT, size, &count); 171 result = pCmDev->GetCaps(CAP_GT_PLATFORM, size, >_platform); 172 result = pCmDev->GetCaps(CAP_SAMPLER_COUNT, size, &samplers); 173 size = sizeof(CM_PLATFORM_INFO); 174 result = pCmDev->GetCaps(CAP_PLATFORM_INFO, size, &platform_info); 175 if (result == CM_SUCCESS) 176 { 177 g_AdapterList[adapterIndex]->MaxThread = count; 178 g_AdapterList[adapterIndex]->EuNumber = platform_info.numSlices * platform_info.numSubSlices * platform_info.numEUsPerSubSlice; 179 g_AdapterList[adapterIndex]->TileNumber = 1; 180 } 181 DestroyCmDevice(pCmDev); 182 return result; 183 } 184 185 QueryAdapterInfo(uint32_t adapterIndex,AdapterInfoType infoName,void * info,uint32_t infoSize,uint32_t * OutInfoSize)186 int32_t CmDevice_RT::QueryAdapterInfo(uint32_t adapterIndex, AdapterInfoType infoName, void *info, uint32_t infoSize, uint32_t *OutInfoSize) 187 { 188 int32_t result = CM_SUCCESS; 189 190 if (adapterIndex < g_supportedAdapterCount) 191 { 192 switch (infoName) 193 { 194 case Description: 195 if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->driverInfo) || infoSize > 250) 196 { 197 *OutInfoSize = 250; 198 if (info != g_AdapterList[adapterIndex]->deviceinfo.pci->driverInfo) 199 { 200 201 memcpy_s(info, infoSize, (void*)g_AdapterList[adapterIndex]->deviceinfo.pci->driverInfo, *OutInfoSize); 202 } 203 result = CM_SUCCESS; 204 } 205 else 206 { 207 result = CM_INVALID_ARG_VALUE; 208 } 209 break; 210 case VendorId: 211 if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->vendor_id)) 212 { 213 *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->vendor_id); 214 if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->vendor_id) 215 { 216 memcpy_s(info, infoSize, (void*)&g_AdapterList[adapterIndex]->deviceinfo.pci->vendor_id, *OutInfoSize); 217 } 218 result = CM_SUCCESS; 219 } 220 else 221 { 222 result = CM_INVALID_ARG_VALUE; 223 } 224 break; 225 case DeviceId: 226 if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->device_id)) 227 { 228 *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->device_id); 229 if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->device_id) 230 { 231 memcpy_s(info, infoSize, (void*)&g_AdapterList[adapterIndex]->deviceinfo.pci->device_id, *OutInfoSize); 232 } 233 result = CM_SUCCESS; 234 } 235 else 236 { 237 result = CM_INVALID_ARG_VALUE; 238 } 239 break; 240 241 case SubSysId: 242 if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->subdevice_id)) 243 { 244 *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->subdevice_id); 245 uint32_t SubSystemID = (g_AdapterList[adapterIndex]->deviceinfo.pci->subdevice_id << 16) | g_AdapterList[adapterIndex]->deviceinfo.pci->subvendor_id; 246 if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->subdevice_id) 247 { 248 memcpy_s(info, infoSize, (void*)&SubSystemID, *OutInfoSize); 249 } 250 result = CM_SUCCESS; 251 } 252 else 253 { 254 result = CM_INVALID_ARG_VALUE; 255 } 256 break; 257 258 case DedicatedVideoMemory: 259 { 260 int k = 1; 261 uint64_t max = g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[0]; 262 263 for (int i = 1; i < 4; i++) 264 { 265 if (g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[i] > max) 266 { 267 max = g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[i]; 268 k = i; 269 } 270 } 271 if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[k])) 272 { 273 *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[k]); 274 if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[k]) 275 { 276 memcpy_s(info, infoSize, (void*)&g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[k], *OutInfoSize); 277 } 278 result = CM_SUCCESS; 279 } 280 else 281 { 282 result = CM_INVALID_ARG_VALUE; 283 } 284 } 285 break; 286 287 case DedicatedSystemMemory: 288 if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->systemMem[0])) 289 { 290 *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->systemMem[0]); 291 if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->systemMem[0]) 292 { 293 memcpy_s(info, infoSize, (void*)&g_AdapterList[adapterIndex]->deviceinfo.pci->systemMem[0], *OutInfoSize); 294 } 295 result = CM_SUCCESS; 296 } 297 else 298 { 299 result = CM_INVALID_ARG_VALUE; 300 } 301 break; 302 303 case SharedSystemMemory: 304 if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->sharedMem[0])) 305 { 306 *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->sharedMem[0]); 307 if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->sharedMem[0]) 308 { 309 memcpy_s(info, infoSize, (void*)&g_AdapterList[adapterIndex]->deviceinfo.pci->sharedMem[1], *OutInfoSize); 310 } 311 result = CM_SUCCESS; 312 } 313 else 314 { 315 result = CM_INVALID_ARG_VALUE; 316 } 317 break; 318 319 ////////////////////// Hardware platform specific information need to pull from CM device////////////////////// 320 case MaxThread: 321 if (g_AdapterList[adapterIndex]->MaxThread == 0) 322 result = GetPlatformInfo(adapterIndex); 323 324 if (infoSize >= sizeof(g_AdapterList[adapterIndex]->MaxThread)) 325 { 326 *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->MaxThread); 327 if (info != &g_AdapterList[adapterIndex]->MaxThread) 328 { 329 memcpy_s(info, infoSize, &g_AdapterList[adapterIndex]->MaxThread, *OutInfoSize); 330 } 331 result = CM_SUCCESS; 332 } 333 else 334 { 335 result = CM_INVALID_ARG_VALUE; 336 } 337 break; 338 339 case EuNumber: 340 if (g_AdapterList[adapterIndex]->MaxThread == 0) 341 result = GetPlatformInfo(adapterIndex); 342 343 if (infoSize >= sizeof(g_AdapterList[adapterIndex]->EuNumber)) 344 { 345 *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->EuNumber); 346 if (info != &g_AdapterList[adapterIndex]->EuNumber) 347 { 348 memcpy_s(info, infoSize, &g_AdapterList[adapterIndex]->EuNumber, *OutInfoSize); 349 } 350 result = CM_SUCCESS; 351 } 352 else 353 { 354 result = CM_INVALID_ARG_VALUE; 355 } 356 break; 357 358 case TileNumber: 359 if (g_AdapterList[adapterIndex]->MaxThread == 0) 360 result = GetPlatformInfo(adapterIndex); 361 362 if (infoSize >= sizeof(g_AdapterList[adapterIndex]->TileNumber)) 363 { 364 *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->TileNumber); 365 if (info != &g_AdapterList[adapterIndex]->TileNumber) 366 { 367 memcpy_s(info, infoSize, &g_AdapterList[adapterIndex]->TileNumber, *OutInfoSize); 368 } 369 result = CM_SUCCESS; 370 } 371 else 372 { 373 result = CM_INVALID_ARG_VALUE; 374 } 375 break; 376 377 default: 378 // unknown Info name 379 result = CM_INVALID_ARG_VALUE; 380 break; 381 } 382 } 383 return result; 384 } Create(CmDevice_RT * & device,uint32_t createOption)385 int32_t CmDevice_RT::Create(CmDevice_RT* &device, uint32_t createOption) 386 { 387 INSERT_PROFILER_RECORD(); 388 389 int32_t result = CM_SUCCESS; 390 uint32_t count = 0; 391 392 if (g_AdapterCount == 0 ) 393 GetSupportedAdapters(count); 394 395 if (g_supportedAdapterCount > 0) 396 { 397 // start from first supported GPU 398 uint32_t Index = 0; 399 device = new CmDevice_RT(nullptr, createOption); 400 401 if (CM_DEVICE_CREATE_OPTION_DEFAULT != createOption) 402 // select last supported GPU 403 Index = g_supportedAdapterCount - 1; 404 405 if (device) 406 { 407 result = device->Initialize(true, Index); 408 if (result != CM_SUCCESS) 409 { 410 CmAssert(0); 411 Destroy(device); 412 } 413 } 414 else 415 { 416 CmAssert(0); 417 result = CM_OUT_OF_HOST_MEMORY; 418 } 419 } 420 else 421 result = CM_NO_SUPPORTED_ADAPTER; 422 423 return result; 424 } 425 426 Create(VADisplay & vaDisplay,CmDevice_RT * & device,uint32_t createOption)427 int32_t CmDevice_RT::Create(VADisplay &vaDisplay, CmDevice_RT* &device, uint32_t createOption) 428 { 429 INSERT_PROFILER_RECORD(); 430 431 int32_t result = CM_FAILURE; 432 device = new (std::nothrow) CmDevice_RT(vaDisplay, createOption); 433 if (device) 434 { 435 result = device->Initialize(false); 436 if (result != CM_SUCCESS) 437 { 438 Destroy(device); 439 } 440 } 441 else 442 { 443 CmAssert(0); 444 result = CM_OUT_OF_HOST_MEMORY; 445 } 446 447 // leave critical section 448 return result; 449 } 450 Destroy(CmDevice_RT * & device)451 int32_t CmDevice_RT::Destroy(CmDevice_RT* &device) 452 { 453 if (device == nullptr) 454 { 455 return CM_FAILURE; 456 } 457 458 // Destroy the cm device object 459 device->FreeResources(); 460 461 //Destroy the Device at CMRT@UMD 462 CM_DESTROYCMDEVICE_PARAM destroyCmDeviceParam; 463 CmSafeMemSet(&destroyCmDeviceParam, 0, sizeof(CM_DESTROYCMDEVICE_PARAM)); 464 destroyCmDeviceParam.cmDeviceHandle = device->m_deviceInUmd; 465 uint32_t inputDataLen = sizeof(CM_DESTROYCMDEVICE_PARAM); 466 467 int32_t result = device->OSALExtensionExecute(CM_FN_DESTROYCMDEVICE, 468 &destroyCmDeviceParam, 469 inputDataLen); 470 471 CmSafeRelease(device); 472 CHK_FAILURE_RETURN(result); 473 474 // leave critical section 475 return destroyCmDeviceParam.returnValue; 476 } 477 CmDevice_RT(VADisplay vaDisplay,uint32_t createOption)478 CmDevice_RT::CmDevice_RT( 479 VADisplay vaDisplay, 480 uint32_t createOption 481 ) : 482 m_cmVersion(0), 483 m_deviceInUmd(nullptr), 484 m_cmCreated(true), 485 m_vaDisplay(vaDisplay), 486 m_drmIndex(0), 487 m_fvaCmExtSendReqMsg(nullptr), 488 #ifdef ANDROID 489 m_display(nullptr), 490 #endif 491 m_gtpinEnabled(false), 492 m_gtpinBufferUP0(nullptr), 493 m_gtpinBufferUP1(nullptr), 494 m_gtpinBufferUP2(nullptr), 495 m_createOption(createOption), 496 #if !defined(ANDROID) 497 m_driFileDescriptor(0), 498 #endif 499 m_driverStoreEnabled(0) 500 { 501 502 // New Surface Manager 503 m_surfaceManager = new CmSurfaceManager(this); 504 505 // New Kernel Debugger 506 m_kernelDebugger = CmExtensionCreator<CmKernelDebugger>::CreateClass(); 507 508 //Initialize L3 cache config 509 CmSafeMemSet(&m_l3Config, 0, sizeof(L3ConfigRegisterValues)); 510 511 } 512 ~CmDevice_RT(void)513 CmDevice_RT::~CmDevice_RT(void) 514 { 515 if (m_cmCreated) 516 { 517 vaTerminate(m_vaDisplay); 518 #ifndef ANDROID 519 FreeLibvaDrm(); 520 #else 521 free(m_display); //Android 522 #endif 523 } 524 525 if (m_kernelDebugger != nullptr) 526 { 527 delete m_kernelDebugger; 528 } 529 } 530 FreeResources()531 int32_t CmDevice_RT::FreeResources() 532 { 533 //Destroy Queue 534 m_criticalSectionQueue.Acquire(); 535 for (auto iter = m_queue.begin(); iter != m_queue.end();) 536 { 537 if (*iter != nullptr) 538 { 539 CmQueue_RT::Destroy(*iter); 540 } 541 iter = m_queue.erase(iter); 542 } 543 m_criticalSectionQueue.Release(); 544 545 //Destroy GTPin Used BufferUp 546 if (m_gtpinBufferUP0 != nullptr) 547 { 548 DestroyBufferUP(m_gtpinBufferUP0); 549 } 550 551 if (m_gtpinBufferUP1 != nullptr) 552 { 553 DestroyBufferUP(m_gtpinBufferUP1); 554 } 555 556 if (m_gtpinBufferUP2 != nullptr) 557 { 558 DestroyBufferUP(m_gtpinBufferUP2); 559 } 560 561 CmSafeRelease(m_surfaceManager); 562 563 return CM_SUCCESS; 564 } 565 CmrtVaSurfaceRelease(void * vaDisplay,void * vaSurface)566 static int32_t CmrtVaSurfaceRelease(void *vaDisplay, void *vaSurface) 567 { 568 VAStatus vaStatus = VA_STATUS_SUCCESS; 569 VADisplay *display = (VADisplay *)(vaDisplay); 570 571 //Destroy VaSurface 572 vaStatus = vaDestroySurfaces(*display, (VASurfaceID *)vaSurface, 1); 573 574 return vaStatus; 575 } 576 Initialize(bool isCmCreated,uint32_t Index)577 int32_t CmDevice_RT::Initialize(bool isCmCreated, uint32_t Index) 578 { 579 int32_t result = CM_SUCCESS; 580 581 m_cmCreated = isCmCreated; 582 583 CLock locker(gDeviceCreationCriticalSection); 584 585 CHK_RET(InitializeLibvaDisplay(Index)); 586 587 CHK_RET(CreateDeviceInUmd()); 588 589 CHK_RET(CheckDdiVersionSupported(m_cmVersion)); 590 591 #if USE_EXTENSION_CODE 592 if (GTpinVariables.GTPinEnabled) 593 { 594 CHK_RET(EnableGtpin()); 595 CHK_RET(RegisterGtpinMarkerFunctions()); 596 597 } 598 #endif 599 if (m_kernelDebugger != nullptr) 600 { 601 m_kernelDebugger->NotifyNewDevice(this, m_deviceInUmd, m_driverStoreEnabled); 602 } 603 604 finish: 605 return result; 606 } 607 CreateDeviceInUmd()608 int32_t CmDevice_RT::CreateDeviceInUmd() 609 { 610 CmDeviceCreationParam createCmDeviceParam; 611 CmSafeMemSet(&createCmDeviceParam, 0, sizeof(createCmDeviceParam)); 612 createCmDeviceParam.returnValue = CM_FAILURE; 613 createCmDeviceParam.createOption = m_createOption; 614 createCmDeviceParam.releaseSurfaceFunc = &CmrtVaSurfaceRelease; 615 uint32_t inputDataLen = sizeof(createCmDeviceParam); 616 617 int32_t result = OSALExtensionExecute(CM_FN_CREATECMDEVICE, 618 &createCmDeviceParam, inputDataLen); 619 620 CHK_FAILURE_RETURN(result); 621 CHK_FAILURE_RETURN(createCmDeviceParam.returnValue); 622 623 m_cmVersion = createCmDeviceParam.version; 624 m_deviceInUmd = createCmDeviceParam.deviceHandleInUmd; 625 m_driverStoreEnabled = createCmDeviceParam.driverStoreEnabled; 626 return CM_SUCCESS; 627 } 628 629 //! 630 //! Create Libva Surface and wrap it as a CmSurface 631 //! It is CALLER's responsibility to allocation memory for all pointers to CmSurface2D 632 //! Input : 633 //! 1) Surface's width [in] 634 //! 2) Surface's height [in] 635 //! 3) Surface's format [in] 636 //! 4) Reference to created VASurfaceID [out] 637 //! 5) Reference to pointer of created Cm Surface [out] 638 //! Output: 639 //! CM_SUCCESS if all CmSurface2D are successfully created; 640 //! CM_VA_SURFACE_NOT_SUPPORTED if libva surface creation fail; 641 //! CM_FAILURE otherwise; CreateVaSurface2D(uint32_t width,uint32_t height,CM_SURFACE_FORMAT format,VASurfaceID & vaSurface,CmSurface2D * & surface)642 CM_RT_API int32_t CmDevice_RT::CreateVaSurface2D(uint32_t width, uint32_t height, CM_SURFACE_FORMAT format, VASurfaceID &vaSurface, CmSurface2D* &surface) 643 { 644 INSERT_PROFILER_RECORD(); 645 646 return m_surfaceManager->CreateVaSurface2D(width, height, format, vaSurface, surface); 647 } 648 649 //! 650 //! 651 //! Create a CmSurface2D from an existing LIBVA surface 652 //! Input : 653 //! Reference to the pointer to the CmSurface2D . 654 //! VASurfaceID 655 //! Output: 656 //! CM_SUCCESS if the CmSurface2D are successfully created; 657 //! CM_OUT_OF_HOST_MEMORY if out of system memory; 658 //! CM_FAILURE otherwise; 659 //! CreateSurface2D(VASurfaceID vaSurface,CmSurface2D * & surface)660 CM_RT_API int32_t CmDevice_RT::CreateSurface2D(VASurfaceID vaSurface, CmSurface2D* &surface) 661 { 662 INSERT_PROFILER_RECORD(); 663 664 return m_surfaceManager->CreateSurface2D(vaSurface, surface); 665 } 666 667 //! 668 //! Create an array of CmSurface2D from an existing array of LIBVA surfaces, which are created by LIBVA's vaCreateSurfaces 669 //! It is CALLER's responsibility to allocation memory for all pointers to CmSurface2D 670 //! Input : 671 //! 1) Pointer to the array of pointers pointing to LIBVA surface 672 //! 2) array size 673 //! 3) Pointer to the array of pointers pointing to CmSurface2D . 674 //! Output: 675 //! CM_SUCCESS if all CmSurface2D are successfully created; 676 //! CM_OUT_OF_HOST_MEMORY if out of system memory; 677 //! CM_FAILURE otherwise; CreateSurface2D(VASurfaceID * vaSurfaceArray,const uint32_t surfaceCount,CmSurface2D ** surfaceArray)678 CM_RT_API int32_t CmDevice_RT::CreateSurface2D(VASurfaceID* vaSurfaceArray, const uint32_t surfaceCount, CmSurface2D** surfaceArray) 679 { 680 INSERT_PROFILER_RECORD(); 681 682 return m_surfaceManager->CreateSurface2D(vaSurfaceArray, surfaceCount, surfaceArray); 683 } 684 OSALExtensionExecute(uint32_t functionId,void * inputData,uint32_t inputDataLength,void ** resourceList,uint32_t resourceCount)685 int32_t CmDevice_RT::OSALExtensionExecute(uint32_t functionId, 686 void *inputData, 687 uint32_t inputDataLength, 688 void **resourceList, 689 uint32_t resourceCount) 690 { 691 CmAssert(inputData); 692 693 // uint32_t functionId = functionId; 694 // void* inputData = pInputData; 695 // uint32_t inputDataLen = iInputDataLen; 696 697 void* outputData = m_deviceInUmd; // pass cm device handle to umd 698 uint32_t outputDataLen = sizeof(m_deviceInUmd); 699 uint32_t vaModuleId = VAExtModuleCMRT; 700 VAStatus hr = VA_STATUS_SUCCESS; 701 702 if (m_fvaCmExtSendReqMsg != nullptr) 703 { 704 hr = m_fvaCmExtSendReqMsg(m_vaDisplay, &vaModuleId, &functionId, inputData, &inputDataLength, 0, outputData, &outputDataLen); 705 } 706 return hr; 707 } 708 709 //Initalize LibVA's VADisplay by supported dri device list index InitializeLibvaDisplay(uint32_t Index)710 int32_t CmDevice_RT::InitializeLibvaDisplay(uint32_t Index) 711 { 712 if (m_cmCreated) 713 { 714 VAStatus vaStatus = VA_STATUS_SUCCESS; 715 int vaMajorVersion, vaMinorVersion; 716 m_drmIndex = Index; 717 718 #ifndef ANDROID 719 int32_t ret = GetLibvaDisplayDrm(m_vaDisplay); 720 if (ret != CM_SUCCESS) 721 { 722 CmAssert(0); 723 return ret; 724 } 725 #else 726 m_display = (Display*)malloc(sizeof(Display)); 727 if (m_display == nullptr) 728 { 729 fprintf(stderr, "Can't connect X server!\n"); 730 return CM_INVALID_LIBVA_INITIALIZE; 731 } 732 733 *(m_display) = ANDROID_DISPLAY; 734 m_vaDisplay = vaGetDisplay(m_display); 735 if (m_vaDisplay == nullptr) 736 { 737 return CM_INVALID_LIBVA_INITIALIZE; 738 } 739 #endif //ANDROID 740 741 vaStatus = vaInitialize(m_vaDisplay, &vaMajorVersion, &vaMinorVersion); 742 if (VA_STATUS_SUCCESS != vaStatus) { 743 return CM_INVALID_LIBVA_INITIALIZE; 744 } 745 } 746 747 m_fvaCmExtSendReqMsg = (pvaCmExtSendReqMsg)vaGetLibFunc(m_vaDisplay, "vaCmExtSendReqMsg"); 748 749 if (m_fvaCmExtSendReqMsg == nullptr) { 750 fprintf(stderr, "Cannot get function of m_fvaCmExtSendReqMsg!\n"); 751 return CM_INVALID_LIBVA_INITIALIZE; 752 } 753 else 754 { 755 return CM_SUCCESS; 756 } 757 } 758 GetVaDpy(VADisplay * & vaDpy)759 CM_RT_API int32_t CmDevice_RT::GetVaDpy(VADisplay* & vaDpy) 760 { 761 INSERT_PROFILER_RECORD(); 762 763 vaDpy = &m_vaDisplay; 764 return CM_SUCCESS; 765 } 766 767 #ifndef ANDROID GetLibvaDisplayDrm(VADisplay & vaDisplay)768 int32_t CmDevice_RT::GetLibvaDisplayDrm(VADisplay & vaDisplay) 769 { 770 pfVAGetDisplayDRM vaGetDisplayDRM = nullptr; 771 char *dlSymErr = nullptr; 772 void *hLibVaDRM = nullptr; 773 774 CLock locker(m_vaReferenceCountCriticalSection); 775 776 if (m_vaReferenceCount > 0) 777 { 778 vaGetDisplayDRM = m_vaGetDisplayDrm; 779 m_vaReferenceCount++; 780 } 781 else 782 { 783 //Load libva-drm.so 784 dlerror(); 785 hLibVaDRM = dlopen("libva-drm.so", RTLD_LAZY); 786 787 if (!hLibVaDRM) 788 { 789 if ((dlSymErr = dlerror()) != nullptr) 790 { 791 fprintf(stderr, "%s\n", dlSymErr); 792 } 793 return CM_INVALID_LIBVA_INITIALIZE; 794 } 795 796 //dynamically load function vaGetDisplayDRM from libva-drm.so 797 dlerror(); 798 vaGetDisplayDRM = (pfVAGetDisplayDRM)dlsym(hLibVaDRM, "vaGetDisplayDRM"); 799 if ((dlSymErr = dlerror()) != nullptr) { 800 fprintf(stderr, "%s\n", dlSymErr); 801 return CM_INVALID_LIBVA_INITIALIZE; 802 } 803 804 m_vaReferenceCount++; 805 m_vaDrm = hLibVaDRM; 806 m_vaGetDisplayDrm = vaGetDisplayDRM; 807 } 808 809 // open the GPU device 810 if (g_supportedAdapterCount < 1) 811 { 812 fprintf(stderr, "No supported Intel GPU device file node detected\n"); 813 return CM_INVALID_LIBVA_INITIALIZE; 814 } 815 816 if (m_drmIndex < g_supportedAdapterCount) 817 { 818 m_driFileDescriptor = GetRendererFileDescriptor(g_AdapterList[m_drmIndex]->nodes[2]); 819 } 820 else 821 { 822 fprintf(stderr, "Invalid drm list index used\n"); 823 return CM_INVALID_LIBVA_INITIALIZE; 824 } 825 826 if (m_driFileDescriptor < 0) 827 { 828 fprintf(stderr, "Failed to open GPU device file node\n"); 829 return CM_INVALID_LIBVA_INITIALIZE; 830 } 831 832 if (m_vaGetDisplayDrm == nullptr) 833 { 834 fprintf(stderr, "m_vaGetDisplayDrm should not be nullptr.\n"); 835 return CM_INVALID_LIBVA_INITIALIZE; 836 } 837 838 // get the display handle. 839 if (vaGetDisplayDRM == nullptr) 840 { 841 fprintf(stderr, "vaGetDisplayDRM should not be nullptr.\n"); 842 return CM_INVALID_LIBVA_INITIALIZE; 843 } 844 vaDisplay = vaGetDisplayDRM(m_driFileDescriptor); 845 846 return CM_SUCCESS; 847 } 848 FreeLibvaDrm()849 int32_t CmDevice_RT::FreeLibvaDrm() 850 { 851 CLock locker(m_vaReferenceCountCriticalSection); 852 if (m_vaReferenceCount > 1) 853 { 854 m_vaReferenceCount--; 855 } 856 else 857 { 858 dlclose(m_vaDrm); 859 m_vaDrm = nullptr; 860 m_vaGetDisplayDrm = nullptr; 861 862 m_vaReferenceCount--; 863 } 864 865 if (m_driFileDescriptor != -1) 866 { 867 close(m_driFileDescriptor); 868 m_driFileDescriptor = -1; 869 } 870 return CM_SUCCESS; 871 } 872 #endif 873 874