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 *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
30 enum vn_feedback_type {
31 VN_FEEDBACK_TYPE_FENCE,
32 VN_FEEDBACK_TYPE_TIMELINE_SEMAPHORE,
33 VN_FEEDBACK_TYPE_EVENT,
34 };
35
36 struct 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
50 struct vn_feedback_cmd_pool {
51 simple_mtx_t mutex;
52
53 VkCommandPool pool;
54 };
55
56 VkResult
57 vn_feedback_pool_init(struct vn_device *dev,
58 struct vn_feedback_pool *pool,
59 uint32_t size,
60 const VkAllocationCallbacks *alloc);
61
62 void
63 vn_feedback_pool_fini(struct vn_feedback_pool *pool);
64
65 struct vn_feedback_slot *
66 vn_feedback_pool_alloc(struct vn_feedback_pool *pool,
67 enum vn_feedback_type type);
68
69 void
70 vn_feedback_pool_free(struct vn_feedback_pool *pool,
71 struct vn_feedback_slot *slot);
72
73 static inline VkResult
vn_feedback_get_status(struct vn_feedback_slot *slot)74 vn_feedback_get_status(struct vn_feedback_slot *slot)
75 {
76 return *slot->status;
77 }
78
79 static inline void
vn_feedback_reset_status(struct vn_feedback_slot *slot)80 vn_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
88 static inline void
vn_feedback_set_status(struct vn_feedback_slot *slot, VkResult status)89 vn_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
96 static inline uint64_t
vn_feedback_get_counter(struct vn_feedback_slot *slot)97 vn_feedback_get_counter(struct vn_feedback_slot *slot)
98 {
99 assert(slot->type == VN_FEEDBACK_TYPE_TIMELINE_SEMAPHORE);
100 return *slot->counter;
101 }
102
103 static inline void
vn_feedback_set_counter(struct vn_feedback_slot *slot, uint64_t counter)104 vn_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
110 void
111 vn_feedback_event_cmd_record(VkCommandBuffer cmd_handle,
112 VkEvent ev_handle,
113 VkPipelineStageFlags stage_mask,
114 VkResult status);
115
116 VkResult
117 vn_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
122 void
123 vn_feedback_fence_cmd_free(VkDevice dev_handle,
124 struct vn_feedback_cmd_pool *pool,
125 VkCommandBuffer cmd_handle);
126
127 VkResult
128 vn_feedback_cmd_pools_init(struct vn_device *dev);
129
130 void
131 vn_feedback_cmd_pools_fini(struct vn_device *dev);
132
133 #endif /* VN_FEEDBACK_H */
134