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