xref: /aosp_15_r20/external/mesa3d/src/imagination/vulkan/winsys/pvrsrvkm/pvr_srv_sync_prim.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2023 Imagination Technologies Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #include <stddef.h>
25 #include <stdint.h>
26 #include <vulkan/vulkan_core.h>
27 
28 #include "pvr_srv.h"
29 #include "pvr_srv_bridge.h"
30 #include "pvr_srv_sync_prim.h"
31 #include "util/log.h"
32 #include "util/simple_mtx.h"
33 #include "util/u_atomic.h"
34 #include "util/u_idalloc.h"
35 #include "vk_alloc.h"
36 #include "vk_log.h"
37 
38 /* Amount of space used to hold sync prim values (in bytes). */
39 #define PVR_SRV_SYNC_PRIM_VALUE_SIZE 4
40 
pvr_srv_sync_prim_block_init(struct pvr_srv_winsys * srv_ws)41 VkResult pvr_srv_sync_prim_block_init(struct pvr_srv_winsys *srv_ws)
42 {
43    /* We don't currently make use of this value, but we're required to provide
44     * a valid pointer to pvr_srv_alloc_sync_primitive_block.
45     */
46    void *sync_block_pmr;
47    uint32_t max_size;
48    VkResult result;
49 
50    result =
51       pvr_srv_alloc_sync_primitive_block(srv_ws->base.render_fd,
52                                          &srv_ws->sync_prim_ctx.block_handle,
53                                          &sync_block_pmr,
54                                          &max_size,
55                                          &srv_ws->sync_prim_ctx.block_fw_addr);
56    if (result != VK_SUCCESS)
57       return result;
58 
59    srv_ws->sync_prim_ctx.max_count = max_size / PVR_SRV_SYNC_PRIM_VALUE_SIZE;
60 
61    /* TODO: This uses ralloc() should we be using vk_alloc()? */
62    util_idalloc_mt_init(&srv_ws->sync_prim_ctx.allocator,
63                         srv_ws->sync_prim_ctx.max_count,
64                         false);
65 
66    return VK_SUCCESS;
67 }
68 
pvr_srv_sync_prim_block_finish(struct pvr_srv_winsys * srv_ws)69 void pvr_srv_sync_prim_block_finish(struct pvr_srv_winsys *srv_ws)
70 {
71    util_idalloc_mt_fini(&srv_ws->sync_prim_ctx.allocator);
72    pvr_srv_free_sync_primitive_block(srv_ws->base.render_fd,
73                                      srv_ws->sync_prim_ctx.block_handle);
74    srv_ws->sync_prim_ctx.block_handle = NULL;
75 }
76 
pvr_srv_sync_prim_alloc(struct pvr_srv_winsys * srv_ws)77 struct pvr_srv_sync_prim *pvr_srv_sync_prim_alloc(struct pvr_srv_winsys *srv_ws)
78 {
79    struct pvr_srv_sync_prim_ctx *ctx = &srv_ws->sync_prim_ctx;
80    struct pvr_srv_sync_prim *sync_prim;
81    unsigned id;
82 
83    sync_prim = vk_alloc(srv_ws->base.alloc,
84                         sizeof(*sync_prim),
85                         8,
86                         VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
87    if (!sync_prim) {
88       vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
89       return NULL;
90    }
91 
92    simple_mtx_lock(&srv_ws->sync_prim_ctx.allocator.mutex);
93 
94    id = util_idalloc_alloc(&srv_ws->sync_prim_ctx.allocator.buf);
95    if (id >= ctx->max_count) {
96       /* FIXME: The last alloc expanded the idalloc. Assuming that the app can
97        * recover, we'll end up having memory that we'll never use.
98        */
99 
100       util_idalloc_free(&srv_ws->sync_prim_ctx.allocator.buf, id);
101       simple_mtx_unlock(&srv_ws->sync_prim_ctx.allocator.mutex);
102       vk_free(srv_ws->base.alloc, sync_prim);
103 
104       vk_errorf(NULL,
105                 VK_ERROR_OUT_OF_DEVICE_MEMORY,
106                 "Out of sync prim block space.");
107 
108       return NULL;
109    }
110 
111    simple_mtx_unlock(&srv_ws->sync_prim_ctx.allocator.mutex);
112 
113    sync_prim->offset = id * PVR_SRV_SYNC_PRIM_VALUE_SIZE;
114    sync_prim->ctx = &srv_ws->sync_prim_ctx;
115    sync_prim->value = 0;
116 
117    return sync_prim;
118 }
119 
120 /* FIXME: Add support for freeing offsets back to the sync block. */
pvr_srv_sync_prim_free(struct pvr_srv_winsys * srv_ws,struct pvr_srv_sync_prim * sync_prim)121 void pvr_srv_sync_prim_free(struct pvr_srv_winsys *srv_ws,
122                             struct pvr_srv_sync_prim *sync_prim)
123 {
124    if (sync_prim) {
125       const uint32_t id = sync_prim->offset / PVR_SRV_SYNC_PRIM_VALUE_SIZE;
126       VkResult result;
127 
128       result = pvr_srv_set_sync_primitive(srv_ws->base.render_fd,
129                                           srv_ws->sync_prim_ctx.block_handle,
130                                           id,
131                                           0);
132       if (result != VK_SUCCESS) {
133          /* Let's keep the id allocated so no one else ends up using it. Using a
134           * non zeroed out sync prim will crash things.
135           */
136 
137          mesa_logw("Failed to free sync prim. "
138                    "Some sync prim block space will be lost.");
139 
140          vk_free(srv_ws->base.alloc, sync_prim);
141          return;
142       }
143 
144       util_idalloc_mt_free(&srv_ws->sync_prim_ctx.allocator, id);
145 
146       vk_free(srv_ws->base.alloc, sync_prim);
147    }
148 }
149