diff options
| author | 2020-02-16 09:51:37 -0400 | |
|---|---|---|
| committer | 2020-04-22 11:36:06 -0400 | |
| commit | da8f17715dbdc7eec92f5f0c11c968a51b86cab4 (patch) | |
| tree | a1604f3cf9abe9128d26834f9c68161ecab6e204 /src | |
| parent | Texture Cache: Implement OnCPUWrite and SyncGuestHost (diff) | |
| download | yuzu-da8f17715dbdc7eec92f5f0c11c968a51b86cab4.tar.gz yuzu-da8f17715dbdc7eec92f5f0c11c968a51b86cab4.tar.xz yuzu-da8f17715dbdc7eec92f5f0c11c968a51b86cab4.zip | |
GPU: Refactor synchronization on Async GPU
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 1 | ||||
| -rw-r--r-- | src/video_core/gpu_thread.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/rasterizer_interface.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 2 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 4 |
11 files changed, 56 insertions, 7 deletions
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 0b77afc71..2516ea993 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp | |||
| @@ -32,6 +32,7 @@ void DmaPusher::DispatchCalls() { | |||
| 32 | } | 32 | } |
| 33 | } | 33 | } |
| 34 | gpu.FlushCommands(); | 34 | gpu.FlushCommands(); |
| 35 | gpu.SyncGuestHost(); | ||
| 35 | } | 36 | } |
| 36 | 37 | ||
| 37 | bool DmaPusher::Step() { | 38 | bool DmaPusher::Step() { |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index baa74ad4c..2298a6273 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -403,9 +403,13 @@ void Maxwell3D::ProcessQueryGet() { | |||
| 403 | "Units other than CROP are unimplemented"); | 403 | "Units other than CROP are unimplemented"); |
| 404 | 404 | ||
| 405 | switch (regs.query.query_get.operation) { | 405 | switch (regs.query.query_get.operation) { |
| 406 | case Regs::QueryOperation::Release: | 406 | case Regs::QueryOperation::Release: { |
| 407 | StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); | 407 | rasterizer.FlushCommands(); |
| 408 | rasterizer.SyncGuestHost(); | ||
| 409 | const u64 result = regs.query.query_sequence; | ||
| 410 | StampQueryResult(result, regs.query.query_get.short_query == 0); | ||
| 408 | break; | 411 | break; |
| 412 | } | ||
| 409 | case Regs::QueryOperation::Acquire: | 413 | case Regs::QueryOperation::Acquire: |
| 410 | // TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that | 414 | // TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that |
| 411 | // matches the current payload. | 415 | // matches the current payload. |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index a606f4abd..13bca5a78 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -142,6 +142,9 @@ void GPU::FlushCommands() { | |||
| 142 | renderer->Rasterizer().FlushCommands(); | 142 | renderer->Rasterizer().FlushCommands(); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | void GPU::SyncGuestHost() { | ||
| 146 | renderer->Rasterizer().SyncGuestHost(); | ||
| 147 | } | ||
| 145 | // Note that, traditionally, methods are treated as 4-byte addressable locations, and hence | 148 | // Note that, traditionally, methods are treated as 4-byte addressable locations, and hence |
| 146 | // their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4. | 149 | // their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4. |
| 147 | // So the values you see in docs might be multiplied by 4. | 150 | // So the values you see in docs might be multiplied by 4. |
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 1a2d747be..99ed190bc 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -156,6 +156,7 @@ public: | |||
| 156 | void CallMethod(const MethodCall& method_call); | 156 | void CallMethod(const MethodCall& method_call); |
| 157 | 157 | ||
| 158 | void FlushCommands(); | 158 | void FlushCommands(); |
| 159 | void SyncGuestHost(); | ||
| 159 | 160 | ||
| 160 | /// Returns a reference to the Maxwell3D GPU engine. | 161 | /// Returns a reference to the Maxwell3D GPU engine. |
| 161 | Engines::Maxwell3D& Maxwell3D(); | 162 | Engines::Maxwell3D& Maxwell3D(); |
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 10cda686b..1994d3bb4 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp | |||
| @@ -40,7 +40,7 @@ static void RunThread(VideoCore::RendererBase& renderer, Core::Frontend::Graphic | |||
| 40 | } else if (const auto data = std::get_if<FlushRegionCommand>(&next.data)) { | 40 | } else if (const auto data = std::get_if<FlushRegionCommand>(&next.data)) { |
| 41 | renderer.Rasterizer().FlushRegion(data->addr, data->size); | 41 | renderer.Rasterizer().FlushRegion(data->addr, data->size); |
| 42 | } else if (const auto data = std::get_if<InvalidateRegionCommand>(&next.data)) { | 42 | } else if (const auto data = std::get_if<InvalidateRegionCommand>(&next.data)) { |
| 43 | renderer.Rasterizer().InvalidateRegion(data->addr, data->size); | 43 | renderer.Rasterizer().OnCPUWrite(data->addr, data->size); |
| 44 | } else if (std::holds_alternative<EndProcessingCommand>(next.data)) { | 44 | } else if (std::holds_alternative<EndProcessingCommand>(next.data)) { |
| 45 | return; | 45 | return; |
| 46 | } else { | 46 | } else { |
| @@ -82,12 +82,12 @@ void ThreadManager::FlushRegion(VAddr addr, u64 size) { | |||
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | void ThreadManager::InvalidateRegion(VAddr addr, u64 size) { | 84 | void ThreadManager::InvalidateRegion(VAddr addr, u64 size) { |
| 85 | system.Renderer().Rasterizer().InvalidateRegion(addr, size); | 85 | system.Renderer().Rasterizer().OnCPUWrite(addr, size); |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | void ThreadManager::FlushAndInvalidateRegion(VAddr addr, u64 size) { | 88 | void ThreadManager::FlushAndInvalidateRegion(VAddr addr, u64 size) { |
| 89 | // Skip flush on asynch mode, as FlushAndInvalidateRegion is not used for anything too important | 89 | // Skip flush on asynch mode, as FlushAndInvalidateRegion is not used for anything too important |
| 90 | InvalidateRegion(addr, size); | 90 | system.Renderer().Rasterizer().OnCPUWrite(addr, size); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | void ThreadManager::WaitIdle() const { | 93 | void ThreadManager::WaitIdle() const { |
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 8ae5b9c4e..0d05a3fc7 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h | |||
| @@ -58,6 +58,12 @@ public: | |||
| 58 | /// Notify rasterizer that any caches of the specified region should be invalidated | 58 | /// Notify rasterizer that any caches of the specified region should be invalidated |
| 59 | virtual void InvalidateRegion(VAddr addr, u64 size) = 0; | 59 | virtual void InvalidateRegion(VAddr addr, u64 size) = 0; |
| 60 | 60 | ||
| 61 | /// Notify rasterizer that any caches of the specified region are desync with guest | ||
| 62 | virtual void OnCPUWrite(VAddr addr, u64 size) = 0; | ||
| 63 | |||
| 64 | /// Sync memory between guest and host. | ||
| 65 | virtual void SyncGuestHost() = 0; | ||
| 66 | |||
| 61 | /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory | 67 | /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory |
| 62 | /// and invalidated | 68 | /// and invalidated |
| 63 | virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; | 69 | virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index ac4485a18..537912745 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -660,6 +660,22 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { | |||
| 660 | query_cache.InvalidateRegion(addr, size); | 660 | query_cache.InvalidateRegion(addr, size); |
| 661 | } | 661 | } |
| 662 | 662 | ||
| 663 | void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { | ||
| 664 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | ||
| 665 | if (!addr || !size) { | ||
| 666 | return; | ||
| 667 | } | ||
| 668 | texture_cache.OnCPUWrite(addr, size); | ||
| 669 | shader_cache.InvalidateRegion(addr, size); | ||
| 670 | buffer_cache.InvalidateRegion(addr, size); | ||
| 671 | } | ||
| 672 | |||
| 673 | void RasterizerOpenGL::SyncGuestHost() { | ||
| 674 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | ||
| 675 | texture_cache.SyncGuestHost(); | ||
| 676 | // buffer_cache.SyncGuestHost(); | ||
| 677 | } | ||
| 678 | |||
| 663 | void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { | 679 | void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { |
| 664 | if (Settings::IsGPULevelExtreme()) { | 680 | if (Settings::IsGPULevelExtreme()) { |
| 665 | FlushRegion(addr, size); | 681 | FlushRegion(addr, size); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index caea174d2..a870024c6 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -67,6 +67,8 @@ public: | |||
| 67 | void FlushAll() override; | 67 | void FlushAll() override; |
| 68 | void FlushRegion(VAddr addr, u64 size) override; | 68 | void FlushRegion(VAddr addr, u64 size) override; |
| 69 | void InvalidateRegion(VAddr addr, u64 size) override; | 69 | void InvalidateRegion(VAddr addr, u64 size) override; |
| 70 | void OnCPUWrite(VAddr addr, u64 size) override; | ||
| 71 | void SyncGuestHost() override; | ||
| 70 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; | 72 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; |
| 71 | void FlushCommands() override; | 73 | void FlushCommands() override; |
| 72 | void TickFrame() override; | 74 | void TickFrame() override; |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 71007bbe8..ad59f558d 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -524,6 +524,20 @@ void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { | |||
| 524 | query_cache.InvalidateRegion(addr, size); | 524 | query_cache.InvalidateRegion(addr, size); |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) { | ||
| 528 | if (!addr || !size) { | ||
| 529 | return; | ||
| 530 | } | ||
| 531 | texture_cache.OnCPUWrite(addr, size); | ||
| 532 | pipeline_cache.InvalidateRegion(addr, size); | ||
| 533 | buffer_cache.InvalidateRegion(addr, size); | ||
| 534 | } | ||
| 535 | |||
| 536 | void RasterizerVulkan::SyncGuestHost() { | ||
| 537 | texture_cache.SyncGuestHost(); | ||
| 538 | // buffer_cache.SyncGuestHost(); | ||
| 539 | } | ||
| 540 | |||
| 527 | void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { | 541 | void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { |
| 528 | FlushRegion(addr, size); | 542 | FlushRegion(addr, size); |
| 529 | InvalidateRegion(addr, size); | 543 | InvalidateRegion(addr, size); |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index d9108f862..285f731bc 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h | |||
| @@ -119,6 +119,8 @@ public: | |||
| 119 | void FlushAll() override; | 119 | void FlushAll() override; |
| 120 | void FlushRegion(VAddr addr, u64 size) override; | 120 | void FlushRegion(VAddr addr, u64 size) override; |
| 121 | void InvalidateRegion(VAddr addr, u64 size) override; | 121 | void InvalidateRegion(VAddr addr, u64 size) override; |
| 122 | void OnCPUWrite(VAddr addr, u64 size) override; | ||
| 123 | void SyncGuestHost() override; | ||
| 122 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; | 124 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; |
| 123 | void FlushCommands() override; | 125 | void FlushCommands() override; |
| 124 | void TickFrame() override; | 126 | void TickFrame() override; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 441fda53d..c23b9f9b9 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -63,7 +63,7 @@ public: | |||
| 63 | } | 63 | } |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | void OnCPUWrite(CacheAddr addr, std::size_t size) { | 66 | void OnCPUWrite(VAddr addr, std::size_t size) { |
| 67 | std::lock_guard lock{mutex}; | 67 | std::lock_guard lock{mutex}; |
| 68 | 68 | ||
| 69 | for (const auto& surface : GetSurfacesInRegion(addr, size)) { | 69 | for (const auto& surface : GetSurfacesInRegion(addr, size)) { |
| @@ -549,7 +549,7 @@ private: | |||
| 549 | } | 549 | } |
| 550 | const auto& final_params = new_surface->GetSurfaceParams(); | 550 | const auto& final_params = new_surface->GetSurfaceParams(); |
| 551 | if (cr_params.type != final_params.type) { | 551 | if (cr_params.type != final_params.type) { |
| 552 | if (Settings::values.use_accurate_gpu_emulation) { | 552 | if (Settings::IsGPULevelExtreme()) { |
| 553 | BufferCopy(current_surface, new_surface); | 553 | BufferCopy(current_surface, new_surface); |
| 554 | } | 554 | } |
| 555 | } else { | 555 | } else { |