summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/rasterizer_cache.h58
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp3
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp4
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
59private: 75private:
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
735void RasterizerOpenGL::SyncGuestHost() { 734void 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
741void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) { 741void 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
540void RasterizerVulkan::SyncGuestHost() { 539void 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
545void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) { 545void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) {