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 80static inline int 81vn_trace_scope_begin(const char *name) 82{ 83 VN_TRACE_BEGIN(name); 84 return 0; 85} 86 87static inline void 88vn_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 101struct vn_instance; 102struct vn_physical_device; 103struct vn_device; 104struct vn_queue; 105struct vn_fence; 106struct vn_semaphore; 107struct vn_device_memory; 108struct vn_buffer; 109struct vn_buffer_view; 110struct vn_image; 111struct vn_image_view; 112struct vn_sampler; 113struct vn_sampler_ycbcr_conversion; 114struct vn_descriptor_set_layout; 115struct vn_descriptor_pool; 116struct vn_descriptor_set; 117struct vn_descriptor_update_template; 118struct vn_render_pass; 119struct vn_framebuffer; 120struct vn_event; 121struct vn_query_pool; 122struct vn_shader_module; 123struct vn_pipeline_layout; 124struct vn_pipeline_cache; 125struct vn_pipeline; 126struct vn_command_pool; 127struct vn_command_buffer; 128 129struct vn_cs_encoder; 130struct vn_cs_decoder; 131 132struct vn_renderer; 133struct vn_renderer_shmem; 134struct vn_renderer_bo; 135struct vn_renderer_sync; 136 137enum 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 145enum 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 153typedef uint64_t vn_object_id; 154 155/* base class of vn_instance */ 156struct vn_instance_base { 157 struct vk_instance base; 158 vn_object_id id; 159}; 160 161/* base class of vn_physical_device */ 162struct vn_physical_device_base { 163 struct vk_physical_device base; 164 vn_object_id id; 165}; 166 167/* base class of vn_device */ 168struct vn_device_base { 169 struct vk_device base; 170 vn_object_id id; 171}; 172 173/* base class of other driver objects */ 174struct vn_object_base { 175 struct vk_object_base base; 176 vn_object_id id; 177}; 178 179struct vn_refcount { 180 atomic_int count; 181}; 182 183struct 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}; 190extern struct vn_env vn_env; 191 192void 193vn_env_init(void); 194 195void 196vn_trace_init(void); 197 198void 199vn_log(struct vn_instance *instance, const char *format, ...) 200 PRINTFLIKE(2, 3); 201 202VkResult 203vn_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 210static inline int 211vn_refcount_load_relaxed(const struct vn_refcount *ref) 212{ 213 return atomic_load_explicit(&ref->count, memory_order_relaxed); 214} 215 216static inline int 217vn_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 222static inline int 223vn_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 228static inline bool 229vn_refcount_is_valid(const struct vn_refcount *ref) 230{ 231 return vn_refcount_load_relaxed(ref) > 0; 232} 233 234static inline void 235vn_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 242static inline bool 243vn_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 256uint32_t 257vn_extension_get_spec_version(const char *name); 258 259void 260vn_relax(uint32_t *iter, const char *reason); 261 262static_assert(sizeof(vn_object_id) >= sizeof(uintptr_t), ""); 263 264static inline VkResult 265vn_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 278static inline void 279vn_instance_base_fini(struct vn_instance_base *instance) 280{ 281 vk_instance_finish(&instance->base); 282} 283 284static inline VkResult 285vn_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 298static inline void 299vn_physical_device_base_fini(struct vn_physical_device_base *physical_dev) 300{ 301 vk_physical_device_finish(&physical_dev->base); 302} 303 304static inline VkResult 305vn_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 317static inline void 318vn_device_base_fini(struct vn_device_base *dev) 319{ 320 vk_device_finish(&dev->base); 321} 322 323static inline void 324vn_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 332static inline void 333vn_object_base_fini(struct vn_object_base *obj) 334{ 335 vk_object_base_finish(&obj->base); 336} 337 338static inline void 339vn_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 358static inline vn_object_id 359vn_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