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