diff options
| author | 2020-05-09 19:25:29 -0400 | |
|---|---|---|
| committer | 2020-05-09 19:25:29 -0400 | |
| commit | 0a4be73b9b2b0e759fe4fff42084d29c3cd1e4c2 (patch) | |
| tree | 93d749146b582b14ec578977088245896a392107 /src | |
| parent | Merge pull request #3902 from degasus/cmake_version_checks (diff) | |
| download | yuzu-0a4be73b9b2b0e759fe4fff42084d29c3cd1e4c2.tar.gz yuzu-0a4be73b9b2b0e759fe4fff42084d29c3cd1e4c2.tar.xz yuzu-0a4be73b9b2b0e759fe4fff42084d29c3cd1e4c2.zip | |
VideoCore: Use SyncGuestMemory mechanism for Shader/Pipeline Cache invalidation.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/rasterizer_cache.h | 58 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 4 |
3 files changed, 61 insertions, 5 deletions
diff --git a/src/video_core/rasterizer_cache.h b/src/video_core/rasterizer_cache.h index 22987751e..5236fbb00 100644 --- a/src/video_core/rasterizer_cache.h +++ b/src/video_core/rasterizer_cache.h | |||
| @@ -56,9 +56,27 @@ public: | |||
| 56 | last_modified_ticks = cache.GetModifiedTicks(); | 56 | last_modified_ticks = cache.GetModifiedTicks(); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | void SetMemoryMarked(bool is_memory_marked_) { | ||
| 60 | is_memory_marked = is_memory_marked_; | ||
| 61 | } | ||
| 62 | |||
| 63 | bool IsMemoryMarked() const { | ||
| 64 | return is_memory_marked; | ||
| 65 | } | ||
| 66 | |||
| 67 | void SetSyncPending(bool is_sync_pending_) { | ||
| 68 | is_sync_pending = is_sync_pending_; | ||
| 69 | } | ||
| 70 | |||
| 71 | bool IsSyncPending() const { | ||
| 72 | return is_sync_pending; | ||
| 73 | } | ||
| 74 | |||
| 59 | private: | 75 | private: |
| 60 | bool is_registered{}; ///< Whether the object is currently registered with the cache | 76 | bool is_registered{}; ///< Whether the object is currently registered with the cache |
| 61 | bool is_dirty{}; ///< Whether the object is dirty (out of sync with guest memory) | 77 | bool is_dirty{}; ///< Whether the object is dirty (out of sync with guest memory) |
| 78 | bool is_memory_marked{}; ///< Whether it's marking rasterizer memory. | ||
| 79 | bool is_sync_pending{}; ///< Whether it's pending deletion. | ||
| 62 | u64 last_modified_ticks{}; ///< When the object was last modified, used for in-order flushing | 80 | u64 last_modified_ticks{}; ///< When the object was last modified, used for in-order flushing |
| 63 | VAddr cpu_addr{}; ///< Cpu address memory, unique from emulated virtual address space | 81 | VAddr cpu_addr{}; ///< Cpu address memory, unique from emulated virtual address space |
| 64 | }; | 82 | }; |
| @@ -94,6 +112,30 @@ public: | |||
| 94 | } | 112 | } |
| 95 | } | 113 | } |
| 96 | 114 | ||
| 115 | void OnCPUWrite(VAddr addr, std::size_t size) { | ||
| 116 | std::lock_guard lock{mutex}; | ||
| 117 | |||
| 118 | for (const auto& object : GetSortedObjectsFromRegion(addr, size)) { | ||
| 119 | if (object->IsRegistered()) { | ||
| 120 | UnmarkMemory(object); | ||
| 121 | object->SetSyncPending(true); | ||
| 122 | marked_for_unregister.emplace_back(object); | ||
| 123 | } | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | void SyncGuestHost() { | ||
| 128 | std::lock_guard lock{mutex}; | ||
| 129 | |||
| 130 | for (const auto& object : marked_for_unregister) { | ||
| 131 | if (object->IsRegistered()) { | ||
| 132 | object->SetSyncPending(false); | ||
| 133 | Unregister(object); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | marked_for_unregister.clear(); | ||
| 137 | } | ||
| 138 | |||
| 97 | /// Invalidates everything in the cache | 139 | /// Invalidates everything in the cache |
| 98 | void InvalidateAll() { | 140 | void InvalidateAll() { |
| 99 | std::lock_guard lock{mutex}; | 141 | std::lock_guard lock{mutex}; |
| @@ -120,19 +162,32 @@ protected: | |||
| 120 | interval_cache.add({GetInterval(object), ObjectSet{object}}); | 162 | interval_cache.add({GetInterval(object), ObjectSet{object}}); |
| 121 | map_cache.insert({object->GetCpuAddr(), object}); | 163 | map_cache.insert({object->GetCpuAddr(), object}); |
| 122 | rasterizer.UpdatePagesCachedCount(object->GetCpuAddr(), object->GetSizeInBytes(), 1); | 164 | rasterizer.UpdatePagesCachedCount(object->GetCpuAddr(), object->GetSizeInBytes(), 1); |
| 165 | object->SetMemoryMarked(true); | ||
| 123 | } | 166 | } |
| 124 | 167 | ||
| 125 | /// Unregisters an object from the cache | 168 | /// Unregisters an object from the cache |
| 126 | virtual void Unregister(const T& object) { | 169 | virtual void Unregister(const T& object) { |
| 127 | std::lock_guard lock{mutex}; | 170 | std::lock_guard lock{mutex}; |
| 128 | 171 | ||
| 172 | UnmarkMemory(object); | ||
| 129 | object->SetIsRegistered(false); | 173 | object->SetIsRegistered(false); |
| 130 | rasterizer.UpdatePagesCachedCount(object->GetCpuAddr(), object->GetSizeInBytes(), -1); | 174 | if (object->IsSyncPending()) { |
| 175 | marked_for_unregister.remove(object); | ||
| 176 | object->SetSyncPending(false); | ||
| 177 | } | ||
| 131 | const VAddr addr = object->GetCpuAddr(); | 178 | const VAddr addr = object->GetCpuAddr(); |
| 132 | interval_cache.subtract({GetInterval(object), ObjectSet{object}}); | 179 | interval_cache.subtract({GetInterval(object), ObjectSet{object}}); |
| 133 | map_cache.erase(addr); | 180 | map_cache.erase(addr); |
| 134 | } | 181 | } |
| 135 | 182 | ||
| 183 | void UnmarkMemory(const T& object) { | ||
| 184 | if (!object->IsMemoryMarked()) { | ||
| 185 | return; | ||
| 186 | } | ||
| 187 | rasterizer.UpdatePagesCachedCount(object->GetCpuAddr(), object->GetSizeInBytes(), -1); | ||
| 188 | object->SetMemoryMarked(false); | ||
| 189 | } | ||
| 190 | |||
| 136 | /// Returns a ticks counter used for tracking when cached objects were last modified | 191 | /// Returns a ticks counter used for tracking when cached objects were last modified |
| 137 | u64 GetModifiedTicks() { | 192 | u64 GetModifiedTicks() { |
| 138 | std::lock_guard lock{mutex}; | 193 | std::lock_guard lock{mutex}; |
| @@ -194,4 +249,5 @@ private: | |||
| 194 | IntervalCache interval_cache; ///< Cache of objects | 249 | IntervalCache interval_cache; ///< Cache of objects |
| 195 | u64 modified_ticks{}; ///< Counter of cache state ticks, used for in-order flushing | 250 | u64 modified_ticks{}; ///< Counter of cache state ticks, used for in-order flushing |
| 196 | VideoCore::RasterizerInterface& rasterizer; | 251 | VideoCore::RasterizerInterface& rasterizer; |
| 252 | std::list<T> marked_for_unregister; | ||
| 197 | }; | 253 | }; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 69dcf952f..467891457 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -701,15 +701,15 @@ void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { | |||
| 701 | return; | 701 | return; |
| 702 | } | 702 | } |
| 703 | texture_cache.OnCPUWrite(addr, size); | 703 | texture_cache.OnCPUWrite(addr, size); |
| 704 | shader_cache.InvalidateRegion(addr, size); | 704 | shader_cache.OnCPUWrite(addr, size); |
| 705 | buffer_cache.OnCPUWrite(addr, size); | 705 | buffer_cache.OnCPUWrite(addr, size); |
| 706 | query_cache.InvalidateRegion(addr, size); | ||
| 707 | } | 706 | } |
| 708 | 707 | ||
| 709 | void RasterizerOpenGL::SyncGuestHost() { | 708 | void RasterizerOpenGL::SyncGuestHost() { |
| 710 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | 709 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); |
| 711 | texture_cache.SyncGuestHost(); | 710 | texture_cache.SyncGuestHost(); |
| 712 | buffer_cache.SyncGuestHost(); | 711 | buffer_cache.SyncGuestHost(); |
| 712 | shader_cache.SyncGuestHost(); | ||
| 713 | } | 713 | } |
| 714 | 714 | ||
| 715 | void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) { | 715 | void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) { |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 8b009fc22..f118e5990 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -532,14 +532,14 @@ void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) { | |||
| 532 | return; | 532 | return; |
| 533 | } | 533 | } |
| 534 | texture_cache.OnCPUWrite(addr, size); | 534 | texture_cache.OnCPUWrite(addr, size); |
| 535 | pipeline_cache.InvalidateRegion(addr, size); | 535 | pipeline_cache.OnCPUWrite(addr, size); |
| 536 | buffer_cache.OnCPUWrite(addr, size); | 536 | buffer_cache.OnCPUWrite(addr, size); |
| 537 | query_cache.InvalidateRegion(addr, size); | ||
| 538 | } | 537 | } |
| 539 | 538 | ||
| 540 | void RasterizerVulkan::SyncGuestHost() { | 539 | void RasterizerVulkan::SyncGuestHost() { |
| 541 | texture_cache.SyncGuestHost(); | 540 | texture_cache.SyncGuestHost(); |
| 542 | buffer_cache.SyncGuestHost(); | 541 | buffer_cache.SyncGuestHost(); |
| 542 | pipeline_cache.SyncGuestHost(); | ||
| 543 | } | 543 | } |
| 544 | 544 | ||
| 545 | void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) { | 545 | void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) { |