diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 0eead859..6cb74423 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -91,10 +91,8 @@ namespace dxvk { float priority = isGpuWritable ? 1.0f : 0.5f; // Ask driver whether we should be using a dedicated allocation - bool useDedicated = dedicatedRequirements.prefersDedicatedAllocation; - handle.memory = m_memAlloc->alloc(&memReq.memoryRequirements, - useDedicated ? &dedMemoryAllocInfo : nullptr, m_memFlags, priority); + dedicatedRequirements, dedMemoryAllocInfo, m_memFlags, priority); if (vkd->vkBindBufferMemory(vkd->device(), handle.buffer, handle.memory.memory(), handle.memory.offset()) != VK_SUCCESS) diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index ceb6b0ce..5a682c5b 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -98,10 +98,8 @@ namespace dxvk { float priority = isGpuWritable ? 1.0f : 0.5f; // Ask driver whether we should be using a dedicated allocation - bool useDedicated = dedicatedRequirements.prefersDedicatedAllocation; - m_memory = memAlloc.alloc(&memReq.memoryRequirements, - useDedicated ? &dedMemoryAllocInfo : nullptr, memFlags, priority); + dedicatedRequirements, dedMemoryAllocInfo, memFlags, priority); // Try to bind the allocated memory slice to the image if (m_vkd->vkBindImageMemory(m_vkd->device(), diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 7c486df3..f9a76c25 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -181,18 +181,28 @@ namespace dxvk { DxvkMemory DxvkMemoryAllocator::alloc( const VkMemoryRequirements* req, - const VkMemoryDedicatedAllocateInfoKHR* dedAllocInfo, + const VkMemoryDedicatedRequirements& dedAllocReq, + const VkMemoryDedicatedAllocateInfoKHR& dedAllocInfo, VkMemoryPropertyFlags flags, float priority) { std::lock_guard lock(m_mutex); + // Try to allocate from a memory type which supports the given flags exactly + auto dedAllocPtr = dedAllocReq.prefersDedicatedAllocation ? &dedAllocInfo : nullptr; + DxvkMemory result = this->tryAlloc(req, dedAllocPtr, flags, priority); + + // If the first attempt failed, try ignoring the dedicated allocation + if (!result && dedAllocPtr && !dedAllocReq.requiresDedicatedAllocation) { + result = this->tryAlloc(req, nullptr, flags, priority); + dedAllocPtr = nullptr; + } + + // If that still didn't work, probe slower memory types as well VkMemoryPropertyFlags optFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; - DxvkMemory result = this->tryAlloc(req, dedAllocInfo, flags, priority); - if (!result && (flags & optFlags)) - result = this->tryAlloc(req, dedAllocInfo, flags & ~optFlags, priority); + result = this->tryAlloc(req, dedAllocPtr, flags & ~optFlags, priority); if (!result) { Logger::err(str::format( diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index 5dfbf996..2c59ce98 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -239,6 +239,7 @@ namespace dxvk { * \brief Allocates device memory * * \param [in] req Memory requirements + * \param [in] dedAllocReq Dedicated allocation requirements * \param [in] dedAllocInfo Dedicated allocation info * \param [in] flags Memory type flags * \param [in] priority Device-local memory priority @@ -246,7 +247,8 @@ namespace dxvk { */ DxvkMemory alloc( const VkMemoryRequirements* req, - const VkMemoryDedicatedAllocateInfoKHR* dedAllocInfo, + const VkMemoryDedicatedRequirements& dedAllocReq, + const VkMemoryDedicatedAllocateInfoKHR& dedAllocInfo, VkMemoryPropertyFlags flags, float priority);