1 /*
2  * Copyright (c) 2015-2016 The Khronos Group Inc.
3  * Copyright (c) 2015-2016 Valve Corporation
4  * Copyright (c) 2015-2016 LunarG, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and/or associated documentation files (the "Materials"), to
8  * deal in the Materials without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Materials, and to permit persons to whom the Materials are
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice(s) and this permission notice shall be included in
14  * all copies or substantial portions of the Materials.
15  *
16  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19  *
20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
23  * USE OR OTHER DEALINGS IN THE MATERIALS.
24  *
25  * Author: Chia-I Wu <olvaffe@gmail.com>
26  * Author: Chris Forbes <chrisf@ijw.co.nz>
27  * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
28  * Author: Mark Lobodzinski <mark@lunarg.com>
29  * Author: Mike Stroyan <mike@LunarG.com>
30  * Author: Tobin Ehlis <tobine@google.com>
31  * Author: Tony Barbour <tony@LunarG.com>
32  */
33 
34 #ifndef TEST_COMMON_H
35 #define TEST_COMMON_H
36 
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <stdbool.h>
40 #include <string.h>
41 #include <assert.h>
42 
43 #ifdef _WIN32
44 #define NOMINMAX
45 // WinSock2.h must be included *BEFORE* windows.h
46 #include <winsock2.h>
47 #endif
48 
49 #include <vulkan/vulkan.h>
50 #include <vulkan/vk_sdk_platform.h>
51 
52 #ifdef _WIN32
53 #pragma warning( push )
54 /*
55     warnings 4251 and 4275 have to do with potential dll-interface mismatch
56     between library (gtest) and users. Since we build the gtest library
57     as part of the test build we know that the dll-interface will match and
58     can disable these warnings.
59  */
60 #pragma warning(disable: 4251)
61 #pragma warning(disable: 4275)
62 #endif
63 #include "gtest/gtest.h"
64 #include "gtest-1.7.0/include/gtest/gtest.h"
65 #ifdef _WIN32
66 #pragma warning( pop )
67 #endif
68 #include "vktestbinding.h"
69 
70 #define ASSERT_VK_SUCCESS(err) ASSERT_EQ(VK_SUCCESS, err) << vk_result_string(err)
71 
vk_result_string(VkResult err)72 static inline const char *vk_result_string(VkResult err)
73 {
74     switch (err) {
75 #define STR(r) case r: return #r
76     STR(VK_SUCCESS);
77     STR(VK_NOT_READY);
78     STR(VK_TIMEOUT);
79     STR(VK_EVENT_SET);
80     STR(VK_EVENT_RESET);
81     STR(VK_ERROR_INITIALIZATION_FAILED);
82     STR(VK_ERROR_OUT_OF_HOST_MEMORY);
83     STR(VK_ERROR_OUT_OF_DEVICE_MEMORY);
84     STR(VK_ERROR_DEVICE_LOST);
85     STR(VK_ERROR_EXTENSION_NOT_PRESENT);
86     STR(VK_ERROR_LAYER_NOT_PRESENT);
87     STR(VK_ERROR_MEMORY_MAP_FAILED);
88     STR(VK_ERROR_INCOMPATIBLE_DRIVER);
89 #undef STR
90     default: return "UNKNOWN_RESULT";
91     }
92 }
93 
test_error_callback(const char * expr,const char * file,unsigned int line,const char * function)94 static inline void test_error_callback(const char *expr, const char *file,
95                                        unsigned int line, const char *function)
96 {
97     ADD_FAILURE_AT(file, line) << "Assertion: `" << expr << "'";
98 }
99 
100 #if defined(__linux__)
101 /* Linux-specific common code: */
102 
103 #include <pthread.h>
104 
105 // Threads:
106 typedef pthread_t test_platform_thread;
107 
test_platform_thread_create(test_platform_thread * thread,void * (* func)(void *),void * data)108 static inline int test_platform_thread_create(test_platform_thread *thread, void *(* func) (void*), void *data)
109 {
110     pthread_attr_t thread_attr;
111     pthread_attr_init(&thread_attr);
112     return pthread_create(thread, &thread_attr, func, data);
113 }
test_platform_thread_join(test_platform_thread thread,void ** retval)114 static inline int test_platform_thread_join(test_platform_thread thread, void **retval)
115 {
116     return pthread_join(thread, retval);
117 }
118 
119 // Thread IDs:
120 typedef pthread_t test_platform_thread_id;
test_platform_get_thread_id()121 static inline test_platform_thread_id test_platform_get_thread_id()
122 {
123     return pthread_self();
124 }
125 
126 // Thread mutex:
127 typedef pthread_mutex_t test_platform_thread_mutex;
test_platform_thread_create_mutex(test_platform_thread_mutex * pMutex)128 static inline void test_platform_thread_create_mutex(test_platform_thread_mutex* pMutex)
129 {
130     pthread_mutex_init(pMutex, NULL);
131 }
test_platform_thread_lock_mutex(test_platform_thread_mutex * pMutex)132 static inline void test_platform_thread_lock_mutex(test_platform_thread_mutex* pMutex)
133 {
134     pthread_mutex_lock(pMutex);
135 }
test_platform_thread_unlock_mutex(test_platform_thread_mutex * pMutex)136 static inline void test_platform_thread_unlock_mutex(test_platform_thread_mutex* pMutex)
137 {
138     pthread_mutex_unlock(pMutex);
139 }
test_platform_thread_delete_mutex(test_platform_thread_mutex * pMutex)140 static inline void test_platform_thread_delete_mutex(test_platform_thread_mutex* pMutex)
141 {
142     pthread_mutex_destroy(pMutex);
143 }
144 typedef pthread_cond_t test_platform_thread_cond;
test_platform_thread_init_cond(test_platform_thread_cond * pCond)145 static inline void test_platform_thread_init_cond(test_platform_thread_cond* pCond)
146 {
147     pthread_cond_init(pCond, NULL);
148 }
test_platform_thread_cond_wait(test_platform_thread_cond * pCond,test_platform_thread_mutex * pMutex)149 static inline void test_platform_thread_cond_wait(test_platform_thread_cond* pCond, test_platform_thread_mutex* pMutex)
150 {
151     pthread_cond_wait(pCond, pMutex);
152 }
test_platform_thread_cond_broadcast(test_platform_thread_cond * pCond)153 static inline void test_platform_thread_cond_broadcast(test_platform_thread_cond* pCond)
154 {
155     pthread_cond_broadcast(pCond);
156 }
157 
158 #elif defined(_WIN32) // defined(__linux__)
159 // Threads:
160 typedef HANDLE test_platform_thread;
test_platform_thread_create(test_platform_thread * thread,void * (* func)(void *),void * data)161 static inline int test_platform_thread_create(test_platform_thread *thread, void *(* func) (void *), void *data)
162 {
163     DWORD threadID;
164     *thread = CreateThread(NULL,           // default security attributes
165               0,                           // use default stack size
166               (LPTHREAD_START_ROUTINE)func,
167               data,                        // thread function argument
168               0,                           // use default creation flags
169               &threadID);                  // returns thread identifier
170     return (*thread != NULL);
171 }
test_platform_thread_join(test_platform_thread thread,void ** retval)172 static inline int test_platform_thread_join(test_platform_thread thread, void **retval)
173 {
174     return WaitForSingleObject(thread, INFINITE);
175 }
176 
177 // Thread IDs:
178 typedef DWORD test_platform_thread_id;
test_platform_get_thread_id()179 static test_platform_thread_id test_platform_get_thread_id()
180 {
181     return GetCurrentThreadId();
182 }
183 
184 // Thread mutex:
185 typedef CRITICAL_SECTION test_platform_thread_mutex;
test_platform_thread_create_mutex(test_platform_thread_mutex * pMutex)186 static void test_platform_thread_create_mutex(test_platform_thread_mutex* pMutex)
187 {
188     InitializeCriticalSection(pMutex);
189 }
test_platform_thread_lock_mutex(test_platform_thread_mutex * pMutex)190 static void test_platform_thread_lock_mutex(test_platform_thread_mutex* pMutex)
191 {
192     EnterCriticalSection(pMutex);
193 }
test_platform_thread_unlock_mutex(test_platform_thread_mutex * pMutex)194 static void test_platform_thread_unlock_mutex(test_platform_thread_mutex* pMutex)
195 {
196     LeaveCriticalSection(pMutex);
197 }
test_platform_thread_delete_mutex(test_platform_thread_mutex * pMutex)198 static void test_platform_thread_delete_mutex(test_platform_thread_mutex* pMutex)
199 {
200     DeleteCriticalSection(pMutex);
201 }
202 typedef CONDITION_VARIABLE test_platform_thread_cond;
test_platform_thread_init_cond(test_platform_thread_cond * pCond)203 static void test_platform_thread_init_cond(test_platform_thread_cond* pCond)
204 {
205     InitializeConditionVariable(pCond);
206 }
test_platform_thread_cond_wait(test_platform_thread_cond * pCond,test_platform_thread_mutex * pMutex)207 static void test_platform_thread_cond_wait(test_platform_thread_cond* pCond, test_platform_thread_mutex* pMutex)
208 {
209     SleepConditionVariableCS(pCond, pMutex, INFINITE);
210 }
test_platform_thread_cond_broadcast(test_platform_thread_cond * pCond)211 static void test_platform_thread_cond_broadcast(test_platform_thread_cond* pCond)
212 {
213     WakeAllConditionVariable(pCond);
214 }
215 #else // defined(_WIN32)
216 
217 #error The "test_common.h" file must be modified for this OS.
218 
219 // NOTE: In order to support another OS, an #elif needs to be added (above the
220 // "#else // defined(_WIN32)") for that OS, and OS-specific versions of the
221 // contents of this file must be created.
222 
223 // NOTE: Other OS-specific changes are also needed for this OS.  Search for
224 // files with "WIN32" in it, as a quick way to find files that must be changed.
225 
226 #endif // defined(_WIN32)
227 
228 #endif // TEST_COMMON_H
229