mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-27 01:17:40 +00:00
[vulkan] Another approach for queries reset
This commit is contained in:
@@ -41,8 +41,8 @@ class SamplesQueryBank : public VideoCommon::BankBase {
|
||||
public:
|
||||
static constexpr size_t BANK_SIZE = 256;
|
||||
static constexpr size_t QUERY_SIZE = 8;
|
||||
explicit SamplesQueryBank(const Device& device_, size_t index_)
|
||||
: BankBase(BANK_SIZE), device{device_}, index{index_} {
|
||||
explicit SamplesQueryBank(const Device& device_, Scheduler& scheduler_, size_t index_)
|
||||
: BankBase(BANK_SIZE), device{device_}, scheduler{scheduler_}, index{index_} {
|
||||
const auto& dev = device.GetLogical();
|
||||
query_pool = dev.CreateQueryPool({
|
||||
.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,
|
||||
@@ -60,12 +60,28 @@ public:
|
||||
void Reset() override {
|
||||
ASSERT(references == 0);
|
||||
VideoCommon::BankBase::Reset();
|
||||
const auto& dev = device.GetLogical();
|
||||
dev.ResetQueryPool(*query_pool, 0, BANK_SIZE);
|
||||
if (device.IsHostQueryResetSupported()) {
|
||||
const auto& dev = device.GetLogical();
|
||||
dev.ResetQueryPool(*query_pool, 0, BANK_SIZE);
|
||||
} else {
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([pool = *query_pool](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.ResetQueryPool(pool, 0, BANK_SIZE);
|
||||
});
|
||||
}
|
||||
host_results.fill(0ULL);
|
||||
next_bank = 0;
|
||||
}
|
||||
|
||||
void AddReference(size_t how_many = 1) {
|
||||
BankBase::AddReference(how_many);
|
||||
last_used_tick = scheduler.CurrentTick();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsDead() const {
|
||||
return BankBase::IsDead() && scheduler.IsFree(last_used_tick);
|
||||
}
|
||||
|
||||
void Sync(size_t start, size_t size) {
|
||||
const auto& dev = device.GetLogical();
|
||||
const VkResult query_result = dev.GetQueryResults(
|
||||
@@ -98,9 +114,11 @@ public:
|
||||
|
||||
private:
|
||||
const Device& device;
|
||||
Scheduler& scheduler;
|
||||
const size_t index;
|
||||
vk::QueryPool query_pool;
|
||||
std::array<u64, BANK_SIZE> host_results;
|
||||
u64 last_used_tick{};
|
||||
};
|
||||
|
||||
using BaseStreamer = VideoCommon::SimpleStreamer<VideoCommon::HostQueryBase>;
|
||||
@@ -431,7 +449,7 @@ private:
|
||||
void ReserveBank() {
|
||||
current_bank_id =
|
||||
bank_pool.ReserveBank([this](std::deque<SamplesQueryBank>& queue, size_t index) {
|
||||
queue.emplace_back(device, index);
|
||||
queue.emplace_back(device, scheduler, index);
|
||||
});
|
||||
if (current_bank) {
|
||||
current_bank->next_bank = current_bank_id + 1;
|
||||
@@ -620,6 +638,15 @@ public:
|
||||
VideoCommon::BankBase::Reset();
|
||||
}
|
||||
|
||||
void AddReference(size_t how_many = 1) {
|
||||
BankBase::AddReference(how_many);
|
||||
last_used_tick = scheduler.CurrentTick();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsDead() const {
|
||||
return BankBase::IsDead() && scheduler.IsFree(last_used_tick);
|
||||
}
|
||||
|
||||
void Sync(StagingBufferRef& stagging_buffer, size_t extra_offset, size_t start, size_t size) {
|
||||
scheduler.RequestOutsideRenderPassOperationContext();
|
||||
scheduler.Record([this, dst_buffer = stagging_buffer.buffer, extra_offset, start,
|
||||
@@ -645,6 +672,7 @@ private:
|
||||
Scheduler& scheduler;
|
||||
const size_t index;
|
||||
vk::Buffer buffer;
|
||||
u64 last_used_tick{};
|
||||
};
|
||||
|
||||
class PrimitivesSucceededStreamer;
|
||||
|
||||
@@ -523,7 +523,6 @@ FN_MAX_LIMIT_LIST
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_EXT_shader_stencil_export.
|
||||
/// Note: Most Mali/NVIDIA drivers don't support this. Use hardware blits as fallback.
|
||||
bool IsExtShaderStencilExportSupported() const {
|
||||
return extensions.shader_stencil_export;
|
||||
}
|
||||
@@ -560,6 +559,11 @@ FN_MAX_LIMIT_LIST
|
||||
return extensions.subgroup_size_control;
|
||||
}
|
||||
|
||||
/// Returns true if vkResetQueryPool (host-side query reset) is supported.
|
||||
bool IsHostQueryResetSupported() const {
|
||||
return features.host_query_reset.hostQueryReset != VK_FALSE;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_EXT_transform_feedback.
|
||||
bool IsExtTransformFeedbackSupported() const {
|
||||
return extensions.transform_feedback;
|
||||
|
||||
@@ -165,6 +165,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
|
||||
X(vkCmdSetColorWriteEnableEXT);
|
||||
X(vkCmdSetColorBlendEnableEXT);
|
||||
X(vkCmdSetColorBlendEquationEXT);
|
||||
X(vkCmdResetQueryPool);
|
||||
X(vkCmdResolveImage);
|
||||
X(vkCreateBuffer);
|
||||
X(vkCreateBufferView);
|
||||
|
||||
@@ -241,6 +241,7 @@ struct DeviceDispatch : InstanceDispatch {
|
||||
PFN_vkCmdPipelineBarrier2 vkCmdPipelineBarrier2{};
|
||||
PFN_vkCmdPushConstants vkCmdPushConstants{};
|
||||
PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR{};
|
||||
PFN_vkCmdResetQueryPool vkCmdResetQueryPool{};
|
||||
PFN_vkCmdResolveImage vkCmdResolveImage{};
|
||||
PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants{};
|
||||
PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT{};
|
||||
@@ -1191,6 +1192,10 @@ public:
|
||||
dld->vkCmdEndQuery(handle, query_pool, query);
|
||||
}
|
||||
|
||||
void ResetQueryPool(VkQueryPool query_pool, u32 first, u32 count) const noexcept {
|
||||
dld->vkCmdResetQueryPool(handle, query_pool, first, count);
|
||||
}
|
||||
|
||||
void BindDescriptorSets(VkPipelineBindPoint bind_point, VkPipelineLayout layout, u32 first,
|
||||
Span<VkDescriptorSet> sets, Span<u32> dynamic_offsets) const noexcept {
|
||||
dld->vkCmdBindDescriptorSets(handle, bind_point, layout, first, sets.size(), sets.data(),
|
||||
|
||||
Reference in New Issue
Block a user