First Commit

This commit is contained in:
2025-02-06 22:24:29 +08:00
parent ed7df4c81e
commit 7539e6a53c
18116 changed files with 6181499 additions and 0 deletions

6
externals/vma/src/.editorconfig vendored Normal file
View File

@@ -0,0 +1,6 @@
root = true
[**.{cpp,h}]
indent_style = space
indent_size = 4
end_of_line = lf

95
externals/vma/src/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,95 @@
#
# Copyright (c) 2017-2024 Advanced Micro Devices, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
if (NOT WIN32)
message(STATUS "VmaSample application is only supported on Windows")
return()
endif()
option(VMA_STATIC_VULKAN_FUNCTIONS "Link statically with Vulkan API" ON)
option(VMA_DYNAMIC_VULKAN_FUNCTIONS "Fetch pointers to Vulkan functions internally (no static linking)" OFF)
option(VMA_DEBUG_ALWAYS_DEDICATED_MEMORY "Every allocation will have its own memory block" OFF)
option(VMA_DEBUG_INITIALIZE_ALLOCATIONS "Automatically fill new allocations and destroyed allocations with some bit pattern" OFF)
option(VMA_DEBUG_GLOBAL_MUTEX "Enable single mutex protecting all entry calls to the library" OFF)
option(VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT "Never exceed VkPhysicalDeviceLimits::maxMemoryAllocationCount and return error" OFF)
message(STATUS "VMA_STATIC_VULKAN_FUNCTIONS = ${VMA_STATIC_VULKAN_FUNCTIONS}")
message(STATUS "VMA_DYNAMIC_VULKAN_FUNCTIONS = ${VMA_DYNAMIC_VULKAN_FUNCTIONS}")
message(STATUS "VMA_DEBUG_ALWAYS_DEDICATED_MEMORY = ${VMA_DEBUG_ALWAYS_DEDICATED_MEMORY}")
message(STATUS "VMA_DEBUG_INITIALIZE_ALLOCATIONS = ${VMA_DEBUG_INITIALIZE_ALLOCATIONS}")
message(STATUS "VMA_DEBUG_GLOBAL_MUTEX = ${VMA_DEBUG_GLOBAL_MUTEX}")
message(STATUS "VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT = ${VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT}")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(Vulkan REQUIRED)
add_executable(VmaSample)
target_sources(VmaSample PRIVATE
Common.cpp
Common.h
SparseBindingTest.cpp
SparseBindingTest.h
Tests.cpp
Tests.h
VmaUsage.cpp
VmaUsage.h
VulkanSample.cpp
../include/vk_mem_alloc.h
)
# Only link to Vulkan library if static linking is used, but always add Vulkan headers directory
if(VMA_STATIC_VULKAN_FUNCTIONS)
target_link_libraries(VmaSample PUBLIC Vulkan::Vulkan)
else()
target_link_libraries(VmaSample PUBLIC Vulkan::Headers)
endif()
target_link_libraries(VmaSample PRIVATE GPUOpen::VulkanMemoryAllocator)
target_compile_definitions(VmaSample PUBLIC
VMA_STATIC_VULKAN_FUNCTIONS=$<BOOL:${VMA_STATIC_VULKAN_FUNCTIONS}>
VMA_DYNAMIC_VULKAN_FUNCTIONS=$<BOOL:${VMA_DYNAMIC_VULKAN_FUNCTIONS}>
VMA_DEBUG_ALWAYS_DEDICATED_MEMORY=$<BOOL:${VMA_DEBUG_ALWAYS_DEDICATED_MEMORY}>
VMA_DEBUG_INITIALIZE_ALLOCATIONS=$<BOOL:${VMA_DEBUG_INITIALIZE_ALLOCATIONS}>
VMA_DEBUG_GLOBAL_MUTEX=$<BOOL:${VMA_DEBUG_GLOBAL_MUTEX}>
VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT=$<BOOL:${VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT}>
)
# Provides MSVC users nicer debugging support
target_sources(VmaSample PRIVATE vk_mem_alloc.natvis)
add_subdirectory(Shaders)
add_dependencies(VmaSample VmaSampleShaders)
# Use Unicode instead of multibyte set
add_compile_definitions(UNICODE _UNICODE)
# Add C++ warnings and security checks
add_compile_options(/permissive- /sdl /W3)
# Set VmaSample as startup project
set_property(DIRECTORY "${PROJECT_SOURCE_DIR}" PROPERTY VS_STARTUP_PROJECT "VmaSample")
set_target_properties(VmaSample PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")

328
externals/vma/src/Common.cpp vendored Normal file
View File

@@ -0,0 +1,328 @@
//
// Copyright (c) 2017-2024 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#include "Common.h"
#ifdef _WIN32
void ReadFile(std::vector<char>& out, const char* fileName)
{
std::ifstream file(fileName, std::ios::ate | std::ios::binary);
assert(file.is_open());
size_t fileSize = (size_t)file.tellg();
if(fileSize > 0)
{
out.resize(fileSize);
file.seekg(0);
file.read(out.data(), fileSize);
}
else
out.clear();
}
void SetConsoleColor(CONSOLE_COLOR color)
{
WORD attr = 0;
switch(color)
{
case CONSOLE_COLOR::INFO:
attr = FOREGROUND_INTENSITY;
break;
case CONSOLE_COLOR::NORMAL:
attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
break;
case CONSOLE_COLOR::WARNING:
attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
break;
case CONSOLE_COLOR::ERROR_:
attr = FOREGROUND_RED | FOREGROUND_INTENSITY;
break;
default:
assert(0);
}
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(out, attr);
}
void PrintMessage(CONSOLE_COLOR color, const char* msg)
{
if(color != CONSOLE_COLOR::NORMAL)
SetConsoleColor(color);
printf("%s\n", msg);
if (color != CONSOLE_COLOR::NORMAL)
SetConsoleColor(CONSOLE_COLOR::NORMAL);
}
void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg)
{
if(color != CONSOLE_COLOR::NORMAL)
SetConsoleColor(color);
wprintf(L"%s\n", msg);
if (color != CONSOLE_COLOR::NORMAL)
SetConsoleColor(CONSOLE_COLOR::NORMAL);
}
static const size_t CONSOLE_SMALL_BUF_SIZE = 256;
void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList)
{
size_t dstLen = (size_t)::_vscprintf(format, argList);
if(dstLen)
{
bool useSmallBuf = dstLen < CONSOLE_SMALL_BUF_SIZE;
char smallBuf[CONSOLE_SMALL_BUF_SIZE];
std::vector<char> bigBuf(useSmallBuf ? 0 : dstLen + 1);
char* bufPtr = useSmallBuf ? smallBuf : bigBuf.data();
::vsprintf_s(bufPtr, dstLen + 1, format, argList);
PrintMessage(color, bufPtr);
}
}
void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList)
{
size_t dstLen = (size_t)::_vcwprintf(format, argList);
if(dstLen)
{
bool useSmallBuf = dstLen < CONSOLE_SMALL_BUF_SIZE;
wchar_t smallBuf[CONSOLE_SMALL_BUF_SIZE];
std::vector<wchar_t> bigBuf(useSmallBuf ? 0 : dstLen + 1);
wchar_t* bufPtr = useSmallBuf ? smallBuf : bigBuf.data();
::vswprintf_s(bufPtr, dstLen + 1, format, argList);
PrintMessage(color, bufPtr);
}
}
void PrintMessageF(CONSOLE_COLOR color, const char* format, ...)
{
va_list argList;
va_start(argList, format);
PrintMessageV(color, format, argList);
va_end(argList);
}
void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...)
{
va_list argList;
va_start(argList, format);
PrintMessageV(color, format, argList);
va_end(argList);
}
void PrintWarningF(const char* format, ...)
{
va_list argList;
va_start(argList, format);
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
va_end(argList);
}
void PrintWarningF(const wchar_t* format, ...)
{
va_list argList;
va_start(argList, format);
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
va_end(argList);
}
void PrintErrorF(const char* format, ...)
{
va_list argList;
va_start(argList, format);
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
va_end(argList);
}
void PrintErrorF(const wchar_t* format, ...)
{
va_list argList;
va_start(argList, format);
PrintMessageV(CONSOLE_COLOR::WARNING, format, argList);
va_end(argList);
}
void SaveFile(const wchar_t* filePath, const void* data, size_t dataSize)
{
FILE* f = nullptr;
_wfopen_s(&f, filePath, L"wb");
if(f)
{
fwrite(data, 1, dataSize, f);
fclose(f);
}
else
assert(0);
}
std::wstring SizeToStr(size_t size)
{
if(size == 0)
return L"0";
wchar_t result[32];
double size2 = (double)size;
if (size2 >= 1024.0*1024.0*1024.0*1024.0)
{
swprintf_s(result, L"%.2f TB", size2 / (1024.0*1024.0*1024.0*1024.0));
}
else if (size2 >= 1024.0*1024.0*1024.0)
{
swprintf_s(result, L"%.2f GB", size2 / (1024.0*1024.0*1024.0));
}
else if (size2 >= 1024.0*1024.0)
{
swprintf_s(result, L"%.2f MB", size2 / (1024.0*1024.0));
}
else if (size2 >= 1024.0)
{
swprintf_s(result, L"%.2f KB", size2 / 1024.0);
}
else
swprintf_s(result, L"%llu B", size);
return result;
}
bool ConvertCharsToUnicode(std::wstring *outStr, const std::string &s, unsigned codePage)
{
if (s.empty())
{
outStr->clear();
return true;
}
// Phase 1 - Get buffer size.
const int size = MultiByteToWideChar(codePage, 0, s.data(), (int)s.length(), NULL, 0);
if (size == 0)
{
outStr->clear();
return false;
}
// Phase 2 - Do conversion.
std::unique_ptr<wchar_t[]> buf(new wchar_t[(size_t)size]);
int result = MultiByteToWideChar(codePage, 0, s.data(), (int)s.length(), buf.get(), size);
if (result == 0)
{
outStr->clear();
return false;
}
outStr->assign(buf.get(), (size_t)size);
return true;
}
bool ConvertCharsToUnicode(std::wstring *outStr, const char *s, size_t sCharCount, unsigned codePage)
{
if (sCharCount == 0)
{
outStr->clear();
return true;
}
assert(sCharCount <= (size_t)INT_MAX);
// Phase 1 - Get buffer size.
int size = MultiByteToWideChar(codePage, 0, s, (int)sCharCount, NULL, 0);
if (size == 0)
{
outStr->clear();
return false;
}
// Phase 2 - Do conversion.
std::unique_ptr<wchar_t[]> buf(new wchar_t[(size_t)size]);
int result = MultiByteToWideChar(codePage, 0, s, (int)sCharCount, buf.get(), size);
if (result == 0)
{
outStr->clear();
return false;
}
outStr->assign(buf.get(), (size_t)size);
return true;
}
const wchar_t* PhysicalDeviceTypeToStr(VkPhysicalDeviceType type)
{
// Skipping common prefix VK_PHYSICAL_DEVICE_TYPE_
static const wchar_t* const VALUES[] = {
L"OTHER",
L"INTEGRATED_GPU",
L"DISCRETE_GPU",
L"VIRTUAL_GPU",
L"CPU",
};
return (uint32_t)type < _countof(VALUES) ? VALUES[(uint32_t)type] : L"";
}
const wchar_t* VendorIDToStr(uint32_t vendorID)
{
switch(vendorID)
{
// Skipping common prefix VK_VENDOR_ID_ for these:
case 0x10001: return L"VIV";
case 0x10002: return L"VSI";
case 0x10003: return L"KAZAN";
case 0x10004: return L"CODEPLAY";
case 0x10005: return L"MESA";
case 0x10006: return L"POCL";
// Others...
case VENDOR_ID_AMD: return L"AMD";
case VENDOR_ID_NVIDIA: return L"NVIDIA";
case VENDOR_ID_INTEL: return L"Intel";
case 0x1010: return L"ImgTec";
case 0x13B5: return L"ARM";
case 0x5143: return L"Qualcomm";
}
return L"";
}
#if VMA_VULKAN_VERSION >= 1002000
const wchar_t* DriverIDToStr(VkDriverId driverID)
{
// Skipping common prefix VK_DRIVER_ID_
static const wchar_t* const VALUES[] = {
L"",
L"AMD_PROPRIETARY",
L"AMD_OPEN_SOURCE",
L"MESA_RADV",
L"NVIDIA_PROPRIETARY",
L"INTEL_PROPRIETARY_WINDOWS",
L"INTEL_OPEN_SOURCE_MESA",
L"IMAGINATION_PROPRIETARY",
L"QUALCOMM_PROPRIETARY",
L"ARM_PROPRIETARY",
L"GOOGLE_SWIFTSHADER",
L"GGP_PROPRIETARY",
L"BROADCOM_PROPRIETARY",
L"MESA_LLVMPIPE",
L"MOLTENVK",
};
return (uint32_t)driverID < _countof(VALUES) ? VALUES[(uint32_t)driverID] : L"";
}
#endif // #if VMA_VULKAN_VERSION >= 1002000
#endif // #ifdef _WIN32

339
externals/vma/src/Common.h vendored Normal file
View File

@@ -0,0 +1,339 @@
//
// Copyright (c) 2017-2024 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#ifndef COMMON_H_
#define COMMON_H_
#include "VmaUsage.h"
#ifdef _WIN32
#include <iostream>
#include <fstream>
#include <vector>
#include <memory>
#include <algorithm>
#include <numeric>
#include <array>
#include <type_traits>
#include <utility>
#include <chrono>
#include <string>
#include <exception>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <cstdarg>
typedef std::chrono::high_resolution_clock::time_point time_point;
typedef std::chrono::high_resolution_clock::duration duration;
#define STRINGIZE(x) STRINGIZE2(x)
#define STRINGIZE2(x) #x
#define LINE_STRING STRINGIZE(__LINE__)
#define TEST(expr) do { if(!(expr)) { \
assert(0 && #expr); \
throw std::runtime_error(__FILE__ "(" LINE_STRING "): ( " #expr " ) == false"); \
} } while(false)
#define ERR_GUARD_VULKAN(expr) do { if((expr) < 0) { \
assert(0 && #expr); \
throw std::runtime_error(__FILE__ "(" LINE_STRING "): VkResult( " #expr " ) < 0"); \
} } while(false)
static const uint32_t VENDOR_ID_AMD = 0x1002;
static const uint32_t VENDOR_ID_NVIDIA = 0x10DE;
static const uint32_t VENDOR_ID_INTEL = 0x8086;
extern VkInstance g_hVulkanInstance;
extern VkPhysicalDevice g_hPhysicalDevice;
extern VkDevice g_hDevice;
extern VkInstance g_hVulkanInstance;
extern VmaAllocator g_hAllocator;
extern bool VK_AMD_device_coherent_memory_enabled;
void SetAllocatorCreateInfo(VmaAllocatorCreateInfo& outInfo);
inline float ToFloatSeconds(duration d)
{
return std::chrono::duration_cast<std::chrono::duration<float>>(d).count();
}
template <typename T>
inline T ceil_div(T x, T y)
{
return (x+y-1) / y;
}
template <typename T>
inline T round_div(T x, T y)
{
return (x+y/(T)2) / y;
}
template <typename T>
static inline T align_up(T val, T align)
{
return (val + align - 1) / align * align;
}
static const float PI = 3.14159265358979323846264338327950288419716939937510582f;
template<typename MainT, typename NewT>
inline void PnextChainPushFront(MainT* mainStruct, NewT* newStruct)
{
newStruct->pNext = mainStruct->pNext;
mainStruct->pNext = newStruct;
}
template<typename MainT, typename NewT>
inline void PnextChainPushBack(MainT* mainStruct, NewT* newStruct)
{
struct VkAnyStruct
{
VkStructureType sType;
void* pNext;
};
VkAnyStruct* lastStruct = (VkAnyStruct*)mainStruct;
while(lastStruct->pNext != nullptr)
{
lastStruct = (VkAnyStruct*)lastStruct->pNext;
}
newStruct->pNext = nullptr;
lastStruct->pNext = newStruct;
}
struct vec3
{
float x, y, z;
vec3() { }
vec3(float x, float y, float z) : x(x), y(y), z(z) { }
float& operator[](uint32_t index) { return *(&x + index); }
const float& operator[](uint32_t index) const { return *(&x + index); }
vec3 operator+(const vec3& rhs) const { return vec3(x + rhs.x, y + rhs.y, z + rhs.z); }
vec3 operator-(const vec3& rhs) const { return vec3(x - rhs.x, y - rhs.y, z - rhs.z); }
vec3 operator*(float s) const { return vec3(x * s, y * s, z * s); }
vec3 Normalized() const
{
return (*this) * (1.f / sqrt(x * x + y * y + z * z));
}
};
inline float Dot(const vec3& lhs, const vec3& rhs)
{
return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
}
inline vec3 Cross(const vec3& lhs, const vec3& rhs)
{
return vec3(
lhs.y * rhs.z - lhs.z * rhs.y,
lhs.z * rhs.x - lhs.x * rhs.z,
lhs.x * rhs.y - lhs.y * rhs.x);
}
struct vec4
{
float x, y, z, w;
vec4() { }
vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
vec4(const vec3& v, float w) : x(v.x), y(v.y), z(v.z), w(w) { }
float& operator[](uint32_t index) { return *(&x + index); }
const float& operator[](uint32_t index) const { return *(&x + index); }
};
struct mat4
{
union
{
struct
{
float _11, _12, _13, _14;
float _21, _22, _23, _24;
float _31, _32, _33, _34;
float _41, _42, _43, _44;
};
float m[4][4]; // [row][column]
};
mat4() { }
mat4(
float _11, float _12, float _13, float _14,
float _21, float _22, float _23, float _24,
float _31, float _32, float _33, float _34,
float _41, float _42, float _43, float _44) :
_11(_11), _12(_12), _13(_13), _14(_14),
_21(_21), _22(_22), _23(_23), _24(_24),
_31(_31), _32(_32), _33(_33), _34(_34),
_41(_41), _42(_42), _43(_43), _44(_44)
{
}
mat4(
const vec4& row1,
const vec4& row2,
const vec4& row3,
const vec4& row4) :
_11(row1.x), _12(row1.y), _13(row1.z), _14(row1.w),
_21(row2.x), _22(row2.y), _23(row2.z), _24(row2.w),
_31(row3.x), _32(row3.y), _33(row3.z), _34(row3.w),
_41(row4.x), _42(row4.y), _43(row4.z), _44(row4.w)
{
}
mat4 operator*(const mat4 &rhs) const
{
return mat4(
_11 * rhs._11 + _12 * rhs._21 + _13 * rhs._31 + _14 * rhs._41,
_11 * rhs._12 + _12 * rhs._22 + _13 * rhs._32 + _14 * rhs._42,
_11 * rhs._13 + _12 * rhs._23 + _13 * rhs._33 + _14 * rhs._43,
_11 * rhs._14 + _12 * rhs._24 + _13 * rhs._34 + _14 * rhs._44,
_21 * rhs._11 + _22 * rhs._21 + _23 * rhs._31 + _24 * rhs._41,
_21 * rhs._12 + _22 * rhs._22 + _23 * rhs._32 + _24 * rhs._42,
_21 * rhs._13 + _22 * rhs._23 + _23 * rhs._33 + _24 * rhs._43,
_21 * rhs._14 + _22 * rhs._24 + _23 * rhs._34 + _24 * rhs._44,
_31 * rhs._11 + _32 * rhs._21 + _33 * rhs._31 + _34 * rhs._41,
_31 * rhs._12 + _32 * rhs._22 + _33 * rhs._32 + _34 * rhs._42,
_31 * rhs._13 + _32 * rhs._23 + _33 * rhs._33 + _34 * rhs._43,
_31 * rhs._14 + _32 * rhs._24 + _33 * rhs._34 + _34 * rhs._44,
_41 * rhs._11 + _42 * rhs._21 + _43 * rhs._31 + _44 * rhs._41,
_41 * rhs._12 + _42 * rhs._22 + _43 * rhs._32 + _44 * rhs._42,
_41 * rhs._13 + _42 * rhs._23 + _43 * rhs._33 + _44 * rhs._43,
_41 * rhs._14 + _42 * rhs._24 + _43 * rhs._34 + _44 * rhs._44);
}
static mat4 RotationY(float angle)
{
const float s = sin(angle), c = cos(angle);
return mat4(
c, 0.f, -s, 0.f,
0.f, 1.f, 0.f, 0.f,
s, 0.f, c, 0.f,
0.f, 0.f, 0.f, 1.f);
}
static mat4 Perspective(float fovY, float aspectRatio, float zNear, float zFar)
{
float yScale = 1.0f / tan(fovY * 0.5f);
float xScale = yScale / aspectRatio;
return mat4(
xScale, 0.0f, 0.0f, 0.0f,
0.0f, yScale, 0.0f, 0.0f,
0.0f, 0.0f, zFar / (zFar - zNear), 1.0f,
0.0f, 0.0f, -zNear * zFar / (zFar - zNear), 0.0f);
}
static mat4 LookAt(vec3 at, vec3 eye, vec3 up)
{
vec3 zAxis = (at - eye).Normalized();
vec3 xAxis = Cross(up, zAxis).Normalized();
vec3 yAxis = Cross(zAxis, xAxis);
return mat4(
xAxis.x, yAxis.x, zAxis.x, 0.0f,
xAxis.y, yAxis.y, zAxis.y, 0.0f,
xAxis.z, yAxis.z, zAxis.z, 0.0f,
-Dot(xAxis, eye), -Dot(yAxis, eye), -Dot(zAxis, eye), 1.0f);
}
};
class RandomNumberGenerator
{
public:
RandomNumberGenerator() : m_Value{GetTickCount()} {}
RandomNumberGenerator(uint32_t seed) : m_Value{seed} { }
void Seed(uint32_t seed) { m_Value = seed; }
uint32_t Generate() { return GenerateFast() ^ (GenerateFast() >> 7); }
private:
uint32_t m_Value;
uint32_t GenerateFast() { return m_Value = (m_Value * 196314165 + 907633515); }
};
// Wrapper for RandomNumberGenerator compatible with STL "UniformRandomNumberGenerator" idea.
struct MyUniformRandomNumberGenerator
{
typedef uint32_t result_type;
MyUniformRandomNumberGenerator(RandomNumberGenerator& gen) : m_Gen(gen) { }
static uint32_t min() { return 0; }
static uint32_t max() { return UINT32_MAX; }
uint32_t operator()() { return m_Gen.Generate(); }
private:
RandomNumberGenerator& m_Gen;
};
void ReadFile(std::vector<char>& out, const char* fileName);
enum class CONSOLE_COLOR
{
INFO,
NORMAL,
WARNING,
ERROR_,
COUNT
};
void SetConsoleColor(CONSOLE_COLOR color);
void PrintMessage(CONSOLE_COLOR color, const char* msg);
void PrintMessage(CONSOLE_COLOR color, const wchar_t* msg);
inline void Print(const char* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
inline void Print(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::NORMAL, msg); }
inline void PrintWarning(const char* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
inline void PrintWarning(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::WARNING, msg); }
inline void PrintError(const char* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
inline void PrintError(const wchar_t* msg) { PrintMessage(CONSOLE_COLOR::ERROR_, msg); }
void PrintMessageV(CONSOLE_COLOR color, const char* format, va_list argList);
void PrintMessageV(CONSOLE_COLOR color, const wchar_t* format, va_list argList);
void PrintMessageF(CONSOLE_COLOR color, const char* format, ...);
void PrintMessageF(CONSOLE_COLOR color, const wchar_t* format, ...);
void PrintWarningF(const char* format, ...);
void PrintWarningF(const wchar_t* format, ...);
void PrintErrorF(const char* format, ...);
void PrintErrorF(const wchar_t* format, ...);
void SaveFile(const wchar_t* filePath, const void* data, size_t dataSize);
std::wstring SizeToStr(size_t size);
// As codePage use e.g. CP_ACP for native Windows 1-byte codepage or CP_UTF8.
bool ConvertCharsToUnicode(std::wstring *outStr, const std::string &s, unsigned codePage);
bool ConvertCharsToUnicode(std::wstring *outStr, const char *s, size_t sCharCount, unsigned codePage);
const wchar_t* PhysicalDeviceTypeToStr(VkPhysicalDeviceType type);
const wchar_t* VendorIDToStr(uint32_t vendorID);
#if VMA_VULKAN_VERSION >= 1002000
const wchar_t* DriverIDToStr(VkDriverId driverID);
#endif
#endif // #ifdef _WIN32
#endif

View File

@@ -0,0 +1,32 @@
# This file will only be executed if VMA_BUILD_SAMPLE_SHADERS is set to ON
find_program(GLSL_VALIDATOR glslangValidator REQUIRED)
if(NOT GLSL_VALIDATOR)
message(FATAL_ERROR "glslangValidator not found!")
endif()
set(SHADERS
Shader.vert
Shader.frag
SparseBindingTest.comp
)
# Compile each shader using glslangValidator
foreach(SHADER ${SHADERS})
get_filename_component(FILE_NAME ${SHADER} NAME)
# Put the .spv files into the bin folder
set(SPIRV ${PROJECT_SOURCE_DIR}/bin/${FILE_NAME}.spv)
add_custom_command(
OUTPUT ${SPIRV}
# Use the same file name and append .spv to the compiled shader
COMMAND ${GLSL_VALIDATOR} -V ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER} -o ${SPIRV}
DEPENDS ${SHADER}
)
list(APPEND SPIRV_FILES ${SPIRV})
endforeach()
add_custom_target(VmaSampleShaders ALL DEPENDS ${SPIRV_FILES})

View File

@@ -0,0 +1,4 @@
%VULKAN_SDK%/Bin32/glslangValidator.exe -V -o ../../bin/Shader.vert.spv Shader.vert
%VULKAN_SDK%/Bin32/glslangValidator.exe -V -o ../../bin/Shader.frag.spv Shader.frag
%VULKAN_SDK%/Bin32/glslangValidator.exe -V -o ../../bin/SparseBindingTest.comp.spv SparseBindingTest.comp
pause

37
externals/vma/src/Shaders/Shader.frag vendored Normal file
View File

@@ -0,0 +1,37 @@
//
// Copyright (c) 2017-2022 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(location = 0) in vec3 inColor;
layout(location = 1) in vec2 inTexCoord;
layout(location = 0) out vec4 outColor;
layout(binding = 1) uniform sampler2D texSampler;
void main()
{
outColor = texture(texSampler, inTexCoord);
outColor.rgb *= inColor;
}

42
externals/vma/src/Shaders/Shader.vert vendored Normal file
View File

@@ -0,0 +1,42 @@
//
// Copyright (c) 2017-2022 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(push_constant) uniform UniformBufferObject
{
mat4 ModelViewProj;
} ubo;
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec2 inTexCoord;
layout(location = 0) out vec3 outColor;
layout(location = 1) out vec2 outTexCoord;
void main() {
gl_Position = ubo.ModelViewProj * vec4(inPosition, 1.0);
outColor = inColor;
outTexCoord = inTexCoord;
}

View File

@@ -0,0 +1,44 @@
//
// Copyright (c) 2018-2022 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#version 450
#extension GL_ARB_separate_shader_objects : enable
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(binding=0) uniform sampler2D img;
layout(binding=1) buffer buf
{
uint bufValues[];
};
void main()
{
ivec2 xy = ivec2(bufValues[gl_GlobalInvocationID.x * 3],
bufValues[gl_GlobalInvocationID.x * 3 + 1]);
vec4 color = texture(img, xy);
bufValues[gl_GlobalInvocationID.x * 3 + 2] =
uint(color.r * 255.0) << 24 |
uint(color.g * 255.0) << 16 |
uint(color.b * 255.0) << 8 |
uint(color.a * 255.0);
}

597
externals/vma/src/SparseBindingTest.cpp vendored Normal file
View File

@@ -0,0 +1,597 @@
//
// Copyright (c) 2017-2024 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#include "Common.h"
#include "SparseBindingTest.h"
#ifdef _WIN32
////////////////////////////////////////////////////////////////////////////////
// External imports
extern VkDevice g_hDevice;
extern VmaAllocator g_hAllocator;
extern uint32_t g_FrameIndex;
extern bool g_SparseBindingEnabled;
extern VkQueue g_hSparseBindingQueue;
extern VkFence g_ImmediateFence;
extern VkCommandBuffer g_hTemporaryCommandBuffer;
void BeginSingleTimeCommands();
void EndSingleTimeCommands();
void SaveAllocatorStatsToFile(const wchar_t* filePath, bool detailed = true);
void LoadShader(std::vector<char>& out, const char* fileName);
////////////////////////////////////////////////////////////////////////////////
// Class definitions
static uint32_t CalculateMipMapCount(uint32_t width, uint32_t height, uint32_t depth)
{
uint32_t mipMapCount = 1;
while(width > 1 || height > 1 || depth > 1)
{
++mipMapCount;
width /= 2;
height /= 2;
depth /= 2;
}
return mipMapCount;
}
class BaseImage
{
public:
virtual void Init(RandomNumberGenerator& rand) = 0;
virtual ~BaseImage();
const VkImageCreateInfo& GetCreateInfo() const { return m_CreateInfo; }
void TestContent(RandomNumberGenerator& rand);
protected:
VkImageCreateInfo m_CreateInfo = {};
VkImage m_Image = VK_NULL_HANDLE;
void FillImageCreateInfo(RandomNumberGenerator& rand);
void UploadContent();
void ValidateContent(RandomNumberGenerator& rand);
};
class TraditionalImage : public BaseImage
{
public:
virtual void Init(RandomNumberGenerator& rand);
virtual ~TraditionalImage();
private:
VmaAllocation m_Allocation = VK_NULL_HANDLE;
};
class SparseBindingImage : public BaseImage
{
public:
virtual void Init(RandomNumberGenerator& rand);
virtual ~SparseBindingImage();
private:
std::vector<VmaAllocation> m_Allocations;
};
////////////////////////////////////////////////////////////////////////////////
// class BaseImage
BaseImage::~BaseImage()
{
if(m_Image)
{
vkDestroyImage(g_hDevice, m_Image, nullptr);
}
}
void BaseImage::TestContent(RandomNumberGenerator& rand)
{
printf("Validating content of %u x %u texture...\n",
m_CreateInfo.extent.width, m_CreateInfo.extent.height);
UploadContent();
ValidateContent(rand);
}
void BaseImage::FillImageCreateInfo(RandomNumberGenerator& rand)
{
constexpr uint32_t imageSizeMin = 8;
constexpr uint32_t imageSizeMax = 2048;
const bool useMipMaps = rand.Generate() % 2 != 0;
ZeroMemory(&m_CreateInfo, sizeof(m_CreateInfo));
m_CreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
m_CreateInfo.imageType = VK_IMAGE_TYPE_2D;
m_CreateInfo.extent.width = rand.Generate() % (imageSizeMax - imageSizeMin) + imageSizeMin;
m_CreateInfo.extent.height = rand.Generate() % (imageSizeMax - imageSizeMin) + imageSizeMin;
m_CreateInfo.extent.depth = 1;
m_CreateInfo.mipLevels = useMipMaps ?
CalculateMipMapCount(m_CreateInfo.extent.width, m_CreateInfo.extent.height, m_CreateInfo.extent.depth) : 1;
m_CreateInfo.arrayLayers = 1;
m_CreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
m_CreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
m_CreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
m_CreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
m_CreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
m_CreateInfo.flags = 0;
}
void BaseImage::UploadContent()
{
VkBufferCreateInfo srcBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
srcBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
srcBufCreateInfo.size = 4 * m_CreateInfo.extent.width * m_CreateInfo.extent.height;
VmaAllocationCreateInfo srcBufAllocCreateInfo = {};
srcBufAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
srcBufAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
VkBuffer srcBuf = nullptr;
VmaAllocation srcBufAlloc = nullptr;
VmaAllocationInfo srcAllocInfo = {};
TEST( vmaCreateBuffer(g_hAllocator, &srcBufCreateInfo, &srcBufAllocCreateInfo, &srcBuf, &srcBufAlloc, &srcAllocInfo) == VK_SUCCESS );
// Fill texels with: r = x % 255, g = u % 255, b = 13, a = 25
uint32_t* srcBufPtr = (uint32_t*)srcAllocInfo.pMappedData;
for(uint32_t y = 0, sizeY = m_CreateInfo.extent.height; y < sizeY; ++y)
{
for(uint32_t x = 0, sizeX = m_CreateInfo.extent.width; x < sizeX; ++x, ++srcBufPtr)
{
const uint8_t r = (uint8_t)x;
const uint8_t g = (uint8_t)y;
const uint8_t b = 13;
const uint8_t a = 25;
*srcBufPtr = (uint32_t)r << 24 | (uint32_t)g << 16 |
(uint32_t)b << 8 | (uint32_t)a;
}
}
BeginSingleTimeCommands();
// Barrier undefined to transfer dst.
{
VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = m_Image;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.layerCount = 1;
barrier.subresourceRange.levelCount = 1;
vkCmdPipelineBarrier(g_hTemporaryCommandBuffer,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // srcStageMask
VK_PIPELINE_STAGE_TRANSFER_BIT, // dstStageMask
0, // dependencyFlags
0, nullptr, // memoryBarriers
0, nullptr, // bufferMemoryBarriers
1, &barrier); // imageMemoryBarriers
}
// CopyBufferToImage
{
VkBufferImageCopy region = {};
region.bufferOffset = 0;
region.bufferRowLength = 0; // Zeros mean tightly packed.
region.bufferImageHeight = 0; // Zeros mean tightly packed.
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
region.imageOffset = { 0, 0, 0 };
region.imageExtent = m_CreateInfo.extent;
vkCmdCopyBufferToImage(g_hTemporaryCommandBuffer, srcBuf, m_Image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
}
// Barrier transfer dst to fragment shader read only.
{
VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER };
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = m_Image;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.layerCount = 1;
barrier.subresourceRange.levelCount = 1;
vkCmdPipelineBarrier(g_hTemporaryCommandBuffer,
VK_PIPELINE_STAGE_TRANSFER_BIT, // srcStageMask
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // dstStageMask
0, // dependencyFlags
0, nullptr, // memoryBarriers
0, nullptr, // bufferMemoryBarriers
1, &barrier); // imageMemoryBarriers
}
EndSingleTimeCommands();
vmaDestroyBuffer(g_hAllocator, srcBuf, srcBufAlloc);
}
void BaseImage::ValidateContent(RandomNumberGenerator& rand)
{
/*
dstBuf has following layout:
For each of texels to be sampled, [0..valueCount):
struct {
in uint32_t pixelX;
in uint32_t pixelY;
out uint32_t pixelColor;
}
*/
const uint32_t valueCount = 128;
VkBufferCreateInfo dstBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
dstBufCreateInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
dstBufCreateInfo.size = valueCount * sizeof(uint32_t) * 3;
VmaAllocationCreateInfo dstBufAllocCreateInfo = {};
dstBufAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
dstBufAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
VkBuffer dstBuf = nullptr;
VmaAllocation dstBufAlloc = nullptr;
VmaAllocationInfo dstBufAllocInfo = {};
TEST( vmaCreateBuffer(g_hAllocator, &dstBufCreateInfo, &dstBufAllocCreateInfo, &dstBuf, &dstBufAlloc, &dstBufAllocInfo) == VK_SUCCESS );
// Fill dstBuf input data.
{
uint32_t* dstBufContent = (uint32_t*)dstBufAllocInfo.pMappedData;
for(uint32_t i = 0; i < valueCount; ++i)
{
const uint32_t x = rand.Generate() % m_CreateInfo.extent.width;
const uint32_t y = rand.Generate() % m_CreateInfo.extent.height;
dstBufContent[i * 3 ] = x;
dstBufContent[i * 3 + 1] = y;
dstBufContent[i * 3 + 2] = 0;
}
}
VkSamplerCreateInfo samplerCreateInfo = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
samplerCreateInfo.magFilter = VK_FILTER_NEAREST;
samplerCreateInfo.minFilter = VK_FILTER_NEAREST;
samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerCreateInfo.unnormalizedCoordinates = VK_TRUE;
VkSampler sampler = nullptr;
TEST( vkCreateSampler( g_hDevice, &samplerCreateInfo, nullptr, &sampler) == VK_SUCCESS );
VkDescriptorSetLayoutBinding bindings[2] = {};
bindings[0].binding = 0;
bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
bindings[0].descriptorCount = 1;
bindings[0].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
bindings[0].pImmutableSamplers = &sampler;
bindings[1].binding = 1;
bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
bindings[1].descriptorCount = 1;
bindings[1].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
VkDescriptorSetLayoutCreateInfo descSetLayoutCreateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO };
descSetLayoutCreateInfo.bindingCount = 2;
descSetLayoutCreateInfo.pBindings = bindings;
VkDescriptorSetLayout descSetLayout = nullptr;
TEST( vkCreateDescriptorSetLayout(g_hDevice, &descSetLayoutCreateInfo, nullptr, &descSetLayout) == VK_SUCCESS );
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
pipelineLayoutCreateInfo.setLayoutCount = 1;
pipelineLayoutCreateInfo.pSetLayouts = &descSetLayout;
VkPipelineLayout pipelineLayout = nullptr;
TEST( vkCreatePipelineLayout(g_hDevice, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout) == VK_SUCCESS );
std::vector<char> shaderCode;
LoadShader(shaderCode, "SparseBindingTest.comp.spv");
VkShaderModuleCreateInfo shaderModuleCreateInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO };
shaderModuleCreateInfo.codeSize = shaderCode.size();
shaderModuleCreateInfo.pCode = (const uint32_t*)shaderCode.data();
VkShaderModule shaderModule = nullptr;
TEST( vkCreateShaderModule(g_hDevice, &shaderModuleCreateInfo, nullptr, &shaderModule) == VK_SUCCESS );
VkComputePipelineCreateInfo pipelineCreateInfo = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO };
pipelineCreateInfo.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
pipelineCreateInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
pipelineCreateInfo.stage.module = shaderModule;
pipelineCreateInfo.stage.pName = "main";
pipelineCreateInfo.layout = pipelineLayout;
VkPipeline pipeline = nullptr;
TEST( vkCreateComputePipelines(g_hDevice, nullptr, 1, &pipelineCreateInfo, nullptr, &pipeline) == VK_SUCCESS );
VkDescriptorPoolSize poolSizes[2] = {};
poolSizes[0].type = bindings[0].descriptorType;
poolSizes[0].descriptorCount = bindings[0].descriptorCount;
poolSizes[1].type = bindings[1].descriptorType;
poolSizes[1].descriptorCount = bindings[1].descriptorCount;
VkDescriptorPoolCreateInfo descPoolCreateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
descPoolCreateInfo.maxSets = 1;
descPoolCreateInfo.poolSizeCount = 2;
descPoolCreateInfo.pPoolSizes = poolSizes;
VkDescriptorPool descPool = nullptr;
TEST( vkCreateDescriptorPool(g_hDevice, &descPoolCreateInfo, nullptr, &descPool) == VK_SUCCESS );
VkDescriptorSetAllocateInfo descSetAllocInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO };
descSetAllocInfo.descriptorPool = descPool;
descSetAllocInfo.descriptorSetCount = 1;
descSetAllocInfo.pSetLayouts = &descSetLayout;
VkDescriptorSet descSet = nullptr;
TEST( vkAllocateDescriptorSets(g_hDevice, &descSetAllocInfo, &descSet) == VK_SUCCESS );
VkImageViewCreateInfo imageViewCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO };
imageViewCreateInfo.image = m_Image;
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
imageViewCreateInfo.format = m_CreateInfo.format;
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageViewCreateInfo.subresourceRange.layerCount = 1;
imageViewCreateInfo.subresourceRange.levelCount = 1;
VkImageView imageView = nullptr;
TEST( vkCreateImageView(g_hDevice, &imageViewCreateInfo, nullptr, &imageView) == VK_SUCCESS );
VkDescriptorImageInfo descImageInfo = {};
descImageInfo.imageView = imageView;
descImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
VkDescriptorBufferInfo descBufferInfo = {};
descBufferInfo.buffer = dstBuf;
descBufferInfo.offset = 0;
descBufferInfo.range = VK_WHOLE_SIZE;
VkWriteDescriptorSet descWrites[2] = {};
descWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descWrites[0].dstSet = descSet;
descWrites[0].dstBinding = bindings[0].binding;
descWrites[0].dstArrayElement = 0;
descWrites[0].descriptorCount = 1;
descWrites[0].descriptorType = bindings[0].descriptorType;
descWrites[0].pImageInfo = &descImageInfo;
descWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descWrites[1].dstSet = descSet;
descWrites[1].dstBinding = bindings[1].binding;
descWrites[1].dstArrayElement = 0;
descWrites[1].descriptorCount = 1;
descWrites[1].descriptorType = bindings[1].descriptorType;
descWrites[1].pBufferInfo = &descBufferInfo;
vkUpdateDescriptorSets(g_hDevice, 2, descWrites, 0, nullptr);
BeginSingleTimeCommands();
vkCmdBindPipeline(g_hTemporaryCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
vkCmdBindDescriptorSets(g_hTemporaryCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descSet, 0, nullptr);
vkCmdDispatch(g_hTemporaryCommandBuffer, valueCount, 1, 1);
EndSingleTimeCommands();
// Validate dstBuf output data.
{
const uint32_t* dstBufContent = (const uint32_t*)dstBufAllocInfo.pMappedData;
for(uint32_t i = 0; i < valueCount; ++i)
{
const uint32_t x = dstBufContent[i * 3 ];
const uint32_t y = dstBufContent[i * 3 + 1];
const uint32_t color = dstBufContent[i * 3 + 2];
const uint8_t a = (uint8_t)(color >> 24);
const uint8_t b = (uint8_t)(color >> 16);
const uint8_t g = (uint8_t)(color >> 8);
const uint8_t r = (uint8_t)color;
TEST(r == (uint8_t)x && g == (uint8_t)y && b == 13 && a == 25);
}
}
vkDestroyImageView(g_hDevice, imageView, nullptr);
vkDestroyDescriptorPool(g_hDevice, descPool, nullptr);
vmaDestroyBuffer(g_hAllocator, dstBuf, dstBufAlloc);
vkDestroyPipeline(g_hDevice, pipeline, nullptr);
vkDestroyShaderModule(g_hDevice, shaderModule, nullptr);
vkDestroyPipelineLayout(g_hDevice, pipelineLayout, nullptr);
vkDestroyDescriptorSetLayout(g_hDevice, descSetLayout, nullptr);
vkDestroySampler(g_hDevice, sampler, nullptr);
}
////////////////////////////////////////////////////////////////////////////////
// class TraditionalImage
void TraditionalImage::Init(RandomNumberGenerator& rand)
{
FillImageCreateInfo(rand);
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
// Default BEST_FIT is clearly better.
//allocCreateInfo.flags |= VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT;
ERR_GUARD_VULKAN( vmaCreateImage(g_hAllocator, &m_CreateInfo, &allocCreateInfo,
&m_Image, &m_Allocation, nullptr) );
}
TraditionalImage::~TraditionalImage()
{
if(m_Allocation)
{
vmaFreeMemory(g_hAllocator, m_Allocation);
}
}
////////////////////////////////////////////////////////////////////////////////
// class SparseBindingImage
void SparseBindingImage::Init(RandomNumberGenerator& rand)
{
assert(g_SparseBindingEnabled && g_hSparseBindingQueue);
// Create image.
FillImageCreateInfo(rand);
m_CreateInfo.flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
ERR_GUARD_VULKAN( vkCreateImage(g_hDevice, &m_CreateInfo, nullptr, &m_Image) );
// Get memory requirements.
VkMemoryRequirements imageMemReq;
vkGetImageMemoryRequirements(g_hDevice, m_Image, &imageMemReq);
// This is just to silence validation layer warning.
// But it doesn't help. Looks like a bug in Vulkan validation layers.
// See: https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/364
uint32_t sparseMemReqCount = 0;
vkGetImageSparseMemoryRequirements(g_hDevice, m_Image, &sparseMemReqCount, nullptr);
TEST(sparseMemReqCount <= 8);
VkSparseImageMemoryRequirements sparseMemReq[8];
vkGetImageSparseMemoryRequirements(g_hDevice, m_Image, &sparseMemReqCount, sparseMemReq);
// According to Vulkan specification, for sparse resources memReq.alignment is also page size.
const VkDeviceSize pageSize = imageMemReq.alignment;
const uint32_t pageCount = (uint32_t)ceil_div<VkDeviceSize>(imageMemReq.size, pageSize);
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.preferredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
VkMemoryRequirements pageMemReq = imageMemReq;
pageMemReq.size = pageSize;
// Allocate and bind memory pages.
m_Allocations.resize(pageCount);
std::fill(m_Allocations.begin(), m_Allocations.end(), nullptr);
std::vector<VkSparseMemoryBind> binds{pageCount};
std::vector<VmaAllocationInfo> allocInfo{pageCount};
ERR_GUARD_VULKAN( vmaAllocateMemoryPages(g_hAllocator, &pageMemReq, &allocCreateInfo, pageCount, m_Allocations.data(), allocInfo.data()) );
for(uint32_t i = 0; i < pageCount; ++i)
{
binds[i] = {};
binds[i].resourceOffset = pageSize * i;
binds[i].size = pageSize;
binds[i].memory = allocInfo[i].deviceMemory;
binds[i].memoryOffset = allocInfo[i].offset;
}
VkSparseImageOpaqueMemoryBindInfo imageBindInfo;
imageBindInfo.image = m_Image;
imageBindInfo.bindCount = pageCount;
imageBindInfo.pBinds = binds.data();
VkBindSparseInfo bindSparseInfo = { VK_STRUCTURE_TYPE_BIND_SPARSE_INFO };
bindSparseInfo.pImageOpaqueBinds = &imageBindInfo;
bindSparseInfo.imageOpaqueBindCount = 1;
ERR_GUARD_VULKAN( vkResetFences(g_hDevice, 1, &g_ImmediateFence) );
ERR_GUARD_VULKAN( vkQueueBindSparse(g_hSparseBindingQueue, 1, &bindSparseInfo, g_ImmediateFence) );
ERR_GUARD_VULKAN( vkWaitForFences(g_hDevice, 1, &g_ImmediateFence, VK_TRUE, UINT64_MAX) );
}
SparseBindingImage::~SparseBindingImage()
{
vmaFreeMemoryPages(g_hAllocator, m_Allocations.size(), m_Allocations.data());
}
////////////////////////////////////////////////////////////////////////////////
// Private functions
////////////////////////////////////////////////////////////////////////////////
// Public functions
void TestSparseBinding()
{
wprintf(L"TESTING SPARSE BINDING:\n");
struct ImageInfo
{
std::unique_ptr<BaseImage> image;
uint32_t endFrame;
};
std::vector<ImageInfo> images;
constexpr uint32_t frameCount = 1000;
constexpr uint32_t imageLifeFramesMin = 1;
constexpr uint32_t imageLifeFramesMax = 400;
RandomNumberGenerator rand(4652467);
for(uint32_t frameIndex = 0; frameIndex < frameCount; ++frameIndex)
{
// Bump frame index.
++g_FrameIndex;
vmaSetCurrentFrameIndex(g_hAllocator, g_FrameIndex);
// Create one new, random image.
ImageInfo imageInfo;
//imageInfo.image = std::make_unique<TraditionalImage>();
imageInfo.image = std::make_unique<SparseBindingImage>();
imageInfo.image->Init(rand);
imageInfo.endFrame = g_FrameIndex + rand.Generate() % (imageLifeFramesMax - imageLifeFramesMin) + imageLifeFramesMin;
images.push_back(std::move(imageInfo));
// Delete all images that expired.
for(size_t imageIndex = images.size(); imageIndex--; )
{
if(g_FrameIndex >= images[imageIndex].endFrame)
{
images.erase(images.begin() + imageIndex);
}
}
}
SaveAllocatorStatsToFile(L"SparseBindingTest.json");
// Choose biggest image. Test uploading and sampling.
BaseImage* biggestImage = nullptr;
for(size_t i = 0, count = images.size(); i < count; ++i)
{
if(!biggestImage ||
images[i].image->GetCreateInfo().extent.width * images[i].image->GetCreateInfo().extent.height >
biggestImage->GetCreateInfo().extent.width * biggestImage->GetCreateInfo().extent.height)
{
biggestImage = images[i].image.get();
}
}
assert(biggestImage);
biggestImage->TestContent(rand);
// Free remaining images.
images.clear();
wprintf(L"Done.\n");
}
#endif // #ifdef _WIN32

29
externals/vma/src/SparseBindingTest.h vendored Normal file
View File

@@ -0,0 +1,29 @@
//
// Copyright (c) 2017-2024 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#pragma once
#ifdef _WIN32
void TestSparseBinding();
#endif // #ifdef _WIN32

8456
externals/vma/src/Tests.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

32
externals/vma/src/Tests.h vendored Normal file
View File

@@ -0,0 +1,32 @@
//
// Copyright (c) 2017-2024 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#ifndef TESTS_H_
#define TESTS_H_
#ifdef _WIN32
void Test();
#endif // #ifdef _WIN32
#endif

30
externals/vma/src/VmaUsage.cpp vendored Normal file
View File

@@ -0,0 +1,30 @@
//
// Copyright (c) 2017-2024 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
/*
In exactly one CPP file define macro VMA_IMPLEMENTATION and then include
vk_mem_alloc.h to include definitions of its internal implementation
*/
#define VMA_IMPLEMENTATION
#include "VmaUsage.h"

109
externals/vma/src/VmaUsage.h vendored Normal file
View File

@@ -0,0 +1,109 @@
//
// Copyright (c) 2017-2024 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#ifndef VMA_USAGE_H_
#define VMA_USAGE_H_
#ifdef _WIN32
#if !defined(NOMINMAX)
#define NOMINMAX
#endif
#if !defined(WIN32_LEAN_AND_MEAN)
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#if !defined(VK_USE_PLATFORM_WIN32_KHR)
#define VK_USE_PLATFORM_WIN32_KHR
#endif // #if !defined(VK_USE_PLATFORM_WIN32_KHR)
#else // #ifdef _WIN32
#include <vulkan/vulkan.h>
#endif // #ifdef _WIN32
#ifdef _MSVC_LANG
// Uncomment to test including `vulkan.h` on your own before including VMA.
//#include <vulkan/vulkan.h>
/*
In every place where you want to use Vulkan Memory Allocator, define appropriate
macros if you want to configure the library and then include its header to
include all public interface declarations. Example:
*/
//#define VMA_HEAVY_ASSERT(expr) assert(expr)
//#define VMA_DEDICATED_ALLOCATION 0
//#define VMA_DEBUG_MARGIN 16
//#define VMA_DEBUG_DETECT_CORRUPTION 1
//#define VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY 256
//#define VMA_USE_STL_SHARED_MUTEX 0
//#define VMA_MEMORY_BUDGET 0
//#define VMA_STATS_STRING_ENABLED 0
//#define VMA_MAPPING_HYSTERESIS_ENABLED 0
//#define VMA_KHR_MAINTENANCE5 0
//#define VMA_VULKAN_VERSION 1003000 // Vulkan 1.3
//#define VMA_VULKAN_VERSION 1002000 // Vulkan 1.2
//#define VMA_VULKAN_VERSION 1001000 // Vulkan 1.1
//#define VMA_VULKAN_VERSION 1000000 // Vulkan 1.0
/*
#define VMA_DEBUG_LOG(format, ...) do { \
printf(format, __VA_ARGS__); \
printf("\n"); \
} while(false)
*/
#pragma warning(push, 4)
#pragma warning(disable: 4127) // conditional expression is constant
#pragma warning(disable: 4100) // unreferenced formal parameter
#pragma warning(disable: 4189) // local variable is initialized but not referenced
#pragma warning(disable: 4324) // structure was padded due to alignment specifier
#pragma warning(disable: 4820) // 'X': 'N' bytes padding added after data member 'X'
#endif // #ifdef _MSVC_LANG
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare" // comparison of unsigned expression < 0 is always false
#pragma clang diagnostic ignored "-Wunused-private-field"
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
#pragma clang diagnostic ignored "-Wnullability-completeness"
#endif
#include "vk_mem_alloc.h"
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef _MSVC_LANG
#pragma warning(pop)
#endif
#endif

2654
externals/vma/src/VulkanSample.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

71
externals/vma/src/vk_mem_alloc.natvis vendored Normal file
View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="VmaRawList&lt;*&gt;">
<DisplayString>{{ Count={m_Count} }}</DisplayString>
<Expand>
<Item Name="[Count]">m_Count</Item>
<LinkedListItems>
<Size>m_Count</Size>
<HeadPointer>m_pFront</HeadPointer>
<NextPointer>pNext</NextPointer>
<ValueNode>Value</ValueNode>
</LinkedListItems>
</Expand>
</Type>
<Type Name="VmaList&lt;*&gt;">
<DisplayString>{{ Count={m_RawList.m_Count} }}</DisplayString>
<Expand>
<Item Name="[Count]">m_RawList.m_Count</Item>
<LinkedListItems>
<Size>m_RawList.m_Count</Size>
<HeadPointer>m_RawList.m_pFront</HeadPointer>
<NextPointer>pNext</NextPointer>
<ValueNode>Value</ValueNode>
</LinkedListItems>
</Expand>
</Type>
<Type Name="VmaVector&lt;*&gt;">
<DisplayString>{{ Count={m_Count} }}</DisplayString>
<Expand>
<Item Name="[Count]">m_Count</Item>
<Item Name="[Capacity]">m_Capacity</Item>
<ArrayItems>
<Size>m_Count</Size>
<ValuePointer>m_pArray</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<!--
Due to custom way of accesing next items in
VmaIntrusiveLinkedList via methods in provided type traits,
every specialization must be manually added with
custom <NextPointer> field describing proper way of iterating the list.
-->
<Type Name="VmaIntrusiveLinkedList&lt;VmaDedicatedAllocationListItemTraits&gt;">
<DisplayString>{{ Count={m_Count} }}</DisplayString>
<Expand>
<Item Name="[Count]">m_Count</Item>
<LinkedListItems>
<Size>m_Count</Size>
<HeadPointer>m_Front</HeadPointer>
<NextPointer>m_DedicatedAllocation.m_Next</NextPointer>
<ValueNode>*this</ValueNode>
</LinkedListItems>
</Expand>
</Type>
<Type Name="VmaIntrusiveLinkedList&lt;VmaPoolListItemTraits&gt;">
<DisplayString>{{ Count={m_Count} }}</DisplayString>
<Expand>
<Item Name="[Count]">m_Count</Item>
<LinkedListItems>
<Size>m_Count</Size>
<HeadPointer>m_Front</HeadPointer>
<NextPointer>m_NextPool</NextPointer>
<ValueNode>*this</ValueNode>
</LinkedListItems>
</Expand>
</Type>
</AutoVisualizer>