Texture Cache: Implement OnCPUWrite and SyncGuestHost
This commit is contained in:
		
							parent
							
								
									084ceb925a
								
							
						
					
					
						commit
						a60a22d9c2
					
				@ -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;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user