• 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 
setMinimized(bool minimized)71     void setMinimized(bool minimized)
72     {
73         m_window->setMinimized(minimized);
74     }
75 
76 private:
77     UniquePtr<win32::Window> m_window;
78 };
79 
80 class VulkanDisplay : public vk::wsi::Win32DisplayInterface
81 {
82 public:
VulkanDisplay(HINSTANCE instance)83     VulkanDisplay(HINSTANCE instance) : vk::wsi::Win32DisplayInterface(vk::pt::Win32InstanceHandle(instance))
84     {
85     }
86 
createWindow(const Maybe<UVec2> & initialSize) const87     vk::wsi::Window *createWindow(const Maybe<UVec2> &initialSize) const
88     {
89         const HINSTANCE instance = (HINSTANCE)m_native.internal;
90         const uint32_t width     = !initialSize ? 400 : initialSize->x();
91         const uint32_t height    = !initialSize ? 300 : initialSize->y();
92 
93         return new VulkanWindow(MovePtr<win32::Window>(new win32::Window(instance, (int)width, (int)height)));
94     }
95 };
96 
97 class VulkanLibrary : public vk::Library
98 {
99 public:
VulkanLibrary(const char * libraryPath)100     VulkanLibrary(const char *libraryPath)
101         : m_library(libraryPath != DE_NULL ? libraryPath : "vulkan-1.dll")
102         , m_driver(m_library)
103     {
104     }
105 
getPlatformInterface(void) const106     const vk::PlatformInterface &getPlatformInterface(void) const
107     {
108         return m_driver;
109     }
getFunctionLibrary(void) const110     const tcu::FunctionLibrary &getFunctionLibrary(void) const
111     {
112         return m_library;
113     }
114 
115 private:
116     const tcu::DynamicFunctionLibrary m_library;
117     const vk::PlatformDriver m_driver;
118 };
119 
VulkanPlatform(HINSTANCE instance)120 VulkanPlatform::VulkanPlatform(HINSTANCE instance) : m_instance(instance)
121 {
122 }
123 
~VulkanPlatform(void)124 VulkanPlatform::~VulkanPlatform(void)
125 {
126 }
127 
createLibrary(LibraryType libraryType,const char * libraryPath) const128 vk::Library *VulkanPlatform::createLibrary(LibraryType libraryType, const char *libraryPath) const
129 {
130     switch (libraryType)
131     {
132     case LIBRARY_TYPE_VULKAN:
133         return new VulkanLibrary(libraryPath);
134     default:
135         TCU_THROW(InternalError, "Unknown library type requested");
136     }
137 }
138 
getStringRegKey(const std::string & regKey,const std::string & strValueName,std::string & strValue)139 ULONG getStringRegKey(const std::string &regKey, const std::string &strValueName, std::string &strValue)
140 {
141     HKEY hKey;
142     ULONG nError;
143     CHAR szBuffer[512];
144     DWORD dwBufferSize = sizeof(szBuffer);
145 
146     nError = RegOpenKeyExA(HKEY_LOCAL_MACHINE, regKey.c_str(), 0, KEY_READ, &hKey);
147 
148     if (ERROR_SUCCESS == nError)
149         nError = RegQueryValueExA(hKey, strValueName.c_str(), 0, DE_NULL, (LPBYTE)szBuffer, &dwBufferSize);
150 
151     if (ERROR_SUCCESS == nError)
152         strValue = szBuffer;
153 
154     return nError;
155 }
156 
getWindowsBits(std::ostream & dst)157 void getWindowsBits(std::ostream &dst)
158 {
159 #if defined(_WIN64)
160     dst << "64"; // 64-bit programs run only on Win64
161     return;
162 #elif defined(_WIN32)
163     BOOL is64 = false;
164     // 32-bit programs run on both 32-bit and 64-bit Windows.
165     // Function is defined from XP SP2 onwards, so we don't need to
166     // check if it exists.
167     if (IsWow64Process(GetCurrentProcess(), &is64))
168     {
169         if (is64)
170             dst << "64";
171         else
172             dst << "32";
173         return;
174     }
175 #endif
176 #if !defined(_WIN64)
177     // IsWow64Process returns failure or neither of
178     // _WIN64 or _WIN32 is defined
179     dst << "Unknown";
180 #endif
181 }
182 
getOSNameFromRegistry(std::ostream & dst)183 void getOSNameFromRegistry(std::ostream &dst)
184 {
185     const char *keypath     = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
186     std::string productname = "Unknown";
187     std::string releaseid   = "Unknown";
188     std::string optional;
189 
190     getStringRegKey(keypath, "ProductName", productname);
191     getStringRegKey(keypath, "ReleaseId", releaseid);
192 
193     getWindowsBits(dst);
194 
195     dst << " bit Windows Product: " << productname << ", Release: " << releaseid;
196 
197     if (ERROR_SUCCESS == getStringRegKey(keypath, "EditionID", optional))
198     {
199         dst << ", Edition: " << optional;
200         if (ERROR_SUCCESS == getStringRegKey(keypath, "EditionSubstring", optional) && optional.length() > 0)
201             dst << " " << optional;
202     }
203 }
204 
getOSVersionFromDLL(std::ostream & dst)205 void getOSVersionFromDLL(std::ostream &dst)
206 {
207     DWORD buffer_size = GetFileVersionInfoSize(("kernel32.dll"), DE_NULL);
208     char *buffer      = 0;
209 
210     if (buffer_size != 0)
211     {
212         buffer = new char[buffer_size];
213         if (buffer != 0)
214         {
215             if (GetFileVersionInfo("kernel32.dll", 0, buffer_size, buffer))
216             {
217                 VS_FIXEDFILEINFO *version = DE_NULL;
218                 UINT version_len          = 0;
219 
220                 if (VerQueryValue(buffer, "\\", (LPVOID *)&version, &version_len))
221                 {
222                     dst << ", DLL Version: " << HIWORD(version->dwProductVersionMS) << "."
223                         << LOWORD(version->dwProductVersionMS) << ", DLL Build: " << HIWORD(version->dwProductVersionLS)
224                         << "." << LOWORD(version->dwProductVersionLS);
225                 }
226             }
227             delete[] buffer;
228         }
229     }
230 }
231 
232 // Old windows version query APIs lie about the version number. There's no replacement
233 // API, and instead applications are supposed to queriy about capabilities instead of
234 // relying on operating system version numbers.
235 //
236 // Since we want to actually know the version number for debugging purposes, we need
237 // to use roundabout ways to fetch the information.
238 //
239 // The registry contains some useful strings, which we print out if the keys
240 // are available. The current official way to get version number is to look at a
241 // system DLL file and read its version number, so we do that too, in case the
242 // registry becomes unreliable in the future.
243 //
244 // If the DLL method fails, we simply don't print out anything about it.
245 // The minimal output from this function is "Windows Product: Unknown, Release: Unknown"
getOSInfo(std::ostream & dst)246 static void getOSInfo(std::ostream &dst)
247 {
248     getOSNameFromRegistry(dst);
249     getOSVersionFromDLL(dst);
250 }
251 
getProcessorArchitectureName(WORD arch)252 const char *getProcessorArchitectureName(WORD arch)
253 {
254     switch (arch)
255     {
256     case PROCESSOR_ARCHITECTURE_AMD64:
257         return "AMD64";
258     case PROCESSOR_ARCHITECTURE_ARM:
259         return "ARM";
260     case PROCESSOR_ARCHITECTURE_IA64:
261         return "IA64";
262     case PROCESSOR_ARCHITECTURE_INTEL:
263         return "INTEL";
264     case PROCESSOR_ARCHITECTURE_UNKNOWN:
265         return "UNKNOWN";
266     default:
267         return DE_NULL;
268     }
269 }
270 
getProcessorInfo(std::ostream & dst)271 static void getProcessorInfo(std::ostream &dst)
272 {
273     SYSTEM_INFO sysInfo;
274 
275     deMemset(&sysInfo, 0, sizeof(sysInfo));
276     GetSystemInfo(&sysInfo);
277 
278     dst << "arch ";
279     {
280         const char *const archName = getProcessorArchitectureName(sysInfo.wProcessorArchitecture);
281 
282         if (archName)
283             dst << archName;
284         else
285             dst << tcu::toHex(sysInfo.wProcessorArchitecture);
286     }
287 
288     dst << ", level " << tcu::toHex(sysInfo.wProcessorLevel) << ", revision " << tcu::toHex(sysInfo.wProcessorRevision);
289 }
290 
describePlatform(std::ostream & dst) const291 void VulkanPlatform::describePlatform(std::ostream &dst) const
292 {
293     dst << "OS: ";
294     getOSInfo(dst);
295     dst << "\n";
296 
297     dst << "CPU: ";
298     getProcessorInfo(dst);
299     dst << "\n";
300 }
301 
createWsiDisplay(vk::wsi::Type wsiType) const302 vk::wsi::Display *VulkanPlatform::createWsiDisplay(vk::wsi::Type wsiType) const
303 {
304     if (wsiType != vk::wsi::TYPE_WIN32)
305         TCU_THROW(NotSupportedError, "WSI type not supported");
306 
307     return new VulkanDisplay(m_instance);
308 }
309 
hasDisplay(vk::wsi::Type wsiType) const310 bool VulkanPlatform::hasDisplay(vk::wsi::Type wsiType) const
311 {
312     if (wsiType != vk::wsi::TYPE_WIN32)
313         return false;
314 
315     return true;
316 }
317 
318 } // namespace win32
319 } // namespace tcu
320