Implement thread-safe MegaBuffer pool

We currently have a global `MegaBuffer` instance that is shared across all channels, this is very problematic as `MegaBuffer` fundamentally works like a state machine with allocations (especially resetting/freeing) and is thread-specific. Therefore, we now have a pool of several `MegaBuffer`s which is allocated from by the `CommandExecutor` and kept channel specific as a result which also limits its usage to a single thread, this allows for individually resetting or freeing any allocations.
This commit is contained in:
PixelyIon
2022-06-05 13:02:33 +05:30
parent 3e08494146
commit a5ca370c36
7 changed files with 126 additions and 79 deletions

View File

@ -267,7 +267,7 @@ namespace skyline::gpu {
return BufferView{shared_from_this(), &views.back()};
}
vk::DeviceSize Buffer::AcquireMegaBuffer() {
vk::DeviceSize Buffer::AcquireMegaBuffer(MegaBuffer& megaBuffer) {
SynchronizeGuest(false, true); // First try and enable megabuffering by doing an immediate sync
if (!megaBufferingEnabled)
@ -278,7 +278,7 @@ namespace skyline::gpu {
if (megaBufferOffset)
return megaBufferOffset; // If the current buffer contents haven't been changed since the last acquire, we can just return the existing offset
megaBufferOffset = gpu.buffer.megaBuffer.Push(backing, true); // Buffers are required to be page aligned in the megabuffer
megaBufferOffset = megaBuffer.Push(backing, true); // Buffers are required to be page aligned in the megabuffer
return megaBufferOffset;
}
@ -370,8 +370,8 @@ namespace skyline::gpu {
bufferDelegate->buffer->Write(pCycle, flushHostCallback, gpuCopyCallback, data, offset + bufferDelegate->view->offset);
}
vk::DeviceSize BufferView::AcquireMegaBuffer() const {
vk::DeviceSize bufferOffset{bufferDelegate->buffer->AcquireMegaBuffer()};
vk::DeviceSize BufferView::AcquireMegaBuffer(MegaBuffer& megaBuffer) const {
vk::DeviceSize bufferOffset{bufferDelegate->buffer->AcquireMegaBuffer(megaBuffer)};
// Propagate 0 results since they signify that megabuffering isn't supported for a buffer
if (bufferOffset)