Added documentation chapter "VK_EXT_memory_priority"

Other fixes in documentation
This commit is contained in:
Adam Sawicki 2022-02-28 12:10:18 +01:00
parent f02c8a46d8
commit 01364c7970
25 changed files with 644 additions and 348 deletions

View file

@ -84,9 +84,11 @@ License: MIT
- [Custom host memory allocator](@ref custom_memory_allocator)
- [Device memory allocation callbacks](@ref allocation_callbacks)
- [Device heap memory limit](@ref heap_memory_limit)
- \subpage vk_khr_dedicated_allocation
- \subpage enabling_buffer_device_address
- \subpage vk_amd_device_coherent_memory
- <b>Extension support</b>
- \subpage vk_khr_dedicated_allocation
- \subpage enabling_buffer_device_address
- \subpage vk_ext_memory_priority
- \subpage vk_amd_device_coherent_memory
- \subpage general_considerations
- [Thread safety](@ref general_considerations_thread_safety)
- [Versioning and compatibility](@ref general_considerations_versioning_and_compatibility)
@ -424,6 +426,7 @@ typedef enum VmaAllocatorCreateFlagBits
VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VmaAllocatorCreateFlagBits;
/// See #VmaAllocatorCreateFlagBigs.
typedef VkFlags VmaAllocatorCreateFlags;
/** @} */
@ -645,6 +648,7 @@ typedef enum VmaAllocationCreateFlagBits
VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VmaAllocationCreateFlagBits;
/// See #VmaAllocationCreateFlagBits.
typedef VkFlags VmaAllocationCreateFlags;
/// Flags to be passed as VmaPoolCreateInfo::flags.
@ -723,6 +727,7 @@ typedef enum VmaDefragmentationFlagBits
VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VmaDefragmentationFlagBits;
/// See #VmaDefragmentationFlagBits.
typedef VkFlags VmaDefragmentationFlags;
/// Operation performed on single defragmentation move. See structure #VmaDefragmentationMove.
@ -1208,6 +1213,10 @@ typedef struct VmaBudget
@{
*/
/** \brief Parameters of new #VmaAllocation.
To be used with functions like vmaCreateBuffer(), vmaCreateImage(), and many others.
*/
typedef struct VmaAllocationCreateInfo
{
/// Use #VmaAllocationCreateFlagBits enum.
@ -1822,14 +1831,19 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryPages(
VmaAllocation VMA_NULLABLE* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations,
VmaAllocationInfo* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocationInfo);
/**
/** \brief Allocates memory suitable for given `VkBuffer`.
\param allocator
\param buffer
\param pCreateInfo
\param[out] pAllocation Handle to allocated memory.
\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
You should free the memory using vmaFreeMemory().
It only creates #VmaAllocation. To bind the memory to the buffer, use vmaBindBufferMemory().
This is a special-purpose function. In most cases you should use vmaCreateBuffer().
You must free the allocation using vmaFreeMemory() when no longer needed.
*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForBuffer(
VmaAllocator VMA_NOT_NULL allocator,
@ -1838,7 +1852,20 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForBuffer(
VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
/// Function similar to vmaAllocateMemoryForBuffer().
/** \brief Allocates memory suitable for given `VkImage`.
\param allocator
\param image
\param pCreateInfo
\param[out] pAllocation Handle to allocated memory.
\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
It only creates #VmaAllocation. To bind the memory to the buffer, use vmaBindImageMemory().
This is a special-purpose function. In most cases you should use vmaCreateImage().
You must free the allocation using vmaFreeMemory() when no longer needed.
*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForImage(
VmaAllocator VMA_NOT_NULL allocator,
VkImage VMA_NOT_NULL_NON_DISPATCHABLE image,
@ -2223,7 +2250,8 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory2(
VkImage VMA_NOT_NULL_NON_DISPATCHABLE image,
const void* VMA_NULLABLE pNext);
/**
/** \brief Creates a new `VkBuffer`, allocates and binds memory for it.
\param allocator
\param pBufferCreateInfo
\param pAllocationCreateInfo
@ -12783,6 +12811,7 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn
VkMemoryPriorityAllocateInfoEXT priorityInfo = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT };
if (m_hAllocator->m_UseExtMemoryPriority)
{
VMA_ASSERT(m_Priority >= 0.f && m_Priority <= 1.f);
priorityInfo.priority = m_Priority;
VmaPnextChainPushFront(&allocInfo, &priorityInfo);
}
@ -14417,6 +14446,7 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory(
VkMemoryPriorityAllocateInfoEXT priorityInfo = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT };
if(m_UseExtMemoryPriority)
{
VMA_ASSERT(priority >= 0.f && priority <= 1.f);
priorityInfo.priority = priority;
VmaPnextChainPushFront(&allocInfo, &priorityInfo);
}
@ -17999,7 +18029,7 @@ for(;;)
for(uint32_t i = 0; i < pass.moveCount; ++i)
{
//- Inspect pass.pMoves[i].srcAllocation, identify what buffer or image it represents.
//- Recreate this buffer or image at pass.pMoves[i].dstMemory, pass.pMoves[i].dstOffset.
//- Recreate and bind this buffer or image at pass.pMoves[i].dstMemory, pass.pMoves[i].dstOffset.
//- Issue a vkCmdCopyBuffer/vkCmdCopyImage to copy its content to the new place.
}
//- Make sure the copy commands finished executing.
@ -18849,6 +18879,86 @@ To learn more about this extension, see:
\page vk_ext_memory_priority VK_EXT_memory_priority
VK_EXT_memory_priority is a device extension that allows to pass additional "priority"
value to Vulkan memory allocations that the implementation may use prefer certain
buffers and images that are critical for performance to stay in device-local memory
in cases when the memory is over-subscribed, while some others may be moved to the system memory.
VMA offers convenient usage of this extension.
If you enable it, you can pass "priority" parameter when creating allocations or custom pools
and the library automatically passes the value to Vulkan using this extension.
If you want to use this extension in connection with VMA, follow these steps:
\section vk_ext_memory_priority_initialization Initialization
1) Call `vkEnumerateDeviceExtensionProperties` for the physical device.
Check if the extension is supported - if returned array of `VkExtensionProperties` contains "VK_EXT_memory_priority".
2) Call `vkGetPhysicalDeviceFeatures2` for the physical device instead of old `vkGetPhysicalDeviceFeatures`.
Attach additional structure `VkPhysicalDeviceMemoryPriorityFeaturesEXT` to `VkPhysicalDeviceFeatures2::pNext` to be returned.
Check if the device feature is really supported - check if `VkPhysicalDeviceMemoryPriorityFeaturesEXT::memoryPriority` is true.
3) While creating device with `vkCreateDevice`, enable this extension - add "VK_EXT_memory_priority"
to the list passed as `VkDeviceCreateInfo::ppEnabledExtensionNames`.
4) While creating the device, also don't set `VkDeviceCreateInfo::pEnabledFeatures`.
Fill in `VkPhysicalDeviceFeatures2` structure instead and pass it as `VkDeviceCreateInfo::pNext`.
Enable this device feature - attach additional structure `VkPhysicalDeviceMemoryPriorityFeaturesEXT` to
`VkPhysicalDeviceFeatures2::pNext` chain and set its member `memoryPriority` to `VK_TRUE`.
5) While creating #VmaAllocator with vmaCreateAllocator() inform VMA that you
have enabled this extension and feature - add #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT
to VmaAllocatorCreateInfo::flags.
\section vk_ext_memory_priority_usage Usage
When using this extension, you should initialize following member:
- VmaAllocationCreateInfo::priority when creating a dedicated allocation with #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT.
- VmaPoolCreateInfo::priority when creating a custom pool.
It should be a floating-point value between `0.0f` and `1.0f`, where recommended default is `0.5f`.
Memory allocated with higher value can be treated by the Vulkan implementation as higher priority
and so it can have lower chances of being pushed out to system memory, experiencing degraded performance.
It might be a good idea to create performance-critical resources like color-attachment or depth-stencil images
as dedicated and set high priority to them. For example:
\code
VkImageCreateInfo imgCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO };
imgCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imgCreateInfo.extent.width = 3840;
imgCreateInfo.extent.height = 2160;
imgCreateInfo.extent.depth = 1;
imgCreateInfo.mipLevels = 1;
imgCreateInfo.arrayLayers = 1;
imgCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
imgCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imgCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imgCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
imgCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
allocCreateInfo.priority = 1.0f;
VkImage img;
VmaAllocation alloc;
vmaCreateImage(allocator, &imgCreateInfo, &allocCreateInfo, &img, &alloc, nullptr);
\endcode
`priority` member is ignored in the following situations:
- Allocations created in custom pools: They inherit the priority, along with all other allocation parameters
from the parametrs passed in #VmaPoolCreateInfo when the pool was created.
- Allocations created in default pools: They inherit the priority from the parameters
VMA used when creating default pools, which means `priority == 0.5f`.
\page vk_amd_device_coherent_memory VK_AMD_device_coherent_memory
VK_AMD_device_coherent_memory is a device extension that enables access to