xref: /aosp_15_r20/external/mesa3d/src/virtio/vulkan/vn_renderer_util.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2021 Google LLC
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "vn_renderer_util.h"
7 
8 void
vn_renderer_shmem_pool_init(UNUSED struct vn_renderer * renderer,struct vn_renderer_shmem_pool * pool,size_t min_alloc_size)9 vn_renderer_shmem_pool_init(UNUSED struct vn_renderer *renderer,
10                             struct vn_renderer_shmem_pool *pool,
11                             size_t min_alloc_size)
12 {
13    *pool = (struct vn_renderer_shmem_pool){
14       /* power-of-two to hit shmem cache */
15       .min_alloc_size = util_next_power_of_two(min_alloc_size),
16    };
17    mtx_init(&pool->mutex, mtx_plain);
18 }
19 
20 void
vn_renderer_shmem_pool_fini(struct vn_renderer * renderer,struct vn_renderer_shmem_pool * pool)21 vn_renderer_shmem_pool_fini(struct vn_renderer *renderer,
22                             struct vn_renderer_shmem_pool *pool)
23 {
24    if (pool->shmem)
25       vn_renderer_shmem_unref(renderer, pool->shmem);
26    mtx_destroy(&pool->mutex);
27 }
28 
29 static bool
vn_renderer_shmem_pool_grow_locked(struct vn_renderer * renderer,struct vn_renderer_shmem_pool * pool,size_t size)30 vn_renderer_shmem_pool_grow_locked(struct vn_renderer *renderer,
31                                    struct vn_renderer_shmem_pool *pool,
32                                    size_t size)
33 {
34    VN_TRACE_FUNC();
35    /* power-of-two to hit shmem cache */
36    size_t alloc_size = pool->min_alloc_size;
37    while (alloc_size < size) {
38       alloc_size <<= 1;
39       if (!alloc_size)
40          return false;
41    }
42 
43    struct vn_renderer_shmem *shmem =
44       vn_renderer_shmem_create(renderer, alloc_size);
45    if (!shmem)
46       return false;
47 
48    if (pool->shmem)
49       vn_renderer_shmem_unref(renderer, pool->shmem);
50 
51    pool->shmem = shmem;
52    pool->size = alloc_size;
53    pool->used = 0;
54 
55    return true;
56 }
57 
58 struct vn_renderer_shmem *
vn_renderer_shmem_pool_alloc(struct vn_renderer * renderer,struct vn_renderer_shmem_pool * pool,size_t size,size_t * out_offset)59 vn_renderer_shmem_pool_alloc(struct vn_renderer *renderer,
60                              struct vn_renderer_shmem_pool *pool,
61                              size_t size,
62                              size_t *out_offset)
63 {
64    mtx_lock(&pool->mutex);
65    if (unlikely(size > pool->size - pool->used)) {
66       if (!vn_renderer_shmem_pool_grow_locked(renderer, pool, size)) {
67          mtx_unlock(&pool->mutex);
68          return NULL;
69       }
70 
71       assert(size <= pool->size - pool->used);
72    }
73 
74    struct vn_renderer_shmem *shmem =
75       vn_renderer_shmem_ref(renderer, pool->shmem);
76    *out_offset = pool->used;
77    pool->used += size;
78    mtx_unlock(&pool->mutex);
79 
80    return shmem;
81 }
82