extra safety

This commit is contained in:
Ilya Doroshenko 2024-08-26 14:11:41 +02:00
parent 8c665c4c95
commit c41e3fb5a6

View File

@ -6093,7 +6093,7 @@ public:
public: public:
// Strengthened // Strengthened
VkResult GetHandle(VkDevice device, VkDeviceMemory memory, decltype(&vkGetMemoryWin32HandleKHR) pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, HANDLE* pHandle) noexcept VkResult GetHandle(VkDevice device, VkDeviceMemory memory, decltype(&vkGetMemoryWin32HandleKHR) pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, bool useMutex, HANDLE* pHandle) noexcept
{ {
*pHandle = VMA_NULL; *pHandle = VMA_NULL;
// We only care about atomicity of handle retrieval, not about memory order. // We only care about atomicity of handle retrieval, not about memory order.
@ -6108,27 +6108,17 @@ public:
HANDLE hCreatedHandle = VMA_NULL; HANDLE hCreatedHandle = VMA_NULL;
VkResult res = VK_SUCCESS;
// If failed, try to create it. // If failed, try to create it.
VkResult res = Create(device, memory, pvkGetMemoryWin32HandleKHR, &hCreatedHandle);
if (res == VK_SUCCESS)
{ {
// Successfully created handle, try to set it. VmaMutexLockWrite lock(m_Mutex, useMutex);
if (!m_hHandle.compare_exchange_strong(handle, hCreatedHandle, std::memory_order_relaxed)) if (m_hHandle.load(std::memory_order_relaxed) == VMA_NULL)
{ {
// AMD workaround res = Create(device, memory, pvkGetMemoryWin32HandleKHR, &hCreatedHandle);
if (hCreatedHandle != m_hHandle.load(std::memory_order_relaxed)) m_hHandle.store(hCreatedHandle, std::memory_order_relaxed);
{
::CloseHandle(hCreatedHandle);
} }
} }
}
// If somehow it was set in the meantime, return it.
if (m_hHandle.load(std::memory_order_relaxed))
{
*pHandle = Duplicate(hTargetProcess); *pHandle = Duplicate(hTargetProcess);
return VK_SUCCESS;
}
return res; return res;
} }
@ -6164,6 +6154,7 @@ private:
} }
private: private:
std::atomic<HANDLE> m_hHandle; std::atomic<HANDLE> m_hHandle;
VMA_RW_MUTEX m_Mutex; // Protects access m_Handle
}; };
#else #else
class VmaWin32Handle class VmaWin32Handle
@ -10802,7 +10793,7 @@ VkResult VmaDeviceMemoryBlock::BindImageMemory(
VkResult VmaDeviceMemoryBlock::CreateWin32Handle(const VmaAllocator hAllocator, decltype(&vkGetMemoryWin32HandleKHR) pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, HANDLE* pHandle) noexcept VkResult VmaDeviceMemoryBlock::CreateWin32Handle(const VmaAllocator hAllocator, decltype(&vkGetMemoryWin32HandleKHR) pvkGetMemoryWin32HandleKHR, HANDLE hTargetProcess, HANDLE* pHandle) noexcept
{ {
VMA_ASSERT(pHandle); VMA_ASSERT(pHandle);
return m_Handle.GetHandle(hAllocator->m_hDevice, m_hMemory, &vkGetMemoryWin32HandleKHR, hTargetProcess, pHandle); return m_Handle.GetHandle(hAllocator->m_hDevice, m_hMemory, &vkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
} }
#endif // VK_USE_PLATFORM_WIN32_KHR #endif // VK_USE_PLATFORM_WIN32_KHR
#endif // _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS #endif // _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS
@ -11115,7 +11106,7 @@ VkResult VmaAllocation_T::GetWin32Handle(VmaAllocator hAllocator, HANDLE hTarget
case ALLOCATION_TYPE_BLOCK: case ALLOCATION_TYPE_BLOCK:
return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, pvkGetMemoryWin32HandleKHR, hTargetProcess, pHandle); return m_BlockAllocation.m_Block->CreateWin32Handle(hAllocator, pvkGetMemoryWin32HandleKHR, hTargetProcess, pHandle);
case ALLOCATION_TYPE_DEDICATED: case ALLOCATION_TYPE_DEDICATED:
return m_DedicatedAllocation.m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, pHandle); return m_DedicatedAllocation.m_Handle.GetHandle(hAllocator->m_hDevice, m_DedicatedAllocation.m_hMemory, pvkGetMemoryWin32HandleKHR, hTargetProcess, hAllocator->m_UseMutex, pHandle);
default: default:
VMA_ASSERT(0); VMA_ASSERT(0);
return VK_ERROR_FEATURE_NOT_PRESENT; return VK_ERROR_FEATURE_NOT_PRESENT;