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