diff options
Diffstat (limited to 'src/virtio/vulkan/vn_feedback.c')
-rw-r--r-- | src/virtio/vulkan/vn_feedback.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/virtio/vulkan/vn_feedback.c b/src/virtio/vulkan/vn_feedback.c index cdfdca9db3b..24041229f0c 100644 --- a/src/virtio/vulkan/vn_feedback.c +++ b/src/virtio/vulkan/vn_feedback.c @@ -7,6 +7,7 @@ #include "vn_device.h" #include "vn_physical_device.h" +#include "vn_queue.h" /* coherent buffer with bound and mapped memory */ struct vn_feedback_buffer { @@ -263,3 +264,61 @@ vn_feedback_pool_free(struct vn_feedback_pool *pool, list_add(&slot->head, &pool->free_slots); simple_mtx_unlock(&pool->mutex); } + +void +vn_feedback_event_cmd_record(VkCommandBuffer cmd_handle, + VkEvent ev_handle, + VkPipelineStageFlags stage_mask, + VkResult status) +{ + /* For vkCmdSetEvent and vkCmdResetEvent feedback interception. + * + * The injection point is after the event call to avoid introducing + * unexpected src stage waiting for VK_PIPELINE_STAGE_HOST_BIT and + * VK_PIPELINE_STAGE_TRANSFER_BIT if they are not already being waited by + * vkCmdSetEvent or vkCmdResetEvent. On the other hand, the delay in the + * feedback signal is acceptable for the nature of VkEvent, and the event + * feedback cmds lifecycle is guarded by the intercepted command buffer. + */ + struct vn_event *ev = vn_event_from_handle(ev_handle); + struct vn_feedback_slot *slot = ev->feedback_slot; + + if (!slot) + return; + + STATIC_ASSERT(sizeof(*slot->status) == 4); + + const VkBufferMemoryBarrier buf_barrier_before = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = NULL, + .srcAccessMask = + VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .buffer = slot->buffer, + .offset = slot->offset, + .size = 4, + }; + vn_CmdPipelineBarrier(cmd_handle, + stage_mask | VK_PIPELINE_STAGE_HOST_BIT | + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, + &buf_barrier_before, 0, NULL); + vn_CmdFillBuffer(cmd_handle, slot->buffer, slot->offset, 4, status); + + const VkBufferMemoryBarrier buf_barrier_after = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = NULL, + .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_HOST_READ_BIT | VK_ACCESS_HOST_WRITE_BIT, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .buffer = slot->buffer, + .offset = slot->offset, + .size = 4, + }; + vn_CmdPipelineBarrier(cmd_handle, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_HOST_BIT, 0, 0, NULL, 1, + &buf_barrier_after, 0, NULL); +} |