summaryrefslogtreecommitdiff
path: root/src/virtio/vulkan/vn_feedback.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/virtio/vulkan/vn_feedback.c')
-rw-r--r--src/virtio/vulkan/vn_feedback.c59
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);
+}