From 882f371de476e54d8ca614da898cbaa1f5969614 Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Sun, 27 Oct 2024 17:17:12 +0300 Subject: [PATCH] Move buffer copies to render thread if they happen in the main thread. --- UnleashedRecomp/gpu/video.cpp | 67 ++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 81ee231..f15f2aa 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -355,6 +355,8 @@ enum class RenderCommandType SetRenderState, DestructResource, UnlockTextureRect, + UnlockBuffer16, + UnlockBuffer32, Present, StretchRect, SetRenderTarget, @@ -398,6 +400,11 @@ struct RenderCommand GuestTexture* texture; } unlockTextureRect; + struct + { + GuestBuffer* buffer; + } unlockBuffer; + struct { GuestDevice* device; @@ -1169,32 +1176,58 @@ static void ExecuteCopyCommandList(const T& function) g_copyQueue->waitForCommandFence(g_copyCommandFence.get()); } +template +static void UnlockBufferImpl(GuestBuffer* buffer) +{ + auto uploadBuffer = g_device->createBuffer(RenderBufferDesc::UploadBuffer(buffer->dataSize)); + + auto dest = reinterpret_cast(uploadBuffer->map()); + auto src = reinterpret_cast(buffer->mappedMemory); + + for (size_t i = 0; i < buffer->dataSize; i += sizeof(T)) + { + *dest = std::byteswap(*src); + ++dest; + ++src; + } + + uploadBuffer->unmap(); + + ExecuteCopyCommandList([&] + { + g_copyCommandList->copyBufferRegion(buffer->buffer->at(0), uploadBuffer->at(0), buffer->dataSize); + }); +} + template static void UnlockBuffer(GuestBuffer* buffer) { if (!buffer->lockedReadOnly) { - auto uploadBuffer = g_device->createBuffer(RenderBufferDesc::UploadBuffer(buffer->dataSize)); - - auto dest = reinterpret_cast(uploadBuffer->map()); - auto src = reinterpret_cast(buffer->mappedMemory); - - for (size_t i = 0; i < buffer->dataSize; i += sizeof(T)) + if (GetCurrentThreadId() == g_mainThreadId) { - *dest = std::byteswap(*src); - ++dest; - ++src; + RenderCommand cmd; + cmd.type = (sizeof(T) == 2) ? RenderCommandType::UnlockBuffer16 : RenderCommandType::UnlockBuffer32; + cmd.unlockBuffer.buffer = buffer; + g_renderQueue.enqueue(cmd); + } + else + { + UnlockBufferImpl(buffer); } - - uploadBuffer->unmap(); - - ExecuteCopyCommandList([&] - { - g_copyCommandList->copyBufferRegion(buffer->buffer->at(0), uploadBuffer->at(0), buffer->dataSize); - }); } } +static void ProcUnlockBuffer16(const RenderCommand& cmd) +{ + UnlockBufferImpl(cmd.unlockBuffer.buffer); +} + +static void ProcUnlockBuffer32(const RenderCommand& cmd) +{ + UnlockBufferImpl(cmd.unlockBuffer.buffer); +} + static void UnlockVertexBuffer(GuestBuffer* buffer) { UnlockBuffer(buffer); @@ -2777,6 +2810,8 @@ static std::thread g_renderThread([] case RenderCommandType::SetRenderState: ProcSetRenderState(cmd); break; case RenderCommandType::DestructResource: ProcDestructResource(cmd); break; case RenderCommandType::UnlockTextureRect: ProcUnlockTextureRect(cmd); break; + case RenderCommandType::UnlockBuffer16: ProcUnlockBuffer16(cmd); break; + case RenderCommandType::UnlockBuffer32: ProcUnlockBuffer32(cmd); break; case RenderCommandType::Present: ProcPresent(cmd); break; case RenderCommandType::StretchRect: ProcStretchRect(cmd); break; case RenderCommandType::SetRenderTarget: ProcSetRenderTarget(cmd); break;