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#include "vn_common.h" 12bf215546Sopenharmony_ci 13bf215546Sopenharmony_ci#include <stdarg.h> 14bf215546Sopenharmony_ci 15bf215546Sopenharmony_ci#include "util/debug.h" 16bf215546Sopenharmony_ci#include "util/log.h" 17bf215546Sopenharmony_ci#include "util/os_misc.h" 18bf215546Sopenharmony_ci#include "util/u_debug.h" 19bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_info.h" 20bf215546Sopenharmony_ci#include "vk_enum_to_str.h" 21bf215546Sopenharmony_ci 22bf215546Sopenharmony_ci#define VN_RELAX_MIN_BASE_SLEEP_US (10) 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_cistatic const struct debug_control vn_debug_options[] = { 25bf215546Sopenharmony_ci { "init", VN_DEBUG_INIT }, 26bf215546Sopenharmony_ci { "result", VN_DEBUG_RESULT }, 27bf215546Sopenharmony_ci { "vtest", VN_DEBUG_VTEST }, 28bf215546Sopenharmony_ci { "wsi", VN_DEBUG_WSI }, 29bf215546Sopenharmony_ci { "no_abort", VN_DEBUG_NO_ABORT }, 30bf215546Sopenharmony_ci { NULL, 0 }, 31bf215546Sopenharmony_ci}; 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_cistatic const struct debug_control vn_perf_options[] = { 34bf215546Sopenharmony_ci { "no_async_set_alloc", VN_PERF_NO_ASYNC_SET_ALLOC }, 35bf215546Sopenharmony_ci { "no_async_buffer_create", VN_PERF_NO_ASYNC_BUFFER_CREATE }, 36bf215546Sopenharmony_ci { "no_async_queue_submit", VN_PERF_NO_ASYNC_QUEUE_SUBMIT }, 37bf215546Sopenharmony_ci { "no_event_feedback", VN_PERF_NO_EVENT_FEEDBACK }, 38bf215546Sopenharmony_ci { "no_fence_feedback", VN_PERF_NO_FENCE_FEEDBACK }, 39bf215546Sopenharmony_ci { NULL, 0 }, 40bf215546Sopenharmony_ci}; 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_cistruct vn_env vn_env; 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_cistatic void 45bf215546Sopenharmony_civn_env_init_once(void) 46bf215546Sopenharmony_ci{ 47bf215546Sopenharmony_ci vn_env.debug = 48bf215546Sopenharmony_ci parse_debug_string(os_get_option("VN_DEBUG"), vn_debug_options); 49bf215546Sopenharmony_ci vn_env.perf = 50bf215546Sopenharmony_ci parse_debug_string(os_get_option("VN_PERF"), vn_perf_options); 51bf215546Sopenharmony_ci vn_env.draw_cmd_batch_limit = 52bf215546Sopenharmony_ci debug_get_num_option("VN_DRAW_CMD_BATCH_LIMIT", UINT32_MAX); 53bf215546Sopenharmony_ci if (!vn_env.draw_cmd_batch_limit) 54bf215546Sopenharmony_ci vn_env.draw_cmd_batch_limit = UINT32_MAX; 55bf215546Sopenharmony_ci vn_env.relax_base_sleep_us = debug_get_num_option( 56bf215546Sopenharmony_ci "VN_RELAX_BASE_SLEEP_US", VN_RELAX_MIN_BASE_SLEEP_US); 57bf215546Sopenharmony_ci vn_env.relax_base_sleep_us = 58bf215546Sopenharmony_ci MAX2(vn_env.relax_base_sleep_us, VN_RELAX_MIN_BASE_SLEEP_US); 59bf215546Sopenharmony_ci} 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_civoid 62bf215546Sopenharmony_civn_env_init(void) 63bf215546Sopenharmony_ci{ 64bf215546Sopenharmony_ci static once_flag once = ONCE_FLAG_INIT; 65bf215546Sopenharmony_ci call_once(&once, vn_env_init_once); 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci /* log per VkInstance creation */ 68bf215546Sopenharmony_ci if (VN_DEBUG(INIT)) { 69bf215546Sopenharmony_ci vn_log(NULL, 70bf215546Sopenharmony_ci "vn_env is as below:" 71bf215546Sopenharmony_ci "\n\tdebug = 0x%" PRIx64 "" 72bf215546Sopenharmony_ci "\n\tperf = 0x%" PRIx64 "" 73bf215546Sopenharmony_ci "\n\tdraw_cmd_batch_limit = %u" 74bf215546Sopenharmony_ci "\n\trelax_base_sleep_us = %u", 75bf215546Sopenharmony_ci vn_env.debug, vn_env.perf, vn_env.draw_cmd_batch_limit, 76bf215546Sopenharmony_ci vn_env.relax_base_sleep_us); 77bf215546Sopenharmony_ci } 78bf215546Sopenharmony_ci} 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_civoid 81bf215546Sopenharmony_civn_trace_init(void) 82bf215546Sopenharmony_ci{ 83bf215546Sopenharmony_ci#ifdef ANDROID 84bf215546Sopenharmony_ci atrace_init(); 85bf215546Sopenharmony_ci#endif 86bf215546Sopenharmony_ci} 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_civoid 89bf215546Sopenharmony_civn_log(struct vn_instance *instance, const char *format, ...) 90bf215546Sopenharmony_ci{ 91bf215546Sopenharmony_ci va_list ap; 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci va_start(ap, format); 94bf215546Sopenharmony_ci mesa_log_v(MESA_LOG_DEBUG, "MESA-VIRTIO", format, ap); 95bf215546Sopenharmony_ci va_end(ap); 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci /* instance may be NULL or partially initialized */ 98bf215546Sopenharmony_ci} 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ciVkResult 101bf215546Sopenharmony_civn_log_result(struct vn_instance *instance, 102bf215546Sopenharmony_ci VkResult result, 103bf215546Sopenharmony_ci const char *where) 104bf215546Sopenharmony_ci{ 105bf215546Sopenharmony_ci vn_log(instance, "%s: %s", where, vk_Result_to_str(result)); 106bf215546Sopenharmony_ci return result; 107bf215546Sopenharmony_ci} 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ciuint32_t 110bf215546Sopenharmony_civn_extension_get_spec_version(const char *name) 111bf215546Sopenharmony_ci{ 112bf215546Sopenharmony_ci const int32_t index = vn_info_extension_index(name); 113bf215546Sopenharmony_ci return index >= 0 ? vn_info_extension_get(index)->spec_version : 0; 114bf215546Sopenharmony_ci} 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_civoid 117bf215546Sopenharmony_civn_relax(uint32_t *iter, const char *reason) 118bf215546Sopenharmony_ci{ 119bf215546Sopenharmony_ci /* Yield for the first 2^busy_wait_order times and then sleep for 120bf215546Sopenharmony_ci * base_sleep_us microseconds for the same number of times. After that, 121bf215546Sopenharmony_ci * keep doubling both sleep length and count. 122bf215546Sopenharmony_ci */ 123bf215546Sopenharmony_ci const uint32_t busy_wait_order = 4; 124bf215546Sopenharmony_ci const uint32_t base_sleep_us = vn_env.relax_base_sleep_us; 125bf215546Sopenharmony_ci const uint32_t warn_order = 12; 126bf215546Sopenharmony_ci const uint32_t abort_order = 14; 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci (*iter)++; 129bf215546Sopenharmony_ci if (*iter < (1 << busy_wait_order)) { 130bf215546Sopenharmony_ci thrd_yield(); 131bf215546Sopenharmony_ci return; 132bf215546Sopenharmony_ci } 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci /* warn occasionally if we have slept at least 1.28ms for 2048 times (plus 135bf215546Sopenharmony_ci * another 2047 shorter sleeps) 136bf215546Sopenharmony_ci */ 137bf215546Sopenharmony_ci if (unlikely(*iter % (1 << warn_order) == 0)) { 138bf215546Sopenharmony_ci vn_log(NULL, "stuck in %s wait with iter at %d", reason, *iter); 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci if (*iter >= (1 << abort_order) && !VN_DEBUG(NO_ABORT)) { 141bf215546Sopenharmony_ci vn_log(NULL, "aborting"); 142bf215546Sopenharmony_ci abort(); 143bf215546Sopenharmony_ci } 144bf215546Sopenharmony_ci } 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci const uint32_t shift = util_last_bit(*iter) - busy_wait_order - 1; 147bf215546Sopenharmony_ci os_time_sleep(base_sleep_us << shift); 148bf215546Sopenharmony_ci} 149