mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	BufferCache: Implement OnCPUWrite and SyncGuestHost
This commit is contained in:
		
							parent
							
								
									da8f17715d
								
							
						
					
					
						commit
						8b1eb44b3e
					
				@ -5,6 +5,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <list>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
@ -137,7 +138,9 @@ public:
 | 
			
		||||
        });
 | 
			
		||||
        for (auto& object : objects) {
 | 
			
		||||
            if (object->IsModified() && object->IsRegistered()) {
 | 
			
		||||
                mutex.unlock();
 | 
			
		||||
                FlushMap(object);
 | 
			
		||||
                mutex.lock();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -154,6 +157,30 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void OnCPUWrite(VAddr addr, std::size_t size) {
 | 
			
		||||
        std::lock_guard lock{mutex};
 | 
			
		||||
 | 
			
		||||
        for (const auto& object : GetMapsInRange(addr, size)) {
 | 
			
		||||
            if (object->IsMemoryMarked() && object->IsRegistered()) {
 | 
			
		||||
                Unmark(object);
 | 
			
		||||
                object->SetSyncPending(true);
 | 
			
		||||
                marked_for_unregister.emplace_back(object);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void SyncGuestHost() {
 | 
			
		||||
        std::lock_guard lock{mutex};
 | 
			
		||||
 | 
			
		||||
        for (const auto& object : marked_for_unregister) {
 | 
			
		||||
            if (object->IsRegistered()) {
 | 
			
		||||
                object->SetSyncPending(false);
 | 
			
		||||
                Unregister(object);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        marked_for_unregister.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual BufferType GetEmptyBuffer(std::size_t size) = 0;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
@ -196,17 +223,30 @@ protected:
 | 
			
		||||
        const IntervalType interval{new_map->GetStart(), new_map->GetEnd()};
 | 
			
		||||
        mapped_addresses.insert({interval, new_map});
 | 
			
		||||
        rasterizer.UpdatePagesCachedCount(cpu_addr, size, 1);
 | 
			
		||||
        new_map->SetMemoryMarked(true);
 | 
			
		||||
        if (inherit_written) {
 | 
			
		||||
            MarkRegionAsWritten(new_map->GetStart(), new_map->GetEnd() - 1);
 | 
			
		||||
            new_map->MarkAsWritten(true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Unregisters an object from the cache
 | 
			
		||||
    void Unregister(MapInterval& map) {
 | 
			
		||||
    void Unmark(const MapInterval& map) {
 | 
			
		||||
        if (!map->IsMemoryMarked()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        const std::size_t size = map->GetEnd() - map->GetStart();
 | 
			
		||||
        rasterizer.UpdatePagesCachedCount(map->GetStart(), size, -1);
 | 
			
		||||
        map->SetMemoryMarked(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Unregisters an object from the cache
 | 
			
		||||
    void Unregister(const MapInterval& map) {
 | 
			
		||||
        Unmark(map);
 | 
			
		||||
        map->MarkAsRegistered(false);
 | 
			
		||||
        if (map->IsSyncPending()) {
 | 
			
		||||
            marked_for_unregister.remove(map);
 | 
			
		||||
            map->SetSyncPending(false);
 | 
			
		||||
        }
 | 
			
		||||
        if (map->IsWritten()) {
 | 
			
		||||
            UnmarkRegionAsWritten(map->GetStart(), map->GetEnd() - 1);
 | 
			
		||||
        }
 | 
			
		||||
@ -479,6 +519,7 @@ private:
 | 
			
		||||
    u64 modified_ticks = 0;
 | 
			
		||||
 | 
			
		||||
    std::vector<u8> staging_buffer;
 | 
			
		||||
    std::list<MapInterval> marked_for_unregister;
 | 
			
		||||
 | 
			
		||||
    std::recursive_mutex mutex;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -46,6 +46,22 @@ public:
 | 
			
		||||
        return is_registered;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VAddr GetStart() const {
 | 
			
		||||
        return start;
 | 
			
		||||
    }
 | 
			
		||||
@ -83,6 +99,8 @@ private:
 | 
			
		||||
    bool is_written{};
 | 
			
		||||
    bool is_modified{};
 | 
			
		||||
    bool is_registered{};
 | 
			
		||||
    bool is_memory_marked{};
 | 
			
		||||
    bool is_sync_pending{};
 | 
			
		||||
    u64 ticks{};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@ MICROPROFILE_DEFINE(DispatchCalls, "GPU", "Execute command buffer", MP_RGB(128,
 | 
			
		||||
void DmaPusher::DispatchCalls() {
 | 
			
		||||
    MICROPROFILE_SCOPE(DispatchCalls);
 | 
			
		||||
 | 
			
		||||
    gpu.SyncGuestHost();
 | 
			
		||||
    // On entering GPU code, assume all memory may be touched by the ARM core.
 | 
			
		||||
    gpu.Maxwell3D().OnMemoryWrite();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -78,7 +78,7 @@ void ThreadManager::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ThreadManager::FlushRegion(VAddr addr, u64 size) {
 | 
			
		||||
    PushCommand(FlushRegionCommand(addr, size));
 | 
			
		||||
    system.Renderer().Rasterizer().FlushRegion(addr, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ThreadManager::InvalidateRegion(VAddr addr, u64 size) {
 | 
			
		||||
 | 
			
		||||
@ -667,13 +667,13 @@ void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) {
 | 
			
		||||
    }
 | 
			
		||||
    texture_cache.OnCPUWrite(addr, size);
 | 
			
		||||
    shader_cache.InvalidateRegion(addr, size);
 | 
			
		||||
    buffer_cache.InvalidateRegion(addr, size);
 | 
			
		||||
    buffer_cache.OnCPUWrite(addr, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerOpenGL::SyncGuestHost() {
 | 
			
		||||
    MICROPROFILE_SCOPE(OpenGL_CacheManagement);
 | 
			
		||||
    texture_cache.SyncGuestHost();
 | 
			
		||||
    // buffer_cache.SyncGuestHost();
 | 
			
		||||
    buffer_cache.SyncGuestHost();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {
 | 
			
		||||
 | 
			
		||||
@ -530,12 +530,12 @@ void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {
 | 
			
		||||
    }
 | 
			
		||||
    texture_cache.OnCPUWrite(addr, size);
 | 
			
		||||
    pipeline_cache.InvalidateRegion(addr, size);
 | 
			
		||||
    buffer_cache.InvalidateRegion(addr, size);
 | 
			
		||||
    buffer_cache.OnCPUWrite(addr, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerVulkan::SyncGuestHost() {
 | 
			
		||||
    texture_cache.SyncGuestHost();
 | 
			
		||||
    // buffer_cache.SyncGuestHost();
 | 
			
		||||
    buffer_cache.SyncGuestHost();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user