[DiscordArchive] by "dynamic descriptor indexing", do you mean having like one big descriptor set with array of all t
[DiscordArchive] by "dynamic descriptor indexing", do you mean having like one big descriptor set with array of all t
Archived author: Deamon • Posted: 2023-07-06T11:49:06.604000+00:00
Original source
Or rather the allocations are done from one single VkBuffer
Archived author: Nix • Posted: 2023-07-06T11:49:22.594000+00:00
Original source
For a single object definitely overkill
Archived author: bandysc • Posted: 2023-07-06T11:50:44.651000+00:00
Original source
out of curiousity, do you unload meshes when they are no longer necessary? how does it work with storing them in one buffers?
hared_ptr. If the subBuffer allocated no longer needed, aka it's destructor was called, then a callback is added to device, that does deallocation after MAX_FRAMES_IN_FLIGHTArchived author: Deamon • Posted: 2023-07-06T11:53:10.689000+00:00
Original source
I do. Basically I use modified https://github.com/sebbbi/OffsetAllocator
Everything in engine is wrapped in std:
hared_ptr. If the subBuffer allocated no longer needed, aka it's destructor was called, then a callback is added to device, that does deallocation after MAX_FRAMES_IN_FLIGHT
[Embed: GitHub - sebbbi/OffsetAllocator: Fast O(1) offset allocator with mi...]
Fast O(1) offset allocator with minimal fragmentation - GitHub - sebbbi/OffsetAllocator: Fast O(1) offset allocator with minimal fragmentation
https://github.com/sebbbi/OffsetAllocator
Archived author: Deamon • Posted: 2023-07-06T11:53:54.503000+00:00
Original source
```cpp
void GBufferVLK::deallocateSubBuffer(BufferInternal &buffer, const OffsetAllocator::Allocation &alloc, const OffsetAllocator::Allocation &uiaAlloc) {
//Destruction of this virtualBlock happens only in deallocation queue.
//So it's safe to assume that even if the buffer's handle been changed by the time VirtualFree happens,
//the virtualBlock was still not been free'd
//So there would be no error
if (alloc.metadata != OffsetAllocator::Allocation::NO_SPACE) {
auto l_alloc = alloc;
auto l_uiaAlloc = uiaAlloc;
auto l_weak = weak_from_this();
m_device->addDeallocationRecord(
[l_alloc, l_uiaAlloc, l_weak]() {
auto shared = l_weak.lock();
if (shared == nullptr) return;
std::unique_lock<std::mutex> lock(shared->m_mutex, std::defer_lock);
lock.lock();
shared->offsetAllocator.free(l_alloc);
shared->uiaAllocator.free(l_uiaAlloc);
lock.unlock();
});
}
}
```
Archived author: Deamon • Posted: 2023-07-06T11:54:52.480000+00:00
Original source
Deallocation queue is common practice, that saves a lot of headache. Basically it makes sure that resources that re-deallocated are no longer used by GPU
Archived author: Deamon • Posted: 2023-07-06T11:56:06.670000+00:00
Original source
If there is not enough space in VkBuffer, I have to create bigger VkBuffer, move all previous data to it and update the DescriptorSets that use that said buffer
Archived author: Deamon • Posted: 2023-07-06T11:59:01.417000+00:00
Original source
Essentially the tracking of free space in VkBuffer is done by OffsetAllocator. That lib gives you offset of your allocation. No actual memory is done by that lib
Archived author: Deamon • Posted: 2023-07-06T12:01:24.728000+00:00
Original source
It's similar to Virtual Allocations in AMD's VMA, but better. With VMA, if you allocate new VkBuffer, you'd need to do all sub allocations from scratch, there is no way to move old offsets to new buffer.
But with this modified OffsetAllocator, I can keep old offsets and just tell lib to add new block of free memory (virtually ofc. No actual memallocs is happening there)
Archived author: Deleted User • Posted: 2023-07-06T16:13:09.904000+00:00
Original source
Looking nice, actually the best map render I've seen so far, good job!