summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-02-16 10:08:07 -0400
committerGravatar Fernando Sahmkow2020-04-22 11:36:07 -0400
commit8b1eb44b3ed5483071dc6754662a277b45e4a809 (patch)
treeed985a775881cce60a98ab7ddc43803ccf7d463c
parentGPU: Refactor synchronization on Async GPU (diff)
downloadyuzu-8b1eb44b3ed5483071dc6754662a277b45e4a809.tar.gz
yuzu-8b1eb44b3ed5483071dc6754662a277b45e4a809.tar.xz
yuzu-8b1eb44b3ed5483071dc6754662a277b45e4a809.zip
BufferCache: Implement OnCPUWrite and SyncGuestHost
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h45
-rw-r--r--src/video_core/buffer_cache/map_interval.h18
-rw-r--r--src/video_core/dma_pusher.cpp1
-rw-r--r--src/video_core/gpu_thread.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp4
6 files changed, 67 insertions, 7 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 83e7a1cde..5b14d52e2 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include <list>
8#include <memory> 9#include <memory>
9#include <mutex> 10#include <mutex>
10#include <unordered_map> 11#include <unordered_map>
@@ -137,7 +138,9 @@ public:
137 }); 138 });
138 for (auto& object : objects) { 139 for (auto& object : objects) {
139 if (object->IsModified() && object->IsRegistered()) { 140 if (object->IsModified() && object->IsRegistered()) {
141 mutex.unlock();
140 FlushMap(object); 142 FlushMap(object);
143 mutex.lock();
141 } 144 }
142 } 145 }
143 } 146 }
@@ -154,6 +157,30 @@ public:
154 } 157 }
155 } 158 }
156 159
160 void OnCPUWrite(VAddr addr, std::size_t size) {
161 std::lock_guard lock{mutex};
162
163 for (const auto& object : GetMapsInRange(addr, size)) {
164 if (object->IsMemoryMarked() && object->IsRegistered()) {
165 Unmark(object);
166 object->SetSyncPending(true);
167 marked_for_unregister.emplace_back(object);
168 }
169 }
170 }
171
172 void SyncGuestHost() {
173 std::lock_guard lock{mutex};
174
175 for (const auto& object : marked_for_unregister) {
176 if (object->IsRegistered()) {
177 object->SetSyncPending(false);
178 Unregister(object);
179 }
180 }
181 marked_for_unregister.clear();
182 }
183
157 virtual BufferType GetEmptyBuffer(std::size_t size) = 0; 184 virtual BufferType GetEmptyBuffer(std::size_t size) = 0;
158 185
159protected: 186protected:
@@ -196,17 +223,30 @@ protected:
196 const IntervalType interval{new_map->GetStart(), new_map->GetEnd()}; 223 const IntervalType interval{new_map->GetStart(), new_map->GetEnd()};
197 mapped_addresses.insert({interval, new_map}); 224 mapped_addresses.insert({interval, new_map});
198 rasterizer.UpdatePagesCachedCount(cpu_addr, size, 1); 225 rasterizer.UpdatePagesCachedCount(cpu_addr, size, 1);
226 new_map->SetMemoryMarked(true);
199 if (inherit_written) { 227 if (inherit_written) {
200 MarkRegionAsWritten(new_map->GetStart(), new_map->GetEnd() - 1); 228 MarkRegionAsWritten(new_map->GetStart(), new_map->GetEnd() - 1);
201 new_map->MarkAsWritten(true); 229 new_map->MarkAsWritten(true);
202 } 230 }
203 } 231 }
204 232
205 /// Unregisters an object from the cache 233 void Unmark(const MapInterval& map) {
206 void Unregister(MapInterval& map) { 234 if (!map->IsMemoryMarked()) {
235 return;
236 }
207 const std::size_t size = map->GetEnd() - map->GetStart(); 237 const std::size_t size = map->GetEnd() - map->GetStart();
208 rasterizer.UpdatePagesCachedCount(map->GetStart(), size, -1); 238 rasterizer.UpdatePagesCachedCount(map->GetStart(), size, -1);
239 map->SetMemoryMarked(false);
240 }
241
242 /// Unregisters an object from the cache
243 void Unregister(const MapInterval& map) {
244 Unmark(map);
209 map->MarkAsRegistered(false); 245 map->MarkAsRegistered(false);
246 if (map->IsSyncPending()) {
247 marked_for_unregister.remove(map);
248 map->SetSyncPending(false);
249 }
210 if (map->IsWritten()) { 250 if (map->IsWritten()) {
211 UnmarkRegionAsWritten(map->GetStart(), map->GetEnd() - 1); 251 UnmarkRegionAsWritten(map->GetStart(), map->GetEnd() - 1);
212 } 252 }
@@ -479,6 +519,7 @@ private:
479 u64 modified_ticks = 0; 519 u64 modified_ticks = 0;
480 520
481 std::vector<u8> staging_buffer; 521 std::vector<u8> staging_buffer;
522 std::list<MapInterval> marked_for_unregister;
482 523
483 std::recursive_mutex mutex; 524 std::recursive_mutex mutex;
484}; 525};
diff --git a/src/video_core/buffer_cache/map_interval.h b/src/video_core/buffer_cache/map_interval.h
index b0956029d..29d8b26f3 100644
--- a/src/video_core/buffer_cache/map_interval.h
+++ b/src/video_core/buffer_cache/map_interval.h
@@ -46,6 +46,22 @@ public:
46 return is_registered; 46 return is_registered;
47 } 47 }
48 48
49 void SetMemoryMarked(bool is_memory_marked_) {
50 is_memory_marked = is_memory_marked_;
51 }
52
53 bool IsMemoryMarked() const {
54 return is_memory_marked;
55 }
56
57 void SetSyncPending(bool is_sync_pending_) {
58 is_sync_pending = is_sync_pending_;
59 }
60
61 bool IsSyncPending() const {
62 return is_sync_pending;
63 }
64
49 VAddr GetStart() const { 65 VAddr GetStart() const {
50 return start; 66 return start;
51 } 67 }
@@ -83,6 +99,8 @@ private:
83 bool is_written{}; 99 bool is_written{};
84 bool is_modified{}; 100 bool is_modified{};
85 bool is_registered{}; 101 bool is_registered{};
102 bool is_memory_marked{};
103 bool is_sync_pending{};
86 u64 ticks{}; 104 u64 ticks{};
87}; 105};
88 106
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp
index 2516ea993..31627b812 100644
--- a/src/video_core/dma_pusher.cpp
+++ b/src/video_core/dma_pusher.cpp
@@ -21,6 +21,7 @@ MICROPROFILE_DEFINE(DispatchCalls, "GPU", "Execute command buffer", MP_RGB(128,
21void DmaPusher::DispatchCalls() { 21void DmaPusher::DispatchCalls() {
22 MICROPROFILE_SCOPE(DispatchCalls); 22 MICROPROFILE_SCOPE(DispatchCalls);
23 23
24 gpu.SyncGuestHost();
24 // On entering GPU code, assume all memory may be touched by the ARM core. 25 // On entering GPU code, assume all memory may be touched by the ARM core.
25 gpu.Maxwell3D().OnMemoryWrite(); 26 gpu.Maxwell3D().OnMemoryWrite();
26 27
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 1994d3bb4..0a8123cfe 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -78,7 +78,7 @@ void ThreadManager::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
78} 78}
79 79
80void ThreadManager::FlushRegion(VAddr addr, u64 size) { 80void ThreadManager::FlushRegion(VAddr addr, u64 size) {
81 PushCommand(FlushRegionCommand(addr, size)); 81 system.Renderer().Rasterizer().FlushRegion(addr, size);
82} 82}
83 83
84void ThreadManager::InvalidateRegion(VAddr addr, u64 size) { 84void ThreadManager::InvalidateRegion(VAddr addr, u64 size) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 537912745..988eaeaa5 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -667,13 +667,13 @@ void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) {
667 } 667 }
668 texture_cache.OnCPUWrite(addr, size); 668 texture_cache.OnCPUWrite(addr, size);
669 shader_cache.InvalidateRegion(addr, size); 669 shader_cache.InvalidateRegion(addr, size);
670 buffer_cache.InvalidateRegion(addr, size); 670 buffer_cache.OnCPUWrite(addr, size);
671} 671}
672 672
673void RasterizerOpenGL::SyncGuestHost() { 673void RasterizerOpenGL::SyncGuestHost() {
674 MICROPROFILE_SCOPE(OpenGL_CacheManagement); 674 MICROPROFILE_SCOPE(OpenGL_CacheManagement);
675 texture_cache.SyncGuestHost(); 675 texture_cache.SyncGuestHost();
676 // buffer_cache.SyncGuestHost(); 676 buffer_cache.SyncGuestHost();
677} 677}
678 678
679void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { 679void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index ad59f558d..4d0c90aa3 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -530,12 +530,12 @@ void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {
530 } 530 }
531 texture_cache.OnCPUWrite(addr, size); 531 texture_cache.OnCPUWrite(addr, size);
532 pipeline_cache.InvalidateRegion(addr, size); 532 pipeline_cache.InvalidateRegion(addr, size);
533 buffer_cache.InvalidateRegion(addr, size); 533 buffer_cache.OnCPUWrite(addr, size);
534} 534}
535 535
536void RasterizerVulkan::SyncGuestHost() { 536void RasterizerVulkan::SyncGuestHost() {
537 texture_cache.SyncGuestHost(); 537 texture_cache.SyncGuestHost();
538 // buffer_cache.SyncGuestHost(); 538 buffer_cache.SyncGuestHost();
539} 539}
540 540
541void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { 541void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) {