xref: /aosp_15_r20/external/deqp/framework/common/tcuLibDrm.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * Vulkan Conformance Tests
3*35238bceSAndroid Build Coastguard Worker  * ------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright (c) 2022 NVIDIA, Inc.
6*35238bceSAndroid Build Coastguard Worker  * Copyright (c) 2022 The Khronos Group Inc.
7*35238bceSAndroid Build Coastguard Worker  *
8*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
9*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
10*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
11*35238bceSAndroid Build Coastguard Worker  *
12*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
13*35238bceSAndroid Build Coastguard Worker  *
14*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
15*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
16*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
18*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
19*35238bceSAndroid Build Coastguard Worker  *
20*35238bceSAndroid Build Coastguard Worker  *//*!
21*35238bceSAndroid Build Coastguard Worker * \file
22*35238bceSAndroid Build Coastguard Worker * \brief Drm utilities.
23*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
24*35238bceSAndroid Build Coastguard Worker 
25*35238bceSAndroid Build Coastguard Worker #if DEQP_SUPPORT_DRM && !defined(CTS_USES_VULKANSC)
26*35238bceSAndroid Build Coastguard Worker 
27*35238bceSAndroid Build Coastguard Worker #include "tcuLibDrm.hpp"
28*35238bceSAndroid Build Coastguard Worker 
29*35238bceSAndroid Build Coastguard Worker #include "tcuDefs.hpp"
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker #include <fcntl.h>
34*35238bceSAndroid Build Coastguard Worker #include <sys/types.h>
35*35238bceSAndroid Build Coastguard Worker #include <sys/stat.h>
36*35238bceSAndroid Build Coastguard Worker #include <unistd.h>
37*35238bceSAndroid Build Coastguard Worker 
38*35238bceSAndroid Build Coastguard Worker #if !defined(__FreeBSD__)
39*35238bceSAndroid Build Coastguard Worker // major() and minor() are defined in sys/types.h on FreeBSD, and in
40*35238bceSAndroid Build Coastguard Worker // sys/sysmacros.h on Linux and Solaris.
41*35238bceSAndroid Build Coastguard Worker #include <sys/sysmacros.h>
42*35238bceSAndroid Build Coastguard Worker #endif // !defined(__FreeBSD__)
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker namespace tcu
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker 
LibDrm(void)47*35238bceSAndroid Build Coastguard Worker LibDrm::LibDrm(void) : DynamicLibrary(libDrmFiles)
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker     pGetDevices2   = (PFNDRMGETDEVICES2PROC)getFunction("drmGetDevices2");
50*35238bceSAndroid Build Coastguard Worker     pGetDevices    = (PFNDRMGETDEVICESPROC)getFunction("drmGetDevices");
51*35238bceSAndroid Build Coastguard Worker     pFreeDevices   = (PFNDRMFREEDEVICESPROC)getFunction("drmFreeDevices");
52*35238bceSAndroid Build Coastguard Worker     pGetResources  = (PFNDRMMODEGETRESOURCESPROC)getFunction("drmModeGetResources");
53*35238bceSAndroid Build Coastguard Worker     pFreeResources = (PFNDRMMODEFREERESOURCESPROC)getFunction("drmModeFreeResources");
54*35238bceSAndroid Build Coastguard Worker     pGetConnector  = (PFNDRMMODEGETCONNECTORPROC)getFunction("drmModeGetConnector");
55*35238bceSAndroid Build Coastguard Worker     pFreeConnector = (PFNDRMMODEFREECONNECTORPROC)getFunction("drmModeFreeConnector");
56*35238bceSAndroid Build Coastguard Worker     pGetEncoder    = (PFNDRMMODEGETENCODERPROC)getFunction("drmModeGetEncoder");
57*35238bceSAndroid Build Coastguard Worker     pFreeEncoder   = (PFNDRMMODEFREEENCODERPROC)getFunction("drmModeFreeEncoder");
58*35238bceSAndroid Build Coastguard Worker     pCreateLease   = (PFNDRMMODECREATELEASEPROC)getFunction("drmModeCreateLease");
59*35238bceSAndroid Build Coastguard Worker     pAuthMagic     = (PFNDRMAUTHMAGIC)getFunction("drmAuthMagic");
60*35238bceSAndroid Build Coastguard Worker 
61*35238bceSAndroid Build Coastguard Worker     /* libdrm did not add this API until 2.4.65, return NotSupported if it's too old. */
62*35238bceSAndroid Build Coastguard Worker     if (!pGetDevices2 && !pGetDevices)
63*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Could not load a valid drmGetDevices() variant from libdrm");
64*35238bceSAndroid Build Coastguard Worker     if (!pFreeDevices)
65*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Could not load drmFreeDevices() from libdrm");
66*35238bceSAndroid Build Coastguard Worker     if (!pGetResources)
67*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Could not load drmModeGetResources() from libdrm");
68*35238bceSAndroid Build Coastguard Worker     if (!pFreeResources)
69*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Could not load drmModeFreeResources() from libdrm");
70*35238bceSAndroid Build Coastguard Worker     if (!pGetConnector)
71*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Could not load drmModeGetConnector() from libdrm");
72*35238bceSAndroid Build Coastguard Worker     if (!pFreeConnector)
73*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Could not load drmModeFreeConnector() from libdrm");
74*35238bceSAndroid Build Coastguard Worker     if (!pGetEncoder)
75*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Could not load drmModeGetEncoder() from libdrm");
76*35238bceSAndroid Build Coastguard Worker     if (!pFreeEncoder)
77*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Could not load drmModeFreeEncoder() from libdrm");
78*35238bceSAndroid Build Coastguard Worker     if (!pCreateLease)
79*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Could not load drmModeCreateLease() from libdrm");
80*35238bceSAndroid Build Coastguard Worker     if (!pAuthMagic)
81*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Could not load drmAuthMagic() from libdrm");
82*35238bceSAndroid Build Coastguard Worker }
83*35238bceSAndroid Build Coastguard Worker 
~LibDrm(void)84*35238bceSAndroid Build Coastguard Worker LibDrm::~LibDrm(void)
85*35238bceSAndroid Build Coastguard Worker {
86*35238bceSAndroid Build Coastguard Worker }
87*35238bceSAndroid Build Coastguard Worker 
getDevices(int * pNumDevices) const88*35238bceSAndroid Build Coastguard Worker drmDevicePtr *LibDrm::getDevices(int *pNumDevices) const
89*35238bceSAndroid Build Coastguard Worker {
90*35238bceSAndroid Build Coastguard Worker     *pNumDevices = intGetDevices(DE_NULL, 0);
91*35238bceSAndroid Build Coastguard Worker 
92*35238bceSAndroid Build Coastguard Worker     if (*pNumDevices < 0)
93*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Failed to query number of DRM devices in system");
94*35238bceSAndroid Build Coastguard Worker 
95*35238bceSAndroid Build Coastguard Worker     if (*pNumDevices == 0)
96*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
97*35238bceSAndroid Build Coastguard Worker 
98*35238bceSAndroid Build Coastguard Worker     drmDevicePtr *devs = new drmDevicePtr[*pNumDevices];
99*35238bceSAndroid Build Coastguard Worker 
100*35238bceSAndroid Build Coastguard Worker     *pNumDevices = intGetDevices(devs, *pNumDevices);
101*35238bceSAndroid Build Coastguard Worker 
102*35238bceSAndroid Build Coastguard Worker     if (*pNumDevices < 0)
103*35238bceSAndroid Build Coastguard Worker     {
104*35238bceSAndroid Build Coastguard Worker         delete[] devs;
105*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Failed to query list of DRM devices in system");
106*35238bceSAndroid Build Coastguard Worker     }
107*35238bceSAndroid Build Coastguard Worker 
108*35238bceSAndroid Build Coastguard Worker     return devs;
109*35238bceSAndroid Build Coastguard Worker }
110*35238bceSAndroid Build Coastguard Worker 
findDeviceNode(drmDevicePtr * devices,int count,int64_t major,int64_t minor) const111*35238bceSAndroid Build Coastguard Worker const char *LibDrm::findDeviceNode(drmDevicePtr *devices, int count, int64_t major, int64_t minor) const
112*35238bceSAndroid Build Coastguard Worker {
113*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < count; i++)
114*35238bceSAndroid Build Coastguard Worker     {
115*35238bceSAndroid Build Coastguard Worker         for (int j = 0; j < DRM_NODE_MAX; j++)
116*35238bceSAndroid Build Coastguard Worker         {
117*35238bceSAndroid Build Coastguard Worker             if (!(devices[i]->available_nodes & (1 << j)))
118*35238bceSAndroid Build Coastguard Worker                 continue;
119*35238bceSAndroid Build Coastguard Worker 
120*35238bceSAndroid Build Coastguard Worker             struct stat statBuf;
121*35238bceSAndroid Build Coastguard Worker             deMemset(&statBuf, 0, sizeof(statBuf));
122*35238bceSAndroid Build Coastguard Worker             int res = stat(devices[i]->nodes[j], &statBuf);
123*35238bceSAndroid Build Coastguard Worker 
124*35238bceSAndroid Build Coastguard Worker             if (res || !(statBuf.st_mode & S_IFCHR))
125*35238bceSAndroid Build Coastguard Worker                 continue;
126*35238bceSAndroid Build Coastguard Worker 
127*35238bceSAndroid Build Coastguard Worker             if (major == major(statBuf.st_rdev) && minor == minor(statBuf.st_rdev))
128*35238bceSAndroid Build Coastguard Worker             {
129*35238bceSAndroid Build Coastguard Worker                 return devices[i]->nodes[j];
130*35238bceSAndroid Build Coastguard Worker             }
131*35238bceSAndroid Build Coastguard Worker         }
132*35238bceSAndroid Build Coastguard Worker     }
133*35238bceSAndroid Build Coastguard Worker 
134*35238bceSAndroid Build Coastguard Worker     return DE_NULL;
135*35238bceSAndroid Build Coastguard Worker }
136*35238bceSAndroid Build Coastguard Worker 
freeDevices(drmDevicePtr * devices,int count) const137*35238bceSAndroid Build Coastguard Worker void LibDrm::freeDevices(drmDevicePtr *devices, int count) const
138*35238bceSAndroid Build Coastguard Worker {
139*35238bceSAndroid Build Coastguard Worker     pFreeDevices(devices, count);
140*35238bceSAndroid Build Coastguard Worker     delete[] devices;
141*35238bceSAndroid Build Coastguard Worker }
142*35238bceSAndroid Build Coastguard Worker 
closeAndDeleteFd(int * fd)143*35238bceSAndroid Build Coastguard Worker static void closeAndDeleteFd(int *fd)
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker     if (fd)
146*35238bceSAndroid Build Coastguard Worker     {
147*35238bceSAndroid Build Coastguard Worker         close(*fd);
148*35238bceSAndroid Build Coastguard Worker         delete fd;
149*35238bceSAndroid Build Coastguard Worker     }
150*35238bceSAndroid Build Coastguard Worker }
151*35238bceSAndroid Build Coastguard Worker 
openFd(const char * node) const152*35238bceSAndroid Build Coastguard Worker LibDrm::FdPtr LibDrm::openFd(const char *node) const
153*35238bceSAndroid Build Coastguard Worker {
154*35238bceSAndroid Build Coastguard Worker     int fd = open(node, O_RDWR);
155*35238bceSAndroid Build Coastguard Worker     if (fd < 0)
156*35238bceSAndroid Build Coastguard Worker         return FdPtr(DE_NULL);
157*35238bceSAndroid Build Coastguard Worker     else
158*35238bceSAndroid Build Coastguard Worker         return FdPtr(new int{fd}, closeAndDeleteFd);
159*35238bceSAndroid Build Coastguard Worker }
160*35238bceSAndroid Build Coastguard Worker 
getResources(int fd) const161*35238bceSAndroid Build Coastguard Worker LibDrm::ResPtr LibDrm::getResources(int fd) const
162*35238bceSAndroid Build Coastguard Worker {
163*35238bceSAndroid Build Coastguard Worker     return ResPtr(pGetResources(fd), pFreeResources);
164*35238bceSAndroid Build Coastguard Worker }
165*35238bceSAndroid Build Coastguard Worker 
getConnector(int fd,uint32_t connectorId) const166*35238bceSAndroid Build Coastguard Worker LibDrm::ConnectorPtr LibDrm::getConnector(int fd, uint32_t connectorId) const
167*35238bceSAndroid Build Coastguard Worker {
168*35238bceSAndroid Build Coastguard Worker     return ConnectorPtr(pGetConnector(fd, connectorId), pFreeConnector);
169*35238bceSAndroid Build Coastguard Worker }
170*35238bceSAndroid Build Coastguard Worker 
getEncoder(int fd,uint32_t encoderId) const171*35238bceSAndroid Build Coastguard Worker LibDrm::EncoderPtr LibDrm::getEncoder(int fd, uint32_t encoderId) const
172*35238bceSAndroid Build Coastguard Worker {
173*35238bceSAndroid Build Coastguard Worker     return EncoderPtr(pGetEncoder(fd, encoderId), pFreeEncoder);
174*35238bceSAndroid Build Coastguard Worker }
175*35238bceSAndroid Build Coastguard Worker 
createLease(int fd,const uint32_t * objects,int numObjects,int flags) const176*35238bceSAndroid Build Coastguard Worker LibDrm::FdPtr LibDrm::createLease(int fd, const uint32_t *objects, int numObjects, int flags) const
177*35238bceSAndroid Build Coastguard Worker {
178*35238bceSAndroid Build Coastguard Worker     uint32_t leaseId;
179*35238bceSAndroid Build Coastguard Worker     int leaseFd = pCreateLease(fd, objects, numObjects, flags, &leaseId);
180*35238bceSAndroid Build Coastguard Worker     if (leaseFd < 0)
181*35238bceSAndroid Build Coastguard Worker         return FdPtr(DE_NULL);
182*35238bceSAndroid Build Coastguard Worker     else
183*35238bceSAndroid Build Coastguard Worker         return FdPtr(new int{leaseFd}, closeAndDeleteFd);
184*35238bceSAndroid Build Coastguard Worker }
185*35238bceSAndroid Build Coastguard Worker 
authMagic(int fd,drm_magic_t magic) const186*35238bceSAndroid Build Coastguard Worker int LibDrm::authMagic(int fd, drm_magic_t magic) const
187*35238bceSAndroid Build Coastguard Worker {
188*35238bceSAndroid Build Coastguard Worker     return pAuthMagic(fd, magic);
189*35238bceSAndroid Build Coastguard Worker }
190*35238bceSAndroid Build Coastguard Worker 
intGetDevices(drmDevicePtr devices[],int maxDevices) const191*35238bceSAndroid Build Coastguard Worker int LibDrm::intGetDevices(drmDevicePtr devices[], int maxDevices) const
192*35238bceSAndroid Build Coastguard Worker {
193*35238bceSAndroid Build Coastguard Worker     if (pGetDevices2)
194*35238bceSAndroid Build Coastguard Worker         return pGetDevices2(0, devices, maxDevices);
195*35238bceSAndroid Build Coastguard Worker     else
196*35238bceSAndroid Build Coastguard Worker         return pGetDevices(devices, maxDevices);
197*35238bceSAndroid Build Coastguard Worker }
198*35238bceSAndroid Build Coastguard Worker 
199*35238bceSAndroid Build Coastguard Worker const char *LibDrm::libDrmFiles[] = {"libdrm.so.2", "libdrm.so", nullptr};
200*35238bceSAndroid Build Coastguard Worker 
201*35238bceSAndroid Build Coastguard Worker } // namespace tcu
202*35238bceSAndroid Build Coastguard Worker 
203*35238bceSAndroid Build Coastguard Worker #endif // DEQP_SUPPORT_DRM && !defined (CTS_USES_VULKANSC)
204