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
11 struct vn_feedback_pool {
12 /* single lock for simplicity though free_slots can use another */
13 simple_mtx_t mutex;
14
15 struct vn_device *dev;
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 /* alignment in bytes for slot suballocation from the feedback buffer */
23 uint32_t alignment;
24
25 /* first entry is the active feedback buffer */
26 struct list_head fb_bufs;
27
28 /* cache for returned feedback slots */
29 struct list_head free_slots;
30 };
31
32 enum vn_feedback_type {
33 VN_FEEDBACK_TYPE_FENCE = 0x1,
34 VN_FEEDBACK_TYPE_SEMAPHORE = 0x2,
35 VN_FEEDBACK_TYPE_EVENT = 0x4,
36 VN_FEEDBACK_TYPE_QUERY = 0x8,
37 };
38
39 struct vn_feedback_slot {
40 enum vn_feedback_type type;
41 uint32_t offset;
42 VkBuffer buf_handle;
43
44 union {
45 void *data;
46 VkResult *status;
47 uint64_t *counter;
48 };
49
50 struct list_head head;
51 };
52
53 struct vn_feedback_cmd_pool {
54 simple_mtx_t mutex;
55
56 VkCommandPool pool_handle;
57 struct list_head free_qfb_cmds;
58 };
59
60 /* coherent buffer with bound and mapped memory */
61 struct vn_feedback_buffer {
62 VkBuffer buf_handle;
63 VkDeviceMemory mem_handle;
64 void *data;
65
66 struct list_head head;
67 };
68
69 struct vn_semaphore_feedback_cmd {
70 struct vn_feedback_slot *src_slot;
71 VkCommandBuffer *cmd_handles;
72
73 struct list_head head;
74 };
75
76 struct vn_query_feedback_cmd {
77 struct vn_feedback_cmd_pool *fb_cmd_pool;
78 VkCommandBuffer cmd_handle;
79
80 struct list_head head;
81 };
82
83 VkResult
84 vn_feedback_pool_init(struct vn_device *dev,
85 struct vn_feedback_pool *pool,
86 uint32_t size,
87 const VkAllocationCallbacks *alloc);
88
89 void
90 vn_feedback_pool_fini(struct vn_feedback_pool *pool);
91
92 struct vn_feedback_slot *
93 vn_feedback_pool_alloc(struct vn_feedback_pool *pool,
94 enum vn_feedback_type type);
95
96 void
97 vn_feedback_pool_free(struct vn_feedback_pool *pool,
98 struct vn_feedback_slot *slot);
99
100 static inline VkResult
vn_feedback_get_status(struct vn_feedback_slot * slot)101 vn_feedback_get_status(struct vn_feedback_slot *slot)
102 {
103 return *slot->status;
104 }
105
106 static inline void
vn_feedback_reset_status(struct vn_feedback_slot * slot)107 vn_feedback_reset_status(struct vn_feedback_slot *slot)
108 {
109 assert(slot->type == VN_FEEDBACK_TYPE_FENCE ||
110 slot->type == VN_FEEDBACK_TYPE_EVENT);
111 *slot->status =
112 slot->type == VN_FEEDBACK_TYPE_FENCE ? VK_NOT_READY : VK_EVENT_RESET;
113 }
114
115 static inline void
vn_feedback_set_status(struct vn_feedback_slot * slot,VkResult status)116 vn_feedback_set_status(struct vn_feedback_slot *slot, VkResult status)
117 {
118 assert(slot->type == VN_FEEDBACK_TYPE_FENCE ||
119 slot->type == VN_FEEDBACK_TYPE_EVENT);
120 *slot->status = status;
121 }
122
123 static inline uint64_t
vn_feedback_get_counter(struct vn_feedback_slot * slot)124 vn_feedback_get_counter(struct vn_feedback_slot *slot)
125 {
126 assert(slot->type == VN_FEEDBACK_TYPE_SEMAPHORE);
127 return *slot->counter;
128 }
129
130 static inline void
vn_feedback_set_counter(struct vn_feedback_slot * slot,uint64_t counter)131 vn_feedback_set_counter(struct vn_feedback_slot *slot, uint64_t counter)
132 {
133 assert(slot->type == VN_FEEDBACK_TYPE_SEMAPHORE);
134 *slot->counter = counter;
135 }
136
137 VkResult
138 vn_feedback_buffer_create(struct vn_device *dev,
139 uint32_t size,
140 const VkAllocationCallbacks *alloc,
141 struct vn_feedback_buffer **out_fb_buf);
142
143 void
144 vn_feedback_buffer_destroy(struct vn_device *dev,
145 struct vn_feedback_buffer *fb_buf,
146 const VkAllocationCallbacks *alloc);
147
148 void
149 vn_event_feedback_cmd_record(VkCommandBuffer cmd_handle,
150 VkEvent ev_handle,
151 VkPipelineStageFlags2 src_stage_mask,
152 VkResult status,
153 bool sync2);
154
155 struct vn_semaphore_feedback_cmd *
156 vn_semaphore_feedback_cmd_alloc(struct vn_device *dev,
157 struct vn_feedback_slot *dst_slot);
158
159 void
160 vn_semaphore_feedback_cmd_free(struct vn_device *dev,
161 struct vn_semaphore_feedback_cmd *sfb_cmd);
162
163 VkResult
164 vn_query_feedback_cmd_alloc(VkDevice dev_handle,
165 struct vn_feedback_cmd_pool *fb_cmd_pool,
166 struct list_head *resolved_query_records,
167 struct vn_query_feedback_cmd **out_qfb_cmd);
168
169 void
170 vn_query_feedback_cmd_free(struct vn_query_feedback_cmd *qfb_cmd);
171
172 VkResult
173 vn_feedback_cmd_alloc(VkDevice dev_handle,
174 struct vn_feedback_cmd_pool *fb_cmd_pool,
175 struct vn_feedback_slot *dst_slot,
176 struct vn_feedback_slot *src_slot,
177 VkCommandBuffer *out_cmd_handle);
178 void
179 vn_feedback_cmd_free(VkDevice dev_handle,
180 struct vn_feedback_cmd_pool *fb_cmd_pool,
181 VkCommandBuffer cmd_handle);
182
183 VkResult
184 vn_feedback_cmd_pools_init(struct vn_device *dev);
185
186 void
187 vn_feedback_cmd_pools_fini(struct vn_device *dev);
188
189 #endif /* VN_FEEDBACK_H */
190