xref: /aosp_15_r20/external/mesa3d/src/virtio/vulkan/vn_feedback.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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