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