From 31ac54258a2cea6d6f63c05a576baf4d4142ffa8 Mon Sep 17 00:00:00 2001 From: Lander Gallastegi Date: Sat, 5 Jul 2025 17:52:22 +0200 Subject: [PATCH] Tracker locking --- src/video_core/buffer_cache/buffer_cache.cpp | 4 ++ src/video_core/buffer_cache/buffer_cache.h | 5 +-- src/video_core/buffer_cache/memory_tracker.h | 40 ++++++++++++++----- src/video_core/page_manager.cpp | 1 + .../renderer_vulkan/vk_rasterizer.h | 1 - 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_cache.cpp b/src/video_core/buffer_cache/buffer_cache.cpp index d55e05d1e..9096fa606 100644 --- a/src/video_core/buffer_cache/buffer_cache.cpp +++ b/src/video_core/buffer_cache/buffer_cache.cpp @@ -996,6 +996,10 @@ void BufferCache::SynchronizeBuffersInRange(VAddr device_addr, u64 size) { }); } +void BufferCache::SynchronizeBuffersForDma() { + +} + void BufferCache::MemoryBarrier() { // Vulkan doesn't know which buffer we access in a shader if we use // BufferDeviceAddress. We need a full memory barrier. diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 900a27aee..14fe957e0 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -5,7 +5,6 @@ #include #include -#include "common/div_ceil.h" #include "common/slot_vector.h" #include "common/types.h" #include "video_core/buffer_cache/buffer.h" @@ -156,8 +155,8 @@ public: /// Synchronizes all buffers in the specified range. void SynchronizeBuffersInRange(VAddr device_addr, u64 size); - /// Synchronizes all buffers neede for DMA. - void SynchronizeDmaBuffers(); + /// Synchronizes all buffers for DMA. + void SynchronizeBuffersForDma(); /// Record memory barrier. Used for buffers when accessed via BDA. void MemoryBarrier(); diff --git a/src/video_core/buffer_cache/memory_tracker.h b/src/video_core/buffer_cache/memory_tracker.h index ca87c7df0..5ac129967 100644 --- a/src/video_core/buffer_cache/memory_tracker.h +++ b/src/video_core/buffer_cache/memory_tracker.h @@ -5,6 +5,7 @@ #include #include +#include #include #include #include "common/debug.h" @@ -24,8 +25,9 @@ public: ~MemoryTracker() = default; /// Returns true if a region has been modified from the CPU + template bool IsRegionCpuModified(VAddr query_cpu_addr, u64 query_size) noexcept { - return IteratePages( + return IteratePages( query_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) { std::scoped_lock lk{manager->lock}; return manager->template IsRegionModified(offset, size); @@ -33,8 +35,9 @@ public: } /// Returns true if a region has been modified from the GPU + template bool IsRegionGpuModified(VAddr query_cpu_addr, u64 query_size) noexcept { - return IteratePages( + return IteratePages( query_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) { std::scoped_lock lk{manager->lock}; return manager->template IsRegionModified(offset, size); @@ -42,8 +45,9 @@ public: } /// Mark region as CPU modified, notifying the device_tracker about this change + template void MarkRegionAsCpuModified(VAddr dirty_cpu_addr, u64 query_size) { - IteratePages(dirty_cpu_addr, query_size, + IteratePages(dirty_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) { std::scoped_lock lk{manager->lock}; manager->template ChangeRegionState( @@ -52,8 +56,9 @@ public: } /// Unmark region as modified from the host GPU + template void UnmarkRegionAsGpuModified(VAddr dirty_cpu_addr, u64 query_size) noexcept { - IteratePages(dirty_cpu_addr, query_size, + IteratePages(dirty_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) { std::scoped_lock lk{manager->lock}; manager->template ChangeRegionState( @@ -62,8 +67,9 @@ public: } /// Removes all protection from a page and ensures GPU data has been flushed if requested + template void InvalidateRegion(VAddr cpu_addr, u64 size, bool try_flush, auto&& on_flush) noexcept { - IteratePages( + IteratePages( cpu_addr, size, [try_flush, &on_flush](RegionManager* manager, u64 offset, size_t size) { const bool should_flush = [&] { @@ -86,8 +92,9 @@ public: } /// Call 'func' for each CPU modified range and unmark those pages as CPU modified + template void ForEachUploadRange(VAddr query_cpu_range, u64 query_size, bool is_written, auto&& func) { - IteratePages(query_cpu_range, query_size, + IteratePages(query_cpu_range, query_size, [&func, is_written](RegionManager* manager, u64 offset, size_t size) { std::scoped_lock lk{manager->lock}; manager->template ForEachModifiedRange( @@ -100,9 +107,9 @@ public: } /// Call 'func' for each GPU modified range and unmark those pages as GPU modified - template + template void ForEachDownloadRange(VAddr query_cpu_range, u64 query_size, auto&& func) { - IteratePages(query_cpu_range, query_size, + IteratePages(query_cpu_range, query_size, [&func](RegionManager* manager, u64 offset, size_t size) { std::scoped_lock lk{manager->lock}; manager->template ForEachModifiedRange( @@ -110,6 +117,17 @@ public: }); } + /// Lck the memory tracker. + void Lock() { + global_lock.lock(); + } + + /// Unlock the memory tracker. + void Unlock() { + global_lock.unlock(); + } + + private: /** * @brief IteratePages Iterates L2 word manager page table. @@ -118,9 +136,12 @@ private: * @param func Callback for each word manager. * @return */ - template + template bool IteratePages(VAddr cpu_address, size_t size, Func&& func) { RENDERER_TRACE; + if constexpr (locking) { + std::shared_lock lock{global_lock}; + } using FuncReturn = typename std::invoke_result::type; static constexpr bool BOOL_BREAK = std::is_same_v; std::size_t remaining_size{size}; @@ -177,6 +198,7 @@ private: std::deque> manager_pool; std::vector free_managers; std::array top_tier{}; + std::shared_mutex global_lock; }; } // namespace VideoCore diff --git a/src/video_core/page_manager.cpp b/src/video_core/page_manager.cpp index 63297bfdc..daa1218cc 100644 --- a/src/video_core/page_manager.cpp +++ b/src/video_core/page_manager.cpp @@ -4,6 +4,7 @@ #include #include "common/assert.h" #include "common/debug.h" +#include "common/div_ceil.h" #include "common/range_lock.h" #include "common/signal_context.h" #include "core/memory.h" diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 4a978746c..1c307651a 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -3,7 +3,6 @@ #pragma once -#include #include "common/recursive_lock.h" #include "common/shared_first_mutex.h" #include "video_core/buffer_cache/buffer_cache.h"