diff --git a/app/src/main/cpp/skyline/gpu/buffer_manager.cpp b/app/src/main/cpp/skyline/gpu/buffer_manager.cpp index 652b36a2..fd181c08 100644 --- a/app/src/main/cpp/skyline/gpu/buffer_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/buffer_manager.cpp @@ -119,6 +119,14 @@ namespace skyline::gpu { return *this; } + bool MegaBuffer::WasUsed() { + return freeRegion != slot->backing.subspan(PAGE_SIZE); + } + + void MegaBuffer::ReplaceCycle(const std::shared_ptr &cycle) { + slot->cycle = cycle; + } + void MegaBuffer::Reset() { freeRegion = slot->backing.subspan(PAGE_SIZE); } diff --git a/app/src/main/cpp/skyline/gpu/buffer_manager.h b/app/src/main/cpp/skyline/gpu/buffer_manager.h index ee28e6b2..50ccc210 100644 --- a/app/src/main/cpp/skyline/gpu/buffer_manager.h +++ b/app/src/main/cpp/skyline/gpu/buffer_manager.h @@ -91,6 +91,17 @@ namespace skyline::gpu { MegaBuffer &operator=(MegaBuffer &&other); + /** + * @return If any allocations into the megabuffer were done at the time of the call + */ + bool WasUsed(); + + /** + * @brief Replaces the cycle associated with the underlying megabuffer with the supplied cycle + * @note The megabuffer must **NOT** have any dependencies that aren't conveyed by the supplied cycle + */ + void ReplaceCycle(const std::shared_ptr &cycle); + /** * @brief Resets the free region of the megabuffer to its initial state, data is left intact but may be overwritten */ diff --git a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp index f4bca831..9711ede1 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp @@ -321,7 +321,10 @@ namespace skyline::gpu::interconnect { SubmitInternal(); activeCommandBuffer = gpu.scheduler.AllocateCommandBuffer(); cycle = activeCommandBuffer.GetFenceCycle(); - megaBuffer = gpu.buffer.AcquireMegaBuffer(cycle); + if (megaBuffer.WasUsed()) + megaBuffer = gpu.buffer.AcquireMegaBuffer(cycle); + else + megaBuffer.ReplaceCycle(cycle); } ResetInternal(); }