diff --git a/src/virtio/vulkan/vn_feedback.c b/src/virtio/vulkan/vn_feedback.c index c482454b842..c9351d4c3c7 100644 --- a/src/virtio/vulkan/vn_feedback.c +++ b/src/virtio/vulkan/vn_feedback.c @@ -8,6 +8,7 @@ #include "vn_command_buffer.h" #include "vn_device.h" #include "vn_physical_device.h" +#include "vn_query_pool.h" #include "vn_queue.h" static uint32_t @@ -512,6 +513,87 @@ vn_feedback_cmd_record(VkCommandBuffer cmd_handle, return vn_EndCommandBuffer(cmd_handle); } +void +vn_feedback_query_copy_cmd_record(VkCommandBuffer cmd_handle, + VkQueryPool pool_handle, + uint32_t query, + uint32_t count) +{ + struct vn_query_pool *pool = vn_query_pool_from_handle(pool_handle); + + if (!pool->feedback) + return; + + /* Results are always 64 bit and include availability bit (also 64 bit) */ + const size_t slot_size = (pool->result_array_size * 8) + 8; + const size_t offset = slot_size * query; + + /* Per spec: "The first synchronization scope includes all commands + * which reference the queries in queryPool indicated by query that + * occur earlier in submission order. If flags does not include + * VK_QUERY_RESULT_WAIT_BIT, vkCmdEndQueryIndexedEXT, + * vkCmdWriteTimestamp2, vkCmdEndQuery, and vkCmdWriteTimestamp are + * excluded from this scope." + * + * Set VK_QUERY_RESULT_WAIT_BIT to ensure ordering after + * vkCmdEndQuery or vkCmdWriteTimestamp makes the query available. + * + * Set VK_QUERY_RESULT_64_BIT as we can convert it to 32 bit if app + * requested that. + */ + vn_CmdCopyQueryPoolResults(cmd_handle, pool_handle, query, count, + pool->feedback->buffer, offset, slot_size, + VK_QUERY_RESULT_WITH_AVAILABILITY_BIT | + VK_QUERY_RESULT_64_BIT | + VK_QUERY_RESULT_WAIT_BIT); + + /* Per spec: "vkCmdCopyQueryPoolResults is considered to be a transfer + * operation, and its writes to buffer memory must be synchronized using + * VK_PIPELINE_STAGE_TRANSFER_BIT and VK_ACCESS_TRANSFER_WRITE_BIT + * before using the results." + */ + vn_feedback_cmd_record_flush_barrier(cmd_handle, pool->feedback->buffer, + offset, slot_size * count); +} + +void +vn_feedback_query_reset_cmd_record(VkCommandBuffer cmd_handle, + VkQueryPool pool_handle, + uint32_t first_query, + uint32_t count) +{ + struct vn_query_pool *pool = vn_query_pool_from_handle(pool_handle); + + if (!pool->feedback) + return; + + /* Results are always 64 bit and include availability bit (also 64 bit) */ + const size_t slot_size = (pool->result_array_size * 8) + 8; + const size_t offset = slot_size * first_query; + + const VkBufferMemoryBarrier buf_barrier_before = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = NULL, + .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .buffer = pool->feedback->buffer, + .offset = offset, + .size = slot_size * count, + }; + + vn_CmdPipelineBarrier(cmd_handle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, + &buf_barrier_before, 0, NULL); + + vn_CmdFillBuffer(cmd_handle, pool->feedback->buffer, offset, + slot_size * count, 0); + + vn_feedback_cmd_record_flush_barrier(cmd_handle, pool->feedback->buffer, + offset, slot_size * count); +} + VkResult vn_feedback_cmd_alloc(VkDevice dev_handle, struct vn_feedback_cmd_pool *pool, diff --git a/src/virtio/vulkan/vn_feedback.h b/src/virtio/vulkan/vn_feedback.h index 9e4863949d4..97b7f9285e5 100644 --- a/src/virtio/vulkan/vn_feedback.h +++ b/src/virtio/vulkan/vn_feedback.h @@ -135,6 +135,19 @@ vn_feedback_event_cmd_record(VkCommandBuffer cmd_handle, VkPipelineStageFlags2 src_stage_mask, VkResult status, bool sync2); + +void +vn_feedback_query_copy_cmd_record(VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + uint32_t queryCount); + +void +vn_feedback_query_reset_cmd_record(VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + uint32_t queryCount); + VkResult vn_feedback_cmd_alloc(VkDevice dev_handle, struct vn_feedback_cmd_pool *pool, diff --git a/src/virtio/vulkan/vn_query_pool.h b/src/virtio/vulkan/vn_query_pool.h index dae225978dd..785c94b35b9 100644 --- a/src/virtio/vulkan/vn_query_pool.h +++ b/src/virtio/vulkan/vn_query_pool.h @@ -13,10 +13,14 @@ #include "vn_common.h" +struct vn_feedback_buffer; + struct vn_query_pool { struct vn_object_base base; VkAllocationCallbacks allocator; + + struct vn_feedback_buffer *feedback; uint32_t result_array_size; }; VK_DEFINE_NONDISP_HANDLE_CASTS(vn_query_pool,