1/* 2 * Copyright 2022 Google LLC 3 * SPDX-License-Identifier: MIT 4 */ 5 6#ifndef VN_FEEDBACK_H 7#define VN_FEEDBACK_H 8 9#include "vn_common.h" 10 11struct vn_feedback_pool { 12 /* single lock for simplicity though free_slots can use another */ 13 simple_mtx_t mutex; 14 15 struct vn_device *device; 16 const VkAllocationCallbacks *alloc; 17 18 /* size in bytes of the feedback buffer */ 19 uint32_t size; 20 /* size in bytes used of the active feedback buffer */ 21 uint32_t used; 22 23 /* first entry is the active feedback buffer */ 24 struct list_head feedback_buffers; 25 26 /* cache for returned feedback slots */ 27 struct list_head free_slots; 28}; 29 30enum vn_feedback_type { 31 VN_FEEDBACK_TYPE_FENCE, 32 VN_FEEDBACK_TYPE_TIMELINE_SEMAPHORE, 33 VN_FEEDBACK_TYPE_EVENT, 34}; 35 36struct vn_feedback_slot { 37 enum vn_feedback_type type; 38 uint32_t offset; 39 VkBuffer buffer; 40 41 union { 42 void *data; 43 VkResult *status; 44 uint64_t *counter; 45 }; 46 47 struct list_head head; 48}; 49 50struct vn_feedback_cmd_pool { 51 simple_mtx_t mutex; 52 53 VkCommandPool pool; 54}; 55 56VkResult 57vn_feedback_pool_init(struct vn_device *dev, 58 struct vn_feedback_pool *pool, 59 uint32_t size, 60 const VkAllocationCallbacks *alloc); 61 62void 63vn_feedback_pool_fini(struct vn_feedback_pool *pool); 64 65struct vn_feedback_slot * 66vn_feedback_pool_alloc(struct vn_feedback_pool *pool, 67 enum vn_feedback_type type); 68 69void 70vn_feedback_pool_free(struct vn_feedback_pool *pool, 71 struct vn_feedback_slot *slot); 72 73static inline VkResult 74vn_feedback_get_status(struct vn_feedback_slot *slot) 75{ 76 return *slot->status; 77} 78 79static inline void 80vn_feedback_reset_status(struct vn_feedback_slot *slot) 81{ 82 assert(slot->type == VN_FEEDBACK_TYPE_FENCE || 83 slot->type == VN_FEEDBACK_TYPE_EVENT); 84 *slot->status = 85 slot->type == VN_FEEDBACK_TYPE_FENCE ? VK_NOT_READY : VK_EVENT_RESET; 86} 87 88static inline void 89vn_feedback_set_status(struct vn_feedback_slot *slot, VkResult status) 90{ 91 assert(slot->type == VN_FEEDBACK_TYPE_FENCE || 92 slot->type == VN_FEEDBACK_TYPE_EVENT); 93 *slot->status = status; 94} 95 96static inline uint64_t 97vn_feedback_get_counter(struct vn_feedback_slot *slot) 98{ 99 assert(slot->type == VN_FEEDBACK_TYPE_TIMELINE_SEMAPHORE); 100 return *slot->counter; 101} 102 103static inline void 104vn_feedback_set_counter(struct vn_feedback_slot *slot, uint64_t counter) 105{ 106 assert(slot->type == VN_FEEDBACK_TYPE_TIMELINE_SEMAPHORE); 107 *slot->counter = counter; 108} 109 110void 111vn_feedback_event_cmd_record(VkCommandBuffer cmd_handle, 112 VkEvent ev_handle, 113 VkPipelineStageFlags stage_mask, 114 VkResult status); 115 116VkResult 117vn_feedback_fence_cmd_alloc(VkDevice dev_handle, 118 struct vn_feedback_cmd_pool *pool, 119 struct vn_feedback_slot *slot, 120 VkCommandBuffer *out_cmd_handle); 121 122void 123vn_feedback_fence_cmd_free(VkDevice dev_handle, 124 struct vn_feedback_cmd_pool *pool, 125 VkCommandBuffer cmd_handle); 126 127VkResult 128vn_feedback_cmd_pools_init(struct vn_device *dev); 129 130void 131vn_feedback_cmd_pools_fini(struct vn_device *dev); 132 133#endif /* VN_FEEDBACK_H */ 134