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