• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 Google LLC
3  * SPDX-License-Identifier: MIT
4  *
5  * based in part on anv and radv which are:
6  * Copyright © 2015 Intel Corporation
7  * Copyright © 2016 Red Hat.
8  * Copyright © 2016 Bas Nieuwenhuizen
9  */
10 
11 #ifndef VN_COMMON_H
12 #define VN_COMMON_H
13 
14 #include <assert.h>
15 #include <inttypes.h>
16 #include <limits.h>
17 #include <stdatomic.h>
18 #include <stdbool.h>
19 #include <stddef.h>
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <vulkan/vulkan.h>
24 
25 #include "c11/threads.h"
26 #include "util/bitscan.h"
27 #include "util/bitset.h"
28 #include "util/compiler.h"
29 #include "util/list.h"
30 #include "util/macros.h"
31 #include "util/os_time.h"
32 #include "util/simple_mtx.h"
33 #include "util/u_math.h"
34 #include "util/xmlconfig.h"
35 #include "vk_alloc.h"
36 #include "vk_debug_report.h"
37 #include "vk_device.h"
38 #include "vk_instance.h"
39 #include "vk_object.h"
40 #include "vk_physical_device.h"
41 #include "vk_util.h"
42 
43 #include "vn_entrypoints.h"
44 
45 #define VN_DEFAULT_ALIGN 8
46 
47 #define VN_DEBUG(category) (unlikely(vn_env.debug & VN_DEBUG_##category))
48 #define VN_PERF(category) (unlikely(vn_env.perf & VN_PERF_##category))
49 
50 #define vn_error(instance, error)                                            \
51    (VN_DEBUG(RESULT) ? vn_log_result((instance), (error), __func__) : (error))
52 #define vn_result(instance, result)                                          \
53    ((result) >= VK_SUCCESS ? (result) : vn_error((instance), (result)))
54 
55 #ifdef ANDROID
56 
57 #include <cutils/trace.h>
58 
59 #define VN_TRACE_BEGIN(name) atrace_begin(ATRACE_TAG_GRAPHICS, name)
60 #define VN_TRACE_END() atrace_end(ATRACE_TAG_GRAPHICS)
61 
62 #else
63 
64 /* XXX we would like to use perfetto, but it lacks a C header */
65 #define VN_TRACE_BEGIN(name)
66 #define VN_TRACE_END()
67 
68 #endif /* ANDROID */
69 
70 #if __has_attribute(cleanup) && __has_attribute(unused)
71 
72 #define VN_TRACE_SCOPE_VAR_CONCAT(name, suffix) name##suffix
73 #define VN_TRACE_SCOPE_VAR(suffix)                                           \
74    VN_TRACE_SCOPE_VAR_CONCAT(_vn_trace_scope_, suffix)
75 #define VN_TRACE_SCOPE(name)                                                 \
76    int VN_TRACE_SCOPE_VAR(__LINE__)                                          \
77       __attribute__((cleanup(vn_trace_scope_end), unused)) =                 \
78          vn_trace_scope_begin(name)
79 
80 static inline int
vn_trace_scope_begin(const char * name)81 vn_trace_scope_begin(const char *name)
82 {
83    VN_TRACE_BEGIN(name);
84    return 0;
85 }
86 
87 static inline void
vn_trace_scope_end(int * scope)88 vn_trace_scope_end(int *scope)
89 {
90    VN_TRACE_END();
91 }
92 
93 #else
94 
95 #define VN_TRACE_SCOPE(name)
96 
97 #endif /* __has_attribute(cleanup) && __has_attribute(unused) */
98 
99 #define VN_TRACE_FUNC() VN_TRACE_SCOPE(__func__)
100 
101 struct vn_instance;
102 struct vn_physical_device;
103 struct vn_device;
104 struct vn_queue;
105 struct vn_fence;
106 struct vn_semaphore;
107 struct vn_device_memory;
108 struct vn_buffer;
109 struct vn_buffer_view;
110 struct vn_image;
111 struct vn_image_view;
112 struct vn_sampler;
113 struct vn_sampler_ycbcr_conversion;
114 struct vn_descriptor_set_layout;
115 struct vn_descriptor_pool;
116 struct vn_descriptor_set;
117 struct vn_descriptor_update_template;
118 struct vn_render_pass;
119 struct vn_framebuffer;
120 struct vn_event;
121 struct vn_query_pool;
122 struct vn_shader_module;
123 struct vn_pipeline_layout;
124 struct vn_pipeline_cache;
125 struct vn_pipeline;
126 struct vn_command_pool;
127 struct vn_command_buffer;
128 
129 struct vn_cs_encoder;
130 struct vn_cs_decoder;
131 
132 struct vn_renderer;
133 struct vn_renderer_shmem;
134 struct vn_renderer_bo;
135 struct vn_renderer_sync;
136 
137 enum vn_debug {
138    VN_DEBUG_INIT = 1ull << 0,
139    VN_DEBUG_RESULT = 1ull << 1,
140    VN_DEBUG_VTEST = 1ull << 2,
141    VN_DEBUG_WSI = 1ull << 3,
142    VN_DEBUG_NO_ABORT = 1ull << 4,
143 };
144 
145 enum vn_perf {
146    VN_PERF_NO_ASYNC_SET_ALLOC = 1ull << 0,
147    VN_PERF_NO_ASYNC_BUFFER_CREATE = 1ull << 1,
148    VN_PERF_NO_ASYNC_QUEUE_SUBMIT = 1ull << 2,
149    VN_PERF_NO_EVENT_FEEDBACK = 1ull << 3,
150    VN_PERF_NO_FENCE_FEEDBACK = 1ull << 4,
151 };
152 
153 typedef uint64_t vn_object_id;
154 
155 /* base class of vn_instance */
156 struct vn_instance_base {
157    struct vk_instance base;
158    vn_object_id id;
159 };
160 
161 /* base class of vn_physical_device */
162 struct vn_physical_device_base {
163    struct vk_physical_device base;
164    vn_object_id id;
165 };
166 
167 /* base class of vn_device */
168 struct vn_device_base {
169    struct vk_device base;
170    vn_object_id id;
171 };
172 
173 /* base class of other driver objects */
174 struct vn_object_base {
175    struct vk_object_base base;
176    vn_object_id id;
177 };
178 
179 struct vn_refcount {
180    atomic_int count;
181 };
182 
183 struct vn_env {
184    uint64_t debug;
185    uint64_t perf;
186    /* zero will be overridden to UINT32_MAX as no limit */
187    uint32_t draw_cmd_batch_limit;
188    uint32_t relax_base_sleep_us;
189 };
190 extern struct vn_env vn_env;
191 
192 void
193 vn_env_init(void);
194 
195 void
196 vn_trace_init(void);
197 
198 void
199 vn_log(struct vn_instance *instance, const char *format, ...)
200    PRINTFLIKE(2, 3);
201 
202 VkResult
203 vn_log_result(struct vn_instance *instance,
204               VkResult result,
205               const char *where);
206 
207 #define VN_REFCOUNT_INIT(val)                                                \
208    (struct vn_refcount) { .count = (val) }
209 
210 static inline int
vn_refcount_load_relaxed(const struct vn_refcount * ref)211 vn_refcount_load_relaxed(const struct vn_refcount *ref)
212 {
213    return atomic_load_explicit(&ref->count, memory_order_relaxed);
214 }
215 
216 static inline int
vn_refcount_fetch_add_relaxed(struct vn_refcount * ref,int val)217 vn_refcount_fetch_add_relaxed(struct vn_refcount *ref, int val)
218 {
219    return atomic_fetch_add_explicit(&ref->count, val, memory_order_relaxed);
220 }
221 
222 static inline int
vn_refcount_fetch_sub_release(struct vn_refcount * ref,int val)223 vn_refcount_fetch_sub_release(struct vn_refcount *ref, int val)
224 {
225    return atomic_fetch_sub_explicit(&ref->count, val, memory_order_release);
226 }
227 
228 static inline bool
vn_refcount_is_valid(const struct vn_refcount * ref)229 vn_refcount_is_valid(const struct vn_refcount *ref)
230 {
231    return vn_refcount_load_relaxed(ref) > 0;
232 }
233 
234 static inline void
vn_refcount_inc(struct vn_refcount * ref)235 vn_refcount_inc(struct vn_refcount *ref)
236 {
237    /* no ordering imposed */
238    ASSERTED const int old = vn_refcount_fetch_add_relaxed(ref, 1);
239    assert(old >= 1);
240 }
241 
242 static inline bool
vn_refcount_dec(struct vn_refcount * ref)243 vn_refcount_dec(struct vn_refcount *ref)
244 {
245    /* prior reads/writes cannot be reordered after this */
246    const int old = vn_refcount_fetch_sub_release(ref, 1);
247    assert(old >= 1);
248 
249    /* subsequent free cannot be reordered before this */
250    if (old == 1)
251       atomic_thread_fence(memory_order_acquire);
252 
253    return old == 1;
254 }
255 
256 uint32_t
257 vn_extension_get_spec_version(const char *name);
258 
259 void
260 vn_relax(uint32_t *iter, const char *reason);
261 
262 static_assert(sizeof(vn_object_id) >= sizeof(uintptr_t), "");
263 
264 static inline VkResult
vn_instance_base_init(struct vn_instance_base * instance,const struct vk_instance_extension_table * supported_extensions,const struct vk_instance_dispatch_table * dispatch_table,const VkInstanceCreateInfo * info,const VkAllocationCallbacks * alloc)265 vn_instance_base_init(
266    struct vn_instance_base *instance,
267    const struct vk_instance_extension_table *supported_extensions,
268    const struct vk_instance_dispatch_table *dispatch_table,
269    const VkInstanceCreateInfo *info,
270    const VkAllocationCallbacks *alloc)
271 {
272    VkResult result = vk_instance_init(&instance->base, supported_extensions,
273                                       dispatch_table, info, alloc);
274    instance->id = (uintptr_t)instance;
275    return result;
276 }
277 
278 static inline void
vn_instance_base_fini(struct vn_instance_base * instance)279 vn_instance_base_fini(struct vn_instance_base *instance)
280 {
281    vk_instance_finish(&instance->base);
282 }
283 
284 static inline VkResult
vn_physical_device_base_init(struct vn_physical_device_base * physical_dev,struct vn_instance_base * instance,const struct vk_device_extension_table * supported_extensions,const struct vk_physical_device_dispatch_table * dispatch_table)285 vn_physical_device_base_init(
286    struct vn_physical_device_base *physical_dev,
287    struct vn_instance_base *instance,
288    const struct vk_device_extension_table *supported_extensions,
289    const struct vk_physical_device_dispatch_table *dispatch_table)
290 {
291    VkResult result =
292       vk_physical_device_init(&physical_dev->base, &instance->base,
293                               supported_extensions, dispatch_table);
294    physical_dev->id = (uintptr_t)physical_dev;
295    return result;
296 }
297 
298 static inline void
vn_physical_device_base_fini(struct vn_physical_device_base * physical_dev)299 vn_physical_device_base_fini(struct vn_physical_device_base *physical_dev)
300 {
301    vk_physical_device_finish(&physical_dev->base);
302 }
303 
304 static inline VkResult
vn_device_base_init(struct vn_device_base * dev,struct vn_physical_device_base * physical_dev,const struct vk_device_dispatch_table * dispatch_table,const VkDeviceCreateInfo * info,const VkAllocationCallbacks * alloc)305 vn_device_base_init(struct vn_device_base *dev,
306                     struct vn_physical_device_base *physical_dev,
307                     const struct vk_device_dispatch_table *dispatch_table,
308                     const VkDeviceCreateInfo *info,
309                     const VkAllocationCallbacks *alloc)
310 {
311    VkResult result = vk_device_init(&dev->base, &physical_dev->base,
312                                     dispatch_table, info, alloc);
313    dev->id = (uintptr_t)dev;
314    return result;
315 }
316 
317 static inline void
vn_device_base_fini(struct vn_device_base * dev)318 vn_device_base_fini(struct vn_device_base *dev)
319 {
320    vk_device_finish(&dev->base);
321 }
322 
323 static inline void
vn_object_base_init(struct vn_object_base * obj,VkObjectType type,struct vn_device_base * dev)324 vn_object_base_init(struct vn_object_base *obj,
325                     VkObjectType type,
326                     struct vn_device_base *dev)
327 {
328    vk_object_base_init(&dev->base, &obj->base, type);
329    obj->id = (uintptr_t)obj;
330 }
331 
332 static inline void
vn_object_base_fini(struct vn_object_base * obj)333 vn_object_base_fini(struct vn_object_base *obj)
334 {
335    vk_object_base_finish(&obj->base);
336 }
337 
338 static inline void
vn_object_set_id(void * obj,vn_object_id id,VkObjectType type)339 vn_object_set_id(void *obj, vn_object_id id, VkObjectType type)
340 {
341    assert(((const struct vk_object_base *)obj)->type == type);
342    switch (type) {
343    case VK_OBJECT_TYPE_INSTANCE:
344       ((struct vn_instance_base *)obj)->id = id;
345       break;
346    case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
347       ((struct vn_physical_device_base *)obj)->id = id;
348       break;
349    case VK_OBJECT_TYPE_DEVICE:
350       ((struct vn_device_base *)obj)->id = id;
351       break;
352    default:
353       ((struct vn_object_base *)obj)->id = id;
354       break;
355    }
356 }
357 
358 static inline vn_object_id
vn_object_get_id(const void * obj,VkObjectType type)359 vn_object_get_id(const void *obj, VkObjectType type)
360 {
361    assert(((const struct vk_object_base *)obj)->type == type);
362    switch (type) {
363    case VK_OBJECT_TYPE_INSTANCE:
364       return ((struct vn_instance_base *)obj)->id;
365    case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
366       return ((struct vn_physical_device_base *)obj)->id;
367    case VK_OBJECT_TYPE_DEVICE:
368       return ((struct vn_device_base *)obj)->id;
369    default:
370       return ((struct vn_object_base *)obj)->id;
371    }
372 }
373 
374 #endif /* VN_COMMON_H */
375