mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-18 06:10:35 +00:00
[TEST] Extend coalescing to more gpu to cpu regions
This commit is contained in:
@@ -791,6 +791,11 @@ bool BufferCache<P>::IsRegionGpuModified(DAddr addr, size_t size) {
|
||||
return is_dirty;
|
||||
}
|
||||
|
||||
template <class P>
|
||||
bool BufferCache<P>::IsRegionGpuModifiedCheap(DAddr addr, size_t size) {
|
||||
return memory_tracker.IsRegionGpuModifiedCheap(addr, size);
|
||||
}
|
||||
|
||||
template <class P>
|
||||
bool BufferCache<P>::IsRegionRegistered(DAddr addr, size_t size) {
|
||||
const DAddr end_addr = addr + size;
|
||||
@@ -1025,7 +1030,8 @@ void BufferCache<P>::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
|
||||
}();
|
||||
const bool use_fast_buffer = needs_alignment_stream
|
||||
|| (has_host_buffer && size <= channel_state->uniform_buffer_skip_cache_size
|
||||
&& !memory_tracker.IsRegionGpuModified(device_addr, size));
|
||||
&& !(memory_tracker.IsRegionGpuModifiedCheap(device_addr, size)
|
||||
&& memory_tracker.IsRegionGpuModified(device_addr, size)));
|
||||
if (use_fast_buffer) {
|
||||
if constexpr (IS_OPENGL) {
|
||||
if (runtime.HasFastBufferSubData()) {
|
||||
|
||||
@@ -300,6 +300,8 @@ public:
|
||||
/// Return true when a CPU region is modified from the GPU
|
||||
[[nodiscard]] bool IsRegionGpuModified(DAddr addr, size_t size);
|
||||
|
||||
[[nodiscard]] bool IsRegionGpuModifiedCheap(DAddr addr, size_t size);
|
||||
|
||||
/// Return true when a region is registered on the cache
|
||||
[[nodiscard]] bool IsRegionRegistered(DAddr addr, size_t size);
|
||||
|
||||
|
||||
@@ -69,6 +69,24 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsRegionGpuModifiedCheap(VAddr query_cpu_addr, u64 query_size) noexcept {
|
||||
std::size_t remaining_size{query_size};
|
||||
std::size_t page_index{query_cpu_addr >> HIGHER_PAGE_BITS};
|
||||
u64 page_offset{query_cpu_addr & HIGHER_PAGE_MASK};
|
||||
while (remaining_size > 0) {
|
||||
const std::size_t copy_amount{
|
||||
std::min<std::size_t>(HIGHER_PAGE_SIZE - page_offset, remaining_size)};
|
||||
const Manager* manager = top_tier[page_index].load(std::memory_order_acquire);
|
||||
if (manager != nullptr && manager->GpuModifiedPageCount() != 0) {
|
||||
return true;
|
||||
}
|
||||
page_index++;
|
||||
page_offset = 0;
|
||||
remaining_size -= copy_amount;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Returns true if a region has been modified from the CPU
|
||||
[[nodiscard]] bool IsRegionCpuModified(VAddr query_cpu_addr, u64 query_size) noexcept {
|
||||
return IteratePages<true>(query_cpu_addr, query_size, [](Manager* manager, u64 offset, size_t size) {
|
||||
|
||||
@@ -127,6 +127,7 @@ struct WordManager {
|
||||
[[maybe_unused]] std::span<u64> cached_words = Span(Type::CachedCPU);
|
||||
std::vector<std::pair<VAddr, u64>> ranges;
|
||||
s64 cpu_delta = 0;
|
||||
s64 gpu_delta = 0;
|
||||
IterateWords(dirty_addr - cpu_addr, size, [&](size_t index, u64 mask) {
|
||||
if (type == Type::CPU || type == Type::CachedCPU) {
|
||||
CollectChangedRanges(!enable, index, untracked_words[index], mask, ranges);
|
||||
@@ -134,6 +135,9 @@ struct WordManager {
|
||||
if (type == Type::CPU) {
|
||||
const u64 old = state_words[index];
|
||||
cpu_delta += enable ? std::popcount(~old & mask) : -std::popcount(old & mask);
|
||||
} else if (type == Type::GPU) {
|
||||
const u64 old = state_words[index];
|
||||
gpu_delta += enable ? std::popcount(~old & mask) : -std::popcount(old & mask);
|
||||
}
|
||||
if (enable) {
|
||||
state_words[index] |= mask;
|
||||
@@ -152,6 +156,9 @@ struct WordManager {
|
||||
if (cpu_delta != 0) {
|
||||
cpu_modified_pages.fetch_add(static_cast<u32>(cpu_delta), std::memory_order_release);
|
||||
}
|
||||
if (gpu_delta != 0) {
|
||||
gpu_modified_pages.fetch_add(static_cast<u32>(gpu_delta), std::memory_order_release);
|
||||
}
|
||||
if (!ranges.empty()) {
|
||||
ApplyCollectedRanges(ranges, (!enable) ? 1 : -1);
|
||||
}
|
||||
@@ -180,6 +187,7 @@ struct WordManager {
|
||||
};
|
||||
std::vector<std::pair<VAddr, u64>> ranges;
|
||||
s64 cpu_delta = 0;
|
||||
s64 gpu_delta = 0;
|
||||
IterateWords(offset, size, [&](size_t index, u64 mask) {
|
||||
if (type == Type::GPU)
|
||||
mask &= ~untracked_words[index];
|
||||
@@ -190,6 +198,8 @@ struct WordManager {
|
||||
}
|
||||
if (type == Type::CPU)
|
||||
cpu_delta -= std::popcount(word);
|
||||
else if (type == Type::GPU)
|
||||
gpu_delta -= std::popcount(word);
|
||||
state_words[index] &= ~mask;
|
||||
if (type == Type::CPU || type == Type::CachedCPU)
|
||||
untracked_words[index] &= ~mask;
|
||||
@@ -214,6 +224,9 @@ struct WordManager {
|
||||
if (cpu_delta != 0) {
|
||||
cpu_modified_pages.fetch_add(static_cast<u32>(cpu_delta), std::memory_order_release);
|
||||
}
|
||||
if (gpu_delta != 0) {
|
||||
gpu_modified_pages.fetch_add(static_cast<u32>(gpu_delta), std::memory_order_release);
|
||||
}
|
||||
if (pending) {
|
||||
release();
|
||||
}
|
||||
@@ -348,10 +361,15 @@ struct WordManager {
|
||||
return cpu_modified_pages.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
[[nodiscard]] u32 GpuModifiedPageCount() const noexcept {
|
||||
return gpu_modified_pages.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
std::array<u64, size_t(Type::Max) * num_words> heap = {};
|
||||
DeviceTracker* tracker = nullptr;
|
||||
VAddr cpu_addr = 0;
|
||||
std::atomic<u32> cpu_modified_pages{0};
|
||||
std::atomic<u32> gpu_modified_pages{0};
|
||||
};
|
||||
|
||||
} // namespace VideoCommon
|
||||
|
||||
@@ -684,9 +684,11 @@ void RasterizerVulkan::FlushRegion(DAddr addr, u64 size, VideoCommon::CacheType
|
||||
|
||||
bool RasterizerVulkan::MustFlushRegion(DAddr addr, u64 size, VideoCommon::CacheType which) {
|
||||
if ((True(which & VideoCommon::CacheType::BufferCache))) {
|
||||
std::scoped_lock lock{buffer_cache.mutex};
|
||||
if (buffer_cache.IsRegionGpuModified(addr, size)) {
|
||||
return true;
|
||||
if (buffer_cache.IsRegionGpuModifiedCheap(addr, size)) {
|
||||
std::scoped_lock lock{buffer_cache.mutex};
|
||||
if (buffer_cache.IsRegionGpuModified(addr, size)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Settings::IsGPULevelHigh()) {
|
||||
|
||||
Reference in New Issue
Block a user