QueryCacheBase::CounterReport (endermag flicker fix)
This commit is contained in:
parent
5d268b1321
commit
2ad5390c91
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
|
|
|
|||
|
|
@ -168,7 +168,9 @@ struct QueryCacheBase<Traits>::QueryCacheBaseImpl {
|
|||
std::array<StreamerInterface*, static_cast<size_t>(QueryType::MaxQueryTypes)> streamers;
|
||||
u64 streamer_mask;
|
||||
std::mutex flush_guard;
|
||||
bool force_flush_uncommitted{};
|
||||
std::deque<u64> flushes_pending;
|
||||
std::deque<bool> force_flushes_pending;
|
||||
std::vector<QueryCacheBase<Traits>::QueryLocation> pending_unregister;
|
||||
};
|
||||
|
||||
|
|
@ -246,6 +248,30 @@ void QueryCacheBase<Traits>::CounterReport(GPUVAddr addr, QueryType counter_type
|
|||
return;
|
||||
}
|
||||
DAddr cpu_addr = *cpu_addr_opt;
|
||||
|
||||
if (is_fence && counter_type == QueryType::Payload) {
|
||||
u8* pointer = impl->device_memory.template GetPointer<u8>(cpu_addr);
|
||||
u8* pointer_timestamp = impl->device_memory.template GetPointer<u8>(cpu_addr + 8);
|
||||
std::function<void()> operation([this, has_timestamp, payload, pointer, pointer_timestamp] {
|
||||
if (has_timestamp) {
|
||||
const u64 timestamp = impl->gpu.GetTicks();
|
||||
const u64 value = static_cast<u64>(payload);
|
||||
std::memcpy(pointer_timestamp, ×tamp, sizeof(timestamp));
|
||||
std::memcpy(pointer, &value, sizeof(value));
|
||||
} else {
|
||||
std::memcpy(pointer, &payload, sizeof(payload));
|
||||
}
|
||||
});
|
||||
impl->rasterizer.SyncOperation(std::move(operation));
|
||||
{
|
||||
std::scoped_lock lk(impl->flush_guard);
|
||||
impl->force_flush_uncommitted = true;
|
||||
}
|
||||
std::function<void()> noop([] {});
|
||||
impl->rasterizer.SignalFence(std::move(noop));
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t new_query_id = streamer->WriteCounter(cpu_addr, has_timestamp, payload, subreport);
|
||||
auto* query = streamer->GetQuery(new_query_id);
|
||||
if (is_fence) {
|
||||
|
|
@ -473,6 +499,8 @@ void QueryCacheBase<Traits>::CommitAsyncFlushes() {
|
|||
}
|
||||
});
|
||||
impl->flushes_pending.push_back(mask);
|
||||
impl->force_flushes_pending.push_back(impl->force_flush_uncommitted);
|
||||
impl->force_flush_uncommitted = false;
|
||||
}
|
||||
std::function<void()> func([this] { UnregisterPending(); });
|
||||
impl->rasterizer.SyncOperation(std::move(func));
|
||||
|
|
@ -496,6 +524,12 @@ void QueryCacheBase<Traits>::CommitAsyncFlushes() {
|
|||
|
||||
template <typename Traits>
|
||||
bool QueryCacheBase<Traits>::HasUncommittedFlushes() const {
|
||||
{
|
||||
std::scoped_lock lk(impl->flush_guard);
|
||||
if (impl->force_flush_uncommitted) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool result = false;
|
||||
impl->ForEachStreamer([&result](StreamerInterface* streamer) {
|
||||
result |= streamer->HasUnsyncedQueries();
|
||||
|
|
@ -507,7 +541,10 @@ bool QueryCacheBase<Traits>::HasUncommittedFlushes() const {
|
|||
template <typename Traits>
|
||||
bool QueryCacheBase<Traits>::ShouldWaitAsyncFlushes() {
|
||||
std::scoped_lock lk(impl->flush_guard);
|
||||
return !impl->flushes_pending.empty() && impl->flushes_pending.front() != 0ULL;
|
||||
if (impl->flushes_pending.empty()) {
|
||||
return false;
|
||||
}
|
||||
return impl->flushes_pending.front() != 0ULL || impl->force_flushes_pending.front();
|
||||
}
|
||||
|
||||
template <typename Traits>
|
||||
|
|
@ -517,6 +554,7 @@ void QueryCacheBase<Traits>::PopAsyncFlushes() {
|
|||
std::scoped_lock lk(impl->flush_guard);
|
||||
mask = impl->flushes_pending.front();
|
||||
impl->flushes_pending.pop_front();
|
||||
impl->force_flushes_pending.pop_front();
|
||||
}
|
||||
if (mask == 0) {
|
||||
return;
|
||||
|
|
|
|||
Loading…
Reference in New Issue