xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/zink/zink_screen.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2018 Collabora Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the Software is 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifndef ZINK_SCREEN_H
25 #define ZINK_SCREEN_H
26 
27 #include "zink_types.h"
28 
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 struct util_dl_library;
35 
36 void
37 zink_init_screen_pipeline_libs(struct zink_screen *screen);
38 
39 
40 /* update last_finished to account for batch_id wrapping */
41 static inline void
zink_screen_update_last_finished(struct zink_screen * screen,uint64_t batch_id)42 zink_screen_update_last_finished(struct zink_screen *screen, uint64_t batch_id)
43 {
44    const uint32_t check_id = (uint32_t)batch_id;
45    /* last_finished may have wrapped */
46    if (screen->last_finished < UINT_MAX / 2) {
47       /* last_finished has wrapped, batch_id has not */
48       if (check_id > UINT_MAX / 2)
49          return;
50    } else if (check_id < UINT_MAX / 2) {
51       /* batch_id has wrapped, last_finished has not */
52       screen->last_finished = check_id;
53       return;
54    }
55    /* neither have wrapped */
56    screen->last_finished = MAX2(check_id, screen->last_finished);
57 }
58 
59 /* check a batch_id against last_finished while accounting for wrapping */
60 static inline bool
zink_screen_check_last_finished(struct zink_screen * screen,uint32_t batch_id)61 zink_screen_check_last_finished(struct zink_screen *screen, uint32_t batch_id)
62 {
63    const uint32_t check_id = (uint32_t)batch_id;
64    assert(check_id);
65    /* last_finished may have wrapped */
66    if (screen->last_finished < UINT_MAX / 2) {
67       /* last_finished has wrapped, batch_id has not */
68       if (check_id > UINT_MAX / 2)
69          return true;
70    } else if (check_id < UINT_MAX / 2) {
71       /* batch_id has wrapped, last_finished has not */
72       return false;
73    }
74    return screen->last_finished >= check_id;
75 }
76 
77 bool
78 zink_screen_init_semaphore(struct zink_screen *screen);
79 
80 static inline bool
zink_screen_handle_vkresult(struct zink_screen * screen,VkResult ret)81 zink_screen_handle_vkresult(struct zink_screen *screen, VkResult ret)
82 {
83    bool success = false;
84    switch (ret) {
85    case VK_SUCCESS:
86       success = true;
87       break;
88    case VK_ERROR_DEVICE_LOST:
89       screen->device_lost = true;
90       mesa_loge("zink: DEVICE LOST!\n");
91       /* if nothing can save us, abort */
92       if (screen->abort_on_hang && !screen->robust_ctx_count)
93          abort();
94       FALLTHROUGH;
95    default:
96       success = false;
97       break;
98    }
99    return success;
100 }
101 
102 typedef const char *(*zink_vkflags_func)(uint64_t);
103 
104 static inline unsigned
zink_string_vkflags_unroll(char * buf,size_t bufsize,uint64_t flags,zink_vkflags_func func)105 zink_string_vkflags_unroll(char *buf, size_t bufsize, uint64_t flags, zink_vkflags_func func)
106 {
107    bool first = true;
108    unsigned idx = 0;
109    u_foreach_bit64(bit, flags) {
110       if (!first)
111          buf[idx++] = '|';
112       idx += snprintf(&buf[idx], bufsize - idx, "%s", func((BITFIELD64_BIT(bit))));
113       first = false;
114    }
115    return idx;
116 }
117 
118 #define VRAM_ALLOC_LOOP(RET, DOIT, ...) \
119    do { \
120       unsigned _us[] = {0, 1000, 10000, 500000, 1000000}; \
121       for (unsigned _i = 0; _i < ARRAY_SIZE(_us); _i++) { \
122          RET = DOIT; \
123          if (RET == VK_SUCCESS || RET != VK_ERROR_OUT_OF_DEVICE_MEMORY) \
124             break; \
125          os_time_sleep(_us[_i]); \
126       } \
127       __VA_ARGS__ \
128    } while (0)
129 
130 VkSemaphore
131 zink_create_semaphore(struct zink_screen *screen);
132 
133 static inline VkDriverId
zink_driverid(const struct zink_screen * screen)134 zink_driverid(const struct zink_screen *screen)
135 {
136    if (!screen->info.have_KHR_maintenance7 || screen->info.layered_props.layeredAPI != VK_PHYSICAL_DEVICE_LAYERED_API_VULKAN_KHR)
137       return screen->info.driver_props.driverID;
138    /* if maint7 is supported, codegen ensures this will always be the "right" value */
139    return screen->info.vk_layered_driver_props.driverID;
140 }
141 
142 void
143 zink_screen_lock_context(struct zink_screen *screen);
144 void
145 zink_screen_unlock_context(struct zink_screen *screen);
146 
147 VkSemaphore
148 zink_create_exportable_semaphore(struct zink_screen *screen);
149 VkSemaphore
150 zink_screen_export_dmabuf_semaphore(struct zink_screen *screen, struct zink_resource *res);
151 bool
152 zink_screen_import_dmabuf_semaphore(struct zink_screen *screen, struct zink_resource *res, VkSemaphore sem);
153 
154 VkFormat
155 zink_get_format(struct zink_screen *screen, enum pipe_format format);
156 
157 void
158 zink_convert_color(const struct zink_screen *screen, enum pipe_format format,
159                    union pipe_color_union *dst,
160                    const union pipe_color_union *src);
161 
162 bool
163 zink_screen_timeline_wait(struct zink_screen *screen, uint64_t batch_id, uint64_t timeout);
164 
165 bool
166 zink_is_depth_format_supported(struct zink_screen *screen, VkFormat format);
167 
168 #define GET_PROC_ADDR_INSTANCE_LOCAL(screen, instance, x) PFN_vk##x vk_##x = (PFN_vk##x)(screen)->vk_GetInstanceProcAddr(instance, "vk"#x)
169 
170 void
171 zink_screen_update_pipeline_cache(struct zink_screen *screen, struct zink_program *pg, bool in_thread);
172 
173 void
174 zink_screen_get_pipeline_cache(struct zink_screen *screen, struct zink_program *pg, bool in_thread);
175 
176 void VKAPI_PTR
177 zink_stub_function_not_loaded(void);
178 
179 bool
180 zink_screen_debug_marker_begin(struct zink_screen *screen, const char *fmt, ...);
181 void
182 zink_screen_debug_marker_end(struct zink_screen *screen, bool emitted);
183 
184 #define warn_missing_feature(warned, feat) \
185    do { \
186       if (!warned) { \
187          if (!(zink_debug & ZINK_DEBUG_QUIET)) \
188             mesa_logw("WARNING: Incorrect rendering will happen " \
189                            "because the Vulkan device doesn't support " \
190                            "the '%s' feature\n", feat); \
191          warned = true; \
192       } \
193    } while (0)
194 
195 #ifdef __cplusplus
196 }
197 #endif
198 
199 #endif
200