summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-02-16 09:33:03 -0400
committerGravatar Fernando Sahmkow2020-04-22 11:36:05 -0400
commita60a22d9c284537be2e3a6a89b8afb37e6f0c510 (patch)
tree0b7c5f0f1256dd58f5f179dbe7661063879a17d1 /src
parentUI: Replasce accurate GPU option for GPU Accuracy Level (diff)
downloadyuzu-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.h18
-rw-r--r--src/video_core/texture_cache/texture_cache.h48
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};