Add support for memory budget to record&replay system
diff --git a/docs/Recording file format.md b/docs/Recording file format.md
index 42d3bc3..42f6151 100644
--- a/docs/Recording file format.md
+++ b/docs/Recording file format.md
@@ -305,6 +305,7 @@
PhysicalDeviceMemory,Type,3,propertyFlags,14
Extension,VK_KHR_dedicated_allocation,1
Extension,VK_KHR_bind_memory2,1
+ Extension,VK_EXT_memory_budget,1
Macro,VMA_DEBUG_ALWAYS_DEDICATED_MEMORY,0
Macro,VMA_DEBUG_ALIGNMENT,1
Macro,VMA_DEBUG_MARGIN,0
diff --git a/src/VmaReplay/Constants.cpp b/src/VmaReplay/Constants.cpp
index 6258117..11552b2 100644
--- a/src/VmaReplay/Constants.cpp
+++ b/src/VmaReplay/Constants.cpp
@@ -737,6 +737,8 @@
"VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT",
"VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT",
"VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT",
+ "VMA_ALLOCATION_CREATE_DONT_BIND_BIT",
+ "VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT",
"VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT",
"VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT",
"VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT",
@@ -749,6 +751,8 @@
VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT,
VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT,
VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT,
+ VMA_ALLOCATION_CREATE_DONT_BIND_BIT,
+ VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT,
VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT,
VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT,
VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT,
diff --git a/src/VmaReplay/Constants.h b/src/VmaReplay/Constants.h
index 4dcea82..4a7479c 100644
--- a/src/VmaReplay/Constants.h
+++ b/src/VmaReplay/Constants.h
@@ -36,6 +36,7 @@
CMD_LINE_OPT_PHYSICAL_DEVICE,
CMD_LINE_OPT_USER_DATA,
CMD_LINE_OPT_VK_KHR_DEDICATED_ALLOCATION,
+ CMD_LINE_OPT_VK_EXT_MEMORY_BUDGET,
CMD_LINE_OPT_VK_LAYER_LUNARG_STANDARD_VALIDATION,
CMD_LINE_OPT_MEM_STATS,
CMD_LINE_OPT_DUMP_STATS_AFTER_LINE,
diff --git a/src/VmaReplay/VmaReplay.cpp b/src/VmaReplay/VmaReplay.cpp
index 57251fb..de5c824 100644
--- a/src/VmaReplay/VmaReplay.cpp
+++ b/src/VmaReplay/VmaReplay.cpp
@@ -670,6 +670,7 @@
static bool g_MemStatsEnabled = false;
VULKAN_EXTENSION_REQUEST g_VK_KHR_dedicated_allocation_request = VULKAN_EXTENSION_REQUEST::DEFAULT;
VULKAN_EXTENSION_REQUEST g_VK_LAYER_LUNARG_standard_validation = VULKAN_EXTENSION_REQUEST::DEFAULT;
+VULKAN_EXTENSION_REQUEST g_VK_EXT_memory_budget_request = VULKAN_EXTENSION_REQUEST::DEFAULT;
struct StatsAfterLineEntry
{
@@ -1063,7 +1064,8 @@
void Compare(
const VkPhysicalDeviceProperties& currDevProps,
const VkPhysicalDeviceMemoryProperties& currMemProps,
- bool currDedicatedAllocationExtensionEnabled);
+ bool currDedicatedAllocationExtensionEnabled,
+ bool currMemoryBudgetEnabled);
private:
enum class OPTION
@@ -1078,6 +1080,8 @@
PhysicalDeviceLimits_bufferImageGranularity,
PhysicalDeviceLimits_nonCoherentAtomSize,
Extension_VK_KHR_dedicated_allocation,
+ Extension_VK_KHR_bind_memory2,
+ Extension_VK_EXT_memory_budget,
Macro_VMA_DEBUG_ALWAYS_DEDICATED_MEMORY,
Macro_VMA_DEBUG_ALIGNMENT,
Macro_VMA_DEBUG_MARGIN,
@@ -1202,6 +1206,10 @@
const StrRange subOptionName = csvSplit.GetRange(1);
if(StrRangeEq(subOptionName, "VK_KHR_dedicated_allocation"))
SetOption(currLineNumber, OPTION::Extension_VK_KHR_dedicated_allocation, csvSplit.GetRange(2));
+ else if(StrRangeEq(subOptionName, "VK_KHR_bind_memory2"))
+ SetOption(currLineNumber, OPTION::Extension_VK_KHR_bind_memory2, csvSplit.GetRange(2));
+ else if(StrRangeEq(subOptionName, "VK_EXT_memory_budget"))
+ SetOption(currLineNumber, OPTION::Extension_VK_EXT_memory_budget, csvSplit.GetRange(2));
else
printf("Line %zu: Unrecognized configuration option.\n", currLineNumber);
}
@@ -1297,7 +1305,8 @@
void ConfigurationParser::Compare(
const VkPhysicalDeviceProperties& currDevProps,
const VkPhysicalDeviceMemoryProperties& currMemProps,
- bool currDedicatedAllocationExtensionEnabled)
+ bool currDedicatedAllocationExtensionEnabled,
+ bool currMemoryBudgetEnabled)
{
CompareOption(VERBOSITY::MAXIMUM, "PhysicalDevice apiVersion",
OPTION::PhysicalDevice_apiVersion, currDevProps.apiVersion);
@@ -1319,7 +1328,7 @@
CompareOption(VERBOSITY::DEFAULT, "PhysicalDeviceLimits nonCoherentAtomSize",
OPTION::PhysicalDeviceLimits_nonCoherentAtomSize, currDevProps.limits.nonCoherentAtomSize);
CompareOption(VERBOSITY::DEFAULT, "Extension VK_KHR_dedicated_allocation",
- OPTION::Extension_VK_KHR_dedicated_allocation, currDedicatedAllocationExtensionEnabled);
+ OPTION::Extension_VK_EXT_memory_budget, currMemoryBudgetEnabled);
CompareMemProps(currMemProps);
}
@@ -1580,6 +1589,7 @@
VkCommandPool m_CommandPool = VK_NULL_HANDLE;
VkCommandBuffer m_CommandBuffer = VK_NULL_HANDLE;
bool m_DedicatedAllocationEnabled = false;
+ bool m_MemoryBudgetEnabled = false;
const VkPhysicalDeviceProperties* m_DevProps = nullptr;
const VkPhysicalDeviceMemoryProperties* m_MemProps = nullptr;
@@ -1700,7 +1710,9 @@
void Player::ApplyConfig(ConfigurationParser& configParser)
{
- configParser.Compare(*m_DevProps, *m_MemProps, m_DedicatedAllocationEnabled);
+ configParser.Compare(*m_DevProps, *m_MemProps,
+ m_DedicatedAllocationEnabled,
+ m_MemoryBudgetEnabled);
}
void Player::ExecuteLine(size_t lineNumber, const StrRange& line)
@@ -2007,15 +2019,35 @@
default: assert(0);
}
- std::vector<const char*> instanceExtensions;
- //instanceExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
- //instanceExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
+ uint32_t availableInstanceExtensionCount = 0;
+ res = vkEnumerateInstanceExtensionProperties(nullptr, &availableInstanceExtensionCount, nullptr);
+ assert(res == VK_SUCCESS);
+ std::vector<VkExtensionProperties> availableInstanceExtensions(availableInstanceExtensionCount);
+ if(availableInstanceExtensionCount > 0)
+ {
+ res = vkEnumerateInstanceExtensionProperties(nullptr, &availableInstanceExtensionCount, availableInstanceExtensions.data());
+ assert(res == VK_SUCCESS);
+ }
+
+ std::vector<const char*> enabledInstanceExtensions;
+ //enabledInstanceExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
+ //enabledInstanceExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
std::vector<const char*> instanceLayers;
if(validationLayersEnabled)
{
instanceLayers.push_back(VALIDATION_LAYER_NAME);
- instanceExtensions.push_back("VK_EXT_debug_report");
+ enabledInstanceExtensions.push_back("VK_EXT_debug_report");
+ }
+
+ bool VK_KHR_get_physical_device_properties2_enabled = false;
+ for(const auto& extensionProperties : availableInstanceExtensions)
+ {
+ if(strcmp(extensionProperties.extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME) == 0)
+ {
+ enabledInstanceExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
+ VK_KHR_get_physical_device_properties2_enabled = true;
+ }
}
VkApplicationInfo appInfo = { VK_STRUCTURE_TYPE_APPLICATION_INFO };
@@ -2027,8 +2059,8 @@
VkInstanceCreateInfo instInfo = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
instInfo.pApplicationInfo = &appInfo;
- instInfo.enabledExtensionCount = (uint32_t)instanceExtensions.size();
- instInfo.ppEnabledExtensionNames = instanceExtensions.data();
+ instInfo.enabledExtensionCount = (uint32_t)enabledInstanceExtensions.size();
+ instInfo.ppEnabledExtensionNames = enabledInstanceExtensions.data();
instInfo.enabledLayerCount = (uint32_t)instanceLayers.size();
instInfo.ppEnabledLayerNames = instanceLayers.data();
@@ -2136,6 +2168,7 @@
// Determine list of device extensions to enable.
std::vector<const char*> enabledDeviceExtensions;
//enabledDeviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
+ bool memoryBudgetAvailable = false;
{
uint32_t propertyCount = 0;
res = vkEnumerateDeviceExtensionProperties(m_PhysicalDevice, nullptr, &propertyCount, nullptr);
@@ -2157,6 +2190,13 @@
{
VK_KHR_dedicated_allocation_available = true;
}
+ else if(strcmp(properties[i].extensionName, VK_EXT_MEMORY_BUDGET_EXTENSION_NAME) == 0)
+ {
+ if(VK_KHR_get_physical_device_properties2_enabled)
+ {
+ memoryBudgetAvailable = true;
+ }
+ }
}
}
}
@@ -2181,11 +2221,32 @@
default: assert(0);
}
+ switch(g_VK_EXT_memory_budget_request)
+ {
+ case VULKAN_EXTENSION_REQUEST::DISABLED:
+ break;
+ case VULKAN_EXTENSION_REQUEST::DEFAULT:
+ m_MemoryBudgetEnabled = memoryBudgetAvailable;
+ break;
+ case VULKAN_EXTENSION_REQUEST::ENABLED:
+ m_MemoryBudgetEnabled = memoryBudgetAvailable;
+ if(!memoryBudgetAvailable)
+ {
+ printf("WARNING: VK_EXT_memory_budget extension cannot be enabled.\n");
+ }
+ break;
+ default: assert(0);
+ }
+
if(m_DedicatedAllocationEnabled)
{
enabledDeviceExtensions.push_back(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
enabledDeviceExtensions.push_back(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
}
+ if(m_MemoryBudgetEnabled)
+ {
+ enabledDeviceExtensions.push_back(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME);
+ }
VkDeviceCreateInfo deviceCreateInfo = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
deviceCreateInfo.enabledExtensionCount = (uint32_t)enabledDeviceExtensions.size();
@@ -2212,6 +2273,7 @@
deviceMemoryCallbacks.pfnFree = FreeDeviceMemoryCallback;
VmaAllocatorCreateInfo allocatorInfo = {};
+ allocatorInfo.instance = m_VulkanInstance;
allocatorInfo.physicalDevice = m_PhysicalDevice;
allocatorInfo.device = m_Device;
allocatorInfo.flags = VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT;
@@ -2221,6 +2283,10 @@
{
allocatorInfo.flags |= VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT;
}
+ if(m_MemoryBudgetEnabled)
+ {
+ allocatorInfo.flags |= VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT;
+ }
res = vmaCreateAllocator(&allocatorInfo, &m_Allocator);
if(res != VK_SUCCESS)
@@ -3941,6 +4007,8 @@
" By default the layers are silently enabled if available.\n"
" --VK_KHR_dedicated_allocation <Value> - 0 to disable or 1 to enable this extension.\n"
" By default the extension is silently enabled if available.\n"
+ " --VK_EXT_memory_budget <Value> - 0 to disable or 1 to enable this extension.\n"
+ " By default the extension is silently enabled if available.\n"
);
}
@@ -4160,6 +4228,7 @@
cmdLineParser.RegisterOpt(CMD_LINE_OPT_PHYSICAL_DEVICE, "PhysicalDevice", true);
cmdLineParser.RegisterOpt(CMD_LINE_OPT_USER_DATA, "UserData", true);
cmdLineParser.RegisterOpt(CMD_LINE_OPT_VK_KHR_DEDICATED_ALLOCATION, "VK_KHR_dedicated_allocation", true);
+ cmdLineParser.RegisterOpt(CMD_LINE_OPT_VK_EXT_MEMORY_BUDGET, "VK_EXT_memory_budget", true);
cmdLineParser.RegisterOpt(CMD_LINE_OPT_VK_LAYER_LUNARG_STANDARD_VALIDATION, VALIDATION_LAYER_NAME, true);
cmdLineParser.RegisterOpt(CMD_LINE_OPT_MEM_STATS, "MemStats", true);
cmdLineParser.RegisterOpt(CMD_LINE_OPT_DUMP_STATS_AFTER_LINE, "DumpStatsAfterLine", true);
@@ -4234,6 +4303,22 @@
}
}
break;
+ case CMD_LINE_OPT_VK_EXT_MEMORY_BUDGET:
+ {
+ bool newValue;
+ if(StrRangeToBool(StrRange(cmdLineParser.GetParameter()), newValue))
+ {
+ g_VK_EXT_memory_budget_request = newValue ?
+ VULKAN_EXTENSION_REQUEST::ENABLED :
+ VULKAN_EXTENSION_REQUEST::DISABLED;
+ }
+ else
+ {
+ PrintCommandLineSyntax();
+ return RESULT_ERROR_COMMAND_LINE;
+ }
+ }
+ break;
case CMD_LINE_OPT_VK_LAYER_LUNARG_STANDARD_VALIDATION:
{
bool newValue;
diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h
index 952fe24..6e61577 100644
--- a/src/vk_mem_alloc.h
+++ b/src/vk_mem_alloc.h
@@ -6796,7 +6796,8 @@
const VkPhysicalDeviceProperties& devProps,
const VkPhysicalDeviceMemoryProperties& memProps,
bool dedicatedAllocationExtensionEnabled,
- bool bindMemory2ExtensionEnabled);
+ bool bindMemory2ExtensionEnabled,
+ bool memoryBudgetExtensionEnabled);
~VmaRecorder();
void RecordCreateAllocator(uint32_t frameIndex);
@@ -14363,7 +14364,8 @@
const VkPhysicalDeviceProperties& devProps,
const VkPhysicalDeviceMemoryProperties& memProps,
bool dedicatedAllocationExtensionEnabled,
- bool bindMemory2ExtensionEnabled)
+ bool bindMemory2ExtensionEnabled,
+ bool memoryBudgetExtensionEnabled)
{
fprintf(m_File, "Config,Begin\n");
@@ -14393,6 +14395,7 @@
fprintf(m_File, "Extension,VK_KHR_dedicated_allocation,%u\n", dedicatedAllocationExtensionEnabled ? 1 : 0);
fprintf(m_File, "Extension,VK_KHR_bind_memory2,%u\n", bindMemory2ExtensionEnabled ? 1 : 0);
+ fprintf(m_File, "Extension,VK_EXT_memory_budget,%u\n", memoryBudgetExtensionEnabled ? 1 : 0);
fprintf(m_File, "Macro,VMA_DEBUG_ALWAYS_DEDICATED_MEMORY,%u\n", VMA_DEBUG_ALWAYS_DEDICATED_MEMORY ? 1 : 0);
fprintf(m_File, "Macro,VMA_DEBUG_ALIGNMENT,%llu\n", (VkDeviceSize)VMA_DEBUG_ALIGNMENT);
@@ -14593,7 +14596,8 @@
m_PhysicalDeviceProperties,
m_MemProps,
m_UseKhrDedicatedAllocation,
- m_UseKhrBindMemory2);
+ m_UseKhrBindMemory2,
+ m_UseExtMemoryBudget);
m_pRecorder->RecordCreateAllocator(GetCurrentFrameIndex());
#else
VMA_ASSERT(0 && "VmaAllocatorCreateInfo::pRecordSettings used, but not supported due to VMA_RECORDING_ENABLED not defined to 1.");