diff options
| -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_pipeline_cache.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 4 |
4 files changed, 62 insertions, 7 deletions
diff --git a/src/video_core/rasterizer_cache.h b/src/video_core/rasterizer_cache.h index 22987751e..096ee337c 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 the object is marking rasterizer memory. | ||
| 79 | bool is_sync_pending{}; ///< Whether the object is 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 92ca22136..8116a5daa 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -727,15 +727,15 @@ void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) { | |||
| 727 | return; | 727 | return; |
| 728 | } | 728 | } |
| 729 | texture_cache.OnCPUWrite(addr, size); | 729 | texture_cache.OnCPUWrite(addr, size); |
| 730 | shader_cache.InvalidateRegion(addr, size); | 730 | shader_cache.OnCPUWrite(addr, size); |
| 731 | buffer_cache.OnCPUWrite(addr, size); | 731 | buffer_cache.OnCPUWrite(addr, size); |
| 732 | query_cache.InvalidateRegion(addr, size); | ||
| 733 | } | 732 | } |
| 734 | 733 | ||
| 735 | void RasterizerOpenGL::SyncGuestHost() { | 734 | void RasterizerOpenGL::SyncGuestHost() { |
| 736 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | 735 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); |
| 737 | texture_cache.SyncGuestHost(); | 736 | texture_cache.SyncGuestHost(); |
| 738 | buffer_cache.SyncGuestHost(); | 737 | buffer_cache.SyncGuestHost(); |
| 738 | shader_cache.SyncGuestHost(); | ||
| 739 | } | 739 | } |
| 740 | 740 | ||
| 741 | void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) { | 741 | void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) { |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index fe45ed269..a5c7b7945 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -329,8 +329,7 @@ VKPipelineCache::DecompileShaders(const GraphicsPipelineCacheKey& key) { | |||
| 329 | 329 | ||
| 330 | const GPUVAddr gpu_addr = GetShaderAddress(system, program_enum); | 330 | const GPUVAddr gpu_addr = GetShaderAddress(system, program_enum); |
| 331 | const auto cpu_addr = memory_manager.GpuToCpuAddress(gpu_addr); | 331 | const auto cpu_addr = memory_manager.GpuToCpuAddress(gpu_addr); |
| 332 | ASSERT(cpu_addr); | 332 | const auto shader = cpu_addr ? TryGet(*cpu_addr) : null_shader; |
| 333 | const auto shader = TryGet(*cpu_addr); | ||
| 334 | ASSERT(shader); | 333 | ASSERT(shader); |
| 335 | 334 | ||
| 336 | const std::size_t stage = index == 0 ? 0 : index - 1; // Stage indices are 0 - 5 | 335 | const std::size_t stage = index == 0 ? 0 : index - 1; // Stage indices are 0 - 5 |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 17a2efe8e..be5b77fae 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) { |