xref: /aosp_15_r20/external/mesa3d/src/virtio/vulkan/vn_feedback.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright 2022 Google LLC
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker 
6*61046927SAndroid Build Coastguard Worker #include "vn_feedback.h"
7*61046927SAndroid Build Coastguard Worker 
8*61046927SAndroid Build Coastguard Worker #include "vn_command_buffer.h"
9*61046927SAndroid Build Coastguard Worker #include "vn_device.h"
10*61046927SAndroid Build Coastguard Worker #include "vn_physical_device.h"
11*61046927SAndroid Build Coastguard Worker #include "vn_query_pool.h"
12*61046927SAndroid Build Coastguard Worker #include "vn_queue.h"
13*61046927SAndroid Build Coastguard Worker 
14*61046927SAndroid Build Coastguard Worker static uint32_t
vn_get_memory_type_index(const VkPhysicalDeviceMemoryProperties * mem_props,uint32_t mem_type_bits,VkMemoryPropertyFlags required_mem_flags)15*61046927SAndroid Build Coastguard Worker vn_get_memory_type_index(const VkPhysicalDeviceMemoryProperties *mem_props,
16*61046927SAndroid Build Coastguard Worker                          uint32_t mem_type_bits,
17*61046927SAndroid Build Coastguard Worker                          VkMemoryPropertyFlags required_mem_flags)
18*61046927SAndroid Build Coastguard Worker {
19*61046927SAndroid Build Coastguard Worker    u_foreach_bit(mem_type_index, mem_type_bits)
20*61046927SAndroid Build Coastguard Worker    {
21*61046927SAndroid Build Coastguard Worker       assert(mem_type_index < mem_props->memoryTypeCount);
22*61046927SAndroid Build Coastguard Worker       if ((mem_props->memoryTypes[mem_type_index].propertyFlags &
23*61046927SAndroid Build Coastguard Worker            required_mem_flags) == required_mem_flags)
24*61046927SAndroid Build Coastguard Worker          return mem_type_index;
25*61046927SAndroid Build Coastguard Worker    }
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker    return UINT32_MAX;
28*61046927SAndroid Build Coastguard Worker }
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker VkResult
vn_feedback_buffer_create(struct vn_device * dev,uint32_t size,const VkAllocationCallbacks * alloc,struct vn_feedback_buffer ** out_fb_buf)31*61046927SAndroid Build Coastguard Worker vn_feedback_buffer_create(struct vn_device *dev,
32*61046927SAndroid Build Coastguard Worker                           uint32_t size,
33*61046927SAndroid Build Coastguard Worker                           const VkAllocationCallbacks *alloc,
34*61046927SAndroid Build Coastguard Worker                           struct vn_feedback_buffer **out_fb_buf)
35*61046927SAndroid Build Coastguard Worker {
36*61046927SAndroid Build Coastguard Worker    const bool exclusive = dev->queue_family_count == 1;
37*61046927SAndroid Build Coastguard Worker    const VkPhysicalDeviceMemoryProperties *mem_props =
38*61046927SAndroid Build Coastguard Worker       &dev->physical_device->memory_properties;
39*61046927SAndroid Build Coastguard Worker    VkDevice dev_handle = vn_device_to_handle(dev);
40*61046927SAndroid Build Coastguard Worker    VkResult result;
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker    struct vn_feedback_buffer *fb_buf =
43*61046927SAndroid Build Coastguard Worker       vk_zalloc(alloc, sizeof(*fb_buf), VN_DEFAULT_ALIGN,
44*61046927SAndroid Build Coastguard Worker                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
45*61046927SAndroid Build Coastguard Worker    if (!fb_buf)
46*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
47*61046927SAndroid Build Coastguard Worker 
48*61046927SAndroid Build Coastguard Worker    /* use concurrent to avoid explicit queue family ownership transfer for
49*61046927SAndroid Build Coastguard Worker     * device created with queues from multiple queue families
50*61046927SAndroid Build Coastguard Worker     */
51*61046927SAndroid Build Coastguard Worker    const VkBufferCreateInfo buf_create_info = {
52*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
53*61046927SAndroid Build Coastguard Worker       .size = size,
54*61046927SAndroid Build Coastguard Worker       /* Feedback for fences and timeline semaphores will write to this buffer
55*61046927SAndroid Build Coastguard Worker        * as a DST when signalling. Timeline semaphore feedback will also read
56*61046927SAndroid Build Coastguard Worker        * from this buffer as a SRC to retrieve the counter value to signal.
57*61046927SAndroid Build Coastguard Worker        */
58*61046927SAndroid Build Coastguard Worker       .usage =
59*61046927SAndroid Build Coastguard Worker          VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
60*61046927SAndroid Build Coastguard Worker       .sharingMode =
61*61046927SAndroid Build Coastguard Worker          exclusive ? VK_SHARING_MODE_EXCLUSIVE : VK_SHARING_MODE_CONCURRENT,
62*61046927SAndroid Build Coastguard Worker       /* below favors the current venus protocol */
63*61046927SAndroid Build Coastguard Worker       .queueFamilyIndexCount = exclusive ? 0 : dev->queue_family_count,
64*61046927SAndroid Build Coastguard Worker       .pQueueFamilyIndices = exclusive ? NULL : dev->queue_families,
65*61046927SAndroid Build Coastguard Worker    };
66*61046927SAndroid Build Coastguard Worker    result = vn_CreateBuffer(dev_handle, &buf_create_info, alloc,
67*61046927SAndroid Build Coastguard Worker                             &fb_buf->buf_handle);
68*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
69*61046927SAndroid Build Coastguard Worker       goto out_free_feedback_buffer;
70*61046927SAndroid Build Coastguard Worker 
71*61046927SAndroid Build Coastguard Worker    struct vn_buffer *buf = vn_buffer_from_handle(fb_buf->buf_handle);
72*61046927SAndroid Build Coastguard Worker    const VkMemoryRequirements *mem_req =
73*61046927SAndroid Build Coastguard Worker       &buf->requirements.memory.memoryRequirements;
74*61046927SAndroid Build Coastguard Worker    const uint32_t mem_type_index =
75*61046927SAndroid Build Coastguard Worker       vn_get_memory_type_index(mem_props, mem_req->memoryTypeBits,
76*61046927SAndroid Build Coastguard Worker                                VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
77*61046927SAndroid Build Coastguard Worker    if (mem_type_index >= mem_props->memoryTypeCount) {
78*61046927SAndroid Build Coastguard Worker       result = VK_ERROR_INITIALIZATION_FAILED;
79*61046927SAndroid Build Coastguard Worker       goto out_destroy_buffer;
80*61046927SAndroid Build Coastguard Worker    }
81*61046927SAndroid Build Coastguard Worker 
82*61046927SAndroid Build Coastguard Worker    const VkMemoryAllocateInfo mem_alloc_info = {
83*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
84*61046927SAndroid Build Coastguard Worker       .allocationSize = mem_req->size,
85*61046927SAndroid Build Coastguard Worker       .memoryTypeIndex = mem_type_index,
86*61046927SAndroid Build Coastguard Worker    };
87*61046927SAndroid Build Coastguard Worker    result = vn_AllocateMemory(dev_handle, &mem_alloc_info, alloc,
88*61046927SAndroid Build Coastguard Worker                               &fb_buf->mem_handle);
89*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
90*61046927SAndroid Build Coastguard Worker       goto out_destroy_buffer;
91*61046927SAndroid Build Coastguard Worker 
92*61046927SAndroid Build Coastguard Worker    const VkBindBufferMemoryInfo bind_info = {
93*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
94*61046927SAndroid Build Coastguard Worker       .buffer = fb_buf->buf_handle,
95*61046927SAndroid Build Coastguard Worker       .memory = fb_buf->mem_handle,
96*61046927SAndroid Build Coastguard Worker       .memoryOffset = 0,
97*61046927SAndroid Build Coastguard Worker    };
98*61046927SAndroid Build Coastguard Worker    result = vn_BindBufferMemory2(dev_handle, 1, &bind_info);
99*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
100*61046927SAndroid Build Coastguard Worker       goto out_free_memory;
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker    result = vn_MapMemory(dev_handle, fb_buf->mem_handle, 0, VK_WHOLE_SIZE, 0,
103*61046927SAndroid Build Coastguard Worker                          &fb_buf->data);
104*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
105*61046927SAndroid Build Coastguard Worker       goto out_free_memory;
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker    *out_fb_buf = fb_buf;
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker out_free_memory:
112*61046927SAndroid Build Coastguard Worker    vn_FreeMemory(dev_handle, fb_buf->mem_handle, alloc);
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker out_destroy_buffer:
115*61046927SAndroid Build Coastguard Worker    vn_DestroyBuffer(dev_handle, fb_buf->buf_handle, alloc);
116*61046927SAndroid Build Coastguard Worker 
117*61046927SAndroid Build Coastguard Worker out_free_feedback_buffer:
118*61046927SAndroid Build Coastguard Worker    vk_free(alloc, fb_buf);
119*61046927SAndroid Build Coastguard Worker 
120*61046927SAndroid Build Coastguard Worker    return result;
121*61046927SAndroid Build Coastguard Worker }
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker void
vn_feedback_buffer_destroy(struct vn_device * dev,struct vn_feedback_buffer * fb_buf,const VkAllocationCallbacks * alloc)124*61046927SAndroid Build Coastguard Worker vn_feedback_buffer_destroy(struct vn_device *dev,
125*61046927SAndroid Build Coastguard Worker                            struct vn_feedback_buffer *fb_buf,
126*61046927SAndroid Build Coastguard Worker                            const VkAllocationCallbacks *alloc)
127*61046927SAndroid Build Coastguard Worker {
128*61046927SAndroid Build Coastguard Worker    VkDevice dev_handle = vn_device_to_handle(dev);
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker    vn_UnmapMemory(dev_handle, fb_buf->mem_handle);
131*61046927SAndroid Build Coastguard Worker    vn_FreeMemory(dev_handle, fb_buf->mem_handle, alloc);
132*61046927SAndroid Build Coastguard Worker    vn_DestroyBuffer(dev_handle, fb_buf->buf_handle, alloc);
133*61046927SAndroid Build Coastguard Worker    vk_free(alloc, fb_buf);
134*61046927SAndroid Build Coastguard Worker }
135*61046927SAndroid Build Coastguard Worker 
136*61046927SAndroid Build Coastguard Worker static inline uint32_t
vn_get_feedback_buffer_alignment(struct vn_device * dev,struct vn_feedback_buffer * fb_buf)137*61046927SAndroid Build Coastguard Worker vn_get_feedback_buffer_alignment(struct vn_device *dev,
138*61046927SAndroid Build Coastguard Worker                                  struct vn_feedback_buffer *fb_buf)
139*61046927SAndroid Build Coastguard Worker {
140*61046927SAndroid Build Coastguard Worker    struct vn_buffer *buf = vn_buffer_from_handle(fb_buf->buf_handle);
141*61046927SAndroid Build Coastguard Worker    return align(buf->requirements.memory.memoryRequirements.alignment,
142*61046927SAndroid Build Coastguard Worker                 dev->physical_device->wa_min_fb_align);
143*61046927SAndroid Build Coastguard Worker }
144*61046927SAndroid Build Coastguard Worker 
145*61046927SAndroid Build Coastguard Worker static VkResult
vn_feedback_pool_grow_locked(struct vn_feedback_pool * pool)146*61046927SAndroid Build Coastguard Worker vn_feedback_pool_grow_locked(struct vn_feedback_pool *pool)
147*61046927SAndroid Build Coastguard Worker {
148*61046927SAndroid Build Coastguard Worker    VN_TRACE_FUNC();
149*61046927SAndroid Build Coastguard Worker    struct vn_feedback_buffer *fb_buf = NULL;
150*61046927SAndroid Build Coastguard Worker    VkResult result;
151*61046927SAndroid Build Coastguard Worker 
152*61046927SAndroid Build Coastguard Worker    result =
153*61046927SAndroid Build Coastguard Worker       vn_feedback_buffer_create(pool->dev, pool->size, pool->alloc, &fb_buf);
154*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
155*61046927SAndroid Build Coastguard Worker       return result;
156*61046927SAndroid Build Coastguard Worker 
157*61046927SAndroid Build Coastguard Worker    pool->used = 0;
158*61046927SAndroid Build Coastguard Worker    pool->alignment = vn_get_feedback_buffer_alignment(pool->dev, fb_buf);
159*61046927SAndroid Build Coastguard Worker 
160*61046927SAndroid Build Coastguard Worker    list_add(&fb_buf->head, &pool->fb_bufs);
161*61046927SAndroid Build Coastguard Worker 
162*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
163*61046927SAndroid Build Coastguard Worker }
164*61046927SAndroid Build Coastguard Worker 
165*61046927SAndroid Build Coastguard Worker VkResult
vn_feedback_pool_init(struct vn_device * dev,struct vn_feedback_pool * pool,uint32_t size,const VkAllocationCallbacks * alloc)166*61046927SAndroid Build Coastguard Worker vn_feedback_pool_init(struct vn_device *dev,
167*61046927SAndroid Build Coastguard Worker                       struct vn_feedback_pool *pool,
168*61046927SAndroid Build Coastguard Worker                       uint32_t size,
169*61046927SAndroid Build Coastguard Worker                       const VkAllocationCallbacks *alloc)
170*61046927SAndroid Build Coastguard Worker {
171*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&pool->mutex, mtx_plain);
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker    pool->dev = dev;
174*61046927SAndroid Build Coastguard Worker    pool->alloc = alloc;
175*61046927SAndroid Build Coastguard Worker    pool->size = size;
176*61046927SAndroid Build Coastguard Worker    pool->used = size;
177*61046927SAndroid Build Coastguard Worker    pool->alignment = 1;
178*61046927SAndroid Build Coastguard Worker    list_inithead(&pool->fb_bufs);
179*61046927SAndroid Build Coastguard Worker    list_inithead(&pool->free_slots);
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
182*61046927SAndroid Build Coastguard Worker }
183*61046927SAndroid Build Coastguard Worker 
184*61046927SAndroid Build Coastguard Worker void
vn_feedback_pool_fini(struct vn_feedback_pool * pool)185*61046927SAndroid Build Coastguard Worker vn_feedback_pool_fini(struct vn_feedback_pool *pool)
186*61046927SAndroid Build Coastguard Worker {
187*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe(struct vn_feedback_slot, slot, &pool->free_slots,
188*61046927SAndroid Build Coastguard Worker                             head)
189*61046927SAndroid Build Coastguard Worker       vk_free(pool->alloc, slot);
190*61046927SAndroid Build Coastguard Worker 
191*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe(struct vn_feedback_buffer, fb_buf, &pool->fb_bufs,
192*61046927SAndroid Build Coastguard Worker                             head)
193*61046927SAndroid Build Coastguard Worker       vn_feedback_buffer_destroy(pool->dev, fb_buf, pool->alloc);
194*61046927SAndroid Build Coastguard Worker 
195*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&pool->mutex);
196*61046927SAndroid Build Coastguard Worker }
197*61046927SAndroid Build Coastguard Worker 
198*61046927SAndroid Build Coastguard Worker static struct vn_feedback_buffer *
vn_feedback_pool_alloc_locked(struct vn_feedback_pool * pool,uint32_t size,uint32_t * out_offset)199*61046927SAndroid Build Coastguard Worker vn_feedback_pool_alloc_locked(struct vn_feedback_pool *pool,
200*61046927SAndroid Build Coastguard Worker                               uint32_t size,
201*61046927SAndroid Build Coastguard Worker                               uint32_t *out_offset)
202*61046927SAndroid Build Coastguard Worker {
203*61046927SAndroid Build Coastguard Worker    /* Default values of pool->used and pool->alignment are used to trigger the
204*61046927SAndroid Build Coastguard Worker     * initial pool grow, and will be properly initialized after that.
205*61046927SAndroid Build Coastguard Worker     */
206*61046927SAndroid Build Coastguard Worker    if (unlikely(align(size, pool->alignment) > pool->size - pool->used)) {
207*61046927SAndroid Build Coastguard Worker       VkResult result = vn_feedback_pool_grow_locked(pool);
208*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
209*61046927SAndroid Build Coastguard Worker          return NULL;
210*61046927SAndroid Build Coastguard Worker 
211*61046927SAndroid Build Coastguard Worker       assert(align(size, pool->alignment) <= pool->size - pool->used);
212*61046927SAndroid Build Coastguard Worker    }
213*61046927SAndroid Build Coastguard Worker 
214*61046927SAndroid Build Coastguard Worker    *out_offset = pool->used;
215*61046927SAndroid Build Coastguard Worker    pool->used += align(size, pool->alignment);
216*61046927SAndroid Build Coastguard Worker 
217*61046927SAndroid Build Coastguard Worker    return list_first_entry(&pool->fb_bufs, struct vn_feedback_buffer, head);
218*61046927SAndroid Build Coastguard Worker }
219*61046927SAndroid Build Coastguard Worker 
220*61046927SAndroid Build Coastguard Worker struct vn_feedback_slot *
vn_feedback_pool_alloc(struct vn_feedback_pool * pool,enum vn_feedback_type type)221*61046927SAndroid Build Coastguard Worker vn_feedback_pool_alloc(struct vn_feedback_pool *pool,
222*61046927SAndroid Build Coastguard Worker                        enum vn_feedback_type type)
223*61046927SAndroid Build Coastguard Worker {
224*61046927SAndroid Build Coastguard Worker    static const uint32_t slot_size = 8;
225*61046927SAndroid Build Coastguard Worker    struct vn_feedback_buffer *fb_buf;
226*61046927SAndroid Build Coastguard Worker    uint32_t offset;
227*61046927SAndroid Build Coastguard Worker    struct vn_feedback_slot *slot;
228*61046927SAndroid Build Coastguard Worker 
229*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&pool->mutex);
230*61046927SAndroid Build Coastguard Worker    if (!list_is_empty(&pool->free_slots)) {
231*61046927SAndroid Build Coastguard Worker       slot =
232*61046927SAndroid Build Coastguard Worker          list_first_entry(&pool->free_slots, struct vn_feedback_slot, head);
233*61046927SAndroid Build Coastguard Worker       list_del(&slot->head);
234*61046927SAndroid Build Coastguard Worker       simple_mtx_unlock(&pool->mutex);
235*61046927SAndroid Build Coastguard Worker 
236*61046927SAndroid Build Coastguard Worker       slot->type = type;
237*61046927SAndroid Build Coastguard Worker       return slot;
238*61046927SAndroid Build Coastguard Worker    }
239*61046927SAndroid Build Coastguard Worker 
240*61046927SAndroid Build Coastguard Worker    slot = vk_alloc(pool->alloc, sizeof(*slot), VN_DEFAULT_ALIGN,
241*61046927SAndroid Build Coastguard Worker                    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
242*61046927SAndroid Build Coastguard Worker    if (!slot) {
243*61046927SAndroid Build Coastguard Worker       simple_mtx_unlock(&pool->mutex);
244*61046927SAndroid Build Coastguard Worker       return NULL;
245*61046927SAndroid Build Coastguard Worker    }
246*61046927SAndroid Build Coastguard Worker 
247*61046927SAndroid Build Coastguard Worker    fb_buf = vn_feedback_pool_alloc_locked(pool, slot_size, &offset);
248*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&pool->mutex);
249*61046927SAndroid Build Coastguard Worker 
250*61046927SAndroid Build Coastguard Worker    if (!fb_buf) {
251*61046927SAndroid Build Coastguard Worker       vk_free(pool->alloc, slot);
252*61046927SAndroid Build Coastguard Worker       return NULL;
253*61046927SAndroid Build Coastguard Worker    }
254*61046927SAndroid Build Coastguard Worker 
255*61046927SAndroid Build Coastguard Worker    slot->type = type;
256*61046927SAndroid Build Coastguard Worker    slot->offset = offset;
257*61046927SAndroid Build Coastguard Worker    slot->buf_handle = fb_buf->buf_handle;
258*61046927SAndroid Build Coastguard Worker    slot->data = fb_buf->data + offset;
259*61046927SAndroid Build Coastguard Worker 
260*61046927SAndroid Build Coastguard Worker    return slot;
261*61046927SAndroid Build Coastguard Worker }
262*61046927SAndroid Build Coastguard Worker 
263*61046927SAndroid Build Coastguard Worker void
vn_feedback_pool_free(struct vn_feedback_pool * pool,struct vn_feedback_slot * slot)264*61046927SAndroid Build Coastguard Worker vn_feedback_pool_free(struct vn_feedback_pool *pool,
265*61046927SAndroid Build Coastguard Worker                       struct vn_feedback_slot *slot)
266*61046927SAndroid Build Coastguard Worker {
267*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&pool->mutex);
268*61046927SAndroid Build Coastguard Worker    list_add(&slot->head, &pool->free_slots);
269*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&pool->mutex);
270*61046927SAndroid Build Coastguard Worker }
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker static inline bool
mask_is_32bit(uint64_t x)273*61046927SAndroid Build Coastguard Worker mask_is_32bit(uint64_t x)
274*61046927SAndroid Build Coastguard Worker {
275*61046927SAndroid Build Coastguard Worker    return (x & 0xffffffff00000000) == 0;
276*61046927SAndroid Build Coastguard Worker }
277*61046927SAndroid Build Coastguard Worker 
278*61046927SAndroid Build Coastguard Worker static void
vn_build_buffer_memory_barrier(const VkDependencyInfo * dep_info,VkBufferMemoryBarrier * barrier1,VkPipelineStageFlags * src_stage_mask,VkPipelineStageFlags * dst_stage_mask)279*61046927SAndroid Build Coastguard Worker vn_build_buffer_memory_barrier(const VkDependencyInfo *dep_info,
280*61046927SAndroid Build Coastguard Worker                                VkBufferMemoryBarrier *barrier1,
281*61046927SAndroid Build Coastguard Worker                                VkPipelineStageFlags *src_stage_mask,
282*61046927SAndroid Build Coastguard Worker                                VkPipelineStageFlags *dst_stage_mask)
283*61046927SAndroid Build Coastguard Worker {
284*61046927SAndroid Build Coastguard Worker 
285*61046927SAndroid Build Coastguard Worker    assert(dep_info->pNext == NULL);
286*61046927SAndroid Build Coastguard Worker    assert(dep_info->memoryBarrierCount == 0);
287*61046927SAndroid Build Coastguard Worker    assert(dep_info->bufferMemoryBarrierCount == 1);
288*61046927SAndroid Build Coastguard Worker    assert(dep_info->imageMemoryBarrierCount == 0);
289*61046927SAndroid Build Coastguard Worker 
290*61046927SAndroid Build Coastguard Worker    const VkBufferMemoryBarrier2 *barrier2 =
291*61046927SAndroid Build Coastguard Worker       &dep_info->pBufferMemoryBarriers[0];
292*61046927SAndroid Build Coastguard Worker    assert(barrier2->pNext == NULL);
293*61046927SAndroid Build Coastguard Worker    assert(mask_is_32bit(barrier2->srcStageMask));
294*61046927SAndroid Build Coastguard Worker    assert(mask_is_32bit(barrier2->srcAccessMask));
295*61046927SAndroid Build Coastguard Worker    assert(mask_is_32bit(barrier2->dstStageMask));
296*61046927SAndroid Build Coastguard Worker    assert(mask_is_32bit(barrier2->dstAccessMask));
297*61046927SAndroid Build Coastguard Worker 
298*61046927SAndroid Build Coastguard Worker    *barrier1 = (VkBufferMemoryBarrier){
299*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
300*61046927SAndroid Build Coastguard Worker       .pNext = NULL,
301*61046927SAndroid Build Coastguard Worker       .srcAccessMask = barrier2->srcAccessMask,
302*61046927SAndroid Build Coastguard Worker       .dstAccessMask = barrier2->dstAccessMask,
303*61046927SAndroid Build Coastguard Worker       .srcQueueFamilyIndex = barrier2->srcQueueFamilyIndex,
304*61046927SAndroid Build Coastguard Worker       .dstQueueFamilyIndex = barrier2->dstQueueFamilyIndex,
305*61046927SAndroid Build Coastguard Worker       .buffer = barrier2->buffer,
306*61046927SAndroid Build Coastguard Worker       .offset = barrier2->offset,
307*61046927SAndroid Build Coastguard Worker       .size = barrier2->size,
308*61046927SAndroid Build Coastguard Worker    };
309*61046927SAndroid Build Coastguard Worker 
310*61046927SAndroid Build Coastguard Worker    *src_stage_mask = barrier2->srcStageMask;
311*61046927SAndroid Build Coastguard Worker    *dst_stage_mask = barrier2->dstStageMask;
312*61046927SAndroid Build Coastguard Worker }
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker static void
vn_cmd_buffer_memory_barrier(VkCommandBuffer cmd_handle,const VkDependencyInfo * dep_info,bool sync2)315*61046927SAndroid Build Coastguard Worker vn_cmd_buffer_memory_barrier(VkCommandBuffer cmd_handle,
316*61046927SAndroid Build Coastguard Worker                              const VkDependencyInfo *dep_info,
317*61046927SAndroid Build Coastguard Worker                              bool sync2)
318*61046927SAndroid Build Coastguard Worker {
319*61046927SAndroid Build Coastguard Worker    if (sync2)
320*61046927SAndroid Build Coastguard Worker       vn_CmdPipelineBarrier2(cmd_handle, dep_info);
321*61046927SAndroid Build Coastguard Worker    else {
322*61046927SAndroid Build Coastguard Worker       VkBufferMemoryBarrier barrier1;
323*61046927SAndroid Build Coastguard Worker       VkPipelineStageFlags src_stage_mask;
324*61046927SAndroid Build Coastguard Worker       VkPipelineStageFlags dst_stage_mask;
325*61046927SAndroid Build Coastguard Worker 
326*61046927SAndroid Build Coastguard Worker       vn_build_buffer_memory_barrier(dep_info, &barrier1, &src_stage_mask,
327*61046927SAndroid Build Coastguard Worker                                      &dst_stage_mask);
328*61046927SAndroid Build Coastguard Worker       vn_CmdPipelineBarrier(cmd_handle, src_stage_mask, dst_stage_mask,
329*61046927SAndroid Build Coastguard Worker                             dep_info->dependencyFlags, 0, NULL, 1, &barrier1,
330*61046927SAndroid Build Coastguard Worker                             0, NULL);
331*61046927SAndroid Build Coastguard Worker    }
332*61046927SAndroid Build Coastguard Worker }
333*61046927SAndroid Build Coastguard Worker 
334*61046927SAndroid Build Coastguard Worker void
vn_event_feedback_cmd_record(VkCommandBuffer cmd_handle,VkEvent ev_handle,VkPipelineStageFlags2 src_stage_mask,VkResult status,bool sync2)335*61046927SAndroid Build Coastguard Worker vn_event_feedback_cmd_record(VkCommandBuffer cmd_handle,
336*61046927SAndroid Build Coastguard Worker                              VkEvent ev_handle,
337*61046927SAndroid Build Coastguard Worker                              VkPipelineStageFlags2 src_stage_mask,
338*61046927SAndroid Build Coastguard Worker                              VkResult status,
339*61046927SAndroid Build Coastguard Worker                              bool sync2)
340*61046927SAndroid Build Coastguard Worker {
341*61046927SAndroid Build Coastguard Worker    /* For vkCmdSetEvent and vkCmdResetEvent feedback interception.
342*61046927SAndroid Build Coastguard Worker     *
343*61046927SAndroid Build Coastguard Worker     * The injection point is after the event call to avoid introducing
344*61046927SAndroid Build Coastguard Worker     * unexpected src stage waiting for VK_PIPELINE_STAGE_HOST_BIT and
345*61046927SAndroid Build Coastguard Worker     * VK_PIPELINE_STAGE_TRANSFER_BIT if they are not already being waited by
346*61046927SAndroid Build Coastguard Worker     * vkCmdSetEvent or vkCmdResetEvent. On the other hand, the delay in the
347*61046927SAndroid Build Coastguard Worker     * feedback signal is acceptable for the nature of VkEvent, and the event
348*61046927SAndroid Build Coastguard Worker     * feedback cmds lifecycle is guarded by the intercepted command buffer.
349*61046927SAndroid Build Coastguard Worker     */
350*61046927SAndroid Build Coastguard Worker    struct vn_event *ev = vn_event_from_handle(ev_handle);
351*61046927SAndroid Build Coastguard Worker    struct vn_feedback_slot *slot = ev->feedback_slot;
352*61046927SAndroid Build Coastguard Worker 
353*61046927SAndroid Build Coastguard Worker    if (!slot)
354*61046927SAndroid Build Coastguard Worker       return;
355*61046927SAndroid Build Coastguard Worker 
356*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(sizeof(*slot->status) == 4);
357*61046927SAndroid Build Coastguard Worker 
358*61046927SAndroid Build Coastguard Worker    const VkDependencyInfo dep_before = {
359*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
360*61046927SAndroid Build Coastguard Worker       .dependencyFlags = 0,
361*61046927SAndroid Build Coastguard Worker       .bufferMemoryBarrierCount = 1,
362*61046927SAndroid Build Coastguard Worker       .pBufferMemoryBarriers =
363*61046927SAndroid Build Coastguard Worker          (VkBufferMemoryBarrier2[]){
364*61046927SAndroid Build Coastguard Worker             {
365*61046927SAndroid Build Coastguard Worker                .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
366*61046927SAndroid Build Coastguard Worker                .srcStageMask = src_stage_mask | VK_PIPELINE_STAGE_HOST_BIT |
367*61046927SAndroid Build Coastguard Worker                                VK_PIPELINE_STAGE_TRANSFER_BIT,
368*61046927SAndroid Build Coastguard Worker                .srcAccessMask =
369*61046927SAndroid Build Coastguard Worker                   VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
370*61046927SAndroid Build Coastguard Worker                .dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT,
371*61046927SAndroid Build Coastguard Worker                .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
372*61046927SAndroid Build Coastguard Worker                .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
373*61046927SAndroid Build Coastguard Worker                .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
374*61046927SAndroid Build Coastguard Worker                .buffer = slot->buf_handle,
375*61046927SAndroid Build Coastguard Worker                .offset = slot->offset,
376*61046927SAndroid Build Coastguard Worker                .size = 4,
377*61046927SAndroid Build Coastguard Worker             },
378*61046927SAndroid Build Coastguard Worker          },
379*61046927SAndroid Build Coastguard Worker    };
380*61046927SAndroid Build Coastguard Worker    vn_cmd_buffer_memory_barrier(cmd_handle, &dep_before, sync2);
381*61046927SAndroid Build Coastguard Worker 
382*61046927SAndroid Build Coastguard Worker    vn_CmdFillBuffer(cmd_handle, slot->buf_handle, slot->offset, 4, status);
383*61046927SAndroid Build Coastguard Worker 
384*61046927SAndroid Build Coastguard Worker    const VkDependencyInfo dep_after = {
385*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
386*61046927SAndroid Build Coastguard Worker       .dependencyFlags = 0,
387*61046927SAndroid Build Coastguard Worker       .bufferMemoryBarrierCount = 1,
388*61046927SAndroid Build Coastguard Worker       .pBufferMemoryBarriers =
389*61046927SAndroid Build Coastguard Worker          (VkBufferMemoryBarrier2[]){
390*61046927SAndroid Build Coastguard Worker             {
391*61046927SAndroid Build Coastguard Worker                .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
392*61046927SAndroid Build Coastguard Worker                .srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT,
393*61046927SAndroid Build Coastguard Worker                .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
394*61046927SAndroid Build Coastguard Worker                .dstStageMask = VK_PIPELINE_STAGE_HOST_BIT,
395*61046927SAndroid Build Coastguard Worker                .dstAccessMask =
396*61046927SAndroid Build Coastguard Worker                   VK_ACCESS_HOST_READ_BIT | VK_ACCESS_HOST_WRITE_BIT,
397*61046927SAndroid Build Coastguard Worker                .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
398*61046927SAndroid Build Coastguard Worker                .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
399*61046927SAndroid Build Coastguard Worker                .buffer = slot->buf_handle,
400*61046927SAndroid Build Coastguard Worker                .offset = slot->offset,
401*61046927SAndroid Build Coastguard Worker                .size = 4,
402*61046927SAndroid Build Coastguard Worker             },
403*61046927SAndroid Build Coastguard Worker          },
404*61046927SAndroid Build Coastguard Worker    };
405*61046927SAndroid Build Coastguard Worker    vn_cmd_buffer_memory_barrier(cmd_handle, &dep_after, sync2);
406*61046927SAndroid Build Coastguard Worker }
407*61046927SAndroid Build Coastguard Worker 
408*61046927SAndroid Build Coastguard Worker static inline void
vn_feedback_cmd_record_flush_barrier(VkCommandBuffer cmd_handle,VkBuffer buffer,VkDeviceSize offset,VkDeviceSize size)409*61046927SAndroid Build Coastguard Worker vn_feedback_cmd_record_flush_barrier(VkCommandBuffer cmd_handle,
410*61046927SAndroid Build Coastguard Worker                                      VkBuffer buffer,
411*61046927SAndroid Build Coastguard Worker                                      VkDeviceSize offset,
412*61046927SAndroid Build Coastguard Worker                                      VkDeviceSize size)
413*61046927SAndroid Build Coastguard Worker {
414*61046927SAndroid Build Coastguard Worker    const VkBufferMemoryBarrier buf_flush_barrier = {
415*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
416*61046927SAndroid Build Coastguard Worker       .pNext = NULL,
417*61046927SAndroid Build Coastguard Worker       .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
418*61046927SAndroid Build Coastguard Worker       .dstAccessMask = VK_ACCESS_HOST_READ_BIT | VK_ACCESS_HOST_WRITE_BIT,
419*61046927SAndroid Build Coastguard Worker       .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
420*61046927SAndroid Build Coastguard Worker       .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
421*61046927SAndroid Build Coastguard Worker       .buffer = buffer,
422*61046927SAndroid Build Coastguard Worker       .offset = offset,
423*61046927SAndroid Build Coastguard Worker       .size = size,
424*61046927SAndroid Build Coastguard Worker    };
425*61046927SAndroid Build Coastguard Worker    vn_CmdPipelineBarrier(cmd_handle, VK_PIPELINE_STAGE_TRANSFER_BIT,
426*61046927SAndroid Build Coastguard Worker                          VK_PIPELINE_STAGE_HOST_BIT, 0, 0, NULL, 1,
427*61046927SAndroid Build Coastguard Worker                          &buf_flush_barrier, 0, NULL);
428*61046927SAndroid Build Coastguard Worker }
429*61046927SAndroid Build Coastguard Worker 
430*61046927SAndroid Build Coastguard Worker static VkResult
vn_feedback_cmd_record(VkCommandBuffer cmd_handle,struct vn_feedback_slot * dst_slot,struct vn_feedback_slot * src_slot)431*61046927SAndroid Build Coastguard Worker vn_feedback_cmd_record(VkCommandBuffer cmd_handle,
432*61046927SAndroid Build Coastguard Worker                        struct vn_feedback_slot *dst_slot,
433*61046927SAndroid Build Coastguard Worker                        struct vn_feedback_slot *src_slot)
434*61046927SAndroid Build Coastguard Worker {
435*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(sizeof(*dst_slot->status) == 4);
436*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(sizeof(*dst_slot->counter) == 8);
437*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(sizeof(*src_slot->counter) == 8);
438*61046927SAndroid Build Coastguard Worker 
439*61046927SAndroid Build Coastguard Worker    /* slot size is 8 bytes for timeline semaphore and 4 bytes fence.
440*61046927SAndroid Build Coastguard Worker     * src slot is non-null for timeline semaphore.
441*61046927SAndroid Build Coastguard Worker     */
442*61046927SAndroid Build Coastguard Worker    const VkDeviceSize buf_size = src_slot ? 8 : 4;
443*61046927SAndroid Build Coastguard Worker 
444*61046927SAndroid Build Coastguard Worker    static const VkCommandBufferBeginInfo begin_info = {
445*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
446*61046927SAndroid Build Coastguard Worker       .pNext = NULL,
447*61046927SAndroid Build Coastguard Worker       .flags = 0,
448*61046927SAndroid Build Coastguard Worker       .pInheritanceInfo = NULL,
449*61046927SAndroid Build Coastguard Worker    };
450*61046927SAndroid Build Coastguard Worker    VkResult result = vn_BeginCommandBuffer(cmd_handle, &begin_info);
451*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
452*61046927SAndroid Build Coastguard Worker       return result;
453*61046927SAndroid Build Coastguard Worker 
454*61046927SAndroid Build Coastguard Worker    static const VkMemoryBarrier mem_barrier_before = {
455*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER,
456*61046927SAndroid Build Coastguard Worker       .pNext = NULL,
457*61046927SAndroid Build Coastguard Worker       /* make pending writes available to stay close to signal op */
458*61046927SAndroid Build Coastguard Worker       .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
459*61046927SAndroid Build Coastguard Worker       /* no need to make all memory visible for feedback update */
460*61046927SAndroid Build Coastguard Worker       .dstAccessMask = 0,
461*61046927SAndroid Build Coastguard Worker    };
462*61046927SAndroid Build Coastguard Worker 
463*61046927SAndroid Build Coastguard Worker    const VkBufferMemoryBarrier buf_barrier_before = {
464*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
465*61046927SAndroid Build Coastguard Worker       .pNext = NULL,
466*61046927SAndroid Build Coastguard Worker       /* slot memory has been made available via mem_barrier_before */
467*61046927SAndroid Build Coastguard Worker       .srcAccessMask = 0,
468*61046927SAndroid Build Coastguard Worker       .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
469*61046927SAndroid Build Coastguard Worker       .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
470*61046927SAndroid Build Coastguard Worker       .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
471*61046927SAndroid Build Coastguard Worker       .buffer = dst_slot->buf_handle,
472*61046927SAndroid Build Coastguard Worker       .offset = dst_slot->offset,
473*61046927SAndroid Build Coastguard Worker       .size = buf_size,
474*61046927SAndroid Build Coastguard Worker    };
475*61046927SAndroid Build Coastguard Worker 
476*61046927SAndroid Build Coastguard Worker    /* host writes for src_slots should implicitly be made visible upon
477*61046927SAndroid Build Coastguard Worker     * QueueSubmit call */
478*61046927SAndroid Build Coastguard Worker    vn_CmdPipelineBarrier(cmd_handle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
479*61046927SAndroid Build Coastguard Worker                          VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 1,
480*61046927SAndroid Build Coastguard Worker                          &mem_barrier_before, 1, &buf_barrier_before, 0,
481*61046927SAndroid Build Coastguard Worker                          NULL);
482*61046927SAndroid Build Coastguard Worker 
483*61046927SAndroid Build Coastguard Worker    /* If passed a src_slot, timeline semaphore feedback records a
484*61046927SAndroid Build Coastguard Worker     * cmd to copy the counter value from the src slot to the dst slot.
485*61046927SAndroid Build Coastguard Worker     * If src_slot is NULL, then fence feedback records a cmd to fill
486*61046927SAndroid Build Coastguard Worker     * the dst slot with VK_SUCCESS.
487*61046927SAndroid Build Coastguard Worker     */
488*61046927SAndroid Build Coastguard Worker    if (src_slot) {
489*61046927SAndroid Build Coastguard Worker       assert(src_slot->type == VN_FEEDBACK_TYPE_SEMAPHORE);
490*61046927SAndroid Build Coastguard Worker       assert(dst_slot->type == VN_FEEDBACK_TYPE_SEMAPHORE);
491*61046927SAndroid Build Coastguard Worker 
492*61046927SAndroid Build Coastguard Worker       const VkBufferCopy buffer_copy = {
493*61046927SAndroid Build Coastguard Worker          .srcOffset = src_slot->offset,
494*61046927SAndroid Build Coastguard Worker          .dstOffset = dst_slot->offset,
495*61046927SAndroid Build Coastguard Worker          .size = buf_size,
496*61046927SAndroid Build Coastguard Worker       };
497*61046927SAndroid Build Coastguard Worker       vn_CmdCopyBuffer(cmd_handle, src_slot->buf_handle, dst_slot->buf_handle,
498*61046927SAndroid Build Coastguard Worker                        1, &buffer_copy);
499*61046927SAndroid Build Coastguard Worker    } else {
500*61046927SAndroid Build Coastguard Worker       assert(dst_slot->type == VN_FEEDBACK_TYPE_FENCE);
501*61046927SAndroid Build Coastguard Worker 
502*61046927SAndroid Build Coastguard Worker       vn_CmdFillBuffer(cmd_handle, dst_slot->buf_handle, dst_slot->offset,
503*61046927SAndroid Build Coastguard Worker                        buf_size, VK_SUCCESS);
504*61046927SAndroid Build Coastguard Worker    }
505*61046927SAndroid Build Coastguard Worker 
506*61046927SAndroid Build Coastguard Worker    vn_feedback_cmd_record_flush_barrier(cmd_handle, dst_slot->buf_handle,
507*61046927SAndroid Build Coastguard Worker                                         dst_slot->offset, buf_size);
508*61046927SAndroid Build Coastguard Worker 
509*61046927SAndroid Build Coastguard Worker    return vn_EndCommandBuffer(cmd_handle);
510*61046927SAndroid Build Coastguard Worker }
511*61046927SAndroid Build Coastguard Worker 
512*61046927SAndroid Build Coastguard Worker struct vn_semaphore_feedback_cmd *
vn_semaphore_feedback_cmd_alloc(struct vn_device * dev,struct vn_feedback_slot * dst_slot)513*61046927SAndroid Build Coastguard Worker vn_semaphore_feedback_cmd_alloc(struct vn_device *dev,
514*61046927SAndroid Build Coastguard Worker                                 struct vn_feedback_slot *dst_slot)
515*61046927SAndroid Build Coastguard Worker {
516*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
517*61046927SAndroid Build Coastguard Worker    struct vn_semaphore_feedback_cmd *sfb_cmd;
518*61046927SAndroid Build Coastguard Worker    VkCommandBuffer *cmd_handles;
519*61046927SAndroid Build Coastguard Worker 
520*61046927SAndroid Build Coastguard Worker    VK_MULTIALLOC(ma);
521*61046927SAndroid Build Coastguard Worker    vk_multialloc_add(&ma, &sfb_cmd, __typeof__(*sfb_cmd), 1);
522*61046927SAndroid Build Coastguard Worker    vk_multialloc_add(&ma, &cmd_handles, __typeof__(*cmd_handles),
523*61046927SAndroid Build Coastguard Worker                      dev->queue_family_count);
524*61046927SAndroid Build Coastguard Worker    if (!vk_multialloc_zalloc(&ma, alloc, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
525*61046927SAndroid Build Coastguard Worker       return NULL;
526*61046927SAndroid Build Coastguard Worker 
527*61046927SAndroid Build Coastguard Worker    struct vn_feedback_slot *src_slot =
528*61046927SAndroid Build Coastguard Worker       vn_feedback_pool_alloc(&dev->feedback_pool, VN_FEEDBACK_TYPE_SEMAPHORE);
529*61046927SAndroid Build Coastguard Worker    if (!src_slot) {
530*61046927SAndroid Build Coastguard Worker       vk_free(alloc, sfb_cmd);
531*61046927SAndroid Build Coastguard Worker       return NULL;
532*61046927SAndroid Build Coastguard Worker    }
533*61046927SAndroid Build Coastguard Worker 
534*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < dev->queue_family_count; i++) {
535*61046927SAndroid Build Coastguard Worker       VkDevice dev_handle = vn_device_to_handle(dev);
536*61046927SAndroid Build Coastguard Worker       VkResult result =
537*61046927SAndroid Build Coastguard Worker          vn_feedback_cmd_alloc(dev_handle, &dev->fb_cmd_pools[i], dst_slot,
538*61046927SAndroid Build Coastguard Worker                                src_slot, &cmd_handles[i]);
539*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
540*61046927SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < i; j++) {
541*61046927SAndroid Build Coastguard Worker             vn_feedback_cmd_free(dev_handle, &dev->fb_cmd_pools[j],
542*61046927SAndroid Build Coastguard Worker                                  cmd_handles[j]);
543*61046927SAndroid Build Coastguard Worker          }
544*61046927SAndroid Build Coastguard Worker 
545*61046927SAndroid Build Coastguard Worker          vn_feedback_pool_free(&dev->feedback_pool, src_slot);
546*61046927SAndroid Build Coastguard Worker          vk_free(alloc, sfb_cmd);
547*61046927SAndroid Build Coastguard Worker          return NULL;
548*61046927SAndroid Build Coastguard Worker       }
549*61046927SAndroid Build Coastguard Worker    }
550*61046927SAndroid Build Coastguard Worker 
551*61046927SAndroid Build Coastguard Worker    sfb_cmd->cmd_handles = cmd_handles;
552*61046927SAndroid Build Coastguard Worker    sfb_cmd->src_slot = src_slot;
553*61046927SAndroid Build Coastguard Worker    return sfb_cmd;
554*61046927SAndroid Build Coastguard Worker }
555*61046927SAndroid Build Coastguard Worker 
556*61046927SAndroid Build Coastguard Worker void
vn_semaphore_feedback_cmd_free(struct vn_device * dev,struct vn_semaphore_feedback_cmd * sfb_cmd)557*61046927SAndroid Build Coastguard Worker vn_semaphore_feedback_cmd_free(struct vn_device *dev,
558*61046927SAndroid Build Coastguard Worker                                struct vn_semaphore_feedback_cmd *sfb_cmd)
559*61046927SAndroid Build Coastguard Worker {
560*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
561*61046927SAndroid Build Coastguard Worker 
562*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < dev->queue_family_count; i++) {
563*61046927SAndroid Build Coastguard Worker       vn_feedback_cmd_free(vn_device_to_handle(dev), &dev->fb_cmd_pools[i],
564*61046927SAndroid Build Coastguard Worker                            sfb_cmd->cmd_handles[i]);
565*61046927SAndroid Build Coastguard Worker    }
566*61046927SAndroid Build Coastguard Worker 
567*61046927SAndroid Build Coastguard Worker    vn_feedback_pool_free(&dev->feedback_pool, sfb_cmd->src_slot);
568*61046927SAndroid Build Coastguard Worker    vk_free(alloc, sfb_cmd);
569*61046927SAndroid Build Coastguard Worker }
570*61046927SAndroid Build Coastguard Worker 
571*61046927SAndroid Build Coastguard Worker static void
vn_query_feedback_cmd_record_internal(VkCommandBuffer cmd_handle,VkQueryPool pool_handle,uint32_t query,uint32_t count,bool copy)572*61046927SAndroid Build Coastguard Worker vn_query_feedback_cmd_record_internal(VkCommandBuffer cmd_handle,
573*61046927SAndroid Build Coastguard Worker                                       VkQueryPool pool_handle,
574*61046927SAndroid Build Coastguard Worker                                       uint32_t query,
575*61046927SAndroid Build Coastguard Worker                                       uint32_t count,
576*61046927SAndroid Build Coastguard Worker                                       bool copy)
577*61046927SAndroid Build Coastguard Worker {
578*61046927SAndroid Build Coastguard Worker    struct vn_query_pool *pool = vn_query_pool_from_handle(pool_handle);
579*61046927SAndroid Build Coastguard Worker    assert(pool->fb_buf);
580*61046927SAndroid Build Coastguard Worker 
581*61046927SAndroid Build Coastguard Worker    /* Results are always 64 bit and include availability bit (also 64 bit) */
582*61046927SAndroid Build Coastguard Worker    const VkDeviceSize slot_size = (pool->result_array_size * 8) + 8;
583*61046927SAndroid Build Coastguard Worker    const VkDeviceSize offset = slot_size * query;
584*61046927SAndroid Build Coastguard Worker    const VkDeviceSize buf_size = slot_size * count;
585*61046927SAndroid Build Coastguard Worker 
586*61046927SAndroid Build Coastguard Worker    /* The first synchronization scope of vkCmdCopyQueryPoolResults does not
587*61046927SAndroid Build Coastguard Worker     * include the query feedback buffer. Insert a barrier to ensure ordering
588*61046927SAndroid Build Coastguard Worker     * against feedback buffer fill cmd injected in vkCmdResetQueryPool.
589*61046927SAndroid Build Coastguard Worker     *
590*61046927SAndroid Build Coastguard Worker     * The second synchronization scope of vkCmdResetQueryPool does not include
591*61046927SAndroid Build Coastguard Worker     * the query feedback buffer. Insert a barrer to ensure ordering against
592*61046927SAndroid Build Coastguard Worker     * prior cmds referencing the queries.
593*61046927SAndroid Build Coastguard Worker     *
594*61046927SAndroid Build Coastguard Worker     * For srcAccessMask, VK_ACCESS_TRANSFER_WRITE_BIT is sufficient since the
595*61046927SAndroid Build Coastguard Worker     * gpu cache invalidation for feedback buffer fill in vkResetQueryPool is
596*61046927SAndroid Build Coastguard Worker     * done implicitly via queue submission.
597*61046927SAndroid Build Coastguard Worker     */
598*61046927SAndroid Build Coastguard Worker    const VkPipelineStageFlags src_stage_mask =
599*61046927SAndroid Build Coastguard Worker       copy ? VK_PIPELINE_STAGE_TRANSFER_BIT
600*61046927SAndroid Build Coastguard Worker            : VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
601*61046927SAndroid Build Coastguard Worker 
602*61046927SAndroid Build Coastguard Worker    const VkBufferMemoryBarrier buf_barrier_before = {
603*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
604*61046927SAndroid Build Coastguard Worker       .pNext = NULL,
605*61046927SAndroid Build Coastguard Worker       .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
606*61046927SAndroid Build Coastguard Worker       .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
607*61046927SAndroid Build Coastguard Worker       .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
608*61046927SAndroid Build Coastguard Worker       .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
609*61046927SAndroid Build Coastguard Worker       .buffer = pool->fb_buf->buf_handle,
610*61046927SAndroid Build Coastguard Worker       .offset = offset,
611*61046927SAndroid Build Coastguard Worker       .size = buf_size,
612*61046927SAndroid Build Coastguard Worker    };
613*61046927SAndroid Build Coastguard Worker    vn_CmdPipelineBarrier(cmd_handle, src_stage_mask,
614*61046927SAndroid Build Coastguard Worker                          VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1,
615*61046927SAndroid Build Coastguard Worker                          &buf_barrier_before, 0, NULL);
616*61046927SAndroid Build Coastguard Worker 
617*61046927SAndroid Build Coastguard Worker    if (copy) {
618*61046927SAndroid Build Coastguard Worker       /* Per spec: "The first synchronization scope includes all commands
619*61046927SAndroid Build Coastguard Worker        * which reference the queries in queryPool indicated by query that
620*61046927SAndroid Build Coastguard Worker        * occur earlier in submission order. If flags does not include
621*61046927SAndroid Build Coastguard Worker        * VK_QUERY_RESULT_WAIT_BIT, vkCmdEndQueryIndexedEXT,
622*61046927SAndroid Build Coastguard Worker        * vkCmdWriteTimestamp2, vkCmdEndQuery, and vkCmdWriteTimestamp are
623*61046927SAndroid Build Coastguard Worker        * excluded from this scope."
624*61046927SAndroid Build Coastguard Worker        *
625*61046927SAndroid Build Coastguard Worker        * Set VK_QUERY_RESULT_WAIT_BIT to ensure ordering after
626*61046927SAndroid Build Coastguard Worker        * vkCmdEndQuery or vkCmdWriteTimestamp makes the query available.
627*61046927SAndroid Build Coastguard Worker        *
628*61046927SAndroid Build Coastguard Worker        * Set VK_QUERY_RESULT_64_BIT as we can convert it to 32 bit if app
629*61046927SAndroid Build Coastguard Worker        * requested that.
630*61046927SAndroid Build Coastguard Worker        *
631*61046927SAndroid Build Coastguard Worker        * Per spec: "vkCmdCopyQueryPoolResults is considered to be a transfer
632*61046927SAndroid Build Coastguard Worker        * operation, and its writes to buffer memory must be synchronized using
633*61046927SAndroid Build Coastguard Worker        * VK_PIPELINE_STAGE_TRANSFER_BIT and VK_ACCESS_TRANSFER_WRITE_BIT
634*61046927SAndroid Build Coastguard Worker        * before using the results."
635*61046927SAndroid Build Coastguard Worker        *
636*61046927SAndroid Build Coastguard Worker        * So we can reuse the flush barrier after this copy cmd.
637*61046927SAndroid Build Coastguard Worker        */
638*61046927SAndroid Build Coastguard Worker       vn_CmdCopyQueryPoolResults(cmd_handle, pool_handle, query, count,
639*61046927SAndroid Build Coastguard Worker                                  pool->fb_buf->buf_handle, offset, slot_size,
640*61046927SAndroid Build Coastguard Worker                                  VK_QUERY_RESULT_WITH_AVAILABILITY_BIT |
641*61046927SAndroid Build Coastguard Worker                                     VK_QUERY_RESULT_64_BIT |
642*61046927SAndroid Build Coastguard Worker                                     VK_QUERY_RESULT_WAIT_BIT);
643*61046927SAndroid Build Coastguard Worker    } else {
644*61046927SAndroid Build Coastguard Worker       vn_CmdFillBuffer(cmd_handle, pool->fb_buf->buf_handle, offset, buf_size,
645*61046927SAndroid Build Coastguard Worker                        0);
646*61046927SAndroid Build Coastguard Worker    }
647*61046927SAndroid Build Coastguard Worker 
648*61046927SAndroid Build Coastguard Worker    vn_feedback_cmd_record_flush_barrier(cmd_handle, pool->fb_buf->buf_handle,
649*61046927SAndroid Build Coastguard Worker                                         offset, buf_size);
650*61046927SAndroid Build Coastguard Worker }
651*61046927SAndroid Build Coastguard Worker 
652*61046927SAndroid Build Coastguard Worker static VkResult
vn_query_feedback_cmd_record(VkDevice dev_handle,struct list_head * query_records,struct vn_query_feedback_cmd * qfb_cmd)653*61046927SAndroid Build Coastguard Worker vn_query_feedback_cmd_record(VkDevice dev_handle,
654*61046927SAndroid Build Coastguard Worker                              struct list_head *query_records,
655*61046927SAndroid Build Coastguard Worker                              struct vn_query_feedback_cmd *qfb_cmd)
656*61046927SAndroid Build Coastguard Worker {
657*61046927SAndroid Build Coastguard Worker    assert(!list_is_empty(query_records));
658*61046927SAndroid Build Coastguard Worker 
659*61046927SAndroid Build Coastguard Worker    static const VkCommandBufferBeginInfo begin_info = {
660*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
661*61046927SAndroid Build Coastguard Worker    };
662*61046927SAndroid Build Coastguard Worker    VkResult result = vn_BeginCommandBuffer(qfb_cmd->cmd_handle, &begin_info);
663*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
664*61046927SAndroid Build Coastguard Worker       return result;
665*61046927SAndroid Build Coastguard Worker 
666*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe(struct vn_cmd_query_record, record, query_records,
667*61046927SAndroid Build Coastguard Worker                             head) {
668*61046927SAndroid Build Coastguard Worker       vn_query_feedback_cmd_record_internal(
669*61046927SAndroid Build Coastguard Worker          qfb_cmd->cmd_handle, vn_query_pool_to_handle(record->query_pool),
670*61046927SAndroid Build Coastguard Worker          record->query, record->query_count, record->copy);
671*61046927SAndroid Build Coastguard Worker    }
672*61046927SAndroid Build Coastguard Worker 
673*61046927SAndroid Build Coastguard Worker    return vn_EndCommandBuffer(qfb_cmd->cmd_handle);
674*61046927SAndroid Build Coastguard Worker }
675*61046927SAndroid Build Coastguard Worker 
676*61046927SAndroid Build Coastguard Worker VkResult
vn_query_feedback_cmd_alloc(VkDevice dev_handle,struct vn_feedback_cmd_pool * fb_cmd_pool,struct list_head * query_records,struct vn_query_feedback_cmd ** out_qfb_cmd)677*61046927SAndroid Build Coastguard Worker vn_query_feedback_cmd_alloc(VkDevice dev_handle,
678*61046927SAndroid Build Coastguard Worker                             struct vn_feedback_cmd_pool *fb_cmd_pool,
679*61046927SAndroid Build Coastguard Worker                             struct list_head *query_records,
680*61046927SAndroid Build Coastguard Worker                             struct vn_query_feedback_cmd **out_qfb_cmd)
681*61046927SAndroid Build Coastguard Worker {
682*61046927SAndroid Build Coastguard Worker    struct vn_query_feedback_cmd *qfb_cmd;
683*61046927SAndroid Build Coastguard Worker    VkResult result;
684*61046927SAndroid Build Coastguard Worker 
685*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&fb_cmd_pool->mutex);
686*61046927SAndroid Build Coastguard Worker 
687*61046927SAndroid Build Coastguard Worker    if (list_is_empty(&fb_cmd_pool->free_qfb_cmds)) {
688*61046927SAndroid Build Coastguard Worker       struct vn_command_pool *cmd_pool =
689*61046927SAndroid Build Coastguard Worker          vn_command_pool_from_handle(fb_cmd_pool->pool_handle);
690*61046927SAndroid Build Coastguard Worker 
691*61046927SAndroid Build Coastguard Worker       qfb_cmd = vk_alloc(&cmd_pool->allocator, sizeof(*qfb_cmd),
692*61046927SAndroid Build Coastguard Worker                          VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
693*61046927SAndroid Build Coastguard Worker       if (!qfb_cmd) {
694*61046927SAndroid Build Coastguard Worker          result = VK_ERROR_OUT_OF_HOST_MEMORY;
695*61046927SAndroid Build Coastguard Worker          goto out_unlock;
696*61046927SAndroid Build Coastguard Worker       }
697*61046927SAndroid Build Coastguard Worker 
698*61046927SAndroid Build Coastguard Worker       const VkCommandBufferAllocateInfo info = {
699*61046927SAndroid Build Coastguard Worker          .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
700*61046927SAndroid Build Coastguard Worker          .commandPool = fb_cmd_pool->pool_handle,
701*61046927SAndroid Build Coastguard Worker          .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
702*61046927SAndroid Build Coastguard Worker          .commandBufferCount = 1,
703*61046927SAndroid Build Coastguard Worker       };
704*61046927SAndroid Build Coastguard Worker       VkCommandBuffer qfb_cmd_handle;
705*61046927SAndroid Build Coastguard Worker       result = vn_AllocateCommandBuffers(dev_handle, &info, &qfb_cmd_handle);
706*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
707*61046927SAndroid Build Coastguard Worker          vk_free(&cmd_pool->allocator, qfb_cmd);
708*61046927SAndroid Build Coastguard Worker          goto out_unlock;
709*61046927SAndroid Build Coastguard Worker       }
710*61046927SAndroid Build Coastguard Worker 
711*61046927SAndroid Build Coastguard Worker       qfb_cmd->fb_cmd_pool = fb_cmd_pool;
712*61046927SAndroid Build Coastguard Worker       qfb_cmd->cmd_handle = qfb_cmd_handle;
713*61046927SAndroid Build Coastguard Worker    } else {
714*61046927SAndroid Build Coastguard Worker       qfb_cmd = list_first_entry(&fb_cmd_pool->free_qfb_cmds,
715*61046927SAndroid Build Coastguard Worker                                  struct vn_query_feedback_cmd, head);
716*61046927SAndroid Build Coastguard Worker       list_del(&qfb_cmd->head);
717*61046927SAndroid Build Coastguard Worker       vn_ResetCommandBuffer(qfb_cmd->cmd_handle, 0);
718*61046927SAndroid Build Coastguard Worker    }
719*61046927SAndroid Build Coastguard Worker 
720*61046927SAndroid Build Coastguard Worker    result = vn_query_feedback_cmd_record(dev_handle, query_records, qfb_cmd);
721*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
722*61046927SAndroid Build Coastguard Worker       list_add(&qfb_cmd->head, &fb_cmd_pool->free_qfb_cmds);
723*61046927SAndroid Build Coastguard Worker       goto out_unlock;
724*61046927SAndroid Build Coastguard Worker    }
725*61046927SAndroid Build Coastguard Worker 
726*61046927SAndroid Build Coastguard Worker    *out_qfb_cmd = qfb_cmd;
727*61046927SAndroid Build Coastguard Worker 
728*61046927SAndroid Build Coastguard Worker out_unlock:
729*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&fb_cmd_pool->mutex);
730*61046927SAndroid Build Coastguard Worker 
731*61046927SAndroid Build Coastguard Worker    return result;
732*61046927SAndroid Build Coastguard Worker }
733*61046927SAndroid Build Coastguard Worker 
734*61046927SAndroid Build Coastguard Worker void
vn_query_feedback_cmd_free(struct vn_query_feedback_cmd * qfb_cmd)735*61046927SAndroid Build Coastguard Worker vn_query_feedback_cmd_free(struct vn_query_feedback_cmd *qfb_cmd)
736*61046927SAndroid Build Coastguard Worker {
737*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&qfb_cmd->fb_cmd_pool->mutex);
738*61046927SAndroid Build Coastguard Worker    list_add(&qfb_cmd->head, &qfb_cmd->fb_cmd_pool->free_qfb_cmds);
739*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&qfb_cmd->fb_cmd_pool->mutex);
740*61046927SAndroid Build Coastguard Worker }
741*61046927SAndroid Build Coastguard Worker 
742*61046927SAndroid Build Coastguard Worker VkResult
vn_feedback_cmd_alloc(VkDevice dev_handle,struct vn_feedback_cmd_pool * fb_cmd_pool,struct vn_feedback_slot * dst_slot,struct vn_feedback_slot * src_slot,VkCommandBuffer * out_cmd_handle)743*61046927SAndroid Build Coastguard Worker vn_feedback_cmd_alloc(VkDevice dev_handle,
744*61046927SAndroid Build Coastguard Worker                       struct vn_feedback_cmd_pool *fb_cmd_pool,
745*61046927SAndroid Build Coastguard Worker                       struct vn_feedback_slot *dst_slot,
746*61046927SAndroid Build Coastguard Worker                       struct vn_feedback_slot *src_slot,
747*61046927SAndroid Build Coastguard Worker                       VkCommandBuffer *out_cmd_handle)
748*61046927SAndroid Build Coastguard Worker {
749*61046927SAndroid Build Coastguard Worker    VkCommandPool cmd_pool_handle = fb_cmd_pool->pool_handle;
750*61046927SAndroid Build Coastguard Worker    const VkCommandBufferAllocateInfo info = {
751*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
752*61046927SAndroid Build Coastguard Worker       .pNext = NULL,
753*61046927SAndroid Build Coastguard Worker       .commandPool = cmd_pool_handle,
754*61046927SAndroid Build Coastguard Worker       .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
755*61046927SAndroid Build Coastguard Worker       .commandBufferCount = 1,
756*61046927SAndroid Build Coastguard Worker    };
757*61046927SAndroid Build Coastguard Worker    VkCommandBuffer cmd_handle;
758*61046927SAndroid Build Coastguard Worker    VkResult result;
759*61046927SAndroid Build Coastguard Worker 
760*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&fb_cmd_pool->mutex);
761*61046927SAndroid Build Coastguard Worker    result = vn_AllocateCommandBuffers(dev_handle, &info, &cmd_handle);
762*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
763*61046927SAndroid Build Coastguard Worker       goto out_unlock;
764*61046927SAndroid Build Coastguard Worker 
765*61046927SAndroid Build Coastguard Worker    result = vn_feedback_cmd_record(cmd_handle, dst_slot, src_slot);
766*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
767*61046927SAndroid Build Coastguard Worker       vn_FreeCommandBuffers(dev_handle, cmd_pool_handle, 1, &cmd_handle);
768*61046927SAndroid Build Coastguard Worker       goto out_unlock;
769*61046927SAndroid Build Coastguard Worker    }
770*61046927SAndroid Build Coastguard Worker 
771*61046927SAndroid Build Coastguard Worker    *out_cmd_handle = cmd_handle;
772*61046927SAndroid Build Coastguard Worker 
773*61046927SAndroid Build Coastguard Worker out_unlock:
774*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&fb_cmd_pool->mutex);
775*61046927SAndroid Build Coastguard Worker 
776*61046927SAndroid Build Coastguard Worker    return result;
777*61046927SAndroid Build Coastguard Worker }
778*61046927SAndroid Build Coastguard Worker 
779*61046927SAndroid Build Coastguard Worker void
vn_feedback_cmd_free(VkDevice dev_handle,struct vn_feedback_cmd_pool * fb_cmd_pool,VkCommandBuffer cmd_handle)780*61046927SAndroid Build Coastguard Worker vn_feedback_cmd_free(VkDevice dev_handle,
781*61046927SAndroid Build Coastguard Worker                      struct vn_feedback_cmd_pool *fb_cmd_pool,
782*61046927SAndroid Build Coastguard Worker                      VkCommandBuffer cmd_handle)
783*61046927SAndroid Build Coastguard Worker {
784*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&fb_cmd_pool->mutex);
785*61046927SAndroid Build Coastguard Worker    vn_FreeCommandBuffers(dev_handle, fb_cmd_pool->pool_handle, 1,
786*61046927SAndroid Build Coastguard Worker                          &cmd_handle);
787*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&fb_cmd_pool->mutex);
788*61046927SAndroid Build Coastguard Worker }
789*61046927SAndroid Build Coastguard Worker 
790*61046927SAndroid Build Coastguard Worker VkResult
vn_feedback_cmd_pools_init(struct vn_device * dev)791*61046927SAndroid Build Coastguard Worker vn_feedback_cmd_pools_init(struct vn_device *dev)
792*61046927SAndroid Build Coastguard Worker {
793*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
794*61046927SAndroid Build Coastguard Worker    VkDevice dev_handle = vn_device_to_handle(dev);
795*61046927SAndroid Build Coastguard Worker    struct vn_feedback_cmd_pool *fb_cmd_pools;
796*61046927SAndroid Build Coastguard Worker    VkCommandPoolCreateInfo info = {
797*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
798*61046927SAndroid Build Coastguard Worker       .pNext = NULL,
799*61046927SAndroid Build Coastguard Worker       .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
800*61046927SAndroid Build Coastguard Worker    };
801*61046927SAndroid Build Coastguard Worker 
802*61046927SAndroid Build Coastguard Worker    if (VN_PERF(NO_FENCE_FEEDBACK) && VN_PERF(NO_SEMAPHORE_FEEDBACK) &&
803*61046927SAndroid Build Coastguard Worker        VN_PERF(NO_QUERY_FEEDBACK))
804*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
805*61046927SAndroid Build Coastguard Worker 
806*61046927SAndroid Build Coastguard Worker    assert(dev->queue_family_count);
807*61046927SAndroid Build Coastguard Worker 
808*61046927SAndroid Build Coastguard Worker    fb_cmd_pools =
809*61046927SAndroid Build Coastguard Worker       vk_zalloc(alloc, sizeof(*fb_cmd_pools) * dev->queue_family_count,
810*61046927SAndroid Build Coastguard Worker                 VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
811*61046927SAndroid Build Coastguard Worker    if (!fb_cmd_pools)
812*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
813*61046927SAndroid Build Coastguard Worker 
814*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < dev->queue_family_count; i++) {
815*61046927SAndroid Build Coastguard Worker       VkResult result;
816*61046927SAndroid Build Coastguard Worker 
817*61046927SAndroid Build Coastguard Worker       info.queueFamilyIndex = dev->queue_families[i];
818*61046927SAndroid Build Coastguard Worker       result = vn_CreateCommandPool(dev_handle, &info, alloc,
819*61046927SAndroid Build Coastguard Worker                                     &fb_cmd_pools[i].pool_handle);
820*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS) {
821*61046927SAndroid Build Coastguard Worker          for (uint32_t j = 0; j < i; j++) {
822*61046927SAndroid Build Coastguard Worker             vn_DestroyCommandPool(dev_handle, fb_cmd_pools[j].pool_handle,
823*61046927SAndroid Build Coastguard Worker                                   alloc);
824*61046927SAndroid Build Coastguard Worker             simple_mtx_destroy(&fb_cmd_pools[j].mutex);
825*61046927SAndroid Build Coastguard Worker          }
826*61046927SAndroid Build Coastguard Worker 
827*61046927SAndroid Build Coastguard Worker          vk_free(alloc, fb_cmd_pools);
828*61046927SAndroid Build Coastguard Worker          return result;
829*61046927SAndroid Build Coastguard Worker       }
830*61046927SAndroid Build Coastguard Worker 
831*61046927SAndroid Build Coastguard Worker       simple_mtx_init(&fb_cmd_pools[i].mutex, mtx_plain);
832*61046927SAndroid Build Coastguard Worker       list_inithead(&fb_cmd_pools[i].free_qfb_cmds);
833*61046927SAndroid Build Coastguard Worker    }
834*61046927SAndroid Build Coastguard Worker 
835*61046927SAndroid Build Coastguard Worker    dev->fb_cmd_pools = fb_cmd_pools;
836*61046927SAndroid Build Coastguard Worker 
837*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
838*61046927SAndroid Build Coastguard Worker }
839*61046927SAndroid Build Coastguard Worker 
840*61046927SAndroid Build Coastguard Worker void
vn_feedback_cmd_pools_fini(struct vn_device * dev)841*61046927SAndroid Build Coastguard Worker vn_feedback_cmd_pools_fini(struct vn_device *dev)
842*61046927SAndroid Build Coastguard Worker {
843*61046927SAndroid Build Coastguard Worker    const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
844*61046927SAndroid Build Coastguard Worker    VkDevice dev_handle = vn_device_to_handle(dev);
845*61046927SAndroid Build Coastguard Worker 
846*61046927SAndroid Build Coastguard Worker    if (!dev->fb_cmd_pools)
847*61046927SAndroid Build Coastguard Worker       return;
848*61046927SAndroid Build Coastguard Worker 
849*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < dev->queue_family_count; i++) {
850*61046927SAndroid Build Coastguard Worker       list_for_each_entry_safe(struct vn_query_feedback_cmd, feedback_cmd,
851*61046927SAndroid Build Coastguard Worker                                &dev->fb_cmd_pools[i].free_qfb_cmds, head)
852*61046927SAndroid Build Coastguard Worker          vk_free(alloc, feedback_cmd);
853*61046927SAndroid Build Coastguard Worker 
854*61046927SAndroid Build Coastguard Worker       vn_DestroyCommandPool(dev_handle, dev->fb_cmd_pools[i].pool_handle,
855*61046927SAndroid Build Coastguard Worker                             alloc);
856*61046927SAndroid Build Coastguard Worker       simple_mtx_destroy(&dev->fb_cmd_pools[i].mutex);
857*61046927SAndroid Build Coastguard Worker    }
858*61046927SAndroid Build Coastguard Worker 
859*61046927SAndroid Build Coastguard Worker    vk_free(alloc, dev->fb_cmd_pools);
860*61046927SAndroid Build Coastguard Worker }
861