diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index 92acc57b1d..66d562a055 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -36,7 +36,7 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3 auto& instance = Core::System::GetInstance(); instance.GetPerfStats().EndGameFrame(); - instance.Renderer().SwapBuffers(framebuffer); + instance.GPU().SwapBuffers(framebuffer); } } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 0a650f36c6..8ce7bc7a5e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -136,16 +136,6 @@ u32 nvhost_gpu::AllocateObjectContext(const std::vector& input, std::vector< return 0; } -static void PushGPUEntries(Tegra::CommandList&& entries) { - if (entries.empty()) { - return; - } - - auto& dma_pusher{Core::System::GetInstance().GPU().DmaPusher()}; - dma_pusher.Push(std::move(entries)); - dma_pusher.DispatchCalls(); -} - u32 nvhost_gpu::SubmitGPFIFO(const std::vector& input, std::vector& output) { if (input.size() < sizeof(IoctlSubmitGpfifo)) { UNIMPLEMENTED(); @@ -163,7 +153,7 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector& input, std::vector& outp std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)], params.num_entries * sizeof(Tegra::CommandListHeader)); - PushGPUEntries(std::move(entries)); + Core::System::GetInstance().GPU().PushGPUEntries(std::move(entries)); params.fence_out.id = 0; params.fence_out.value = 0; @@ -184,7 +174,7 @@ u32 nvhost_gpu::KickoffPB(const std::vector& input, std::vector& output) Memory::ReadBlock(params.address, entries.data(), params.num_entries * sizeof(Tegra::CommandListHeader)); - PushGPUEntries(std::move(entries)); + Core::System::GetInstance().GPU().PushGPUEntries(std::move(entries)); params.fence_out.id = 0; params.fence_out.value = 0; diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 6a613aeabf..bdc0a346b6 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -141,7 +141,7 @@ void NVFlinger::Compose() { // There was no queued buffer to draw, render previous frame system_instance.GetPerfStats().EndGameFrame(); - system_instance.Renderer().SwapBuffers({}); + system_instance.GPU().SwapBuffers({}); continue; } diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 63a958f11f..f94a67e77f 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp @@ -17,6 +17,13 @@ DmaPusher::~DmaPusher() = default; MICROPROFILE_DEFINE(DispatchCalls, "GPU", "Execute command buffer", MP_RGB(128, 128, 192)); +void DmaPusher::QueuePendingCalls() { + for (auto& entry : dma_writebuffer) { + dma_readbuffer.push(std::move(entry)); + } + dma_writebuffer.clear(); +} + void DmaPusher::DispatchCalls() { MICROPROFILE_SCOPE(DispatchCalls); @@ -89,9 +96,9 @@ bool DmaPusher::Step() { break; } } - } else if (ib_enable && !dma_pushbuffer.empty()) { + } else if (ib_enable && !dma_readbuffer.empty()) { // Current pushbuffer empty, but we have more IB entries to read - const CommandList& command_list{dma_pushbuffer.front()}; + const CommandList& command_list{dma_readbuffer.front()}; const CommandListHeader& command_list_header{command_list[dma_pushbuffer_subindex++]}; dma_get = command_list_header.addr; dma_put = dma_get + command_list_header.size * sizeof(u32); @@ -99,7 +106,7 @@ bool DmaPusher::Step() { if (dma_pushbuffer_subindex >= command_list.size()) { // We've gone through the current list, remove it from the queue - dma_pushbuffer.pop(); + dma_readbuffer.pop(); dma_pushbuffer_subindex = 0; } } else { diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h index 16e0697c4f..a65d12621a 100644 --- a/src/video_core/dma_pusher.h +++ b/src/video_core/dma_pusher.h @@ -61,9 +61,10 @@ public: ~DmaPusher(); void Push(CommandList&& entries) { - dma_pushbuffer.push(std::move(entries)); + dma_writebuffer.push_back(std::move(entries)); } + void QueuePendingCalls(); void DispatchCalls(); private: @@ -75,8 +76,9 @@ private: GPU& gpu; - std::queue dma_pushbuffer; ///< Queue of command lists to be processed - std::size_t dma_pushbuffer_subindex{}; ///< Index within a command list within the pushbuffer + std::vector dma_writebuffer; + std::queue dma_readbuffer; + std::size_t dma_pushbuffer_subindex{}; ///< Index within a command list within the pushbuffer struct DmaState { u32 method; ///< Current method diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index d439e7527d..48e88fd04b 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -61,6 +61,17 @@ const DmaPusher& GPU::DmaPusher() const { return *dma_pusher; } +void GPU::PushGPUEntries(Tegra::CommandList&& entries) { + dma_pusher->Push(std::move(entries)); + dma_pusher->QueuePendingCalls(); + dma_pusher->DispatchCalls(); +} + +void GPU::SwapBuffers( + std::optional> framebuffer) { + renderer.SwapBuffers(std::move(framebuffer)); +} + u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { ASSERT(format != RenderTargetFormat::NONE); diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 5758972a1f..accae9eebc 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -156,6 +156,13 @@ public: /// Returns a const reference to the GPU DMA pusher. const Tegra::DmaPusher& DmaPusher() const; + /// Push GPU command entries to be processed + void PushGPUEntries(Tegra::CommandList&& entries); + + /// Swap buffers (render frame) + void SwapBuffers( + std::optional> framebuffer); + private: std::unique_ptr dma_pusher; std::unique_ptr memory_manager;