summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-02-16 09:51:37 -0400
committerGravatar Fernando Sahmkow2020-04-22 11:36:06 -0400
commitda8f17715dbdc7eec92f5f0c11c968a51b86cab4 (patch)
treea1604f3cf9abe9128d26834f9c68161ecab6e204 /src
parentTexture Cache: Implement OnCPUWrite and SyncGuestHost (diff)
downloadyuzu-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.cpp1
-rw-r--r--src/video_core/engines/maxwell_3d.cpp8
-rw-r--r--src/video_core/gpu.cpp3
-rw-r--r--src/video_core/gpu.h1
-rw-r--r--src/video_core/gpu_thread.cpp6
-rw-r--r--src/video_core/rasterizer_interface.h6
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp16
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp14
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h2
-rw-r--r--src/video_core/texture_cache/texture_cache.h4
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
37bool DmaPusher::Step() { 38bool 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
145void 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
84void ThreadManager::InvalidateRegion(VAddr addr, u64 size) { 84void ThreadManager::InvalidateRegion(VAddr addr, u64 size) {
85 system.Renderer().Rasterizer().InvalidateRegion(addr, size); 85 system.Renderer().Rasterizer().OnCPUWrite(addr, size);
86} 86}
87 87
88void ThreadManager::FlushAndInvalidateRegion(VAddr addr, u64 size) { 88void 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
93void ThreadManager::WaitIdle() const { 93void 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
663void 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
673void RasterizerOpenGL::SyncGuestHost() {
674 MICROPROFILE_SCOPE(OpenGL_CacheManagement);
675 texture_cache.SyncGuestHost();
676 // buffer_cache.SyncGuestHost();
677}
678
663void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { 679void 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
527void 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
536void RasterizerVulkan::SyncGuestHost() {
537 texture_cache.SyncGuestHost();
538 // buffer_cache.SyncGuestHost();
539}
540
527void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { 541void 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 {