Texture Cache: Implement OnCPUWrite and SyncGuestHost
This commit is contained in:
		
							parent
							
								
									084ceb925a
								
							
						
					
					
						commit
						a60a22d9c2
					
				@ -192,6 +192,22 @@ public:
 | 
			
		||||
        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_) {
 | 
			
		||||
        is_picked = is_picked_;
 | 
			
		||||
    }
 | 
			
		||||
@ -303,6 +319,8 @@ private:
 | 
			
		||||
    bool is_target{};
 | 
			
		||||
    bool is_registered{};
 | 
			
		||||
    bool is_picked{};
 | 
			
		||||
    bool is_memory_marked{};
 | 
			
		||||
    bool is_sync_pending{};
 | 
			
		||||
    u32 index{NO_RT};
 | 
			
		||||
    u64 modification_tick{};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
#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
 | 
			
		||||
     * collide. Protection is currently only done on 3D slices.
 | 
			
		||||
@ -85,7 +110,9 @@ public:
 | 
			
		||||
            return a->GetModificationTick() < b->GetModificationTick();
 | 
			
		||||
        });
 | 
			
		||||
        for (const auto& surface : surfaces) {
 | 
			
		||||
            mutex.unlock();
 | 
			
		||||
            FlushSurface(surface);
 | 
			
		||||
            mutex.lock();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -345,9 +372,20 @@ protected:
 | 
			
		||||
        surface->SetCpuAddr(*cpu_addr);
 | 
			
		||||
        RegisterInnerCache(surface);
 | 
			
		||||
        surface->MarkAsRegistered(true);
 | 
			
		||||
        surface->SetMemoryMarked(true);
 | 
			
		||||
        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) {
 | 
			
		||||
        if (guard_render_targets && surface->IsProtected()) {
 | 
			
		||||
            return;
 | 
			
		||||
@ -355,9 +393,11 @@ protected:
 | 
			
		||||
        if (!guard_render_targets && surface->IsRenderTarget()) {
 | 
			
		||||
            ManageRenderTargetUnregister(surface);
 | 
			
		||||
        }
 | 
			
		||||
        const std::size_t size = surface->GetSizeInBytes();
 | 
			
		||||
        const VAddr cpu_addr = surface->GetCpuAddr();
 | 
			
		||||
        rasterizer.UpdatePagesCachedCount(cpu_addr, size, -1);
 | 
			
		||||
        Unmark(surface);
 | 
			
		||||
        if (surface->IsSyncPending()) {
 | 
			
		||||
            marked_for_unregister.remove(surface);
 | 
			
		||||
            surface->SetSyncPending(false);
 | 
			
		||||
        }
 | 
			
		||||
        UnregisterInnerCache(surface);
 | 
			
		||||
        surface->MarkAsRegistered(false);
 | 
			
		||||
        ReserveSurface(surface->GetSurfaceParams(), surface);
 | 
			
		||||
@ -1150,6 +1190,8 @@ private:
 | 
			
		||||
    std::unordered_map<u32, TSurface> invalid_cache;
 | 
			
		||||
    std::vector<u8> invalid_memory;
 | 
			
		||||
 | 
			
		||||
    std::list<TSurface> marked_for_unregister;
 | 
			
		||||
 | 
			
		||||
    StagingCache staging_cache;
 | 
			
		||||
    std::recursive_mutex mutex;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user