Browse Source

[VK] VMA changes

todo
pull/323/head
wildcard 7 months ago
parent
commit
e95b908318
  1. 25
      src/video_core/vulkan_common/vulkan_memory_allocator.cpp

25
src/video_core/vulkan_common/vulkan_memory_allocator.cpp

@ -291,11 +291,17 @@ MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, M
return std::move(*commit); return std::move(*commit);
} }
// Commit has failed, allocate more memory. // Commit has failed, allocate more memory.
const u64 chunk_size = AllocationChunkSize(requirements.size);
u64 chunk_size = AllocationChunkSize(requirements.size);
if (!TryAllocMemory(flags, type_mask, chunk_size)) { if (!TryAllocMemory(flags, type_mask, chunk_size)) {
const u64 floor = std::max<u64>(requirements.size, 4ull << 20);
while (chunk_size > floor && !TryAllocMemory(flags, type_mask, (chunk_size >>= 1))) {
// keep halving until we can make progress
}
if (chunk_size <= floor && !TryAllocMemory(flags, type_mask, floor)) {
// TODO(Rodrigo): Handle out of memory situations in some way like flushing to guest memory. // TODO(Rodrigo): Handle out of memory situations in some way like flushing to guest memory.
throw vk::Exception(VK_ERROR_OUT_OF_DEVICE_MEMORY); throw vk::Exception(VK_ERROR_OUT_OF_DEVICE_MEMORY);
} }
}
// Commit again, this time it won't fail since there's a fresh allocation above. // Commit again, this time it won't fail since there's a fresh allocation above.
// If it does, there's a bug. // If it does, there's a bug.
return TryCommit(requirements, flags).value(); return TryCommit(requirements, flags).value();
@ -331,11 +337,26 @@ void MemoryAllocator::ReleaseMemory(MemoryAllocation* alloc) {
std::optional<MemoryCommit> MemoryAllocator::TryCommit(const VkMemoryRequirements& requirements, std::optional<MemoryCommit> MemoryAllocator::TryCommit(const VkMemoryRequirements& requirements,
VkMemoryPropertyFlags flags) { VkMemoryPropertyFlags flags) {
//conservative, spec-compliant alignment for suballocation
VkDeviceSize eff_align = requirements.alignment;
const auto& limits = device.GetPhysical().GetProperties().limits;
if ((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) &&
!(flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
// Non-coherent memory must be invalidated on atom boundary
if (limits.nonCoherentAtomSize > eff_align) eff_align = limits.nonCoherentAtomSize;
}
// Separate buffers to avoid stalls on tilers
if (buffer_image_granularity > eff_align)
{
eff_align = buffer_image_granularity;
}
eff_align = std::bit_ceil(eff_align);
for (auto& allocation : allocations) { for (auto& allocation : allocations) {
if (!allocation->IsCompatible(flags, requirements.memoryTypeBits)) { if (!allocation->IsCompatible(flags, requirements.memoryTypeBits)) {
continue; continue;
} }
if (auto commit = allocation->Commit(requirements.size, requirements.alignment)) {
if (auto commit = allocation->Commit(requirements.size, eff_align)) {
return commit; return commit;
} }
} }

Loading…
Cancel
Save