Texture Cache: Implement OnCPUWrite and SyncGuestHost
This commit is contained in:
		| @@ -192,6 +192,22 @@ public: | |||||||
|         index = index_; |         index = index_; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     void SetMemoryMarked(bool is_memory_marked_) { | ||||||
|  |         is_memory_marked = is_memory_marked_; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     bool IsMemoryMarked() const { | ||||||
|  |         return is_memory_marked; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void SetSyncPending(bool is_sync_pending_) { | ||||||
|  |         is_sync_pending = is_sync_pending_; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     bool IsSyncPending() const { | ||||||
|  |         return is_sync_pending; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     void MarkAsPicked(bool is_picked_) { |     void MarkAsPicked(bool is_picked_) { | ||||||
|         is_picked = is_picked_; |         is_picked = is_picked_; | ||||||
|     } |     } | ||||||
| @@ -303,6 +319,8 @@ private: | |||||||
|     bool is_target{}; |     bool is_target{}; | ||||||
|     bool is_registered{}; |     bool is_registered{}; | ||||||
|     bool is_picked{}; |     bool is_picked{}; | ||||||
|  |     bool is_memory_marked{}; | ||||||
|  |     bool is_sync_pending{}; | ||||||
|     u32 index{NO_RT}; |     u32 index{NO_RT}; | ||||||
|     u64 modification_tick{}; |     u64 modification_tick{}; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
|  |  | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| #include <array> | #include <array> | ||||||
|  | #include <list> | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <mutex> | #include <mutex> | ||||||
| #include <set> | #include <set> | ||||||
| @@ -62,6 +63,30 @@ public: | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     void OnCPUWrite(CacheAddr addr, std::size_t size) { | ||||||
|  |         std::lock_guard lock{mutex}; | ||||||
|  |  | ||||||
|  |         for (const auto& surface : GetSurfacesInRegion(addr, size)) { | ||||||
|  |             if (surface->IsMemoryMarked()) { | ||||||
|  |                 Unmark(surface); | ||||||
|  |                 surface->SetSyncPending(true); | ||||||
|  |                 marked_for_unregister.emplace_back(surface); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void SyncGuestHost() { | ||||||
|  |         std::lock_guard lock{mutex}; | ||||||
|  |  | ||||||
|  |         for (const auto& surface : marked_for_unregister) { | ||||||
|  |             if (surface->IsRegistered()) { | ||||||
|  |                 surface->SetSyncPending(false); | ||||||
|  |                 Unregister(surface); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         marked_for_unregister.clear(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Guarantees that rendertargets don't unregister themselves if the |      * Guarantees that rendertargets don't unregister themselves if the | ||||||
|      * collide. Protection is currently only done on 3D slices. |      * collide. Protection is currently only done on 3D slices. | ||||||
| @@ -85,7 +110,9 @@ public: | |||||||
|             return a->GetModificationTick() < b->GetModificationTick(); |             return a->GetModificationTick() < b->GetModificationTick(); | ||||||
|         }); |         }); | ||||||
|         for (const auto& surface : surfaces) { |         for (const auto& surface : surfaces) { | ||||||
|  |             mutex.unlock(); | ||||||
|             FlushSurface(surface); |             FlushSurface(surface); | ||||||
|  |             mutex.lock(); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -345,9 +372,20 @@ protected: | |||||||
|         surface->SetCpuAddr(*cpu_addr); |         surface->SetCpuAddr(*cpu_addr); | ||||||
|         RegisterInnerCache(surface); |         RegisterInnerCache(surface); | ||||||
|         surface->MarkAsRegistered(true); |         surface->MarkAsRegistered(true); | ||||||
|  |         surface->SetMemoryMarked(true); | ||||||
|         rasterizer.UpdatePagesCachedCount(*cpu_addr, size, 1); |         rasterizer.UpdatePagesCachedCount(*cpu_addr, size, 1); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     void Unmark(TSurface surface) { | ||||||
|  |         if (!surface->IsMemoryMarked()) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         const std::size_t size = surface->GetSizeInBytes(); | ||||||
|  |         const VAddr cpu_addr = surface->GetCpuAddr(); | ||||||
|  |         rasterizer.UpdatePagesCachedCount(cpu_addr, size, -1); | ||||||
|  |         surface->SetMemoryMarked(false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     void Unregister(TSurface surface) { |     void Unregister(TSurface surface) { | ||||||
|         if (guard_render_targets && surface->IsProtected()) { |         if (guard_render_targets && surface->IsProtected()) { | ||||||
|             return; |             return; | ||||||
| @@ -355,9 +393,11 @@ protected: | |||||||
|         if (!guard_render_targets && surface->IsRenderTarget()) { |         if (!guard_render_targets && surface->IsRenderTarget()) { | ||||||
|             ManageRenderTargetUnregister(surface); |             ManageRenderTargetUnregister(surface); | ||||||
|         } |         } | ||||||
|         const std::size_t size = surface->GetSizeInBytes(); |         Unmark(surface); | ||||||
|         const VAddr cpu_addr = surface->GetCpuAddr(); |         if (surface->IsSyncPending()) { | ||||||
|         rasterizer.UpdatePagesCachedCount(cpu_addr, size, -1); |             marked_for_unregister.remove(surface); | ||||||
|  |             surface->SetSyncPending(false); | ||||||
|  |         } | ||||||
|         UnregisterInnerCache(surface); |         UnregisterInnerCache(surface); | ||||||
|         surface->MarkAsRegistered(false); |         surface->MarkAsRegistered(false); | ||||||
|         ReserveSurface(surface->GetSurfaceParams(), surface); |         ReserveSurface(surface->GetSurfaceParams(), surface); | ||||||
| @@ -1150,6 +1190,8 @@ private: | |||||||
|     std::unordered_map<u32, TSurface> invalid_cache; |     std::unordered_map<u32, TSurface> invalid_cache; | ||||||
|     std::vector<u8> invalid_memory; |     std::vector<u8> invalid_memory; | ||||||
|  |  | ||||||
|  |     std::list<TSurface> marked_for_unregister; | ||||||
|  |  | ||||||
|     StagingCache staging_cache; |     StagingCache staging_cache; | ||||||
|     std::recursive_mutex mutex; |     std::recursive_mutex mutex; | ||||||
| }; | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user