[VK] VMA changes
All checks were successful
eden-license / license-header (pull_request) Successful in 35s
All checks were successful
eden-license / license-header (pull_request) Successful in 35s
todo
This commit is contained in:
parent
44d658bbc5
commit
e95b908318
1 changed files with 25 additions and 4 deletions
|
@ -291,10 +291,16 @@ 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)) {
|
||||||
// TODO(Rodrigo): Handle out of memory situations in some way like flushing to guest memory.
|
const u64 floor = std::max<u64>(requirements.size, 4ull << 20);
|
||||||
throw vk::Exception(VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
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.
|
||||||
|
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.
|
||||||
|
@ -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…
Add table
Add a link
Reference in a new issue