xref: /aosp_15_r20/external/intel-media-driver/cmrtlib/linux/hardware/cm_device_os.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
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, &gt_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