diff --git a/third_party/vma.h b/third_party/vma.h
index 8df0364..f2b58bf 100644
--- a/third_party/vma.h
+++ b/third_party/vma.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2017-2025 Advanced Micro Devices, Inc. All rights reserved.
+// Copyright (c) 2017-2026 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
@@ -25,11 +25,11 @@
/** \mainpage Vulkan Memory Allocator
-Version 3.3.0
+Version 3.4.0
-Copyright (c) 2017-2025 Advanced Micro Devices, Inc. All rights reserved. \n
+Copyright (c) 2017-2026 Advanced Micro Devices, Inc. All rights reserved. \n
License: MIT \n
-See also: [product page on GPUOpen](https://gpuopen.com/gaming-product/vulkan-memory-allocator/),
+See also: [product page on GPUOpen](https://gpuopen.com/vulkan-memory-allocator/),
[repository on GitHub](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator)
@@ -79,6 +79,8 @@ See also: [product page on GPUOpen](https://gpuopen.com/gaming-product/vulkan-me
- [Corruption detection](@ref debugging_memory_usage_corruption_detection)
- [Leak detection features](@ref debugging_memory_usage_leak_detection)
- \subpage other_api_interop
+ - [Exporting memory](@ref other_api_interop_exporting_memory)
+ - [Importing memory](@ref other_api_interop_importing_memory)
- \subpage usage_patterns
- [GPU-only resource](@ref usage_patterns_gpu_only)
- [Staging copy for upload](@ref usage_patterns_staging_copy_upload)
@@ -95,7 +97,6 @@ See also: [product page on GPUOpen](https://gpuopen.com/gaming-product/vulkan-me
- \subpage enabling_buffer_device_address
- \subpage vk_ext_memory_priority
- \subpage vk_amd_device_coherent_memory
- - \subpage vk_khr_external_memory_win32
- \subpage general_considerations
- [Thread safety](@ref general_considerations_thread_safety)
- [Versioning and compatibility](@ref general_considerations_versioning_and_compatibility)
@@ -128,10 +129,14 @@ See documentation chapter: \ref statistics.
extern "C" {
#endif
-#if !defined(VULKAN_H_)
-#include
+#ifndef VMA_VULKAN_HEADERS_ALREADY_INCLUDED
+ #if !defined(VULKAN_H_)
+ #include
+ #endif
#endif
+#define VMA_VERSION (VK_MAKE_VERSION(3, 4, 0))
+
#if !defined(VMA_VULKAN_VERSION)
#if defined(VK_VERSION_1_4)
#define VMA_VULKAN_VERSION 1004000
@@ -191,8 +196,16 @@ extern "C" {
#endif
#endif
+#if !defined(VMA_GET_PHYSICAL_DEVICE_PROPERTIES2)
+ #if VK_KHR_get_physical_device_properties2 || VMA_VULKAN_VERSION >= 1001000
+ #define VMA_GET_PHYSICAL_DEVICE_PROPERTIES2 1
+ #else
+ #define VMA_GET_PHYSICAL_DEVICE_PROPERTIES2 0
+ #endif
+#endif
+
#if !defined(VMA_MEMORY_BUDGET)
- #if VK_EXT_memory_budget && (VK_KHR_get_physical_device_properties2 || VMA_VULKAN_VERSION >= 1001000)
+ #if VK_EXT_memory_budget && VMA_GET_PHYSICAL_DEVICE_PROPERTIES2
#define VMA_MEMORY_BUDGET 1
#else
#define VMA_MEMORY_BUDGET 0
@@ -478,7 +491,7 @@ typedef enum VmaAllocatorCreateFlagBits
You should set this flag if you found available and enabled this device extension,
while creating Vulkan device passed as VmaAllocatorCreateInfo::device.
- For more information, see \ref vk_khr_external_memory_win32.
+ For more information, see \ref other_api_interop.
*/
VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT = 0x00000200,
@@ -1046,7 +1059,7 @@ typedef struct VmaVulkanFunctions
/// Fetch "vkBindImageMemory2" on Vulkan >= 1.1, fetch "vkBindImageMemory2KHR" when using VK_KHR_bind_memory2 extension.
PFN_vkBindImageMemory2KHR VMA_NULLABLE vkBindImageMemory2KHR;
#endif
-#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000
+#if VMA_GET_PHYSICAL_DEVICE_PROPERTIES2
/// Fetch from "vkGetPhysicalDeviceMemoryProperties2" on Vulkan >= 1.1, but you can also fetch it from "vkGetPhysicalDeviceMemoryProperties2KHR" if you enabled extension VK_KHR_get_physical_device_properties2.
PFN_vkGetPhysicalDeviceMemoryProperties2KHR VMA_NULLABLE vkGetPhysicalDeviceMemoryProperties2KHR;
#endif
@@ -1061,6 +1074,10 @@ typedef struct VmaVulkanFunctions
#else
void* VMA_NULLABLE vkGetMemoryWin32HandleKHR;
#endif
+#if VMA_GET_PHYSICAL_DEVICE_PROPERTIES2
+ /// Fetch from "vkGetPhysicalDeviceProperties2" on Vulkan >= 1.1, but you can also fetch it from "vkGetPhysicalDeviceProperties2KHR" if you enabled extension VK_KHR_get_physical_device_properties2.
+ PFN_vkGetPhysicalDeviceProperties2KHR VMA_NULLABLE vkGetPhysicalDeviceProperties2KHR;
+#endif
} VmaVulkanFunctions;
/// Description of a Allocator to be created.
@@ -1335,6 +1352,19 @@ typedef struct VmaAllocationCreateInfo
Otherwise, it has the priority of a memory block where it is placed and this variable is ignored.
*/
float priority;
+ /** \brief Additional minimum alignment to be used for this allocation. Can be 0.
+
+ Leave 0 (default) not to impose any additional alignment. If not 0, it must be a power of two.
+
+ When creating a buffer or an image, specifying a custom alignment is not needed in most cases,
+ because Vulkan implementation inspects the `CreateInfo` structure (including intended usage flags)
+ and returns required alignment through functions like `vkGetBufferMemoryRequirements2`, which VMA automatically
+ uses and respects.
+ Extra alignment may be needed in some cases, like when using a buffer for acceleration structure scratch
+ (`VkPhysicalDeviceAccelerationStructurePropertiesKHR::minAccelerationStructureScratchOffsetAlignment`, see also issue #523)
+ or when doing interop with OpenGL.
+ */
+ VkDeviceSize minAlignment;
} VmaAllocationCreateInfo;
/// Describes parameter of created #VmaPool.
@@ -1378,8 +1408,14 @@ typedef struct VmaPoolCreateInfo
/** \brief Additional minimum alignment to be used for all allocations created from this pool. Can be 0.
Leave 0 (default) not to impose any additional alignment. If not 0, it must be a power of two.
- It can be useful in cases where alignment returned by Vulkan by functions like `vkGetBufferMemoryRequirements` is not enough,
- e.g. when doing interop with OpenGL.
+
+ When creating a buffer or an image, specifying a custom alignment is not needed in most cases,
+ because Vulkan implementation inspects the `CreateInfo` structure (including intended usage flags)
+ and returns required alignment through functions like `vkGetBufferMemoryRequirements2`, which VMA automatically
+ uses and respects.
+ Extra alignment may be needed in some cases, like when using a buffer for acceleration structure scratch
+ (`VkPhysicalDeviceAccelerationStructurePropertiesKHR::minAccelerationStructureScratchOffsetAlignment`, see also issue #523)
+ or when doing interop with OpenGL.
*/
VkDeviceSize minAllocationAlignment;
/** \brief Additional `pNext` chain to be attached to `VkMemoryAllocateInfo` used for every allocation made by this pool. Optional.
@@ -1820,20 +1856,20 @@ VMA_CALL_PRE void VMA_CALL_POST vmaGetHeapBudgets(
*/
/**
-\brief Helps to find memoryTypeIndex, given memoryTypeBits and VmaAllocationCreateInfo.
+\brief Helps to find `memoryTypeIndex`, given `memoryTypeBits` and #VmaAllocationCreateInfo.
This algorithm tries to find a memory type that:
-- Is allowed by memoryTypeBits.
-- Contains all the flags from pAllocationCreateInfo->requiredFlags.
+- Is allowed by `memoryTypeBits`.
+- Contains all the flags from `pAllocationCreateInfo->requiredFlags`.
- Matches intended usage.
-- Has as many flags from pAllocationCreateInfo->preferredFlags as possible.
+- Has as many flags from `pAllocationCreateInfo->preferredFlags` as possible.
-\return Returns VK_ERROR_FEATURE_NOT_PRESENT if not found. Receiving such result
+\return Returns `VK_ERROR_FEATURE_NOT_PRESENT` if not found. Receiving such result
from this function or any other allocating function probably means that your
device doesn't support any memory type with requested features for the specific
type of resource you want to use it for. Please check parameters of your
-resource, like image layout (OPTIMAL versus LINEAR) or mip level count.
+resource, like image layout (`OPTIMAL` versus `LINEAR`) or mip level count.
*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndex(
VmaAllocator VMA_NOT_NULL allocator,
@@ -1842,10 +1878,10 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndex(
uint32_t* VMA_NOT_NULL pMemoryTypeIndex);
/**
-\brief Helps to find memoryTypeIndex, given VkBufferCreateInfo and VmaAllocationCreateInfo.
+\brief Helps to find `memoryTypeIndex`, given `VkBufferCreateInfo` and #VmaAllocationCreateInfo.
It can be useful e.g. to determine value to be used as VmaPoolCreateInfo::memoryTypeIndex.
-It internally creates a temporary, dummy buffer that never has memory bound.
+It may need to internally create a temporary, dummy buffer that never has memory bound.
*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo(
VmaAllocator VMA_NOT_NULL allocator,
@@ -1854,10 +1890,10 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo(
uint32_t* VMA_NOT_NULL pMemoryTypeIndex);
/**
-\brief Helps to find memoryTypeIndex, given VkImageCreateInfo and VmaAllocationCreateInfo.
+\brief Helps to find `memoryTypeIndex`, given `VkImageCreateInfo` and #VmaAllocationCreateInfo.
It can be useful e.g. to determine value to be used as VmaPoolCreateInfo::memoryTypeIndex.
-It internally creates a temporary, dummy image that never has memory bound.
+It may need to internally create a temporary, dummy image that never has memory bound.
*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo(
VmaAllocator VMA_NOT_NULL allocator,
@@ -1962,16 +1998,25 @@ VMA_CALL_PRE void VMA_CALL_POST vmaSetPoolName(
/** \brief General purpose memory allocation.
-\param allocator
-\param pVkMemoryRequirements
-\param pCreateInfo
+\param allocator The main allocator object.
+\param pVkMemoryRequirements Requirements for the allocated memory.
+\param pCreateInfo Allocation creation parameters.
\param[out] pAllocation Handle to allocated memory.
-\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
+\param[out] pAllocationInfo Optional, can be null. Information about allocated memory. It can be also fetched later using vmaGetAllocationInfo().
-You should free the memory using vmaFreeMemory() or vmaFreeMemoryPages().
+The function creates a #VmaAllocation object without creating a buffer or an image together with it.
-It is recommended to use vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage(),
-vmaCreateBuffer(), vmaCreateImage() instead whenever possible.
+- It is recommended to use vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage(),
+ vmaCreateBuffer(), vmaCreateImage() instead whenever possible.
+- You can also create a buffer or an image later in an existing allocation using
+ vmaCreateAliasingBuffer2(), vmaCreateAliasingImage2().
+- You can also create a buffer or an image on your own and bind it to an existing allocation
+ using vmaBindBufferMemory2(), vmaBindImageMemory2().
+
+You must free the returned allocation object using vmaFreeMemory() or vmaFreeMemoryPages().
+
+There is also extended version of this function: vmaAllocateDedicatedMemory()
+that offers additional parameter `pMemoryAllocateNext`.
*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory(
VmaAllocator VMA_NOT_NULL allocator,
@@ -1980,6 +2025,22 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory(
VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
+/** \brief General purpose allocation of a dedicated memory.
+
+This function is similar vmaAllocateMemory(), but
+it always allocates dedicated memory - flag #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT is implied.
+It offers additional parameter `pMemoryAllocateNext`,
+which can be used to attach `pNext` chain to the `VkMemoryAllocateInfo` structure.
+It can be useful for importing external memory. For more information, see \ref other_api_interop.
+*/
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateDedicatedMemory(
+ VmaAllocator VMA_NOT_NULL allocator,
+ const VkMemoryRequirements* VMA_NOT_NULL pVkMemoryRequirements,
+ const VmaAllocationCreateInfo* VMA_NOT_NULL pCreateInfo,
+ void* VMA_NULLABLE VMA_EXTENDS_VK_STRUCT(VkMemoryAllocateInfo) pMemoryAllocateNext,
+ VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
+ VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
+
/** \brief General purpose memory allocation for multiple allocation objects at once.
\param allocator Allocator object.
@@ -2142,13 +2203,16 @@ VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationMemoryProperties(
/**
\brief Given an allocation, returns Win32 handle that may be imported by other processes or APIs.
-\param hTargetProcess Must be a valid handle to target process or null. If it's null, the function returns
+\param allocator The main allocator object.
+\param allocation Allocation.
+\param hTargetProcess A valid handle to target process or null. If it's null, the function returns
handle for the current process.
\param[out] pHandle Output parameter that returns the handle.
The function fills `pHandle` with handle that can be used in target process.
The handle is fetched using function `vkGetMemoryWin32HandleKHR`.
-When no longer needed, you must close it using:
+
+Each call to this function creates a new handle that must be closed using:
\code
CloseHandle(handle);
@@ -2161,14 +2225,76 @@ Note the handle is returned for the entire `VkDeviceMemory` block that the alloc
If the allocation is sub-allocated from a larger block, you may need to consider the offset of the allocation
(VmaAllocationInfo::offset).
+This function always uses `VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT`.
+An extended version of this function is available as vmaGetMemoryWin32Handle2()
+that allows using other handle type.
+
+This function is available compile-time only when VK_KHR_external_memory_win32 extension is available.
+It can be manually disabled by predefining `VMA_EXTERNAL_MEMORY_WIN32=0` macro.
+
If the function fails with `VK_ERROR_FEATURE_NOT_PRESENT` error code, please double-check
-that VmaVulkanFunctions::vkGetMemoryWin32HandleKHR function pointer is set, e.g. either by using `VMA_DYNAMIC_VULKAN_FUNCTIONS`
+that VmaVulkanFunctions::vkGetMemoryWin32HandleKHR function pointer is set, e.g.
+either by using macro `VMA_DYNAMIC_VULKAN_FUNCTIONS`
or by manually passing it through VmaAllocatorCreateInfo::pVulkanFunctions.
-For more information, see chapter \ref vk_khr_external_memory_win32.
+For more information, see chapter \ref other_api_interop.
*/
-VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle(VmaAllocator VMA_NOT_NULL allocator,
- VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle);
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle(
+ VmaAllocator VMA_NOT_NULL allocator,
+ VmaAllocation VMA_NOT_NULL allocation,
+ HANDLE hTargetProcess,
+ HANDLE* VMA_NOT_NULL pHandle);
+
+/**
+\brief Given an allocation, returns Win32 handle that may be imported by other processes or APIs.
+
+\param allocator The main allocator object.
+\param allocation Allocation.
+\param handleType Type of handle to be exported. It should be one of:
+ - `VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR`
+ - `VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR`
+ - `VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR`
+ - `VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR`
+ - `VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR`
+ - `VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR`
+\param hTargetProcess A valid handle to target process or null. If it's null, the function returns
+ handle for the current process.
+\param[out] pHandle Output parameter that returns the handle.
+
+The function fills `pHandle` with handle that can be used in target process.
+The handle is fetched using function `vkGetMemoryWin32HandleKHR`.
+
+If `handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR`,
+or other NT handle types,
+each call to this function creates a new handle that must be closed using:
+
+\code
+CloseHandle(handle);
+\endcode
+
+You can close it any time, before or after destroying the allocation object.
+It is reference-counted internally by Windows.
+
+Note the handle is returned for the entire `VkDeviceMemory` block that the allocation belongs to.
+If the allocation is sub-allocated from a larger block, you may need to consider the offset of the allocation
+(VmaAllocationInfo::offset).
+
+This function is available compile-time only when VK_KHR_external_memory_win32 extension is available.
+It can be manually disabled by predefining `VMA_EXTERNAL_MEMORY_WIN32=0` macro.
+
+If the function fails with `VK_ERROR_FEATURE_NOT_PRESENT` error code, please double-check
+that VmaVulkanFunctions::vkGetMemoryWin32HandleKHR function pointer is set, e.g.
+either by using macro `VMA_DYNAMIC_VULKAN_FUNCTIONS`
+or by manually passing it through VmaAllocatorCreateInfo::pVulkanFunctions.
+
+For more information, see chapter \ref other_api_interop.
+*/
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle2(
+ VmaAllocator VMA_NOT_NULL allocator,
+ VmaAllocation VMA_NOT_NULL allocation,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ HANDLE hTargetProcess,
+ HANDLE* VMA_NOT_NULL pHandle);
#endif // VMA_EXTERNAL_MEMORY_WIN32
/** \brief Maps memory represented by given allocation and returns pointer to it.
@@ -2541,12 +2667,13 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory2(
/** \brief Creates a new `VkBuffer`, allocates and binds memory for it.
-\param allocator
-\param pBufferCreateInfo
-\param pAllocationCreateInfo
+\param allocator The main allocator object.
+\param pBufferCreateInfo Buffer creation parameters.
+\param pAllocationCreateInfo Allocation creation parameters.
\param[out] pBuffer Buffer that was created.
\param[out] pAllocation Allocation that was created.
-\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo().
+\param[out] pAllocationInfo Optional, can be null. Information about allocated memory.
+ It can be also fetched later using vmaGetAllocationInfo().
This function automatically:
@@ -2555,14 +2682,14 @@ This function automatically:
-# Binds the buffer with the memory.
If any of these operations fail, buffer and allocation are not created,
-returned value is negative error code, `*pBuffer` and `*pAllocation` are null.
+returned value is negative error code, `*pBuffer` and `*pAllocation` are returned as null.
If the function succeeded, you must destroy both buffer and allocation when you
no longer need them using either convenience function vmaDestroyBuffer() or
separately, using `vkDestroyBuffer()` and vmaFreeMemory().
-If #VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT flag was used,
-VK_KHR_dedicated_allocation extension is used internally to query driver whether
+If VK_KHR_dedicated_allocation extenion or Vulkan version >= 1.1 is used,
+the function queries the driver whether
it requires or prefers the new buffer to have dedicated allocation. If yes,
and if dedicated allocation is possible
(#VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT is not used), it creates dedicated
@@ -2572,6 +2699,9 @@ allocation for this buffer, just like when using
\note This function creates a new `VkBuffer`. Sub-allocation of parts of one large buffer,
although recommended as a good practice, is out of scope of this library and could be implemented
by the user as a higher-level logic on top of VMA.
+
+There is also an extended versions of this function available with additional parameter `pMemoryAllocateNext` -
+see vmaCreateDedicatedBuffer().
*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBuffer(
VmaAllocator VMA_NOT_NULL allocator,
@@ -2586,6 +2716,10 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBuffer(
Similar to vmaCreateBuffer() but provides additional parameter `minAlignment` which allows to specify custom,
minimum alignment to be used when placing the buffer inside a larger memory block, which may be needed e.g.
for interop with OpenGL.
+
+\deprecated
+This function in obsolete since new VmaAllocationCreateInfo::minAlignment member allows specifying custom
+alignment while using any allocation function, like the standard vmaCreateBuffer().
*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment(
VmaAllocator VMA_NOT_NULL allocator,
@@ -2596,6 +2730,23 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment(
VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
+/** \brief Creates a dedicated buffer while offering extra parameter `pMemoryAllocateNext`.
+
+This function is similar vmaCreateBuffer(), but
+it always allocates dedicated memory for the buffer - flag #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT is implied.
+It offers additional parameter `pMemoryAllocateNext`,
+which can be used to attach `pNext` chain to the `VkMemoryAllocateInfo` structure.
+It can be useful for importing external memory. For more information, see \ref other_api_interop.
+*/
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateDedicatedBuffer(
+ VmaAllocator VMA_NOT_NULL allocator,
+ const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo,
+ const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo,
+ void* VMA_NULLABLE VMA_EXTENDS_VK_STRUCT(VkMemoryAllocateInfo) pMemoryAllocateNext,
+ VkBuffer VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pBuffer,
+ VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
+ VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
+
/** \brief Creates a new `VkBuffer`, binds already created memory for it.
\param allocator
@@ -2668,7 +2819,11 @@ VMA_CALL_PRE void VMA_CALL_POST vmaDestroyBuffer(
VkBuffer VMA_NULLABLE_NON_DISPATCHABLE buffer,
VmaAllocation VMA_NULLABLE allocation);
-/// Function similar to vmaCreateBuffer().
+/** \brief Function similar to vmaCreateBuffer() but for images.
+
+There is also an extended version of this function available: vmaCreateDedicatedImage()
+which offers additional parameter `pMemoryAllocateNext`.
+*/
VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage(
VmaAllocator VMA_NOT_NULL allocator,
const VkImageCreateInfo* VMA_NOT_NULL pImageCreateInfo,
@@ -2677,6 +2832,23 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage(
VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
+/** \brief Function similar to vmaCreateDedicatedBuffer() but for images.
+
+This function is similar vmaCreateImage(), but
+it always allocates dedicated memory for the image - flag #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT is implied.
+It offers additional parameter `pMemoryAllocateNext`,
+which can be used to attach `pNext` chain to the `VkMemoryAllocateInfo` structure.
+It can be useful for importing external memory. For more information, see \ref other_api_interop.
+*/
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateDedicatedImage(
+ VmaAllocator VMA_NOT_NULL allocator,
+ const VkImageCreateInfo* VMA_NOT_NULL pImageCreateInfo,
+ const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo,
+ void* VMA_NULLABLE VMA_EXTENDS_VK_STRUCT(VkMemoryAllocateInfo) pMemoryAllocateNext,
+ VkImage VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pImage,
+ VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation,
+ VmaAllocationInfo* VMA_NULLABLE pAllocationInfo);
+
/// Function similar to vmaCreateAliasingBuffer() but for images.
VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAliasingImage(
VmaAllocator VMA_NOT_NULL allocator,
@@ -2967,7 +3139,7 @@ remove them if not needed.
*/
#if !defined(VMA_CONFIGURATION_USER_INCLUDES_H)
#include // for assert
- #include // for min, max, swap
+ #include // for min, max, swap, sort
#include
#else
#include VMA_CONFIGURATION_USER_INCLUDES_H
@@ -3017,7 +3189,9 @@ remove them if not needed.
#if defined(__ANDROID_API__) && (__ANDROID_API__ < 16)
#include
-static void* vma_aligned_alloc(size_t alignment, size_t size)
+namespace
+{
+void* vma_aligned_alloc(size_t alignment, size_t size)
{
// alignment must be >= sizeof(void*)
if(alignment < sizeof(void*))
@@ -3027,6 +3201,7 @@ static void* vma_aligned_alloc(size_t alignment, size_t size)
return memalign(alignment, size);
}
+} // namespace
#elif defined(__APPLE__) || defined(__ANDROID__) || (defined(__linux__) && defined(__GLIBCXX__) && !defined(_GLIBCXX_HAVE_ALIGNED_ALLOC))
#include
@@ -3034,7 +3209,9 @@ static void* vma_aligned_alloc(size_t alignment, size_t size)
#include
#endif
-static void* vma_aligned_alloc(size_t alignment, size_t size)
+namespace
+{
+void* vma_aligned_alloc(size_t alignment, size_t size)
{
// Unfortunately, aligned_alloc causes VMA to crash due to it returning null pointers. (At least under 11.4)
// Therefore, for now disable this specific exception until a proper solution is found.
@@ -3062,35 +3239,46 @@ static void* vma_aligned_alloc(size_t alignment, size_t size)
return pointer;
return VMA_NULL;
}
+} // namespace
#elif defined(_WIN32)
-static void* vma_aligned_alloc(size_t alignment, size_t size)
+namespace {
+void* vma_aligned_alloc(size_t alignment, size_t size)
{
return _aligned_malloc(size, alignment);
}
+} // namespace
#elif __cplusplus >= 201703L || _MSVC_LANG >= 201703L // C++17
-static void* vma_aligned_alloc(size_t alignment, size_t size)
+namespace {
+void* vma_aligned_alloc(size_t alignment, size_t size)
{
return aligned_alloc(alignment, size);
}
+} // namespace
#else
-static void* vma_aligned_alloc(size_t alignment, size_t size)
+namespace
+{
+void* vma_aligned_alloc(size_t alignment, size_t size)
{
VMA_ASSERT(0 && "Could not implement aligned_alloc automatically. Please enable C++17 or later in your compiler or provide custom implementation of macro VMA_SYSTEM_ALIGNED_MALLOC (and VMA_SYSTEM_ALIGNED_FREE if needed) using the API of your system.");
return VMA_NULL;
}
+} // namespace
#endif
+namespace
+{
#if defined(_WIN32)
-static void vma_aligned_free(void* ptr)
+void vma_aligned_free(void* ptr)
{
_aligned_free(ptr);
}
#else
-static void vma_aligned_free(void* VMA_NULLABLE ptr)
+void vma_aligned_free(void* VMA_NULLABLE ptr)
{
free(ptr);
}
#endif
+} // namespace
#ifndef VMA_ALIGN_OF
#define VMA_ALIGN_OF(type) (alignof(type))
@@ -3171,18 +3359,20 @@ static void vma_aligned_free(void* VMA_NULLABLE ptr)
// Define this macro to 1 to enable functions: vmaBuildStatsString, vmaFreeStatsString.
#if VMA_STATS_STRING_ENABLED
- static inline void VmaUint32ToStr(char* VMA_NOT_NULL outStr, size_t strLen, uint32_t num)
+namespace {
+ inline void VmaUint32ToStr(char* VMA_NOT_NULL outStr, size_t strLen, uint32_t num)
{
snprintf(outStr, strLen, "%" PRIu32, num);
}
- static inline void VmaUint64ToStr(char* VMA_NOT_NULL outStr, size_t strLen, uint64_t num)
+ inline void VmaUint64ToStr(char* VMA_NOT_NULL outStr, size_t strLen, uint64_t num)
{
snprintf(outStr, strLen, "%" PRIu64, num);
}
- static inline void VmaPtrToStr(char* VMA_NOT_NULL outStr, size_t strLen, const void* ptr)
+ inline void VmaPtrToStr(char* VMA_NOT_NULL outStr, size_t strLen, const void* ptr)
{
snprintf(outStr, strLen, "%p", ptr);
}
+} // namespace
#endif
#ifndef VMA_MUTEX
@@ -3266,6 +3456,11 @@ If providing your own implementation, you need to implement a subset of std::ato
#define VMA_ATOMIC_UINT64 std::atomic
#endif
+#ifndef VMA_ATOMIC_BOOL
+ #include
+ #define VMA_ATOMIC_BOOL std::atomic
+#endif
+
#ifndef VMA_DEBUG_ALWAYS_DEDICATED_MEMORY
/**
Every allocation will have its own memory block.
@@ -3377,31 +3572,33 @@ END OF CONFIGURATION
*/
#endif // _VMA_CONFIGURATION
-
-static const uint8_t VMA_ALLOCATION_FILL_PATTERN_CREATED = 0xDC;
-static const uint8_t VMA_ALLOCATION_FILL_PATTERN_DESTROYED = 0xEF;
+namespace
+{
+constexpr uint8_t VMA_ALLOCATION_FILL_PATTERN_CREATED = 0xDC;
+constexpr uint8_t VMA_ALLOCATION_FILL_PATTERN_DESTROYED = 0xEF;
// Decimal 2139416166, float NaN, little-endian binary 66 E6 84 7F.
-static const uint32_t VMA_CORRUPTION_DETECTION_MAGIC_VALUE = 0x7F84E666;
+constexpr uint32_t VMA_CORRUPTION_DETECTION_MAGIC_VALUE = 0x7F84E666;
// Copy of some Vulkan definitions so we don't need to check their existence just to handle few constants.
-static const uint32_t VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY = 0x00000040;
-static const uint32_t VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY = 0x00000080;
-static const uint32_t VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY = 0x00020000;
-static const uint32_t VK_IMAGE_CREATE_DISJOINT_BIT_COPY = 0x00000200;
-static const int32_t VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT_COPY = 1000158000;
-static const uint32_t VMA_ALLOCATION_INTERNAL_STRATEGY_MIN_OFFSET = 0x10000000U;
-static const uint32_t VMA_ALLOCATION_TRY_COUNT = 32;
-static const uint32_t VMA_VENDOR_ID_AMD = 4098;
+constexpr uint32_t VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY = 0x00000040;
+constexpr uint32_t VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY = 0x00000080;
+constexpr uint32_t VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY = 0x00020000;
+constexpr uint32_t VK_IMAGE_CREATE_DISJOINT_BIT_COPY = 0x00000200;
+constexpr int32_t VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT_COPY = 1000158000;
+constexpr uint32_t VMA_ALLOCATION_INTERNAL_STRATEGY_MIN_OFFSET = 0x10000000U;
+constexpr uint32_t VMA_ALLOCATION_TRY_COUNT = 32;
+constexpr uint32_t VMA_VENDOR_ID_AMD = 4098;
// This one is tricky. Vulkan specification defines this code as available since
// Vulkan 1.0, but doesn't actually define it in Vulkan SDK earlier than 1.2.131.
// See pull request #207.
#define VK_ERROR_UNKNOWN_COPY ((VkResult)-13)
+} // namespace
#if VMA_STATS_STRING_ENABLED
// Correspond to values of enum VmaSuballocationType.
-static const char* const VMA_SUBALLOCATION_TYPE_NAMES[] =
+const char* const VMA_SUBALLOCATION_TYPE_NAMES[] =
{
"FREE",
"UNKNOWN",
@@ -3412,7 +3609,7 @@ static const char* const VMA_SUBALLOCATION_TYPE_NAMES[] =
};
#endif
-static const VkAllocationCallbacks VmaEmptyAllocationCallbacks =
+const VkAllocationCallbacks VmaEmptyAllocationCallbacks =
{ VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL };
@@ -3451,6 +3648,8 @@ enum class VmaAllocationRequestType
// Opaque handle used by allocation algorithms to identify single allocation in any conforming way.
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VmaAllocHandle);
+struct VmaBufferImageUsage;
+
struct VmaMutexLock;
struct VmaMutexLockRead;
struct VmaMutexLockWrite;
@@ -3515,419 +3714,12 @@ class VmaAllocationObjectAllocator;
#endif // _VMA_FORWARD_DECLARATIONS
+#ifndef _VMA_BUFFER_IMAGE_USAGE
-#ifndef _VMA_FUNCTIONS
-
-/*
-Returns number of bits set to 1 in (v).
-
-On specific platforms and compilers you can use intrinsics like:
-
-Visual Studio:
- return __popcnt(v);
-GCC, Clang:
- return static_cast(__builtin_popcount(v));
-
-Define macro VMA_COUNT_BITS_SET to provide your optimized implementation.
-But you need to check in runtime whether user's CPU supports these, as some old processors don't.
-*/
-static inline uint32_t VmaCountBitsSet(uint32_t v)
-{
-#if VMA_CPP20
- return std::popcount(v);
-#else
- uint32_t c = v - ((v >> 1) & 0x55555555);
- c = ((c >> 2) & 0x33333333) + (c & 0x33333333);
- c = ((c >> 4) + c) & 0x0F0F0F0F;
- c = ((c >> 8) + c) & 0x00FF00FF;
- c = ((c >> 16) + c) & 0x0000FFFF;
- return c;
-#endif
-}
-
-static inline uint8_t VmaBitScanLSB(uint64_t mask)
-{
-#if defined(_MSC_VER) && defined(_WIN64)
- unsigned long pos;
- if (_BitScanForward64(&pos, mask))
- return static_cast(pos);
- return UINT8_MAX;
-#elif VMA_CPP20
- if(mask != 0)
- return static_cast(std::countr_zero(mask));
- return UINT8_MAX;
-#elif defined __GNUC__ || defined __clang__
- return static_cast(__builtin_ffsll(mask)) - 1U;
-#else
- uint8_t pos = 0;
- uint64_t bit = 1;
- do
- {
- if (mask & bit)
- return pos;
- bit <<= 1;
- } while (pos++ < 63);
- return UINT8_MAX;
-#endif
-}
-
-static inline uint8_t VmaBitScanLSB(uint32_t mask)
-{
-#ifdef _MSC_VER
- unsigned long pos;
- if (_BitScanForward(&pos, mask))
- return static_cast(pos);
- return UINT8_MAX;
-#elif VMA_CPP20
- if(mask != 0)
- return static_cast(std::countr_zero(mask));
- return UINT8_MAX;
-#elif defined __GNUC__ || defined __clang__
- return static_cast(__builtin_ffs(mask)) - 1U;
-#else
- uint8_t pos = 0;
- uint32_t bit = 1;
- do
- {
- if (mask & bit)
- return pos;
- bit <<= 1;
- } while (pos++ < 31);
- return UINT8_MAX;
-#endif
-}
-
-static inline uint8_t VmaBitScanMSB(uint64_t mask)
-{
-#if defined(_MSC_VER) && defined(_WIN64)
- unsigned long pos;
- if (_BitScanReverse64(&pos, mask))
- return static_cast(pos);
-#elif VMA_CPP20
- if(mask != 0)
- return 63 - static_cast(std::countl_zero(mask));
-#elif defined __GNUC__ || defined __clang__
- if (mask != 0)
- return 63 - static_cast(__builtin_clzll(mask));
-#else
- uint8_t pos = 63;
- uint64_t bit = 1ULL << 63;
- do
- {
- if (mask & bit)
- return pos;
- bit >>= 1;
- } while (pos-- > 0);
-#endif
- return UINT8_MAX;
-}
-
-static inline uint8_t VmaBitScanMSB(uint32_t mask)
-{
-#ifdef _MSC_VER
- unsigned long pos;
- if (_BitScanReverse(&pos, mask))
- return static_cast(pos);
-#elif VMA_CPP20
- if(mask != 0)
- return 31 - static_cast(std::countl_zero(mask));
-#elif defined __GNUC__ || defined __clang__
- if (mask != 0)
- return 31 - static_cast(__builtin_clz(mask));
-#else
- uint8_t pos = 31;
- uint32_t bit = 1UL << 31;
- do
- {
- if (mask & bit)
- return pos;
- bit >>= 1;
- } while (pos-- > 0);
-#endif
- return UINT8_MAX;
-}
-
-/*
-Returns true if given number is a power of two.
-T must be unsigned integer number or signed integer but always nonnegative.
-For 0 returns true.
-*/
-template
-inline bool VmaIsPow2(T x)
-{
- return (x & (x - 1)) == 0;
-}
-
-// Aligns given value up to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 16.
-// Use types like uint32_t, uint64_t as T.
-template
-static inline T VmaAlignUp(T val, T alignment)
-{
- VMA_HEAVY_ASSERT(VmaIsPow2(alignment));
- return (val + alignment - 1) & ~(alignment - 1);
-}
-
-// Aligns given value down to nearest multiply of align value. For example: VmaAlignDown(11, 8) = 8.
-// Use types like uint32_t, uint64_t as T.
-template
-static inline T VmaAlignDown(T val, T alignment)
-{
- VMA_HEAVY_ASSERT(VmaIsPow2(alignment));
- return val & ~(alignment - 1);
-}
-
-// Division with mathematical rounding to nearest number.
-template
-static inline T VmaRoundDiv(T x, T y)
-{
- return (x + (y / (T)2)) / y;
-}
-
-// Divide by 'y' and round up to nearest integer.
-template
-static inline T VmaDivideRoundingUp(T x, T y)
-{
- return (x + y - (T)1) / y;
-}
-
-// Returns smallest power of 2 greater or equal to v.
-static inline uint32_t VmaNextPow2(uint32_t v)
-{
- v--;
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- v++;
- return v;
-}
-
-static inline uint64_t VmaNextPow2(uint64_t v)
-{
- v--;
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- v |= v >> 32;
- v++;
- return v;
-}
-
-// Returns largest power of 2 less or equal to v.
-static inline uint32_t VmaPrevPow2(uint32_t v)
-{
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- v = v ^ (v >> 1);
- return v;
-}
-
-static inline uint64_t VmaPrevPow2(uint64_t v)
-{
- v |= v >> 1;
- v |= v >> 2;
- v |= v >> 4;
- v |= v >> 8;
- v |= v >> 16;
- v |= v >> 32;
- v = v ^ (v >> 1);
- return v;
-}
-
-static inline bool VmaStrIsEmpty(const char* pStr)
-{
- return pStr == VMA_NULL || *pStr == '\0';
-}
-
-/*
-Returns true if two memory blocks occupy overlapping pages.
-ResourceA must be in less memory offset than ResourceB.
-
-Algorithm is based on "Vulkan 1.0.39 - A Specification (with all registered Vulkan extensions)"
-chapter 11.6 "Resource Memory Association", paragraph "Buffer-Image Granularity".
-*/
-static inline bool VmaBlocksOnSamePage(
- VkDeviceSize resourceAOffset,
- VkDeviceSize resourceASize,
- VkDeviceSize resourceBOffset,
- VkDeviceSize pageSize)
-{
- VMA_ASSERT(resourceAOffset + resourceASize <= resourceBOffset && resourceASize > 0 && pageSize > 0);
- VkDeviceSize resourceAEnd = resourceAOffset + resourceASize - 1;
- VkDeviceSize resourceAEndPage = resourceAEnd & ~(pageSize - 1);
- VkDeviceSize resourceBStart = resourceBOffset;
- VkDeviceSize resourceBStartPage = resourceBStart & ~(pageSize - 1);
- return resourceAEndPage == resourceBStartPage;
-}
-
-/*
-Returns true if given suballocation types could conflict and must respect
-VkPhysicalDeviceLimits::bufferImageGranularity. They conflict if one is buffer
-or linear image and another one is optimal image. If type is unknown, behave
-conservatively.
-*/
-static inline bool VmaIsBufferImageGranularityConflict(
- VmaSuballocationType suballocType1,
- VmaSuballocationType suballocType2)
-{
- if (suballocType1 > suballocType2)
- {
- std::swap(suballocType1, suballocType2);
- }
-
- switch (suballocType1)
- {
- case VMA_SUBALLOCATION_TYPE_FREE:
- return false;
- case VMA_SUBALLOCATION_TYPE_UNKNOWN:
- return true;
- case VMA_SUBALLOCATION_TYPE_BUFFER:
- return
- suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||
- suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
- case VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN:
- return
- suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||
- suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR ||
- suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
- case VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR:
- return
- suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
- case VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL:
- return false;
- default:
- VMA_ASSERT(0);
- return true;
- }
-}
-
-static void VmaWriteMagicValue(void* pData, VkDeviceSize offset)
-{
-#if VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_DETECT_CORRUPTION
- uint32_t* pDst = (uint32_t*)((char*)pData + offset);
- const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t);
- for (size_t i = 0; i < numberCount; ++i, ++pDst)
- {
- *pDst = VMA_CORRUPTION_DETECTION_MAGIC_VALUE;
- }
-#else
- // no-op
-#endif
-}
-
-static bool VmaValidateMagicValue(const void* pData, VkDeviceSize offset)
-{
-#if VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_DETECT_CORRUPTION
- const uint32_t* pSrc = (const uint32_t*)((const char*)pData + offset);
- const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t);
- for (size_t i = 0; i < numberCount; ++i, ++pSrc)
- {
- if (*pSrc != VMA_CORRUPTION_DETECTION_MAGIC_VALUE)
- {
- return false;
- }
- }
-#endif
- return true;
-}
-
-/*
-Fills structure with parameters of an example buffer to be used for transfers
-during GPU memory defragmentation.
-*/
-static void VmaFillGpuDefragmentationBufferCreateInfo(VkBufferCreateInfo& outBufCreateInfo)
-{
- memset(&outBufCreateInfo, 0, sizeof(outBufCreateInfo));
- outBufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
- outBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
- outBufCreateInfo.size = (VkDeviceSize)VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE; // Example size.
-}
-
-
-/*
-Performs binary search and returns iterator to first element that is greater or
-equal to (key), according to comparison (cmp).
-
-Cmp should return true if first argument is less than second argument.
-
-Returned value is the found element, if present in the collection or place where
-new element with value (key) should be inserted.
-*/
-template
-static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT& key, const CmpLess& cmp)
-{
- size_t down = 0;
- size_t up = size_t(end - beg);
- while (down < up)
- {
- const size_t mid = down + (up - down) / 2; // Overflow-safe midpoint calculation
- if (cmp(*(beg + mid), key))
- {
- down = mid + 1;
- }
- else
- {
- up = mid;
- }
- }
- return beg + down;
-}
-
-template
-IterT VmaBinaryFindSorted(const IterT& beg, const IterT& end, const KeyT& value, const CmpLess& cmp)
-{
- IterT it = VmaBinaryFindFirstNotLess(
- beg, end, value, cmp);
- if (it == end ||
- (!cmp(*it, value) && !cmp(value, *it)))
- {
- return it;
- }
- return end;
-}
-
-/*
-Returns true if all pointers in the array are not-null and unique.
-Warning! O(n^2) complexity. Use only inside VMA_HEAVY_ASSERT.
-T must be pointer type, e.g. VmaAllocation, VmaPool.
-*/
-template
-static bool VmaValidatePointerArray(uint32_t count, const T* arr)
-{
- for (uint32_t i = 0; i < count; ++i)
- {
- const T iPtr = arr[i];
- if (iPtr == VMA_NULL)
- {
- return false;
- }
- for (uint32_t j = i + 1; j < count; ++j)
- {
- if (iPtr == arr[j])
- {
- return false;
- }
- }
- }
- return true;
-}
-
-template
-static inline void VmaPnextChainPushFront(MainT* mainStruct, NewT* newStruct)
-{
- newStruct->pNext = mainStruct->pNext;
- mainStruct->pNext = newStruct;
-}
// Finds structure with s->sType == sType in mainStruct->pNext chain.
// Returns pointer to it. If not found, returns null.
template
-static inline const FindT* VmaPnextChainFind(const MainT* mainStruct, VkStructureType sType)
+inline const FindT* VmaPnextChainFind(const MainT* mainStruct, VkStructureType sType)
{
for(const VkBaseInStructure* s = (const VkBaseInStructure*)mainStruct->pNext;
s != VMA_NULL; s = s->pNext)
@@ -4000,9 +3792,423 @@ VmaBufferImageUsage::VmaBufferImageUsage(const VkImageCreateInfo &createInfo)
// VkImageUsageFlags2CreateInfoKHR, like the one for buffers...
}
+#endif // _VMA_BUFFER_IMAGE_USAGE
+
+#ifndef _VMA_FUNCTIONS
+
+namespace
+{
+
+/*
+Returns number of bits set to 1 in (v).
+
+On specific platforms and compilers you can use intrinsics like:
+
+Visual Studio:
+ return __popcnt(v);
+GCC, Clang:
+ return static_cast(__builtin_popcount(v));
+
+Define macro VMA_COUNT_BITS_SET to provide your optimized implementation.
+But you need to check in runtime whether user's CPU supports these, as some old processors don't.
+*/
+inline uint32_t VmaCountBitsSet(uint32_t v)
+{
+#if VMA_CPP20
+ return std::popcount(v);
+#else
+ uint32_t c = v - ((v >> 1) & 0x55555555);
+ c = ((c >> 2) & 0x33333333) + (c & 0x33333333);
+ c = ((c >> 4) + c) & 0x0F0F0F0F;
+ c = ((c >> 8) + c) & 0x00FF00FF;
+ c = ((c >> 16) + c) & 0x0000FFFF;
+ return c;
+#endif
+}
+
+inline uint8_t VmaBitScanLSB(uint64_t mask)
+{
+#if defined(_MSC_VER) && defined(_WIN64)
+ unsigned long pos;
+ if (_BitScanForward64(&pos, mask))
+ return static_cast(pos);
+ return UINT8_MAX;
+#elif VMA_CPP20
+ if(mask != 0)
+ return static_cast(std::countr_zero(mask));
+ return UINT8_MAX;
+#elif defined __GNUC__ || defined __clang__
+ return static_cast(__builtin_ffsll(mask)) - 1U;
+#else
+ uint8_t pos = 0;
+ uint64_t bit = 1;
+ do
+ {
+ if (mask & bit)
+ return pos;
+ bit <<= 1;
+ } while (pos++ < 63);
+ return UINT8_MAX;
+#endif
+}
+
+inline uint8_t VmaBitScanLSB(uint32_t mask)
+{
+#ifdef _MSC_VER
+ unsigned long pos;
+ if (_BitScanForward(&pos, mask))
+ return static_cast(pos);
+ return UINT8_MAX;
+#elif VMA_CPP20
+ if(mask != 0)
+ return static_cast(std::countr_zero(mask));
+ return UINT8_MAX;
+#elif defined __GNUC__ || defined __clang__
+ return static_cast(__builtin_ffs(mask)) - 1U;
+#else
+ uint8_t pos = 0;
+ uint32_t bit = 1;
+ do
+ {
+ if (mask & bit)
+ return pos;
+ bit <<= 1;
+ } while (pos++ < 31);
+ return UINT8_MAX;
+#endif
+}
+
+inline uint8_t VmaBitScanMSB(uint64_t mask)
+{
+#if defined(_MSC_VER) && defined(_WIN64)
+ unsigned long pos;
+ if (_BitScanReverse64(&pos, mask))
+ return static_cast(pos);
+#elif VMA_CPP20
+ if(mask != 0)
+ return 63 - static_cast(std::countl_zero(mask));
+#elif defined __GNUC__ || defined __clang__
+ if (mask != 0)
+ return 63 - static_cast(__builtin_clzll(mask));
+#else
+ uint8_t pos = 63;
+ uint64_t bit = 1ULL << 63;
+ do
+ {
+ if (mask & bit)
+ return pos;
+ bit >>= 1;
+ } while (pos-- > 0);
+#endif
+ return UINT8_MAX;
+}
+
+inline uint8_t VmaBitScanMSB(uint32_t mask)
+{
+#ifdef _MSC_VER
+ unsigned long pos;
+ if (_BitScanReverse(&pos, mask))
+ return static_cast(pos);
+#elif VMA_CPP20
+ if(mask != 0)
+ return 31 - static_cast(std::countl_zero(mask));
+#elif defined __GNUC__ || defined __clang__
+ if (mask != 0)
+ return 31 - static_cast(__builtin_clz(mask));
+#else
+ uint8_t pos = 31;
+ uint32_t bit = 1UL << 31;
+ do
+ {
+ if (mask & bit)
+ return pos;
+ bit >>= 1;
+ } while (pos-- > 0);
+#endif
+ return UINT8_MAX;
+}
+
+/*
+Returns true if given number is a power of two.
+T must be unsigned integer number or signed integer but always nonnegative.
+For 0 returns true.
+*/
+template
+inline bool VmaIsPow2(T x)
+{
+ return (x & (x - 1)) == 0;
+}
+
+// Aligns given value up to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 16.
+// Use types like uint32_t, uint64_t as T.
+template
+inline T VmaAlignUp(T val, T alignment)
+{
+ VMA_HEAVY_ASSERT(VmaIsPow2(alignment));
+ return (val + alignment - 1) & ~(alignment - 1);
+}
+
+// Aligns given value down to nearest multiply of align value. For example: VmaAlignDown(11, 8) = 8.
+// Use types like uint32_t, uint64_t as T.
+template
+inline T VmaAlignDown(T val, T alignment)
+{
+ VMA_HEAVY_ASSERT(VmaIsPow2(alignment));
+ return val & ~(alignment - 1);
+}
+
+// Division with mathematical rounding to nearest number.
+template
+inline T VmaRoundDiv(T x, T y)
+{
+ return (x + (y / (T)2)) / y;
+}
+
+// Divide by 'y' and round up to nearest integer.
+template
+inline T VmaDivideRoundingUp(T x, T y)
+{
+ return (x + y - (T)1) / y;
+}
+
+// Returns smallest power of 2 greater or equal to v.
+inline uint32_t VmaNextPow2(uint32_t v)
+{
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v++;
+ return v;
+}
+
+inline uint64_t VmaNextPow2(uint64_t v)
+{
+ v--;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v |= v >> 32;
+ v++;
+ return v;
+}
+
+// Returns largest power of 2 less or equal to v.
+inline uint32_t VmaPrevPow2(uint32_t v)
+{
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v = v ^ (v >> 1);
+ return v;
+}
+
+inline uint64_t VmaPrevPow2(uint64_t v)
+{
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ v |= v >> 32;
+ v = v ^ (v >> 1);
+ return v;
+}
+
+inline bool VmaStrIsEmpty(const char* pStr)
+{
+ return pStr == VMA_NULL || *pStr == '\0';
+}
+
+/*
+Returns true if two memory blocks occupy overlapping pages.
+ResourceA must be in less memory offset than ResourceB.
+
+Algorithm is based on "Vulkan 1.0.39 - A Specification (with all registered Vulkan extensions)"
+chapter 11.6 "Resource Memory Association", paragraph "Buffer-Image Granularity".
+*/
+inline bool VmaBlocksOnSamePage(
+ VkDeviceSize resourceAOffset,
+ VkDeviceSize resourceASize,
+ VkDeviceSize resourceBOffset,
+ VkDeviceSize pageSize)
+{
+ VMA_ASSERT(resourceAOffset + resourceASize <= resourceBOffset && resourceASize > 0 && pageSize > 0);
+ VkDeviceSize resourceAEnd = resourceAOffset + resourceASize - 1;
+ VkDeviceSize resourceAEndPage = resourceAEnd & ~(pageSize - 1);
+ VkDeviceSize resourceBStart = resourceBOffset;
+ VkDeviceSize resourceBStartPage = resourceBStart & ~(pageSize - 1);
+ return resourceAEndPage == resourceBStartPage;
+}
+
+/*
+Returns true if given suballocation types could conflict and must respect
+VkPhysicalDeviceLimits::bufferImageGranularity. They conflict if one is buffer
+or linear image and another one is optimal image. If type is unknown, behave
+conservatively.
+*/
+inline bool VmaIsBufferImageGranularityConflict(
+ VmaSuballocationType suballocType1,
+ VmaSuballocationType suballocType2)
+{
+ if (suballocType1 > suballocType2)
+ {
+ std::swap(suballocType1, suballocType2);
+ }
+
+ switch (suballocType1)
+ {
+ case VMA_SUBALLOCATION_TYPE_FREE:
+ return false;
+ case VMA_SUBALLOCATION_TYPE_UNKNOWN:
+ return true;
+ case VMA_SUBALLOCATION_TYPE_BUFFER:
+ return
+ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||
+ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
+ case VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN:
+ return
+ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN ||
+ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR ||
+ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
+ case VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR:
+ return
+ suballocType2 == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL;
+ case VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL:
+ return false;
+ default:
+ VMA_ASSERT(0);
+ return true;
+ }
+}
+
+void VmaWriteMagicValue(void* pData, VkDeviceSize offset)
+{
+#if VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_DETECT_CORRUPTION
+ uint32_t* pDst = (uint32_t*)((char*)pData + offset);
+ const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t);
+ for (size_t i = 0; i < numberCount; ++i, ++pDst)
+ {
+ *pDst = VMA_CORRUPTION_DETECTION_MAGIC_VALUE;
+ }
+#else
+ // no-op
+#endif
+}
+
+bool VmaValidateMagicValue(const void* pData, VkDeviceSize offset)
+{
+#if VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_DETECT_CORRUPTION
+ const uint32_t* pSrc = (const uint32_t*)((const char*)pData + offset);
+ const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t);
+ for (size_t i = 0; i < numberCount; ++i, ++pSrc)
+ {
+ if (*pSrc != VMA_CORRUPTION_DETECTION_MAGIC_VALUE)
+ {
+ return false;
+ }
+ }
+#endif
+ return true;
+}
+
+/*
+Fills structure with parameters of an example buffer to be used for transfers
+during GPU memory defragmentation.
+*/
+void VmaFillGpuDefragmentationBufferCreateInfo(VkBufferCreateInfo& outBufCreateInfo)
+{
+ memset(&outBufCreateInfo, 0, sizeof(outBufCreateInfo));
+ outBufCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ outBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+ outBufCreateInfo.size = (VkDeviceSize)VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE; // Example size.
+}
+
+
+/*
+Performs binary search and returns iterator to first element that is greater or
+equal to (key), according to comparison (cmp).
+
+Cmp should return true if first argument is less than second argument.
+
+Returned value is the found element, if present in the collection or place where
+new element with value (key) should be inserted.
+*/
+template
+IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT& key, const CmpLess& cmp)
+{
+ size_t down = 0;
+ size_t up = size_t(end - beg);
+ while (down < up)
+ {
+ const size_t mid = down + (up - down) / 2; // Overflow-safe midpoint calculation
+ if (cmp(*(beg + mid), key))
+ {
+ down = mid + 1;
+ }
+ else
+ {
+ up = mid;
+ }
+ }
+ return beg + down;
+}
+
+template
+IterT VmaBinaryFindSorted(const IterT& beg, const IterT& end, const KeyT& value, const CmpLess& cmp)
+{
+ IterT it = VmaBinaryFindFirstNotLess(
+ beg, end, value, cmp);
+ if (it == end ||
+ (!cmp(*it, value) && !cmp(value, *it)))
+ {
+ return it;
+ }
+ return end;
+}
+
+/*
+Returns true if all pointers in the array are not-null and unique.
+Warning! O(n^2) complexity. Use only inside VMA_HEAVY_ASSERT.
+T must be pointer type, e.g. VmaAllocation, VmaPool.
+*/
+template
+bool VmaValidatePointerArray(uint32_t count, const T* arr)
+{
+ for (uint32_t i = 0; i < count; ++i)
+ {
+ const T iPtr = arr[i];
+ if (iPtr == VMA_NULL)
+ {
+ return false;
+ }
+ for (uint32_t j = i + 1; j < count; ++j)
+ {
+ if (iPtr == arr[j])
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+template
+inline void VmaPnextChainPushFront(MainT* mainStruct, NewT* newStruct)
+{
+ newStruct->pNext = mainStruct->pNext;
+ mainStruct->pNext = newStruct;
+}
+
// This is the main algorithm that guides the selection of a memory type best for an allocation -
// converts usage to required/preferred/not preferred flags.
-static bool FindMemoryPreferences(
+bool FindMemoryPreferences(
bool isIntegratedGPU,
const VmaAllocationCreateInfo& allocCreateInfo,
VmaBufferImageUsage bufImgUsage,
@@ -4078,8 +4284,11 @@ static bool FindMemoryPreferences(
}
else
{
- // Always CPU memory.
- outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+ if(hostAccessAllowTransferInstead)
+ outPreferredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+ else
+ // Always CPU memory.
+ outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
}
}
// CPU sequential write - may be CPU or host-visible GPU memory, uncached and write-combined.
@@ -4094,7 +4303,12 @@ static bool FindMemoryPreferences(
}
else
{
- outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+ if(hostAccessAllowTransferInstead)
+ outPreferredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+ else
+ // Always CPU memory.
+ outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+
// Direct GPU access, CPU sequential write (e.g. a dynamic uniform buffer updated every frame)
if(deviceAccess)
{
@@ -4154,7 +4368,7 @@ static bool FindMemoryPreferences(
////////////////////////////////////////////////////////////////////////////////
// Memory allocation
-static void* VmaMalloc(const VkAllocationCallbacks* pAllocationCallbacks, size_t size, size_t alignment)
+inline void* VmaMalloc(const VkAllocationCallbacks* pAllocationCallbacks, size_t size, size_t alignment)
{
void* result = VMA_NULL;
if ((pAllocationCallbacks != VMA_NULL) &&
@@ -4174,7 +4388,7 @@ static void* VmaMalloc(const VkAllocationCallbacks* pAllocationCallbacks, size_t
return result;
}
-static void VmaFree(const VkAllocationCallbacks* pAllocationCallbacks, void* ptr)
+inline void VmaFree(const VkAllocationCallbacks* pAllocationCallbacks, void* ptr)
{
if ((pAllocationCallbacks != VMA_NULL) &&
(pAllocationCallbacks->pfnFree != VMA_NULL))
@@ -4188,13 +4402,13 @@ static void VmaFree(const VkAllocationCallbacks* pAllocationCallbacks, void* ptr
}
template
-static T* VmaAllocate(const VkAllocationCallbacks* pAllocationCallbacks)
+T* VmaAllocate(const VkAllocationCallbacks* pAllocationCallbacks)
{
return (T*)VmaMalloc(pAllocationCallbacks, sizeof(T), VMA_ALIGN_OF(T));
}
template
-static T* VmaAllocateArray(const VkAllocationCallbacks* pAllocationCallbacks, size_t count)
+T* VmaAllocateArray(const VkAllocationCallbacks* pAllocationCallbacks, size_t count)
{
return (T*)VmaMalloc(pAllocationCallbacks, sizeof(T) * count, VMA_ALIGN_OF(T));
}
@@ -4204,14 +4418,14 @@ static T* VmaAllocateArray(const VkAllocationCallbacks* pAllocationCallbacks, si
#define vma_new_array(allocator, type, count) new(VmaAllocateArray((allocator), (count)))(type)
template
-static void vma_delete(const VkAllocationCallbacks* pAllocationCallbacks, T* ptr)
+void vma_delete(const VkAllocationCallbacks* pAllocationCallbacks, T* ptr)
{
ptr->~T();
VmaFree(pAllocationCallbacks, ptr);
}
template
-static void vma_delete_array(const VkAllocationCallbacks* pAllocationCallbacks, T* ptr, size_t count)
+void vma_delete_array(const VkAllocationCallbacks* pAllocationCallbacks, T* ptr, size_t count)
{
if (ptr != VMA_NULL)
{
@@ -4223,7 +4437,7 @@ static void vma_delete_array(const VkAllocationCallbacks* pAllocationCallbacks,
}
}
-static char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char* srcStr)
+char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char* srcStr)
{
if (srcStr != VMA_NULL)
{
@@ -4236,7 +4450,7 @@ static char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char
}
#if VMA_STATS_STRING_ENABLED
-static char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char* srcStr, size_t strLen)
+char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char* srcStr, size_t strLen)
{
if (srcStr != VMA_NULL)
{
@@ -4249,7 +4463,7 @@ static char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char
}
#endif // VMA_STATS_STRING_ENABLED
-static void VmaFreeString(const VkAllocationCallbacks* allocs, char* str)
+void VmaFreeString(const VkAllocationCallbacks* allocs, char* str)
{
if (str != VMA_NULL)
{
@@ -4287,11 +4501,17 @@ bool VmaVectorRemoveSorted(VectorT& vector, const typename VectorT::value_type&
}
return false;
}
+
+} // namespace
+
#endif // _VMA_FUNCTIONS
#ifndef _VMA_STATISTICS_FUNCTIONS
-static void VmaClearStatistics(VmaStatistics& outStats)
+namespace
+{
+
+void VmaClearStatistics(VmaStatistics& outStats)
{
outStats.blockCount = 0;
outStats.allocationCount = 0;
@@ -4299,7 +4519,7 @@ static void VmaClearStatistics(VmaStatistics& outStats)
outStats.allocationBytes = 0;
}
-static void VmaAddStatistics(VmaStatistics& inoutStats, const VmaStatistics& src)
+void VmaAddStatistics(VmaStatistics& inoutStats, const VmaStatistics& src)
{
inoutStats.blockCount += src.blockCount;
inoutStats.allocationCount += src.allocationCount;
@@ -4307,7 +4527,7 @@ static void VmaAddStatistics(VmaStatistics& inoutStats, const VmaStatistics& src
inoutStats.allocationBytes += src.allocationBytes;
}
-static void VmaClearDetailedStatistics(VmaDetailedStatistics& outStats)
+void VmaClearDetailedStatistics(VmaDetailedStatistics& outStats)
{
VmaClearStatistics(outStats.statistics);
outStats.unusedRangeCount = 0;
@@ -4317,7 +4537,7 @@ static void VmaClearDetailedStatistics(VmaDetailedStatistics& outStats)
outStats.unusedRangeSizeMax = 0;
}
-static void VmaAddDetailedStatisticsAllocation(VmaDetailedStatistics& inoutStats, VkDeviceSize size)
+void VmaAddDetailedStatisticsAllocation(VmaDetailedStatistics& inoutStats, VkDeviceSize size)
{
inoutStats.statistics.allocationCount++;
inoutStats.statistics.allocationBytes += size;
@@ -4325,14 +4545,14 @@ static void VmaAddDetailedStatisticsAllocation(VmaDetailedStatistics& inoutStats
inoutStats.allocationSizeMax = VMA_MAX(inoutStats.allocationSizeMax, size);
}
-static void VmaAddDetailedStatisticsUnusedRange(VmaDetailedStatistics& inoutStats, VkDeviceSize size)
+void VmaAddDetailedStatisticsUnusedRange(VmaDetailedStatistics& inoutStats, VkDeviceSize size)
{
inoutStats.unusedRangeCount++;
inoutStats.unusedRangeSizeMin = VMA_MIN(inoutStats.unusedRangeSizeMin, size);
inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, size);
}
-static void VmaAddDetailedStatistics(VmaDetailedStatistics& inoutStats, const VmaDetailedStatistics& src)
+void VmaAddDetailedStatistics(VmaDetailedStatistics& inoutStats, const VmaDetailedStatistics& src)
{
VmaAddStatistics(inoutStats.statistics, src.statistics);
inoutStats.unusedRangeCount += src.unusedRangeCount;
@@ -4342,6 +4562,8 @@ static void VmaAddDetailedStatistics(VmaDetailedStatistics& inoutStats, const Vm
inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, src.unusedRangeSizeMax);
}
+} // namespace
+
#endif // _VMA_STATISTICS_FUNCTIONS
#ifndef _VMA_MUTEX_LOCK
@@ -4441,8 +4663,8 @@ struct VmaStlAllocator
VmaStlAllocator(const VmaStlAllocator&) = default;
VmaStlAllocator& operator=(const VmaStlAllocator&) = delete;
- T* allocate(size_t n) { return VmaAllocateArray(m_pCallbacks, n); }
- void deallocate(T* p, size_t n) { VmaFree(m_pCallbacks, p); }
+ T* allocate(size_t n);
+ void deallocate(T* p, size_t n);
template
bool operator==(const VmaStlAllocator& rhs) const
@@ -4455,6 +4677,12 @@ struct VmaStlAllocator
return m_pCallbacks != rhs.m_pCallbacks;
}
};
+
+template
+T* VmaStlAllocator::allocate(size_t n) { return VmaAllocateArray(m_pCallbacks, n); }
+
+template
+void VmaStlAllocator::deallocate(T* p, size_t n) { VmaFree(m_pCallbacks, p); }
#endif // _VMA_STL_ALLOCATOR
#ifndef _VMA_VECTOR
@@ -4476,7 +4704,7 @@ public:
VmaVector(size_t count, const T& value, const AllocatorT& allocator) : VmaVector(count, allocator) {}
VmaVector(const VmaVector& src);
VmaVector& operator=(const VmaVector& rhs);
- ~VmaVector() { VmaFree(m_Allocator.m_pCallbacks, m_pArray); }
+ ~VmaVector();
bool empty() const { return m_Count == 0; }
size_t size() const { return m_Count; }
@@ -4517,6 +4745,9 @@ private:
};
#ifndef _VMA_VECTOR_FUNCTIONS
+template
+VmaVector::~VmaVector() { VmaFree(m_Allocator.m_pCallbacks, m_pArray); }
+
template
VmaVector::VmaVector(const AllocatorT& allocator)
: m_Allocator(allocator),
@@ -4600,7 +4831,8 @@ void VmaVector::resize(size_t newCount)
if (newCapacity != m_Capacity)
{
- T* const newArray = newCapacity ? VmaAllocateArray(m_Allocator.m_pCallbacks, newCapacity) : VMA_NULL;
+ VMA_HEAVY_ASSERT(newCapacity > 0);
+ T* const newArray = VmaAllocateArray(m_Allocator.m_pCallbacks, newCapacity);
const size_t elementsToCopy = VMA_MIN(m_Count, newCount);
if (elementsToCopy != 0)
{
@@ -4657,17 +4889,23 @@ void VmaVector::remove(size_t index)
}
#endif // _VMA_VECTOR_FUNCTIONS
+namespace
+{
+
template
-static void VmaVectorInsert(VmaVector& vec, size_t index, const T& item)
+void VmaVectorInsert(VmaVector& vec, size_t index, const T& item)
{
vec.insert(index, item);
}
template
-static void VmaVectorRemove(VmaVector& vec, size_t index)
+void VmaVectorRemove(VmaVector& vec, size_t index)
{
vec.remove(index);
}
+
+} // namespace
+
#endif // _VMA_VECTOR
#ifndef _VMA_SMALL_VECTOR
@@ -6065,7 +6303,10 @@ void VmaJsonWriter::WriteIndent(bool oneLess)
}
#endif // _VMA_JSON_WRITER_FUNCTIONS
-static void VmaPrintDetailedStatistics(VmaJsonWriter& json, const VmaDetailedStatistics& stat)
+namespace
+{
+
+void VmaPrintDetailedStatistics(VmaJsonWriter& json, const VmaDetailedStatistics& stat)
{
json.BeginObject();
@@ -6096,6 +6337,9 @@ static void VmaPrintDetailedStatistics(VmaJsonWriter& json, const VmaDetailedSta
}
json.EndObject();
}
+
+} // namespace
+
#endif // _VMA_JSON_WRITER
#ifndef _VMA_MAPPING_HYSTERESIS
@@ -6176,7 +6420,7 @@ public:
}
private:
- static const int32_t COUNTER_MIN_EXTRA_MAPPING = 7;
+ static constexpr int32_t COUNTER_MIN_EXTRA_MAPPING = 7;
uint32_t m_MinorCounter = 0;
uint32_t m_MajorCounter = 0;
@@ -6203,40 +6447,45 @@ class VmaWin32Handle
{
public:
VmaWin32Handle() noexcept : m_hHandle(VMA_NULL) { }
- explicit VmaWin32Handle(HANDLE hHandle) noexcept : m_hHandle(hHandle) { }
- ~VmaWin32Handle() noexcept { if (m_hHandle != VMA_NULL) { ::CloseHandle(m_hHandle); } }
+ explicit VmaWin32Handle(HANDLE hHandle) noexcept
+ : m_hHandle(hHandle)
+ , m_IsNTHandle(IsNTHandle(hHandle))
+ {
+ }
+ ~VmaWin32Handle() noexcept { if (m_hHandle != VMA_NULL && m_IsNTHandle) { ::CloseHandle(m_hHandle); } }
VMA_CLASS_NO_COPY_NO_MOVE(VmaWin32Handle)
public:
// Strengthened
- VkResult GetHandle(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, bool useMutex, HANDLE* pHandle) noexcept
+ VkResult GetHandle(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE hTargetProcess, bool useMutex, HANDLE* pHandle) noexcept
{
*pHandle = VMA_NULL;
// Try to get handle first.
- if (m_hHandle != VMA_NULL)
- {
- *pHandle = Duplicate(hTargetProcess);
- return VK_SUCCESS;
- }
-
VkResult res = VK_SUCCESS;
- // If failed, try to create it.
+ if (m_hHandle == VMA_NULL)
{
VmaMutexLockWrite lock(m_Mutex, useMutex);
if (m_hHandle == VMA_NULL)
{
- res = Create(device, memory, pvkGetMemoryWin32HandleKHR, &m_hHandle);
+ res = Create(device, memory, pvkGetMemoryWin32HandleKHR, handleType, &m_hHandle);
+ if (res != VK_SUCCESS) {
+ m_hHandle = VMA_NULL;
+ return res;
+ }
+ m_IsNTHandle = IsNTHandle(m_hHandle);
}
}
-
- *pHandle = Duplicate(hTargetProcess);
+ if (res == VK_SUCCESS) {
+ // KMT handle is returned as is.
+ *pHandle = m_IsNTHandle ? Duplicate(hTargetProcess) : m_hHandle;
+ }
return res;
}
operator bool() const noexcept { return m_hHandle != VMA_NULL; }
private:
// Not atomic
- static VkResult Create(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE* pHandle) noexcept
+ static VkResult Create(VkDevice device, VkDeviceMemory memory, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE* pHandle) noexcept
{
VkResult res = VK_ERROR_FEATURE_NOT_PRESENT;
if (pvkGetMemoryWin32HandleKHR != VMA_NULL)
@@ -6244,7 +6493,7 @@ private:
VkMemoryGetWin32HandleInfoKHR handleInfo{ };
handleInfo.sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR;
handleInfo.memory = memory;
- handleInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
+ handleInfo.handleType = handleType;
res = pvkGetMemoryWin32HandleKHR(device, &handleInfo, pHandle);
}
return res;
@@ -6262,9 +6511,15 @@ private:
}
return hDupHandle;
}
+ static bool IsNTHandle(HANDLE hHandle) noexcept
+ {
+ DWORD flags = 0;
+ return (hHandle != VMA_NULL) ? (::GetHandleInformation(hHandle, &flags) != 0) : false;
+ }
private:
HANDLE m_hHandle;
VMA_RW_MUTEX m_Mutex; // Protects access m_Handle
+ bool m_IsNTHandle = false; // True if m_Handle is NT handle, false if it's a KMT handle.
};
#else
class VmaWin32Handle
@@ -6272,6 +6527,7 @@ class VmaWin32Handle
// ABI compatibility
void* placeholder = VMA_NULL;
VMA_RW_MUTEX placeholder2;
+ bool placeholder3 = false;
};
#endif // VMA_EXTERNAL_MEMORY_WIN32
@@ -6312,6 +6568,7 @@ public:
uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; }
uint32_t GetId() const { return m_Id; }
void* GetMappedData() const { return m_pMappedData; }
+ bool IsMapped() const { return m_IsMapped.load(); }
uint32_t GetMapRefCount() const { return m_MapCount; }
// Call when allocation/free was made from m_pMetadata.
@@ -6346,6 +6603,7 @@ public:
VkResult CreateWin32Handle(
const VmaAllocator hAllocator,
PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR,
+ VkExternalMemoryHandleTypeFlagBits handleType,
HANDLE hTargetProcess,
HANDLE* pHandle)noexcept;
#endif // VMA_EXTERNAL_MEMORY_WIN32
@@ -6358,12 +6616,18 @@ private:
/*
Protects access to m_hMemory so it is not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory.
Also protects m_MapCount, m_pMappedData.
+ m_IsMapped mirrors whether m_pMappedData is non-null and can be read without this mutex in allocation heuristics.
Allocations, deallocations, any change in m_pMetadata is protected by parent's VmaBlockVector::m_Mutex.
*/
VMA_MUTEX m_MapAndBindMutex;
VmaMappingHysteresis m_MappingHysteresis;
uint32_t m_MapCount;
void* m_pMappedData;
+ /*
+ Mirrors `m_pMappedData != VMA_NULL` for allocation heuristics that only need mapped/unmapped state.
+ This is atomic so allocation scans don't race with Map/Unmap while the actual mapped pointer remains protected by m_MapAndBindMutex.
+ */
+ VMA_ATOMIC_BOOL m_IsMapped;
VmaWin32Handle m_Handle;
};
@@ -6460,7 +6724,7 @@ public:
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
- VkResult GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* hHandle) noexcept;
+ VkResult GetWin32Handle(VmaAllocator hAllocator, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE hTargetProcess, HANDLE* hHandle) noexcept;
#endif // VMA_EXTERNAL_MEMORY_WIN32
private:
@@ -6928,6 +7192,14 @@ void VmaBlockMetadata::PrintDetailedMap_End(class VmaJsonWriter& json)
#ifndef _VMA_BLOCK_BUFFER_IMAGE_GRANULARITY
// Before deleting object of this class remember to call 'Destroy()'
+/*
+Tracks block occupancy at VkPhysicalDeviceLimits::bufferImageGranularity page boundaries.
+For each granularity-sized page in a memory block, m_RegionInfo stores:
+- allocCount: how many allocations touch this page as their first or last page.
+- allocType: the remembered VmaSuballocationType for that page while allocCount > 0.
+Only boundary pages are tracked because buffer-image granularity conflicts matter when
+adjacent allocations share the same granularity page at the start or end of an allocation.
+*/
class VmaBlockBufferImageGranularity final
{
public:
@@ -6950,6 +7222,21 @@ public:
VkDeviceSize& inOutAllocSize,
VkDeviceSize& inOutAllocAlignment) const;
+ /*
+ Checks whether an allocation placed in a free block would conflict with existing
+ allocations due to buffer-image granularity requirements and, if needed, aligns the
+ allocation start to the next granularity page.
+
+ Parameters:
+ - inOutAllocOffset: candidate allocation offset inside the block; may be increased.
+ - allocSize: size of the allocation being placed.
+ - blockOffset: start offset of the free block being considered.
+ - blockSize: size of the free block being considered.
+ - allocType: VmaSuballocationType of the allocation being placed.
+
+ Returns true when the placement conflicts or no longer fits in the free block after alignment.
+ Returns false when the placement is valid, possibly after updating inOutAllocOffset.
+ */
bool CheckConflictAndAlignUp(VkDeviceSize& inOutAllocOffset,
VkDeviceSize allocSize,
VkDeviceSize blockOffset,
@@ -6966,7 +7253,7 @@ public:
bool FinishValidation(ValidationContext& ctx) const;
private:
- static const uint16_t MAX_LOW_BUFFER_IMAGE_GRANULARITY = 256;
+ static constexpr uint16_t MAX_LOW_BUFFER_IMAGE_GRANULARITY = 256;
struct RegionInfo
{
@@ -7038,56 +7325,62 @@ bool VmaBlockBufferImageGranularity::CheckConflictAndAlignUp(VkDeviceSize& inOut
VkDeviceSize blockSize,
VmaSuballocationType allocType) const
{
- if (IsEnabled())
+ if (!IsEnabled())
+ return false;
+
+ uint32_t startPage = GetStartPage(inOutAllocOffset);
+ if (m_RegionInfo[startPage].allocCount > 0 &&
+ VmaIsBufferImageGranularityConflict(static_cast(m_RegionInfo[startPage].allocType), allocType))
{
- uint32_t startPage = GetStartPage(inOutAllocOffset);
+ inOutAllocOffset = VmaAlignUp(inOutAllocOffset, m_BufferImageGranularity);
+ if (blockSize < allocSize + inOutAllocOffset - blockOffset)
+ return true;
+ startPage = GetStartPage(inOutAllocOffset);
if (m_RegionInfo[startPage].allocCount > 0 &&
VmaIsBufferImageGranularityConflict(static_cast(m_RegionInfo[startPage].allocType), allocType))
- {
- inOutAllocOffset = VmaAlignUp(inOutAllocOffset, m_BufferImageGranularity);
- if (blockSize < allocSize + inOutAllocOffset - blockOffset)
- return true;
- ++startPage;
- }
- uint32_t endPage = GetEndPage(inOutAllocOffset, allocSize);
- if (endPage != startPage &&
- m_RegionInfo[endPage].allocCount > 0 &&
- VmaIsBufferImageGranularityConflict(static_cast(m_RegionInfo[endPage].allocType), allocType))
{
return true;
}
}
+ uint32_t endPage = GetEndPage(inOutAllocOffset, allocSize);
+ if (endPage != startPage &&
+ m_RegionInfo[endPage].allocCount > 0 &&
+ VmaIsBufferImageGranularityConflict(static_cast(m_RegionInfo[endPage].allocType), allocType))
+ {
+ return true;
+ }
+
return false;
}
void VmaBlockBufferImageGranularity::AllocPages(uint8_t allocType, VkDeviceSize offset, VkDeviceSize size)
{
- if (IsEnabled())
- {
- uint32_t startPage = GetStartPage(offset);
- AllocPage(m_RegionInfo[startPage], allocType);
+ if (!IsEnabled())
+ return;
- uint32_t endPage = GetEndPage(offset, size);
- if (startPage != endPage)
- AllocPage(m_RegionInfo[endPage], allocType);
- }
+ uint32_t startPage = GetStartPage(offset);
+ AllocPage(m_RegionInfo[startPage], allocType);
+
+ uint32_t endPage = GetEndPage(offset, size);
+ if (startPage != endPage)
+ AllocPage(m_RegionInfo[endPage], allocType);
}
void VmaBlockBufferImageGranularity::FreePages(VkDeviceSize offset, VkDeviceSize size)
{
- if (IsEnabled())
+ if (!IsEnabled())
+ return;
+
+ uint32_t startPage = GetStartPage(offset);
+ --m_RegionInfo[startPage].allocCount;
+ if (m_RegionInfo[startPage].allocCount == 0)
+ m_RegionInfo[startPage].allocType = VMA_SUBALLOCATION_TYPE_FREE;
+ uint32_t endPage = GetEndPage(offset, size);
+ if (startPage != endPage)
{
- uint32_t startPage = GetStartPage(offset);
- --m_RegionInfo[startPage].allocCount;
- if (m_RegionInfo[startPage].allocCount == 0)
- m_RegionInfo[startPage].allocType = VMA_SUBALLOCATION_TYPE_FREE;
- uint32_t endPage = GetEndPage(offset, size);
- if (startPage != endPage)
- {
- --m_RegionInfo[endPage].allocCount;
- if (m_RegionInfo[endPage].allocCount == 0)
- m_RegionInfo[endPage].allocType = VMA_SUBALLOCATION_TYPE_FREE;
- }
+ --m_RegionInfo[endPage].allocCount;
+ if (m_RegionInfo[endPage].allocCount == 0)
+ m_RegionInfo[endPage].allocType = VMA_SUBALLOCATION_TYPE_FREE;
}
}
@@ -7112,36 +7405,38 @@ VmaBlockBufferImageGranularity::ValidationContext VmaBlockBufferImageGranularity
bool VmaBlockBufferImageGranularity::Validate(ValidationContext& ctx,
VkDeviceSize offset, VkDeviceSize size) const
{
- if (IsEnabled())
- {
- uint32_t start = GetStartPage(offset);
- ++ctx.pageAllocs[start];
- VMA_VALIDATE(m_RegionInfo[start].allocCount > 0);
+ if (!IsEnabled())
+ return true;
- uint32_t end = GetEndPage(offset, size);
- if (start != end)
- {
- ++ctx.pageAllocs[end];
- VMA_VALIDATE(m_RegionInfo[end].allocCount > 0);
- }
+ uint32_t start = GetStartPage(offset);
+ ++ctx.pageAllocs[start];
+ VMA_VALIDATE(m_RegionInfo[start].allocCount > 0);
+
+ uint32_t end = GetEndPage(offset, size);
+ if (start != end)
+ {
+ ++ctx.pageAllocs[end];
+ VMA_VALIDATE(m_RegionInfo[end].allocCount > 0);
}
+
return true;
}
bool VmaBlockBufferImageGranularity::FinishValidation(ValidationContext& ctx) const
{
- // Check proper page structure
- if (IsEnabled())
- {
- VMA_ASSERT(ctx.pageAllocs != VMA_NULL && "Validation context not initialized!");
+ if (!IsEnabled())
+ return true;
- for (uint32_t page = 0; page < m_RegionCount; ++page)
- {
- VMA_VALIDATE(ctx.pageAllocs[page] == m_RegionInfo[page].allocCount);
- }
- vma_delete_array(ctx.allocCallbacks, ctx.pageAllocs, m_RegionCount);
- ctx.pageAllocs = VMA_NULL;
+ // Check proper page structure
+ VMA_ASSERT(ctx.pageAllocs != VMA_NULL && "Validation context not initialized!");
+
+ for (uint32_t page = 0; page < m_RegionCount; ++page)
+ {
+ VMA_VALIDATE(ctx.pageAllocs[page] == m_RegionInfo[page].allocCount);
}
+ vma_delete_array(ctx.allocCallbacks, ctx.pageAllocs, m_RegionCount);
+ ctx.pageAllocs = VMA_NULL;
+
return true;
}
@@ -8907,11 +9202,11 @@ private:
// According to original paper it should be preferable 4 or 5:
// M. Masmano, I. Ripoll, A. Crespo, and J. Real "TLSF: a New Dynamic Memory Allocator for Real-Time Systems"
// http://www.gii.upv.es/tlsf/files/ecrts04_tlsf.pdf
- static const uint8_t SECOND_LEVEL_INDEX = 5;
- static const uint16_t SMALL_BUFFER_SIZE = 256;
- static const uint32_t INITIAL_BLOCK_ALLOC_COUNT = 16;
- static const uint8_t MEMORY_CLASS_SHIFT = 7;
- static const uint8_t MAX_MEMORY_CLASSES = 65 - MEMORY_CLASS_SHIFT;
+ static constexpr uint8_t SECOND_LEVEL_INDEX = 5;
+ static constexpr uint16_t SMALL_BUFFER_SIZE = 256;
+ static constexpr uint32_t INITIAL_BLOCK_ALLOC_COUNT = 16;
+ static constexpr uint8_t MEMORY_CLASS_SHIFT = 7;
+ static constexpr uint8_t MAX_MEMORY_CLASSES = 65 - MEMORY_CLASS_SHIFT;
class Block
{
@@ -9927,7 +10222,7 @@ public:
private:
// Max number of allocations to ignore due to size constraints before ending single pass
- static const uint8_t MAX_ALLOCS_TO_IGNORE = 16;
+ static constexpr uint8_t MAX_ALLOCS_TO_IGNORE = 16;
enum class CounterStatus { Pass, Ignore, End };
struct FragmentedBlock
@@ -10385,14 +10680,32 @@ public:
VmaBufferImageUsage bufImgUsage,
uint32_t* pMemoryTypeIndex) const;
+ // Common code for public functions vmaCreateBuffer, vmaCreateBufferWithAlignment, etc.
+ VkResult CreateBuffer(
+ const VkBufferCreateInfo* pBufferCreateInfo,
+ const VmaAllocationCreateInfo* pAllocationCreateInfo,
+ void* pMemoryAllocateNext, // pNext chain for VkMemoryAllocateInfo.
+ VkBuffer* pBuffer,
+ VmaAllocation* pAllocation,
+ VmaAllocationInfo* pAllocationInfo);
+ // Common code for public functions vmaCreateImage, vmaCreateDedicatedImage.
+ VkResult CreateImage(
+ const VkImageCreateInfo* pImageCreateInfo,
+ const VmaAllocationCreateInfo* pAllocationCreateInfo,
+ void* pMemoryAllocateNext, // pNext chain for VkMemoryAllocateInfo.
+ VkImage* pImage,
+ VmaAllocation* pAllocation,
+ VmaAllocationInfo* pAllocationInfo);
+
// Main allocation function.
VkResult AllocateMemory(
- const VkMemoryRequirements& vkMemReq,
+ VkMemoryRequirements vkMemReq,
bool requiresDedicatedAllocation,
bool prefersDedicatedAllocation,
VkBuffer dedicatedBuffer,
VkImage dedicatedImage,
VmaBufferImageUsage dedicatedBufferImageUsage,
+ void* pMemoryAllocateNext, // Optional pNext chain for VkMemoryAllocateInfo.
const VmaAllocationCreateInfo& createInfo,
VmaSuballocationType suballocType,
size_t allocationCount,
@@ -10538,6 +10851,7 @@ private:
VkBuffer dedicatedBuffer,
VkImage dedicatedImage,
VmaBufferImageUsage dedicatedBufferImageUsage,
+ void* pMemoryAllocateNext, // Optional pNext chain for VkMemoryAllocateInfo.
const VmaAllocationCreateInfo& createInfo,
uint32_t memTypeIndex,
VmaSuballocationType suballocType,
@@ -10577,7 +10891,7 @@ private:
VmaBufferImageUsage dedicatedBufferImageUsage,
size_t allocationCount,
VmaAllocation* pAllocations,
- const void* pNextChain = VMA_NULL);
+ const void* pNextChain);
void FreeDedicatedMemory(VmaAllocation allocation);
@@ -10609,30 +10923,32 @@ private:
#ifndef _VMA_MEMORY_FUNCTIONS
-static void* VmaMalloc(VmaAllocator hAllocator, size_t size, size_t alignment)
+namespace
+{
+inline void* VmaMalloc(VmaAllocator hAllocator, size_t size, size_t alignment)
{
return VmaMalloc(&hAllocator->m_AllocationCallbacks, size, alignment);
}
-static void VmaFree(VmaAllocator hAllocator, void* ptr)
+inline void VmaFree(VmaAllocator hAllocator, void* ptr)
{
VmaFree(&hAllocator->m_AllocationCallbacks, ptr);
}
template
-static T* VmaAllocate(VmaAllocator hAllocator)
+T* VmaAllocate(VmaAllocator hAllocator)
{
return (T*)VmaMalloc(hAllocator, sizeof(T), VMA_ALIGN_OF(T));
}
template
-static T* VmaAllocateArray(VmaAllocator hAllocator, size_t count)
+T* VmaAllocateArray(VmaAllocator hAllocator, size_t count)
{
return (T*)VmaMalloc(hAllocator, sizeof(T) * count, VMA_ALIGN_OF(T));
}
template
-static void vma_delete(VmaAllocator hAllocator, T* ptr)
+void vma_delete(VmaAllocator hAllocator, T* ptr)
{
if(ptr != VMA_NULL)
{
@@ -10642,7 +10958,7 @@ static void vma_delete(VmaAllocator hAllocator, T* ptr)
}
template
-static void vma_delete_array(VmaAllocator hAllocator, T* ptr, size_t count)
+void vma_delete_array(VmaAllocator hAllocator, T* ptr, size_t count)
{
if(ptr != VMA_NULL)
{
@@ -10651,6 +10967,7 @@ static void vma_delete_array(VmaAllocator hAllocator, T* ptr, size_t count)
VmaFree(hAllocator, ptr);
}
}
+} // namespace
#endif // _VMA_MEMORY_FUNCTIONS
#ifndef _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS
@@ -10661,7 +10978,8 @@ VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator)
m_Id(0),
m_hMemory(VK_NULL_HANDLE),
m_MapCount(0),
- m_pMappedData(VMA_NULL){}
+ m_pMappedData(VMA_NULL),
+ m_IsMapped(false){}
VmaDeviceMemoryBlock::~VmaDeviceMemoryBlock()
{
@@ -10717,6 +11035,8 @@ void VmaDeviceMemoryBlock::Destroy(VmaAllocator allocator)
VMA_ASSERT_LEAK(m_hMemory != VK_NULL_HANDLE);
allocator->FreeVulkanMemory(m_MemoryTypeIndex, m_pMetadata->GetSize(), m_hMemory);
m_hMemory = VK_NULL_HANDLE;
+ m_pMappedData = VMA_NULL;
+ m_IsMapped.store(false);
vma_delete(allocator, m_pMetadata);
m_pMetadata = VMA_NULL;
@@ -10737,6 +11057,7 @@ void VmaDeviceMemoryBlock::PostFree(VmaAllocator hAllocator)
if (m_MapCount == 0)
{
m_pMappedData = VMA_NULL;
+ m_IsMapped.store(false);
(*hAllocator->GetVulkanFunctions().vkUnmapMemory)(hAllocator->m_hDevice, m_hMemory);
}
}
@@ -10797,6 +11118,7 @@ VkResult VmaDeviceMemoryBlock::Map(VmaAllocator hAllocator, uint32_t count, void
if (result == VK_SUCCESS)
{
VMA_ASSERT(m_pMappedData != VMA_NULL);
+ m_IsMapped.store(true);
m_MappingHysteresis.PostMap();
m_MapCount = count;
if (ppData != VMA_NULL)
@@ -10822,6 +11144,7 @@ void VmaDeviceMemoryBlock::Unmap(VmaAllocator hAllocator, uint32_t count)
if (totalMapCount == 0)
{
m_pMappedData = VMA_NULL;
+ m_IsMapped.store(false);
(*hAllocator->GetVulkanFunctions().vkUnmapMemory)(hAllocator->m_hDevice, m_hMemory);
}
m_MappingHysteresis.PostUnmap();
@@ -10904,10 +11227,10 @@ VkResult VmaDeviceMemoryBlock::BindImageMemory(
}
#if VMA_EXTERNAL_MEMORY_WIN32
-VkResult VmaDeviceMemoryBlock::CreateWin32Handle(const VmaAllocator hAllocator, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
+VkResult VmaDeviceMemoryBlock::CreateWin32Handle(const VmaAllocator hAllocator, PFN_vkGetMemoryWin32HandleKHR pvkGetMemoryWin32HandleKHR, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
{
VMA_ASSERT(pHandle);
- return m_Handle.GetHandle(hAllocator->m_hDevice, m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
+ return m_Handle.GetHandle(hAllocator->m_hDevice, m_hMemory, pvkGetMemoryWin32HandleKHR, handleType, hTargetProcess, hAllocator->m_UseMutex, pHandle);
}
#endif // VMA_EXTERNAL_MEMORY_WIN32
#endif // _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS
@@ -11225,16 +11548,16 @@ void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const
}
}
#if VMA_EXTERNAL_MEMORY_WIN32
-VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
+VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
{
auto pvkGetMemoryWin32HandleKHR = hAllocator->GetVulkanFunctions().vkGetMemoryWin32HandleKHR;
switch (m_Type)
{
case ALLOCATION_TYPE_BLOCK:
- return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, pvkGetMemoryWin32HandleKHR, hTargetProcess, pHandle);
+ return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, pvkGetMemoryWin32HandleKHR, handleType, hTargetProcess, pHandle);
case ALLOCATION_TYPE_DEDICATED:
EnsureExtraData(hAllocator);
- return m_DedicatedAllocation.m_ExtraData->m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
+ return m_DedicatedAllocation.m_ExtraData->m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, handleType, hTargetProcess, hAllocator->m_UseMutex, pHandle);
default:
VMA_ASSERT(0);
return VK_ERROR_FEATURE_NOT_PRESENT;
@@ -11348,11 +11671,13 @@ bool VmaBlockVector::IsEmpty()
bool VmaBlockVector::IsCorruptionDetectionEnabled() const
{
- const uint32_t requiredMemFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
- return (VMA_DEBUG_DETECT_CORRUPTION != 0) &&
- (VMA_DEBUG_MARGIN > 0) &&
- (m_Algorithm == 0 || m_Algorithm == VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) &&
+#if (VMA_DEBUG_DETECT_CORRUPTION == 0) || (VMA_DEBUG_MARGIN == 0)
+ return false;
+#else
+ constexpr uint32_t requiredMemFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+ return (m_Algorithm == 0 || m_Algorithm == VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) &&
(m_hAllocator->m_MemProps.memoryTypes[m_MemoryTypeIndex].propertyFlags & requiredMemFlags) == requiredMemFlags;
+#endif
}
VkResult VmaBlockVector::Allocate(
@@ -11481,7 +11806,7 @@ VkResult VmaBlockVector::AllocatePage(
{
VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex];
VMA_ASSERT(pCurrBlock);
- const bool isBlockMapped = pCurrBlock->GetMappedData() != VMA_NULL;
+ const bool isBlockMapped = pCurrBlock->IsMapped();
if((mappingI == 0) == (isMappingAllowed == isBlockMapped))
{
VkResult res = AllocateFromBlock(
@@ -11802,10 +12127,11 @@ VkResult VmaBlockVector::CommitAllocationRequest(
else
(*pAllocation)->SetUserData(m_hAllocator, pUserData);
m_hAllocator->m_Budget.AddAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), allocRequest.size);
- if (VMA_DEBUG_INITIALIZE_ALLOCATIONS)
- {
- m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);
- }
+
+#if VMA_DEBUG_INITIALIZE_ALLOCATIONS
+ m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);
+#endif
+
if (IsCorruptionDetectionEnabled())
{
VkResult res = pBlock->WriteMagicValueAfterAllocation(m_hAllocator, (*pAllocation)->GetOffset(), allocRequest.size);
@@ -11958,6 +12284,8 @@ VmaDefragmentationContext_T::VmaDefragmentationContext_T(
m_BlockVectorCount = 1;
m_PoolBlockVector = &info.pool->m_BlockVector;
m_pBlockVectors = &m_PoolBlockVector;
+
+ VmaMutexLockWrite lock(m_PoolBlockVector->m_Mutex, hAllocator->m_UseMutex);
m_PoolBlockVector->SetIncrementalSort(false);
m_PoolBlockVector->SortByFreeSize();
}
@@ -11971,6 +12299,7 @@ VmaDefragmentationContext_T::VmaDefragmentationContext_T(
VmaBlockVector* vector = m_pBlockVectors[i];
if (vector != VMA_NULL)
{
+ VmaMutexLockWrite lock(vector->m_Mutex, hAllocator->m_UseMutex);
vector->SetIncrementalSort(false);
vector->SortByFreeSize();
}
@@ -12001,6 +12330,7 @@ VmaDefragmentationContext_T::~VmaDefragmentationContext_T()
{
if (m_PoolBlockVector != VMA_NULL)
{
+ VmaMutexLockWrite lock(m_PoolBlockVector->m_Mutex, m_PoolBlockVector->m_hAllocator->m_UseMutex);
m_PoolBlockVector->SetIncrementalSort(true);
}
else
@@ -12009,7 +12339,10 @@ VmaDefragmentationContext_T::~VmaDefragmentationContext_T()
{
VmaBlockVector* vector = m_pBlockVectors[i];
if (vector != VMA_NULL)
+ {
+ VmaMutexLockWrite lock(vector->m_Mutex, vector->m_hAllocator->m_UseMutex);
vector->SetIncrementalSort(true);
+ }
}
}
@@ -12107,7 +12440,11 @@ VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMo
{
case VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY:
{
- uint8_t mapCount = move.srcAllocation->SwapBlockAllocation(vector->m_hAllocator, move.dstTmpAllocation);
+ uint8_t mapCount = 0;
+ {
+ VmaMutexLockWrite swapLock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex);
+ mapCount = move.srcAllocation->SwapBlockAllocation(vector->m_hAllocator, move.dstTmpAllocation);
+ }
if (mapCount > 0)
{
allocator = vector->m_hAllocator;
@@ -13024,7 +13361,7 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
}
#endif
}
-#if !(VMA_MEMORY_BUDGET)
+#if !(VMA_MEMORY_BUDGET) || !(VMA_GET_PHYSICAL_DEVICE_PROPERTIES2)
if((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT) != 0)
{
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT set but required extension is disabled by preprocessor macros.");
@@ -13100,8 +13437,35 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
ImportVulkanFunctions(pCreateInfo->pVulkanFunctions);
- (*m_VulkanFunctions.vkGetPhysicalDeviceProperties)(m_PhysicalDevice, &m_PhysicalDeviceProperties);
- (*m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties)(m_PhysicalDevice, &m_MemProps);
+ // Call vkGetPhysicalDeviceProperties[2][KHR].
+#if VMA_GET_PHYSICAL_DEVICE_PROPERTIES2
+ if(m_VulkanFunctions.vkGetPhysicalDeviceProperties2KHR)
+ {
+ VkPhysicalDeviceProperties2KHR props2 = {
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR };
+ (*m_VulkanFunctions.vkGetPhysicalDeviceProperties2KHR)(m_PhysicalDevice, &props2);
+ memcpy(&m_PhysicalDeviceProperties, &props2.properties, sizeof(m_PhysicalDeviceProperties));
+ }
+ else
+#endif
+ {
+ (*m_VulkanFunctions.vkGetPhysicalDeviceProperties)(m_PhysicalDevice, &m_PhysicalDeviceProperties);
+ }
+
+ // Call vkGetPhysicalDeviceMemoryProperties[2][KHR].
+#if VMA_GET_PHYSICAL_DEVICE_PROPERTIES2
+ if(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR)
+ {
+ VkPhysicalDeviceMemoryProperties2KHR memProps2 = {
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR };
+ (*m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR)(m_PhysicalDevice, &memProps2);
+ memcpy(&m_MemProps, &memProps2.memoryProperties, sizeof(m_MemProps));
+ }
+ else
+#endif
+ {
+ (*m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties)(m_PhysicalDevice, &m_MemProps);
+ }
VMA_ASSERT(VmaIsPow2(VMA_MIN_ALIGNMENT));
VMA_ASSERT(VmaIsPow2(VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY));
@@ -13244,6 +13608,7 @@ void VmaAllocator_T::ImportVulkanFunctions_Static()
if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
{
m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR = (PFN_vkGetPhysicalDeviceMemoryProperties2)vkGetPhysicalDeviceMemoryProperties2;
+ m_VulkanFunctions.vkGetPhysicalDeviceProperties2KHR = (PFN_vkGetPhysicalDeviceProperties2)vkGetPhysicalDeviceProperties2;
}
#endif
@@ -13295,8 +13660,9 @@ void VmaAllocator_T::ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVul
VMA_COPY_IF_NOT_NULL(vkBindImageMemory2KHR);
#endif
-#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000
+#if VMA_GET_PHYSICAL_DEVICE_PROPERTIES2
VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties2KHR);
+ VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceProperties2KHR);
#endif
#if VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
@@ -13355,18 +13721,22 @@ void VmaAllocator_T::ImportVulkanFunctions_Dynamic()
}
#endif
-#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000
+#if VMA_GET_PHYSICAL_DEVICE_PROPERTIES2
if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
{
VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2");
+ VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceProperties2KHR, PFN_vkGetPhysicalDeviceProperties2KHR, "vkGetPhysicalDeviceProperties2");
// Try to fetch the pointer from the other name, based on suspected driver bug - see issue #410.
VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2KHR");
+ VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceProperties2KHR, PFN_vkGetPhysicalDeviceProperties2KHR, "vkGetPhysicalDeviceProperties2KHR");
}
else if(m_UseExtMemoryBudget)
{
VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2KHR");
+ VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceProperties2KHR, PFN_vkGetPhysicalDeviceProperties2KHR, "vkGetPhysicalDeviceProperties2KHR");
// Try to fetch the pointer from the other name, based on suspected driver bug - see issue #410.
VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2");
+ VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceProperties2KHR, PFN_vkGetPhysicalDeviceProperties2KHR, "vkGetPhysicalDeviceProperties2");
}
#endif
@@ -13386,17 +13756,6 @@ void VmaAllocator_T::ImportVulkanFunctions_Dynamic()
}
#endif // #if VMA_BIND_MEMORY2
-#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000
- if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
- {
- VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2");
- }
- else if(m_UseExtMemoryBudget)
- {
- VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, PFN_vkGetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2KHR");
- }
-#endif // #if VMA_MEMORY_BUDGET
-
#if VMA_VULKAN_VERSION >= 1003000
if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0))
{
@@ -13459,12 +13818,14 @@ void VmaAllocator_T::ValidateVulkanFunctions() const
}
#endif
-#if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000
+#if VMA_GET_PHYSICAL_DEVICE_PROPERTIES2
if(m_UseExtMemoryBudget || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
{
VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR != VMA_NULL);
+ VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceProperties2KHR != VMA_NULL);
}
#endif
+
#if VMA_EXTERNAL_MEMORY_WIN32
if (m_UseKhrExternalMemoryWin32)
{
@@ -13496,6 +13857,7 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
VkBuffer dedicatedBuffer,
VkImage dedicatedImage,
VmaBufferImageUsage dedicatedBufferImageUsage,
+ void* pMemoryAllocateNext,
const VmaAllocationCreateInfo& createInfo,
uint32_t memTypeIndex,
VmaSuballocationType suballocType,
@@ -13516,6 +13878,14 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
if(res != VK_SUCCESS)
return res;
+ const void* allocateNextPtr = blockVector.GetAllocationNextPtr();
+ if(pMemoryAllocateNext != VMA_NULL)
+ {
+ VMA_ASSERT(allocateNextPtr == VMA_NULL &&
+ "You shouldn't create a dedicated allocation with a custom pMemoryAllocateNext if the pNext chain is already provided for this pool.");
+ allocateNextPtr = pMemoryAllocateNext;
+ }
+
if((finalCreateInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0)
{
return AllocateDedicatedMemory(
@@ -13536,7 +13906,7 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
dedicatedBufferImageUsage,
allocationCount,
pAllocations,
- blockVector.GetAllocationNextPtr());
+ allocateNextPtr);
}
const bool canAllocateDedicated =
@@ -13579,7 +13949,7 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
dedicatedBufferImageUsage,
allocationCount,
pAllocations,
- blockVector.GetAllocationNextPtr());
+ allocateNextPtr);
if(res == VK_SUCCESS)
{
// Succeeded: AllocateDedicatedMemory function already filled pMemory, nothing more to do here.
@@ -13620,7 +13990,7 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
dedicatedBufferImageUsage,
allocationCount,
pAllocations,
- blockVector.GetAllocationNextPtr());
+ allocateNextPtr);
if(res == VK_SUCCESS)
{
// Succeeded: AllocateDedicatedMemory function already filled pMemory, nothing more to do here.
@@ -13628,6 +13998,7 @@ VkResult VmaAllocator_T::AllocateMemoryOfType(
return VK_SUCCESS;
}
}
+
// Everything failed: Return error code.
VMA_DEBUG_LOG(" vkAllocateMemory FAILED");
return res;
@@ -13825,10 +14196,10 @@ VkResult VmaAllocator_T::AllocateDedicatedMemoryPage(
else
(*pAllocation)->SetUserData(this, pUserData);
m_Budget.AddAllocation(MemoryTypeIndexToHeapIndex(memTypeIndex), size);
- if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)
- {
- FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);
- }
+
+#if VMA_DEBUG_INITIALIZE_ALLOCATIONS
+ FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED);
+#endif
return VK_SUCCESS;
}
@@ -14027,11 +14398,12 @@ VkResult VmaAllocator_T::CalcAllocationParams(
return VK_ERROR_FEATURE_NOT_PRESENT;
}
- if(VMA_DEBUG_ALWAYS_DEDICATED_MEMORY &&
- (inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0)
+#if VMA_DEBUG_ALWAYS_DEDICATED_MEMORY
+ if((inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0)
{
inoutCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
}
+#endif
// Non-auto USAGE values imply HOST_ACCESS flags.
// And so does VMA_MEMORY_USAGE_UNKNOWN because it is used with custom pools.
@@ -14050,13 +14422,176 @@ VkResult VmaAllocator_T::CalcAllocationParams(
return VK_SUCCESS;
}
+VkResult VmaAllocator_T::CreateBuffer(
+ const VkBufferCreateInfo* pBufferCreateInfo,
+ const VmaAllocationCreateInfo* pAllocationCreateInfo,
+ void* pMemoryAllocateNext,
+ VkBuffer* pBuffer,
+ VmaAllocation* pAllocation,
+ VmaAllocationInfo* pAllocationInfo)
+{
+ *pBuffer = VK_NULL_HANDLE;
+ *pAllocation = VK_NULL_HANDLE;
+
+ if (pBufferCreateInfo->size == 0)
+ {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ if ((pBufferCreateInfo->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY) != 0 &&
+ !m_UseKhrBufferDeviceAddress)
+ {
+ VMA_ASSERT(0 && "Creating a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is not valid if VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT was not used.");
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // 1. Create VkBuffer.
+ VkResult res = (*m_VulkanFunctions.vkCreateBuffer)(m_hDevice, pBufferCreateInfo,
+ GetAllocationCallbacks(), pBuffer);
+ if (res >= 0)
+ {
+ // 2. vkGetBufferMemoryRequirements.
+ VkMemoryRequirements vkMemReq = {};
+ bool requiresDedicatedAllocation = false;
+ bool prefersDedicatedAllocation = false;
+ GetBufferMemoryRequirements(*pBuffer, vkMemReq,
+ requiresDedicatedAllocation, prefersDedicatedAllocation);
+
+ // 3. Allocate memory using allocator.
+ res = AllocateMemory(
+ vkMemReq,
+ requiresDedicatedAllocation,
+ prefersDedicatedAllocation,
+ *pBuffer, // dedicatedBuffer
+ VK_NULL_HANDLE, // dedicatedImage
+ VmaBufferImageUsage(*pBufferCreateInfo, m_UseKhrMaintenance5), // dedicatedBufferImageUsage
+ pMemoryAllocateNext,
+ *pAllocationCreateInfo,
+ VMA_SUBALLOCATION_TYPE_BUFFER,
+ 1, // allocationCount
+ pAllocation);
+ if (res >= 0)
+ {
+ // 3. Bind buffer with memory.
+ if ((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0)
+ {
+ res = BindBufferMemory(*pAllocation, 0, *pBuffer, VMA_NULL);
+ }
+ if (res >= 0)
+ {
+ // All steps succeeded.
+#if VMA_STATS_STRING_ENABLED
+ (*pAllocation)->InitBufferUsage(*pBufferCreateInfo, m_UseKhrMaintenance5);
+#endif
+ if (pAllocationInfo != VMA_NULL)
+ {
+ GetAllocationInfo(*pAllocation, pAllocationInfo);
+ }
+
+ return VK_SUCCESS;
+ }
+ FreeMemory(1, pAllocation);
+ *pAllocation = VK_NULL_HANDLE;
+ (*m_VulkanFunctions.vkDestroyBuffer)(m_hDevice, *pBuffer, GetAllocationCallbacks());
+ *pBuffer = VK_NULL_HANDLE;
+ return res;
+ }
+ (*m_VulkanFunctions.vkDestroyBuffer)(m_hDevice, *pBuffer, GetAllocationCallbacks());
+ *pBuffer = VK_NULL_HANDLE;
+ return res;
+ }
+ return res;
+}
+
+VkResult VmaAllocator_T::CreateImage(
+ const VkImageCreateInfo* pImageCreateInfo,
+ const VmaAllocationCreateInfo* pAllocationCreateInfo,
+ void* pMemoryAllocateNext,
+ VkImage* pImage,
+ VmaAllocation* pAllocation,
+ VmaAllocationInfo* pAllocationInfo)
+{
+ *pImage = VK_NULL_HANDLE;
+ *pAllocation = VK_NULL_HANDLE;
+
+ if (pImageCreateInfo->extent.width == 0 ||
+ pImageCreateInfo->extent.height == 0 ||
+ pImageCreateInfo->extent.depth == 0 ||
+ pImageCreateInfo->mipLevels == 0 ||
+ pImageCreateInfo->arrayLayers == 0)
+ {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ // 1. Create VkImage.
+ VkResult res = (*m_VulkanFunctions.vkCreateImage)(m_hDevice, pImageCreateInfo,
+ GetAllocationCallbacks(), pImage);
+ if (res == VK_SUCCESS)
+ {
+ VmaSuballocationType suballocType = pImageCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL ?
+ VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL :
+ VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR;
+
+ // 2. Allocate memory using allocator.
+ VkMemoryRequirements vkMemReq = {};
+ bool requiresDedicatedAllocation = false;
+ bool prefersDedicatedAllocation = false;
+ GetImageMemoryRequirements(*pImage, vkMemReq,
+ requiresDedicatedAllocation, prefersDedicatedAllocation);
+
+ res = AllocateMemory(
+ vkMemReq,
+ requiresDedicatedAllocation,
+ prefersDedicatedAllocation,
+ VK_NULL_HANDLE, // dedicatedBuffer
+ *pImage, // dedicatedImage
+ VmaBufferImageUsage(*pImageCreateInfo), // dedicatedBufferImageUsage
+ pMemoryAllocateNext,
+ *pAllocationCreateInfo,
+ suballocType,
+ 1, // allocationCount
+ pAllocation);
+ if (res == VK_SUCCESS)
+ {
+ // 3. Bind image with memory.
+ if ((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0)
+ {
+ res = BindImageMemory(*pAllocation, 0, *pImage, VMA_NULL);
+ }
+ if (res == VK_SUCCESS)
+ {
+ // All steps succeeded.
+#if VMA_STATS_STRING_ENABLED
+ (*pAllocation)->InitImageUsage(*pImageCreateInfo);
+#endif
+ if (pAllocationInfo != VMA_NULL)
+ {
+ GetAllocationInfo(*pAllocation, pAllocationInfo);
+ }
+
+ return VK_SUCCESS;
+ }
+ FreeMemory(1, pAllocation);
+ *pAllocation = VK_NULL_HANDLE;
+ (*m_VulkanFunctions.vkDestroyImage)(m_hDevice, *pImage, GetAllocationCallbacks());
+ *pImage = VK_NULL_HANDLE;
+ return res;
+ }
+ (*m_VulkanFunctions.vkDestroyImage)(m_hDevice, *pImage, GetAllocationCallbacks());
+ *pImage = VK_NULL_HANDLE;
+ return res;
+ }
+ return res;
+}
+
VkResult VmaAllocator_T::AllocateMemory(
- const VkMemoryRequirements& vkMemReq,
+ VkMemoryRequirements vkMemReq,
bool requiresDedicatedAllocation,
bool prefersDedicatedAllocation,
VkBuffer dedicatedBuffer,
VkImage dedicatedImage,
VmaBufferImageUsage dedicatedBufferImageUsage,
+ // pNext chain for VkMemoryAllocateInfo. When used, must specify requiresDedicatedAllocation = true.
+ void* pMemoryAllocateNext,
const VmaAllocationCreateInfo& createInfo,
VmaSuballocationType suballocType,
size_t allocationCount,
@@ -14064,8 +14599,15 @@ VkResult VmaAllocator_T::AllocateMemory(
{
memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount);
+ vkMemReq.alignment = VMA_MAX(vkMemReq.alignment, createInfo.minAlignment);
VMA_ASSERT(VmaIsPow2(vkMemReq.alignment));
+ // If using custom pNext chain for VkMemoryAllocateInfo, must require dedicated allocations.
+ if(pMemoryAllocateNext != VMA_NULL)
+ {
+ requiresDedicatedAllocation = true;
+ }
+
if(vkMemReq.size == 0)
{
return VK_ERROR_INITIALIZATION_FAILED;
@@ -14087,6 +14629,7 @@ VkResult VmaAllocator_T::AllocateMemory(
dedicatedBuffer,
dedicatedImage,
dedicatedBufferImageUsage,
+ pMemoryAllocateNext,
createInfoFinal,
blockVector.GetMemoryTypeIndex(),
suballocType,
@@ -14116,6 +14659,7 @@ VkResult VmaAllocator_T::AllocateMemory(
dedicatedBuffer,
dedicatedImage,
dedicatedBufferImageUsage,
+ pMemoryAllocateNext,
createInfoFinal,
memTypeIndex,
suballocType,
@@ -14150,10 +14694,9 @@ void VmaAllocator_T::FreeMemory(
if(allocation != VK_NULL_HANDLE)
{
- if(VMA_DEBUG_INITIALIZE_ALLOCATIONS)
- {
- FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);
- }
+#if VMA_DEBUG_INITIALIZE_ALLOCATIONS
+ FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED);
+#endif
switch(allocation->GetType())
{
@@ -14997,8 +15540,8 @@ void VmaAllocator_T::UpdateVulkanBudget()
void VmaAllocator_T::FillAllocation(VmaAllocation hAllocation, uint8_t pattern)
{
- if(VMA_DEBUG_INITIALIZE_ALLOCATIONS &&
- hAllocation->IsMappingAllowed() &&
+#if VMA_DEBUG_INITIALIZE_ALLOCATIONS
+ if(hAllocation->IsMappingAllowed() &&
(m_MemProps.memoryTypes[hAllocation->GetMemoryTypeIndex()].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0)
{
void* pData = VMA_NULL;
@@ -15014,6 +15557,7 @@ void VmaAllocator_T::FillAllocation(VmaAllocation hAllocation, uint8_t pattern)
VMA_ASSERT(0 && "VMA_DEBUG_INITIALIZE_ALLOCATIONS is enabled, but couldn't map memory to fill allocation.");
}
}
+#endif // #if VMA_DEBUG_INITIALIZE_ALLOCATIONS
}
uint32_t VmaAllocator_T::GetGpuDefragmentationMemoryTypeBits()
@@ -15162,6 +15706,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaImportVulkanFunctionsFromVolk(
if (pAllocatorCreateInfo->vulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0))
{
COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceMemoryProperties2, vkGetPhysicalDeviceMemoryProperties2KHR)
+ COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceProperties2, vkGetPhysicalDeviceProperties2KHR)
COPY_DEVICE_TO_VMA_FUNC(vkGetBufferMemoryRequirements2, vkGetBufferMemoryRequirements2KHR)
COPY_DEVICE_TO_VMA_FUNC(vkGetImageMemoryRequirements2, vkGetImageMemoryRequirements2KHR)
COPY_DEVICE_TO_VMA_FUNC(vkBindBufferMemory2, vkBindBufferMemory2KHR)
@@ -15200,6 +15745,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaImportVulkanFunctionsFromVolk(
if ((pAllocatorCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_BUDGET_BIT) != 0)
{
COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceMemoryProperties2KHR, vkGetPhysicalDeviceMemoryProperties2KHR)
+ COPY_GLOBAL_TO_VMA_FUNC(vkGetPhysicalDeviceProperties2KHR, vkGetPhysicalDeviceProperties2KHR)
}
#endif
#if VMA_EXTERNAL_MEMORY_WIN32
@@ -15543,7 +16089,8 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo(
VkResult res = VK_SUCCESS;
#if VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
- if(funcs->vkGetDeviceBufferMemoryRequirements)
+ if (funcs->vkGetDeviceBufferMemoryRequirements &&
+ (allocator->m_UseKhrMaintenance4 || allocator->m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0)))
{
// Can query straight from VkBufferCreateInfo :)
VkDeviceBufferMemoryRequirementsKHR devBufMemReq = {VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR};
@@ -15552,29 +16099,27 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo(
VkMemoryRequirements2 memReq = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2};
(*funcs->vkGetDeviceBufferMemoryRequirements)(hDev, &devBufMemReq, &memReq);
- res = allocator->FindMemoryTypeIndex(
+ return allocator->FindMemoryTypeIndex(
memReq.memoryRequirements.memoryTypeBits, pAllocationCreateInfo,
VmaBufferImageUsage(*pBufferCreateInfo, allocator->m_UseKhrMaintenance5), pMemoryTypeIndex);
}
- else
#endif // VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
+
+ // Must create a dummy buffer to query :(
+ VkBuffer hBuffer = VK_NULL_HANDLE;
+ res = funcs->vkCreateBuffer(
+ hDev, pBufferCreateInfo, allocator->GetAllocationCallbacks(), &hBuffer);
+ if(res == VK_SUCCESS)
{
- // Must create a dummy buffer to query :(
- VkBuffer hBuffer = VK_NULL_HANDLE;
- res = funcs->vkCreateBuffer(
- hDev, pBufferCreateInfo, allocator->GetAllocationCallbacks(), &hBuffer);
- if(res == VK_SUCCESS)
- {
- VkMemoryRequirements memReq = {};
- funcs->vkGetBufferMemoryRequirements(hDev, hBuffer, &memReq);
+ VkMemoryRequirements memReq = {};
+ funcs->vkGetBufferMemoryRequirements(hDev, hBuffer, &memReq);
- res = allocator->FindMemoryTypeIndex(
- memReq.memoryTypeBits, pAllocationCreateInfo,
- VmaBufferImageUsage(*pBufferCreateInfo, allocator->m_UseKhrMaintenance5), pMemoryTypeIndex);
+ res = allocator->FindMemoryTypeIndex(
+ memReq.memoryTypeBits, pAllocationCreateInfo,
+ VmaBufferImageUsage(*pBufferCreateInfo, allocator->m_UseKhrMaintenance5), pMemoryTypeIndex);
- funcs->vkDestroyBuffer(
- hDev, hBuffer, allocator->GetAllocationCallbacks());
- }
+ funcs->vkDestroyBuffer(
+ hDev, hBuffer, allocator->GetAllocationCallbacks());
}
return res;
}
@@ -15595,7 +16140,8 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo(
VkResult res = VK_SUCCESS;
#if VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
- if(funcs->vkGetDeviceImageMemoryRequirements)
+ if(funcs->vkGetDeviceImageMemoryRequirements &&
+ (allocator->m_UseKhrMaintenance4 || allocator->m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0)))
{
// Can query straight from VkImageCreateInfo :)
VkDeviceImageMemoryRequirementsKHR devImgMemReq = {VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR};
@@ -15606,29 +16152,27 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo(
VkMemoryRequirements2 memReq = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2};
(*funcs->vkGetDeviceImageMemoryRequirements)(hDev, &devImgMemReq, &memReq);
- res = allocator->FindMemoryTypeIndex(
+ return allocator->FindMemoryTypeIndex(
memReq.memoryRequirements.memoryTypeBits, pAllocationCreateInfo,
VmaBufferImageUsage(*pImageCreateInfo), pMemoryTypeIndex);
}
- else
#endif // VMA_KHR_MAINTENANCE4 || VMA_VULKAN_VERSION >= 1003000
+
+ // Must create a dummy image to query :(
+ VkImage hImage = VK_NULL_HANDLE;
+ res = funcs->vkCreateImage(
+ hDev, pImageCreateInfo, allocator->GetAllocationCallbacks(), &hImage);
+ if(res == VK_SUCCESS)
{
- // Must create a dummy image to query :(
- VkImage hImage = VK_NULL_HANDLE;
- res = funcs->vkCreateImage(
- hDev, pImageCreateInfo, allocator->GetAllocationCallbacks(), &hImage);
- if(res == VK_SUCCESS)
- {
- VkMemoryRequirements memReq = {};
- funcs->vkGetImageMemoryRequirements(hDev, hImage, &memReq);
+ VkMemoryRequirements memReq = {};
+ funcs->vkGetImageMemoryRequirements(hDev, hImage, &memReq);
- res = allocator->FindMemoryTypeIndex(
- memReq.memoryTypeBits, pAllocationCreateInfo,
- VmaBufferImageUsage(*pImageCreateInfo), pMemoryTypeIndex);
+ res = allocator->FindMemoryTypeIndex(
+ memReq.memoryTypeBits, pAllocationCreateInfo,
+ VmaBufferImageUsage(*pImageCreateInfo), pMemoryTypeIndex);
- funcs->vkDestroyImage(
- hDev, hImage, allocator->GetAllocationCallbacks());
- }
+ funcs->vkDestroyImage(
+ hDev, hImage, allocator->GetAllocationCallbacks());
}
return res;
}
@@ -15748,6 +16292,42 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory(
VK_NULL_HANDLE, // dedicatedBuffer
VK_NULL_HANDLE, // dedicatedImage
VmaBufferImageUsage::UNKNOWN, // dedicatedBufferImageUsage
+ VMA_NULL, // pMemoryAllocateNext
+ *pCreateInfo,
+ VMA_SUBALLOCATION_TYPE_UNKNOWN,
+ 1, // allocationCount
+ pAllocation);
+
+ if(pAllocationInfo != VMA_NULL && result == VK_SUCCESS)
+ {
+ allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);
+ }
+
+ return result;
+}
+
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateDedicatedMemory(
+ VmaAllocator allocator,
+ const VkMemoryRequirements* pVkMemoryRequirements,
+ const VmaAllocationCreateInfo* pCreateInfo,
+ void* pMemoryAllocateNext,
+ VmaAllocation* pAllocation,
+ VmaAllocationInfo* pAllocationInfo)
+{
+ VMA_ASSERT(allocator && pVkMemoryRequirements && pCreateInfo && pAllocation);
+
+ VMA_DEBUG_LOG("vmaAllocateDedicatedMemory");
+
+ VMA_DEBUG_GLOBAL_MUTEX_LOCK
+
+ VkResult result = allocator->AllocateMemory(
+ *pVkMemoryRequirements,
+ true, // requiresDedicatedAllocation
+ false, // prefersDedicatedAllocation
+ VK_NULL_HANDLE, // dedicatedBuffer
+ VK_NULL_HANDLE, // dedicatedImage
+ VmaBufferImageUsage::UNKNOWN, // dedicatedBufferImageUsage
+ pMemoryAllocateNext,
*pCreateInfo,
VMA_SUBALLOCATION_TYPE_UNKNOWN,
1, // allocationCount
@@ -15787,6 +16367,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryPages(
VK_NULL_HANDLE, // dedicatedBuffer
VK_NULL_HANDLE, // dedicatedImage
VmaBufferImageUsage::UNKNOWN, // dedicatedBufferImageUsage
+ VMA_NULL, // pMemoryAllocateNext
*pCreateInfo,
VMA_SUBALLOCATION_TYPE_UNKNOWN,
allocationCount,
@@ -15830,6 +16411,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForBuffer(
buffer, // dedicatedBuffer
VK_NULL_HANDLE, // dedicatedImage
VmaBufferImageUsage::UNKNOWN, // dedicatedBufferImageUsage
+ VMA_NULL, // pMemoryAllocateNext
*pCreateInfo,
VMA_SUBALLOCATION_TYPE_BUFFER,
1, // allocationCount
@@ -15869,6 +16451,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForImage(
VK_NULL_HANDLE, // dedicatedBuffer
image, // dedicatedImage
VmaBufferImageUsage::UNKNOWN, // dedicatedBufferImageUsage
+ VMA_NULL, // pMemoryAllocateNext
*pCreateInfo,
VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN,
1, // allocationCount
@@ -16264,86 +16847,13 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBuffer(
VmaAllocationInfo* pAllocationInfo)
{
VMA_ASSERT(allocator && pBufferCreateInfo && pAllocationCreateInfo && pBuffer && pAllocation);
-
- if(pBufferCreateInfo->size == 0)
- {
- return VK_ERROR_INITIALIZATION_FAILED;
- }
- if((pBufferCreateInfo->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY) != 0 &&
- !allocator->m_UseKhrBufferDeviceAddress)
- {
- VMA_ASSERT(0 && "Creating a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is not valid if VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT was not used.");
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-
VMA_DEBUG_LOG("vmaCreateBuffer");
+ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
- VMA_DEBUG_GLOBAL_MUTEX_LOCK
+ return allocator->CreateBuffer(pBufferCreateInfo, pAllocationCreateInfo,
+ VMA_NULL, // pMemoryAllocateNext
+ pBuffer, pAllocation, pAllocationInfo);
- *pBuffer = VK_NULL_HANDLE;
- *pAllocation = VK_NULL_HANDLE;
-
- // 1. Create VkBuffer.
- VkResult res = (*allocator->GetVulkanFunctions().vkCreateBuffer)(
- allocator->m_hDevice,
- pBufferCreateInfo,
- allocator->GetAllocationCallbacks(),
- pBuffer);
- if(res >= 0)
- {
- // 2. vkGetBufferMemoryRequirements.
- VkMemoryRequirements vkMemReq = {};
- bool requiresDedicatedAllocation = false;
- bool prefersDedicatedAllocation = false;
- allocator->GetBufferMemoryRequirements(*pBuffer, vkMemReq,
- requiresDedicatedAllocation, prefersDedicatedAllocation);
-
- // 3. Allocate memory using allocator.
- res = allocator->AllocateMemory(
- vkMemReq,
- requiresDedicatedAllocation,
- prefersDedicatedAllocation,
- *pBuffer, // dedicatedBuffer
- VK_NULL_HANDLE, // dedicatedImage
- VmaBufferImageUsage(*pBufferCreateInfo, allocator->m_UseKhrMaintenance5), // dedicatedBufferImageUsage
- *pAllocationCreateInfo,
- VMA_SUBALLOCATION_TYPE_BUFFER,
- 1, // allocationCount
- pAllocation);
-
- if(res >= 0)
- {
- // 3. Bind buffer with memory.
- if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0)
- {
- res = allocator->BindBufferMemory(*pAllocation, 0, *pBuffer, VMA_NULL);
- }
- if(res >= 0)
- {
- // All steps succeeded.
- #if VMA_STATS_STRING_ENABLED
- (*pAllocation)->InitBufferUsage(*pBufferCreateInfo, allocator->m_UseKhrMaintenance5);
- #endif
- if(pAllocationInfo != VMA_NULL)
- {
- allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);
- }
-
- return VK_SUCCESS;
- }
- allocator->FreeMemory(
- 1, // allocationCount
- pAllocation);
- *pAllocation = VK_NULL_HANDLE;
- (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
- *pBuffer = VK_NULL_HANDLE;
- return res;
- }
- (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
- *pBuffer = VK_NULL_HANDLE;
- return res;
- }
- return res;
}
VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment(
@@ -16356,89 +16866,36 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment(
VmaAllocationInfo* pAllocationInfo)
{
VMA_ASSERT(allocator && pBufferCreateInfo && pAllocationCreateInfo && VmaIsPow2(minAlignment) && pBuffer && pAllocation);
-
- if(pBufferCreateInfo->size == 0)
- {
- return VK_ERROR_INITIALIZATION_FAILED;
- }
- if((pBufferCreateInfo->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY) != 0 &&
- !allocator->m_UseKhrBufferDeviceAddress)
- {
- VMA_ASSERT(0 && "Creating a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is not valid if VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT was not used.");
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-
VMA_DEBUG_LOG("vmaCreateBufferWithAlignment");
+ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
- VMA_DEBUG_GLOBAL_MUTEX_LOCK
+ VmaAllocationCreateInfo allocCreateInfoCopy = *pAllocationCreateInfo;
+ allocCreateInfoCopy.minAlignment = VMA_MAX(allocCreateInfoCopy.minAlignment, minAlignment);
- *pBuffer = VK_NULL_HANDLE;
- *pAllocation = VK_NULL_HANDLE;
+ return allocator->CreateBuffer(pBufferCreateInfo, &allocCreateInfoCopy,
+ VMA_NULL, // pMemoryAllocateNext
+ pBuffer, pAllocation, pAllocationInfo);
+}
- // 1. Create VkBuffer.
- VkResult res = (*allocator->GetVulkanFunctions().vkCreateBuffer)(
- allocator->m_hDevice,
- pBufferCreateInfo,
- allocator->GetAllocationCallbacks(),
- pBuffer);
- if(res >= 0)
- {
- // 2. vkGetBufferMemoryRequirements.
- VkMemoryRequirements vkMemReq = {};
- bool requiresDedicatedAllocation = false;
- bool prefersDedicatedAllocation = false;
- allocator->GetBufferMemoryRequirements(*pBuffer, vkMemReq,
- requiresDedicatedAllocation, prefersDedicatedAllocation);
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateDedicatedBuffer(
+ VmaAllocator allocator,
+ const VkBufferCreateInfo* pBufferCreateInfo,
+ const VmaAllocationCreateInfo* pAllocationCreateInfo,
+ void* pMemoryAllocateNext,
+ VkBuffer* pBuffer,
+ VmaAllocation* pAllocation,
+ VmaAllocationInfo* pAllocationInfo)
+{
+ VMA_ASSERT(allocator && pBufferCreateInfo && pAllocationCreateInfo && pBuffer && pAllocation);
+ VMA_DEBUG_LOG("vmaCreateDedicatedBuffer");
+ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
- // 2a. Include minAlignment
- vkMemReq.alignment = VMA_MAX(vkMemReq.alignment, minAlignment);
+ VmaAllocationCreateInfo allocCreateInfoCopy = *pAllocationCreateInfo;
+ allocCreateInfoCopy.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
- // 3. Allocate memory using allocator.
- res = allocator->AllocateMemory(
- vkMemReq,
- requiresDedicatedAllocation,
- prefersDedicatedAllocation,
- *pBuffer, // dedicatedBuffer
- VK_NULL_HANDLE, // dedicatedImage
- VmaBufferImageUsage(*pBufferCreateInfo, allocator->m_UseKhrMaintenance5), // dedicatedBufferImageUsage
- *pAllocationCreateInfo,
- VMA_SUBALLOCATION_TYPE_BUFFER,
- 1, // allocationCount
- pAllocation);
-
- if(res >= 0)
- {
- // 3. Bind buffer with memory.
- if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0)
- {
- res = allocator->BindBufferMemory(*pAllocation, 0, *pBuffer, VMA_NULL);
- }
- if(res >= 0)
- {
- // All steps succeeded.
- #if VMA_STATS_STRING_ENABLED
- (*pAllocation)->InitBufferUsage(*pBufferCreateInfo, allocator->m_UseKhrMaintenance5);
- #endif
- if(pAllocationInfo != VMA_NULL)
- {
- allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);
- }
-
- return VK_SUCCESS;
- }
- allocator->FreeMemory(
- 1, // allocationCount
- pAllocation);
- *pAllocation = VK_NULL_HANDLE;
- (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
- *pBuffer = VK_NULL_HANDLE;
- return res;
- }
- (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks());
- *pBuffer = VK_NULL_HANDLE;
- return res;
- }
- return res;
+ return allocator->CreateBuffer(pBufferCreateInfo, &allocCreateInfoCopy,
+ pMemoryAllocateNext, // pMemoryAllocateNext
+ pBuffer, pAllocation, pAllocationInfo);
}
VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAliasingBuffer(
@@ -16534,90 +16991,37 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage(
VmaAllocationInfo* pAllocationInfo)
{
VMA_ASSERT(allocator && pImageCreateInfo && pAllocationCreateInfo && pImage && pAllocation);
-
VMA_ASSERT((pImageCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT_COPY) == 0 &&
"vmaCreateImage() doesn't support disjoint multi-planar images. Please allocate memory for the planes using vmaAllocateMemory() and bind them using vmaBindImageMemory2().");
-
- if(pImageCreateInfo->extent.width == 0 ||
- pImageCreateInfo->extent.height == 0 ||
- pImageCreateInfo->extent.depth == 0 ||
- pImageCreateInfo->mipLevels == 0 ||
- pImageCreateInfo->arrayLayers == 0)
- {
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-
VMA_DEBUG_LOG("vmaCreateImage");
+ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
- VMA_DEBUG_GLOBAL_MUTEX_LOCK
+ return allocator->CreateImage(pImageCreateInfo, pAllocationCreateInfo,
+ VMA_NULL, // pMemoryAllocateNext
+ pImage, pAllocation, pAllocationInfo);
+}
- *pImage = VK_NULL_HANDLE;
- *pAllocation = VK_NULL_HANDLE;
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateDedicatedImage(
+ VmaAllocator allocator,
+ const VkImageCreateInfo* pImageCreateInfo,
+ const VmaAllocationCreateInfo* pAllocationCreateInfo,
+ void* pMemoryAllocateNext,
+ VkImage* pImage,
+ VmaAllocation* pAllocation,
+ VmaAllocationInfo* pAllocationInfo)
+{
+ VMA_ASSERT(allocator && pImageCreateInfo && pAllocationCreateInfo && pImage && pAllocation);
+ VMA_ASSERT((pImageCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT_COPY) == 0 &&
+ "vmaCreateDedicatedImage() doesn't support disjoint multi-planar images. Please allocate memory for the planes using vmaAllocateMemory() and bind them using vmaBindImageMemory2().");
+ VMA_DEBUG_LOG("vmaCreateDedicatedImage");
+ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
- // 1. Create VkImage.
- VkResult res = (*allocator->GetVulkanFunctions().vkCreateImage)(
- allocator->m_hDevice,
- pImageCreateInfo,
- allocator->GetAllocationCallbacks(),
- pImage);
- if(res == VK_SUCCESS)
- {
- VmaSuballocationType suballocType = pImageCreateInfo->tiling == VK_IMAGE_TILING_OPTIMAL ?
- VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL :
- VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR;
+ VmaAllocationCreateInfo allocCreateInfoCopy = *pAllocationCreateInfo;
+ allocCreateInfoCopy.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;
- // 2. Allocate memory using allocator.
- VkMemoryRequirements vkMemReq = {};
- bool requiresDedicatedAllocation = false;
- bool prefersDedicatedAllocation = false;
- allocator->GetImageMemoryRequirements(*pImage, vkMemReq,
- requiresDedicatedAllocation, prefersDedicatedAllocation);
-
- res = allocator->AllocateMemory(
- vkMemReq,
- requiresDedicatedAllocation,
- prefersDedicatedAllocation,
- VK_NULL_HANDLE, // dedicatedBuffer
- *pImage, // dedicatedImage
- VmaBufferImageUsage(*pImageCreateInfo), // dedicatedBufferImageUsage
- *pAllocationCreateInfo,
- suballocType,
- 1, // allocationCount
- pAllocation);
-
- if(res == VK_SUCCESS)
- {
- // 3. Bind image with memory.
- if((pAllocationCreateInfo->flags & VMA_ALLOCATION_CREATE_DONT_BIND_BIT) == 0)
- {
- res = allocator->BindImageMemory(*pAllocation, 0, *pImage, VMA_NULL);
- }
- if(res == VK_SUCCESS)
- {
- // All steps succeeded.
- #if VMA_STATS_STRING_ENABLED
- (*pAllocation)->InitImageUsage(*pImageCreateInfo);
- #endif
- if(pAllocationInfo != VMA_NULL)
- {
- allocator->GetAllocationInfo(*pAllocation, pAllocationInfo);
- }
-
- return VK_SUCCESS;
- }
- allocator->FreeMemory(
- 1, // allocationCount
- pAllocation);
- *pAllocation = VK_NULL_HANDLE;
- (*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, *pImage, allocator->GetAllocationCallbacks());
- *pImage = VK_NULL_HANDLE;
- return res;
- }
- (*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, *pImage, allocator->GetAllocationCallbacks());
- *pImage = VK_NULL_HANDLE;
- return res;
- }
- return res;
+ return allocator->CreateImage(pImageCreateInfo, &allocCreateInfoCopy,
+ pMemoryAllocateNext, // pMemoryAllocateNext
+ pImage, pAllocation, pAllocationInfo);
}
VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAliasingImage(
@@ -16837,7 +17241,20 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle(VmaAllocator VMA_NOT
{
VMA_ASSERT(allocator && allocation && pHandle);
VMA_DEBUG_GLOBAL_MUTEX_LOCK;
- return allocation->GetWin32Handle(allocator, hTargetProcess, pHandle);
+ return allocation->GetWin32Handle(allocator, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, hTargetProcess, pHandle);
+}
+VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle2(VmaAllocator VMA_NOT_NULL allocator,
+ VmaAllocation VMA_NOT_NULL allocation, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle)
+{
+ VMA_ASSERT(allocator && allocation && pHandle);
+ VMA_ASSERT(handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR ||
+ handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR ||
+ handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR ||
+ handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR ||
+ handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR ||
+ handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR);
+ VMA_DEBUG_GLOBAL_MUTEX_LOCK;
+ return allocation->GetWin32Handle(allocator, handleType, hTargetProcess, pHandle);
}
#endif // VMA_EXTERNAL_MEMORY_WIN32
#endif // VMA_STATS_STRING_ENABLED
@@ -16845,7 +17262,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32Handle(VmaAllocator VMA_NOT
#endif // VMA_IMPLEMENTATION
/**
-\page faq Frequenty asked questions
+\page faq Frequently asked questions
What is VMA?
@@ -17006,7 +17423,6 @@ Among many extensions available for Vulkan, only a few interact with memory mana
VMA can automatically take advantage of them. Some of them are:
VK_EXT_memory_budget, VK_EXT_memory_priority, VK_KHR_external_memory_win32, and VK_KHR_maintenance*
extensions that are later promoted to the new versions of the core Vulkan API.
-
To use them, it is your responsibility to validate if they are available on the current system and if so,
enable them while creating the Vulkan device object.
You also need to pass appropriate #VmaAllocatorCreateFlagBits to inform VMA that they are enabled.
@@ -17057,8 +17473,8 @@ You can access it in multiple ways:
Is it a mature project?
-Yes! The library is in development since June 2017, has over 1000 commits, over 400 issue tickets
-and pull requests (most of them resolved), and over 70 contributors.
+Yes! The library is in development since June 2017, has over 1000 commits, over 500 issue tickets
+and pull requests (most of them resolved), and over 80 contributors.
It is distributed together with Vulkan SDK.
It is used by many software projects, including some large and popular ones like Qt or Blender,
as well as some AAA games.
@@ -18008,7 +18424,7 @@ Many of the common concerns can be addressed in a different way than using custo
- If you want to select specific memory type for your allocation,
you can set VmaAllocationCreateInfo::memoryTypeBits to `(1U << myMemoryTypeIndex)` instead.
- If you need to create a buffer with certain minimum alignment, you can still do it
- using default pools with dedicated function vmaCreateBufferWithAlignment().
+ using default pools by specifying VmaAllocationCreateInfo::minAlignment.
\section linear_algorithm Linear allocation algorithm
@@ -18636,31 +19052,163 @@ individual names to allocations using vmaSetAllocationName(), can greatly aid in
\page other_api_interop Interop with other graphics APIs
-VMA provides some features that help with interoperability with other graphics APIs, e.g. OpenGL.
+VMA provides some features that help with interoperability with other graphics APIs, e.g. OpenGL, Direct3D 11, Direct3D 12.
-\section opengl_interop_exporting_memory Exporting memory
+\section other_api_interop_exporting_memory Exporting memory
-If you want to attach `VkExportMemoryAllocateInfoKHR` or other structure to `pNext` chain of memory allocations made by the library:
+On Windows, the VK_KHR_external_memory_win32 device extension allows exporting a Win32 `HANDLE`
+of a `VkDeviceMemory` block, to be able to reference the memory on other Vulkan logical devices or instances,
+in multiple processes, and/or in multiple APIs.
+VMA offers support for it.
-You can create \ref custom_memory_pools for such allocations.
-Define and fill in your `VkExportMemoryAllocateInfoKHR` structure and attach it to VmaPoolCreateInfo::pMemoryAllocateNext
-while creating the custom pool.
-Please note that the structure must remain alive and unchanged for the whole lifetime of the #VmaPool,
-not only while creating it, as no copy of the structure is made,
-but its original pointer is used for each allocation instead.
+\subsection other_api_interop_exporting_initialization Initialization
+
+1) Make sure the extension is defined in the code by including following header before including VMA:
+
+\code
+#include
+\endcode
+
+2) Check if "VK_KHR_external_memory_win32" is available among device extensions.
+Enable it when creating the `VkDevice` object.
+
+3) Enable the usage of this extension in VMA by setting flag #VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT
+when calling vmaCreateAllocator().
+
+4) Make sure that VMA has access to the `vkGetMemoryWin32HandleKHR` function by either enabling `VMA_DYNAMIC_VULKAN_FUNCTIONS` macro
+or setting VmaVulkanFunctions::vkGetMemoryWin32HandleKHR explicitly.
+For more information, see \ref quick_start_initialization_importing_vulkan_functions.
+
+\subsection other_api_interop_exporting_preparations Preparations
+
+You can find example usage among tests, in file "Tests.cpp", function `TestWin32Handles()`.
+
+To use the extenion, buffers need to be created with `VkExternalMemoryBufferCreateInfoKHR` attached to their `pNext` chain,
+and memory allocations need to be made with `VkExportMemoryAllocateInfoKHR` attached to their `pNext` chain.
+To make use of them, you need to use \ref custom_memory_pools. Example:
+
+\code
+constexpr VkExternalMemoryHandleTypeFlagsKHR handleType =
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR;
+
+// Define an example buffer and allocation parameters.
+VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
+ nullptr,
+ handleType
+};
+VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
+exampleBufCreateInfo.size = 0x10000; // Doesn't matter here.
+exampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+exampleBufCreateInfo.pNext = &externalMemBufCreateInfo;
+
+VmaAllocationCreateInfo exampleAllocCreateInfo = {};
+exampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
+
+// Find memory type index to use for the custom pool.
+uint32_t memTypeIndex;
+VkResult res = vmaFindMemoryTypeIndexForBufferInfo(g_Allocator,
+ &exampleBufCreateInfo, &exampleAllocCreateInfo, &memTypeIndex);
+// Check res...
+
+// Create a custom pool.
+constexpr static VkExportMemoryAllocateInfoKHR exportMemAllocInfo = {
+ VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
+ nullptr,
+ handleType
+};
+VmaPoolCreateInfo poolCreateInfo = {};
+poolCreateInfo.memoryTypeIndex = memTypeIndex;
+poolCreateInfo.pMemoryAllocateNext = (void*)&exportMemAllocInfo;
+
+VmaPool pool;
+res = vmaCreatePool(g_Allocator, &poolCreateInfo, &pool);
+// Check res...
+
+// YOUR OTHER CODE COMES HERE....
+
+// At the end, don't forget to destroy it!
+vmaDestroyPool(g_Allocator, pool);
+\endcode
+
+Note that the structure passed as VmaPoolCreateInfo::pMemoryAllocateNext must remain alive and unchanged
+for the whole lifetime of the custom pool, because it will be used when the pool allocates a new device memory block.
+No copy is made internally. This is why variable `exportMemAllocInfo` is defined as static.
If you want to export all memory allocated by VMA from certain memory types,
-also dedicated allocations or other allocations made from default pools,
+including dedicated allocations and allocations made from default pools,
an alternative solution is to fill in VmaAllocatorCreateInfo::pTypeExternalMemoryHandleTypes.
It should point to an array with `VkExternalMemoryHandleTypeFlagsKHR` to be automatically passed by the library
through `VkExportMemoryAllocateInfoKHR` on each allocation made from a specific memory type.
-Please note that new versions of the library also support dedicated allocations created in custom pools.
-
You should not mix these two methods in a way that allows to apply both to the same memory type.
Otherwise, `VkExportMemoryAllocateInfoKHR` structure would be attached twice to the `pNext` chain of `VkMemoryAllocateInfo`.
+\subsection other_api_interop_exporting_memory_allocation Memory allocation
-\section opengl_interop_custom_alignment Custom alignment
+Finally, you can create a buffer with an allocation out of the custom pool.
+The buffer should use same flags as the sample buffer used to find the memory type.
+It should also specify `VkExternalMemoryBufferCreateInfoKHR` in its `pNext` chain.
+
+\code
+VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
+ nullptr,
+ handleType
+};
+VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
+bufCreateInfo.size = // Your desired buffer size.
+bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+bufCreateInfo.pNext = &externalMemBufCreateInfo;
+
+VmaAllocationCreateInfo allocCreateInfo = {};
+allocCreateInfo.pool = pool; // It is enough to set this one member.
+
+VkBuffer buf;
+VmaAllocation alloc;
+res = vmaCreateBuffer(g_Allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, nullptr);
+// Check res...
+
+// YOUR OTHER CODE COMES HERE....
+
+// At the end, don't forget to destroy it!
+vmaDestroyBuffer(g_Allocator, buf, alloc);
+\endcode
+
+If you need each allocation to have its own device memory block and start at offset 0, you can still do
+by using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag. It works also with custom pools.
+
+Alternatively, you can use convenient functions vmaCreateDedicatedBuffer(), vmaCreateDedicatedImage() that
+always allocate dedicated memory for the buffer/image created, and also allow specifying custom `pNext` chain
+for the `VkMemoryAllocateInfo` structure.
+
+\subsection other_api_interop_exporting_exporting_win32_handle Exporting Win32 handle
+
+After the allocation is created, you can acquire a Win32 `HANDLE` to the `VkDeviceMemory` block it belongs to.
+VMA function vmaGetMemoryWin32Handle2() is a replacement of the Vulkan function `vkGetMemoryWin32HandleKHR`.
+
+\code
+HANDLE handle;
+res = vmaGetMemoryWin32Handle2(g_Allocator, alloc, handleType, nullptr, &handle);
+// Check res...
+
+// YOUR OTHER CODE COMES HERE....
+
+// At the end, you must close the handle.
+CloseHandle(handle);
+\endcode
+
+Documentation of the VK_KHR_external_memory_win32 extension states that:
+
+> If handleType is defined as an NT handle, vkGetMemoryWin32HandleKHR must be called no more than once for each valid unique combination of memory and handleType.
+
+This is ensured automatically inside VMA.
+If `VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT` is used as the handle type,
+or other NT handle types,
+the library fetches the handle on first use, remembers it internally, and closes it when the memory block or dedicated allocation is destroyed.
+Every time you call vmaGetMemoryWin32Handle2(), VMA calls `DuplicateHandle` and returns a new handle that you need to close.
+For further information, please check the documentation of this function.
+
+\subsection other_api_interop_exporting_custom_alignment Custom alignment
Buffers or images exported to a different API like OpenGL may require a different alignment,
higher than the one used by the library automatically, queried from functions like `vkGetBufferMemoryRequirements`.
@@ -18672,20 +19220,59 @@ to be made out of this pool.
The alignment actually used will be the maximum of this member and the alignment returned for the specific buffer or image
from a function like `vkGetBufferMemoryRequirements`, which is called by VMA automatically.
-If you want to create a buffer with a specific minimum alignment out of default pools,
-use special function vmaCreateBufferWithAlignment(), which takes additional parameter `minAlignment`.
+If you want to create a buffer/image/allocate memory with a specific minimum alignment out of default pools,
+you can use VmaAllocationCreateInfo::minAlignment.
Note the problem of alignment affects only resources placed inside bigger `VkDeviceMemory` blocks and not dedicated
allocations, as these, by definition, always have alignment = 0 because the resource is bound to the beginning of its dedicated block.
You can ensure that an allocation is created as dedicated by using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT.
Contrary to Direct3D 12, Vulkan doesn't have a concept of alignment of the entire memory block passed on its allocation.
-\section opengl_interop_extended_allocation_information Extended allocation information
+\subsection other_api_interop_exporting_extended_allocation_information Extended allocation information
If you want to rely on VMA to allocate your buffers and images inside larger memory blocks,
but you need to know the size of the entire block and whether the allocation was made
with its own dedicated memory, use function vmaGetAllocationInfo2() to retrieve
-extended allocation information in structure #VmaAllocationInfo2.
+extended allocation information in structure #VmaAllocationInfo2, which provides extra members:
+`blockSize` and `dedicatedMemory`.
+
+\section other_api_interop_importing_memory Importing memory
+
+Importing external memory requires attaching an extra structure like `VkImportMemoryWin32HandleInfoKHR`
+to the `pNext` chain of `VkMemoryAllocateInfo` structure.
+VMA offers support for it by providing functions that allocate memory, create a buffer or an image
+always with a dedicated `VkDeviceMemory` block and accept custom `pNext` pointer:
+vmaAllocateDedicatedMemory(), vmaCreateDedicatedBuffer(), vmaCreateDedicatedImage().
+Example:
+
+\code
+constexpr VkExternalMemoryHandleTypeFlagBits handleType =
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT;
+
+VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {
+ VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR };
+externalMemBufCreateInfo.handleTypes = handleType;
+
+VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
+bufCreateInfo.pNext = &externalMemBufCreateInfo; // !!!
+bufCreateInfo.size = ...
+bufCreateInfo.usage = ...
+
+VkImportMemoryWin32HandleInfoKHR importInfo = {
+ VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR };
+importInfo.handleType = handleType;
+importInfo.handle = myExternalHandleToImport;
+
+VmaAllocationCreateInfo allocCreateInfo = {};
+allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
+
+VkBuffer buf = VK_NULL_HANDLE;
+VmaAllocation alloc = VK_NULL_HANDLE;
+VkResult res = vmaCreateDedicatedBuffer(allocator, &bufCreateInfo, &allocCreateInfo,
+ &importInfo, // pMemoryAllocateNext !!!
+ &buf, &alloc, nullptr);
+// Check res...
+\endcode
@@ -18865,11 +19452,9 @@ vmaGetAllocationMemoryProperties(allocator, alloc, &memPropFlags);
if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
{
- // Allocation ended up in a mappable memory and is already mapped - write to it directly.
-
- // [Executed in runtime]:
- memcpy(allocInfo.pMappedData, myData, myDataSize);
- result = vmaFlushAllocation(allocator, alloc, 0, VK_WHOLE_SIZE);
+ // The Allocation ended up in a mappable memory.
+ // Calling vmaCopyMemoryToAllocation() does vmaMapMemory(), memcpy(), vmaUnmapMemory(), and vmaFlushAllocation().
+ result = vmaCopyMemoryToAllocation(allocator, myData, alloc, 0, myDataSize);
// Check result...
VkBufferMemoryBarrier bufMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
@@ -18881,6 +19466,7 @@ if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
bufMemBarrier.offset = 0;
bufMemBarrier.size = VK_WHOLE_SIZE;
+ // It's important to insert a buffer memory barrier here to ensure writing to the buffer has finished.
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
0, 0, nullptr, 1, &bufMemBarrier, 0, nullptr);
}
@@ -18903,9 +19489,8 @@ else
&stagingBuf, &stagingAlloc, &stagingAllocInfo);
// Check result...
- // [Executed in runtime]:
- memcpy(stagingAllocInfo.pMappedData, myData, myDataSize);
- result = vmaFlushAllocation(allocator, stagingAlloc, 0, VK_WHOLE_SIZE);
+ // Calling vmaCopyMemoryToAllocation() does vmaMapMemory(), memcpy(), vmaUnmapMemory(), and vmaFlushAllocation().
+ result = vmaCopyMemoryToAllocation(allocator, myData, stagingAlloc, 0, myDataSize);
// Check result...
VkBufferMemoryBarrier bufMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
@@ -18917,6 +19502,7 @@ else
bufMemBarrier.offset = 0;
bufMemBarrier.size = VK_WHOLE_SIZE;
+ // Insert a buffer memory barrier to make sure writing to the staging buffer has finished.
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
0, 0, nullptr, 1, &bufMemBarrier, 0, nullptr);
@@ -18937,6 +19523,7 @@ else
bufMemBarrier2.offset = 0;
bufMemBarrier2.size = VK_WHOLE_SIZE;
+ // Make sure copying from staging buffer to the actual buffer has finished by inserting a buffer memory barrier.
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
0, 0, nullptr, 1, &bufMemBarrier2, 0, nullptr);
}
@@ -19241,145 +19828,6 @@ Example use of this extension can be found in the code of the sample and test su
accompanying this library.
-\page vk_khr_external_memory_win32 VK_KHR_external_memory_win32
-
-On Windows, the VK_KHR_external_memory_win32 device extension allows exporting a Win32 `HANDLE`
-of a `VkDeviceMemory` block, to be able to reference the memory on other Vulkan logical devices or instances,
-in multiple processes, and/or in multiple APIs.
-VMA offers support for it.
-
-\section vk_khr_external_memory_win32_initialization Initialization
-
-1) Make sure the extension is defined in the code by including following header before including VMA:
-
-\code
-#include
-\endcode
-
-2) Check if "VK_KHR_external_memory_win32" is available among device extensions.
-Enable it when creating the `VkDevice` object.
-
-3) Enable the usage of this extension in VMA by setting flag #VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT
-when calling vmaCreateAllocator().
-
-4) Make sure that VMA has access to the `vkGetMemoryWin32HandleKHR` function by either enabling `VMA_DYNAMIC_VULKAN_FUNCTIONS` macro
-or setting VmaVulkanFunctions::vkGetMemoryWin32HandleKHR explicitly.
-For more information, see \ref quick_start_initialization_importing_vulkan_functions.
-
-\section vk_khr_external_memory_win32_preparations Preparations
-
-You can find example usage among tests, in file "Tests.cpp", function `TestWin32Handles()`.
-
-To use the extenion, buffers need to be created with `VkExternalMemoryBufferCreateInfoKHR` attached to their `pNext` chain,
-and memory allocations need to be made with `VkExportMemoryAllocateInfoKHR` attached to their `pNext` chain.
-To make use of them, you need to use \ref custom_memory_pools. Example:
-
-\code
-// Define an example buffer and allocation parameters.
-VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {
- VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
- nullptr,
- VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
-};
-VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
-exampleBufCreateInfo.size = 0x10000; // Doesn't matter here.
-exampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
-exampleBufCreateInfo.pNext = &externalMemBufCreateInfo;
-
-VmaAllocationCreateInfo exampleAllocCreateInfo = {};
-exampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
-
-// Find memory type index to use for the custom pool.
-uint32_t memTypeIndex;
-VkResult res = vmaFindMemoryTypeIndexForBufferInfo(g_Allocator,
- &exampleBufCreateInfo, &exampleAllocCreateInfo, &memTypeIndex);
-// Check res...
-
-// Create a custom pool.
-constexpr static VkExportMemoryAllocateInfoKHR exportMemAllocInfo = {
- VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
- nullptr,
- VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
-};
-VmaPoolCreateInfo poolCreateInfo = {};
-poolCreateInfo.memoryTypeIndex = memTypeIndex;
-poolCreateInfo.pMemoryAllocateNext = (void*)&exportMemAllocInfo;
-
-VmaPool pool;
-res = vmaCreatePool(g_Allocator, &poolCreateInfo, &pool);
-// Check res...
-
-// YOUR OTHER CODE COMES HERE....
-
-// At the end, don't forget to destroy it!
-vmaDestroyPool(g_Allocator, pool);
-\endcode
-
-Note that the structure passed as VmaPoolCreateInfo::pMemoryAllocateNext must remain alive and unchanged
-for the whole lifetime of the custom pool, because it will be used when the pool allocates a new device memory block.
-No copy is made internally. This is why variable `exportMemAllocInfo` is defined as `static`.
-
-\section vk_khr_external_memory_win32_memory_allocation Memory allocation
-
-Finally, you can create a buffer with an allocation out of the custom pool.
-The buffer should use same flags as the sample buffer used to find the memory type.
-It should also specify `VkExternalMemoryBufferCreateInfoKHR` in its `pNext` chain.
-
-\code
-VkExternalMemoryBufferCreateInfoKHR externalMemBufCreateInfo = {
- VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
- nullptr,
- VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
-};
-VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
-bufCreateInfo.size = // Your desired buffer size.
-bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
-bufCreateInfo.pNext = &externalMemBufCreateInfo;
-
-VmaAllocationCreateInfo allocCreateInfo = {};
-allocCreateInfo.pool = pool; // It is enough to set this one member.
-
-VkBuffer buf;
-VmaAllocation alloc;
-res = vmaCreateBuffer(g_Allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, nullptr);
-// Check res...
-
-// YOUR OTHER CODE COMES HERE....
-
-// At the end, don't forget to destroy it!
-vmaDestroyBuffer(g_Allocator, buf, alloc);
-\endcode
-
-If you need each allocation to have its own device memory block and start at offset 0, you can still do
-by using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag. It works also with custom pools.
-
-\section vk_khr_external_memory_win32_exporting_win32_handle Exporting Win32 handle
-
-After the allocation is created, you can acquire a Win32 `HANDLE` to the `VkDeviceMemory` block it belongs to.
-VMA function vmaGetMemoryWin32Handle() is a replacement of the Vulkan function `vkGetMemoryWin32HandleKHR`.
-
-\code
-HANDLE handle;
-res = vmaGetMemoryWin32Handle(g_Allocator, alloc, nullptr, &handle);
-// Check res...
-
-// YOUR OTHER CODE COMES HERE....
-
-// At the end, you must close the handle.
-CloseHandle(handle);
-\endcode
-
-Documentation of the VK_KHR_external_memory_win32 extension states that:
-
-> If handleType is defined as an NT handle, vkGetMemoryWin32HandleKHR must be called no more than once for each valid unique combination of memory and handleType.
-
-This is ensured automatically inside VMA.
-The library fetches the handle on first use, remembers it internally, and closes it when the memory block or dedicated allocation is destroyed.
-Every time you call vmaGetMemoryWin32Handle(), VMA calls `DuplicateHandle` and returns a new handle that you need to close.
-
-For further information, please check documentation of the vmaGetMemoryWin32Handle() function.
-
-
\page enabling_buffer_device_address Enabling buffer device address
Device extension VK_KHR_buffer_device_address
@@ -19475,9 +19923,6 @@ When using this library, you can meet following types of warnings issued by
Vulkan validation layer. They don't necessarily indicate a bug, so you may need
to just ignore them.
-- *vkBindBufferMemory(): Binding memory to buffer 0xeb8e4 but vkGetBufferMemoryRequirements() has not been called on that buffer.*
- - It happens when VK_KHR_dedicated_allocation extension is enabled.
- `vkGetBufferMemoryRequirements2KHR` function is used instead, while validation layer seems to be unaware of it.
- *Mapping an image with layout VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL can result in undefined behavior if this memory is used by the device. Only GENERAL or PREINITIALIZED should be used.*
- It happens when you map a buffer or image, because the library maps entire
`VkDeviceMemory` block, where different types of images and buffers may end
diff --git a/third_party/vulkan/vulkan.cppm b/third_party/vulkan/vulkan.cppm
index 9d46b60..86956de 100644
--- a/third_party/vulkan/vulkan.cppm
+++ b/third_party/vulkan/vulkan.cppm
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -27,7 +26,7 @@ export module vulkan;
export import std;
-VULKAN_HPP_STATIC_ASSERT( VK_HEADER_VERSION == 352, "Wrong VK_HEADER_VERSION!" );
+VULKAN_HPP_STATIC_ASSERT( VK_HEADER_VERSION == 353, "Wrong VK_HEADER_VERSION!" );
#if defined( _MSC_VER )
# pragma warning( push )
diff --git a/third_party/vulkan/vulkan.hpp b/third_party/vulkan/vulkan.hpp
index 0bcb6f9..0c98d7a 100644
--- a/third_party/vulkan/vulkan.hpp
+++ b/third_party/vulkan/vulkan.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -37,7 +36,7 @@
# endif
#endif
-VULKAN_HPP_STATIC_ASSERT( VK_HEADER_VERSION == 352, "Wrong VK_HEADER_VERSION!" );
+VULKAN_HPP_STATIC_ASSERT( VK_HEADER_VERSION == 353, "Wrong VK_HEADER_VERSION!" );
VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
{
@@ -11195,6 +11194,10 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
VULKAN_HPP_CONSTEXPR_INLINE auto ARMPipelineOpacityMicromapSpecVersion = VK_ARM_PIPELINE_OPACITY_MICROMAP_SPEC_VERSION;
VULKAN_HPP_CONSTEXPR_INLINE auto ARMPipelineOpacityMicromapExtensionName = VK_ARM_PIPELINE_OPACITY_MICROMAP_EXTENSION_NAME;
+ //=== VK_KHR_video_encode_feedback2 ===
+ VULKAN_HPP_CONSTEXPR_INLINE auto KHRVideoEncodeFeedback2SpecVersion = VK_KHR_VIDEO_ENCODE_FEEDBACK_2_SPEC_VERSION;
+ VULKAN_HPP_CONSTEXPR_INLINE auto KHRVideoEncodeFeedback2ExtensionName = VK_KHR_VIDEO_ENCODE_FEEDBACK_2_EXTENSION_NAME;
+
#if defined( VK_USE_PLATFORM_METAL_EXT )
//=== VK_EXT_external_memory_metal ===
VULKAN_HPP_CONSTEXPR_INLINE auto EXTExternalMemoryMetalSpecVersion = VK_EXT_EXTERNAL_MEMORY_METAL_SPEC_VERSION;
@@ -11233,6 +11236,10 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
VULKAN_HPP_CONSTEXPR_INLINE auto NVPresentMeteringSpecVersion = VK_NV_PRESENT_METERING_SPEC_VERSION;
VULKAN_HPP_CONSTEXPR_INLINE auto NVPresentMeteringExtensionName = VK_NV_PRESENT_METERING_EXTENSION_NAME;
+ //=== VK_EXT_multisampled_render_to_swapchain ===
+ VULKAN_HPP_CONSTEXPR_INLINE auto EXTMultisampledRenderToSwapchainSpecVersion = VK_EXT_MULTISAMPLED_RENDER_TO_SWAPCHAIN_SPEC_VERSION;
+ VULKAN_HPP_CONSTEXPR_INLINE auto EXTMultisampledRenderToSwapchainExtensionName = VK_EXT_MULTISAMPLED_RENDER_TO_SWAPCHAIN_EXTENSION_NAME;
+
//=== VK_EXT_fragment_density_map_offset ===
VULKAN_HPP_CONSTEXPR_INLINE auto EXTFragmentDensityMapOffsetSpecVersion = VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION;
VULKAN_HPP_CONSTEXPR_INLINE auto EXTFragmentDensityMapOffsetExtensionName = VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME;
@@ -11299,6 +11306,10 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
VULKAN_HPP_CONSTEXPR_INLINE auto SECUbmSurfaceExtensionName = VK_SEC_UBM_SURFACE_EXTENSION_NAME;
#endif /*VK_USE_PLATFORM_UBM_SEC*/
+ //=== VK_KHR_extended_flags ===
+ VULKAN_HPP_CONSTEXPR_INLINE auto KHRExtendedFlagsSpecVersion = VK_KHR_EXTENDED_FLAGS_SPEC_VERSION;
+ VULKAN_HPP_CONSTEXPR_INLINE auto KHRExtendedFlagsExtensionName = VK_KHR_EXTENDED_FLAGS_EXTENSION_NAME;
+
//=== VK_VALVE_shader_mixed_float_dot_product ===
VULKAN_HPP_CONSTEXPR_INLINE auto VALVEShaderMixedFloatDotProductSpecVersion = VK_VALVE_SHADER_MIXED_FLOAT_DOT_PRODUCT_SPEC_VERSION;
VULKAN_HPP_CONSTEXPR_INLINE auto VALVEShaderMixedFloatDotProductExtensionName = VK_VALVE_SHADER_MIXED_FLOAT_DOT_PRODUCT_EXTENSION_NAME;
@@ -21756,6 +21767,43 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
};
};
+ //=== VK_KHR_video_encode_feedback2 ===
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
# if defined( VK_USE_PLATFORM_METAL_EXT )
//=== VK_EXT_external_memory_metal ===
template <>
@@ -21992,6 +22040,34 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
};
};
+ //=== VK_EXT_multisampled_render_to_swapchain ===
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
//=== VK_EXT_fragment_density_map_offset ===
template <>
struct StructExtends
@@ -22476,6 +22552,178 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
};
};
+ //=== VK_KHR_extended_flags ===
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
+ template <>
+ struct StructExtends
+ {
+ enum
+ {
+ value = true
+ };
+ };
+
//=== VK_VALVE_shader_mixed_float_dot_product ===
template <>
struct StructExtends
diff --git a/third_party/vulkan/vulkan_core.h b/third_party/vulkan/vulkan_core.h
index 005e9c9..9e89950 100644
--- a/third_party/vulkan/vulkan_core.h
+++ b/third_party/vulkan/vulkan_core.h
@@ -66,7 +66,7 @@ extern "C" {
//#define VK_API_VERSION VK_MAKE_API_VERSION(0, 1, 0, 0) // Patch version should always be set to 0
// Version of this file
-#define VK_HEADER_VERSION 352
+#define VK_HEADER_VERSION 353
// Complete version of this file
#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 4, VK_HEADER_VERSION)
@@ -1404,6 +1404,9 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_FLEXIBLE_DIMENSIONS_PROPERTIES_NV = 1000593001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_2_PROPERTIES_NV = 1000593002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_OPACITY_MICROMAP_FEATURES_ARM = 1000596000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_FEEDBACK_2_FEATURES_KHR = 1000598000,
+ VK_STRUCTURE_TYPE_VIDEO_ENCODE_FEEDBACK_2_CAPABILITIES_KHR = 1000598001,
+ VK_STRUCTURE_TYPE_QUERY_POOL_VIDEO_ENCODE_PER_PARTITION_FEEDBACK_CREATE_INFO_KHR = 1000598002,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_METAL_HANDLE_INFO_EXT = 1000602000,
VK_STRUCTURE_TYPE_MEMORY_METAL_HANDLE_PROPERTIES_EXT = 1000602001,
VK_STRUCTURE_TYPE_MEMORY_GET_METAL_HANDLE_INFO_EXT = 1000602002,
@@ -1426,6 +1429,8 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_KHR = 1000286001,
VK_STRUCTURE_TYPE_SET_PRESENT_CONFIG_NV = 1000613000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_METERING_FEATURES_NV = 1000613001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SWAPCHAIN_FEATURES_EXT = 1000616000,
+ VK_STRUCTURE_TYPE_SWAPCHAIN_FLAGS_SURFACE_CAPABILITIES_EXT = 1000616001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_EXT = 1000425000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_EXT = 1000425001,
VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_EXT = 1000425002,
@@ -1465,6 +1470,13 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_QUEUE_FAMILY_OPTIMAL_IMAGE_TRANSFER_GRANULARITY_PROPERTIES_KHR = 1000657001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_PARTITIONED_FEATURES_EXT = 1000662000,
VK_STRUCTURE_TYPE_UBM_SURFACE_CREATE_INFO_SEC = 1000664000,
+ VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_4_KHR = 1000668000,
+ VK_STRUCTURE_TYPE_IMAGE_CREATE_FLAGS_2_CREATE_INFO_KHR = 1000668001,
+ VK_STRUCTURE_TYPE_IMAGE_USAGE_FLAGS_2_CREATE_INFO_KHR = 1000668002,
+ VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_2_CREATE_INFO_KHR = 1000668003,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_FLAGS_FEATURES_KHR = 1000668004,
+ VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_2_CREATE_INFO_KHR = 1000668005,
+ VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_2_KHR = 1000668006,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MIXED_FLOAT_DOT_PRODUCT_FEATURES_VALVE = 1000673000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_THROTTLE_HINT_FEATURES_SEC = 1000674000,
VK_STRUCTURE_TYPE_THROTTLE_HINT_SUBMIT_INFO_SEC = 1000674001,
@@ -9043,6 +9055,7 @@ typedef enum VkSwapchainCreateFlagBitsKHR {
VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR = 0x00000040,
VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR = 0x00000080,
VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_KHR = 0x00000008,
+ VK_SWAPCHAIN_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT = 0x00000100,
VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT = VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_KHR,
VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkSwapchainCreateFlagBitsKHR;
@@ -12214,6 +12227,13 @@ typedef enum VkVideoEncodeFeedbackFlagBitsKHR {
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR = 0x00000001,
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR = 0x00000002,
VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_HAS_OVERRIDES_BIT_KHR = 0x00000004,
+ VK_VIDEO_ENCODE_FEEDBACK_AVERAGE_QUANTIZATION_BIT_KHR = 0x00000008,
+ VK_VIDEO_ENCODE_FEEDBACK_MIN_QUANTIZATION_BIT_KHR = 0x00000010,
+ VK_VIDEO_ENCODE_FEEDBACK_MAX_QUANTIZATION_BIT_KHR = 0x00000020,
+ VK_VIDEO_ENCODE_FEEDBACK_INTRA_PIXELS_BIT_KHR = 0x00000040,
+ VK_VIDEO_ENCODE_FEEDBACK_INTER_PIXELS_BIT_KHR = 0x00000080,
+ VK_VIDEO_ENCODE_FEEDBACK_SKIPPED_PIXELS_BIT_KHR = 0x00000100,
+ VK_VIDEO_ENCODE_FEEDBACK_PICTURE_PARTITION_COUNT_BIT_KHR = 0x00000200,
VK_VIDEO_ENCODE_FEEDBACK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
} VkVideoEncodeFeedbackFlagBitsKHR;
typedef VkFlags VkVideoEncodeFeedbackFlagsKHR;
@@ -14569,6 +14589,40 @@ typedef struct VkVideoDecodeAV1InlineSessionParametersInfoKHR {
+// VK_KHR_video_encode_feedback2 is a preprocessor guard. Do not pass it to API calls.
+#define VK_KHR_video_encode_feedback2 1
+#define VK_KHR_VIDEO_ENCODE_FEEDBACK_2_SPEC_VERSION 1
+#define VK_KHR_VIDEO_ENCODE_FEEDBACK_2_EXTENSION_NAME "VK_KHR_video_encode_feedback2"
+
+typedef enum VkVideoEncodePerPartitionFeedbackFlagBitsKHR {
+ VK_VIDEO_ENCODE_PER_PARTITION_FEEDBACK_STATUS_BIT_KHR = 0x00000001,
+ VK_VIDEO_ENCODE_PER_PARTITION_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR = 0x00000002,
+ VK_VIDEO_ENCODE_PER_PARTITION_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR = 0x00000004,
+ VK_VIDEO_ENCODE_PER_PARTITION_FEEDBACK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkVideoEncodePerPartitionFeedbackFlagBitsKHR;
+typedef VkFlags VkVideoEncodePerPartitionFeedbackFlagsKHR;
+typedef struct VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 videoEncodeFeedback2;
+} VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR;
+
+typedef struct VkVideoEncodeFeedback2CapabilitiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ uint32_t maxPerPartitionFeedbackEntries;
+ VkVideoEncodePerPartitionFeedbackFlagsKHR supportedPerPartitionEncodeFeedbackFlags;
+} VkVideoEncodeFeedback2CapabilitiesKHR;
+
+typedef struct VkQueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR {
+ VkStructureType sType;
+ const void* pNext;
+ uint32_t maxPerPartitionFeedbackEntries;
+ VkVideoEncodePerPartitionFeedbackFlagsKHR perPartitionEncodeFeedbackFlags;
+} VkQueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR;
+
+
+
// VK_KHR_depth_clamp_zero_one is a preprocessor guard. Do not pass it to API calls.
#define VK_KHR_depth_clamp_zero_one 1
#define VK_KHR_DEPTH_CLAMP_ZERO_ONE_SPEC_VERSION 1
@@ -14775,6 +14829,117 @@ typedef struct VkQueueFamilyOptimalImageTransferGranularityPropertiesKHR {
+// VK_KHR_extended_flags is a preprocessor guard. Do not pass it to API calls.
+#define VK_KHR_extended_flags 1
+#define VK_KHR_EXTENDED_FLAGS_SPEC_VERSION 1
+#define VK_KHR_EXTENDED_FLAGS_EXTENSION_NAME "VK_KHR_extended_flags"
+typedef VkFlags64 VkFormatFeatureFlags4KHR;
+
+// Flag bits for VkFormatFeatureFlagBits4KHR
+typedef VkFlags64 VkFormatFeatureFlagBits4KHR;
+
+typedef VkFlags64 VkImageUsageFlags2KHR;
+
+// Flag bits for VkImageUsageFlagBits2KHR
+typedef VkFlags64 VkImageUsageFlagBits2KHR;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_TRANSFER_SRC_BIT_KHR = 0x00000001ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_TRANSFER_DST_BIT_KHR = 0x00000002ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_SAMPLED_BIT_KHR = 0x00000004ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_STORAGE_BIT_KHR = 0x00000008ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_COLOR_ATTACHMENT_BIT_KHR = 0x00000010ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 0x00000020ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_TRANSIENT_ATTACHMENT_BIT_KHR = 0x00000040ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_INPUT_ATTACHMENT_BIT_KHR = 0x00000080ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00000100ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_VIDEO_DECODE_DST_BIT_KHR = 0x00000400ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_VIDEO_DECODE_SRC_BIT_KHR = 0x00000800ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_VIDEO_DECODE_DPB_BIT_KHR = 0x00001000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_VIDEO_ENCODE_DST_BIT_KHR = 0x00002000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_VIDEO_ENCODE_SRC_BIT_KHR = 0x00004000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_VIDEO_ENCODE_DPB_BIT_KHR = 0x00008000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x00040000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x00080000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_SAMPLE_WEIGHT_BIT_QCOM = 0x00100000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_SAMPLE_BLOCK_MATCH_BIT_QCOM = 0x00200000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_HOST_TRANSFER_BIT_KHR = 0x00400000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_TENSOR_ALIASING_BIT_ARM = 0x00800000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR = 0x02000000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_VIDEO_ENCODE_EMPHASIS_MAP_BIT_KHR = 0x04000000ULL;
+static const VkImageUsageFlagBits2KHR VK_IMAGE_USAGE_2_TILE_MEMORY_BIT_QCOM = 0x08000000ULL;
+
+typedef VkFlags64 VkImageCreateFlags2KHR;
+
+// Flag bits for VkImageCreateFlagBits2KHR
+typedef VkFlags64 VkImageCreateFlagBits2KHR;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_SPARSE_BINDING_BIT_KHR = 0x00000001ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_SPARSE_RESIDENCY_BIT_KHR = 0x00000002ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_SPARSE_ALIASED_BIT_KHR = 0x00000004ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_MUTABLE_FORMAT_BIT_KHR = 0x00000008ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_CUBE_COMPATIBLE_BIT_KHR = 0x00000010ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_ALIAS_SINGLE_LAYER_DESCRIPTOR_BIT_KHR = 0x00400000ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_2D_ARRAY_COMPATIBLE_BIT_KHR = 0x00000020ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000040ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = 0x00000080ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_EXTENDED_USAGE_BIT_KHR = 0x00000100ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_DISJOINT_BIT_KHR = 0x00000200ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_ALIAS_BIT_KHR = 0x00000400ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_PROTECTED_BIT_KHR = 0x00000800ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_CORNER_SAMPLED_BIT_NV = 0x00002000ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_SUBSAMPLED_BIT_EXT = 0x00004000ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT = 0x00008000ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = 0x00010000ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_2D_VIEW_COMPATIBLE_BIT_EXT = 0x00020000ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT = 0x00040000ULL;
+static const VkImageCreateFlagBits2KHR VK_IMAGE_CREATE_2_VIDEO_PROFILE_INDEPENDENT_BIT_KHR = 0x00100000ULL;
+
+typedef struct VkFormatProperties4KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkFormatFeatureFlags4KHR linearTilingFeatures;
+ VkFormatFeatureFlags4KHR optimalTilingFeatures;
+ VkFormatFeatureFlags4KHR bufferFeatures;
+} VkFormatProperties4KHR;
+
+typedef struct VkImageUsageFlags2CreateInfoKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkImageUsageFlags2KHR usage;
+} VkImageUsageFlags2CreateInfoKHR;
+
+typedef struct VkImageCreateFlags2CreateInfoKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkImageCreateFlags2KHR flags;
+} VkImageCreateFlags2CreateInfoKHR;
+
+typedef struct VkImageViewUsage2CreateInfoKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkImageUsageFlags2KHR usage;
+} VkImageViewUsage2CreateInfoKHR;
+
+typedef struct VkPhysicalDeviceExtendedFlagsFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 extendedFlags;
+} VkPhysicalDeviceExtendedFlagsFeaturesKHR;
+
+typedef struct VkImageStencilUsage2CreateInfoKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkImageUsageFlags2KHR stencilUsage;
+} VkImageStencilUsage2CreateInfoKHR;
+
+typedef struct VkSharedPresentSurfaceCapabilities2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkImageUsageFlags2KHR sharedPresentSupportedUsageFlags;
+} VkSharedPresentSurfaceCapabilities2KHR;
+
+
+
// VK_EXT_debug_report is a preprocessor guard. Do not pass it to API calls.
#define VK_EXT_debug_report 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
@@ -16431,7 +16596,7 @@ typedef VkResult (VKAPI_PTR *PFN_vkCmdEndGpaSessionAMD)(VkCommandBuffer commandB
typedef VkResult (VKAPI_PTR *PFN_vkCmdBeginGpaSampleAMD)(VkCommandBuffer commandBuffer, VkGpaSessionAMD gpaSession, const VkGpaSampleBeginInfoAMD* pGpaSampleBeginInfo, uint32_t* pSampleID);
typedef void (VKAPI_PTR *PFN_vkCmdEndGpaSampleAMD)(VkCommandBuffer commandBuffer, VkGpaSessionAMD gpaSession, uint32_t sampleID);
typedef VkResult (VKAPI_PTR *PFN_vkGetGpaSessionStatusAMD)(VkDevice device, VkGpaSessionAMD gpaSession);
-typedef VkResult (VKAPI_PTR *PFN_vkGetGpaSessionResultsAMD)(VkDevice device, VkGpaSessionAMD gpaSession, uint32_t sampleID, size_t* pSizeInBytes, void* pData);
+typedef VkResult (VKAPI_PTR *PFN_vkGetGpaSessionResultsAMD)(VkDevice device, VkGpaSessionAMD gpaSession, uint32_t sampleID, size_t* pSizeInBytes, void* pData);
typedef VkResult (VKAPI_PTR *PFN_vkResetGpaSessionAMD)(VkDevice device, VkGpaSessionAMD gpaSession);
typedef void (VKAPI_PTR *PFN_vkCmdCopyGpaSessionResultsAMD)(VkCommandBuffer commandBuffer, VkGpaSessionAMD gpaSession);
@@ -25754,6 +25919,24 @@ typedef struct VkPhysicalDevicePresentMeteringFeaturesNV {
+// VK_EXT_multisampled_render_to_swapchain is a preprocessor guard. Do not pass it to API calls.
+#define VK_EXT_multisampled_render_to_swapchain 1
+#define VK_EXT_MULTISAMPLED_RENDER_TO_SWAPCHAIN_SPEC_VERSION 1
+#define VK_EXT_MULTISAMPLED_RENDER_TO_SWAPCHAIN_EXTENSION_NAME "VK_EXT_multisampled_render_to_swapchain"
+typedef struct VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 multisampledRenderToSwapchain;
+} VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT;
+
+typedef struct VkSwapchainFlagsSurfaceCapabilitiesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkSwapchainCreateFlagsKHR swapchainSupportedFlags;
+} VkSwapchainFlagsSurfaceCapabilitiesEXT;
+
+
+
// VK_EXT_fragment_density_map_offset is a preprocessor guard. Do not pass it to API calls.
#define VK_EXT_fragment_density_map_offset 1
#define VK_EXT_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION 1
diff --git a/third_party/vulkan/vulkan_enums.hpp b/third_party/vulkan/vulkan_enums.hpp
index fd80ee0..8b418eb 100644
--- a/third_party/vulkan/vulkan_enums.hpp
+++ b/third_party/vulkan/vulkan_enums.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -1766,12 +1765,15 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
#if defined( VK_USE_PLATFORM_OHOS )
eSurfaceCreateInfoOHOS = VK_STRUCTURE_TYPE_SURFACE_CREATE_INFO_OHOS,
#endif /*VK_USE_PLATFORM_OHOS*/
- ePhysicalDeviceHdrVividFeaturesHUAWEI = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HDR_VIVID_FEATURES_HUAWEI,
- eHdrVividDynamicMetadataHUAWEI = VK_STRUCTURE_TYPE_HDR_VIVID_DYNAMIC_METADATA_HUAWEI,
- ePhysicalDeviceCooperativeMatrix2FeaturesNV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_2_FEATURES_NV,
- eCooperativeMatrixFlexibleDimensionsPropertiesNV = VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_FLEXIBLE_DIMENSIONS_PROPERTIES_NV,
- ePhysicalDeviceCooperativeMatrix2PropertiesNV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_2_PROPERTIES_NV,
- ePhysicalDevicePipelineOpacityMicromapFeaturesARM = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_OPACITY_MICROMAP_FEATURES_ARM,
+ ePhysicalDeviceHdrVividFeaturesHUAWEI = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HDR_VIVID_FEATURES_HUAWEI,
+ eHdrVividDynamicMetadataHUAWEI = VK_STRUCTURE_TYPE_HDR_VIVID_DYNAMIC_METADATA_HUAWEI,
+ ePhysicalDeviceCooperativeMatrix2FeaturesNV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_2_FEATURES_NV,
+ eCooperativeMatrixFlexibleDimensionsPropertiesNV = VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_FLEXIBLE_DIMENSIONS_PROPERTIES_NV,
+ ePhysicalDeviceCooperativeMatrix2PropertiesNV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_2_PROPERTIES_NV,
+ ePhysicalDevicePipelineOpacityMicromapFeaturesARM = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_OPACITY_MICROMAP_FEATURES_ARM,
+ ePhysicalDeviceVideoEncodeFeedback2FeaturesKHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_FEEDBACK_2_FEATURES_KHR,
+ eVideoEncodeFeedback2CapabilitiesKHR = VK_STRUCTURE_TYPE_VIDEO_ENCODE_FEEDBACK_2_CAPABILITIES_KHR,
+ eQueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR = VK_STRUCTURE_TYPE_QUERY_POOL_VIDEO_ENCODE_PER_PARTITION_FEEDBACK_CREATE_INFO_KHR,
#if defined( VK_USE_PLATFORM_METAL_EXT )
eImportMemoryMetalHandleInfoEXT = VK_STRUCTURE_TYPE_IMPORT_MEMORY_METAL_HANDLE_INFO_EXT,
eMemoryMetalHandlePropertiesEXT = VK_STRUCTURE_TYPE_MEMORY_METAL_HANDLE_PROPERTIES_EXT,
@@ -1799,6 +1801,8 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
ePhysicalDeviceRobustness2PropertiesEXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT,
eSetPresentConfigNV = VK_STRUCTURE_TYPE_SET_PRESENT_CONFIG_NV,
ePhysicalDevicePresentMeteringFeaturesNV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_METERING_FEATURES_NV,
+ ePhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SWAPCHAIN_FEATURES_EXT,
+ eSwapchainFlagsSurfaceCapabilitiesEXT = VK_STRUCTURE_TYPE_SWAPCHAIN_FLAGS_SURFACE_CAPABILITIES_EXT,
ePhysicalDeviceFragmentDensityMapOffsetFeaturesEXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_EXT,
ePhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM,
ePhysicalDeviceFragmentDensityMapOffsetPropertiesEXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_EXT,
@@ -1845,6 +1849,13 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
#if defined( VK_USE_PLATFORM_UBM_SEC )
eUbmSurfaceCreateInfoSEC = VK_STRUCTURE_TYPE_UBM_SURFACE_CREATE_INFO_SEC,
#endif /*VK_USE_PLATFORM_UBM_SEC*/
+ eFormatProperties4KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_4_KHR,
+ eImageCreateFlags2CreateInfoKHR = VK_STRUCTURE_TYPE_IMAGE_CREATE_FLAGS_2_CREATE_INFO_KHR,
+ eImageUsageFlags2CreateInfoKHR = VK_STRUCTURE_TYPE_IMAGE_USAGE_FLAGS_2_CREATE_INFO_KHR,
+ eImageViewUsage2CreateInfoKHR = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_2_CREATE_INFO_KHR,
+ ePhysicalDeviceExtendedFlagsFeaturesKHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_FLAGS_FEATURES_KHR,
+ eImageStencilUsage2CreateInfoKHR = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_2_CREATE_INFO_KHR,
+ eSharedPresentSurfaceCapabilities2KHR = VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_2_KHR,
ePhysicalDeviceShaderMixedFloatDotProductFeaturesVALVE = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MIXED_FLOAT_DOT_PRODUCT_FEATURES_VALVE,
ePhysicalDeviceThrottleHintFeaturesSEC = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_THROTTLE_HINT_FEATURES_SEC,
eThrottleHintSubmitInfoSEC = VK_STRUCTURE_TYPE_THROTTLE_HINT_SUBMIT_INFO_SEC,
@@ -5906,14 +5917,15 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
// wrapper class for enum VkSwapchainCreateFlagBitsKHR, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkSwapchainCreateFlagBitsKHR.html
enum class SwapchainCreateFlagBitsKHR : VkSwapchainCreateFlagsKHR
{
- eSplitInstanceBindRegions = VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR,
- eProtected = VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR,
- eMutableFormat = VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR,
- ePresentTimingEXT = VK_SWAPCHAIN_CREATE_PRESENT_TIMING_BIT_EXT,
- ePresentId2 = VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR,
- ePresentWait2 = VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR,
- eDeferredMemoryAllocation = VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_KHR,
- eDeferredMemoryAllocationEXT = VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT
+ eSplitInstanceBindRegions = VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR,
+ eProtected = VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR,
+ eMutableFormat = VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR,
+ ePresentTimingEXT = VK_SWAPCHAIN_CREATE_PRESENT_TIMING_BIT_EXT,
+ ePresentId2 = VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR,
+ ePresentWait2 = VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR,
+ eDeferredMemoryAllocation = VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_KHR,
+ eDeferredMemoryAllocationEXT = VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT,
+ eMultisampledRenderToSingleSampledEXT = VK_SWAPCHAIN_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT
};
// wrapper using for bitmask VkSwapchainCreateFlagsKHR, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkSwapchainCreateFlagsKHR.html
@@ -5927,7 +5939,7 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
static VULKAN_HPP_CONST_OR_CONSTEXPR SwapchainCreateFlagsKHR allFlags =
SwapchainCreateFlagBitsKHR::eSplitInstanceBindRegions | SwapchainCreateFlagBitsKHR::eProtected | SwapchainCreateFlagBitsKHR::eMutableFormat |
SwapchainCreateFlagBitsKHR::ePresentTimingEXT | SwapchainCreateFlagBitsKHR::ePresentId2 | SwapchainCreateFlagBitsKHR::ePresentWait2 |
- SwapchainCreateFlagBitsKHR::eDeferredMemoryAllocation;
+ SwapchainCreateFlagBitsKHR::eDeferredMemoryAllocation | SwapchainCreateFlagBitsKHR::eMultisampledRenderToSingleSampledEXT;
};
// wrapper class for enum VkDeviceGroupPresentModeFlagBitsKHR, see
@@ -8179,7 +8191,14 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
{
eBitstreamBufferOffset = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR,
eBitstreamBytesWritten = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR,
- eBitstreamHasOverrides = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_HAS_OVERRIDES_BIT_KHR
+ eBitstreamHasOverrides = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_HAS_OVERRIDES_BIT_KHR,
+ eAverageQuantization = VK_VIDEO_ENCODE_FEEDBACK_AVERAGE_QUANTIZATION_BIT_KHR,
+ eMinQuantization = VK_VIDEO_ENCODE_FEEDBACK_MIN_QUANTIZATION_BIT_KHR,
+ eMaxQuantization = VK_VIDEO_ENCODE_FEEDBACK_MAX_QUANTIZATION_BIT_KHR,
+ eIntraPixels = VK_VIDEO_ENCODE_FEEDBACK_INTRA_PIXELS_BIT_KHR,
+ eInterPixels = VK_VIDEO_ENCODE_FEEDBACK_INTER_PIXELS_BIT_KHR,
+ eSkippedPixels = VK_VIDEO_ENCODE_FEEDBACK_SKIPPED_PIXELS_BIT_KHR,
+ ePicturePartitionCount = VK_VIDEO_ENCODE_FEEDBACK_PICTURE_PARTITION_COUNT_BIT_KHR
};
// wrapper using for bitmask VkVideoEncodeFeedbackFlagsKHR, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkVideoEncodeFeedbackFlagsKHR.html
@@ -8190,9 +8209,11 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
{
using WrappedType = VkVideoEncodeFeedbackFlagBitsKHR;
static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
- static VULKAN_HPP_CONST_OR_CONSTEXPR VideoEncodeFeedbackFlagsKHR allFlags = VideoEncodeFeedbackFlagBitsKHR::eBitstreamBufferOffset |
- VideoEncodeFeedbackFlagBitsKHR::eBitstreamBytesWritten |
- VideoEncodeFeedbackFlagBitsKHR::eBitstreamHasOverrides;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR VideoEncodeFeedbackFlagsKHR allFlags =
+ VideoEncodeFeedbackFlagBitsKHR::eBitstreamBufferOffset | VideoEncodeFeedbackFlagBitsKHR::eBitstreamBytesWritten |
+ VideoEncodeFeedbackFlagBitsKHR::eBitstreamHasOverrides | VideoEncodeFeedbackFlagBitsKHR::eAverageQuantization |
+ VideoEncodeFeedbackFlagBitsKHR::eMinQuantization | VideoEncodeFeedbackFlagBitsKHR::eMaxQuantization | VideoEncodeFeedbackFlagBitsKHR::eIntraPixels |
+ VideoEncodeFeedbackFlagBitsKHR::eInterPixels | VideoEncodeFeedbackFlagBitsKHR::eSkippedPixels | VideoEncodeFeedbackFlagBitsKHR::ePicturePartitionCount;
};
// wrapper class for enum VkVideoEncodeUsageFlagBitsKHR, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkVideoEncodeUsageFlagBitsKHR.html
@@ -10172,6 +10193,31 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
};
#endif /*VK_USE_PLATFORM_OHOS*/
+ //=== VK_KHR_video_encode_feedback2 ===
+
+ // wrapper class for enum VkVideoEncodePerPartitionFeedbackFlagBitsKHR, see
+ // https://registry.khronos.org/vulkan/specs/latest/man/html/VkVideoEncodePerPartitionFeedbackFlagBitsKHR.html
+ enum class VideoEncodePerPartitionFeedbackFlagBitsKHR : VkVideoEncodePerPartitionFeedbackFlagsKHR
+ {
+ eStatus = VK_VIDEO_ENCODE_PER_PARTITION_FEEDBACK_STATUS_BIT_KHR,
+ eBitstreamBufferOffset = VK_VIDEO_ENCODE_PER_PARTITION_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR,
+ eBitstreamBytesWritten = VK_VIDEO_ENCODE_PER_PARTITION_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR
+ };
+
+ // wrapper using for bitmask VkVideoEncodePerPartitionFeedbackFlagsKHR, see
+ // https://registry.khronos.org/vulkan/specs/latest/man/html/VkVideoEncodePerPartitionFeedbackFlagsKHR.html
+ using VideoEncodePerPartitionFeedbackFlagsKHR = Flags;
+
+ template <>
+ struct FlagTraits
+ {
+ using WrappedType = VkVideoEncodePerPartitionFeedbackFlagBitsKHR;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR VideoEncodePerPartitionFeedbackFlagsKHR allFlags = VideoEncodePerPartitionFeedbackFlagBitsKHR::eStatus |
+ VideoEncodePerPartitionFeedbackFlagBitsKHR::eBitstreamBufferOffset |
+ VideoEncodePerPartitionFeedbackFlagBitsKHR::eBitstreamBytesWritten;
+ };
+
//=== VK_ARM_performance_counters_by_region ===
enum class PerformanceCounterDescriptionFlagBitsARM : VkPerformanceCounterDescriptionFlagsARM
@@ -10440,6 +10486,116 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
};
#endif /*VK_USE_PLATFORM_UBM_SEC*/
+ //=== VK_KHR_extended_flags ===
+
+ enum class FormatFeatureFlagBits4KHR : VkFormatFeatureFlags4KHR
+ {
+ };
+
+ // wrapper using for bitmask VkFormatFeatureFlags4KHR, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkFormatFeatureFlags4KHR.html
+ using FormatFeatureFlags4KHR = Flags;
+
+ template <>
+ struct FlagTraits
+ {
+ static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR FormatFeatureFlags4KHR allFlags = {};
+ };
+
+ // wrapper class for enum VkImageUsageFlagBits2KHR, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageUsageFlagBits2KHR.html
+ enum class ImageUsageFlagBits2KHR : VkImageUsageFlags2KHR
+ {
+ eTransferSrc = VK_IMAGE_USAGE_2_TRANSFER_SRC_BIT_KHR,
+ eTransferDst = VK_IMAGE_USAGE_2_TRANSFER_DST_BIT_KHR,
+ eSampled = VK_IMAGE_USAGE_2_SAMPLED_BIT_KHR,
+ eStorage = VK_IMAGE_USAGE_2_STORAGE_BIT_KHR,
+ eColorAttachment = VK_IMAGE_USAGE_2_COLOR_ATTACHMENT_BIT_KHR,
+ eDepthStencilAttachment = VK_IMAGE_USAGE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR,
+ eTransientAttachment = VK_IMAGE_USAGE_2_TRANSIENT_ATTACHMENT_BIT_KHR,
+ eInputAttachment = VK_IMAGE_USAGE_2_INPUT_ATTACHMENT_BIT_KHR,
+ eFragmentShadingRateAttachment = VK_IMAGE_USAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR,
+ eFragmentDensityMapEXT = VK_IMAGE_USAGE_2_FRAGMENT_DENSITY_MAP_BIT_EXT,
+ eVideoDecodeDst = VK_IMAGE_USAGE_2_VIDEO_DECODE_DST_BIT_KHR,
+ eVideoDecodeSrc = VK_IMAGE_USAGE_2_VIDEO_DECODE_SRC_BIT_KHR,
+ eVideoDecodeDpb = VK_IMAGE_USAGE_2_VIDEO_DECODE_DPB_BIT_KHR,
+ eVideoEncodeDst = VK_IMAGE_USAGE_2_VIDEO_ENCODE_DST_BIT_KHR,
+ eVideoEncodeSrc = VK_IMAGE_USAGE_2_VIDEO_ENCODE_SRC_BIT_KHR,
+ eVideoEncodeDpb = VK_IMAGE_USAGE_2_VIDEO_ENCODE_DPB_BIT_KHR,
+ eInvocationMaskHUAWEI = VK_IMAGE_USAGE_2_INVOCATION_MASK_BIT_HUAWEI,
+ eAttachmentFeedbackLoopEXT = VK_IMAGE_USAGE_2_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT,
+ eSampleWeightQCOM = VK_IMAGE_USAGE_2_SAMPLE_WEIGHT_BIT_QCOM,
+ eSampleBlockMatchQCOM = VK_IMAGE_USAGE_2_SAMPLE_BLOCK_MATCH_BIT_QCOM,
+ eHostTransfer = VK_IMAGE_USAGE_2_HOST_TRANSFER_BIT_KHR,
+ eTensorAliasingARM = VK_IMAGE_USAGE_2_TENSOR_ALIASING_BIT_ARM,
+ eVideoEncodeQuantizationDeltaMap = VK_IMAGE_USAGE_2_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR,
+ eVideoEncodeEmphasisMap = VK_IMAGE_USAGE_2_VIDEO_ENCODE_EMPHASIS_MAP_BIT_KHR,
+ eTileMemoryQCOM = VK_IMAGE_USAGE_2_TILE_MEMORY_BIT_QCOM
+ };
+
+ // wrapper using for bitmask VkImageUsageFlags2KHR, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageUsageFlags2KHR.html
+ using ImageUsageFlags2KHR = Flags;
+
+ template <>
+ struct FlagTraits
+ {
+ using WrappedType = VkImageUsageFlagBits2KHR;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR ImageUsageFlags2KHR allFlags =
+ ImageUsageFlagBits2KHR::eTransferSrc | ImageUsageFlagBits2KHR::eTransferDst | ImageUsageFlagBits2KHR::eSampled | ImageUsageFlagBits2KHR::eStorage |
+ ImageUsageFlagBits2KHR::eColorAttachment | ImageUsageFlagBits2KHR::eDepthStencilAttachment | ImageUsageFlagBits2KHR::eTransientAttachment |
+ ImageUsageFlagBits2KHR::eInputAttachment | ImageUsageFlagBits2KHR::eFragmentShadingRateAttachment | ImageUsageFlagBits2KHR::eFragmentDensityMapEXT |
+ ImageUsageFlagBits2KHR::eVideoDecodeDst | ImageUsageFlagBits2KHR::eVideoDecodeSrc | ImageUsageFlagBits2KHR::eVideoDecodeDpb |
+ ImageUsageFlagBits2KHR::eVideoEncodeDst | ImageUsageFlagBits2KHR::eVideoEncodeSrc | ImageUsageFlagBits2KHR::eVideoEncodeDpb |
+ ImageUsageFlagBits2KHR::eInvocationMaskHUAWEI | ImageUsageFlagBits2KHR::eAttachmentFeedbackLoopEXT | ImageUsageFlagBits2KHR::eSampleWeightQCOM |
+ ImageUsageFlagBits2KHR::eSampleBlockMatchQCOM | ImageUsageFlagBits2KHR::eHostTransfer | ImageUsageFlagBits2KHR::eTensorAliasingARM |
+ ImageUsageFlagBits2KHR::eVideoEncodeQuantizationDeltaMap | ImageUsageFlagBits2KHR::eVideoEncodeEmphasisMap | ImageUsageFlagBits2KHR::eTileMemoryQCOM;
+ };
+
+ // wrapper class for enum VkImageCreateFlagBits2KHR, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageCreateFlagBits2KHR.html
+ enum class ImageCreateFlagBits2KHR : VkImageCreateFlags2KHR
+ {
+ eSparseBinding = VK_IMAGE_CREATE_2_SPARSE_BINDING_BIT_KHR,
+ eSparseResidency = VK_IMAGE_CREATE_2_SPARSE_RESIDENCY_BIT_KHR,
+ eSparseAliased = VK_IMAGE_CREATE_2_SPARSE_ALIASED_BIT_KHR,
+ eMutableFormat = VK_IMAGE_CREATE_2_MUTABLE_FORMAT_BIT_KHR,
+ eCubeCompatible = VK_IMAGE_CREATE_2_CUBE_COMPATIBLE_BIT_KHR,
+ eAliasSingleLayerDescriptor = VK_IMAGE_CREATE_2_ALIAS_SINGLE_LAYER_DESCRIPTOR_BIT_KHR,
+ e2DArrayCompatible = VK_IMAGE_CREATE_2_2D_ARRAY_COMPATIBLE_BIT_KHR,
+ eSplitInstanceBindRegions = VK_IMAGE_CREATE_2_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR,
+ eBlockTexelViewCompatible = VK_IMAGE_CREATE_2_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR,
+ eExtendedUsage = VK_IMAGE_CREATE_2_EXTENDED_USAGE_BIT_KHR,
+ eDisjoint = VK_IMAGE_CREATE_2_DISJOINT_BIT_KHR,
+ eAlias = VK_IMAGE_CREATE_2_ALIAS_BIT_KHR,
+ eProtected = VK_IMAGE_CREATE_2_PROTECTED_BIT_KHR,
+ eSampleLocationsCompatibleDepthEXT = VK_IMAGE_CREATE_2_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT,
+ eCornerSampledNV = VK_IMAGE_CREATE_2_CORNER_SAMPLED_BIT_NV,
+ eSubsampledEXT = VK_IMAGE_CREATE_2_SUBSAMPLED_BIT_EXT,
+ eFragmentDensityMapOffsetEXT = VK_IMAGE_CREATE_2_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT,
+ eDescriptorBufferCaptureReplayEXT = VK_IMAGE_CREATE_2_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT,
+ e2DViewCompatibleEXT = VK_IMAGE_CREATE_2_2D_VIEW_COMPATIBLE_BIT_EXT,
+ eMultisampledRenderToSingleSampledEXT = VK_IMAGE_CREATE_2_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT,
+ eVideoProfileIndependent = VK_IMAGE_CREATE_2_VIDEO_PROFILE_INDEPENDENT_BIT_KHR
+ };
+
+ // wrapper using for bitmask VkImageCreateFlags2KHR, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageCreateFlags2KHR.html
+ using ImageCreateFlags2KHR = Flags;
+
+ template <>
+ struct FlagTraits
+ {
+ using WrappedType = VkImageCreateFlagBits2KHR;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR bool isBitmask = true;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR ImageCreateFlags2KHR allFlags =
+ ImageCreateFlagBits2KHR::eSparseBinding | ImageCreateFlagBits2KHR::eSparseResidency | ImageCreateFlagBits2KHR::eSparseAliased |
+ ImageCreateFlagBits2KHR::eMutableFormat | ImageCreateFlagBits2KHR::eCubeCompatible | ImageCreateFlagBits2KHR::eAliasSingleLayerDescriptor |
+ ImageCreateFlagBits2KHR::e2DArrayCompatible | ImageCreateFlagBits2KHR::eSplitInstanceBindRegions | ImageCreateFlagBits2KHR::eBlockTexelViewCompatible |
+ ImageCreateFlagBits2KHR::eExtendedUsage | ImageCreateFlagBits2KHR::eDisjoint | ImageCreateFlagBits2KHR::eAlias | ImageCreateFlagBits2KHR::eProtected |
+ ImageCreateFlagBits2KHR::eSampleLocationsCompatibleDepthEXT | ImageCreateFlagBits2KHR::eCornerSampledNV | ImageCreateFlagBits2KHR::eSubsampledEXT |
+ ImageCreateFlagBits2KHR::eFragmentDensityMapOffsetEXT | ImageCreateFlagBits2KHR::eDescriptorBufferCaptureReplayEXT |
+ ImageCreateFlagBits2KHR::e2DViewCompatibleEXT | ImageCreateFlagBits2KHR::eMultisampledRenderToSingleSampledEXT |
+ ImageCreateFlagBits2KHR::eVideoProfileIndependent;
+ };
+
//=== VK_SEC_throttle_hint ===
// wrapper class for enum VkThrottleHintTypeSEC, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkThrottleHintTypeSEC.html
diff --git a/third_party/vulkan/vulkan_extension_inspection.hpp b/third_party/vulkan/vulkan_extension_inspection.hpp
index b0d92da..f7e4ad2 100644
--- a/third_party/vulkan/vulkan_extension_inspection.hpp
+++ b/third_party/vulkan/vulkan_extension_inspection.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -514,6 +513,7 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
"VK_HUAWEI_hdr_vivid",
"VK_NV_cooperative_matrix2",
"VK_ARM_pipeline_opacity_micromap",
+ "VK_KHR_video_encode_feedback2",
#if defined( VK_USE_PLATFORM_METAL_EXT )
"VK_EXT_external_memory_metal",
#endif /*VK_USE_PLATFORM_METAL_EXT*/
@@ -525,6 +525,7 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
"VK_VALVE_fragment_density_map_layered",
"VK_KHR_robustness2",
"VK_NV_present_metering",
+ "VK_EXT_multisampled_render_to_swapchain",
"VK_EXT_fragment_density_map_offset",
"VK_EXT_zero_initialize_device_memory",
"VK_KHR_present_mode_fifo_latest_ready",
@@ -540,6 +541,7 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
"VK_NV_compute_occupancy_priority",
"VK_KHR_maintenance11",
"VK_EXT_shader_subgroup_partitioned",
+ "VK_KHR_extended_flags",
"VK_VALVE_shader_mixed_float_dot_product",
"VK_SEC_throttle_hint",
"VK_ARM_data_graph_neural_accelerator_statistics",
@@ -1147,13 +1149,21 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
{ "VK_EXT_descriptor_heap",
{ { "VK_VERSION_1_0",
{ {
- "VK_KHR_buffer_device_address",
- "VK_KHR_maintenance5",
- } } },
+ "VK_KHR_buffer_device_address",
+ "VK_KHR_extended_flags",
+ },
+ {
+ "VK_KHR_buffer_device_address",
+ "VK_KHR_maintenance5",
+ } } },
{ "VK_VERSION_1_2",
{ {
- "VK_KHR_maintenance5",
- } } } } },
+ "VK_KHR_extended_flags",
+ },
+ {
+ "VK_KHR_maintenance5",
+ } } },
+ { "VK_VERSION_1_4", { {} } } } },
{ "VK_EXT_inline_uniform_block",
{ { "VK_VERSION_1_0",
{ {
@@ -2550,9 +2560,13 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
{ "VK_AMDX_dense_geometry_format",
{ { "VK_VERSION_1_0",
{ {
- "VK_KHR_acceleration_structure",
- "VK_KHR_maintenance5",
- } } },
+ "VK_KHR_acceleration_structure",
+ "VK_KHR_extended_flags",
+ },
+ {
+ "VK_KHR_acceleration_structure",
+ "VK_KHR_maintenance5",
+ } } },
{ "VK_VERSION_1_4",
{ {
"VK_KHR_acceleration_structure",
@@ -2593,8 +2607,11 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
{ "VK_KHR_pipeline_binary",
{ { "VK_VERSION_1_0",
{ {
- "VK_KHR_maintenance5",
- } } },
+ "VK_KHR_extended_flags",
+ },
+ {
+ "VK_KHR_maintenance5",
+ } } },
{ "VK_VERSION_1_4", { {} } } } },
{ "VK_QCOM_tile_properties",
{ { "VK_VERSION_1_0",
@@ -2710,9 +2727,13 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
{ "VK_ARM_data_graph",
{ { "VK_VERSION_1_3",
{ {
- "VK_KHR_deferred_host_operations",
- "VK_KHR_maintenance5",
- } } } } },
+ "VK_KHR_deferred_host_operations",
+ "VK_KHR_extended_flags",
+ },
+ {
+ "VK_KHR_deferred_host_operations",
+ "VK_KHR_maintenance5",
+ } } } } },
{ "VK_ARM_data_graph_instruction_set_tosa",
{ { "VK_VERSION_1_0",
{ {
@@ -2954,13 +2975,20 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
{ "VK_EXT_device_generated_commands",
{ { "VK_VERSION_1_0",
{ {
- "VK_KHR_buffer_device_address",
- "VK_KHR_maintenance5",
- } } },
+ "VK_KHR_buffer_device_address",
+ "VK_KHR_extended_flags",
+ },
+ {
+ "VK_KHR_buffer_device_address",
+ "VK_KHR_maintenance5",
+ } } },
{ "VK_VERSION_1_2",
{ {
- "VK_KHR_maintenance5",
- } } },
+ "VK_KHR_extended_flags",
+ },
+ {
+ "VK_KHR_maintenance5",
+ } } },
{ "VK_VERSION_1_3", { {} } } } },
{ "VK_KHR_device_fault",
{ { "VK_VERSION_1_0",
@@ -3033,6 +3061,11 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
{ { "VK_VERSION_1_0",
{ {
"VK_EXT_opacity_micromap",
+ } } } } },
+ { "VK_KHR_video_encode_feedback2",
+ { { "VK_VERSION_1_0",
+ { {
+ "VK_KHR_video_encode_queue",
} } } } }
#if defined( VK_USE_PLATFORM_METAL_EXT )
,
@@ -3077,9 +3110,13 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
{ "VK_VALVE_fragment_density_map_layered",
{ { "VK_VERSION_1_0",
{ {
- "VK_EXT_fragment_density_map",
- "VK_KHR_maintenance5",
- } } },
+ "VK_EXT_fragment_density_map",
+ "VK_KHR_extended_flags",
+ },
+ {
+ "VK_EXT_fragment_density_map",
+ "VK_KHR_maintenance5",
+ } } },
{ "VK_VERSION_1_4",
{ {
"VK_EXT_fragment_density_map",
@@ -3096,6 +3133,12 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
"VK_KHR_get_physical_device_properties2",
} } },
{ "VK_VERSION_1_1", { {} } } } },
+ { "VK_EXT_multisampled_render_to_swapchain",
+ { { "VK_VERSION_1_0",
+ { {
+ "VK_EXT_multisampled_render_to_single_sampled",
+ "VK_KHR_swapchain",
+ } } } } },
{ "VK_EXT_fragment_density_map_offset",
{ { "VK_VERSION_1_0",
{ {
@@ -3204,6 +3247,12 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
} } } } }
#endif /*VK_USE_PLATFORM_UBM_SEC*/
,
+ { "VK_KHR_extended_flags",
+ { { "VK_VERSION_1_0",
+ { {
+ "VK_KHR_get_physical_device_properties2",
+ } } },
+ { "VK_VERSION_1_1", { {} } } } },
{ "VK_VALVE_shader_mixed_float_dot_product",
{ { "VK_VERSION_1_0",
{ {
@@ -4196,22 +4245,24 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
( extension == "VK_KHR_device_fault" ) || ( extension == "VK_KHR_maintenance8" ) || ( extension == "VK_MESA_image_alignment_control" ) ||
( extension == "VK_KHR_shader_fma" ) || ( extension == "VK_NV_push_constant_bank" ) || ( extension == "VK_EXT_ray_tracing_invocation_reorder" ) ||
( extension == "VK_EXT_depth_clamp_control" ) || ( extension == "VK_KHR_maintenance9" ) || ( extension == "VK_KHR_video_maintenance2" ) ||
- ( extension == "VK_HUAWEI_hdr_vivid" ) || ( extension == "VK_NV_cooperative_matrix2" ) || ( extension == "VK_ARM_pipeline_opacity_micromap" )
+ ( extension == "VK_HUAWEI_hdr_vivid" ) || ( extension == "VK_NV_cooperative_matrix2" ) || ( extension == "VK_ARM_pipeline_opacity_micromap" ) ||
+ ( extension == "VK_KHR_video_encode_feedback2" )
#if defined( VK_USE_PLATFORM_METAL_EXT )
|| ( extension == "VK_EXT_external_memory_metal" )
#endif /*VK_USE_PLATFORM_METAL_EXT*/
|| ( extension == "VK_KHR_depth_clamp_zero_one" ) || ( extension == "VK_ARM_performance_counters_by_region" ) ||
( extension == "VK_ARM_shader_instrumentation" ) || ( extension == "VK_EXT_vertex_attribute_robustness" ) || ( extension == "VK_ARM_format_pack" ) ||
( extension == "VK_VALVE_fragment_density_map_layered" ) || ( extension == "VK_KHR_robustness2" ) || ( extension == "VK_NV_present_metering" ) ||
- ( extension == "VK_EXT_fragment_density_map_offset" ) || ( extension == "VK_EXT_zero_initialize_device_memory" ) ||
- ( extension == "VK_KHR_present_mode_fifo_latest_ready" ) || ( extension == "VK_KHR_opacity_micromap" ) ||
- ( extension == "VK_EXT_shader_64bit_indexing" ) || ( extension == "VK_EXT_custom_resolve" ) || ( extension == "VK_QCOM_data_graph_model" ) ||
- ( extension == "VK_KHR_maintenance10" ) || ( extension == "VK_ARM_data_graph_optical_flow" ) || ( extension == "VK_EXT_shader_long_vector" ) ||
- ( extension == "VK_SEC_pipeline_cache_incremental_mode" ) || ( extension == "VK_EXT_shader_uniform_buffer_unsized_array" ) ||
- ( extension == "VK_NV_compute_occupancy_priority" ) || ( extension == "VK_KHR_maintenance11" ) ||
- ( extension == "VK_EXT_shader_subgroup_partitioned" ) || ( extension == "VK_VALVE_shader_mixed_float_dot_product" ) ||
- ( extension == "VK_SEC_throttle_hint" ) || ( extension == "VK_ARM_data_graph_neural_accelerator_statistics" ) ||
- ( extension == "VK_EXT_primitive_restart_index" ) || ( extension == "VK_NV_cooperative_matrix_decode_vector" );
+ ( extension == "VK_EXT_multisampled_render_to_swapchain" ) || ( extension == "VK_EXT_fragment_density_map_offset" ) ||
+ ( extension == "VK_EXT_zero_initialize_device_memory" ) || ( extension == "VK_KHR_present_mode_fifo_latest_ready" ) ||
+ ( extension == "VK_KHR_opacity_micromap" ) || ( extension == "VK_EXT_shader_64bit_indexing" ) || ( extension == "VK_EXT_custom_resolve" ) ||
+ ( extension == "VK_QCOM_data_graph_model" ) || ( extension == "VK_KHR_maintenance10" ) || ( extension == "VK_ARM_data_graph_optical_flow" ) ||
+ ( extension == "VK_EXT_shader_long_vector" ) || ( extension == "VK_SEC_pipeline_cache_incremental_mode" ) ||
+ ( extension == "VK_EXT_shader_uniform_buffer_unsized_array" ) || ( extension == "VK_NV_compute_occupancy_priority" ) ||
+ ( extension == "VK_KHR_maintenance11" ) || ( extension == "VK_EXT_shader_subgroup_partitioned" ) || ( extension == "VK_KHR_extended_flags" ) ||
+ ( extension == "VK_VALVE_shader_mixed_float_dot_product" ) || ( extension == "VK_SEC_throttle_hint" ) ||
+ ( extension == "VK_ARM_data_graph_neural_accelerator_statistics" ) || ( extension == "VK_EXT_primitive_restart_index" ) ||
+ ( extension == "VK_NV_cooperative_matrix_decode_vector" );
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_20 bool isInstanceExtension( std::string const & extension )
diff --git a/third_party/vulkan/vulkan_format_traits.hpp b/third_party/vulkan/vulkan_format_traits.hpp
index b6a704e..9aac6c8 100644
--- a/third_party/vulkan/vulkan_format_traits.hpp
+++ b/third_party/vulkan/vulkan_format_traits.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
diff --git a/third_party/vulkan/vulkan_funcs.hpp b/third_party/vulkan/vulkan_funcs.hpp
index bb6a499..b43d51a 100644
--- a/third_party/vulkan/vulkan_funcs.hpp
+++ b/third_party/vulkan/vulkan_funcs.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
diff --git a/third_party/vulkan/vulkan_handles.hpp b/third_party/vulkan/vulkan_handles.hpp
index a355dc4..9fc95f1 100644
--- a/third_party/vulkan/vulkan_handles.hpp
+++ b/third_party/vulkan/vulkan_handles.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -2311,6 +2310,11 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
//=== VK_ARM_pipeline_opacity_micromap ===
struct PhysicalDevicePipelineOpacityMicromapFeaturesARM;
+ //=== VK_KHR_video_encode_feedback2 ===
+ struct PhysicalDeviceVideoEncodeFeedback2FeaturesKHR;
+ struct VideoEncodeFeedback2CapabilitiesKHR;
+ struct QueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR;
+
#if defined( VK_USE_PLATFORM_METAL_EXT )
//=== VK_EXT_external_memory_metal ===
struct ImportMemoryMetalHandleInfoEXT;
@@ -2357,6 +2361,10 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
struct SetPresentConfigNV;
struct PhysicalDevicePresentMeteringFeaturesNV;
+ //=== VK_EXT_multisampled_render_to_swapchain ===
+ struct PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT;
+ struct SwapchainFlagsSurfaceCapabilitiesEXT;
+
//=== VK_EXT_fragment_density_map_offset ===
struct PhysicalDeviceFragmentDensityMapOffsetFeaturesEXT;
using PhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM = PhysicalDeviceFragmentDensityMapOffsetFeaturesEXT;
@@ -2439,6 +2447,15 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
struct UbmSurfaceCreateInfoSEC;
#endif /*VK_USE_PLATFORM_UBM_SEC*/
+ //=== VK_KHR_extended_flags ===
+ struct FormatProperties4KHR;
+ struct ImageUsageFlags2CreateInfoKHR;
+ struct ImageCreateFlags2CreateInfoKHR;
+ struct ImageViewUsage2CreateInfoKHR;
+ struct PhysicalDeviceExtendedFlagsFeaturesKHR;
+ struct ImageStencilUsage2CreateInfoKHR;
+ struct SharedPresentSurfaceCapabilities2KHR;
+
//=== VK_VALVE_shader_mixed_float_dot_product ===
struct PhysicalDeviceShaderMixedFloatDotProductFeaturesVALVE;
diff --git a/third_party/vulkan/vulkan_hash.hpp b/third_party/vulkan/vulkan_hash.hpp
index 6e52e38..86073d2 100644
--- a/third_party/vulkan/vulkan_hash.hpp
+++ b/third_party/vulkan/vulkan_hash.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -6846,6 +6845,21 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t operator()( VULKAN_HPP_NAMESPACE::FormatProperties4KHR const & formatProperties4KHR ) const VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, formatProperties4KHR.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, formatProperties4KHR.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, formatProperties4KHR.linearTilingFeatures );
+ VULKAN_HPP_HASH_COMBINE( seed, formatProperties4KHR.optimalTilingFeatures );
+ VULKAN_HPP_HASH_COMBINE( seed, formatProperties4KHR.bufferFeatures );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
@@ -7780,6 +7794,19 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t operator()( VULKAN_HPP_NAMESPACE::ImageCreateFlags2CreateInfoKHR const & imageCreateFlags2CreateInfoKHR ) const VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, imageCreateFlags2CreateInfoKHR.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, imageCreateFlags2CreateInfoKHR.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, imageCreateFlags2CreateInfoKHR.flags );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
@@ -8005,6 +8032,19 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t operator()( VULKAN_HPP_NAMESPACE::ImageStencilUsage2CreateInfoKHR const & imageStencilUsage2CreateInfoKHR ) const VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, imageStencilUsage2CreateInfoKHR.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, imageStencilUsage2CreateInfoKHR.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, imageStencilUsage2CreateInfoKHR.stencilUsage );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
@@ -8031,6 +8071,19 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t operator()( VULKAN_HPP_NAMESPACE::ImageUsageFlags2CreateInfoKHR const & imageUsageFlags2CreateInfoKHR ) const VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, imageUsageFlags2CreateInfoKHR.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, imageUsageFlags2CreateInfoKHR.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, imageUsageFlags2CreateInfoKHR.usage );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
@@ -8129,6 +8182,19 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t operator()( VULKAN_HPP_NAMESPACE::ImageViewUsage2CreateInfoKHR const & imageViewUsage2CreateInfoKHR ) const VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, imageViewUsage2CreateInfoKHR.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, imageViewUsage2CreateInfoKHR.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, imageViewUsage2CreateInfoKHR.usage );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
@@ -11562,6 +11628,20 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t
+ operator()( VULKAN_HPP_NAMESPACE::PhysicalDeviceExtendedFlagsFeaturesKHR const & physicalDeviceExtendedFlagsFeaturesKHR ) const VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, physicalDeviceExtendedFlagsFeaturesKHR.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, physicalDeviceExtendedFlagsFeaturesKHR.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, physicalDeviceExtendedFlagsFeaturesKHR.extendedFlags );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
@@ -13504,6 +13584,20 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t operator()( VULKAN_HPP_NAMESPACE::PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT const &
+ physicalDeviceMultisampledRenderToSwapchainFeaturesEXT ) const VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, physicalDeviceMultisampledRenderToSwapchainFeaturesEXT.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, physicalDeviceMultisampledRenderToSwapchainFeaturesEXT.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, physicalDeviceMultisampledRenderToSwapchainFeaturesEXT.multisampledRenderToSwapchain );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
@@ -16410,6 +16504,20 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t operator()( VULKAN_HPP_NAMESPACE::PhysicalDeviceVideoEncodeFeedback2FeaturesKHR const & physicalDeviceVideoEncodeFeedback2FeaturesKHR ) const
+ VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, physicalDeviceVideoEncodeFeedback2FeaturesKHR.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, physicalDeviceVideoEncodeFeedback2FeaturesKHR.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, physicalDeviceVideoEncodeFeedback2FeaturesKHR.videoEncodeFeedback2 );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
@@ -18233,6 +18341,21 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t operator()( VULKAN_HPP_NAMESPACE::QueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR const &
+ queryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR ) const VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, queryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, queryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, queryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR.maxPerPartitionFeedbackEntries );
+ VULKAN_HPP_HASH_COMBINE( seed, queryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR.perPartitionEncodeFeedbackFlags );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
@@ -19703,6 +19826,19 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t operator()( VULKAN_HPP_NAMESPACE::SharedPresentSurfaceCapabilities2KHR const & sharedPresentSurfaceCapabilities2KHR ) const VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, sharedPresentSurfaceCapabilities2KHR.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, sharedPresentSurfaceCapabilities2KHR.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, sharedPresentSurfaceCapabilities2KHR.sharedPresentSupportedUsageFlags );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
@@ -20242,6 +20378,19 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t operator()( VULKAN_HPP_NAMESPACE::SwapchainFlagsSurfaceCapabilitiesEXT const & swapchainFlagsSurfaceCapabilitiesEXT ) const VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, swapchainFlagsSurfaceCapabilitiesEXT.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, swapchainFlagsSurfaceCapabilitiesEXT.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, swapchainFlagsSurfaceCapabilitiesEXT.swapchainSupportedFlags );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
@@ -21413,6 +21562,20 @@ VULKAN_HPP_EXPORT namespace std
}
};
+ template <>
+ struct hash
+ {
+ std::size_t operator()( VULKAN_HPP_NAMESPACE::VideoEncodeFeedback2CapabilitiesKHR const & videoEncodeFeedback2CapabilitiesKHR ) const VULKAN_HPP_NOEXCEPT
+ {
+ std::size_t seed = 0;
+ VULKAN_HPP_HASH_COMBINE( seed, videoEncodeFeedback2CapabilitiesKHR.sType );
+ VULKAN_HPP_HASH_COMBINE( seed, videoEncodeFeedback2CapabilitiesKHR.pNext );
+ VULKAN_HPP_HASH_COMBINE( seed, videoEncodeFeedback2CapabilitiesKHR.maxPerPartitionFeedbackEntries );
+ VULKAN_HPP_HASH_COMBINE( seed, videoEncodeFeedback2CapabilitiesKHR.supportedPerPartitionEncodeFeedbackFlags );
+ return seed;
+ }
+ };
+
template <>
struct hash
{
diff --git a/third_party/vulkan/vulkan_hpp_macros.hpp b/third_party/vulkan/vulkan_hpp_macros.hpp
index 5cb6e98..769f320 100644
--- a/third_party/vulkan/vulkan_hpp_macros.hpp
+++ b/third_party/vulkan/vulkan_hpp_macros.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
diff --git a/third_party/vulkan/vulkan_raii.hpp b/third_party/vulkan/vulkan_raii.hpp
index 3c13501..5533056 100644
--- a/third_party/vulkan/vulkan_raii.hpp
+++ b/third_party/vulkan/vulkan_raii.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
diff --git a/third_party/vulkan/vulkan_shared.hpp b/third_party/vulkan/vulkan_shared.hpp
index 926f99a..29bd9a6 100644
--- a/third_party/vulkan/vulkan_shared.hpp
+++ b/third_party/vulkan/vulkan_shared.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
diff --git a/third_party/vulkan/vulkan_static_assertions.hpp b/third_party/vulkan/vulkan_static_assertions.hpp
index 74594eb..c404095 100644
--- a/third_party/vulkan/vulkan_static_assertions.hpp
+++ b/third_party/vulkan/vulkan_static_assertions.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -9840,6 +9839,31 @@ VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value,
"PhysicalDevicePipelineOpacityMicromapFeaturesARM is not nothrow_move_constructible!" );
+//=== VK_KHR_video_encode_feedback2 ===
+
+VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::PhysicalDeviceVideoEncodeFeedback2FeaturesKHR ) ==
+ sizeof( VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR ),
+ "struct and wrapper have different size!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value,
+ "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "PhysicalDeviceVideoEncodeFeedback2FeaturesKHR is not nothrow_move_constructible!" );
+
+VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::VideoEncodeFeedback2CapabilitiesKHR ) == sizeof( VkVideoEncodeFeedback2CapabilitiesKHR ),
+ "struct and wrapper have different size!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value,
+ "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "VideoEncodeFeedback2CapabilitiesKHR is not nothrow_move_constructible!" );
+
+VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::QueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR ) ==
+ sizeof( VkQueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR ),
+ "struct and wrapper have different size!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value,
+ "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "QueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR is not nothrow_move_constructible!" );
+
#if defined( VK_USE_PLATFORM_METAL_EXT )
//=== VK_EXT_external_memory_metal ===
@@ -10030,6 +10054,23 @@ VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value,
"PhysicalDevicePresentMeteringFeaturesNV is not nothrow_move_constructible!" );
+//=== VK_EXT_multisampled_render_to_swapchain ===
+
+VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT ) ==
+ sizeof( VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT ),
+ "struct and wrapper have different size!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value,
+ "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT is not nothrow_move_constructible!" );
+
+VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::SwapchainFlagsSurfaceCapabilitiesEXT ) == sizeof( VkSwapchainFlagsSurfaceCapabilitiesEXT ),
+ "struct and wrapper have different size!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value,
+ "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "SwapchainFlagsSurfaceCapabilitiesEXT is not nothrow_move_constructible!" );
+
//=== VK_EXT_fragment_density_map_offset ===
VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::PhysicalDeviceFragmentDensityMapOffsetFeaturesEXT ) ==
@@ -10367,6 +10408,51 @@ VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value, "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "FormatProperties4KHR is not nothrow_move_constructible!" );
+
+VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::ImageUsageFlags2CreateInfoKHR ) == sizeof( VkImageUsageFlags2CreateInfoKHR ),
+ "struct and wrapper have different size!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value, "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "ImageUsageFlags2CreateInfoKHR is not nothrow_move_constructible!" );
+
+VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::ImageCreateFlags2CreateInfoKHR ) == sizeof( VkImageCreateFlags2CreateInfoKHR ),
+ "struct and wrapper have different size!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value, "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "ImageCreateFlags2CreateInfoKHR is not nothrow_move_constructible!" );
+
+VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::ImageViewUsage2CreateInfoKHR ) == sizeof( VkImageViewUsage2CreateInfoKHR ),
+ "struct and wrapper have different size!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value, "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "ImageViewUsage2CreateInfoKHR is not nothrow_move_constructible!" );
+
+VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::PhysicalDeviceExtendedFlagsFeaturesKHR ) == sizeof( VkPhysicalDeviceExtendedFlagsFeaturesKHR ),
+ "struct and wrapper have different size!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value,
+ "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "PhysicalDeviceExtendedFlagsFeaturesKHR is not nothrow_move_constructible!" );
+
+VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::ImageStencilUsage2CreateInfoKHR ) == sizeof( VkImageStencilUsage2CreateInfoKHR ),
+ "struct and wrapper have different size!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value, "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "ImageStencilUsage2CreateInfoKHR is not nothrow_move_constructible!" );
+
+VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::SharedPresentSurfaceCapabilities2KHR ) == sizeof( VkSharedPresentSurfaceCapabilities2KHR ),
+ "struct and wrapper have different size!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_standard_layout::value,
+ "struct wrapper is not a standard layout!" );
+VULKAN_HPP_STATIC_ASSERT( std::is_nothrow_move_constructible::value,
+ "SharedPresentSurfaceCapabilities2KHR is not nothrow_move_constructible!" );
+
//=== VK_VALVE_shader_mixed_float_dot_product ===
VULKAN_HPP_STATIC_ASSERT( sizeof( VULKAN_HPP_NAMESPACE::PhysicalDeviceShaderMixedFloatDotProductFeaturesVALVE ) ==
diff --git a/third_party/vulkan/vulkan_structs.hpp b/third_party/vulkan/vulkan_structs.hpp
index 302892b..70a855f 100644
--- a/third_party/vulkan/vulkan_structs.hpp
+++ b/third_party/vulkan/vulkan_structs.hpp
@@ -1,5 +1,4 @@
// Copyright 2015-2026 The Khronos Group Inc.
-//
// SPDX-License-Identifier: Apache-2.0 OR MIT
//
@@ -68518,6 +68517,111 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
using FormatProperties3KHR = FormatProperties3;
+ // wrapper struct for struct VkFormatProperties4KHR, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkFormatProperties4KHR.html
+ struct FormatProperties4KHR
+ {
+ using NativeType = VkFormatProperties4KHR;
+
+ static bool const allowDuplicate = false;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType::eFormatProperties4KHR;
+
+#if !defined( VULKAN_HPP_NO_CONSTRUCTORS ) && !defined( VULKAN_HPP_NO_STRUCT_CONSTRUCTORS )
+ VULKAN_HPP_CONSTEXPR FormatProperties4KHR( FormatFeatureFlags4KHR linearTilingFeatures_ = {},
+ FormatFeatureFlags4KHR optimalTilingFeatures_ = {},
+ FormatFeatureFlags4KHR bufferFeatures_ = {},
+ void * pNext_ = nullptr ) VULKAN_HPP_NOEXCEPT
+ : pNext{ pNext_ }
+ , linearTilingFeatures{ linearTilingFeatures_ }
+ , optimalTilingFeatures{ optimalTilingFeatures_ }
+ , bufferFeatures{ bufferFeatures_ }
+ {
+ }
+
+ VULKAN_HPP_CONSTEXPR FormatProperties4KHR( FormatProperties4KHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+
+ FormatProperties4KHR( VkFormatProperties4KHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ : FormatProperties4KHR( *reinterpret_cast( &rhs ) )
+ {
+ }
+
+ FormatProperties4KHR & operator=( FormatProperties4KHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+#endif /*VULKAN_HPP_NO_CONSTRUCTORS*/
+
+ FormatProperties4KHR & operator=( VkFormatProperties4KHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ *this = *reinterpret_cast( &rhs );
+ return *this;
+ }
+
+ operator VkFormatProperties4KHR const &() const VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkFormatProperties4KHR &() VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkFormatProperties4KHR const *() const VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+ operator VkFormatProperties4KHR *() VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+#if defined( VULKAN_HPP_USE_REFLECT )
+ std::tuple
+ reflect() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::tie( sType, pNext, linearTilingFeatures, optimalTilingFeatures, bufferFeatures );
+ }
+#endif
+
+#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+ auto operator<=>( FormatProperties4KHR const & ) const = default;
+#else
+ bool operator==( FormatProperties4KHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+# if defined( VULKAN_HPP_USE_REFLECT )
+ return this->reflect() == rhs.reflect();
+# else
+ return ( sType == rhs.sType ) && ( pNext == rhs.pNext ) && ( linearTilingFeatures == rhs.linearTilingFeatures ) &&
+ ( optimalTilingFeatures == rhs.optimalTilingFeatures ) && ( bufferFeatures == rhs.bufferFeatures );
+# endif
+ }
+
+ bool operator!=( FormatProperties4KHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return !operator==( rhs );
+ }
+#endif
+
+ public:
+ StructureType sType = StructureType::eFormatProperties4KHR;
+ void * pNext = {};
+ FormatFeatureFlags4KHR linearTilingFeatures = {};
+ FormatFeatureFlags4KHR optimalTilingFeatures = {};
+ FormatFeatureFlags4KHR bufferFeatures = {};
+ };
+
+#if 20 <= VULKAN_HPP_CPP_VERSION
+ template <>
+ struct CppType
+ {
+ using Type = FormatProperties4KHR;
+ };
+#endif
+
+ template <>
+ struct CppType
+ {
+ using Type = FormatProperties4KHR;
+ };
+
// wrapper struct for struct VkFragmentShadingRateAttachmentInfoKHR, see
// https://registry.khronos.org/vulkan/specs/latest/man/html/VkFragmentShadingRateAttachmentInfoKHR.html
struct FragmentShadingRateAttachmentInfoKHR
@@ -79038,6 +79142,129 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
};
#endif
+ // wrapper struct for struct VkImageCreateFlags2CreateInfoKHR, see
+ // https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageCreateFlags2CreateInfoKHR.html
+ struct ImageCreateFlags2CreateInfoKHR
+ {
+ using NativeType = VkImageCreateFlags2CreateInfoKHR;
+
+ static bool const allowDuplicate = false;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType::eImageCreateFlags2CreateInfoKHR;
+
+#if !defined( VULKAN_HPP_NO_CONSTRUCTORS ) && !defined( VULKAN_HPP_NO_STRUCT_CONSTRUCTORS )
+ VULKAN_HPP_CONSTEXPR ImageCreateFlags2CreateInfoKHR( ImageCreateFlags2KHR flags_ = {}, void * pNext_ = nullptr ) VULKAN_HPP_NOEXCEPT
+ : pNext{ pNext_ }
+ , flags{ flags_ }
+ {
+ }
+
+ VULKAN_HPP_CONSTEXPR ImageCreateFlags2CreateInfoKHR( ImageCreateFlags2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+
+ ImageCreateFlags2CreateInfoKHR( VkImageCreateFlags2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ : ImageCreateFlags2CreateInfoKHR( *reinterpret_cast( &rhs ) )
+ {
+ }
+
+ ImageCreateFlags2CreateInfoKHR & operator=( ImageCreateFlags2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+#endif /*VULKAN_HPP_NO_CONSTRUCTORS*/
+
+ ImageCreateFlags2CreateInfoKHR & operator=( VkImageCreateFlags2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ *this = *reinterpret_cast( &rhs );
+ return *this;
+ }
+
+#if !defined( VULKAN_HPP_NO_SETTERS ) && !defined( VULKAN_HPP_NO_STRUCT_SETTERS )
+ VULKAN_HPP_CONSTEXPR_14 ImageCreateFlags2CreateInfoKHR & setPNext( void * pNext_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageCreateFlags2CreateInfoKHR && setPNext( void * pNext_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return std::move( *this );
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageCreateFlags2CreateInfoKHR & setFlags( ImageCreateFlags2KHR flags_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ flags = flags_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageCreateFlags2CreateInfoKHR && setFlags( ImageCreateFlags2KHR flags_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ flags = flags_;
+ return std::move( *this );
+ }
+#endif /*VULKAN_HPP_NO_SETTERS*/
+
+ operator VkImageCreateFlags2CreateInfoKHR const &() const VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkImageCreateFlags2CreateInfoKHR &() VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkImageCreateFlags2CreateInfoKHR const *() const VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+ operator VkImageCreateFlags2CreateInfoKHR *() VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+#if defined( VULKAN_HPP_USE_REFLECT )
+ std::tuple reflect() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::tie( sType, pNext, flags );
+ }
+#endif
+
+#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+ auto operator<=>( ImageCreateFlags2CreateInfoKHR const & ) const = default;
+#else
+ bool operator==( ImageCreateFlags2CreateInfoKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+# if defined( VULKAN_HPP_USE_REFLECT )
+ return this->reflect() == rhs.reflect();
+# else
+ return ( sType == rhs.sType ) && ( pNext == rhs.pNext ) && ( flags == rhs.flags );
+# endif
+ }
+
+ bool operator!=( ImageCreateFlags2CreateInfoKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return !operator==( rhs );
+ }
+#endif
+
+ public:
+ StructureType sType = StructureType::eImageCreateFlags2CreateInfoKHR;
+ void * pNext = {};
+ ImageCreateFlags2KHR flags = {};
+ };
+
+#if 20 <= VULKAN_HPP_CPP_VERSION
+ template <>
+ struct CppType
+ {
+ using Type = ImageCreateFlags2CreateInfoKHR;
+ };
+#endif
+
+ template <>
+ struct CppType
+ {
+ using Type = ImageCreateFlags2CreateInfoKHR;
+ };
+
// wrapper struct for struct VkImageViewCreateInfo, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageViewCreateInfo.html
struct ImageViewCreateInfo
{
@@ -81329,6 +81556,129 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
using ImageSparseMemoryRequirementsInfo2KHR = ImageSparseMemoryRequirementsInfo2;
+ // wrapper struct for struct VkImageStencilUsage2CreateInfoKHR, see
+ // https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageStencilUsage2CreateInfoKHR.html
+ struct ImageStencilUsage2CreateInfoKHR
+ {
+ using NativeType = VkImageStencilUsage2CreateInfoKHR;
+
+ static bool const allowDuplicate = false;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType::eImageStencilUsage2CreateInfoKHR;
+
+#if !defined( VULKAN_HPP_NO_CONSTRUCTORS ) && !defined( VULKAN_HPP_NO_STRUCT_CONSTRUCTORS )
+ VULKAN_HPP_CONSTEXPR ImageStencilUsage2CreateInfoKHR( ImageUsageFlags2KHR stencilUsage_ = {}, void * pNext_ = nullptr ) VULKAN_HPP_NOEXCEPT
+ : pNext{ pNext_ }
+ , stencilUsage{ stencilUsage_ }
+ {
+ }
+
+ VULKAN_HPP_CONSTEXPR ImageStencilUsage2CreateInfoKHR( ImageStencilUsage2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+
+ ImageStencilUsage2CreateInfoKHR( VkImageStencilUsage2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ : ImageStencilUsage2CreateInfoKHR( *reinterpret_cast( &rhs ) )
+ {
+ }
+
+ ImageStencilUsage2CreateInfoKHR & operator=( ImageStencilUsage2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+#endif /*VULKAN_HPP_NO_CONSTRUCTORS*/
+
+ ImageStencilUsage2CreateInfoKHR & operator=( VkImageStencilUsage2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ *this = *reinterpret_cast( &rhs );
+ return *this;
+ }
+
+#if !defined( VULKAN_HPP_NO_SETTERS ) && !defined( VULKAN_HPP_NO_STRUCT_SETTERS )
+ VULKAN_HPP_CONSTEXPR_14 ImageStencilUsage2CreateInfoKHR & setPNext( void * pNext_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageStencilUsage2CreateInfoKHR && setPNext( void * pNext_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return std::move( *this );
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageStencilUsage2CreateInfoKHR & setStencilUsage( ImageUsageFlags2KHR stencilUsage_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ stencilUsage = stencilUsage_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageStencilUsage2CreateInfoKHR && setStencilUsage( ImageUsageFlags2KHR stencilUsage_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ stencilUsage = stencilUsage_;
+ return std::move( *this );
+ }
+#endif /*VULKAN_HPP_NO_SETTERS*/
+
+ operator VkImageStencilUsage2CreateInfoKHR const &() const VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkImageStencilUsage2CreateInfoKHR &() VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkImageStencilUsage2CreateInfoKHR const *() const VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+ operator VkImageStencilUsage2CreateInfoKHR *() VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+#if defined( VULKAN_HPP_USE_REFLECT )
+ std::tuple reflect() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::tie( sType, pNext, stencilUsage );
+ }
+#endif
+
+#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+ auto operator<=>( ImageStencilUsage2CreateInfoKHR const & ) const = default;
+#else
+ bool operator==( ImageStencilUsage2CreateInfoKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+# if defined( VULKAN_HPP_USE_REFLECT )
+ return this->reflect() == rhs.reflect();
+# else
+ return ( sType == rhs.sType ) && ( pNext == rhs.pNext ) && ( stencilUsage == rhs.stencilUsage );
+# endif
+ }
+
+ bool operator!=( ImageStencilUsage2CreateInfoKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return !operator==( rhs );
+ }
+#endif
+
+ public:
+ StructureType sType = StructureType::eImageStencilUsage2CreateInfoKHR;
+ void * pNext = {};
+ ImageUsageFlags2KHR stencilUsage = {};
+ };
+
+#if 20 <= VULKAN_HPP_CPP_VERSION
+ template <>
+ struct CppType
+ {
+ using Type = ImageStencilUsage2CreateInfoKHR;
+ };
+#endif
+
+ template <>
+ struct CppType
+ {
+ using Type = ImageStencilUsage2CreateInfoKHR;
+ };
+
// wrapper struct for struct VkImageStencilUsageCreateInfo, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageStencilUsageCreateInfo.html
struct ImageStencilUsageCreateInfo
{
@@ -81575,6 +81925,129 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
using Type = ImageSwapchainCreateInfoKHR;
};
+ // wrapper struct for struct VkImageUsageFlags2CreateInfoKHR, see
+ // https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageUsageFlags2CreateInfoKHR.html
+ struct ImageUsageFlags2CreateInfoKHR
+ {
+ using NativeType = VkImageUsageFlags2CreateInfoKHR;
+
+ static bool const allowDuplicate = false;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType::eImageUsageFlags2CreateInfoKHR;
+
+#if !defined( VULKAN_HPP_NO_CONSTRUCTORS ) && !defined( VULKAN_HPP_NO_STRUCT_CONSTRUCTORS )
+ VULKAN_HPP_CONSTEXPR ImageUsageFlags2CreateInfoKHR( ImageUsageFlags2KHR usage_ = {}, void * pNext_ = nullptr ) VULKAN_HPP_NOEXCEPT
+ : pNext{ pNext_ }
+ , usage{ usage_ }
+ {
+ }
+
+ VULKAN_HPP_CONSTEXPR ImageUsageFlags2CreateInfoKHR( ImageUsageFlags2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+
+ ImageUsageFlags2CreateInfoKHR( VkImageUsageFlags2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ : ImageUsageFlags2CreateInfoKHR( *reinterpret_cast( &rhs ) )
+ {
+ }
+
+ ImageUsageFlags2CreateInfoKHR & operator=( ImageUsageFlags2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+#endif /*VULKAN_HPP_NO_CONSTRUCTORS*/
+
+ ImageUsageFlags2CreateInfoKHR & operator=( VkImageUsageFlags2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ *this = *reinterpret_cast( &rhs );
+ return *this;
+ }
+
+#if !defined( VULKAN_HPP_NO_SETTERS ) && !defined( VULKAN_HPP_NO_STRUCT_SETTERS )
+ VULKAN_HPP_CONSTEXPR_14 ImageUsageFlags2CreateInfoKHR & setPNext( void * pNext_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageUsageFlags2CreateInfoKHR && setPNext( void * pNext_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return std::move( *this );
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageUsageFlags2CreateInfoKHR & setUsage( ImageUsageFlags2KHR usage_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ usage = usage_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageUsageFlags2CreateInfoKHR && setUsage( ImageUsageFlags2KHR usage_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ usage = usage_;
+ return std::move( *this );
+ }
+#endif /*VULKAN_HPP_NO_SETTERS*/
+
+ operator VkImageUsageFlags2CreateInfoKHR const &() const VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkImageUsageFlags2CreateInfoKHR &() VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkImageUsageFlags2CreateInfoKHR const *() const VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+ operator VkImageUsageFlags2CreateInfoKHR *() VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+#if defined( VULKAN_HPP_USE_REFLECT )
+ std::tuple reflect() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::tie( sType, pNext, usage );
+ }
+#endif
+
+#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+ auto operator<=>( ImageUsageFlags2CreateInfoKHR const & ) const = default;
+#else
+ bool operator==( ImageUsageFlags2CreateInfoKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+# if defined( VULKAN_HPP_USE_REFLECT )
+ return this->reflect() == rhs.reflect();
+# else
+ return ( sType == rhs.sType ) && ( pNext == rhs.pNext ) && ( usage == rhs.usage );
+# endif
+ }
+
+ bool operator!=( ImageUsageFlags2CreateInfoKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return !operator==( rhs );
+ }
+#endif
+
+ public:
+ StructureType sType = StructureType::eImageUsageFlags2CreateInfoKHR;
+ void * pNext = {};
+ ImageUsageFlags2KHR usage = {};
+ };
+
+#if 20 <= VULKAN_HPP_CPP_VERSION
+ template <>
+ struct CppType
+ {
+ using Type = ImageUsageFlags2CreateInfoKHR;
+ };
+#endif
+
+ template <>
+ struct CppType
+ {
+ using Type = ImageUsageFlags2CreateInfoKHR;
+ };
+
// wrapper struct for struct VkImageViewASTCDecodeModeEXT, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageViewASTCDecodeModeEXT.html
struct ImageViewASTCDecodeModeEXT
{
@@ -82487,6 +82960,128 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
using Type = ImageViewSlicedCreateInfoEXT;
};
+ // wrapper struct for struct VkImageViewUsage2CreateInfoKHR, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageViewUsage2CreateInfoKHR.html
+ struct ImageViewUsage2CreateInfoKHR
+ {
+ using NativeType = VkImageViewUsage2CreateInfoKHR;
+
+ static bool const allowDuplicate = false;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType::eImageViewUsage2CreateInfoKHR;
+
+#if !defined( VULKAN_HPP_NO_CONSTRUCTORS ) && !defined( VULKAN_HPP_NO_STRUCT_CONSTRUCTORS )
+ VULKAN_HPP_CONSTEXPR ImageViewUsage2CreateInfoKHR( ImageUsageFlags2KHR usage_ = {}, void * pNext_ = nullptr ) VULKAN_HPP_NOEXCEPT
+ : pNext{ pNext_ }
+ , usage{ usage_ }
+ {
+ }
+
+ VULKAN_HPP_CONSTEXPR ImageViewUsage2CreateInfoKHR( ImageViewUsage2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+
+ ImageViewUsage2CreateInfoKHR( VkImageViewUsage2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ : ImageViewUsage2CreateInfoKHR( *reinterpret_cast( &rhs ) )
+ {
+ }
+
+ ImageViewUsage2CreateInfoKHR & operator=( ImageViewUsage2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+#endif /*VULKAN_HPP_NO_CONSTRUCTORS*/
+
+ ImageViewUsage2CreateInfoKHR & operator=( VkImageViewUsage2CreateInfoKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ *this = *reinterpret_cast( &rhs );
+ return *this;
+ }
+
+#if !defined( VULKAN_HPP_NO_SETTERS ) && !defined( VULKAN_HPP_NO_STRUCT_SETTERS )
+ VULKAN_HPP_CONSTEXPR_14 ImageViewUsage2CreateInfoKHR & setPNext( void * pNext_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageViewUsage2CreateInfoKHR && setPNext( void * pNext_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return std::move( *this );
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageViewUsage2CreateInfoKHR & setUsage( ImageUsageFlags2KHR usage_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ usage = usage_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 ImageViewUsage2CreateInfoKHR && setUsage( ImageUsageFlags2KHR usage_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ usage = usage_;
+ return std::move( *this );
+ }
+#endif /*VULKAN_HPP_NO_SETTERS*/
+
+ operator VkImageViewUsage2CreateInfoKHR const &() const VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkImageViewUsage2CreateInfoKHR &() VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkImageViewUsage2CreateInfoKHR const *() const VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+ operator VkImageViewUsage2CreateInfoKHR *() VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+#if defined( VULKAN_HPP_USE_REFLECT )
+ std::tuple reflect() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::tie( sType, pNext, usage );
+ }
+#endif
+
+#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+ auto operator<=>( ImageViewUsage2CreateInfoKHR const & ) const = default;
+#else
+ bool operator==( ImageViewUsage2CreateInfoKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+# if defined( VULKAN_HPP_USE_REFLECT )
+ return this->reflect() == rhs.reflect();
+# else
+ return ( sType == rhs.sType ) && ( pNext == rhs.pNext ) && ( usage == rhs.usage );
+# endif
+ }
+
+ bool operator!=( ImageViewUsage2CreateInfoKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return !operator==( rhs );
+ }
+#endif
+
+ public:
+ StructureType sType = StructureType::eImageViewUsage2CreateInfoKHR;
+ void * pNext = {};
+ ImageUsageFlags2KHR usage = {};
+ };
+
+#if 20 <= VULKAN_HPP_CPP_VERSION
+ template <>
+ struct CppType
+ {
+ using Type = ImageViewUsage2CreateInfoKHR;
+ };
+#endif
+
+ template <>
+ struct CppType
+ {
+ using Type = ImageViewUsage2CreateInfoKHR;
+ };
+
// wrapper struct for struct VkImageViewUsageCreateInfo, see https://registry.khronos.org/vulkan/specs/latest/man/html/VkImageViewUsageCreateInfo.html
struct ImageViewUsageCreateInfo
{
@@ -114667,6 +115262,129 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
using Type = PhysicalDeviceExtendedDynamicStateFeaturesEXT;
};
+ // wrapper struct for struct VkPhysicalDeviceExtendedFlagsFeaturesKHR, see
+ // https://registry.khronos.org/vulkan/specs/latest/man/html/VkPhysicalDeviceExtendedFlagsFeaturesKHR.html
+ struct PhysicalDeviceExtendedFlagsFeaturesKHR
+ {
+ using NativeType = VkPhysicalDeviceExtendedFlagsFeaturesKHR;
+
+ static bool const allowDuplicate = false;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType::ePhysicalDeviceExtendedFlagsFeaturesKHR;
+
+#if !defined( VULKAN_HPP_NO_CONSTRUCTORS ) && !defined( VULKAN_HPP_NO_STRUCT_CONSTRUCTORS )
+ VULKAN_HPP_CONSTEXPR PhysicalDeviceExtendedFlagsFeaturesKHR( Bool32 extendedFlags_ = {}, void * pNext_ = nullptr ) VULKAN_HPP_NOEXCEPT
+ : pNext{ pNext_ }
+ , extendedFlags{ extendedFlags_ }
+ {
+ }
+
+ VULKAN_HPP_CONSTEXPR PhysicalDeviceExtendedFlagsFeaturesKHR( PhysicalDeviceExtendedFlagsFeaturesKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+
+ PhysicalDeviceExtendedFlagsFeaturesKHR( VkPhysicalDeviceExtendedFlagsFeaturesKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ : PhysicalDeviceExtendedFlagsFeaturesKHR( *reinterpret_cast( &rhs ) )
+ {
+ }
+
+ PhysicalDeviceExtendedFlagsFeaturesKHR & operator=( PhysicalDeviceExtendedFlagsFeaturesKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+#endif /*VULKAN_HPP_NO_CONSTRUCTORS*/
+
+ PhysicalDeviceExtendedFlagsFeaturesKHR & operator=( VkPhysicalDeviceExtendedFlagsFeaturesKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ *this = *reinterpret_cast( &rhs );
+ return *this;
+ }
+
+#if !defined( VULKAN_HPP_NO_SETTERS ) && !defined( VULKAN_HPP_NO_STRUCT_SETTERS )
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceExtendedFlagsFeaturesKHR & setPNext( void * pNext_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceExtendedFlagsFeaturesKHR && setPNext( void * pNext_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return std::move( *this );
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceExtendedFlagsFeaturesKHR & setExtendedFlags( Bool32 extendedFlags_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ extendedFlags = extendedFlags_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceExtendedFlagsFeaturesKHR && setExtendedFlags( Bool32 extendedFlags_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ extendedFlags = extendedFlags_;
+ return std::move( *this );
+ }
+#endif /*VULKAN_HPP_NO_SETTERS*/
+
+ operator VkPhysicalDeviceExtendedFlagsFeaturesKHR const &() const VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkPhysicalDeviceExtendedFlagsFeaturesKHR &() VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkPhysicalDeviceExtendedFlagsFeaturesKHR const *() const VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+ operator VkPhysicalDeviceExtendedFlagsFeaturesKHR *() VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+#if defined( VULKAN_HPP_USE_REFLECT )
+ std::tuple reflect() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::tie( sType, pNext, extendedFlags );
+ }
+#endif
+
+#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+ auto operator<=>( PhysicalDeviceExtendedFlagsFeaturesKHR const & ) const = default;
+#else
+ bool operator==( PhysicalDeviceExtendedFlagsFeaturesKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+# if defined( VULKAN_HPP_USE_REFLECT )
+ return this->reflect() == rhs.reflect();
+# else
+ return ( sType == rhs.sType ) && ( pNext == rhs.pNext ) && ( extendedFlags == rhs.extendedFlags );
+# endif
+ }
+
+ bool operator!=( PhysicalDeviceExtendedFlagsFeaturesKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return !operator==( rhs );
+ }
+#endif
+
+ public:
+ StructureType sType = StructureType::ePhysicalDeviceExtendedFlagsFeaturesKHR;
+ void * pNext = {};
+ Bool32 extendedFlags = {};
+ };
+
+#if 20 <= VULKAN_HPP_CPP_VERSION
+ template <>
+ struct CppType
+ {
+ using Type = PhysicalDeviceExtendedFlagsFeaturesKHR;
+ };
+#endif
+
+ template <>
+ struct CppType
+ {
+ using Type = PhysicalDeviceExtendedFlagsFeaturesKHR;
+ };
+
// wrapper struct for struct VkPhysicalDeviceExtendedSparseAddressSpaceFeaturesNV, see
// https://registry.khronos.org/vulkan/specs/latest/man/html/VkPhysicalDeviceExtendedSparseAddressSpaceFeaturesNV.html
struct PhysicalDeviceExtendedSparseAddressSpaceFeaturesNV
@@ -130064,6 +130782,136 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
using Type = PhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT;
};
+ // wrapper struct for struct VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT, see
+ // https://registry.khronos.org/vulkan/specs/latest/man/html/VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT.html
+ struct PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT
+ {
+ using NativeType = VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT;
+
+ static bool const allowDuplicate = false;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType::ePhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT;
+
+#if !defined( VULKAN_HPP_NO_CONSTRUCTORS ) && !defined( VULKAN_HPP_NO_STRUCT_CONSTRUCTORS )
+ VULKAN_HPP_CONSTEXPR PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT( Bool32 multisampledRenderToSwapchain_ = {},
+ void * pNext_ = nullptr ) VULKAN_HPP_NOEXCEPT
+ : pNext{ pNext_ }
+ , multisampledRenderToSwapchain{ multisampledRenderToSwapchain_ }
+ {
+ }
+
+ VULKAN_HPP_CONSTEXPR PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT( PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT const & rhs )
+ VULKAN_HPP_NOEXCEPT = default;
+
+ PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT( VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT const & rhs ) VULKAN_HPP_NOEXCEPT
+ : PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT( *reinterpret_cast( &rhs ) )
+ {
+ }
+
+ PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT &
+ operator=( PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+#endif /*VULKAN_HPP_NO_CONSTRUCTORS*/
+
+ PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT &
+ operator=( VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ *this = *reinterpret_cast( &rhs );
+ return *this;
+ }
+
+#if !defined( VULKAN_HPP_NO_SETTERS ) && !defined( VULKAN_HPP_NO_STRUCT_SETTERS )
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT & setPNext( void * pNext_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT && setPNext( void * pNext_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return std::move( *this );
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT & setMultisampledRenderToSwapchain( Bool32 multisampledRenderToSwapchain_ ) &
+ VULKAN_HPP_NOEXCEPT
+ {
+ multisampledRenderToSwapchain = multisampledRenderToSwapchain_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT &&
+ setMultisampledRenderToSwapchain( Bool32 multisampledRenderToSwapchain_ ) &&
+ VULKAN_HPP_NOEXCEPT
+ {
+ multisampledRenderToSwapchain = multisampledRenderToSwapchain_;
+ return std::move( *this );
+ }
+#endif /*VULKAN_HPP_NO_SETTERS*/
+
+ operator VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT const &() const VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT &() VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT const *() const VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+ operator VkPhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT *() VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+#if defined( VULKAN_HPP_USE_REFLECT )
+ std::tuple reflect() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::tie( sType, pNext, multisampledRenderToSwapchain );
+ }
+#endif
+
+#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+ auto operator<=>( PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT const & ) const = default;
+#else
+ bool operator==( PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+# if defined( VULKAN_HPP_USE_REFLECT )
+ return this->reflect() == rhs.reflect();
+# else
+ return ( sType == rhs.sType ) && ( pNext == rhs.pNext ) && ( multisampledRenderToSwapchain == rhs.multisampledRenderToSwapchain );
+# endif
+ }
+
+ bool operator!=( PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return !operator==( rhs );
+ }
+#endif
+
+ public:
+ StructureType sType = StructureType::ePhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT;
+ void * pNext = {};
+ Bool32 multisampledRenderToSwapchain = {};
+ };
+
+#if 20 <= VULKAN_HPP_CPP_VERSION
+ template <>
+ struct CppType
+ {
+ using Type = PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT;
+ };
+#endif
+
+ template <>
+ struct CppType
+ {
+ using Type = PhysicalDeviceMultisampledRenderToSwapchainFeaturesEXT;
+ };
+
// wrapper struct for struct VkPhysicalDeviceMultiviewFeatures, see
// https://registry.khronos.org/vulkan/specs/latest/man/html/VkPhysicalDeviceMultiviewFeatures.html
struct PhysicalDeviceMultiviewFeatures
@@ -154952,6 +155800,130 @@ VULKAN_HPP_EXPORT namespace VULKAN_HPP_NAMESPACE
using Type = PhysicalDeviceVideoEncodeAV1FeaturesKHR;
};
+ // wrapper struct for struct VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR, see
+ // https://registry.khronos.org/vulkan/specs/latest/man/html/VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR.html
+ struct PhysicalDeviceVideoEncodeFeedback2FeaturesKHR
+ {
+ using NativeType = VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR;
+
+ static bool const allowDuplicate = false;
+ static VULKAN_HPP_CONST_OR_CONSTEXPR StructureType structureType = StructureType::ePhysicalDeviceVideoEncodeFeedback2FeaturesKHR;
+
+#if !defined( VULKAN_HPP_NO_CONSTRUCTORS ) && !defined( VULKAN_HPP_NO_STRUCT_CONSTRUCTORS )
+ VULKAN_HPP_CONSTEXPR PhysicalDeviceVideoEncodeFeedback2FeaturesKHR( Bool32 videoEncodeFeedback2_ = {}, void * pNext_ = nullptr ) VULKAN_HPP_NOEXCEPT
+ : pNext{ pNext_ }
+ , videoEncodeFeedback2{ videoEncodeFeedback2_ }
+ {
+ }
+
+ VULKAN_HPP_CONSTEXPR
+ PhysicalDeviceVideoEncodeFeedback2FeaturesKHR( PhysicalDeviceVideoEncodeFeedback2FeaturesKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+
+ PhysicalDeviceVideoEncodeFeedback2FeaturesKHR( VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ : PhysicalDeviceVideoEncodeFeedback2FeaturesKHR( *reinterpret_cast( &rhs ) )
+ {
+ }
+
+ PhysicalDeviceVideoEncodeFeedback2FeaturesKHR & operator=( PhysicalDeviceVideoEncodeFeedback2FeaturesKHR const & rhs ) VULKAN_HPP_NOEXCEPT = default;
+#endif /*VULKAN_HPP_NO_CONSTRUCTORS*/
+
+ PhysicalDeviceVideoEncodeFeedback2FeaturesKHR & operator=( VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR const & rhs ) VULKAN_HPP_NOEXCEPT
+ {
+ *this = *reinterpret_cast( &rhs );
+ return *this;
+ }
+
+#if !defined( VULKAN_HPP_NO_SETTERS ) && !defined( VULKAN_HPP_NO_STRUCT_SETTERS )
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceVideoEncodeFeedback2FeaturesKHR & setPNext( void * pNext_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceVideoEncodeFeedback2FeaturesKHR && setPNext( void * pNext_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ pNext = pNext_;
+ return std::move( *this );
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceVideoEncodeFeedback2FeaturesKHR & setVideoEncodeFeedback2( Bool32 videoEncodeFeedback2_ ) & VULKAN_HPP_NOEXCEPT
+ {
+ videoEncodeFeedback2 = videoEncodeFeedback2_;
+ return *this;
+ }
+
+ VULKAN_HPP_CONSTEXPR_14 PhysicalDeviceVideoEncodeFeedback2FeaturesKHR && setVideoEncodeFeedback2( Bool32 videoEncodeFeedback2_ ) && VULKAN_HPP_NOEXCEPT
+ {
+ videoEncodeFeedback2 = videoEncodeFeedback2_;
+ return std::move( *this );
+ }
+#endif /*VULKAN_HPP_NO_SETTERS*/
+
+ operator VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR const &() const VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR &() VULKAN_HPP_NOEXCEPT
+ {
+ return *reinterpret_cast( this );
+ }
+
+ operator VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR const *() const VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+ operator VkPhysicalDeviceVideoEncodeFeedback2FeaturesKHR *() VULKAN_HPP_NOEXCEPT
+ {
+ return reinterpret_cast( this );
+ }
+
+#if defined( VULKAN_HPP_USE_REFLECT )
+ std::tuple reflect() const VULKAN_HPP_NOEXCEPT
+ {
+ return std::tie( sType, pNext, videoEncodeFeedback2 );
+ }
+#endif
+
+#if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR )
+ auto operator<=>( PhysicalDeviceVideoEncodeFeedback2FeaturesKHR const & ) const = default;
+#else
+ bool operator==( PhysicalDeviceVideoEncodeFeedback2FeaturesKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+# if defined( VULKAN_HPP_USE_REFLECT )
+ return this->reflect() == rhs.reflect();
+# else
+ return ( sType == rhs.sType ) && ( pNext == rhs.pNext ) && ( videoEncodeFeedback2 == rhs.videoEncodeFeedback2 );
+# endif
+ }
+
+ bool operator!=( PhysicalDeviceVideoEncodeFeedback2FeaturesKHR const & rhs ) const VULKAN_HPP_NOEXCEPT
+ {
+ return !operator==( rhs );
+ }
+#endif
+
+ public:
+ StructureType sType = StructureType::ePhysicalDeviceVideoEncodeFeedback2FeaturesKHR;
+ void * pNext = {};
+ Bool32 videoEncodeFeedback2 = {};
+ };
+
+#if 20 <= VULKAN_HPP_CPP_VERSION
+ template <>
+ struct CppType
+ {
+ using Type = PhysicalDeviceVideoEncodeFeedback2FeaturesKHR;
+ };
+#endif
+
+ template <>
+ struct CppType