blob: 714fa6a02642c9af0d32f74347c374398a88ed3d [file] [log] [blame]
Adam Sawickif1a793c2018-03-13 15:42:22 +01001#ifndef COMMON_H_
2#define COMMON_H_
3
Adam Sawickib8333fb2018-03-13 16:15:53 +01004#include "VmaUsage.h"
5
Adam Sawickif1a793c2018-03-13 15:42:22 +01006#ifdef _WIN32
7
Adam Sawickib8333fb2018-03-13 16:15:53 +01008#include <iostream>
Adam Sawickif1a793c2018-03-13 15:42:22 +01009#include <fstream>
10#include <vector>
Adam Sawickif1a793c2018-03-13 15:42:22 +010011#include <memory>
12#include <algorithm>
13#include <numeric>
14#include <array>
15#include <type_traits>
16#include <utility>
Adam Sawickib8333fb2018-03-13 16:15:53 +010017#include <chrono>
18#include <string>
Adam Sawickib8d34d52018-10-03 17:41:20 +020019#include <exception>
Adam Sawickif1a793c2018-03-13 15:42:22 +010020
Adam Sawickif1a793c2018-03-13 15:42:22 +010021#include <cassert>
22#include <cstdlib>
23#include <cstdio>
Adam Sawickib8333fb2018-03-13 16:15:53 +010024#include <cstdarg>
25
26typedef std::chrono::high_resolution_clock::time_point time_point;
27typedef std::chrono::high_resolution_clock::duration duration;
Adam Sawickif1a793c2018-03-13 15:42:22 +010028
Adam Sawickib8d34d52018-10-03 17:41:20 +020029#ifdef _DEBUG
30 #define TEST(expr) do { \
31 if(!(expr)) { \
32 assert(0 && #expr); \
33 } \
34 } while(0)
35#else
36 #define TEST(expr) do { \
37 if(!(expr)) { \
38 throw std::runtime_error("TEST FAILED: " #expr); \
39 } \
40 } while(0)
41#endif
42
43#define ERR_GUARD_VULKAN(expr) TEST((expr) >= 0)
Adam Sawickif1a793c2018-03-13 15:42:22 +010044
Adam Sawickib8333fb2018-03-13 16:15:53 +010045extern VkPhysicalDevice g_hPhysicalDevice;
46extern VkDevice g_hDevice;
47extern VmaAllocator g_hAllocator;
48extern bool g_MemoryAliasingWarningEnabled;
49
50inline float ToFloatSeconds(duration d)
51{
52 return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();
53}
54
55template <typename T>
56inline T ceil_div(T x, T y)
57{
Adam Sawicki82c3f332018-06-11 15:27:33 +020058 return (x+y-1) / y;
Adam Sawickib8333fb2018-03-13 16:15:53 +010059}
Adam Sawickiff0f7b82018-10-18 14:44:05 +020060template <typename T>
61inline T round_div(T x, T y)
62{
63 return (x+y/(T)2) / y;
64}
Adam Sawickib8333fb2018-03-13 16:15:53 +010065
66template <typename T>
67static inline T align_up(T val, T align)
68{
Adam Sawicki82c3f332018-06-11 15:27:33 +020069 return (val + align - 1) / align * align;
Adam Sawickib8333fb2018-03-13 16:15:53 +010070}
71
Adam Sawicki82c3f332018-06-11 15:27:33 +020072static const float PI = 3.14159265358979323846264338327950288419716939937510582f;
73
74struct vec3
75{
76 float x, y, z;
77
78 vec3() { }
79 vec3(float x, float y, float z) : x(x), y(y), z(z) { }
80
81 float& operator[](uint32_t index) { return *(&x + index); }
82 const float& operator[](uint32_t index) const { return *(&x + index); }
83
84 vec3 operator+(const vec3& rhs) const { return vec3(x + rhs.x, y + rhs.y, z + rhs.z); }
85 vec3 operator-(const vec3& rhs) const { return vec3(x - rhs.x, y - rhs.y, z - rhs.z); }
86 vec3 operator*(float s) const { return vec3(x * s, y * s, z * s); }
87
88 vec3 Normalized() const
89 {
90 return (*this) * (1.f / sqrt(x * x + y * y + z * z));
91 }
92};
93
94inline float Dot(const vec3& lhs, const vec3& rhs)
95{
96 return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
97}
98inline vec3 Cross(const vec3& lhs, const vec3& rhs)
99{
100 return vec3(
101 lhs.y * rhs.z - lhs.z * rhs.y,
102 lhs.z * rhs.x - lhs.x * rhs.z,
103 lhs.x * rhs.y - lhs.y * rhs.x);
104}
105
106struct vec4
107{
108 float x, y, z, w;
109
110 vec4() { }
111 vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
112 vec4(const vec3& v, float w) : x(v.x), y(v.y), z(v.z), w(w) { }
113
114 float& operator[](uint32_t index) { return *(&x + index); }
115 const float& operator[](uint32_t index) const { return *(&x + index); }
116};
117
118struct mat4
119{
120 union
121 {
122 struct
123 {
124 float _11, _12, _13, _14;
125 float _21, _22, _23, _24;
126 float _31, _32, _33, _34;
127 float _41, _42, _43, _44;
128 };
129 float m[4][4]; // [row][column]
130 };
131
132 mat4() { }
133
134 mat4(
135 float _11, float _12, float _13, float _14,
136 float _21, float _22, float _23, float _24,
137 float _31, float _32, float _33, float _34,
138 float _41, float _42, float _43, float _44) :
139 _11(_11), _12(_12), _13(_13), _14(_14),
140 _21(_21), _22(_22), _23(_23), _24(_24),
141 _31(_31), _32(_32), _33(_33), _34(_34),
142 _41(_41), _42(_42), _43(_43), _44(_44)
143 {
144 }
145
146 mat4(
147 const vec4& row1,
148 const vec4& row2,
149 const vec4& row3,
150 const vec4& row4) :
151 _11(row1.x), _12(row1.y), _13(row1.z), _14(row1.w),
152 _21(row2.x), _22(row2.y), _23(row2.z), _24(row2.w),
153 _31(row3.x), _32(row3.y), _33(row3.z), _34(row3.w),
154 _41(row4.x), _42(row4.y), _43(row4.z), _44(row4.w)
155 {
156 }
157
158 mat4 operator*(const mat4 &rhs) const
159 {
160 return mat4(
161 _11 * rhs._11 + _12 * rhs._21 + _13 * rhs._31 + _14 * rhs._41,
162 _11 * rhs._12 + _12 * rhs._22 + _13 * rhs._32 + _14 * rhs._42,
163 _11 * rhs._13 + _12 * rhs._23 + _13 * rhs._33 + _14 * rhs._43,
164 _11 * rhs._14 + _12 * rhs._24 + _13 * rhs._34 + _14 * rhs._44,
165
166 _21 * rhs._11 + _22 * rhs._21 + _23 * rhs._31 + _24 * rhs._41,
167 _21 * rhs._12 + _22 * rhs._22 + _23 * rhs._32 + _24 * rhs._42,
168 _21 * rhs._13 + _22 * rhs._23 + _23 * rhs._33 + _24 * rhs._43,
169 _21 * rhs._14 + _22 * rhs._24 + _23 * rhs._34 + _24 * rhs._44,
170
171 _31 * rhs._11 + _32 * rhs._21 + _33 * rhs._31 + _34 * rhs._41,
172 _31 * rhs._12 + _32 * rhs._22 + _33 * rhs._32 + _34 * rhs._42,
173 _31 * rhs._13 + _32 * rhs._23 + _33 * rhs._33 + _34 * rhs._43,
174 _31 * rhs._14 + _32 * rhs._24 + _33 * rhs._34 + _34 * rhs._44,
175
176 _41 * rhs._11 + _42 * rhs._21 + _43 * rhs._31 + _44 * rhs._41,
177 _41 * rhs._12 + _42 * rhs._22 + _43 * rhs._32 + _44 * rhs._42,
178 _41 * rhs._13 + _42 * rhs._23 + _43 * rhs._33 + _44 * rhs._43,
179 _41 * rhs._14 + _42 * rhs._24 + _43 * rhs._34 + _44 * rhs._44);
180 }
181
182 static mat4 RotationY(float angle)
183 {
184 const float s = sin(angle), c = cos(angle);
185 return mat4(
186 c, 0.f, -s, 0.f,
187 0.f, 1.f, 0.f, 0.f,
188 s, 0.f, c, 0.f,
189 0.f, 0.f, 0.f, 1.f);
190 }
191
192 static mat4 Perspective(float fovY, float aspectRatio, float zNear, float zFar)
193 {
194 float yScale = 1.0f / tan(fovY * 0.5f);
195 float xScale = yScale / aspectRatio;
196 return mat4(
197 xScale, 0.0f, 0.0f, 0.0f,
198 0.0f, yScale, 0.0f, 0.0f,
199 0.0f, 0.0f, zFar / (zFar - zNear), 1.0f,
200 0.0f, 0.0f, -zNear * zFar / (zFar - zNear), 0.0f);
201 }
202
203 static mat4 LookAt(vec3 at, vec3 eye, vec3 up)
204 {
205 vec3 zAxis = (at - eye).Normalized();
206 vec3 xAxis = Cross(up, zAxis).Normalized();
207 vec3 yAxis = Cross(zAxis, xAxis);
208 return mat4(
209 xAxis.x, yAxis.x, zAxis.x, 0.0f,
210 xAxis.y, yAxis.y, zAxis.y, 0.0f,
211 xAxis.z, yAxis.z, zAxis.z, 0.0f,
212 -Dot(xAxis, eye), -Dot(yAxis, eye), -Dot(zAxis, eye), 1.0f);
213 }
214};
215
Adam Sawickib8333fb2018-03-13 16:15:53 +0100216class RandomNumberGenerator
217{
218public:
219 RandomNumberGenerator() : m_Value{GetTickCount()} {}
220 RandomNumberGenerator(uint32_t seed) : m_Value{seed} { }
221 void Seed(uint32_t seed) { m_Value = seed; }
222 uint32_t Generate() { return GenerateFast() ^ (GenerateFast() >> 7); }
223
224private:
225 uint32_t m_Value;
226 uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }
227};
228
Adam Sawicki0a607132018-08-24 11:18:41 +0200229// Wrapper for RandomNumberGenerator compatible with STL "UniformRandomNumberGenerator" idea.
230struct MyUniformRandomNumberGenerator
231{
232 typedef uint32_t result_type;
233 MyUniformRandomNumberGenerator(RandomNumberGenerator& gen) : m_Gen(gen) { }
234 static uint32_t min() { return 0; }
235 static uint32_t max() { return UINT32_MAX; }
236 uint32_t operator()() { return m_Gen.Generate(); }
237
238private:
239 RandomNumberGenerator& m_Gen;
240};
241
Adam Sawickib8333fb2018-03-13 16:15:53 +0100242void ReadFile(std::vector<char>& out, const char* fileName);
243
244enum class CONSOLE_COLOR
245{
246 INFO,
247 NORMAL,
248 WARNING,
249 ERROR_,
250 COUNT
251};
252
253void SetConsoleColor(CONSOLE_COLOR color);
254
255void PrintMessage(CONSOLE_COLOR color, const char* msg);
256void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg);
257
258inline void Print(const char* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
259inline void Print(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
260inline void PrintWarning(const char* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
261inline void PrintWarning(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
262inline void PrintError(const char* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
263inline void PrintError(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
264
265void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList);
266void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList);
267void PrintMessageF(CONSOLE_COLOR color, const char* format, ...);
268void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...);
269void PrintWarningF(const char* format, ...);
270void PrintWarningF(const wchar_t* format, ...);
271void PrintErrorF(const char* format, ...);
272void PrintErrorF(const wchar_t* format, ...);
273
274void SaveFile(const wchar_t* filePath, const void* data, size_t dataSize);
275
Adam Sawickif1a793c2018-03-13 15:42:22 +0100276#endif // #ifdef _WIN32
277
278#endif