diff options
| author | 2020-02-16 09:33:03 -0400 | |
|---|---|---|
| committer | 2020-04-22 11:36:05 -0400 | |
| commit | a60a22d9c284537be2e3a6a89b8afb37e6f0c510 (patch) | |
| tree | 0b7c5f0f1256dd58f5f179dbe7661063879a17d1 /src | |
| parent | UI: Replasce accurate GPU option for GPU Accuracy Level (diff) | |
| download | yuzu-a60a22d9c284537be2e3a6a89b8afb37e6f0c510.tar.gz yuzu-a60a22d9c284537be2e3a6a89b8afb37e6f0c510.tar.xz yuzu-a60a22d9c284537be2e3a6a89b8afb37e6f0c510.zip | |
Texture Cache: Implement OnCPUWrite and SyncGuestHost
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/texture_cache/surface_base.h | 18 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 48 |
2 files changed, 63 insertions, 3 deletions
diff --git a/src/video_core/texture_cache/surface_base.h b/src/video_core/texture_cache/surface_base.h index c5ab21f56..79e10ffbb 100644 --- a/src/video_core/texture_cache/surface_base.h +++ b/src/video_core/texture_cache/surface_base.h | |||
| @@ -192,6 +192,22 @@ public: | |||
| 192 | index = index_; | 192 | index = index_; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | void SetMemoryMarked(bool is_memory_marked_) { | ||
| 196 | is_memory_marked = is_memory_marked_; | ||
| 197 | } | ||
| 198 | |||
| 199 | bool IsMemoryMarked() const { | ||
| 200 | return is_memory_marked; | ||
| 201 | } | ||
| 202 | |||
| 203 | void SetSyncPending(bool is_sync_pending_) { | ||
| 204 | is_sync_pending = is_sync_pending_; | ||
| 205 | } | ||
| 206 | |||
| 207 | bool IsSyncPending() const { | ||
| 208 | return is_sync_pending; | ||
| 209 | } | ||
| 210 | |||
| 195 | void MarkAsPicked(bool is_picked_) { | 211 | void MarkAsPicked(bool is_picked_) { |
| 196 | is_picked = is_picked_; | 212 | is_picked = is_picked_; |
| 197 | } | 213 | } |
| @@ -303,6 +319,8 @@ private: | |||
| 303 | bool is_target{}; | 319 | bool is_target{}; |
| 304 | bool is_registered{}; | 320 | bool is_registered{}; |
| 305 | bool is_picked{}; | 321 | bool is_picked{}; |
| 322 | bool is_memory_marked{}; | ||
| 323 | bool is_sync_pending{}; | ||
| 306 | u32 index{NO_RT}; | 324 | u32 index{NO_RT}; |
| 307 | u64 modification_tick{}; | 325 | u64 modification_tick{}; |
| 308 | }; | 326 | }; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 7432691d1..441fda53d 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <algorithm> | 7 | #include <algorithm> |
| 8 | #include <array> | 8 | #include <array> |
| 9 | #include <list> | ||
| 9 | #include <memory> | 10 | #include <memory> |
| 10 | #include <mutex> | 11 | #include <mutex> |
| 11 | #include <set> | 12 | #include <set> |
| @@ -62,6 +63,30 @@ public: | |||
| 62 | } | 63 | } |
| 63 | } | 64 | } |
| 64 | 65 | ||
| 66 | void OnCPUWrite(CacheAddr addr, std::size_t size) { | ||
| 67 | std::lock_guard lock{mutex}; | ||
| 68 | |||
| 69 | for (const auto& surface : GetSurfacesInRegion(addr, size)) { | ||
| 70 | if (surface->IsMemoryMarked()) { | ||
| 71 | Unmark(surface); | ||
| 72 | surface->SetSyncPending(true); | ||
| 73 | marked_for_unregister.emplace_back(surface); | ||
| 74 | } | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | void SyncGuestHost() { | ||
| 79 | std::lock_guard lock{mutex}; | ||
| 80 | |||
| 81 | for (const auto& surface : marked_for_unregister) { | ||
| 82 | if (surface->IsRegistered()) { | ||
| 83 | surface->SetSyncPending(false); | ||
| 84 | Unregister(surface); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | marked_for_unregister.clear(); | ||
| 88 | } | ||
| 89 | |||
| 65 | /** | 90 | /** |
| 66 | * Guarantees that rendertargets don't unregister themselves if the | 91 | * Guarantees that rendertargets don't unregister themselves if the |
| 67 | * collide. Protection is currently only done on 3D slices. | 92 | * collide. Protection is currently only done on 3D slices. |
| @@ -85,7 +110,9 @@ public: | |||
| 85 | return a->GetModificationTick() < b->GetModificationTick(); | 110 | return a->GetModificationTick() < b->GetModificationTick(); |
| 86 | }); | 111 | }); |
| 87 | for (const auto& surface : surfaces) { | 112 | for (const auto& surface : surfaces) { |
| 113 | mutex.unlock(); | ||
| 88 | FlushSurface(surface); | 114 | FlushSurface(surface); |
| 115 | mutex.lock(); | ||
| 89 | } | 116 | } |
| 90 | } | 117 | } |
| 91 | 118 | ||
| @@ -345,9 +372,20 @@ protected: | |||
| 345 | surface->SetCpuAddr(*cpu_addr); | 372 | surface->SetCpuAddr(*cpu_addr); |
| 346 | RegisterInnerCache(surface); | 373 | RegisterInnerCache(surface); |
| 347 | surface->MarkAsRegistered(true); | 374 | surface->MarkAsRegistered(true); |
| 375 | surface->SetMemoryMarked(true); | ||
| 348 | rasterizer.UpdatePagesCachedCount(*cpu_addr, size, 1); | 376 | rasterizer.UpdatePagesCachedCount(*cpu_addr, size, 1); |
| 349 | } | 377 | } |
| 350 | 378 | ||
| 379 | void Unmark(TSurface surface) { | ||
| 380 | if (!surface->IsMemoryMarked()) { | ||
| 381 | return; | ||
| 382 | } | ||
| 383 | const std::size_t size = surface->GetSizeInBytes(); | ||
| 384 | const VAddr cpu_addr = surface->GetCpuAddr(); | ||
| 385 | rasterizer.UpdatePagesCachedCount(cpu_addr, size, -1); | ||
| 386 | surface->SetMemoryMarked(false); | ||
| 387 | } | ||
| 388 | |||
| 351 | void Unregister(TSurface surface) { | 389 | void Unregister(TSurface surface) { |
| 352 | if (guard_render_targets && surface->IsProtected()) { | 390 | if (guard_render_targets && surface->IsProtected()) { |
| 353 | return; | 391 | return; |
| @@ -355,9 +393,11 @@ protected: | |||
| 355 | if (!guard_render_targets && surface->IsRenderTarget()) { | 393 | if (!guard_render_targets && surface->IsRenderTarget()) { |
| 356 | ManageRenderTargetUnregister(surface); | 394 | ManageRenderTargetUnregister(surface); |
| 357 | } | 395 | } |
| 358 | const std::size_t size = surface->GetSizeInBytes(); | 396 | Unmark(surface); |
| 359 | const VAddr cpu_addr = surface->GetCpuAddr(); | 397 | if (surface->IsSyncPending()) { |
| 360 | rasterizer.UpdatePagesCachedCount(cpu_addr, size, -1); | 398 | marked_for_unregister.remove(surface); |
| 399 | surface->SetSyncPending(false); | ||
| 400 | } | ||
| 361 | UnregisterInnerCache(surface); | 401 | UnregisterInnerCache(surface); |
| 362 | surface->MarkAsRegistered(false); | 402 | surface->MarkAsRegistered(false); |
| 363 | ReserveSurface(surface->GetSurfaceParams(), surface); | 403 | ReserveSurface(surface->GetSurfaceParams(), surface); |
| @@ -1150,6 +1190,8 @@ private: | |||
| 1150 | std::unordered_map<u32, TSurface> invalid_cache; | 1190 | std::unordered_map<u32, TSurface> invalid_cache; |
| 1151 | std::vector<u8> invalid_memory; | 1191 | std::vector<u8> invalid_memory; |
| 1152 | 1192 | ||
| 1193 | std::list<TSurface> marked_for_unregister; | ||
| 1194 | |||
| 1153 | StagingCache staging_cache; | 1195 | StagingCache staging_cache; |
| 1154 | std::recursive_mutex mutex; | 1196 | std::recursive_mutex mutex; |
| 1155 | }; | 1197 | }; |