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:
parent
19408f0ebe
commit
eac86fab15
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user