mirror of
https://github.com/yuzu-mirror/yuzu
synced 2024-12-20 12:13:05 +00:00
Fence Manager: Force ordering on WFI.
This commit is contained in:
parent
73638ca593
commit
cf38faee9b
4 changed files with 71 additions and 38 deletions
|
@ -152,6 +152,8 @@ public:
|
|||
/// Return true when there are uncommitted buffers to be downloaded
|
||||
[[nodiscard]] bool HasUncommittedFlushes() const noexcept;
|
||||
|
||||
void AccumulateFlushes();
|
||||
|
||||
/// Return true when the caller should wait for async downloads
|
||||
[[nodiscard]] bool ShouldWaitAsyncFlushes() const noexcept;
|
||||
|
||||
|
@ -334,6 +336,7 @@ private:
|
|||
std::vector<BufferId> cached_write_buffer_ids;
|
||||
|
||||
IntervalSet uncommitted_ranges;
|
||||
std::deque<IntervalSet> committed_ranges;
|
||||
|
||||
size_t immediate_buffer_capacity = 0;
|
||||
std::unique_ptr<u8[]> immediate_buffer_alloc;
|
||||
|
@ -551,7 +554,19 @@ void BufferCache<P>::FlushCachedWrites() {
|
|||
|
||||
template <class P>
|
||||
bool BufferCache<P>::HasUncommittedFlushes() const noexcept {
|
||||
return !uncommitted_ranges.empty();
|
||||
return !uncommitted_ranges.empty() || !committed_ranges.empty();
|
||||
}
|
||||
|
||||
template <class P>
|
||||
void BufferCache<P>::AccumulateFlushes() {
|
||||
if (Settings::values.gpu_accuracy.GetValue() != Settings::GPUAccuracy::High) {
|
||||
uncommitted_ranges.clear();
|
||||
return;
|
||||
}
|
||||
if (uncommitted_ranges.empty()) {
|
||||
return;
|
||||
}
|
||||
committed_ranges.emplace_back(std::move(uncommitted_ranges));
|
||||
}
|
||||
|
||||
template <class P>
|
||||
|
@ -561,8 +576,8 @@ bool BufferCache<P>::ShouldWaitAsyncFlushes() const noexcept {
|
|||
|
||||
template <class P>
|
||||
void BufferCache<P>::CommitAsyncFlushesHigh() {
|
||||
const IntervalSet& intervals = uncommitted_ranges;
|
||||
if (intervals.empty()) {
|
||||
AccumulateFlushes();
|
||||
if (committed_ranges.empty()) {
|
||||
return;
|
||||
}
|
||||
MICROPROFILE_SCOPE(GPU_DownloadMemory);
|
||||
|
@ -570,6 +585,7 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
|
|||
boost::container::small_vector<std::pair<BufferCopy, BufferId>, 1> downloads;
|
||||
u64 total_size_bytes = 0;
|
||||
u64 largest_copy = 0;
|
||||
for (const IntervalSet& intervals : committed_ranges) {
|
||||
for (auto& interval : intervals) {
|
||||
const std::size_t size = interval.upper() - interval.lower();
|
||||
const VAddr cpu_addr = interval.lower();
|
||||
|
@ -607,6 +623,8 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
|
|||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
committed_ranges.clear();
|
||||
if (downloads.empty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -644,6 +662,7 @@ void BufferCache<P>::CommitAsyncFlushes() {
|
|||
CommitAsyncFlushesHigh();
|
||||
} else {
|
||||
uncommitted_ranges.clear();
|
||||
committed_ranges.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,12 @@ public:
|
|||
delayed_destruction_ring.Tick();
|
||||
}
|
||||
|
||||
// Unlike other fences, this one doesn't
|
||||
void SignalOrdering() {
|
||||
std::scoped_lock lock{buffer_cache.mutex};
|
||||
buffer_cache.AccumulateFlushes();
|
||||
}
|
||||
|
||||
void SignalReference() {
|
||||
// Only sync references on High
|
||||
if (Settings::values.gpu_accuracy.GetValue() != Settings::GPUAccuracy::High) {
|
||||
|
|
|
@ -657,6 +657,10 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {
|
|||
|
||||
void RasterizerOpenGL::WaitForIdle() {
|
||||
glMemoryBarrier(GL_ALL_BARRIER_BITS);
|
||||
if (!gpu.IsAsync()) {
|
||||
return;
|
||||
}
|
||||
fence_manager.SignalOrdering();
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::FragmentBarrier() {
|
||||
|
|
|
@ -619,6 +619,10 @@ void RasterizerVulkan::WaitForIdle() {
|
|||
cmdbuf.SetEvent(event, flags);
|
||||
cmdbuf.WaitEvents(event, flags, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, {}, {}, {});
|
||||
});
|
||||
if (!gpu.IsAsync()) {
|
||||
return;
|
||||
}
|
||||
fence_manager.SignalOrdering();
|
||||
}
|
||||
|
||||
void RasterizerVulkan::FragmentBarrier() {
|
||||
|
|
Loading…
Reference in a new issue