mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
synced 2024-11-24 23:54:35 +00:00
Merge pull request #442 from Agrael1/master
[WIP] Win32 Handle extension
This commit is contained in:
commit
0d55cf5276
1
Doxyfile
1
Doxyfile
@ -2466,6 +2466,7 @@ PREDEFINED = VMA_CALL_PRE= \
|
|||||||
VMA_MEMORY_PRIORITY=1 \
|
VMA_MEMORY_PRIORITY=1 \
|
||||||
VMA_KHR_MAINTENANCE4=1 \
|
VMA_KHR_MAINTENANCE4=1 \
|
||||||
VMA_KHR_MAINTENANCE5=1 \
|
VMA_KHR_MAINTENANCE5=1 \
|
||||||
|
VMA_EXTERNAL_MEMORY_WIN32=1 \
|
||||||
VMA_EXTERNAL_MEMORY=1 \
|
VMA_EXTERNAL_MEMORY=1 \
|
||||||
VMA_EXTENDS_VK_STRUCT= \
|
VMA_EXTENDS_VK_STRUCT= \
|
||||||
VMA_STATS_STRING_ENABLED=1
|
VMA_STATS_STRING_ENABLED=1
|
||||||
|
@ -242,6 +242,15 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Defined to 1 when VK_KHR_external_memory_win32 device extension is defined in Vulkan headers.
|
||||||
|
#if !defined(VMA_EXTERNAL_MEMORY_WIN32)
|
||||||
|
#if VK_KHR_external_memory_win32
|
||||||
|
#define VMA_EXTERNAL_MEMORY_WIN32 1
|
||||||
|
#else
|
||||||
|
#define VMA_EXTERNAL_MEMORY_WIN32 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// Define these macros to decorate all public functions with additional code,
|
// Define these macros to decorate all public functions with additional code,
|
||||||
// before and after returned type, appropriately. This may be useful for
|
// before and after returned type, appropriately. This may be useful for
|
||||||
// exporting the functions when compiling VMA as a separate library. Example:
|
// exporting the functions when compiling VMA as a separate library. Example:
|
||||||
@ -461,6 +470,14 @@ typedef enum VmaAllocatorCreateFlagBits
|
|||||||
*/
|
*/
|
||||||
VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT = 0x00000100,
|
VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT = 0x00000100,
|
||||||
|
|
||||||
|
/**
|
||||||
|
Enables usage of VK_KHR_external_memory_win32 extension in the library.
|
||||||
|
|
||||||
|
You should set this flag if you found available and enabled this device extension,
|
||||||
|
while creating Vulkan device passed as VmaAllocatorCreateInfo::device.
|
||||||
|
*/
|
||||||
|
VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT = 0x00000200,
|
||||||
|
|
||||||
VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
||||||
} VmaAllocatorCreateFlagBits;
|
} VmaAllocatorCreateFlagBits;
|
||||||
/// See #VmaAllocatorCreateFlagBits.
|
/// See #VmaAllocatorCreateFlagBits.
|
||||||
@ -1035,6 +1052,11 @@ typedef struct VmaVulkanFunctions
|
|||||||
/// Fetch from "vkGetDeviceImageMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceImageMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4.
|
/// Fetch from "vkGetDeviceImageMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceImageMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4.
|
||||||
PFN_vkGetDeviceImageMemoryRequirementsKHR VMA_NULLABLE vkGetDeviceImageMemoryRequirements;
|
PFN_vkGetDeviceImageMemoryRequirementsKHR VMA_NULLABLE vkGetDeviceImageMemoryRequirements;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
PFN_vkGetMemoryWin32HandleKHR VMA_NULLABLE vkGetMemoryWin32HandleKHR;
|
||||||
|
#else
|
||||||
|
void* VMA_NULLABLE vkGetMemoryWin32HandleKHR;
|
||||||
|
#endif
|
||||||
} VmaVulkanFunctions;
|
} VmaVulkanFunctions;
|
||||||
|
|
||||||
/// Description of a Allocator to be created.
|
/// Description of a Allocator to be created.
|
||||||
@ -2052,6 +2074,21 @@ VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationMemoryProperties(
|
|||||||
VmaAllocation VMA_NOT_NULL allocation,
|
VmaAllocation VMA_NOT_NULL allocation,
|
||||||
VkMemoryPropertyFlags* VMA_NOT_NULL pFlags);
|
VkMemoryPropertyFlags* VMA_NOT_NULL pFlags);
|
||||||
|
|
||||||
|
|
||||||
|
#if VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
/**
|
||||||
|
\brief Given an allocation, returns Win32 Handle, that may be imported by other processes or APIs.
|
||||||
|
|
||||||
|
`hTargetProcess` must be a valid handle to target process or NULL. If it's `NULL`, the function returns
|
||||||
|
handle for the current process.
|
||||||
|
|
||||||
|
If the allocation was created with `VMA_ALLOCATION_CREATE_EXPORT_WIN32_HANDLE_BIT` flag,
|
||||||
|
the function fills `pHandle` with handle that can be used in target process.
|
||||||
|
*/
|
||||||
|
VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32HandleKHR(VmaAllocator VMA_NOT_NULL allocator,
|
||||||
|
VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle);
|
||||||
|
#endif // VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
|
||||||
/** \brief Maps memory represented by given allocation and returns pointer to it.
|
/** \brief Maps memory represented by given allocation and returns pointer to it.
|
||||||
|
|
||||||
Maps memory represented by given allocation to make it accessible to CPU code.
|
Maps memory represented by given allocation to make it accessible to CPU code.
|
||||||
@ -6069,6 +6106,84 @@ private:
|
|||||||
|
|
||||||
#endif // _VMA_MAPPING_HYSTERESIS
|
#endif // _VMA_MAPPING_HYSTERESIS
|
||||||
|
|
||||||
|
#if VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
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); } }
|
||||||
|
VMA_CLASS_NO_COPY_NO_MOVE(VmaWin32Handle)
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Strengthened
|
||||||
|
VkResult GetHandle(VkDevice device, VkDeviceMemory memory, decltype(&vkGetMemoryWin32HandleKHR) pvkGetMemoryWin32HandleKHR, 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.
|
||||||
|
{
|
||||||
|
VmaMutexLockWrite lock(m_Mutex, useMutex);
|
||||||
|
if (m_hHandle == VMA_NULL)
|
||||||
|
{
|
||||||
|
res = Create(device, memory, pvkGetMemoryWin32HandleKHR, &m_hHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*pHandle = Duplicate(hTargetProcess);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool() const noexcept { return m_hHandle != VMA_NULL; }
|
||||||
|
private:
|
||||||
|
// Not atomic
|
||||||
|
static VkResult Create(VkDevice device, VkDeviceMemory memory, decltype(&vkGetMemoryWin32HandleKHR) pvkGetMemoryWin32HandleKHR, HANDLE* pHandle) noexcept
|
||||||
|
{
|
||||||
|
VkResult res = VK_ERROR_FEATURE_NOT_PRESENT;
|
||||||
|
if (pvkGetMemoryWin32HandleKHR != VMA_NULL)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
res = pvkGetMemoryWin32HandleKHR(device, &handleInfo, pHandle);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
HANDLE Duplicate(HANDLE hTargetProcess = VMA_NULL) const noexcept
|
||||||
|
{
|
||||||
|
if (!m_hHandle)
|
||||||
|
return m_hHandle;
|
||||||
|
|
||||||
|
HANDLE hCurrentProcess = ::GetCurrentProcess();
|
||||||
|
HANDLE hDupHandle = VMA_NULL;
|
||||||
|
if (!::DuplicateHandle(hCurrentProcess, m_hHandle, hTargetProcess ? hTargetProcess : hCurrentProcess, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||||
|
{
|
||||||
|
VMA_ASSERT(0 && "Failed to duplicate handle.");
|
||||||
|
}
|
||||||
|
return hDupHandle;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
HANDLE m_hHandle;
|
||||||
|
VMA_RW_MUTEX m_Mutex; // Protects access m_Handle
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
class VmaWin32Handle
|
||||||
|
{
|
||||||
|
// ABI compatibility
|
||||||
|
void* placeholder = VMA_NULL;
|
||||||
|
VMA_RW_MUTEX placeholder2;
|
||||||
|
};
|
||||||
|
#endif // VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
|
||||||
|
|
||||||
#ifndef _VMA_DEVICE_MEMORY_BLOCK
|
#ifndef _VMA_DEVICE_MEMORY_BLOCK
|
||||||
/*
|
/*
|
||||||
Represents a single block of device memory (`VkDeviceMemory`) with all the
|
Represents a single block of device memory (`VkDeviceMemory`) with all the
|
||||||
@ -6135,7 +6250,13 @@ public:
|
|||||||
VkDeviceSize allocationLocalOffset,
|
VkDeviceSize allocationLocalOffset,
|
||||||
VkImage hImage,
|
VkImage hImage,
|
||||||
const void* pNext);
|
const void* pNext);
|
||||||
|
#if VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
VkResult CreateWin32Handle(
|
||||||
|
const VmaAllocator hAllocator,
|
||||||
|
decltype(&vkGetMemoryWin32HandleKHR) pvkGetMemoryWin32HandleKHR,
|
||||||
|
HANDLE hTargetProcess,
|
||||||
|
HANDLE* pHandle)noexcept;
|
||||||
|
#endif // VMA_EXTERNAL_MEMORY_WIN32
|
||||||
private:
|
private:
|
||||||
VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
|
VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
|
||||||
uint32_t m_MemoryTypeIndex;
|
uint32_t m_MemoryTypeIndex;
|
||||||
@ -6151,6 +6272,8 @@ private:
|
|||||||
VmaMappingHysteresis m_MappingHysteresis;
|
VmaMappingHysteresis m_MappingHysteresis;
|
||||||
uint32_t m_MapCount;
|
uint32_t m_MapCount;
|
||||||
void* m_pMappedData;
|
void* m_pMappedData;
|
||||||
|
|
||||||
|
VmaWin32Handle m_Handle; // Win32 handle
|
||||||
};
|
};
|
||||||
#endif // _VMA_DEVICE_MEMORY_BLOCK
|
#endif // _VMA_DEVICE_MEMORY_BLOCK
|
||||||
|
|
||||||
@ -6236,6 +6359,10 @@ public:
|
|||||||
void PrintParameters(class VmaJsonWriter& json) const;
|
void PrintParameters(class VmaJsonWriter& json) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
VkResult GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* hHandle) noexcept;
|
||||||
|
#endif // VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Allocation out of VmaDeviceMemoryBlock.
|
// Allocation out of VmaDeviceMemoryBlock.
|
||||||
struct BlockAllocation
|
struct BlockAllocation
|
||||||
@ -6251,6 +6378,7 @@ private:
|
|||||||
void* m_pMappedData; // Not null means memory is mapped.
|
void* m_pMappedData; // Not null means memory is mapped.
|
||||||
VmaAllocation_T* m_Prev;
|
VmaAllocation_T* m_Prev;
|
||||||
VmaAllocation_T* m_Next;
|
VmaAllocation_T* m_Next;
|
||||||
|
VmaWin32Handle m_Handle; // Win32 handle
|
||||||
};
|
};
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
@ -10071,6 +10199,7 @@ public:
|
|||||||
bool m_UseExtMemoryPriority;
|
bool m_UseExtMemoryPriority;
|
||||||
bool m_UseKhrMaintenance4;
|
bool m_UseKhrMaintenance4;
|
||||||
bool m_UseKhrMaintenance5;
|
bool m_UseKhrMaintenance5;
|
||||||
|
bool m_UseKhrExternalMemoryWin32;
|
||||||
const VkDevice m_hDevice;
|
const VkDevice m_hDevice;
|
||||||
const VkInstance m_hInstance;
|
const VkInstance m_hInstance;
|
||||||
const bool m_AllocationCallbacksSpecified;
|
const bool m_AllocationCallbacksSpecified;
|
||||||
@ -10434,7 +10563,8 @@ VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator)
|
|||||||
m_Id(0),
|
m_Id(0),
|
||||||
m_hMemory(VK_NULL_HANDLE),
|
m_hMemory(VK_NULL_HANDLE),
|
||||||
m_MapCount(0),
|
m_MapCount(0),
|
||||||
m_pMappedData(VMA_NULL) {}
|
m_pMappedData(VMA_NULL),
|
||||||
|
m_Handle(VMA_NULL) {}
|
||||||
|
|
||||||
VmaDeviceMemoryBlock::~VmaDeviceMemoryBlock()
|
VmaDeviceMemoryBlock::~VmaDeviceMemoryBlock()
|
||||||
{
|
{
|
||||||
@ -10677,6 +10807,14 @@ VkResult VmaDeviceMemoryBlock::BindImageMemory(
|
|||||||
VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex);
|
VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex);
|
||||||
return hAllocator->BindVulkanImage(m_hMemory, memoryOffset, hImage, pNext);
|
return hAllocator->BindVulkanImage(m_hMemory, memoryOffset, hImage, pNext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
VkResult VmaDeviceMemoryBlock::CreateWin32Handle(const VmaAllocator hAllocator, decltype(&vkGetMemoryWin32HandleKHR) pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
|
||||||
|
{
|
||||||
|
VMA_ASSERT(pHandle);
|
||||||
|
return m_Handle.GetHandle(hAllocator->m_hDevice, m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
|
||||||
|
}
|
||||||
|
#endif // VMA_EXTERNAL_MEMORY_WIN32
|
||||||
#endif // _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS
|
#endif // _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS
|
||||||
|
|
||||||
#ifndef _VMA_ALLOCATION_T_FUNCTIONS
|
#ifndef _VMA_ALLOCATION_T_FUNCTIONS
|
||||||
@ -10977,6 +11115,23 @@ void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const
|
|||||||
json.WriteString(m_pName);
|
json.WriteString(m_pName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
|
||||||
|
{
|
||||||
|
// Where do we get this function from?
|
||||||
|
auto pvkGetMemoryWin32HandleKHR = hAllocator->GetVulkanFunctions().vkGetMemoryWin32HandleKHR;
|
||||||
|
switch (m_Type)
|
||||||
|
{
|
||||||
|
case ALLOCATION_TYPE_BLOCK:
|
||||||
|
return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, pvkGetMemoryWin32HandleKHR, hTargetProcess, pHandle);
|
||||||
|
case ALLOCATION_TYPE_DEDICATED:
|
||||||
|
return m_DedicatedAllocation.m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
|
||||||
|
default:
|
||||||
|
VMA_ASSERT(0);
|
||||||
|
return VK_ERROR_FEATURE_NOT_PRESENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // VMA_EXTERNAL_MEMORY_WIN32
|
||||||
#endif // VMA_STATS_STRING_ENABLED
|
#endif // VMA_STATS_STRING_ENABLED
|
||||||
|
|
||||||
void VmaAllocation_T::FreeName(VmaAllocator hAllocator)
|
void VmaAllocation_T::FreeName(VmaAllocator hAllocator)
|
||||||
@ -12707,6 +12862,7 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
|
|||||||
m_UseExtMemoryPriority((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT) != 0),
|
m_UseExtMemoryPriority((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT) != 0),
|
||||||
m_UseKhrMaintenance4((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT) != 0),
|
m_UseKhrMaintenance4((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE4_BIT) != 0),
|
||||||
m_UseKhrMaintenance5((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT) != 0),
|
m_UseKhrMaintenance5((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT) != 0),
|
||||||
|
m_UseKhrExternalMemoryWin32((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT) != 0),
|
||||||
m_hDevice(pCreateInfo->device),
|
m_hDevice(pCreateInfo->device),
|
||||||
m_hInstance(pCreateInfo->instance),
|
m_hInstance(pCreateInfo->instance),
|
||||||
m_AllocationCallbacksSpecified(pCreateInfo->pAllocationCallbacks != VMA_NULL),
|
m_AllocationCallbacksSpecified(pCreateInfo->pAllocationCallbacks != VMA_NULL),
|
||||||
@ -12798,6 +12954,19 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
|
|||||||
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
|
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if !(VMA_KHR_MAINTENANCE5)
|
||||||
|
if(m_UseKhrMaintenance5)
|
||||||
|
{
|
||||||
|
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !(VMA_EXTERNAL_MEMORY_WIN32)
|
||||||
|
if(m_UseKhrExternalMemoryWin32)
|
||||||
|
{
|
||||||
|
VMA_ASSERT(0 && "VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT is set but required extension is not available in your Vulkan header or its support in VMA has been disabled by a preprocessor macro.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
memset(&m_DeviceMemoryCallbacks, 0 ,sizeof(m_DeviceMemoryCallbacks));
|
memset(&m_DeviceMemoryCallbacks, 0 ,sizeof(m_DeviceMemoryCallbacks));
|
||||||
memset(&m_PhysicalDeviceProperties, 0, sizeof(m_PhysicalDeviceProperties));
|
memset(&m_PhysicalDeviceProperties, 0, sizeof(m_PhysicalDeviceProperties));
|
||||||
@ -13022,7 +13191,9 @@ void VmaAllocator_T::ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVul
|
|||||||
VMA_COPY_IF_NOT_NULL(vkGetDeviceBufferMemoryRequirements);
|
VMA_COPY_IF_NOT_NULL(vkGetDeviceBufferMemoryRequirements);
|
||||||
VMA_COPY_IF_NOT_NULL(vkGetDeviceImageMemoryRequirements);
|
VMA_COPY_IF_NOT_NULL(vkGetDeviceImageMemoryRequirements);
|
||||||
#endif
|
#endif
|
||||||
|
#if VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
VMA_COPY_IF_NOT_NULL(vkGetMemoryWin32HandleKHR);
|
||||||
|
#endif
|
||||||
#undef VMA_COPY_IF_NOT_NULL
|
#undef VMA_COPY_IF_NOT_NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13124,7 +13295,12 @@ void VmaAllocator_T::ImportVulkanFunctions_Dynamic()
|
|||||||
VMA_FETCH_DEVICE_FUNC(vkGetDeviceImageMemoryRequirements, PFN_vkGetDeviceImageMemoryRequirementsKHR, "vkGetDeviceImageMemoryRequirementsKHR");
|
VMA_FETCH_DEVICE_FUNC(vkGetDeviceImageMemoryRequirements, PFN_vkGetDeviceImageMemoryRequirementsKHR, "vkGetDeviceImageMemoryRequirementsKHR");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
if (m_UseKhrExternalMemoryWin32)
|
||||||
|
{
|
||||||
|
VMA_FETCH_DEVICE_FUNC(vkGetMemoryWin32HandleKHR, PFN_vkGetMemoryWin32HandleKHR, "vkGetMemoryWin32HandleKHR");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#undef VMA_FETCH_DEVICE_FUNC
|
#undef VMA_FETCH_DEVICE_FUNC
|
||||||
#undef VMA_FETCH_INSTANCE_FUNC
|
#undef VMA_FETCH_INSTANCE_FUNC
|
||||||
}
|
}
|
||||||
@ -13173,6 +13349,12 @@ void VmaAllocator_T::ValidateVulkanFunctions()
|
|||||||
VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR != VMA_NULL);
|
VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR != VMA_NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
if (m_UseKhrExternalMemoryWin32)
|
||||||
|
{
|
||||||
|
VMA_ASSERT(m_VulkanFunctions.vkGetMemoryWin32HandleKHR != VMA_NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Not validating these due to suspected driver bugs with these function
|
// Not validating these due to suspected driver bugs with these function
|
||||||
// pointers being null despite correct extension or Vulkan version is enabled.
|
// pointers being null despite correct extension or Vulkan version is enabled.
|
||||||
@ -16429,6 +16611,15 @@ VMA_CALL_PRE void VMA_CALL_POST vmaFreeVirtualBlockStatsString(VmaVirtualBlock V
|
|||||||
VmaFreeString(virtualBlock->GetAllocationCallbacks(), pStatsString);
|
VmaFreeString(virtualBlock->GetAllocationCallbacks(), pStatsString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
VMA_CALL_PRE VkResult VMA_CALL_POST vmaGetMemoryWin32HandleKHR(VmaAllocator VMA_NOT_NULL allocator,
|
||||||
|
VmaAllocation VMA_NOT_NULL allocation, HANDLE hTargetProcess, HANDLE* VMA_NOT_NULL pHandle)
|
||||||
|
{
|
||||||
|
VMA_ASSERT(allocator && allocation);
|
||||||
|
VMA_DEBUG_GLOBAL_MUTEX_LOCK;
|
||||||
|
return allocation->GetWin32Handle(allocator, hTargetProcess, pHandle);
|
||||||
|
}
|
||||||
|
#endif // VMA_EXTERNAL_MEMORY_WIN32
|
||||||
#endif // VMA_STATS_STRING_ENABLED
|
#endif // VMA_STATS_STRING_ENABLED
|
||||||
#endif // _VMA_PUBLIC_INTERFACE
|
#endif // _VMA_PUBLIC_INTERFACE
|
||||||
#endif // VMA_IMPLEMENTATION
|
#endif // VMA_IMPLEMENTATION
|
||||||
|
@ -17,14 +17,22 @@ foreach(SHADER ${SHADERS})
|
|||||||
get_filename_component(FILE_NAME ${SHADER} NAME)
|
get_filename_component(FILE_NAME ${SHADER} NAME)
|
||||||
|
|
||||||
# Put the .spv files into the bin folder
|
# Put the .spv files into the bin folder
|
||||||
|
set(SPIRV_BIN ${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}.spv)
|
||||||
set(SPIRV ${PROJECT_SOURCE_DIR}/bin/${FILE_NAME}.spv)
|
set(SPIRV ${PROJECT_SOURCE_DIR}/bin/${FILE_NAME}.spv)
|
||||||
|
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${SPIRV}
|
OUTPUT ${SPIRV}
|
||||||
# Use the same file name and append .spv to the compiled shader
|
# Use the same file name and append .spv to the compiled shader
|
||||||
COMMAND ${GLSL_VALIDATOR} -V ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER} -o ${SPIRV}
|
COMMAND ${GLSL_VALIDATOR} -V ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER} -o ${SPIRV}
|
||||||
DEPENDS ${SHADER}
|
DEPENDS ${SHADER}
|
||||||
)
|
)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${SPIRV_BIN}
|
||||||
|
# Use the same file name and append .spv to the compiled shader
|
||||||
|
COMMAND ${GLSL_VALIDATOR} -V ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER} -o ${SPIRV_BIN}
|
||||||
|
DEPENDS ${SHADER}
|
||||||
|
)
|
||||||
|
|
||||||
list(APPEND SPIRV_FILES ${SPIRV})
|
list(APPEND SPIRV_FILES ${SPIRV})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
@ -8253,6 +8253,71 @@ static void TestMappingHysteresis()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void TestWin32Handles()
|
||||||
|
{
|
||||||
|
#if VMA_EXTERNAL_MEMORY_WIN32
|
||||||
|
wprintf(L"Test Win32 handles\n");
|
||||||
|
constexpr static VkExportMemoryAllocateInfoKHR exportInfo{
|
||||||
|
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
|
||||||
|
nullptr,
|
||||||
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
|
||||||
|
};
|
||||||
|
constexpr static VkExternalMemoryBufferCreateInfoKHR externalInfo{
|
||||||
|
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
|
||||||
|
nullptr,
|
||||||
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
|
||||||
|
};
|
||||||
|
|
||||||
|
VkBufferCreateInfo sampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||||
|
sampleBufCreateInfo.size = 0x1000; // Doesn't matter.
|
||||||
|
sampleBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
sampleBufCreateInfo.pNext = &externalInfo;
|
||||||
|
|
||||||
|
VmaAllocationCreateInfo sampleAllocCreateInfo = {};
|
||||||
|
sampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
|
||||||
|
sampleAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
|
||||||
|
|
||||||
|
uint32_t memTypeIndex;
|
||||||
|
TEST(vmaFindMemoryTypeIndexForBufferInfo(g_hAllocator,
|
||||||
|
&sampleBufCreateInfo, &sampleAllocCreateInfo, &memTypeIndex) == VK_SUCCESS);
|
||||||
|
// Check res...
|
||||||
|
|
||||||
|
|
||||||
|
// Create a pool that can have at most 2 blocks, 128 MiB each.
|
||||||
|
VmaPoolCreateInfo poolCreateInfo = {};
|
||||||
|
poolCreateInfo.memoryTypeIndex = memTypeIndex;
|
||||||
|
poolCreateInfo.blockSize = 128ull * 1024 * 1024;
|
||||||
|
poolCreateInfo.maxBlockCount = 2;
|
||||||
|
poolCreateInfo.pMemoryAllocateNext = (void*)&exportInfo;
|
||||||
|
|
||||||
|
|
||||||
|
VmaPool pool;
|
||||||
|
TEST(vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool) == VK_SUCCESS);
|
||||||
|
|
||||||
|
|
||||||
|
sampleAllocCreateInfo.pool = pool;
|
||||||
|
|
||||||
|
VkBuffer buf;
|
||||||
|
VmaAllocation alloc;
|
||||||
|
VmaAllocationInfo allocInfo;
|
||||||
|
TEST(vmaCreateBuffer(g_hAllocator, &sampleBufCreateInfo, &sampleAllocCreateInfo, &buf, &alloc, &allocInfo) == VK_SUCCESS);
|
||||||
|
HANDLE handle;
|
||||||
|
HANDLE handle2;
|
||||||
|
TEST(vmaGetMemoryWin32HandleKHR(g_hAllocator, alloc, nullptr, &handle) == VK_SUCCESS);
|
||||||
|
TEST(handle != nullptr);
|
||||||
|
TEST(vmaGetMemoryWin32HandleKHR(g_hAllocator, alloc, nullptr, &handle2) == VK_SUCCESS);
|
||||||
|
TEST(handle2 != nullptr);
|
||||||
|
TEST(handle2 != handle);
|
||||||
|
|
||||||
|
vmaDestroyBuffer(g_hAllocator, buf, alloc);
|
||||||
|
TEST(CloseHandle(handle));
|
||||||
|
TEST(CloseHandle(handle2));
|
||||||
|
|
||||||
|
vmaDestroyPool(g_hAllocator, pool);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void Test()
|
void Test()
|
||||||
{
|
{
|
||||||
wprintf(L"TESTING:\n");
|
wprintf(L"TESTING:\n");
|
||||||
@ -8295,6 +8360,7 @@ void Test()
|
|||||||
TestMappingHysteresis();
|
TestMappingHysteresis();
|
||||||
TestDeviceLocalMapped();
|
TestDeviceLocalMapped();
|
||||||
TestMaintenance5();
|
TestMaintenance5();
|
||||||
|
TestWin32Handles();
|
||||||
TestMappingMultithreaded();
|
TestMappingMultithreaded();
|
||||||
TestLinearAllocator();
|
TestLinearAllocator();
|
||||||
ManuallyTestLinearAllocator();
|
ManuallyTestLinearAllocator();
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#pragma comment(lib, "shlwapi.lib")
|
#pragma comment(lib, "shlwapi.lib")
|
||||||
|
|
||||||
static const char* const SHADER_PATH1 = "./";
|
static const char* const SHADER_PATH1 = "./Shaders/";
|
||||||
static const char* const SHADER_PATH2 = "../bin/";
|
static const char* const SHADER_PATH2 = "../bin/";
|
||||||
static const wchar_t* const WINDOW_CLASS_NAME = L"VULKAN_MEMORY_ALLOCATOR_SAMPLE";
|
static const wchar_t* const WINDOW_CLASS_NAME = L"VULKAN_MEMORY_ALLOCATOR_SAMPLE";
|
||||||
static const char* const VALIDATION_LAYER_NAME = "VK_LAYER_KHRONOS_validation";
|
static const char* const VALIDATION_LAYER_NAME = "VK_LAYER_KHRONOS_validation";
|
||||||
@ -69,6 +69,7 @@ bool VK_KHR_buffer_device_address_enabled = false;
|
|||||||
bool VK_EXT_memory_priority_enabled = false;
|
bool VK_EXT_memory_priority_enabled = false;
|
||||||
bool VK_EXT_debug_utils_enabled = false;
|
bool VK_EXT_debug_utils_enabled = false;
|
||||||
bool VK_KHR_maintenance5_enabled = false;
|
bool VK_KHR_maintenance5_enabled = false;
|
||||||
|
bool VK_KHR_external_memory_win32_enabled = false;
|
||||||
bool g_SparseBindingEnabled = false;
|
bool g_SparseBindingEnabled = false;
|
||||||
|
|
||||||
// # Pointers to functions from extensions
|
// # Pointers to functions from extensions
|
||||||
@ -1449,6 +1450,7 @@ static void PrintEnabledFeatures()
|
|||||||
}
|
}
|
||||||
wprintf(L"VK_EXT_memory_priority: %d\n", VK_EXT_memory_priority_enabled ? 1 : 0);
|
wprintf(L"VK_EXT_memory_priority: %d\n", VK_EXT_memory_priority_enabled ? 1 : 0);
|
||||||
wprintf(L"VK_KHR_maintenance5: %d\n", VK_KHR_maintenance5_enabled? 1 : 0);
|
wprintf(L"VK_KHR_maintenance5: %d\n", VK_KHR_maintenance5_enabled? 1 : 0);
|
||||||
|
wprintf(L"VK_KHR_external_memory_win32: %d\n", VK_KHR_external_memory_win32_enabled ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAllocatorCreateInfo(VmaAllocatorCreateInfo& outInfo)
|
void SetAllocatorCreateInfo(VmaAllocatorCreateInfo& outInfo)
|
||||||
@ -1494,6 +1496,11 @@ void SetAllocatorCreateInfo(VmaAllocatorCreateInfo& outInfo)
|
|||||||
outInfo.flags |= VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT;
|
outInfo.flags |= VMA_ALLOCATOR_CREATE_KHR_MAINTENANCE5_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(VK_KHR_external_memory_win32_enabled)
|
||||||
|
{
|
||||||
|
outInfo.flags |= VMA_ALLOCATOR_CREATE_KHR_EXTERNAL_MEMORY_WIN32_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
if(USE_CUSTOM_CPU_ALLOCATION_CALLBACKS)
|
if(USE_CUSTOM_CPU_ALLOCATION_CALLBACKS)
|
||||||
{
|
{
|
||||||
outInfo.pAllocationCallbacks = &g_CpuAllocationCallbacks;
|
outInfo.pAllocationCallbacks = &g_CpuAllocationCallbacks;
|
||||||
@ -1876,6 +1883,8 @@ static void InitializeApplication()
|
|||||||
VK_EXT_memory_priority_enabled = true;
|
VK_EXT_memory_priority_enabled = true;
|
||||||
else if(strcmp(physicalDeviceExtensionProperties[i].extensionName, VK_KHR_MAINTENANCE_5_EXTENSION_NAME) == 0)
|
else if(strcmp(physicalDeviceExtensionProperties[i].extensionName, VK_KHR_MAINTENANCE_5_EXTENSION_NAME) == 0)
|
||||||
VK_KHR_maintenance5_enabled = true;
|
VK_KHR_maintenance5_enabled = true;
|
||||||
|
else if (strcmp(physicalDeviceExtensionProperties[i].extensionName, VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME) == 0)
|
||||||
|
VK_KHR_external_memory_win32_enabled = VMA_DYNAMIC_VULKAN_FUNCTIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetVulkanApiVersion() >= VK_API_VERSION_1_2)
|
if(GetVulkanApiVersion() >= VK_API_VERSION_1_2)
|
||||||
@ -2036,6 +2045,8 @@ static void InitializeApplication()
|
|||||||
enabledDeviceExtensions.push_back(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME);
|
enabledDeviceExtensions.push_back(VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME);
|
||||||
if(VK_KHR_maintenance5_enabled)
|
if(VK_KHR_maintenance5_enabled)
|
||||||
enabledDeviceExtensions.push_back(VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
|
enabledDeviceExtensions.push_back(VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
|
||||||
|
if (VK_KHR_external_memory_win32_enabled)
|
||||||
|
enabledDeviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME);
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures2 deviceFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 };
|
VkPhysicalDeviceFeatures2 deviceFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 };
|
||||||
deviceFeatures.features.samplerAnisotropy = VK_TRUE;
|
deviceFeatures.features.samplerAnisotropy = VK_TRUE;
|
||||||
|
Loading…
Reference in New Issue
Block a user