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