| /* |
| * Copyright (c) 2017, Intel Corporation |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| * OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| #include "cm_device.h" |
| #include "drm_device.h" |
| #include <dlfcn.h> |
| #include <cstdio> |
| |
| #include "cm_mem.h" |
| #include "cm_surface_manager.h" |
| #include "cm_queue.h" |
| #include "cm_timer.h" |
| #include "cm_debug.h" |
| #include "cm_extension_creator.h" |
| |
| #if USE_EXTENSION_CODE |
| #include "cm_gtpin_external_interface.h" |
| #endif |
| |
| #include <unistd.h> |
| #include <fcntl.h> |
| |
| #define INTEL_VENDOR_ID 0x8086 |
| |
| // hold up to 32 GPU adapters |
| drmDevicePtr g_AdapterList[32]; |
| int32_t g_AdapterCount = 0; |
| int32_t g_supportedAdapterCount = 0; |
| |
| #ifndef ANDROID |
| uint32_t CmDevice_RT::m_vaReferenceCount = 0; |
| CSync CmDevice_RT::m_vaReferenceCountCriticalSection; |
| void *CmDevice_RT::m_vaDrm = nullptr; |
| pfVAGetDisplayDRM CmDevice_RT::m_vaGetDisplayDrm = nullptr; |
| #endif |
| // current binary version, query by command "strings", |
| // e.g. "strings -a igfxcmrt64.so | grep current_version " |
| volatile static char cmrtCurrentVersion[] = "cmrt_current_version: " \ |
| "6.0.0.9010\0"; |
| CSync gDeviceCreationCriticalSection; |
| |
| int32_t CmDevice_RT::GetSupportedAdapters(uint32_t &count) |
| { |
| INSERT_PROFILER_RECORD(); |
| int32_t result = CM_SUCCESS; |
| uint32_t i = 0; |
| uint32_t k = 0; |
| |
| if (!g_AdapterCount) |
| { |
| int max_device = 256; |
| drmDevicePtr devices[max_device]; |
| int node_count = drmGetDevices(devices, max_device); |
| int supported_adapter_count = 0; |
| for (int node_idx = 0; node_idx < node_count; ++node_idx) |
| { |
| char *card_name = strrchr(devices[node_idx]->nodes[0], '/'); |
| ++card_name; |
| size_t len = strlen(devices[node_idx]->deviceinfo.pci->driverInfo); |
| if (len > 0) |
| { |
| devices[node_idx]->deviceinfo.pci->driverInfo[len - 1] = ' '; |
| } |
| snprintf(devices[node_idx]->deviceinfo.pci->driverInfo + len, |
| (sizeof devices[node_idx]->deviceinfo.pci->driverInfo) - len, |
| " %s", card_name); |
| |
| size_t render_name_length = strlen(devices[node_idx]->nodes[2]); |
| if (!render_name_length) |
| { |
| continue; |
| } |
| char *render_name = strrchr(devices[node_idx]->nodes[2], '/'); |
| if (!render_name) |
| { |
| continue; |
| } |
| ++render_name; |
| len = strlen(devices[node_idx]->deviceinfo.pci->driverInfo); |
| snprintf(devices[node_idx]->deviceinfo.pci->driverInfo + len, |
| (sizeof devices[node_idx]->deviceinfo.pci->driverInfo) - len, |
| " %s", render_name); |
| if (INTEL_VENDOR_ID == devices[node_idx]->deviceinfo.pci->vendor_id) |
| { |
| g_AdapterList[supported_adapter_count] = devices[node_idx]; |
| ++supported_adapter_count; |
| } |
| } |
| |
| if (!node_count) |
| { |
| result = CM_NO_SUPPORTED_ADAPTER; |
| } |
| g_AdapterCount = node_count; |
| g_supportedAdapterCount = supported_adapter_count; |
| } |
| count = g_supportedAdapterCount; |
| return result; |
| } |
| |
| int32_t CmDevice_RT::CreateCmDeviceFromAdapter(CmDevice_RT* &pCmDev, int32_t adapterIndex, uint32_t CreateOption) |
| { |
| INSERT_PROFILER_RECORD(); |
| |
| int32_t result = CM_SUCCESS; |
| |
| pCmDev = new CmDevice_RT(nullptr, CreateOption); |
| |
| if (pCmDev) |
| { |
| result = pCmDev->Initialize(true, adapterIndex); |
| if (result != CM_SUCCESS) |
| { |
| CmAssert(0); |
| Destroy(pCmDev); |
| } |
| } |
| else |
| { |
| CmAssert(0); |
| result = CM_OUT_OF_HOST_MEMORY; |
| } |
| |
| return result; |
| } |
| |
| |
| extern "C" CM_RT_API int32_t DestroyCmDevice(CmDevice* &device); |
| //! Helper function to get hardware platform specifc info from CM device APIs |
| |
| int32_t CmDevice_RT::GetPlatformInfo(uint32_t adapterIndex) |
| { |
| uint32_t version = 0; |
| CmDevice_RT *pDev = nullptr; |
| CmDevice *pCmDev = nullptr; |
| // Create a CM Device |
| int32_t result = CreateCmDeviceFromAdapter(pDev, adapterIndex); |
| if ((result != CM_SUCCESS) || (pDev == nullptr)) |
| { |
| return CM_FAILURE; |
| } |
| |
| pCmDev = static_cast<CmDevice*>(pDev); |
| uint32_t gpu_platform = 0; |
| uint32_t gt_platform = 0; |
| CM_PLATFORM_INFO platform_info; |
| uint32_t count; |
| uint32_t samplers; |
| size_t size = 4; |
| |
| result = pCmDev->GetCaps(CAP_HW_THREAD_COUNT, size, &count); |
| result = pCmDev->GetCaps(CAP_GT_PLATFORM, size, >_platform); |
| result = pCmDev->GetCaps(CAP_SAMPLER_COUNT, size, &samplers); |
| size = sizeof(CM_PLATFORM_INFO); |
| result = pCmDev->GetCaps(CAP_PLATFORM_INFO, size, &platform_info); |
| if (result == CM_SUCCESS) |
| { |
| g_AdapterList[adapterIndex]->MaxThread = count; |
| g_AdapterList[adapterIndex]->EuNumber = platform_info.numSlices * platform_info.numSubSlices * platform_info.numEUsPerSubSlice; |
| g_AdapterList[adapterIndex]->TileNumber = 1; |
| } |
| DestroyCmDevice(pCmDev); |
| return result; |
| } |
| |
| |
| int32_t CmDevice_RT::QueryAdapterInfo(uint32_t adapterIndex, AdapterInfoType infoName, void *info, uint32_t infoSize, uint32_t *OutInfoSize) |
| { |
| int32_t result = CM_SUCCESS; |
| |
| if (adapterIndex < g_supportedAdapterCount) |
| { |
| switch (infoName) |
| { |
| case Description: |
| if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->driverInfo) || infoSize > 250) |
| { |
| *OutInfoSize = 250; |
| if (info != g_AdapterList[adapterIndex]->deviceinfo.pci->driverInfo) |
| { |
| |
| memcpy_s(info, infoSize, (void*)g_AdapterList[adapterIndex]->deviceinfo.pci->driverInfo, *OutInfoSize); |
| } |
| result = CM_SUCCESS; |
| } |
| else |
| { |
| result = CM_INVALID_ARG_VALUE; |
| } |
| break; |
| case VendorId: |
| if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->vendor_id)) |
| { |
| *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->vendor_id); |
| if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->vendor_id) |
| { |
| memcpy_s(info, infoSize, (void*)&g_AdapterList[adapterIndex]->deviceinfo.pci->vendor_id, *OutInfoSize); |
| } |
| result = CM_SUCCESS; |
| } |
| else |
| { |
| result = CM_INVALID_ARG_VALUE; |
| } |
| break; |
| case DeviceId: |
| if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->device_id)) |
| { |
| *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->device_id); |
| if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->device_id) |
| { |
| memcpy_s(info, infoSize, (void*)&g_AdapterList[adapterIndex]->deviceinfo.pci->device_id, *OutInfoSize); |
| } |
| result = CM_SUCCESS; |
| } |
| else |
| { |
| result = CM_INVALID_ARG_VALUE; |
| } |
| break; |
| |
| case SubSysId: |
| if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->subdevice_id)) |
| { |
| *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->subdevice_id); |
| uint32_t SubSystemID = (g_AdapterList[adapterIndex]->deviceinfo.pci->subdevice_id << 16) | g_AdapterList[adapterIndex]->deviceinfo.pci->subvendor_id; |
| if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->subdevice_id) |
| { |
| memcpy_s(info, infoSize, (void*)&SubSystemID, *OutInfoSize); |
| } |
| result = CM_SUCCESS; |
| } |
| else |
| { |
| result = CM_INVALID_ARG_VALUE; |
| } |
| break; |
| |
| case DedicatedVideoMemory: |
| { |
| int k = 1; |
| uint64_t max = g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[0]; |
| |
| for (int i = 1; i < 4; i++) |
| { |
| if (g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[i] > max) |
| { |
| max = g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[i]; |
| k = i; |
| } |
| } |
| if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[k])) |
| { |
| *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[k]); |
| if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[k]) |
| { |
| memcpy_s(info, infoSize, (void*)&g_AdapterList[adapterIndex]->deviceinfo.pci->videoMem[k], *OutInfoSize); |
| } |
| result = CM_SUCCESS; |
| } |
| else |
| { |
| result = CM_INVALID_ARG_VALUE; |
| } |
| } |
| break; |
| |
| case DedicatedSystemMemory: |
| if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->systemMem[0])) |
| { |
| *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->systemMem[0]); |
| if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->systemMem[0]) |
| { |
| memcpy_s(info, infoSize, (void*)&g_AdapterList[adapterIndex]->deviceinfo.pci->systemMem[0], *OutInfoSize); |
| } |
| result = CM_SUCCESS; |
| } |
| else |
| { |
| result = CM_INVALID_ARG_VALUE; |
| } |
| break; |
| |
| case SharedSystemMemory: |
| if (infoSize >= sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->sharedMem[0])) |
| { |
| *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->deviceinfo.pci->sharedMem[0]); |
| if (info != &g_AdapterList[adapterIndex]->deviceinfo.pci->sharedMem[0]) |
| { |
| memcpy_s(info, infoSize, (void*)&g_AdapterList[adapterIndex]->deviceinfo.pci->sharedMem[1], *OutInfoSize); |
| } |
| result = CM_SUCCESS; |
| } |
| else |
| { |
| result = CM_INVALID_ARG_VALUE; |
| } |
| break; |
| |
| ////////////////////// Hardware platform specific information need to pull from CM device////////////////////// |
| case MaxThread: |
| if (g_AdapterList[adapterIndex]->MaxThread == 0) |
| result = GetPlatformInfo(adapterIndex); |
| |
| if (infoSize >= sizeof(g_AdapterList[adapterIndex]->MaxThread)) |
| { |
| *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->MaxThread); |
| if (info != &g_AdapterList[adapterIndex]->MaxThread) |
| { |
| memcpy_s(info, infoSize, &g_AdapterList[adapterIndex]->MaxThread, *OutInfoSize); |
| } |
| result = CM_SUCCESS; |
| } |
| else |
| { |
| result = CM_INVALID_ARG_VALUE; |
| } |
| break; |
| |
| case EuNumber: |
| if (g_AdapterList[adapterIndex]->MaxThread == 0) |
| result = GetPlatformInfo(adapterIndex); |
| |
| if (infoSize >= sizeof(g_AdapterList[adapterIndex]->EuNumber)) |
| { |
| *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->EuNumber); |
| if (info != &g_AdapterList[adapterIndex]->EuNumber) |
| { |
| memcpy_s(info, infoSize, &g_AdapterList[adapterIndex]->EuNumber, *OutInfoSize); |
| } |
| result = CM_SUCCESS; |
| } |
| else |
| { |
| result = CM_INVALID_ARG_VALUE; |
| } |
| break; |
| |
| case TileNumber: |
| if (g_AdapterList[adapterIndex]->MaxThread == 0) |
| result = GetPlatformInfo(adapterIndex); |
| |
| if (infoSize >= sizeof(g_AdapterList[adapterIndex]->TileNumber)) |
| { |
| *OutInfoSize = (uint32_t)sizeof(g_AdapterList[adapterIndex]->TileNumber); |
| if (info != &g_AdapterList[adapterIndex]->TileNumber) |
| { |
| memcpy_s(info, infoSize, &g_AdapterList[adapterIndex]->TileNumber, *OutInfoSize); |
| } |
| result = CM_SUCCESS; |
| } |
| else |
| { |
| result = CM_INVALID_ARG_VALUE; |
| } |
| break; |
| |
| default: |
| // unknown Info name |
| result = CM_INVALID_ARG_VALUE; |
| break; |
| } |
| } |
| return result; |
| } |
| int32_t CmDevice_RT::Create(CmDevice_RT* &device, uint32_t createOption) |
| { |
| INSERT_PROFILER_RECORD(); |
| |
| int32_t result = CM_SUCCESS; |
| uint32_t count = 0; |
| |
| if (g_AdapterCount == 0 ) |
| { |
| result = GetSupportedAdapters(count); |
| } |
| |
| if (g_supportedAdapterCount > 0) |
| { |
| // start from first supported GPU |
| uint32_t Index = 0; |
| device = new CmDevice_RT(nullptr, createOption); |
| |
| if (CM_DEVICE_CREATE_OPTION_DEFAULT != createOption) |
| // select last supported GPU |
| Index = g_supportedAdapterCount - 1; |
| |
| if (device) |
| { |
| result = device->Initialize(true, Index); |
| if (result != CM_SUCCESS) |
| { |
| CmAssert(0); |
| Destroy(device); |
| } |
| } |
| else |
| { |
| CmAssert(0); |
| result = CM_OUT_OF_HOST_MEMORY; |
| } |
| } |
| else |
| result = CM_NO_SUPPORTED_ADAPTER; |
| |
| return result; |
| } |
| |
| |
| int32_t CmDevice_RT::Create(VADisplay &vaDisplay, CmDevice_RT* &device, uint32_t createOption) |
| { |
| INSERT_PROFILER_RECORD(); |
| |
| int32_t result = CM_FAILURE; |
| device = new (std::nothrow) CmDevice_RT(vaDisplay, createOption); |
| if (device) |
| { |
| result = device->Initialize(false); |
| if (result != CM_SUCCESS) |
| { |
| Destroy(device); |
| } |
| } |
| else |
| { |
| CmAssert(0); |
| result = CM_OUT_OF_HOST_MEMORY; |
| } |
| |
| // leave critical section |
| return result; |
| } |
| |
| int32_t CmDevice_RT::Destroy(CmDevice_RT* &device) |
| { |
| if (device == nullptr) |
| { |
| return CM_FAILURE; |
| } |
| |
| // Destroy the cm device object |
| device->FreeResources(); |
| |
| //Destroy the Device at CMRT@UMD |
| CM_DESTROYCMDEVICE_PARAM destroyCmDeviceParam; |
| CmSafeMemSet(&destroyCmDeviceParam, 0, sizeof(CM_DESTROYCMDEVICE_PARAM)); |
| destroyCmDeviceParam.cmDeviceHandle = device->m_deviceInUmd; |
| uint32_t inputDataLen = sizeof(CM_DESTROYCMDEVICE_PARAM); |
| |
| int32_t result = device->OSALExtensionExecute(CM_FN_DESTROYCMDEVICE, |
| &destroyCmDeviceParam, |
| inputDataLen); |
| |
| CmSafeRelease(device); |
| CHK_FAILURE_RETURN(result); |
| |
| // leave critical section |
| return destroyCmDeviceParam.returnValue; |
| } |
| |
| CmDevice_RT::CmDevice_RT( |
| VADisplay vaDisplay, |
| uint32_t createOption |
| ) : |
| m_cmVersion(0), |
| m_deviceInUmd(nullptr), |
| m_cmCreated(true), |
| m_vaDisplay(vaDisplay), |
| #ifdef ANDROID |
| m_display(nullptr), |
| #endif |
| m_drmIndex(0), |
| m_fvaCmExtSendReqMsg(nullptr), |
| m_gtpinEnabled(false), |
| m_gtpinBufferUP0(nullptr), |
| m_gtpinBufferUP1(nullptr), |
| m_gtpinBufferUP2(nullptr), |
| m_createOption(createOption), |
| m_driverStoreEnabled(0), |
| m_driFileDescriptor(0) |
| { |
| |
| // New Surface Manager |
| m_surfaceManager = new CmSurfaceManager(this); |
| |
| // New Kernel Debugger |
| m_kernelDebugger = CmExtensionCreator<CmKernelDebugger>::CreateClass(); |
| |
| //Initialize L3 cache config |
| CmSafeMemSet(&m_l3Config, 0, sizeof(L3ConfigRegisterValues)); |
| |
| } |
| |
| CmDevice_RT::~CmDevice_RT(void) |
| { |
| if (m_cmCreated) |
| { |
| vaTerminate(m_vaDisplay); |
| #ifndef ANDROID |
| FreeLibvaDrm(); |
| #else |
| free(m_display); //Android |
| #endif |
| } |
| |
| if (m_kernelDebugger != nullptr) |
| { |
| delete m_kernelDebugger; |
| } |
| } |
| |
| int32_t CmDevice_RT::FreeResources() |
| { |
| //Destroy Queue |
| m_criticalSectionQueue.Acquire(); |
| for (auto iter = m_queue.begin(); iter != m_queue.end();) |
| { |
| if (*iter != nullptr) |
| { |
| CmQueue_RT::Destroy(*iter); |
| } |
| iter = m_queue.erase(iter); |
| } |
| m_criticalSectionQueue.Release(); |
| |
| //Destroy GTPin Used BufferUp |
| if (m_gtpinBufferUP0 != nullptr) |
| { |
| DestroyBufferUP(m_gtpinBufferUP0); |
| } |
| |
| if (m_gtpinBufferUP1 != nullptr) |
| { |
| DestroyBufferUP(m_gtpinBufferUP1); |
| } |
| |
| if (m_gtpinBufferUP2 != nullptr) |
| { |
| DestroyBufferUP(m_gtpinBufferUP2); |
| } |
| |
| CmSafeRelease(m_surfaceManager); |
| |
| return CM_SUCCESS; |
| } |
| |
| static int32_t CmrtVaSurfaceRelease(void *vaDisplay, void *vaSurface) |
| { |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| VADisplay *display = (VADisplay *)(vaDisplay); |
| |
| //Destroy VaSurface |
| vaStatus = vaDestroySurfaces(*display, (VASurfaceID *)vaSurface, 1); |
| |
| return vaStatus; |
| } |
| |
| int32_t CmDevice_RT::Initialize(bool isCmCreated, uint32_t Index) |
| { |
| int32_t result = CM_SUCCESS; |
| |
| m_cmCreated = isCmCreated; |
| |
| CLock locker(gDeviceCreationCriticalSection); |
| |
| CHK_RET(InitializeLibvaDisplay(Index)); |
| |
| CHK_RET(CreateDeviceInUmd()); |
| |
| CHK_RET(CheckDdiVersionSupported(m_cmVersion)); |
| |
| #if USE_EXTENSION_CODE |
| if (GTpinVariables.GTPinEnabled) |
| { |
| CHK_RET(EnableGtpin()); |
| CHK_RET(RegisterGtpinMarkerFunctions()); |
| |
| } |
| #endif |
| if (m_kernelDebugger != nullptr) |
| { |
| m_kernelDebugger->NotifyNewDevice(this, m_deviceInUmd, m_driverStoreEnabled); |
| } |
| |
| finish: |
| return result; |
| } |
| |
| int32_t CmDevice_RT::CreateDeviceInUmd() |
| { |
| CmDeviceCreationParam createCmDeviceParam; |
| CmSafeMemSet(&createCmDeviceParam, 0, sizeof(createCmDeviceParam)); |
| createCmDeviceParam.returnValue = CM_FAILURE; |
| createCmDeviceParam.createOption = m_createOption; |
| createCmDeviceParam.releaseSurfaceFunc = &CmrtVaSurfaceRelease; |
| uint32_t inputDataLen = sizeof(createCmDeviceParam); |
| |
| int32_t result = OSALExtensionExecute(CM_FN_CREATECMDEVICE, |
| &createCmDeviceParam, inputDataLen); |
| |
| CHK_FAILURE_RETURN(result); |
| CHK_FAILURE_RETURN(createCmDeviceParam.returnValue); |
| |
| m_cmVersion = createCmDeviceParam.version; |
| m_deviceInUmd = createCmDeviceParam.deviceHandleInUmd; |
| m_driverStoreEnabled = createCmDeviceParam.driverStoreEnabled; |
| return CM_SUCCESS; |
| } |
| |
| //! |
| //! Create Libva Surface and wrap it as a CmSurface |
| //! It is CALLER's responsibility to allocation memory for all pointers to CmSurface2D |
| //! Input : |
| //! 1) Surface's width [in] |
| //! 2) Surface's height [in] |
| //! 3) Surface's format [in] |
| //! 4) Reference to created VASurfaceID [out] |
| //! 5) Reference to pointer of created Cm Surface [out] |
| //! Output: |
| //! CM_SUCCESS if all CmSurface2D are successfully created; |
| //! CM_VA_SURFACE_NOT_SUPPORTED if libva surface creation fail; |
| //! CM_FAILURE otherwise; |
| CM_RT_API int32_t CmDevice_RT::CreateVaSurface2D(uint32_t width, uint32_t height, CM_SURFACE_FORMAT format, VASurfaceID &vaSurface, CmSurface2D* &surface) |
| { |
| INSERT_PROFILER_RECORD(); |
| |
| return m_surfaceManager->CreateVaSurface2D(width, height, format, vaSurface, surface); |
| } |
| |
| //! |
| //! |
| //! Create a CmSurface2D from an existing LIBVA surface |
| //! Input : |
| //! Reference to the pointer to the CmSurface2D . |
| //! VASurfaceID |
| //! Output: |
| //! CM_SUCCESS if the CmSurface2D are successfully created; |
| //! CM_OUT_OF_HOST_MEMORY if out of system memory; |
| //! CM_FAILURE otherwise; |
| //! |
| CM_RT_API int32_t CmDevice_RT::CreateSurface2D(VASurfaceID vaSurface, CmSurface2D* &surface) |
| { |
| INSERT_PROFILER_RECORD(); |
| |
| return m_surfaceManager->CreateSurface2D(vaSurface, surface); |
| } |
| |
| //! |
| //! Create an array of CmSurface2D from an existing array of LIBVA surfaces, which are created by LIBVA's vaCreateSurfaces |
| //! It is CALLER's responsibility to allocation memory for all pointers to CmSurface2D |
| //! Input : |
| //! 1) Pointer to the array of pointers pointing to LIBVA surface |
| //! 2) array size |
| //! 3) Pointer to the array of pointers pointing to CmSurface2D . |
| //! Output: |
| //! CM_SUCCESS if all CmSurface2D are successfully created; |
| //! CM_OUT_OF_HOST_MEMORY if out of system memory; |
| //! CM_FAILURE otherwise; |
| CM_RT_API int32_t CmDevice_RT::CreateSurface2D(VASurfaceID* vaSurfaceArray, const uint32_t surfaceCount, CmSurface2D** surfaceArray) |
| { |
| INSERT_PROFILER_RECORD(); |
| |
| return m_surfaceManager->CreateSurface2D(vaSurfaceArray, surfaceCount, surfaceArray); |
| } |
| |
| int32_t CmDevice_RT::OSALExtensionExecute(uint32_t functionId, |
| void *inputData, |
| uint32_t inputDataLength, |
| void **resourceList, |
| uint32_t resourceCount) |
| { |
| CmAssert(inputData); |
| |
| // uint32_t functionId = functionId; |
| // void* inputData = pInputData; |
| // uint32_t inputDataLen = iInputDataLen; |
| |
| void* outputData = m_deviceInUmd; // pass cm device handle to umd |
| uint32_t outputDataLen = sizeof(m_deviceInUmd); |
| uint32_t vaModuleId = VAExtModuleCMRT; |
| VAStatus hr = VA_STATUS_SUCCESS; |
| |
| if (m_fvaCmExtSendReqMsg != nullptr) |
| { |
| hr = m_fvaCmExtSendReqMsg(m_vaDisplay, &vaModuleId, &functionId, inputData, &inputDataLength, 0, outputData, &outputDataLen); |
| } |
| return hr; |
| } |
| |
| //Initalize LibVA's VADisplay by supported dri device list index |
| int32_t CmDevice_RT::InitializeLibvaDisplay(uint32_t Index) |
| { |
| if (m_cmCreated) |
| { |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| int vaMajorVersion, vaMinorVersion; |
| m_drmIndex = Index; |
| |
| #ifndef ANDROID |
| int32_t ret = GetLibvaDisplayDrm(m_vaDisplay); |
| if (ret != CM_SUCCESS) |
| { |
| CmAssert(0); |
| return ret; |
| } |
| #else |
| m_display = (Display*)malloc(sizeof(Display)); |
| if (m_display == nullptr) |
| { |
| fprintf(stderr, "Can't connect X server!\n"); |
| return CM_INVALID_LIBVA_INITIALIZE; |
| } |
| |
| *(m_display) = ANDROID_DISPLAY; |
| m_vaDisplay = vaGetDisplay(m_display); |
| if (m_vaDisplay == nullptr) |
| { |
| return CM_INVALID_LIBVA_INITIALIZE; |
| } |
| #endif //ANDROID |
| |
| vaStatus = vaInitialize(m_vaDisplay, &vaMajorVersion, &vaMinorVersion); |
| if (VA_STATUS_SUCCESS != vaStatus) { |
| return CM_INVALID_LIBVA_INITIALIZE; |
| } |
| } |
| |
| m_fvaCmExtSendReqMsg = (pvaCmExtSendReqMsg)vaGetLibFunc(m_vaDisplay, "vaCmExtSendReqMsg"); |
| |
| if (m_fvaCmExtSendReqMsg == nullptr) { |
| fprintf(stderr, "Cannot get function of m_fvaCmExtSendReqMsg!\n"); |
| return CM_INVALID_LIBVA_INITIALIZE; |
| } |
| else |
| { |
| return CM_SUCCESS; |
| } |
| } |
| |
| CM_RT_API int32_t CmDevice_RT::GetVaDpy(VADisplay* & vaDpy) |
| { |
| INSERT_PROFILER_RECORD(); |
| |
| vaDpy = &m_vaDisplay; |
| return CM_SUCCESS; |
| } |
| |
| #ifndef ANDROID |
| int32_t CmDevice_RT::GetLibvaDisplayDrm(VADisplay & vaDisplay) |
| { |
| pfVAGetDisplayDRM vaGetDisplayDRM = nullptr; |
| char *dlSymErr = nullptr; |
| void *hLibVaDRM = nullptr; |
| |
| CLock locker(m_vaReferenceCountCriticalSection); |
| |
| if (m_vaReferenceCount > 0) |
| { |
| vaGetDisplayDRM = m_vaGetDisplayDrm; |
| m_vaReferenceCount++; |
| } |
| else |
| { |
| //Load libva-drm.so |
| dlerror(); |
| hLibVaDRM = dlopen("libva-drm.so", RTLD_LAZY); |
| |
| if (!hLibVaDRM) |
| { |
| if ((dlSymErr = dlerror()) != nullptr) |
| { |
| fprintf(stderr, "%s\n", dlSymErr); |
| } |
| return CM_INVALID_LIBVA_INITIALIZE; |
| } |
| |
| //dynamically load function vaGetDisplayDRM from libva-drm.so |
| dlerror(); |
| vaGetDisplayDRM = (pfVAGetDisplayDRM)dlsym(hLibVaDRM, "vaGetDisplayDRM"); |
| if ((dlSymErr = dlerror()) != nullptr) { |
| fprintf(stderr, "%s\n", dlSymErr); |
| return CM_INVALID_LIBVA_INITIALIZE; |
| } |
| |
| m_vaReferenceCount++; |
| m_vaDrm = hLibVaDRM; |
| m_vaGetDisplayDrm = vaGetDisplayDRM; |
| } |
| |
| // open the GPU device |
| if (g_supportedAdapterCount < 1) |
| { |
| fprintf(stderr, "No supported Intel GPU device file node detected\n"); |
| return CM_INVALID_LIBVA_INITIALIZE; |
| } |
| |
| if (m_drmIndex < g_supportedAdapterCount) |
| { |
| m_driFileDescriptor = GetRendererFileDescriptor(g_AdapterList[m_drmIndex]->nodes[2]); |
| } |
| else |
| { |
| fprintf(stderr, "Invalid drm list index used\n"); |
| return CM_INVALID_LIBVA_INITIALIZE; |
| } |
| |
| if (m_driFileDescriptor < 0) |
| { |
| fprintf(stderr, "Failed to open GPU device file node\n"); |
| return CM_INVALID_LIBVA_INITIALIZE; |
| } |
| |
| if (m_vaGetDisplayDrm == nullptr) |
| { |
| fprintf(stderr, "m_vaGetDisplayDrm should not be nullptr.\n"); |
| return CM_INVALID_LIBVA_INITIALIZE; |
| } |
| |
| // get the display handle. |
| if (vaGetDisplayDRM == nullptr) |
| { |
| fprintf(stderr, "vaGetDisplayDRM should not be nullptr.\n"); |
| return CM_INVALID_LIBVA_INITIALIZE; |
| } |
| vaDisplay = vaGetDisplayDRM(m_driFileDescriptor); |
| |
| return CM_SUCCESS; |
| } |
| |
| int32_t CmDevice_RT::FreeLibvaDrm() |
| { |
| CLock locker(m_vaReferenceCountCriticalSection); |
| if (m_vaReferenceCount > 1) |
| { |
| m_vaReferenceCount--; |
| } |
| else |
| { |
| dlclose(m_vaDrm); |
| m_vaDrm = nullptr; |
| m_vaGetDisplayDrm = nullptr; |
| |
| m_vaReferenceCount--; |
| } |
| |
| if (m_driFileDescriptor != -1) |
| { |
| close(m_driFileDescriptor); |
| m_driFileDescriptor = -1; |
| } |
| return CM_SUCCESS; |
| } |
| #endif |
| |