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
resize(const UVec2 & newSize)67 void resize (const UVec2& newSize)
68 {
69 m_window->setDimensions((int)newSize.x(), (int)newSize.y());
70 }
71
72 private:
73 UniquePtr<x11::XlibWindow> m_window;
74 };
75
76 class VulkanDisplayXlib : public vk::wsi::XlibDisplayInterface
77 {
78 public:
VulkanDisplayXlib(MovePtr<x11::DisplayBase> display)79 VulkanDisplayXlib (MovePtr<x11::DisplayBase> display)
80 : vk::wsi::XlibDisplayInterface (vk::pt::XlibDisplayPtr(((x11::XlibDisplay*)display.get())->getXDisplay()))
81 , m_display (display)
82 {
83 }
84
createWindow(const Maybe<UVec2> & initialSize) const85 vk::wsi::Window* createWindow (const Maybe<UVec2>& initialSize) const
86 {
87 x11::XlibDisplay* instance = (x11::XlibDisplay*)(m_display.get());
88 const deUint32 height = !initialSize ? (deUint32)DEFAULT_WINDOW_HEIGHT : initialSize->y();
89 const deUint32 width = !initialSize ? (deUint32)DEFAULT_WINDOW_WIDTH : initialSize->x();
90 return new VulkanWindowXlib(MovePtr<x11::XlibWindow>(new x11::XlibWindow(*instance, (int)width, (int)height, instance->getVisual(0))));
91 }
92
93 private:
94 MovePtr<x11::DisplayBase> m_display;
95 };
96
97 #endif // DEQP_SUPPORT_X11
98
99 #if defined (DEQP_SUPPORT_XCB)
100
101 class VulkanWindowXcb : public vk::wsi::XcbWindowInterface
102 {
103 public:
VulkanWindowXcb(MovePtr<x11::XcbWindow> window)104 VulkanWindowXcb (MovePtr<x11::XcbWindow> window)
105 : vk::wsi::XcbWindowInterface (vk::pt::XcbWindow(window->getXID()))
106 , m_window (window)
107 {
108 }
109
resize(const UVec2 & newSize)110 void resize (const UVec2& newSize)
111 {
112 m_window->setDimensions((int)newSize.x(), (int)newSize.y());
113 }
114
115 private:
116 UniquePtr<x11::XcbWindow> m_window;
117 };
118
119 class VulkanDisplayXcb : public vk::wsi::XcbDisplayInterface
120 {
121 public:
VulkanDisplayXcb(MovePtr<x11::DisplayBase> display)122 VulkanDisplayXcb (MovePtr<x11::DisplayBase> display)
123 : vk::wsi::XcbDisplayInterface (vk::pt::XcbConnectionPtr(((x11::XcbDisplay*)display.get())->getConnection()))
124 , m_display (display)
125 {
126 }
127
createWindow(const Maybe<UVec2> & initialSize) const128 vk::wsi::Window* createWindow (const Maybe<UVec2>& initialSize) const
129 {
130 x11::XcbDisplay* instance = (x11::XcbDisplay*)(m_display.get());
131 const deUint32 height = !initialSize ? (deUint32)DEFAULT_WINDOW_HEIGHT : initialSize->y();
132 const deUint32 width = !initialSize ? (deUint32)DEFAULT_WINDOW_WIDTH : initialSize->x();
133 return new VulkanWindowXcb(MovePtr<x11::XcbWindow>(new x11::XcbWindow(*instance, (int)width, (int)height, DE_NULL)));
134 }
135
136 private:
137 MovePtr<x11::DisplayBase> m_display;
138 };
139 #endif // DEQP_SUPPORT_XCB
140
141 #if defined (DEQP_SUPPORT_WAYLAND)
142 class VulkanWindowWayland : public vk::wsi::WaylandWindowInterface
143 {
144 public:
VulkanWindowWayland(MovePtr<wayland::Window> window)145 VulkanWindowWayland (MovePtr<wayland::Window> window)
146 : vk::wsi::WaylandWindowInterface (vk::pt::WaylandSurfacePtr(window->getSurface()))
147 , m_window (window)
148 {
149 }
150
resize(const UVec2 & newSize)151 void resize (const UVec2& newSize)
152 {
153 m_window->setDimensions((int)newSize.x(), (int)newSize.y());
154 }
155
156 private:
157 UniquePtr<wayland::Window> m_window;
158 };
159
160 class VulkanDisplayWayland : public vk::wsi::WaylandDisplayInterface
161 {
162 public:
VulkanDisplayWayland(MovePtr<wayland::Display> display)163 VulkanDisplayWayland (MovePtr<wayland::Display> display)
164 : vk::wsi::WaylandDisplayInterface (vk::pt::WaylandDisplayPtr(display->getDisplay()))
165 , m_display (display)
166 {
167 }
168
createWindow(const Maybe<UVec2> & initialSize) const169 vk::wsi::Window* createWindow (const Maybe<UVec2>& initialSize) const
170 {
171 const deUint32 height = !initialSize ? (deUint32)DEFAULT_WINDOW_HEIGHT : initialSize->y();
172 const deUint32 width = !initialSize ? (deUint32)DEFAULT_WINDOW_WIDTH : initialSize->x();
173 return new VulkanWindowWayland(MovePtr<wayland::Window>(new wayland::Window(*m_display, (int)width, (int)height)));
174 }
175
176 private:
177 MovePtr<wayland::Display> m_display;
178 };
179 #endif // DEQP_SUPPORT_WAYLAND
180
181 class VulkanLibrary : public vk::Library
182 {
183 public:
VulkanLibrary(void)184 VulkanLibrary (void)
185 : m_library ("libvulkan.so.1")
186 , m_driver (m_library)
187 {
188 }
189
getPlatformInterface(void) const190 const vk::PlatformInterface& getPlatformInterface (void) const
191 {
192 return m_driver;
193 }
194
getFunctionLibrary(void) const195 const tcu::FunctionLibrary& getFunctionLibrary (void) const
196 {
197 return m_library;
198 }
199
200 private:
201 const DynamicFunctionLibrary m_library;
202 const vk::PlatformDriver m_driver;
203 };
204
VulkanPlatform(EventState & eventState)205 VulkanPlatform::VulkanPlatform (EventState& eventState)
206 : m_eventState(eventState)
207 {
208 }
209
createWsiDisplay(vk::wsi::Type wsiType) const210 vk::wsi::Display* VulkanPlatform::createWsiDisplay (vk::wsi::Type wsiType) const
211 {
212 switch(wsiType)
213 {
214 #if defined (DEQP_SUPPORT_X11)
215 case vk::wsi::TYPE_XLIB:
216 return new VulkanDisplayXlib(MovePtr<x11::DisplayBase>(new x11::XlibDisplay(m_eventState,X11_DISPLAY)));
217 break;
218 #endif // DEQP_SUPPORT_X11
219 #if defined (DEQP_SUPPORT_XCB)
220 case vk::wsi::TYPE_XCB:
221 return new VulkanDisplayXcb(MovePtr<x11::DisplayBase>(new x11::XcbDisplay(m_eventState,X11_DISPLAY)));
222 break;
223 #endif // DEQP_SUPPORT_XCB
224 #if defined (DEQP_SUPPORT_WAYLAND)
225 case vk::wsi::TYPE_WAYLAND:
226 return new VulkanDisplayWayland(MovePtr<wayland::Display>(new wayland::Display(m_eventState, WAYLAND_DISPLAY)));
227 break;
228 #endif // DEQP_SUPPORT_WAYLAND
229
230 default:
231 TCU_THROW(NotSupportedError, "WSI type not supported");
232
233 };
234 }
hasDisplay(vk::wsi::Type wsiType) const235 bool VulkanPlatform::hasDisplay (vk::wsi::Type wsiType) const
236 {
237 switch(wsiType)
238 {
239 #if defined (DEQP_SUPPORT_X11)
240 case vk::wsi::TYPE_XLIB:
241 return x11::XlibDisplay::hasDisplay(X11_DISPLAY);
242 #endif // DEQP_SUPPORT_X11
243 #if defined (DEQP_SUPPORT_XCB)
244 case vk::wsi::TYPE_XCB:
245 return x11::XcbDisplay::hasDisplay(X11_DISPLAY);
246 #endif // DEQP_SUPPORT_XCB
247 #if defined (DEQP_SUPPORT_WAYLAND)
248 case vk::wsi::TYPE_WAYLAND:
249 return wayland::Display::hasDisplay(WAYLAND_DISPLAY);
250 #endif // DEQP_SUPPORT_WAYLAND
251 default:
252 return false;
253
254 };
255 }
createLibrary(void) const256 vk::Library* VulkanPlatform::createLibrary (void) const
257 {
258 return new VulkanLibrary();
259 }
260
describePlatform(std::ostream & dst) const261 void VulkanPlatform::describePlatform (std::ostream& dst) const
262 {
263 utsname sysInfo;
264 deMemset(&sysInfo, 0, sizeof(sysInfo));
265
266 if (uname(&sysInfo) != 0)
267 throw std::runtime_error("uname() failed");
268
269 dst << "OS: " << sysInfo.sysname << " " << sysInfo.release << " " << sysInfo.version << "\n";
270 dst << "CPU: " << sysInfo.machine << "\n";
271 }
272
getMemoryLimits(vk::PlatformMemoryLimits & limits) const273 void VulkanPlatform::getMemoryLimits (vk::PlatformMemoryLimits& limits) const
274 {
275 limits.totalSystemMemory = 256*1024*1024;
276 limits.totalDeviceLocalMemory = 128*1024*1024;
277 limits.deviceMemoryAllocationGranularity = 64*1024;
278 limits.devicePageSize = 4096;
279 limits.devicePageTableEntrySize = 8;
280 limits.devicePageTableHierarchyLevels = 3;
281 }
282
283 } // linux
284 } // tcu
285
286