|
|
|
@ -110,13 +110,16 @@ struct HostSyncValues { |
|
|
|
|
|
|
|
class SamplesStreamer : public BaseStreamer { |
|
|
|
public: |
|
|
|
explicit SamplesStreamer(size_t id_, QueryCacheRuntime& runtime_, const Device& device_, |
|
|
|
explicit SamplesStreamer(size_t id_, QueryCacheRuntime& runtime_, |
|
|
|
VideoCore::RasterizerInterface* rasterizer_, const Device& device_, |
|
|
|
Scheduler& scheduler_, const MemoryAllocator& memory_allocator_) |
|
|
|
: BaseStreamer(id_), runtime{runtime_}, device{device_}, scheduler{scheduler_}, |
|
|
|
memory_allocator{memory_allocator_} { |
|
|
|
: BaseStreamer(id_), runtime{runtime_}, rasterizer{rasterizer_}, device{device_}, |
|
|
|
scheduler{scheduler_}, memory_allocator{memory_allocator_} { |
|
|
|
BuildResolveBuffer(); |
|
|
|
current_bank = nullptr; |
|
|
|
current_query = nullptr; |
|
|
|
ammend_value = 0; |
|
|
|
acumulation_value = 0; |
|
|
|
} |
|
|
|
|
|
|
|
~SamplesStreamer() = default; |
|
|
|
@ -151,6 +154,11 @@ public: |
|
|
|
PauseCounter(); |
|
|
|
} |
|
|
|
AbandonCurrentQuery(); |
|
|
|
std::function<void()> func([this, counts = pending_flush_queries.size()] { |
|
|
|
ammend_value = 0; |
|
|
|
acumulation_value = 0; |
|
|
|
}); |
|
|
|
rasterizer->SyncOperation(std::move(func)); |
|
|
|
} |
|
|
|
|
|
|
|
void CloseCounter() override { |
|
|
|
@ -244,7 +252,7 @@ public: |
|
|
|
} |
|
|
|
if (query->size_slots > 1) { |
|
|
|
// This is problematic.
|
|
|
|
UNIMPLEMENTED(); |
|
|
|
// UNIMPLEMENTED();
|
|
|
|
} |
|
|
|
query->flags |= VideoCommon::QueryFlagBits::IsHostSynced; |
|
|
|
auto loc_data = offsets[query->start_bank_id]; |
|
|
|
@ -255,16 +263,20 @@ public: |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
ReplicateCurrentQueryIfNeeded(); |
|
|
|
std::function<void()> func([this] { ammend_value = acumulation_value; }); |
|
|
|
rasterizer->SyncOperation(std::move(func)); |
|
|
|
AbandonCurrentQuery(); |
|
|
|
pending_sync.clear(); |
|
|
|
} |
|
|
|
|
|
|
|
size_t WriteCounter(VAddr address, bool has_timestamp, u32 value, |
|
|
|
[[maybe_unused]] std::optional<u32> subreport) override { |
|
|
|
PauseCounter(); |
|
|
|
auto index = BuildQuery(); |
|
|
|
auto* new_query = GetQuery(index); |
|
|
|
new_query->guest_address = address; |
|
|
|
new_query->value = 100; |
|
|
|
new_query->value = 0; |
|
|
|
new_query->flags &= ~VideoCommon::QueryFlagBits::IsOrphan; |
|
|
|
if (has_timestamp) { |
|
|
|
new_query->flags |= VideoCommon::QueryFlagBits::HasTimestamp; |
|
|
|
@ -291,6 +303,7 @@ public: |
|
|
|
|
|
|
|
void PushUnsyncedQueries() override { |
|
|
|
PauseCounter(); |
|
|
|
current_bank->Close(); |
|
|
|
{ |
|
|
|
std::scoped_lock lk(flush_guard); |
|
|
|
pending_flush_sets.emplace_back(std::move(pending_flush_queries)); |
|
|
|
@ -429,6 +442,34 @@ private: |
|
|
|
current_query_id = 0; |
|
|
|
} |
|
|
|
|
|
|
|
void ReplicateCurrentQueryIfNeeded() { |
|
|
|
if (pending_sync.empty()) { |
|
|
|
return; |
|
|
|
} |
|
|
|
if (!current_query) { |
|
|
|
return; |
|
|
|
} |
|
|
|
auto index = BuildQuery(); |
|
|
|
auto* new_query = GetQuery(index); |
|
|
|
new_query->guest_address = 0; |
|
|
|
new_query->value = 0; |
|
|
|
new_query->flags &= ~VideoCommon::QueryFlagBits::IsOrphan; |
|
|
|
new_query->start_bank_id = current_query->start_bank_id; |
|
|
|
new_query->size_banks = current_query->size_banks; |
|
|
|
new_query->start_slot = current_query->start_slot; |
|
|
|
new_query->size_slots = current_query->size_slots; |
|
|
|
ApplyBankOp(new_query, [](SamplesQueryBank* bank, size_t start, size_t amount) { |
|
|
|
bank->AddReference(amount); |
|
|
|
}); |
|
|
|
pending_flush_queries.push_back(index); |
|
|
|
std::function<void()> func([this, index] { |
|
|
|
auto* query = GetQuery(index); |
|
|
|
query->value += GetAmmendValue(); |
|
|
|
SetAccumulationValue(query->value); |
|
|
|
Free(index); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
void BuildResolveBuffer() { |
|
|
|
const VkBufferCreateInfo buffer_ci = { |
|
|
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, |
|
|
|
@ -448,6 +489,7 @@ private: |
|
|
|
static constexpr size_t resolve_slots = 8; |
|
|
|
|
|
|
|
QueryCacheRuntime& runtime; |
|
|
|
VideoCore::RasterizerInterface* rasterizer; |
|
|
|
const Device& device; |
|
|
|
Scheduler& scheduler; |
|
|
|
const MemoryAllocator& memory_allocator; |
|
|
|
@ -470,6 +512,7 @@ private: |
|
|
|
size_t current_query_id; |
|
|
|
VideoCommon::HostQueryBase* current_query; |
|
|
|
bool has_started{}; |
|
|
|
bool current_unset{}; |
|
|
|
std::mutex flush_guard; |
|
|
|
}; |
|
|
|
|
|
|
|
@ -677,7 +720,6 @@ public: |
|
|
|
size_t offset_base = staging_ref.offset; |
|
|
|
for (auto q : pending_flush_queries) { |
|
|
|
auto* query = GetQuery(q); |
|
|
|
query->flags |= VideoCommon::QueryFlagBits::IsQueuedForAsyncFlush; |
|
|
|
auto& bank = bank_pool.GetBank(query->start_bank_id); |
|
|
|
bank.Sync(staging_ref, offset_base, query->start_slot, 1); |
|
|
|
offset_base += TFBQueryBank::QUERY_SIZE; |
|
|
|
@ -1047,8 +1089,8 @@ struct QueryCacheRuntimeImpl { |
|
|
|
buffer_cache{buffer_cache_}, device{device_}, |
|
|
|
memory_allocator{memory_allocator_}, scheduler{scheduler_}, staging_pool{staging_pool_}, |
|
|
|
guest_streamer(0, runtime), |
|
|
|
sample_streamer(static_cast<size_t>(QueryType::ZPassPixelCount64), runtime, device, |
|
|
|
scheduler, memory_allocator), |
|
|
|
sample_streamer(static_cast<size_t>(QueryType::ZPassPixelCount64), runtime, rasterizer, |
|
|
|
device, scheduler, memory_allocator), |
|
|
|
tfb_streamer(static_cast<size_t>(QueryType::StreamingByteCount), runtime, device, |
|
|
|
scheduler, memory_allocator, staging_pool), |
|
|
|
primitives_succeeded_streamer( |
|
|
|
@ -1277,6 +1319,10 @@ bool QueryCacheRuntime::HostConditionalRenderingCompareValues(VideoCommon::Looku |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!is_in_bc[0] && !is_in_bc[1]) { |
|
|
|
// Both queries are in query cache, it's best to just flush.
|
|
|
|
return false; |
|
|
|
} |
|
|
|
HostConditionalRenderingCompareBCImpl(object_1.address, equal_check); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|