• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright (C) 2018 Collabora Ltd
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  **************************************************************************/
24 
25 #include "vrend_debug.h"
26 #include "vrend_renderer.h"
27 #include "util/u_debug.h"
28 #include <stdlib.h>
29 #include <stdio.h>
30 
31 static const char *command_names[VIRGL_MAX_COMMANDS] = {
32    "NOP",
33    "CREATE_OBJECT",
34    "BIND_OBJECT",
35    "DESTROY_OBJECT",
36    "SET_VIEWPORT_STATE",
37    "SET_FRAMEBUFFER_STATE",
38    "SET_VERTEX_BUFFERS",
39    "CLEAR",
40    "DRAW_VBO",
41    "RESOURCE_INLINE_WRITE",
42    "SET_SAMPLER_VIEWS",
43    "SET_INDEX_BUFFER",
44    "SET_CONSTANT_BUFFER",
45    "SET_STENCIL_REF",
46    "SET_BLEND_COLOR",
47    "SET_SCISSOR_STATE",
48    "BLIT",
49    "RESOURCE_COPY_REGION",
50    "BIND_SAMPLER_STATES",
51    "BEGIN_QUERY",
52    "END_QUERY",
53    "GET_QUERY_RESULT",
54    "SET_POLYGON_STIPPLE",
55    "SET_CLIP_STATE",
56    "SET_SAMPLE_MASK",
57    "SET_STREAMOUT_TARGETS",
58    "SET_RENDER_CONDITION",
59    "SET_UNIFORM_BUFFER",
60    "SET_SUB_CTX",
61    "CREATE_SUB_CTX",
62    "DESTROY_SUB_CTX",
63    "BIND_SHADER",
64    "SET_TESS_STATE",
65    "SET_MIN_SAMPLES",
66    "SET_SHADER_BUFFERS",
67    "SET_SHADER_IMAGES",
68    "MEMORY_BARRIER",
69    "LAUNCH_GRID",
70    "SET_FRAMEBUFFER_STATE_NO_ATTACH",
71    "TEXTURE_BARRIER",
72    "SET_ATOMIC_BUFFERS",
73    "SET_DEBUG_FLAGS",
74    "GET_QBO_RESULT",
75    "TRANSFER3D",
76    "END_TRANSFERS",
77    "COPY_TRANSFER3D",
78    "TWEAK",
79    "CLEAR_TEXTURE"
80    "PIPE_RESOURCE_CREATE",
81    "PIPE_RESOURCE_SET_TYPE",
82 };
83 
84 static const char *object_type_names[VIRGL_MAX_OBJECTS] = {
85    "NULL",
86    "BLEND",
87    "RASTERIZER",
88    "DSA",
89    "SHADER",
90    "VERTEX_ELEMENTS",
91    "SAMPLER_VIEW",
92    "SAMPLER_STATE",
93    "SURFACE",
94    "QUERY",
95    "STREAMOUT_TARGET"
96 };
97 
vrend_get_comand_name(enum virgl_context_cmd cmd)98 const char *vrend_get_comand_name(enum virgl_context_cmd cmd)
99 {
100    if (cmd < VIRGL_MAX_COMMANDS)
101       return command_names[cmd];
102    return "UNKNOWN";
103 }
104 
vrend_get_object_type_name(enum virgl_object_type obj)105 extern const char *vrend_get_object_type_name(enum virgl_object_type obj)
106 {
107    if (obj < VIRGL_MAX_OBJECTS)
108       return object_type_names[obj];
109    return "UNKNOWN";
110 }
111 
112 static const struct debug_named_value vrend_debug_options[] = {
113    {"tgsi", dbg_shader_tgsi, "Print TGSI"},
114    {"glsl", dbg_shader_glsl, "Print GLSL shaders created from TGSI"},
115    {"shader", dbg_shader, "Print TGSI and created GLSL shaders"},
116    {"stream", dbg_shader_streamout, "Print shader streamout"},
117    {"cmd", dbg_cmd, "Print incoming commands"},
118    {"obj", dbg_object, "Print object creation"},
119    {"blit", dbg_blit, "Debug blit code path"},
120    {"copyres", dbg_copy_resource, "Debug copy resource code path"},
121    {"feat", dbg_features, "Log features found"},
122    {"tex", dbg_tex, "Log texture operations"},
123    {"caller", dbg_caller, "Log who is creating the context"},
124    {"tweak", dbg_tweak, "Log tweaks"},
125    {"query", dbg_query, "Log queries"},
126    {"gles", dbg_gles, "GLES host specific debug"},
127    {"all", dbg_all, "Enable all debugging output"},
128    {"guestallow", dbg_allow_guest_override, "Allow the guest to override the debug flags"},
129    {"khr", dbg_khr, "Enable debug via KHR_debug extension"},
130    DEBUG_NAMED_VALUE_END
131 };
132 
133 static uint64_t vrend_debug_flags = 0;
134 static int vrend_debug_flags_initalized = 0;
135 
vrend_get_debug_flags(const char * flagstring)136 int vrend_get_debug_flags(const char *flagstring)
137 {
138    int retval;
139    char buf[1024] = "";
140 
141    /* Unfortunately the available function to scan the flags take the string
142     * from the environment. The alternative to using setenv would be to
143     * duplicate code or to change the gallium/util intefaces and diverge more
144     * from mesa. So just stick to the environment variable. */
145    snprintf(buf, 1024, "VREND_TEMP_DEBUG_STRING_%d", getpid());
146    setenv(buf, flagstring, 1);
147 
148    retval = (int)debug_get_flags_option(buf,
149                                         vrend_debug_options, 0);
150    unsetenv(buf);
151    return retval;
152 }
153 
vrend_init_debug_flags()154 void vrend_init_debug_flags()
155 {
156    if (!vrend_debug_flags_initalized)  {
157       vrend_debug_flags_initalized = 1;
158       vrend_debug_flags = debug_get_flags_option("VREND_DEBUG",
159                                                  vrend_debug_options, 0);
160    }
161 }
162 
vrend_debug(const struct vrend_context * ctx,enum virgl_debug_flags flag)163 unsigned vrend_debug(const struct vrend_context *ctx, enum virgl_debug_flags flag)
164 {
165    return (vrend_debug_flags & flag) || vrend_context_has_debug_flag(ctx, flag);
166 }
167 
vrend_debug_add_flag(enum virgl_debug_flags flag)168 void vrend_debug_add_flag(enum virgl_debug_flags flag)
169 {
170    vrend_debug_flags |= flag;
171 }
172 
vrend_debug_can_override(void)173 int  vrend_debug_can_override(void)
174 {
175    return vrend_debug_flags & dbg_allow_guest_override;
176 }
177 
178 static
vrend_default_debug_callback(const char * fmt,va_list va)179 void vrend_default_debug_callback(const char *fmt, va_list va)
180 {
181    static FILE* fp = NULL;
182    if (NULL == fp) {
183       const char* log = getenv("VIRGL_LOG_FILE");
184       if (log) {
185          char *log_prefix = strdup(log);
186          char *log_suffix = strstr(log_prefix, "%PID%");
187          if (log_suffix) {
188             *log_suffix = 0;
189             log_suffix += 5;
190             int len = strlen(log) + 32;
191             char *name = malloc(len);
192             snprintf(name, len, "%s%d%s", log_prefix, getpid(), log_suffix);
193             fp = fopen(name, "a");
194             free(name);
195          } else {
196             fp = fopen(log, "a");
197          }
198          free(log_prefix);
199          if (NULL == fp) {
200             fprintf(stderr, "Can't open %s\n", log);
201             fp = stderr;
202          }
203       } else {
204             fp = stderr;
205       }
206    }
207    vfprintf(fp, fmt, va);
208    fflush(fp);
209 }
210 
211 static virgl_debug_callback_type debug_callback = vrend_default_debug_callback;
212 
vrend_printf(const char * fmt,...)213 void vrend_printf(const char *fmt, ...)
214 {
215    if (debug_callback) {
216       va_list va;
217       va_start(va, fmt);
218       debug_callback(fmt, va);
219       va_end(va);
220    }
221 }
222 
vrend_set_debug_callback(virgl_debug_callback_type cb)223 virgl_debug_callback_type vrend_set_debug_callback(virgl_debug_callback_type cb)
224 {
225    virgl_debug_callback_type retval = debug_callback;
226    debug_callback = cb;
227    return retval;
228 }
229 
230