diff options
| author | 2020-12-11 22:26:14 -0800 | |
|---|---|---|
| committer | 2020-12-28 16:33:48 -0800 | |
| commit | 14c825bd1c37b2444e858bf1a75fb77455b4eb52 (patch) | |
| tree | 60dfa8c299f4709d04ca652c8eb35e7f7b13ad89 /src/video_core/gpu.cpp | |
| parent | hle: kernel: hle_ipc: Remove SleepClientThread. (diff) | |
| download | yuzu-14c825bd1c37b2444e858bf1a75fb77455b4eb52.tar.gz yuzu-14c825bd1c37b2444e858bf1a75fb77455b4eb52.tar.xz yuzu-14c825bd1c37b2444e858bf1a75fb77455b4eb52.zip | |
video_core: gpu: Refactor out synchronous/asynchronous GPU implementations.
- We must always use a GPU thread now, even with synchronous GPU.
Diffstat (limited to 'src/video_core/gpu.cpp')
| -rw-r--r-- | src/video_core/gpu.cpp | 76 |
1 files changed, 71 insertions, 5 deletions
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index e2512a7f2..f99a8a0de 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include "core/core_timing.h" | 10 | #include "core/core_timing.h" |
| 11 | #include "core/core_timing_util.h" | 11 | #include "core/core_timing_util.h" |
| 12 | #include "core/frontend/emu_window.h" | 12 | #include "core/frontend/emu_window.h" |
| 13 | #include "core/hardware_interrupt_manager.h" | ||
| 13 | #include "core/memory.h" | 14 | #include "core/memory.h" |
| 14 | #include "core/settings.h" | 15 | #include "core/settings.h" |
| 15 | #include "video_core/engines/fermi_2d.h" | 16 | #include "video_core/engines/fermi_2d.h" |
| @@ -36,7 +37,8 @@ GPU::GPU(Core::System& system_, bool is_async_, bool use_nvdec_) | |||
| 36 | kepler_compute{std::make_unique<Engines::KeplerCompute>(system, *memory_manager)}, | 37 | kepler_compute{std::make_unique<Engines::KeplerCompute>(system, *memory_manager)}, |
| 37 | maxwell_dma{std::make_unique<Engines::MaxwellDMA>(system, *memory_manager)}, | 38 | maxwell_dma{std::make_unique<Engines::MaxwellDMA>(system, *memory_manager)}, |
| 38 | kepler_memory{std::make_unique<Engines::KeplerMemory>(system, *memory_manager)}, | 39 | kepler_memory{std::make_unique<Engines::KeplerMemory>(system, *memory_manager)}, |
| 39 | shader_notify{std::make_unique<VideoCore::ShaderNotify>()}, is_async{is_async_} {} | 40 | shader_notify{std::make_unique<VideoCore::ShaderNotify>()}, is_async{is_async_}, |
| 41 | gpu_thread{system_} {} | ||
| 40 | 42 | ||
| 41 | GPU::~GPU() = default; | 43 | GPU::~GPU() = default; |
| 42 | 44 | ||
| @@ -198,10 +200,6 @@ void GPU::SyncGuestHost() { | |||
| 198 | renderer->Rasterizer().SyncGuestHost(); | 200 | renderer->Rasterizer().SyncGuestHost(); |
| 199 | } | 201 | } |
| 200 | 202 | ||
| 201 | void GPU::OnCommandListEnd() { | ||
| 202 | renderer->Rasterizer().ReleaseFences(); | ||
| 203 | } | ||
| 204 | |||
| 205 | enum class GpuSemaphoreOperation { | 203 | enum class GpuSemaphoreOperation { |
| 206 | AcquireEqual = 0x1, | 204 | AcquireEqual = 0x1, |
| 207 | WriteLong = 0x2, | 205 | WriteLong = 0x2, |
| @@ -461,4 +459,72 @@ void GPU::ProcessSemaphoreAcquire() { | |||
| 461 | } | 459 | } |
| 462 | } | 460 | } |
| 463 | 461 | ||
| 462 | void GPU::Start() { | ||
| 463 | gpu_thread.StartThread(*renderer, renderer->Context(), *dma_pusher, *cdma_pusher); | ||
| 464 | cpu_context = renderer->GetRenderWindow().CreateSharedContext(); | ||
| 465 | cpu_context->MakeCurrent(); | ||
| 466 | } | ||
| 467 | |||
| 468 | void GPU::ObtainContext() { | ||
| 469 | cpu_context->MakeCurrent(); | ||
| 470 | } | ||
| 471 | |||
| 472 | void GPU::ReleaseContext() { | ||
| 473 | cpu_context->DoneCurrent(); | ||
| 474 | } | ||
| 475 | |||
| 476 | void GPU::PushGPUEntries(Tegra::CommandList&& entries) { | ||
| 477 | gpu_thread.SubmitList(std::move(entries)); | ||
| 478 | } | ||
| 479 | |||
| 480 | void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) { | ||
| 481 | if (!use_nvdec) { | ||
| 482 | return; | ||
| 483 | } | ||
| 484 | // This condition fires when a video stream ends, clear all intermediary data | ||
| 485 | if (entries[0].raw == 0xDEADB33F) { | ||
| 486 | cdma_pusher.reset(); | ||
| 487 | return; | ||
| 488 | } | ||
| 489 | if (!cdma_pusher) { | ||
| 490 | cdma_pusher = std::make_unique<Tegra::CDmaPusher>(*this); | ||
| 491 | } | ||
| 492 | |||
| 493 | // SubmitCommandBuffer would make the nvdec operations async, this is not currently working | ||
| 494 | // TODO(ameerj): RE proper async nvdec operation | ||
| 495 | // gpu_thread.SubmitCommandBuffer(std::move(entries)); | ||
| 496 | |||
| 497 | cdma_pusher->Push(std::move(entries)); | ||
| 498 | cdma_pusher->DispatchCalls(); | ||
| 499 | } | ||
| 500 | |||
| 501 | void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | ||
| 502 | gpu_thread.SwapBuffers(framebuffer); | ||
| 503 | } | ||
| 504 | |||
| 505 | void GPU::FlushRegion(VAddr addr, u64 size) { | ||
| 506 | gpu_thread.FlushRegion(addr, size); | ||
| 507 | } | ||
| 508 | |||
| 509 | void GPU::InvalidateRegion(VAddr addr, u64 size) { | ||
| 510 | gpu_thread.InvalidateRegion(addr, size); | ||
| 511 | } | ||
| 512 | |||
| 513 | void GPU::FlushAndInvalidateRegion(VAddr addr, u64 size) { | ||
| 514 | gpu_thread.FlushAndInvalidateRegion(addr, size); | ||
| 515 | } | ||
| 516 | |||
| 517 | void GPU::TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const { | ||
| 518 | auto& interrupt_manager = system.InterruptManager(); | ||
| 519 | interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value); | ||
| 520 | } | ||
| 521 | |||
| 522 | void GPU::WaitIdle() const { | ||
| 523 | gpu_thread.WaitIdle(); | ||
| 524 | } | ||
| 525 | |||
| 526 | void GPU::OnCommandListEnd() { | ||
| 527 | gpu_thread.OnCommandListEnd(); | ||
| 528 | } | ||
| 529 | |||
| 464 | } // namespace Tegra | 530 | } // namespace Tegra |