mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2025-06-17 19:57:55 -05:00
Query Cache: Fix guest side sample counting
This commit is contained in:
@ -9,16 +9,15 @@
|
||||
namespace VideoCommon {
|
||||
|
||||
enum class QueryFlagBits : u32 {
|
||||
HasTimestamp = 1 << 0, ///< Indicates if this query has a timestamp.
|
||||
IsFinalValueSynced = 1 << 1, ///< Indicates if the query has been synced in the host
|
||||
IsHostSynced = 1 << 2, ///< Indicates if the query has been synced in the host
|
||||
IsGuestSynced = 1 << 3, ///< Indicates if the query has been synced with the guest.
|
||||
IsHostManaged = 1 << 4, ///< Indicates if this query points to a host query
|
||||
IsRewritten = 1 << 5, ///< Indicates if this query was rewritten by another query
|
||||
IsInvalidated = 1 << 6, ///< Indicates the value of th query has been nullified.
|
||||
IsOrphan = 1 << 7, ///< Indicates the query has not been set by a guest query.
|
||||
IsFence = 1 << 8, ///< Indicates the query is a fence.
|
||||
IsQueuedForAsyncFlush = 1 << 9, ///< Indicates that the query can be flushed at any moment
|
||||
HasTimestamp = 1 << 0, ///< Indicates if this query has a timestamp.
|
||||
IsFinalValueSynced = 1 << 1, ///< Indicates if the query has been synced in the host
|
||||
IsHostSynced = 1 << 2, ///< Indicates if the query has been synced in the host
|
||||
IsGuestSynced = 1 << 3, ///< Indicates if the query has been synced with the guest.
|
||||
IsHostManaged = 1 << 4, ///< Indicates if this query points to a host query
|
||||
IsRewritten = 1 << 5, ///< Indicates if this query was rewritten by another query
|
||||
IsInvalidated = 1 << 6, ///< Indicates the value of th query has been nullified.
|
||||
IsOrphan = 1 << 7, ///< Indicates the query has not been set by a guest query.
|
||||
IsFence = 1 << 8, ///< Indicates the query is a fence.
|
||||
};
|
||||
DECLARE_ENUM_FLAG_OPERATORS(QueryFlagBits)
|
||||
|
||||
|
@ -256,30 +256,32 @@ void QueryCacheBase<Traits>::CounterReport(GPUVAddr addr, QueryType counter_type
|
||||
u8* pointer = impl->cpu_memory.GetPointer(cpu_addr);
|
||||
u8* pointer_timestamp = impl->cpu_memory.GetPointer(cpu_addr + 8);
|
||||
bool is_synced = !Settings::IsGPULevelHigh() && is_fence;
|
||||
std::function<void()> operation(
|
||||
[this, is_synced, query_base = query, query_location, pointer, pointer_timestamp] {
|
||||
if (True(query_base->flags & QueryFlagBits::IsInvalidated)) {
|
||||
if (!is_synced) [[likely]] {
|
||||
impl->pending_unregister.push_back(query_location);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (False(query_base->flags & QueryFlagBits::IsFinalValueSynced)) [[unlikely]] {
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
if (True(query_base->flags & QueryFlagBits::HasTimestamp)) {
|
||||
u64 timestamp = impl->gpu.GetTicks();
|
||||
std::memcpy(pointer_timestamp, ×tamp, sizeof(timestamp));
|
||||
std::memcpy(pointer, &query_base->value, sizeof(query_base->value));
|
||||
} else {
|
||||
u32 value = static_cast<u32>(query_base->value);
|
||||
std::memcpy(pointer, &value, sizeof(value));
|
||||
}
|
||||
std::function<void()> operation([this, is_synced, streamer, query_base = query, query_location,
|
||||
pointer, pointer_timestamp] {
|
||||
if (True(query_base->flags & QueryFlagBits::IsInvalidated)) {
|
||||
if (!is_synced) [[likely]] {
|
||||
impl->pending_unregister.push_back(query_location);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (False(query_base->flags & QueryFlagBits::IsFinalValueSynced)) [[unlikely]] {
|
||||
UNREACHABLE();
|
||||
return;
|
||||
}
|
||||
query_base->value += streamer->GetAmmendValue();
|
||||
streamer->SetAccumulationValue(query_base->value);
|
||||
if (True(query_base->flags & QueryFlagBits::HasTimestamp)) {
|
||||
u64 timestamp = impl->gpu.GetTicks();
|
||||
std::memcpy(pointer_timestamp, ×tamp, sizeof(timestamp));
|
||||
std::memcpy(pointer, &query_base->value, sizeof(query_base->value));
|
||||
} else {
|
||||
u32 value = static_cast<u32>(query_base->value);
|
||||
std::memcpy(pointer, &value, sizeof(value));
|
||||
}
|
||||
if (!is_synced) [[likely]] {
|
||||
impl->pending_unregister.push_back(query_location);
|
||||
}
|
||||
});
|
||||
if (is_fence) {
|
||||
impl->rasterizer.SignalFence(std::move(operation));
|
||||
} else {
|
||||
@ -354,9 +356,9 @@ void QueryCacheBase<Traits>::NotifySegment(bool resume) {
|
||||
if (resume) {
|
||||
impl->runtime.ResumeHostConditionalRendering();
|
||||
} else {
|
||||
impl->runtime.PauseHostConditionalRendering();
|
||||
CounterClose(VideoCommon::QueryType::ZPassPixelCount64);
|
||||
CounterClose(VideoCommon::QueryType::StreamingByteCount);
|
||||
impl->runtime.PauseHostConditionalRendering();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,14 @@ public:
|
||||
return dependence_mask;
|
||||
}
|
||||
|
||||
u64 GetAmmendValue() const {
|
||||
return ammend_value;
|
||||
}
|
||||
|
||||
void SetAccumulationValue(u64 new_value) {
|
||||
acumulation_value = new_value;
|
||||
}
|
||||
|
||||
protected:
|
||||
void MakeDependent(StreamerInterface* depend_on) {
|
||||
dependence_mask |= 1ULL << depend_on->id;
|
||||
@ -87,6 +95,8 @@ protected:
|
||||
const size_t id;
|
||||
u64 dependence_mask;
|
||||
u64 dependent_mask;
|
||||
u64 ammend_value{};
|
||||
u64 acumulation_value{};
|
||||
};
|
||||
|
||||
template <typename QueryType>
|
||||
|
Reference in New Issue
Block a user