• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,
94                   "Failed to query number of DRM devices in system");
95 
96     if (*pNumDevices == 0)
97         return DE_NULL;
98 
99     drmDevicePtr *devs = new drmDevicePtr[*pNumDevices];
100 
101     *pNumDevices = intGetDevices(devs, *pNumDevices);
102 
103     if (*pNumDevices < 0) {
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,deInt64 major,deInt64 minor) const111 const char* LibDrm::findDeviceNode (drmDevicePtr *devices, int count, deInt64 major, deInt64 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) &&
128 				minor == minor(statBuf.st_rdev))
129             {
130 				return devices[i]->nodes[j];
131 			}
132 		}
133 	}
134 
135     return DE_NULL;
136 }
137 
freeDevices(drmDevicePtr * devices,int count) const138 void LibDrm::freeDevices (drmDevicePtr *devices, int count) const
139 {
140     pFreeDevices(devices, count);
141     delete[] devices;
142 }
143 
closeAndDeleteFd(int * fd)144 static void closeAndDeleteFd(int* fd) {
145     if (fd) {
146         close(*fd);
147         delete fd;
148     }
149 }
150 
openFd(const char * node) const151 LibDrm::FdPtr LibDrm::openFd (const char* node) const
152 {
153     int fd = open(node, O_RDWR);
154     if (fd < 0)
155         return FdPtr(DE_NULL);
156     else
157         return FdPtr(new int{fd}, closeAndDeleteFd);
158 }
159 
getResources(int fd) const160 LibDrm::ResPtr LibDrm::getResources (int fd) const
161 {
162     return ResPtr(pGetResources(fd), pFreeResources);
163 }
164 
getConnector(int fd,deUint32 connectorId) const165 LibDrm::ConnectorPtr LibDrm::getConnector (int fd, deUint32 connectorId) const
166 {
167     return ConnectorPtr(pGetConnector(fd, connectorId), pFreeConnector);
168 }
169 
getEncoder(int fd,deUint32 encoderId) const170 LibDrm::EncoderPtr LibDrm::getEncoder (int fd, deUint32 encoderId) const
171 {
172     return EncoderPtr(pGetEncoder(fd, encoderId), pFreeEncoder);
173 }
174 
createLease(int fd,const deUint32 * objects,int numObjects,int flags) const175 LibDrm::FdPtr LibDrm::createLease (int fd, const deUint32 *objects, int numObjects, int flags) const
176 {
177     deUint32 leaseId;
178     int leaseFd = pCreateLease(fd, objects, numObjects, flags, &leaseId);
179     if (leaseFd < 0)
180         return FdPtr(DE_NULL);
181     else
182         return FdPtr(new int{leaseFd}, closeAndDeleteFd);
183 }
184 
authMagic(int fd,drm_magic_t magic) const185 int LibDrm::authMagic (int fd, drm_magic_t magic) const
186 {
187     return pAuthMagic(fd, magic);
188 }
189 
intGetDevices(drmDevicePtr devices[],int maxDevices) const190 int LibDrm::intGetDevices (drmDevicePtr devices[], int maxDevices) const
191 {
192     if (pGetDevices2)
193         return pGetDevices2(0, devices, maxDevices);
194     else
195         return pGetDevices(devices, maxDevices);
196 }
197 
198 const char* LibDrm::libDrmFiles[] =
199 {
200 	"libdrm.so.2",
201 	"libdrm.so",
202 	nullptr
203 };
204 
205 } // tcu
206 
207 #endif // DEQP_SUPPORT_DRM && !defined (CTS_USES_VULKANSC)
208