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