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