mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-24 13:54:17 +01:00
[dxvk] Introduce allocation modes
Will be useful when relocating resources for defragmentation purposes.
This commit is contained in:
parent
1525fbef03
commit
527d9c2236
@ -183,6 +183,7 @@ namespace dxvk {
|
|||||||
DxvkAllocationInfo allocationInfo = { };
|
DxvkAllocationInfo allocationInfo = { };
|
||||||
allocationInfo.resourceCookie = cookie();
|
allocationInfo.resourceCookie = cookie();
|
||||||
allocationInfo.properties = m_properties;
|
allocationInfo.properties = m_properties;
|
||||||
|
allocationInfo.mode = mode;
|
||||||
|
|
||||||
return m_allocator->createImageResource(imageInfo,
|
return m_allocator->createImageResource(imageInfo,
|
||||||
allocationInfo, sharedMemoryInfo);
|
allocationInfo, sharedMemoryInfo);
|
||||||
|
@ -581,6 +581,10 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we're not allowed to allocate device memory, move on.
|
||||||
|
if (allocationInfo.mode.test(DxvkAllocationMode::NoAllocation))
|
||||||
|
continue;
|
||||||
|
|
||||||
// If the allocation is very large, use a dedicated allocation instead
|
// If the allocation is very large, use a dedicated allocation instead
|
||||||
// of creating a new chunk. This way we avoid excessive fragmentation,
|
// of creating a new chunk. This way we avoid excessive fragmentation,
|
||||||
// especially when a multiple such resources are created at once.
|
// especially when a multiple such resources are created at once.
|
||||||
@ -685,7 +689,8 @@ namespace dxvk {
|
|||||||
if (likely(allocation && allocation->m_buffer))
|
if (likely(allocation && allocation->m_buffer))
|
||||||
return allocation;
|
return allocation;
|
||||||
|
|
||||||
if (!allocation && (allocationInfo.properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
|
if (!allocation && (allocationInfo.properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
|
||||||
|
&& !allocationInfo.mode.test(DxvkAllocationMode::NoFallback)) {
|
||||||
DxvkAllocationInfo fallbackInfo = allocationInfo;
|
DxvkAllocationInfo fallbackInfo = allocationInfo;
|
||||||
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||||
|
|
||||||
@ -695,9 +700,21 @@ namespace dxvk {
|
|||||||
return allocation;
|
return allocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we can't get an allocation for a global buffer, there's no
|
||||||
|
// real point in retrying with a dedicated buffer since the result
|
||||||
|
// will most likely be the same.
|
||||||
|
if (!allocation) {
|
||||||
|
if (allocationInfo.mode.isClear()) {
|
||||||
|
logMemoryError(memoryRequirements);
|
||||||
|
logMemoryStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// If we end up here with an allocation but no buffer, something
|
// If we end up here with an allocation but no buffer, something
|
||||||
// is weird, but we can keep the allocation around for now.
|
// is weird, but we can keep the allocation around for now.
|
||||||
if (allocation && !allocation->m_buffer) {
|
if (!allocation->m_buffer) {
|
||||||
Logger::err(str::format("Got allocation from memory type ",
|
Logger::err(str::format("Got allocation from memory type ",
|
||||||
allocation->m_type->index, " without global buffer"));
|
allocation->m_type->index, " without global buffer"));
|
||||||
}
|
}
|
||||||
@ -732,14 +749,15 @@ namespace dxvk {
|
|||||||
|| (allocation->m_address & requirements.memoryRequirements.alignment))
|
|| (allocation->m_address & requirements.memoryRequirements.alignment))
|
||||||
allocation = allocateMemory(requirements.memoryRequirements, allocationInfo);
|
allocation = allocateMemory(requirements.memoryRequirements, allocationInfo);
|
||||||
|
|
||||||
if (!allocation && (allocationInfo.properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
|
if (!allocation && (allocationInfo.properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
|
||||||
|
&& !allocationInfo.mode.test(DxvkAllocationMode::NoFallback)) {
|
||||||
DxvkAllocationInfo fallbackInfo = allocationInfo;
|
DxvkAllocationInfo fallbackInfo = allocationInfo;
|
||||||
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||||
|
|
||||||
allocation = allocateMemory(requirements.memoryRequirements, fallbackInfo);
|
allocation = allocateMemory(requirements.memoryRequirements, fallbackInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!allocation) {
|
if (!allocation && allocationInfo.mode.isClear()) {
|
||||||
logMemoryError(requirements.memoryRequirements);
|
logMemoryError(requirements.memoryRequirements);
|
||||||
logMemoryStats();
|
logMemoryStats();
|
||||||
}
|
}
|
||||||
@ -820,7 +838,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
if (!(createInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
|
if (!(createInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
|
||||||
// If a dedicated allocation is at least preferred for this resource, try this first
|
// If a dedicated allocation is at least preferred for this resource, try this first
|
||||||
if (!allocation && dedicatedRequirements.prefersDedicatedAllocation) {
|
if (!allocation && dedicatedRequirements.prefersDedicatedAllocation
|
||||||
|
&& !allocationInfo.mode.test(DxvkAllocationMode::NoAllocation)) {
|
||||||
VkMemoryDedicatedAllocateInfo dedicatedInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, next };
|
VkMemoryDedicatedAllocateInfo dedicatedInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, next };
|
||||||
dedicatedInfo.image = image;
|
dedicatedInfo.image = image;
|
||||||
|
|
||||||
@ -830,7 +849,8 @@ namespace dxvk {
|
|||||||
// Only retry with a dedicated sysmem allocation if a dedicated allocation
|
// Only retry with a dedicated sysmem allocation if a dedicated allocation
|
||||||
// is required. Otherwise, we should try to suballocate in device memory.
|
// is required. Otherwise, we should try to suballocate in device memory.
|
||||||
if (!allocation && dedicatedRequirements.requiresDedicatedAllocation
|
if (!allocation && dedicatedRequirements.requiresDedicatedAllocation
|
||||||
&& (allocationInfo.properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
|
&& !allocationInfo.mode.test(DxvkAllocationMode::NoFallback)
|
||||||
|
&& (allocationInfo.properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
|
||||||
DxvkAllocationInfo fallbackInfo = allocationInfo;
|
DxvkAllocationInfo fallbackInfo = allocationInfo;
|
||||||
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||||
|
|
||||||
@ -850,7 +870,8 @@ namespace dxvk {
|
|||||||
// Try to suballocate memory and fall back to system memory on error.
|
// Try to suballocate memory and fall back to system memory on error.
|
||||||
allocation = allocateMemory(requirements.memoryRequirements, allocationInfo);
|
allocation = allocateMemory(requirements.memoryRequirements, allocationInfo);
|
||||||
|
|
||||||
if (!allocation && (allocationInfo.properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)) {
|
if (!allocation && (allocationInfo.properties & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
|
||||||
|
&& !allocationInfo.mode.test(DxvkAllocationMode::NoFallback)) {
|
||||||
DxvkAllocationInfo fallbackInfo = allocationInfo;
|
DxvkAllocationInfo fallbackInfo = allocationInfo;
|
||||||
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||||
|
|
||||||
@ -890,8 +911,11 @@ namespace dxvk {
|
|||||||
if (!allocation) {
|
if (!allocation) {
|
||||||
vk->vkDestroyImage(vk->device(), image, nullptr);
|
vk->vkDestroyImage(vk->device(), image, nullptr);
|
||||||
|
|
||||||
logMemoryError(requirements.memoryRequirements);
|
if (allocationInfo.mode.isClear()) {
|
||||||
logMemoryStats();
|
logMemoryError(requirements.memoryRequirements);
|
||||||
|
logMemoryStats();
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -927,6 +927,23 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Allocation modes
|
||||||
|
*/
|
||||||
|
enum class DxvkAllocationMode : uint32_t {
|
||||||
|
/// If set, the allocation will fail if video memory is
|
||||||
|
/// full rather than falling back to system memory.
|
||||||
|
NoFallback = 0,
|
||||||
|
/// If set, the allocation will only succeed if it
|
||||||
|
/// can be suballocated from an existing chunk.
|
||||||
|
NoAllocation = 1,
|
||||||
|
|
||||||
|
eFlagEnum
|
||||||
|
};
|
||||||
|
|
||||||
|
using DxvkAllocationModes = Flags<DxvkAllocationMode>;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Allocation properties
|
* \brief Allocation properties
|
||||||
*/
|
*/
|
||||||
@ -935,6 +952,8 @@ namespace dxvk {
|
|||||||
uint64_t resourceCookie = 0u;
|
uint64_t resourceCookie = 0u;
|
||||||
/// Desired memory property flags
|
/// Desired memory property flags
|
||||||
VkMemoryPropertyFlags properties = 0u;
|
VkMemoryPropertyFlags properties = 0u;
|
||||||
|
/// Allocation mode flags
|
||||||
|
DxvkAllocationModes mode = 0u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user