First Commit
This commit is contained in:
6
externals/vma/src/.editorconfig
vendored
Normal file
6
externals/vma/src/.editorconfig
vendored
Normal 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
95
externals/vma/src/CMakeLists.txt
vendored
Normal 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
328
externals/vma/src/Common.cpp
vendored
Normal 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
339
externals/vma/src/Common.h
vendored
Normal 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
|
||||
32
externals/vma/src/Shaders/CMakeLists.txt
vendored
Normal file
32
externals/vma/src/Shaders/CMakeLists.txt
vendored
Normal 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})
|
||||
4
externals/vma/src/Shaders/CompileShaders.bat
vendored
Normal file
4
externals/vma/src/Shaders/CompileShaders.bat
vendored
Normal 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
37
externals/vma/src/Shaders/Shader.frag
vendored
Normal 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
42
externals/vma/src/Shaders/Shader.vert
vendored
Normal 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;
|
||||
}
|
||||
44
externals/vma/src/Shaders/SparseBindingTest.comp
vendored
Normal file
44
externals/vma/src/Shaders/SparseBindingTest.comp
vendored
Normal 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
597
externals/vma/src/SparseBindingTest.cpp
vendored
Normal 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, ®ion);
|
||||
}
|
||||
|
||||
// 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
29
externals/vma/src/SparseBindingTest.h
vendored
Normal 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
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
32
externals/vma/src/Tests.h
vendored
Normal 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
30
externals/vma/src/VmaUsage.cpp
vendored
Normal 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
109
externals/vma/src/VmaUsage.h
vendored
Normal 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
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
71
externals/vma/src/vk_mem_alloc.natvis
vendored
Normal 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<*>">
|
||||
<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<*>">
|
||||
<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<*>">
|
||||
<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<VmaDedicatedAllocationListItemTraits>">
|
||||
<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<VmaPoolListItemTraits>">
|
||||
<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>
|
||||
Reference in New Issue
Block a user