• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Tester Core
3  * ----------------------------------------
4  *
5  * Copyright 2016 The Android Open Source Project
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 Win32 Vulkan platform
22  *//*--------------------------------------------------------------------*/
23 
24 #include "tcuWin32VulkanPlatform.hpp"
25 #include "tcuWin32Window.hpp"
26 
27 #include "tcuFormatUtil.hpp"
28 #include "tcuFunctionLibrary.hpp"
29 #include "tcuVector.hpp"
30 
31 #include "vkWsiPlatform.hpp"
32 
33 #include "deUniquePtr.hpp"
34 #include "deMemory.h"
35 
36 namespace tcu
37 {
38 namespace win32
39 {
40 
41 using de::MovePtr;
42 using de::UniquePtr;
43 
44 DE_STATIC_ASSERT(sizeof(vk::pt::Win32InstanceHandle)	== sizeof(HINSTANCE));
45 DE_STATIC_ASSERT(sizeof(vk::pt::Win32WindowHandle)		== sizeof(HWND));
46 
47 class VulkanWindow : public vk::wsi::Win32WindowInterface
48 {
49 public:
VulkanWindow(MovePtr<win32::Window> window)50 	VulkanWindow (MovePtr<win32::Window> window)
51 		: vk::wsi::Win32WindowInterface	(vk::pt::Win32WindowHandle(window->getHandle()))
52 		, m_window						(window)
53 	{
54 	}
55 
setVisible(bool visible)56 	void setVisible(bool visible)
57 	{
58 		m_window->setVisible(visible);
59 	}
60 
setForeground(void)61 	void setForeground(void)
62 	{
63 		m_window->setForeground();
64 	}
65 
resize(const UVec2 & newSize)66 	void resize (const UVec2& newSize)
67 	{
68 		m_window->setSize((int)newSize.x(), (int)newSize.y());
69 	}
70 
71 private:
72 	UniquePtr<win32::Window>	m_window;
73 };
74 
75 class VulkanDisplay : public vk::wsi::Win32DisplayInterface
76 {
77 public:
VulkanDisplay(HINSTANCE instance)78 	VulkanDisplay (HINSTANCE instance)
79 		: vk::wsi::Win32DisplayInterface	(vk::pt::Win32InstanceHandle(instance))
80 	{
81 	}
82 
createWindow(const Maybe<UVec2> & initialSize) const83 	vk::wsi::Window* createWindow (const Maybe<UVec2>& initialSize) const
84 	{
85 		const HINSTANCE	instance	= (HINSTANCE)m_native.internal;
86 		const deUint32	width		= !initialSize ? 400 : initialSize->x();
87 		const deUint32	height		= !initialSize ? 300 : initialSize->y();
88 
89 		return new VulkanWindow(MovePtr<win32::Window>(new win32::Window(instance, (int)width, (int)height)));
90 	}
91 };
92 
93 class VulkanLibrary : public vk::Library
94 {
95 public:
VulkanLibrary(const char * libraryPath)96 	VulkanLibrary (const char* libraryPath)
97 		: m_library	(libraryPath != DE_NULL ? libraryPath : "vulkan-1.dll")
98 		, m_driver	(m_library)
99 	{
100 	}
101 
getPlatformInterface(void) const102 	const vk::PlatformInterface&	getPlatformInterface	(void) const
103 	{
104 		return m_driver;
105 	}
getFunctionLibrary(void) const106 	const tcu::FunctionLibrary&		getFunctionLibrary		(void) const
107 	{
108 		return m_library;
109 	}
110 
111 private:
112 	const tcu::DynamicFunctionLibrary	m_library;
113 	const vk::PlatformDriver			m_driver;
114 };
115 
116 class VulkanVideoDecodeParserLibrary : public vk::Library
117 {
118 public:
VulkanVideoDecodeParserLibrary(void)119 	VulkanVideoDecodeParserLibrary(void)
120 		: m_library("nvidia-vkvideo-parser.dll")
121 	{
122 	}
123 
getPlatformInterface(void) const124 	const vk::PlatformInterface& getPlatformInterface(void) const
125 	{
126 		TCU_THROW(InternalError, "getPlatformInterface is not possible for VulkanVideoDecodeParserLibrary");
127 	}
getFunctionLibrary(void) const128 	const tcu::FunctionLibrary& getFunctionLibrary(void) const
129 	{
130 		return m_library;
131 	}
132 
133 private:
134 	const tcu::DynamicFunctionLibrary	m_library;
135 };
136 
137 
VulkanPlatform(HINSTANCE instance)138 VulkanPlatform::VulkanPlatform (HINSTANCE instance)
139 	: m_instance(instance)
140 {
141 }
142 
~VulkanPlatform(void)143 VulkanPlatform::~VulkanPlatform (void)
144 {
145 }
146 
createLibrary(LibraryType libraryType,const char * libraryPath) const147 vk::Library* VulkanPlatform::createLibrary (LibraryType libraryType, const char* libraryPath) const
148 {
149 	switch(libraryType)
150 	{
151 		case LIBRARY_TYPE_VULKAN:						return new VulkanLibrary(libraryPath);
152 		case LIBRARY_TYPE_VULKAN_VIDEO_DECODE_PARSER:	return new VulkanVideoDecodeParserLibrary();
153 		default: TCU_THROW(InternalError, "Unknown library type requested");
154 	}
155 }
156 
getStringRegKey(const std::string & regKey,const std::string & strValueName,std::string & strValue)157 ULONG getStringRegKey (const std::string& regKey, const std::string& strValueName, std::string& strValue)
158 {
159 	HKEY	hKey;
160 	ULONG	nError;
161 	CHAR	szBuffer[512];
162 	DWORD	dwBufferSize = sizeof(szBuffer);
163 
164 	nError = RegOpenKeyExA(HKEY_LOCAL_MACHINE, regKey.c_str(), 0, KEY_READ, &hKey);
165 
166 	if (ERROR_SUCCESS == nError)
167 		nError = RegQueryValueExA(hKey, strValueName.c_str(), 0, DE_NULL, (LPBYTE)szBuffer, &dwBufferSize);
168 
169 	if (ERROR_SUCCESS == nError)
170 		strValue = szBuffer;
171 
172 	return nError;
173 }
174 
getWindowsBits(std::ostream & dst)175 void getWindowsBits (std::ostream& dst)
176 {
177 #if defined(_WIN64)
178 	dst << "64"; // 64-bit programs run only on Win64
179 	return;
180 #elif defined(_WIN32)
181 	BOOL is64 = false;
182 	// 32-bit programs run on both 32-bit and 64-bit Windows.
183 	// Function is defined from XP SP2 onwards, so we don't need to
184 	// check if it exists.
185 	if (IsWow64Process(GetCurrentProcess(), &is64))
186 	{
187 		if (is64)
188 			dst << "64";
189 		else
190 			dst << "32";
191 		return;
192 	}
193 #endif
194 #if !defined(_WIN64)
195 	// IsWow64Process returns failure or neither of
196 	// _WIN64 or _WIN32 is defined
197 	dst << "Unknown";
198 #endif
199 }
200 
getOSNameFromRegistry(std::ostream & dst)201 void getOSNameFromRegistry (std::ostream& dst)
202 {
203 	const char* keypath		= "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
204 	std::string productname	= "Unknown";
205 	std::string releaseid	= "Unknown";
206 	std::string optional;
207 
208 	getStringRegKey(keypath, "ProductName", productname);
209 	getStringRegKey(keypath, "ReleaseId", releaseid);
210 
211 	getWindowsBits(dst);
212 
213 	dst << " bit Windows Product: " << productname << ", Release: " << releaseid;
214 
215 	if (ERROR_SUCCESS == getStringRegKey(keypath, "EditionID", optional))
216 	{
217 		dst << ", Edition: " << optional;
218 		if (ERROR_SUCCESS == getStringRegKey(keypath, "EditionSubstring", optional)
219 			&& optional.length() > 0)
220 			dst << " " << optional;
221 	}
222 }
223 
getOSVersionFromDLL(std::ostream & dst)224 void getOSVersionFromDLL (std::ostream& dst)
225 {
226 	DWORD	buffer_size	= GetFileVersionInfoSize(("kernel32.dll"), DE_NULL);
227 	char*	buffer		= 0;
228 
229 	if (buffer_size != 0)
230 	{
231 		buffer = new char[buffer_size];
232 		if (buffer != 0)
233 		{
234 			if (GetFileVersionInfo("kernel32.dll", 0, buffer_size, buffer))
235 			{
236 				VS_FIXEDFILEINFO*	version		= DE_NULL;
237 				UINT				version_len	= 0;
238 
239 				if (VerQueryValue(buffer, "\\", (LPVOID*)&version, &version_len))
240 				{
241 					dst << ", DLL Version: " << HIWORD(version->dwProductVersionMS) << "." << LOWORD(version->dwProductVersionMS)
242 						<< ", DLL Build: "   << HIWORD(version->dwProductVersionLS) << "." << LOWORD(version->dwProductVersionLS);
243 				}
244 			}
245 			delete[] buffer;
246 		}
247 	}
248 }
249 
250 // Old windows version query APIs lie about the version number. There's no replacement
251 // API, and instead applications are supposed to queriy about capabilities instead of
252 // relying on operating system version numbers.
253 //
254 // Since we want to actually know the version number for debugging purposes, we need
255 // to use roundabout ways to fetch the information.
256 //
257 // The registry contains some useful strings, which we print out if the keys
258 // are available. The current official way to get version number is to look at a
259 // system DLL file and read its version number, so we do that too, in case the
260 // registry becomes unreliable in the future.
261 //
262 // If the DLL method fails, we simply don't print out anything about it.
263 // The minimal output from this function is "Windows Product: Unknown, Release: Unknown"
getOSInfo(std::ostream & dst)264 static void getOSInfo (std::ostream& dst)
265 {
266 	getOSNameFromRegistry(dst);
267 	getOSVersionFromDLL(dst);
268 }
269 
getProcessorArchitectureName(WORD arch)270 const char* getProcessorArchitectureName (WORD arch)
271 {
272 	switch (arch)
273 	{
274 		case PROCESSOR_ARCHITECTURE_AMD64:		return "AMD64";
275 		case PROCESSOR_ARCHITECTURE_ARM:		return "ARM";
276 		case PROCESSOR_ARCHITECTURE_IA64:		return "IA64";
277 		case PROCESSOR_ARCHITECTURE_INTEL:		return "INTEL";
278 		case PROCESSOR_ARCHITECTURE_UNKNOWN:	return "UNKNOWN";
279 		default:								return DE_NULL;
280 	}
281 }
282 
getProcessorInfo(std::ostream & dst)283 static void getProcessorInfo (std::ostream& dst)
284 {
285 	SYSTEM_INFO	sysInfo;
286 
287 	deMemset(&sysInfo, 0, sizeof(sysInfo));
288 	GetSystemInfo(&sysInfo);
289 
290 	dst << "arch ";
291 	{
292 		const char* const	archName	= getProcessorArchitectureName(sysInfo.wProcessorArchitecture);
293 
294 		if (archName)
295 			dst << archName;
296 		else
297 			dst << tcu::toHex(sysInfo.wProcessorArchitecture);
298 	}
299 
300 	dst << ", level " << tcu::toHex(sysInfo.wProcessorLevel) << ", revision " << tcu::toHex(sysInfo.wProcessorRevision);
301 }
302 
describePlatform(std::ostream & dst) const303 void VulkanPlatform::describePlatform (std::ostream& dst) const
304 {
305 	dst << "OS: ";
306 	getOSInfo(dst);
307 	dst << "\n";
308 
309 	dst << "CPU: ";
310 	getProcessorInfo(dst);
311 	dst << "\n";
312 }
313 
createWsiDisplay(vk::wsi::Type wsiType) const314 vk::wsi::Display* VulkanPlatform::createWsiDisplay (vk::wsi::Type wsiType) const
315 {
316 	if (wsiType != vk::wsi::TYPE_WIN32)
317 		TCU_THROW(NotSupportedError, "WSI type not supported");
318 
319 	return new VulkanDisplay(m_instance);
320 }
321 
hasDisplay(vk::wsi::Type wsiType) const322 bool VulkanPlatform::hasDisplay (vk::wsi::Type wsiType)  const
323 {
324 	if (wsiType != vk::wsi::TYPE_WIN32)
325 		return false;
326 
327 	return true;
328 }
329 
330 } // win32
331 } // tcu
332