mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-12 04:35:56 +00:00
Tracker locking
This commit is contained in:
parent
4f99f304e6
commit
31ac54258a
5 changed files with 38 additions and 13 deletions
|
@ -996,6 +996,10 @@ void BufferCache::SynchronizeBuffersInRange(VAddr device_addr, u64 size) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BufferCache::SynchronizeBuffersForDma() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void BufferCache::MemoryBarrier() {
|
void BufferCache::MemoryBarrier() {
|
||||||
// Vulkan doesn't know which buffer we access in a shader if we use
|
// Vulkan doesn't know which buffer we access in a shader if we use
|
||||||
// BufferDeviceAddress. We need a full memory barrier.
|
// BufferDeviceAddress. We need a full memory barrier.
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include "common/div_ceil.h"
|
|
||||||
#include "common/slot_vector.h"
|
#include "common/slot_vector.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "video_core/buffer_cache/buffer.h"
|
#include "video_core/buffer_cache/buffer.h"
|
||||||
|
@ -156,8 +155,8 @@ public:
|
||||||
/// Synchronizes all buffers in the specified range.
|
/// Synchronizes all buffers in the specified range.
|
||||||
void SynchronizeBuffersInRange(VAddr device_addr, u64 size);
|
void SynchronizeBuffersInRange(VAddr device_addr, u64 size);
|
||||||
|
|
||||||
/// Synchronizes all buffers neede for DMA.
|
/// Synchronizes all buffers for DMA.
|
||||||
void SynchronizeDmaBuffers();
|
void SynchronizeBuffersForDma();
|
||||||
|
|
||||||
/// Record memory barrier. Used for buffers when accessed via BDA.
|
/// Record memory barrier. Used for buffers when accessed via BDA.
|
||||||
void MemoryBarrier();
|
void MemoryBarrier();
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
|
@ -24,8 +25,9 @@ public:
|
||||||
~MemoryTracker() = default;
|
~MemoryTracker() = default;
|
||||||
|
|
||||||
/// Returns true if a region has been modified from the CPU
|
/// Returns true if a region has been modified from the CPU
|
||||||
|
template <bool locking = true>
|
||||||
bool IsRegionCpuModified(VAddr query_cpu_addr, u64 query_size) noexcept {
|
bool IsRegionCpuModified(VAddr query_cpu_addr, u64 query_size) noexcept {
|
||||||
return IteratePages<true>(
|
return IteratePages<true, locking>(
|
||||||
query_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) {
|
query_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) {
|
||||||
std::scoped_lock lk{manager->lock};
|
std::scoped_lock lk{manager->lock};
|
||||||
return manager->template IsRegionModified<Type::CPU>(offset, size);
|
return manager->template IsRegionModified<Type::CPU>(offset, size);
|
||||||
|
@ -33,8 +35,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if a region has been modified from the GPU
|
/// Returns true if a region has been modified from the GPU
|
||||||
|
template <bool locking = true>
|
||||||
bool IsRegionGpuModified(VAddr query_cpu_addr, u64 query_size) noexcept {
|
bool IsRegionGpuModified(VAddr query_cpu_addr, u64 query_size) noexcept {
|
||||||
return IteratePages<false>(
|
return IteratePages<false, locking>(
|
||||||
query_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) {
|
query_cpu_addr, query_size, [](RegionManager* manager, u64 offset, size_t size) {
|
||||||
std::scoped_lock lk{manager->lock};
|
std::scoped_lock lk{manager->lock};
|
||||||
return manager->template IsRegionModified<Type::GPU>(offset, size);
|
return manager->template IsRegionModified<Type::GPU>(offset, size);
|
||||||
|
@ -42,8 +45,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark region as CPU modified, notifying the device_tracker about this change
|
/// Mark region as CPU modified, notifying the device_tracker about this change
|
||||||
|
template <bool locking = true>
|
||||||
void MarkRegionAsCpuModified(VAddr dirty_cpu_addr, u64 query_size) {
|
void MarkRegionAsCpuModified(VAddr dirty_cpu_addr, u64 query_size) {
|
||||||
IteratePages<false>(dirty_cpu_addr, query_size,
|
IteratePages<false, locking>(dirty_cpu_addr, query_size,
|
||||||
[](RegionManager* manager, u64 offset, size_t size) {
|
[](RegionManager* manager, u64 offset, size_t size) {
|
||||||
std::scoped_lock lk{manager->lock};
|
std::scoped_lock lk{manager->lock};
|
||||||
manager->template ChangeRegionState<Type::CPU, true>(
|
manager->template ChangeRegionState<Type::CPU, true>(
|
||||||
|
@ -52,8 +56,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unmark region as modified from the host GPU
|
/// Unmark region as modified from the host GPU
|
||||||
|
template <bool locking = true>
|
||||||
void UnmarkRegionAsGpuModified(VAddr dirty_cpu_addr, u64 query_size) noexcept {
|
void UnmarkRegionAsGpuModified(VAddr dirty_cpu_addr, u64 query_size) noexcept {
|
||||||
IteratePages<false>(dirty_cpu_addr, query_size,
|
IteratePages<false, locking>(dirty_cpu_addr, query_size,
|
||||||
[](RegionManager* manager, u64 offset, size_t size) {
|
[](RegionManager* manager, u64 offset, size_t size) {
|
||||||
std::scoped_lock lk{manager->lock};
|
std::scoped_lock lk{manager->lock};
|
||||||
manager->template ChangeRegionState<Type::GPU, false>(
|
manager->template ChangeRegionState<Type::GPU, false>(
|
||||||
|
@ -62,8 +67,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes all protection from a page and ensures GPU data has been flushed if requested
|
/// Removes all protection from a page and ensures GPU data has been flushed if requested
|
||||||
|
template <bool locking = true>
|
||||||
void InvalidateRegion(VAddr cpu_addr, u64 size, bool try_flush, auto&& on_flush) noexcept {
|
void InvalidateRegion(VAddr cpu_addr, u64 size, bool try_flush, auto&& on_flush) noexcept {
|
||||||
IteratePages<false>(
|
IteratePages<false, locking>(
|
||||||
cpu_addr, size,
|
cpu_addr, size,
|
||||||
[try_flush, &on_flush](RegionManager* manager, u64 offset, size_t size) {
|
[try_flush, &on_flush](RegionManager* manager, u64 offset, size_t size) {
|
||||||
const bool should_flush = [&] {
|
const bool should_flush = [&] {
|
||||||
|
@ -86,8 +92,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call 'func' for each CPU modified range and unmark those pages as CPU modified
|
/// Call 'func' for each CPU modified range and unmark those pages as CPU modified
|
||||||
|
template <bool locking = true>
|
||||||
void ForEachUploadRange(VAddr query_cpu_range, u64 query_size, bool is_written, auto&& func) {
|
void ForEachUploadRange(VAddr query_cpu_range, u64 query_size, bool is_written, auto&& func) {
|
||||||
IteratePages<true>(query_cpu_range, query_size,
|
IteratePages<true, locking>(query_cpu_range, query_size,
|
||||||
[&func, is_written](RegionManager* manager, u64 offset, size_t size) {
|
[&func, is_written](RegionManager* manager, u64 offset, size_t size) {
|
||||||
std::scoped_lock lk{manager->lock};
|
std::scoped_lock lk{manager->lock};
|
||||||
manager->template ForEachModifiedRange<Type::CPU, true>(
|
manager->template ForEachModifiedRange<Type::CPU, true>(
|
||||||
|
@ -100,9 +107,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call 'func' for each GPU modified range and unmark those pages as GPU modified
|
/// Call 'func' for each GPU modified range and unmark those pages as GPU modified
|
||||||
template <bool clear>
|
template <bool clear, bool locking = true>
|
||||||
void ForEachDownloadRange(VAddr query_cpu_range, u64 query_size, auto&& func) {
|
void ForEachDownloadRange(VAddr query_cpu_range, u64 query_size, auto&& func) {
|
||||||
IteratePages<false>(query_cpu_range, query_size,
|
IteratePages<false, locking>(query_cpu_range, query_size,
|
||||||
[&func](RegionManager* manager, u64 offset, size_t size) {
|
[&func](RegionManager* manager, u64 offset, size_t size) {
|
||||||
std::scoped_lock lk{manager->lock};
|
std::scoped_lock lk{manager->lock};
|
||||||
manager->template ForEachModifiedRange<Type::GPU, clear>(
|
manager->template ForEachModifiedRange<Type::GPU, clear>(
|
||||||
|
@ -110,6 +117,17 @@ public:
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Lck the memory tracker.
|
||||||
|
void Lock() {
|
||||||
|
global_lock.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unlock the memory tracker.
|
||||||
|
void Unlock() {
|
||||||
|
global_lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief IteratePages Iterates L2 word manager page table.
|
* @brief IteratePages Iterates L2 word manager page table.
|
||||||
|
@ -118,9 +136,12 @@ private:
|
||||||
* @param func Callback for each word manager.
|
* @param func Callback for each word manager.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
template <bool create_region_on_fail, typename Func>
|
template <bool create_region_on_fail, bool locking, typename Func>
|
||||||
bool IteratePages(VAddr cpu_address, size_t size, Func&& func) {
|
bool IteratePages(VAddr cpu_address, size_t size, Func&& func) {
|
||||||
RENDERER_TRACE;
|
RENDERER_TRACE;
|
||||||
|
if constexpr (locking) {
|
||||||
|
std::shared_lock lock{global_lock};
|
||||||
|
}
|
||||||
using FuncReturn = typename std::invoke_result<Func, RegionManager*, u64, size_t>::type;
|
using FuncReturn = typename std::invoke_result<Func, RegionManager*, u64, size_t>::type;
|
||||||
static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
|
static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
|
||||||
std::size_t remaining_size{size};
|
std::size_t remaining_size{size};
|
||||||
|
@ -177,6 +198,7 @@ private:
|
||||||
std::deque<std::array<RegionManager, MANAGER_POOL_SIZE>> manager_pool;
|
std::deque<std::array<RegionManager, MANAGER_POOL_SIZE>> manager_pool;
|
||||||
std::vector<RegionManager*> free_managers;
|
std::vector<RegionManager*> free_managers;
|
||||||
std::array<RegionManager*, NUM_HIGH_PAGES> top_tier{};
|
std::array<RegionManager*, NUM_HIGH_PAGES> top_tier{};
|
||||||
|
std::shared_mutex global_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace VideoCore
|
} // namespace VideoCore
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
|
#include "common/div_ceil.h"
|
||||||
#include "common/range_lock.h"
|
#include "common/range_lock.h"
|
||||||
#include "common/signal_context.h"
|
#include "common/signal_context.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <shared_mutex>
|
|
||||||
#include "common/recursive_lock.h"
|
#include "common/recursive_lock.h"
|
||||||
#include "common/shared_first_mutex.h"
|
#include "common/shared_first_mutex.h"
|
||||||
#include "video_core/buffer_cache/buffer_cache.h"
|
#include "video_core/buffer_cache/buffer_cache.h"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue