Add support for memory budget to record&replay system

This commit is contained in:
Adam Sawicki 2019-11-18 13:40:03 +01:00
parent b68b368c67
commit a63e37c656
5 changed files with 108 additions and 13 deletions

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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<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 @@ 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<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 @@ 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 <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 @@ 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;

View File

@ -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.");