diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 43fe5b080..faa48a678 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -22,6 +22,8 @@ BufferCache
::BufferCache(VideoCore::RasterizerInterface& rasterizer_, void(slot_buffers.insert(runtime, NullBufferParams{})); common_ranges.clear(); + active_async_buffers = IMPLEMENTS_ASYNC_DOWNLOADS && !Settings::IsGPULevelHigh(); + if (!runtime.CanReportMemoryUsage()) { minimum_memory = DEFAULT_EXPECTED_MEMORY; critical_memory = DEFAULT_CRITICAL_MEMORY; @@ -72,6 +74,8 @@ void BufferCache
::TickFrame() { uniform_cache_hits[0] = 0; uniform_cache_shots[0] = 0; + active_async_buffers = IMPLEMENTS_ASYNC_DOWNLOADS && !Settings::IsGPULevelHigh(); + const bool skip_preferred = hits * 256 < shots * 251; uniform_buffer_skip_cache_size = skip_preferred ? DEFAULT_SKIP_CACHE_SIZE : 0; @@ -130,7 +134,7 @@ void BufferCache
::WaitOnAsyncFlushes(VAddr cpu_addr, u64 size) {
template ::ClearDownload(IntervalType subtract_interval) {
- async_downloads -= std::make_pair(subtract_interval, std::numeric_limits ::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am
}};
boost::container::small_vector ::CommitAsyncFlushesHigh() {
AccumulateFlushes();
if (committed_ranges.empty()) {
- if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) {
+ if (active_async_buffers) {
async_buffers.emplace_back(std::optional ::CommitAsyncFlushesHigh() {
}
committed_ranges.clear();
if (downloads.empty()) {
- if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) {
+ if (active_async_buffers) {
async_buffers.emplace_back(std::optional ::PopAsyncBuffers() {
common_ranges.subtract(base_interval);
}
});
- async_downloads -= std::make_pair(IntervalType(cpu_addr, cpu_addr + copy.size), 1);
+ const IntervalType subtract_interval{cpu_addr, cpu_addr + copy.size};
+ RemoveEachInOverlapCounter(async_downloads, subtract_interval, -1);
}
runtime.FreeDeferredStagingBuffer(*async_buffer);
async_buffers.pop_front();
@@ -1198,10 +1201,8 @@ void BufferCache ::MarkWrittenBuffer(BufferId buffer_id, VAddr cpu_addr, u32 s
const IntervalType base_interval{cpu_addr, cpu_addr + size};
common_ranges.add(base_interval);
- if (Settings::values.gpu_accuracy.GetValue() == Settings::GPUAccuracy::High) {
- uncommitted_ranges.add(base_interval);
- pending_ranges.add(base_interval);
- }
+ uncommitted_ranges.add(base_interval);
+ pending_ranges.add(base_interval);
}
template ::DownloadBufferMemory(Buffer& buffer, VAddr cpu_addr, u64 si
.size = new_size,
});
// Align up to avoid cache conflicts
- constexpr u64 align = 8ULL;
+ constexpr u64 align = 64ULL;
constexpr u64 mask = ~(align - 1ULL);
total_size_bytes += (new_size + align - 1) & mask;
largest_copy = std::max(largest_copy, new_size);
diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h
index 6f29cba25..d4914a8f5 100644
--- a/src/video_core/buffer_cache/buffer_cache_base.h
+++ b/src/video_core/buffer_cache/buffer_cache_base.h
@@ -345,13 +345,30 @@ private:
if (inter_addr < start_address) {
inter_addr = start_address;
}
- if (it->second <= 0) {
- __debugbreak();
- }
func(inter_addr, inter_addr_end, it->second);
}
}
+ void RemoveEachInOverlapCounter(OverlapCounter& current_range, const IntervalType search_interval, int subtract_value) {
+ bool any_removals = false;
+ current_range.add(std::make_pair(search_interval, subtract_value));
+ do {
+ any_removals = false;
+ auto it = current_range.lower_bound(search_interval);
+ if (it == current_range.end()) {
+ return;
+ }
+ auto end_it = current_range.upper_bound(search_interval);
+ for (; it != end_it; it++) {
+ if (it->second <= 0) {
+ any_removals = true;
+ current_range.erase(it);
+ break;
+ }
+ }
+ } while (any_removals);
+ }
+
static bool IsRangeGranular(VAddr cpu_addr, size_t size) {
return (cpu_addr & ~Core::Memory::YUZU_PAGEMASK) ==
((cpu_addr + size) & ~Core::Memory::YUZU_PAGEMASK);
@@ -554,6 +571,8 @@ private:
u64 minimum_memory = 0;
u64 critical_memory = 0;
+ bool active_async_buffers = false;
+
std::array