• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #ifndef COMMON_H_
24 #define COMMON_H_
25 
26 #include "VmaUsage.h"
27 
28 #ifdef _WIN32
29 
30 #include <iostream>
31 #include <fstream>
32 #include <vector>
33 #include <memory>
34 #include <algorithm>
35 #include <numeric>
36 #include <array>
37 #include <type_traits>
38 #include <utility>
39 #include <chrono>
40 #include <string>
41 #include <exception>
42 
43 #include <cassert>
44 #include <cstdlib>
45 #include <cstdio>
46 #include <cstdarg>
47 
48 typedef std::chrono::high_resolution_clock::time_point time_point;
49 typedef std::chrono::high_resolution_clock::duration duration;
50 
51 #define STRINGIZE(x) STRINGIZE2(x)
52 #define STRINGIZE2(x) #x
53 #define LINE_STRING STRINGIZE(__LINE__)
54 #define TEST(expr)  do { if(!(expr)) { \
55         assert(0 && #expr); \
56         throw std::runtime_error(__FILE__ "(" LINE_STRING "): ( " #expr " ) == false"); \
57     } } while(false)
58 #define ERR_GUARD_VULKAN(expr)  do { if((expr) < 0) { \
59         assert(0 && #expr); \
60         throw std::runtime_error(__FILE__ "(" LINE_STRING "): VkResult( " #expr " ) < 0"); \
61     } } while(false)
62 
63 static const uint32_t VENDOR_ID_AMD = 0x1002;
64 static const uint32_t VENDOR_ID_NVIDIA = 0x10DE;
65 static const uint32_t VENDOR_ID_INTEL = 0x8086;
66 
67 extern VkInstance g_hVulkanInstance;
68 extern VkPhysicalDevice g_hPhysicalDevice;
69 extern VkDevice g_hDevice;
70 extern VkInstance g_hVulkanInstance;
71 extern VmaAllocator g_hAllocator;
72 extern bool VK_AMD_device_coherent_memory_enabled;
73 
74 void SetAllocatorCreateInfo(VmaAllocatorCreateInfo& outInfo);
75 
ToFloatSeconds(duration d)76 inline float ToFloatSeconds(duration d)
77 {
78     return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();
79 }
80 
81 template <typename T>
ceil_div(T x,T y)82 inline T ceil_div(T x, T y)
83 {
84     return (x+y-1) / y;
85 }
86 template <typename T>
round_div(T x,T y)87 inline T round_div(T x, T y)
88 {
89     return (x+y/(T)2) / y;
90 }
91 
92 template <typename T>
align_up(T val,T align)93 static inline T align_up(T val, T align)
94 {
95     return (val + align - 1) / align * align;
96 }
97 
98 static const float PI = 3.14159265358979323846264338327950288419716939937510582f;
99 
100 template<typename MainT, typename NewT>
PnextChainPushFront(MainT * mainStruct,NewT * newStruct)101 inline void PnextChainPushFront(MainT* mainStruct, NewT* newStruct)
102 {
103     newStruct->pNext = mainStruct->pNext;
104     mainStruct->pNext = newStruct;
105 }
106 template<typename MainT, typename NewT>
PnextChainPushBack(MainT * mainStruct,NewT * newStruct)107 inline void PnextChainPushBack(MainT* mainStruct, NewT* newStruct)
108 {
109     struct VkAnyStruct
110     {
111         VkStructureType sType;
112         void* pNext;
113     };
114     VkAnyStruct* lastStruct = (VkAnyStruct*)mainStruct;
115     while(lastStruct->pNext != nullptr)
116     {
117         lastStruct = (VkAnyStruct*)lastStruct->pNext;
118     }
119     newStruct->pNext = nullptr;
120     lastStruct->pNext = newStruct;
121 }
122 
123 struct vec3
124 {
125     float x, y, z;
126 
vec3vec3127     vec3() { }
vec3vec3128     vec3(float x, float y, float z) : x(x), y(y), z(z) { }
129 
130     float& operator[](uint32_t index) { return *(&x + index); }
131     const float& operator[](uint32_t index) const { return *(&x + index); }
132 
133     vec3 operator+(const vec3& rhs) const { return vec3(x + rhs.x, y + rhs.y, z + rhs.z); }
134     vec3 operator-(const vec3& rhs) const { return vec3(x - rhs.x, y - rhs.y, z - rhs.z); }
135     vec3 operator*(float s) const { return vec3(x * s, y * s, z * s); }
136 
Normalizedvec3137     vec3 Normalized() const
138     {
139         return (*this) * (1.f / sqrt(x * x + y * y + z * z));
140     }
141 };
142 
Dot(const vec3 & lhs,const vec3 & rhs)143 inline float Dot(const vec3& lhs, const vec3& rhs)
144 {
145     return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
146 }
Cross(const vec3 & lhs,const vec3 & rhs)147 inline vec3 Cross(const vec3& lhs, const vec3& rhs)
148 {
149     return vec3(
150         lhs.y * rhs.z - lhs.z * rhs.y,
151 	    lhs.z * rhs.x - lhs.x * rhs.z,
152 	    lhs.x * rhs.y - lhs.y * rhs.x);
153 }
154 
155 struct vec4
156 {
157     float x, y, z, w;
158 
vec4vec4159     vec4() { }
vec4vec4160     vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
vec4vec4161     vec4(const vec3& v, float w) : x(v.x), y(v.y), z(v.z), w(w) { }
162 
163     float& operator[](uint32_t index) { return *(&x + index); }
164     const float& operator[](uint32_t index) const { return *(&x + index); }
165 };
166 
167 struct mat4
168 {
169     union
170     {
171         struct
172         {
173             float _11, _12, _13, _14;
174             float _21, _22, _23, _24;
175             float _31, _32, _33, _34;
176             float _41, _42, _43, _44;
177         };
178         float m[4][4]; // [row][column]
179     };
180 
mat4mat4181     mat4() { }
182 
mat4mat4183     mat4(
184         float _11, float _12, float _13, float _14,
185         float _21, float _22, float _23, float _24,
186         float _31, float _32, float _33, float _34,
187         float _41, float _42, float _43, float _44) :
188         _11(_11), _12(_12), _13(_13), _14(_14),
189         _21(_21), _22(_22), _23(_23), _24(_24),
190         _31(_31), _32(_32), _33(_33), _34(_34),
191         _41(_41), _42(_42), _43(_43), _44(_44)
192     {
193     }
194 
mat4mat4195     mat4(
196         const vec4& row1,
197         const vec4& row2,
198         const vec4& row3,
199         const vec4& row4) :
200         _11(row1.x), _12(row1.y), _13(row1.z), _14(row1.w),
201         _21(row2.x), _22(row2.y), _23(row2.z), _24(row2.w),
202         _31(row3.x), _32(row3.y), _33(row3.z), _34(row3.w),
203         _41(row4.x), _42(row4.y), _43(row4.z), _44(row4.w)
204     {
205     }
206 
207     mat4 operator*(const mat4 &rhs) const
208     {
209         return mat4(
210             _11 * rhs._11 + _12 * rhs._21 + _13 * rhs._31 + _14 * rhs._41,
211             _11 * rhs._12 + _12 * rhs._22 + _13 * rhs._32 + _14 * rhs._42,
212             _11 * rhs._13 + _12 * rhs._23 + _13 * rhs._33 + _14 * rhs._43,
213             _11 * rhs._14 + _12 * rhs._24 + _13 * rhs._34 + _14 * rhs._44,
214 
215             _21 * rhs._11 + _22 * rhs._21 + _23 * rhs._31 + _24 * rhs._41,
216             _21 * rhs._12 + _22 * rhs._22 + _23 * rhs._32 + _24 * rhs._42,
217             _21 * rhs._13 + _22 * rhs._23 + _23 * rhs._33 + _24 * rhs._43,
218             _21 * rhs._14 + _22 * rhs._24 + _23 * rhs._34 + _24 * rhs._44,
219 
220             _31 * rhs._11 + _32 * rhs._21 + _33 * rhs._31 + _34 * rhs._41,
221             _31 * rhs._12 + _32 * rhs._22 + _33 * rhs._32 + _34 * rhs._42,
222             _31 * rhs._13 + _32 * rhs._23 + _33 * rhs._33 + _34 * rhs._43,
223             _31 * rhs._14 + _32 * rhs._24 + _33 * rhs._34 + _34 * rhs._44,
224 
225             _41 * rhs._11 + _42 * rhs._21 + _43 * rhs._31 + _44 * rhs._41,
226             _41 * rhs._12 + _42 * rhs._22 + _43 * rhs._32 + _44 * rhs._42,
227             _41 * rhs._13 + _42 * rhs._23 + _43 * rhs._33 + _44 * rhs._43,
228             _41 * rhs._14 + _42 * rhs._24 + _43 * rhs._34 + _44 * rhs._44);
229     }
230 
RotationYmat4231     static mat4 RotationY(float angle)
232     {
233         const float s = sin(angle), c = cos(angle);
234         return mat4(
235             c,   0.f, -s,  0.f,
236             0.f, 1.f, 0.f, 0.f,
237             s,   0.f, c,   0.f,
238             0.f, 0.f, 0.f, 1.f);
239     }
240 
Perspectivemat4241     static mat4 Perspective(float fovY, float aspectRatio, float zNear, float zFar)
242     {
243         float yScale = 1.0f / tan(fovY * 0.5f);
244         float xScale = yScale / aspectRatio;
245         return mat4(
246             xScale, 0.0f, 0.0f, 0.0f,
247             0.0f, yScale, 0.0f, 0.0f,
248             0.0f, 0.0f, zFar / (zFar - zNear), 1.0f,
249             0.0f, 0.0f, -zNear * zFar / (zFar - zNear), 0.0f);
250     }
251 
LookAtmat4252     static mat4 LookAt(vec3 at, vec3 eye, vec3 up)
253     {
254         vec3 zAxis = (at - eye).Normalized();
255         vec3 xAxis = Cross(up, zAxis).Normalized();
256         vec3 yAxis = Cross(zAxis, xAxis);
257         return mat4(
258             xAxis.x, yAxis.x, zAxis.x, 0.0f,
259             xAxis.y, yAxis.y, zAxis.y, 0.0f,
260             xAxis.z, yAxis.z, zAxis.z, 0.0f,
261             -Dot(xAxis, eye), -Dot(yAxis, eye), -Dot(zAxis, eye), 1.0f);
262     }
263 };
264 
265 class RandomNumberGenerator
266 {
267 public:
RandomNumberGenerator()268     RandomNumberGenerator() : m_Value{GetTickCount()} {}
RandomNumberGenerator(uint32_t seed)269     RandomNumberGenerator(uint32_t seed) : m_Value{seed} { }
Seed(uint32_t seed)270     void Seed(uint32_t seed) { m_Value = seed; }
Generate()271     uint32_t Generate() { return GenerateFast() ^ (GenerateFast() >> 7); }
272 
273 private:
274     uint32_t m_Value;
GenerateFast()275     uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }
276 };
277 
278 // Wrapper for RandomNumberGenerator compatible with STL "UniformRandomNumberGenerator" idea.
279 struct MyUniformRandomNumberGenerator
280 {
281     typedef uint32_t result_type;
MyUniformRandomNumberGeneratorMyUniformRandomNumberGenerator282     MyUniformRandomNumberGenerator(RandomNumberGenerator& gen) : m_Gen(gen) { }
minMyUniformRandomNumberGenerator283     static uint32_t min() { return 0; }
maxMyUniformRandomNumberGenerator284     static uint32_t max() { return UINT32_MAX; }
operatorMyUniformRandomNumberGenerator285     uint32_t operator()() { return m_Gen.Generate(); }
286 
287 private:
288     RandomNumberGenerator& m_Gen;
289 };
290 
291 void ReadFile(std::vector<char>& out, const char* fileName);
292 
293 enum class CONSOLE_COLOR
294 {
295     INFO,
296     NORMAL,
297     WARNING,
298     ERROR_,
299     COUNT
300 };
301 
302 void SetConsoleColor(CONSOLE_COLOR color);
303 
304 void PrintMessage(CONSOLE_COLOR color, const char* msg);
305 void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg);
306 
Print(const char * msg)307 inline void Print(const char* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
Print(const wchar_t * msg)308 inline void Print(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
PrintWarning(const char * msg)309 inline void PrintWarning(const char* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
PrintWarning(const wchar_t * msg)310 inline void PrintWarning(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
PrintError(const char * msg)311 inline void PrintError(const char* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
PrintError(const wchar_t * msg)312 inline void PrintError(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
313 
314 void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList);
315 void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList);
316 void PrintMessageF(CONSOLE_COLOR color, const char* format, ...);
317 void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...);
318 void PrintWarningF(const char* format, ...);
319 void PrintWarningF(const wchar_t* format, ...);
320 void PrintErrorF(const char* format, ...);
321 void PrintErrorF(const wchar_t* format, ...);
322 
323 void SaveFile(const wchar_t* filePath, const void* data, size_t dataSize);
324 
325 std::wstring SizeToStr(size_t size);
326 // As codePage use e.g. CP_ACP for native Windows 1-byte codepage or CP_UTF8.
327 bool ConvertCharsToUnicode(std::wstring *outStr, const std::string &s, unsigned codePage);
328 bool ConvertCharsToUnicode(std::wstring *outStr, const char *s, size_t sCharCount, unsigned codePage);
329 
330 const wchar_t* PhysicalDeviceTypeToStr(VkPhysicalDeviceType type);
331 const wchar_t* VendorIDToStr(uint32_t vendorID);
332 
333 #if VMA_VULKAN_VERSION >= 1002000
334 const wchar_t* DriverIDToStr(VkDriverId driverID);
335 #endif
336 
337 #endif // #ifdef _WIN32
338 
339 #endif
340