1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-29 19:24:10 +01:00

[dxvk] Do not map allocations that don't need a HOST_VISIBLE memory type

Should reduce the amount of virtual memory used on systems without
dedicated VRAM. Refs #640.
This commit is contained in:
Philip Rebohle 2018-09-17 09:08:00 +02:00
parent 19408f0ebe
commit eac86fab15
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 31 additions and 14 deletions

View File

@ -72,7 +72,15 @@ namespace dxvk {
} }
DxvkMemory DxvkMemoryChunk::alloc(VkDeviceSize size, VkDeviceSize align) { DxvkMemory DxvkMemoryChunk::alloc(
VkMemoryPropertyFlags flags,
VkDeviceSize size,
VkDeviceSize align) {
// Property flags must be compatible. This could
// be refined a bit in the future if necessary.
if (m_memory.memFlags != flags)
return DxvkMemory();
// If the chunk is full, return // If the chunk is full, return
if (m_freeList.size() == 0) if (m_freeList.size() == 0)
return DxvkMemory(); return DxvkMemory();
@ -219,7 +227,7 @@ namespace dxvk {
if (supported && adequate) { if (supported && adequate) {
result = this->tryAllocFromType(&m_memTypes[i], result = this->tryAllocFromType(&m_memTypes[i],
req->size, req->alignment, dedAllocInfo); flags, req->size, req->alignment, dedAllocInfo);
} }
} }
@ -229,29 +237,31 @@ namespace dxvk {
DxvkMemory DxvkMemoryAllocator::tryAllocFromType( DxvkMemory DxvkMemoryAllocator::tryAllocFromType(
DxvkMemoryType* type, DxvkMemoryType* type,
VkMemoryPropertyFlags flags,
VkDeviceSize size, VkDeviceSize size,
VkDeviceSize align, VkDeviceSize align,
const VkMemoryDedicatedAllocateInfoKHR* dedAllocInfo) { const VkMemoryDedicatedAllocateInfoKHR* dedAllocInfo) {
DxvkMemory memory; DxvkMemory memory;
if ((size >= type->heap->chunkSize / 4) || dedAllocInfo) { if ((size >= type->heap->chunkSize / 4) || dedAllocInfo) {
DxvkDeviceMemory devMem = this->tryAllocDeviceMemory(type, size, dedAllocInfo); DxvkDeviceMemory devMem = this->tryAllocDeviceMemory(
type, flags, size, dedAllocInfo);
if (devMem.memHandle != VK_NULL_HANDLE) if (devMem.memHandle != VK_NULL_HANDLE)
memory = DxvkMemory(this, nullptr, type, devMem.memHandle, 0, size, devMem.memPointer); memory = DxvkMemory(this, nullptr, type, devMem.memHandle, 0, size, devMem.memPointer);
} else { } else {
for (uint32_t i = 0; i < type->chunks.size() && !memory; i++) for (uint32_t i = 0; i < type->chunks.size() && !memory; i++)
memory = type->chunks[i]->alloc(size, align); memory = type->chunks[i]->alloc(flags, size, align);
if (!memory) { if (!memory) {
DxvkDeviceMemory devMem = tryAllocDeviceMemory( DxvkDeviceMemory devMem = tryAllocDeviceMemory(
type, type->heap->chunkSize, nullptr); type, flags, type->heap->chunkSize, nullptr);
if (devMem.memHandle == VK_NULL_HANDLE) if (devMem.memHandle == VK_NULL_HANDLE)
return DxvkMemory(); return DxvkMemory();
Rc<DxvkMemoryChunk> chunk = new DxvkMemoryChunk(this, type, devMem); Rc<DxvkMemoryChunk> chunk = new DxvkMemoryChunk(this, type, devMem);
memory = chunk->alloc(size, align); memory = chunk->alloc(flags, size, align);
type->chunks.push_back(std::move(chunk)); type->chunks.push_back(std::move(chunk));
} }
@ -266,6 +276,7 @@ namespace dxvk {
DxvkDeviceMemory DxvkMemoryAllocator::tryAllocDeviceMemory( DxvkDeviceMemory DxvkMemoryAllocator::tryAllocDeviceMemory(
DxvkMemoryType* type, DxvkMemoryType* type,
VkMemoryPropertyFlags flags,
VkDeviceSize size, VkDeviceSize size,
const VkMemoryDedicatedAllocateInfoKHR* dedAllocInfo) { const VkMemoryDedicatedAllocateInfoKHR* dedAllocInfo) {
if ((type->memType.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) if ((type->memType.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
@ -274,7 +285,8 @@ namespace dxvk {
return DxvkDeviceMemory(); return DxvkDeviceMemory();
DxvkDeviceMemory result; DxvkDeviceMemory result;
result.memSize = size; result.memSize = size;
result.memFlags = flags;
VkMemoryAllocateInfo info; VkMemoryAllocateInfo info;
info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
@ -285,7 +297,7 @@ namespace dxvk {
if (m_vkd->vkAllocateMemory(m_vkd->device(), &info, nullptr, &result.memHandle) != VK_SUCCESS) if (m_vkd->vkAllocateMemory(m_vkd->device(), &info, nullptr, &result.memHandle) != VK_SUCCESS)
return DxvkDeviceMemory(); return DxvkDeviceMemory();
if (type->memType.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
VkResult status = m_vkd->vkMapMemory(m_vkd->device(), result.memHandle, 0, VK_WHOLE_SIZE, 0, &result.memPointer); VkResult status = m_vkd->vkMapMemory(m_vkd->device(), result.memHandle, 0, VK_WHOLE_SIZE, 0, &result.memPointer);
if (status != VK_SUCCESS) { if (status != VK_SUCCESS) {

View File

@ -27,9 +27,10 @@ namespace dxvk {
* be persistently mapped. * be persistently mapped.
*/ */
struct DxvkDeviceMemory { struct DxvkDeviceMemory {
VkDeviceMemory memHandle = VK_NULL_HANDLE; VkDeviceMemory memHandle = VK_NULL_HANDLE;
void* memPointer = nullptr; void* memPointer = nullptr;
VkDeviceSize memSize = 0; VkDeviceSize memSize = 0;
VkMemoryPropertyFlags memFlags = 0;
}; };
@ -159,19 +160,21 @@ namespace dxvk {
DxvkDeviceMemory memory); DxvkDeviceMemory memory);
~DxvkMemoryChunk(); ~DxvkMemoryChunk();
/** /**
* \brief Allocates memory from the chunk * \brief Allocates memory from the chunk
* *
* On failure, this returns a slice with * On failure, this returns a slice with
* \c VK_NULL_HANDLE as the memory handle. * \c VK_NULL_HANDLE as the memory handle.
* \param [in] flags Requested memory flags
* \param [in] size Number of bytes to allocate * \param [in] size Number of bytes to allocate
* \param [in] align Required alignment * \param [in] align Required alignment
* \returns The allocated memory slice * \returns The allocated memory slice
*/ */
DxvkMemory alloc( DxvkMemory alloc(
VkDeviceSize size, VkMemoryPropertyFlags flags,
VkDeviceSize align); VkDeviceSize size,
VkDeviceSize align);
/** /**
* \brief Frees memory * \brief Frees memory
@ -267,12 +270,14 @@ namespace dxvk {
DxvkMemory tryAllocFromType( DxvkMemory tryAllocFromType(
DxvkMemoryType* type, DxvkMemoryType* type,
VkMemoryPropertyFlags flags,
VkDeviceSize size, VkDeviceSize size,
VkDeviceSize align, VkDeviceSize align,
const VkMemoryDedicatedAllocateInfoKHR* dedAllocInfo); const VkMemoryDedicatedAllocateInfoKHR* dedAllocInfo);
DxvkDeviceMemory tryAllocDeviceMemory( DxvkDeviceMemory tryAllocDeviceMemory(
DxvkMemoryType* type, DxvkMemoryType* type,
VkMemoryPropertyFlags flags,
VkDeviceSize size, VkDeviceSize size,
const VkMemoryDedicatedAllocateInfoKHR* dedAllocInfo); const VkMemoryDedicatedAllocateInfoKHR* dedAllocInfo);