1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
3 * ----------------------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Linux Vulkan Platform.
22 *//*--------------------------------------------------------------------*/
23
24 #include "tcuLnxVulkanPlatform.hpp"
25 #include "tcuLnxPlatform.hpp"
26 #include "vkWsiPlatform.hpp"
27 #include "gluPlatform.hpp"
28 #include "tcuLnx.hpp"
29 #include "tcuFunctionLibrary.hpp"
30 #include "deUniquePtr.hpp"
31 #include "deMemory.h"
32
33 #include <sys/utsname.h>
34
35 using de::MovePtr;
36 using de::UniquePtr;
37
38 #if defined (DEQP_SUPPORT_X11)
39 # include "tcuLnxX11.hpp"
40 # if defined (DEQP_SUPPORT_XCB)
41 # include "tcuLnxX11Xcb.hpp"
42 # endif // DEQP_SUPPORT_XCB
43 # define X11_DISPLAY ""
44 #endif // DEQP_SUPPORT_X11
45
46 #if defined (DEQP_SUPPORT_WAYLAND)
47 # include "tcuLnxWayland.hpp"
48 # define WAYLAND_DISPLAY DE_NULL
49 #endif // DEQP_SUPPORT_WAYLAND
50
51 namespace tcu
52 {
53 namespace lnx
54 {
55
56 #if defined (DEQP_SUPPORT_X11)
57
58 class VulkanWindowXlib : public vk::wsi::XlibWindowInterface
59 {
60 public:
VulkanWindowXlib(MovePtr<x11::XlibWindow> window)61 VulkanWindowXlib (MovePtr<x11::XlibWindow> window)
62 : vk::wsi::XlibWindowInterface (vk::pt::XlibWindow(window->getXID()))
63 , m_window (window)
64 {
65 }
66
setVisible(bool visible)67 void setVisible(bool visible)
68 {
69 m_window->setVisibility(visible);
70 }
71
resize(const UVec2 & newSize)72 void resize (const UVec2& newSize)
73 {
74 m_window->setDimensions((int)newSize.x(), (int)newSize.y());
75 }
76
77 private:
78 UniquePtr<x11::XlibWindow> m_window;
79 };
80
81 class VulkanDisplayXlib : public vk::wsi::XlibDisplayInterface
82 {
83 public:
VulkanDisplayXlib(MovePtr<x11::DisplayBase> display)84 VulkanDisplayXlib (MovePtr<x11::DisplayBase> display)
85 : vk::wsi::XlibDisplayInterface (vk::pt::XlibDisplayPtr(((x11::XlibDisplay*)display.get())->getXDisplay()))
86 , m_display (display)
87 {
88 }
89
createWindow(const Maybe<UVec2> & initialSize) const90 vk::wsi::Window* createWindow (const Maybe<UVec2>& initialSize) const
91 {
92 x11::XlibDisplay* instance = (x11::XlibDisplay*)(m_display.get());
93 const deUint32 height = !initialSize ? (deUint32)DEFAULT_WINDOW_HEIGHT : initialSize->y();
94 const deUint32 width = !initialSize ? (deUint32)DEFAULT_WINDOW_WIDTH : initialSize->x();
95 return new VulkanWindowXlib(MovePtr<x11::XlibWindow>(new x11::XlibWindow(*instance, (int)width, (int)height, instance->getVisual(0))));
96 }
97
98 private:
99 MovePtr<x11::DisplayBase> m_display;
100 };
101
102 #endif // DEQP_SUPPORT_X11
103
104 #if defined (DEQP_SUPPORT_XCB)
105
106 class VulkanWindowXcb : public vk::wsi::XcbWindowInterface
107 {
108 public:
VulkanWindowXcb(MovePtr<x11::XcbWindow> window)109 VulkanWindowXcb (MovePtr<x11::XcbWindow> window)
110 : vk::wsi::XcbWindowInterface (vk::pt::XcbWindow(window->getXID()))
111 , m_window (window)
112 {
113 }
114
setVisible(bool visible)115 void setVisible(bool visible)
116 {
117 m_window->setVisibility(visible);
118 }
119
resize(const UVec2 & newSize)120 void resize (const UVec2& newSize)
121 {
122 m_window->setDimensions((int)newSize.x(), (int)newSize.y());
123 }
124
125 private:
126 UniquePtr<x11::XcbWindow> m_window;
127 };
128
129 class VulkanDisplayXcb : public vk::wsi::XcbDisplayInterface
130 {
131 public:
VulkanDisplayXcb(MovePtr<x11::DisplayBase> display)132 VulkanDisplayXcb (MovePtr<x11::DisplayBase> display)
133 : vk::wsi::XcbDisplayInterface (vk::pt::XcbConnectionPtr(((x11::XcbDisplay*)display.get())->getConnection()))
134 , m_display (display)
135 {
136 }
137
createWindow(const Maybe<UVec2> & initialSize) const138 vk::wsi::Window* createWindow (const Maybe<UVec2>& initialSize) const
139 {
140 x11::XcbDisplay* instance = (x11::XcbDisplay*)(m_display.get());
141 const deUint32 height = !initialSize ? (deUint32)DEFAULT_WINDOW_HEIGHT : initialSize->y();
142 const deUint32 width = !initialSize ? (deUint32)DEFAULT_WINDOW_WIDTH : initialSize->x();
143 return new VulkanWindowXcb(MovePtr<x11::XcbWindow>(new x11::XcbWindow(*instance, (int)width, (int)height, DE_NULL)));
144 }
145
146 private:
147 MovePtr<x11::DisplayBase> m_display;
148 };
149 #endif // DEQP_SUPPORT_XCB
150
151 #if defined (DEQP_SUPPORT_WAYLAND)
152 class VulkanWindowWayland : public vk::wsi::WaylandWindowInterface
153 {
154 public:
VulkanWindowWayland(MovePtr<wayland::Window> window)155 VulkanWindowWayland (MovePtr<wayland::Window> window)
156 : vk::wsi::WaylandWindowInterface (vk::pt::WaylandSurfacePtr(window->getSurface()))
157 , m_window (window)
158 {
159 }
160
setVisible(bool visible)161 void setVisible(bool visible)
162 {
163 m_window->setVisibility(visible);
164 }
165
resize(const UVec2 & newSize)166 void resize (const UVec2& newSize)
167 {
168 m_window->setDimensions((int)newSize.x(), (int)newSize.y());
169 }
170
171 private:
172 UniquePtr<wayland::Window> m_window;
173 };
174
175 class VulkanDisplayWayland : public vk::wsi::WaylandDisplayInterface
176 {
177 public:
VulkanDisplayWayland(MovePtr<wayland::Display> display)178 VulkanDisplayWayland (MovePtr<wayland::Display> display)
179 : vk::wsi::WaylandDisplayInterface (vk::pt::WaylandDisplayPtr(display->getDisplay()))
180 , m_display (display)
181 {
182 }
183
createWindow(const Maybe<UVec2> & initialSize) const184 vk::wsi::Window* createWindow (const Maybe<UVec2>& initialSize) const
185 {
186 const deUint32 height = !initialSize ? (deUint32)DEFAULT_WINDOW_HEIGHT : initialSize->y();
187 const deUint32 width = !initialSize ? (deUint32)DEFAULT_WINDOW_WIDTH : initialSize->x();
188 return new VulkanWindowWayland(MovePtr<wayland::Window>(new wayland::Window(*m_display, (int)width, (int)height)));
189 }
190
191 private:
192 MovePtr<wayland::Display> m_display;
193 };
194 #endif // DEQP_SUPPORT_WAYLAND
195
196 #if defined (DEQP_SUPPORT_HEADLESS)
197
198 struct VulkanWindowHeadless : public vk::wsi::Window
199 {
200 public:
resizetcu::lnx::VulkanWindowHeadless201 void resize (const UVec2&)
202 {
203 }
204 };
205
206 class VulkanDisplayHeadless : public vk::wsi::Display
207 {
208 public:
VulkanDisplayHeadless()209 VulkanDisplayHeadless ()
210 {
211 }
212
createWindow(const Maybe<UVec2> &) const213 vk::wsi::Window* createWindow (const Maybe<UVec2>&) const
214 {
215 return new VulkanWindowHeadless();
216 }
217 };
218
219 #endif // DEQP_SUPPORT_HEADLESS
220
221 class VulkanLibrary : public vk::Library
222 {
223 public:
VulkanLibrary(void)224 VulkanLibrary (void)
225 : m_library ("libvulkan.so.1")
226 , m_driver (m_library)
227 {
228 }
229
getPlatformInterface(void) const230 const vk::PlatformInterface& getPlatformInterface (void) const
231 {
232 return m_driver;
233 }
234
getFunctionLibrary(void) const235 const tcu::FunctionLibrary& getFunctionLibrary (void) const
236 {
237 return m_library;
238 }
239
240 private:
241 const DynamicFunctionLibrary m_library;
242 const vk::PlatformDriver m_driver;
243 };
244
VulkanPlatform(EventState & eventState)245 VulkanPlatform::VulkanPlatform (EventState& eventState)
246 : m_eventState(eventState)
247 {
248 }
249
createWsiDisplay(vk::wsi::Type wsiType) const250 vk::wsi::Display* VulkanPlatform::createWsiDisplay (vk::wsi::Type wsiType) const
251 {
252 if (!hasDisplay(wsiType))
253 {
254 throw NotSupportedError("This display type is not available: ", NULL, __FILE__, __LINE__);
255 }
256
257 switch(wsiType)
258 {
259 #if defined (DEQP_SUPPORT_X11)
260 case vk::wsi::TYPE_XLIB:
261 return new VulkanDisplayXlib(MovePtr<x11::DisplayBase>(new x11::XlibDisplay(m_eventState,X11_DISPLAY)));
262 break;
263 #endif // DEQP_SUPPORT_X11
264 #if defined (DEQP_SUPPORT_XCB)
265 case vk::wsi::TYPE_XCB:
266 return new VulkanDisplayXcb(MovePtr<x11::DisplayBase>(new x11::XcbDisplay(m_eventState,X11_DISPLAY)));
267 break;
268 #endif // DEQP_SUPPORT_XCB
269 #if defined (DEQP_SUPPORT_WAYLAND)
270 case vk::wsi::TYPE_WAYLAND:
271 return new VulkanDisplayWayland(MovePtr<wayland::Display>(new wayland::Display(m_eventState, WAYLAND_DISPLAY)));
272 break;
273 #endif // DEQP_SUPPORT_WAYLAND
274 #if defined (DEQP_SUPPORT_HEADLESS)
275 case vk::wsi::TYPE_HEADLESS:
276 return new VulkanDisplayHeadless();
277 break;
278 #endif // DEQP_SUPPORT_HEADLESS
279
280 default:
281 TCU_THROW(NotSupportedError, "WSI type not supported");
282
283 };
284 }
hasDisplay(vk::wsi::Type wsiType) const285 bool VulkanPlatform::hasDisplay (vk::wsi::Type wsiType) const
286 {
287 switch(wsiType)
288 {
289 #if defined (DEQP_SUPPORT_X11)
290 case vk::wsi::TYPE_XLIB:
291 return x11::XlibDisplay::hasDisplay(X11_DISPLAY);
292 #endif // DEQP_SUPPORT_X11
293 #if defined (DEQP_SUPPORT_XCB)
294 case vk::wsi::TYPE_XCB:
295 return x11::XcbDisplay::hasDisplay(X11_DISPLAY);
296 #endif // DEQP_SUPPORT_XCB
297 #if defined (DEQP_SUPPORT_WAYLAND)
298 case vk::wsi::TYPE_WAYLAND:
299 return wayland::Display::hasDisplay(WAYLAND_DISPLAY);
300 #endif // DEQP_SUPPORT_WAYLAND
301 #if defined (DEQP_SUPPORT_HEADLESS)
302 case vk::wsi::TYPE_HEADLESS:
303 return true;
304 #endif // DEQP_SUPPORT_HEADLESS
305 default:
306 return false;
307
308 };
309 }
createLibrary(void) const310 vk::Library* VulkanPlatform::createLibrary (void) const
311 {
312 return new VulkanLibrary();
313 }
314
describePlatform(std::ostream & dst) const315 void VulkanPlatform::describePlatform (std::ostream& dst) const
316 {
317 utsname sysInfo;
318 deMemset(&sysInfo, 0, sizeof(sysInfo));
319
320 if (uname(&sysInfo) != 0)
321 throw std::runtime_error("uname() failed");
322
323 dst << "OS: " << sysInfo.sysname << " " << sysInfo.release << " " << sysInfo.version << "\n";
324 dst << "CPU: " << sysInfo.machine << "\n";
325 }
326
getMemoryLimits(vk::PlatformMemoryLimits & limits) const327 void VulkanPlatform::getMemoryLimits (vk::PlatformMemoryLimits& limits) const
328 {
329 limits.totalSystemMemory = 256*1024*1024;
330 limits.totalDeviceLocalMemory = 128*1024*1024;
331 limits.deviceMemoryAllocationGranularity = 64*1024;
332 limits.devicePageSize = 4096;
333 limits.devicePageTableEntrySize = 8;
334 limits.devicePageTableHierarchyLevels = 3;
335 }
336
337 } // linux
338 } // tcu
339
340