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