/*------------------------------------------------------------------------- * Vulkan Conformance Tests * ------------------------ * * Copyright (c) 2022 NVIDIA, Inc. * Copyright (c) 2022 The Khronos Group Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Drm utilities. *//*--------------------------------------------------------------------*/ #if DEQP_SUPPORT_DRM && !defined(CTS_USES_VULKANSC) #include "tcuLibDrm.hpp" #include "tcuDefs.hpp" #include "deMemory.h" #include #include #include #include #if !defined(__FreeBSD__) // major() and minor() are defined in sys/types.h on FreeBSD, and in // sys/sysmacros.h on Linux and Solaris. #include #endif // !defined(__FreeBSD__) namespace tcu { LibDrm::LibDrm(void) : DynamicLibrary(libDrmFiles) { pGetDevices2 = (PFNDRMGETDEVICES2PROC)getFunction("drmGetDevices2"); pGetDevices = (PFNDRMGETDEVICESPROC)getFunction("drmGetDevices"); pFreeDevices = (PFNDRMFREEDEVICESPROC)getFunction("drmFreeDevices"); pGetResources = (PFNDRMMODEGETRESOURCESPROC)getFunction("drmModeGetResources"); pFreeResources = (PFNDRMMODEFREERESOURCESPROC)getFunction("drmModeFreeResources"); pGetConnector = (PFNDRMMODEGETCONNECTORPROC)getFunction("drmModeGetConnector"); pFreeConnector = (PFNDRMMODEFREECONNECTORPROC)getFunction("drmModeFreeConnector"); pGetEncoder = (PFNDRMMODEGETENCODERPROC)getFunction("drmModeGetEncoder"); pFreeEncoder = (PFNDRMMODEFREEENCODERPROC)getFunction("drmModeFreeEncoder"); pCreateLease = (PFNDRMMODECREATELEASEPROC)getFunction("drmModeCreateLease"); pAuthMagic = (PFNDRMAUTHMAGIC)getFunction("drmAuthMagic"); /* libdrm did not add this API until 2.4.65, return NotSupported if it's too old. */ if (!pGetDevices2 && !pGetDevices) TCU_THROW(NotSupportedError, "Could not load a valid drmGetDevices() variant from libdrm"); if (!pFreeDevices) TCU_THROW(NotSupportedError, "Could not load drmFreeDevices() from libdrm"); if (!pGetResources) TCU_FAIL("Could not load drmModeGetResources() from libdrm"); if (!pFreeResources) TCU_FAIL("Could not load drmModeFreeResources() from libdrm"); if (!pGetConnector) TCU_FAIL("Could not load drmModeGetConnector() from libdrm"); if (!pFreeConnector) TCU_FAIL("Could not load drmModeFreeConnector() from libdrm"); if (!pGetEncoder) TCU_FAIL("Could not load drmModeGetEncoder() from libdrm"); if (!pFreeEncoder) TCU_FAIL("Could not load drmModeFreeEncoder() from libdrm"); if (!pCreateLease) TCU_FAIL("Could not load drmModeCreateLease() from libdrm"); if (!pAuthMagic) TCU_FAIL("Could not load drmAuthMagic() from libdrm"); } LibDrm::~LibDrm(void) { } drmDevicePtr *LibDrm::getDevices(int *pNumDevices) const { *pNumDevices = intGetDevices(DE_NULL, 0); if (*pNumDevices < 0) TCU_THROW(NotSupportedError, "Failed to query number of DRM devices in system"); if (*pNumDevices == 0) return DE_NULL; drmDevicePtr *devs = new drmDevicePtr[*pNumDevices]; *pNumDevices = intGetDevices(devs, *pNumDevices); if (*pNumDevices < 0) { delete[] devs; TCU_FAIL("Failed to query list of DRM devices in system"); } return devs; } const char *LibDrm::findDeviceNode(drmDevicePtr *devices, int count, int64_t major, int64_t minor) const { for (int i = 0; i < count; i++) { for (int j = 0; j < DRM_NODE_MAX; j++) { if (!(devices[i]->available_nodes & (1 << j))) continue; struct stat statBuf; deMemset(&statBuf, 0, sizeof(statBuf)); int res = stat(devices[i]->nodes[j], &statBuf); if (res || !(statBuf.st_mode & S_IFCHR)) continue; if (major == major(statBuf.st_rdev) && minor == minor(statBuf.st_rdev)) { return devices[i]->nodes[j]; } } } return DE_NULL; } void LibDrm::freeDevices(drmDevicePtr *devices, int count) const { pFreeDevices(devices, count); delete[] devices; } static void closeAndDeleteFd(int *fd) { if (fd) { close(*fd); delete fd; } } LibDrm::FdPtr LibDrm::openFd(const char *node) const { int fd = open(node, O_RDWR); if (fd < 0) return FdPtr(DE_NULL); else return FdPtr(new int{fd}, closeAndDeleteFd); } LibDrm::ResPtr LibDrm::getResources(int fd) const { return ResPtr(pGetResources(fd), pFreeResources); } LibDrm::ConnectorPtr LibDrm::getConnector(int fd, uint32_t connectorId) const { return ConnectorPtr(pGetConnector(fd, connectorId), pFreeConnector); } LibDrm::EncoderPtr LibDrm::getEncoder(int fd, uint32_t encoderId) const { return EncoderPtr(pGetEncoder(fd, encoderId), pFreeEncoder); } LibDrm::FdPtr LibDrm::createLease(int fd, const uint32_t *objects, int numObjects, int flags) const { uint32_t leaseId; int leaseFd = pCreateLease(fd, objects, numObjects, flags, &leaseId); if (leaseFd < 0) return FdPtr(DE_NULL); else return FdPtr(new int{leaseFd}, closeAndDeleteFd); } int LibDrm::authMagic(int fd, drm_magic_t magic) const { return pAuthMagic(fd, magic); } int LibDrm::intGetDevices(drmDevicePtr devices[], int maxDevices) const { if (pGetDevices2) return pGetDevices2(0, devices, maxDevices); else return pGetDevices(devices, maxDevices); } const char *LibDrm::libDrmFiles[] = {"libdrm.so.2", "libdrm.so", nullptr}; } // namespace tcu #endif // DEQP_SUPPORT_DRM && !defined (CTS_USES_VULKANSC)