vkd3d: Setup resizable bar budget.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
cec741706d
commit
710fa98918
|
@ -201,7 +201,12 @@ static HRESULT vkd3d_try_allocate_device_memory(struct d3d12_device *device,
|
|||
WARN("Attempting to allocate from memory type %u, but exceeding fixed budget: %"PRIu64" + %"PRIu64" > %"PRIu64".\n",
|
||||
type_index, *type_current, size, *type_budget);
|
||||
pthread_mutex_unlock(&memory_info->budget_lock);
|
||||
continue;
|
||||
|
||||
/* If we're out of DEVICE budget, don't try other types. */
|
||||
if (type_flags & optional_flags)
|
||||
return E_OUTOFMEMORY;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5983,6 +5983,60 @@ static uint32_t vkd3d_memory_info_find_global_mask(const struct vkd3d_memory_top
|
|||
return ~mask;
|
||||
}
|
||||
|
||||
static void vkd3d_memory_info_init_budgets(struct vkd3d_memory_info *info,
|
||||
const struct vkd3d_memory_topology *topology,
|
||||
struct d3d12_device *device)
|
||||
{
|
||||
bool heap_index_needs_budget;
|
||||
VkMemoryPropertyFlags flags;
|
||||
uint32_t heap_index;
|
||||
uint32_t i;
|
||||
|
||||
info->budget_sensitive_mask = 0;
|
||||
|
||||
/* Nothing to do if we don't have separate heaps. */
|
||||
if (topology->device_local_heap_count == 0 || topology->host_only_heap_count == 0)
|
||||
return;
|
||||
if (!topology->exists_device_only_type || !topology->exists_host_only_type)
|
||||
return;
|
||||
|
||||
for (i = 0; i < device->memory_properties.memoryTypeCount; i++)
|
||||
{
|
||||
const VkMemoryPropertyFlags pinned_mask = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
||||
flags = device->memory_properties.memoryTypes[i].propertyFlags;
|
||||
heap_index = device->memory_properties.memoryTypes[i].heapIndex;
|
||||
|
||||
/* Work around a driver workaround on NV drivers which targets certain
|
||||
* older DXVK versions (use of DXVK DXGI is likely what impacts us here),
|
||||
* since we don't see this behavior in native builds.
|
||||
* Even with resizable BAR, we might observe two different heaps,
|
||||
* with very slightly different heap sizes.
|
||||
* It's straight forward to be universally robust against these kinds of scenarios,
|
||||
* so just go for that.
|
||||
* If we're within 75% of the actual VRAM size, assume we've hit this scenario.
|
||||
* This should exclude small BAR from explicit budget, since that's just 256 MB. */
|
||||
heap_index_needs_budget =
|
||||
(device->memory_properties.memoryHeaps[heap_index].size >
|
||||
3 * device->memory_properties.memoryHeaps[topology->largest_device_local_heap_index].size / 4) &&
|
||||
(device->memory_properties.memoryHeaps[heap_index].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT);
|
||||
|
||||
if ((flags & pinned_mask) == pinned_mask && heap_index_needs_budget)
|
||||
{
|
||||
/* Limit this type. This limit is a pure heuristic and we might need further tuning here.
|
||||
* If there's a separate heap type for PCI-e BAR,
|
||||
* don't bother limiting it since the size is already going to be tiny.
|
||||
* The driver will limit us naturally. */
|
||||
info->budget_sensitive_mask |= 1u << i;
|
||||
info->type_budget[i] = device->memory_properties.memoryHeaps[heap_index].size / 16;
|
||||
info->type_current[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
INFO("Applying resizable BAR budget to memory types: 0x%x.\n", info->budget_sensitive_mask);
|
||||
}
|
||||
|
||||
void vkd3d_memory_info_cleanup(struct vkd3d_memory_info *info,
|
||||
struct d3d12_device *device)
|
||||
{
|
||||
|
@ -6010,6 +6064,7 @@ HRESULT vkd3d_memory_info_init(struct vkd3d_memory_info *info,
|
|||
|
||||
vkd3d_memory_info_get_topology(&topology, device);
|
||||
info->global_mask = vkd3d_memory_info_find_global_mask(&topology, device);
|
||||
vkd3d_memory_info_init_budgets(info, &topology, device);
|
||||
|
||||
if (pthread_mutex_init(&info->budget_lock, NULL) != 0)
|
||||
return E_OUTOFMEMORY;
|
||||
|
|
Loading…
Reference in New Issue