From a63e37c65666fb138aba9fb3deb2f15efdc09fae Mon Sep 17 00:00:00 2001 From: Adam Sawicki Date: Mon, 18 Nov 2019 13:40:03 +0100 Subject: [PATCH] Add support for memory budget to record&replay system --- docs/Recording file format.md | 1 + src/VmaReplay/Constants.cpp | 4 ++ src/VmaReplay/Constants.h | 1 + src/VmaReplay/VmaReplay.cpp | 105 ++++++++++++++++++++++++++++++---- src/vk_mem_alloc.h | 10 +++- 5 files changed, 108 insertions(+), 13 deletions(-) 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 @@ An ordered sequence of values of some type, separated by single space. 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 @@ const char* VMA_ALLOCATION_CREATE_FLAG_NAMES[] = { "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 @@ const uint32_t VMA_ALLOCATION_CREATE_FLAG_VALUES[] = { 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 @@ enum CMD_LINE_OPT 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_UserDataEnabled = true; 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 @@ public: void Compare( const VkPhysicalDeviceProperties& currDevProps, const VkPhysicalDeviceMemoryProperties& currMemProps, - bool currDedicatedAllocationExtensionEnabled); + bool currDedicatedAllocationExtensionEnabled, + bool currMemoryBudgetEnabled); private: enum class OPTION @@ -1078,6 +1080,8 @@ private: 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 @@ bool ConfigurationParser::Parse(LineSplit& lineSplit) 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 @@ bool ConfigurationParser::Parse(LineSplit& lineSplit) 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 @@ void ConfigurationParser::Compare( 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 @@ private: 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 @@ Player::~Player() 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 @@ int Player::InitVulkan() default: assert(0); } - std::vector 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 availableInstanceExtensions(availableInstanceExtensionCount); + if(availableInstanceExtensionCount > 0) + { + res = vkEnumerateInstanceExtensionProperties(nullptr, &availableInstanceExtensionCount, availableInstanceExtensions.data()); + assert(res == VK_SUCCESS); + } + + std::vector enabledInstanceExtensions; + //enabledInstanceExtensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); + //enabledInstanceExtensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); std::vector 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 @@ int Player::InitVulkan() 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 @@ int Player::InitVulkan() // Determine list of device extensions to enable. std::vector 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 @@ int Player::InitVulkan() { 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 @@ int Player::InitVulkan() 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 @@ int Player::InitVulkan() 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 @@ int Player::InitVulkan() { 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 @@ static void PrintCommandLineSyntax() " By default the layers are silently enabled if available.\n" " --VK_KHR_dedicated_allocation - 0 to disable or 1 to enable this extension.\n" " By default the extension is silently enabled if available.\n" + " --VK_EXT_memory_budget - 0 to disable or 1 to enable this extension.\n" + " By default the extension is silently enabled if available.\n" ); } @@ -4160,6 +4228,7 @@ static int main2(int argc, char** argv) 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 @@ static int main2(int argc, char** argv) } } 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 @@ public: const VkPhysicalDeviceProperties& devProps, const VkPhysicalDeviceMemoryProperties& memProps, bool dedicatedAllocationExtensionEnabled, - bool bindMemory2ExtensionEnabled); + bool bindMemory2ExtensionEnabled, + bool memoryBudgetExtensionEnabled); ~VmaRecorder(); void RecordCreateAllocator(uint32_t frameIndex); @@ -14363,7 +14364,8 @@ void VmaRecorder::WriteConfiguration( const VkPhysicalDeviceProperties& devProps, const VkPhysicalDeviceMemoryProperties& memProps, bool dedicatedAllocationExtensionEnabled, - bool bindMemory2ExtensionEnabled) + bool bindMemory2ExtensionEnabled, + bool memoryBudgetExtensionEnabled) { fprintf(m_File, "Config,Begin\n"); @@ -14393,6 +14395,7 @@ void VmaRecorder::WriteConfiguration( 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 @@ VkResult VmaAllocator_T::Init(const VmaAllocatorCreateInfo* pCreateInfo) 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.");