diff options
| author | 2020-02-16 10:08:07 -0400 | |
|---|---|---|
| committer | 2020-04-22 11:36:07 -0400 | |
| commit | 8b1eb44b3ed5483071dc6754662a277b45e4a809 (patch) | |
| tree | ed985a775881cce60a98ab7ddc43803ccf7d463c | |
| parent | GPU: Refactor synchronization on Async GPU (diff) | |
| download | yuzu-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.h | 45 | ||||
| -rw-r--r-- | src/video_core/buffer_cache/map_interval.h | 18 | ||||
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/gpu_thread.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 4 |
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 | ||
| 159 | protected: | 186 | protected: |
| @@ -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, | |||
| 21 | void DmaPusher::DispatchCalls() { | 21 | void 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 | ||
| 80 | void ThreadManager::FlushRegion(VAddr addr, u64 size) { | 80 | void ThreadManager::FlushRegion(VAddr addr, u64 size) { |
| 81 | PushCommand(FlushRegionCommand(addr, size)); | 81 | system.Renderer().Rasterizer().FlushRegion(addr, size); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | void ThreadManager::InvalidateRegion(VAddr addr, u64 size) { | 84 | void 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 | ||
| 673 | void RasterizerOpenGL::SyncGuestHost() { | 673 | void 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 | ||
| 679 | void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { | 679 | void 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 | ||
| 536 | void RasterizerVulkan::SyncGuestHost() { | 536 | void RasterizerVulkan::SyncGuestHost() { |
| 537 | texture_cache.SyncGuestHost(); | 537 | texture_cache.SyncGuestHost(); |
| 538 | // buffer_cache.SyncGuestHost(); | 538 | buffer_cache.SyncGuestHost(); |
| 539 | } | 539 | } |
| 540 | 540 | ||
| 541 | void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { | 541 | void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { |