208 lines
6.0 KiB
C++
208 lines
6.0 KiB
C++
/*-------------------------------------------------------------------------
|
|
* 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 <fcntl.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#if !defined(__FreeBSD__)
|
|
// major() and minor() are defined in sys/types.h on FreeBSD, and in
|
|
// sys/sysmacros.h on Linux and Solaris.
|
|
#include <sys/sysmacros.h>
|
|
#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, deInt64 major, deInt64 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, deUint32 connectorId) const
|
|
{
|
|
return ConnectorPtr(pGetConnector(fd, connectorId), pFreeConnector);
|
|
}
|
|
|
|
LibDrm::EncoderPtr LibDrm::getEncoder (int fd, deUint32 encoderId) const
|
|
{
|
|
return EncoderPtr(pGetEncoder(fd, encoderId), pFreeEncoder);
|
|
}
|
|
|
|
LibDrm::FdPtr LibDrm::createLease (int fd, const deUint32 *objects, int numObjects, int flags) const
|
|
{
|
|
deUint32 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
|
|
};
|
|
|
|
} // tcu
|
|
|
|
#endif // DEQP_SUPPORT_DRM && !defined (CTS_USES_VULKANSC)
|