mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 10:54:16 +01:00
[dxvk] Introduce allocation modes
Will be useful when relocating resources for defragmentation purposes.
This commit is contained in:
parent
9a8406f28a
commit
3a1de271cb
@ -183,6 +183,7 @@ namespace dxvk {
|
||||
DxvkAllocationInfo allocationInfo = { };
|
||||
allocationInfo.resourceCookie = cookie();
|
||||
allocationInfo.properties = m_properties;
|
||||
allocationInfo.mode = mode;
|
||||
|
||||
return m_allocator->createImageResource(imageInfo,
|
||||
allocationInfo, sharedMemoryInfo);
|
||||
|
@ -579,6 +579,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
|
||||
// of creating a new chunk. This way we avoid excessive fragmentation,
|
||||
// especially when a multiple such resources are created at once.
|
||||
@ -683,7 +687,8 @@ namespace dxvk {
|
||||
if (likely(allocation && allocation->m_buffer))
|
||||
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;
|
||||
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
@ -693,9 +698,21 @@ namespace dxvk {
|
||||
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
|
||||
// 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 ",
|
||||
allocation->m_type->index, " without global buffer"));
|
||||
}
|
||||
@ -730,14 +747,15 @@ namespace dxvk {
|
||||
|| (allocation->m_address & requirements.memoryRequirements.alignment))
|
||||
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;
|
||||
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
allocation = allocateMemory(requirements.memoryRequirements, fallbackInfo);
|
||||
}
|
||||
|
||||
if (!allocation) {
|
||||
if (!allocation && allocationInfo.mode.isClear()) {
|
||||
logMemoryError(requirements.memoryRequirements);
|
||||
logMemoryStats();
|
||||
}
|
||||
@ -818,7 +836,8 @@ namespace dxvk {
|
||||
|
||||
if (!(createInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
|
||||
// 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 };
|
||||
dedicatedInfo.image = image;
|
||||
|
||||
@ -828,7 +847,8 @@ namespace dxvk {
|
||||
// Only retry with a dedicated sysmem allocation if a dedicated allocation
|
||||
// is required. Otherwise, we should try to suballocate in device memory.
|
||||
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;
|
||||
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
@ -848,7 +868,8 @@ namespace dxvk {
|
||||
// Try to suballocate memory and fall back to system memory on error.
|
||||
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;
|
||||
fallbackInfo.properties &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
@ -888,8 +909,11 @@ namespace dxvk {
|
||||
if (!allocation) {
|
||||
vk->vkDestroyImage(vk->device(), image, nullptr);
|
||||
|
||||
logMemoryError(requirements.memoryRequirements);
|
||||
logMemoryStats();
|
||||
if (allocationInfo.mode.isClear()) {
|
||||
logMemoryError(requirements.memoryRequirements);
|
||||
logMemoryStats();
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
@ -935,6 +952,8 @@ namespace dxvk {
|
||||
uint64_t resourceCookie = 0u;
|
||||
/// Desired memory property flags
|
||||
VkMemoryPropertyFlags properties = 0u;
|
||||
/// Allocation mode flags
|
||||
DxvkAllocationModes mode = 0u;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user