Adam Sawicki | ae5c466 | 2019-01-02 10:23:35 +0100 | [diff] [blame] | 1 | //
|
Adam Sawicki | aa18374 | 2021-02-16 17:28:49 +0100 | [diff] [blame^] | 2 | // Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved.
|
Adam Sawicki | ae5c466 | 2019-01-02 10:23:35 +0100 | [diff] [blame] | 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 |
|
Adam Sawicki | f1a793c | 2018-03-13 15:42:22 +0100 | [diff] [blame] | 23 | #ifndef COMMON_H_
|
| 24 | #define COMMON_H_
|
| 25 |
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 26 | #include "VmaUsage.h"
|
| 27 |
|
Adam Sawicki | f1a793c | 2018-03-13 15:42:22 +0100 | [diff] [blame] | 28 | #ifdef _WIN32
|
| 29 |
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 30 | #include <iostream>
|
Adam Sawicki | f1a793c | 2018-03-13 15:42:22 +0100 | [diff] [blame] | 31 | #include <fstream>
|
| 32 | #include <vector>
|
Adam Sawicki | f1a793c | 2018-03-13 15:42:22 +0100 | [diff] [blame] | 33 | #include <memory>
|
| 34 | #include <algorithm>
|
| 35 | #include <numeric>
|
| 36 | #include <array>
|
| 37 | #include <type_traits>
|
| 38 | #include <utility>
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 39 | #include <chrono>
|
| 40 | #include <string>
|
Adam Sawicki | b8d34d5 | 2018-10-03 17:41:20 +0200 | [diff] [blame] | 41 | #include <exception>
|
Adam Sawicki | f1a793c | 2018-03-13 15:42:22 +0100 | [diff] [blame] | 42 |
|
Adam Sawicki | f1a793c | 2018-03-13 15:42:22 +0100 | [diff] [blame] | 43 | #include <cassert>
|
| 44 | #include <cstdlib>
|
| 45 | #include <cstdio>
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 46 | #include <cstdarg>
|
| 47 |
|
| 48 | typedef std::chrono::high_resolution_clock::time_point time_point;
|
| 49 | typedef std::chrono::high_resolution_clock::duration duration;
|
Adam Sawicki | f1a793c | 2018-03-13 15:42:22 +0100 | [diff] [blame] | 50 |
|
Adam Sawicki | b8d34d5 | 2018-10-03 17:41:20 +0200 | [diff] [blame] | 51 | #ifdef _DEBUG
|
| 52 | #define TEST(expr) do { \
|
| 53 | if(!(expr)) { \
|
| 54 | assert(0 && #expr); \
|
| 55 | } \
|
| 56 | } while(0)
|
| 57 | #else
|
| 58 | #define TEST(expr) do { \
|
| 59 | if(!(expr)) { \
|
| 60 | throw std::runtime_error("TEST FAILED: " #expr); \
|
| 61 | } \
|
| 62 | } while(0)
|
| 63 | #endif
|
| 64 |
|
| 65 | #define ERR_GUARD_VULKAN(expr) TEST((expr) >= 0)
|
Adam Sawicki | f1a793c | 2018-03-13 15:42:22 +0100 | [diff] [blame] | 66 |
|
Adam Sawicki | 5088250 | 2020-02-07 16:51:31 +0100 | [diff] [blame] | 67 | extern VkInstance g_hVulkanInstance;
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 68 | extern VkPhysicalDevice g_hPhysicalDevice;
|
| 69 | extern VkDevice g_hDevice;
|
Adam Sawicki | 4ac8ff8 | 2019-11-18 14:47:33 +0100 | [diff] [blame] | 70 | extern VkInstance g_hVulkanInstance;
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 71 | extern VmaAllocator g_hAllocator;
|
Adam Sawicki | 5088250 | 2020-02-07 16:51:31 +0100 | [diff] [blame] | 72 | extern bool VK_AMD_device_coherent_memory_enabled;
|
| 73 |
|
| 74 | void SetAllocatorCreateInfo(VmaAllocatorCreateInfo& outInfo);
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 75 |
|
| 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>
|
| 82 | inline T ceil_div(T x, T y)
|
| 83 | {
|
Adam Sawicki | 82c3f33 | 2018-06-11 15:27:33 +0200 | [diff] [blame] | 84 | return (x+y-1) / y;
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 85 | }
|
Adam Sawicki | ff0f7b8 | 2018-10-18 14:44:05 +0200 | [diff] [blame] | 86 | template <typename T>
|
| 87 | inline T round_div(T x, T y)
|
| 88 | {
|
| 89 | return (x+y/(T)2) / y;
|
| 90 | }
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 91 |
|
| 92 | template <typename T>
|
| 93 | static inline T align_up(T val, T align)
|
| 94 | {
|
Adam Sawicki | 82c3f33 | 2018-06-11 15:27:33 +0200 | [diff] [blame] | 95 | return (val + align - 1) / align * align;
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 96 | }
|
| 97 |
|
Adam Sawicki | 82c3f33 | 2018-06-11 15:27:33 +0200 | [diff] [blame] | 98 | static const float PI = 3.14159265358979323846264338327950288419716939937510582f;
|
| 99 |
|
Adam Sawicki | e73e988 | 2020-03-20 18:05:42 +0100 | [diff] [blame] | 100 | template<typename MainT, typename NewT>
|
| 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>
|
| 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 |
|
Adam Sawicki | 82c3f33 | 2018-06-11 15:27:33 +0200 | [diff] [blame] | 123 | struct vec3
|
| 124 | {
|
| 125 | float x, y, z;
|
| 126 |
|
| 127 | vec3() { }
|
| 128 | 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 |
|
| 137 | vec3 Normalized() const
|
| 138 | {
|
| 139 | return (*this) * (1.f / sqrt(x * x + y * y + z * z));
|
| 140 | }
|
| 141 | };
|
| 142 |
|
| 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 | }
|
| 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 |
|
| 159 | vec4() { }
|
| 160 | vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
|
| 161 | 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 |
|
| 181 | mat4() { }
|
| 182 |
|
| 183 | 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 |
|
| 195 | 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 |
|
| 231 | 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 |
|
| 241 | 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 |
|
| 252 | 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 |
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 265 | class RandomNumberGenerator
|
| 266 | {
|
| 267 | public:
|
| 268 | RandomNumberGenerator() : m_Value{GetTickCount()} {}
|
| 269 | RandomNumberGenerator(uint32_t seed) : m_Value{seed} { }
|
| 270 | void Seed(uint32_t seed) { m_Value = seed; }
|
| 271 | uint32_t Generate() { return GenerateFast() ^ (GenerateFast() >> 7); }
|
| 272 |
|
| 273 | private:
|
| 274 | uint32_t m_Value;
|
| 275 | uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }
|
| 276 | };
|
| 277 |
|
Adam Sawicki | 0a60713 | 2018-08-24 11:18:41 +0200 | [diff] [blame] | 278 | // Wrapper for RandomNumberGenerator compatible with STL "UniformRandomNumberGenerator" idea.
|
| 279 | struct MyUniformRandomNumberGenerator
|
| 280 | {
|
| 281 | typedef uint32_t result_type;
|
| 282 | MyUniformRandomNumberGenerator(RandomNumberGenerator& gen) : m_Gen(gen) { }
|
| 283 | static uint32_t min() { return 0; }
|
| 284 | static uint32_t max() { return UINT32_MAX; }
|
| 285 | uint32_t operator()() { return m_Gen.Generate(); }
|
| 286 |
|
| 287 | private:
|
| 288 | RandomNumberGenerator& m_Gen;
|
| 289 | };
|
| 290 |
|
Adam Sawicki | b8333fb | 2018-03-13 16:15:53 +0100 | [diff] [blame] | 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 |
|
| 307 | inline void Print(const char* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
|
| 308 | inline void Print(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
|
| 309 | inline void PrintWarning(const char* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
|
| 310 | inline void PrintWarning(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
|
| 311 | inline void PrintError(const char* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, 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 |
|
Adam Sawicki | f1a793c | 2018-03-13 15:42:22 +0100 | [diff] [blame] | 325 | #endif // #ifdef _WIN32
|
| 326 |
|
| 327 | #endif
|