1 /*
2 * Copyright 2003 VMware, Inc.
3 * Copyright © 2006 Intel Corporation
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 (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 /**
26 * \file gen_debug.c
27 *
28 * Support for the INTEL_DEBUG environment variable, along with other
29 * miscellaneous debugging code.
30 */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36 #include "dev/gen_debug.h"
37 #include "git_sha1.h"
38 #include "util/macros.h"
39 #include "util/debug.h"
40 #include "c11/threads.h"
41
42 uint64_t intel_debug = 0;
43
44 static const struct debug_control debug_control[] = {
45 { "tex", DEBUG_TEXTURE},
46 { "state", DEBUG_STATE},
47 { "blit", DEBUG_BLIT},
48 { "mip", DEBUG_MIPTREE},
49 { "fall", DEBUG_PERF},
50 { "perf", DEBUG_PERF},
51 { "perfmon", DEBUG_PERFMON},
52 { "bat", DEBUG_BATCH},
53 { "pix", DEBUG_PIXEL},
54 { "buf", DEBUG_BUFMGR},
55 { "fbo", DEBUG_FBO},
56 { "fs", DEBUG_WM },
57 { "gs", DEBUG_GS},
58 { "sync", DEBUG_SYNC},
59 { "prim", DEBUG_PRIMS },
60 { "vert", DEBUG_VERTS },
61 { "dri", DEBUG_DRI },
62 { "sf", DEBUG_SF },
63 { "submit", DEBUG_SUBMIT },
64 { "wm", DEBUG_WM },
65 { "urb", DEBUG_URB },
66 { "vs", DEBUG_VS },
67 { "clip", DEBUG_CLIP },
68 { "shader_time", DEBUG_SHADER_TIME },
69 { "no16", DEBUG_NO16 },
70 { "blorp", DEBUG_BLORP },
71 { "nodualobj", DEBUG_NO_DUAL_OBJECT_GS },
72 { "optimizer", DEBUG_OPTIMIZER },
73 { "ann", DEBUG_ANNOTATION },
74 { "no8", DEBUG_NO8 },
75 { "no-oaconfig", DEBUG_NO_OACONFIG },
76 { "spill_fs", DEBUG_SPILL_FS },
77 { "spill_vec4", DEBUG_SPILL_VEC4 },
78 { "cs", DEBUG_CS },
79 { "hex", DEBUG_HEX },
80 { "nocompact", DEBUG_NO_COMPACTION },
81 { "hs", DEBUG_TCS },
82 { "tcs", DEBUG_TCS },
83 { "ds", DEBUG_TES },
84 { "tes", DEBUG_TES },
85 { "l3", DEBUG_L3 },
86 { "do32", DEBUG_DO32 },
87 { "norbc", DEBUG_NO_RBC },
88 { "nohiz", DEBUG_NO_HIZ },
89 { "color", DEBUG_COLOR },
90 { "reemit", DEBUG_REEMIT },
91 { "soft64", DEBUG_SOFT64 },
92 { "tcs8", DEBUG_TCS_EIGHT_PATCH },
93 { "bt", DEBUG_BT },
94 { "pc", DEBUG_PIPE_CONTROL },
95 { "nofc", DEBUG_NO_FAST_CLEAR },
96 { "no32", DEBUG_NO32 },
97 { "shaders", DEBUG_WM | DEBUG_VS | DEBUG_TCS |
98 DEBUG_TES | DEBUG_GS | DEBUG_CS },
99 { NULL, 0 }
100 };
101
102 uint64_t
intel_debug_flag_for_shader_stage(gl_shader_stage stage)103 intel_debug_flag_for_shader_stage(gl_shader_stage stage)
104 {
105 uint64_t flags[] = {
106 [MESA_SHADER_VERTEX] = DEBUG_VS,
107 [MESA_SHADER_TESS_CTRL] = DEBUG_TCS,
108 [MESA_SHADER_TESS_EVAL] = DEBUG_TES,
109 [MESA_SHADER_GEOMETRY] = DEBUG_GS,
110 [MESA_SHADER_FRAGMENT] = DEBUG_WM,
111 [MESA_SHADER_COMPUTE] = DEBUG_CS,
112 };
113 STATIC_ASSERT(MESA_SHADER_STAGES == 6);
114 return flags[stage];
115 }
116
117 static void
brw_process_intel_debug_variable_once(void)118 brw_process_intel_debug_variable_once(void)
119 {
120 intel_debug = parse_debug_string(getenv("INTEL_DEBUG"), debug_control);
121 }
122
123 void
brw_process_intel_debug_variable(void)124 brw_process_intel_debug_variable(void)
125 {
126 static once_flag process_intel_debug_variable_flag = ONCE_FLAG_INIT;
127
128 call_once(&process_intel_debug_variable_flag,
129 brw_process_intel_debug_variable_once);
130 }
131
132 static uint64_t debug_identifier[4] = {
133 0xffeeddccbbaa9988,
134 0x7766554433221100,
135 0xffeeddccbbaa9988,
136 0x7766554433221100,
137 };
138
139 void *
intel_debug_identifier(void)140 intel_debug_identifier(void)
141 {
142 return debug_identifier;
143 }
144
145 uint32_t
intel_debug_identifier_size(void)146 intel_debug_identifier_size(void)
147 {
148 return sizeof(debug_identifier);
149 }
150
151 uint32_t
intel_debug_write_identifiers(void * _output,uint32_t output_size,const char * driver_name)152 intel_debug_write_identifiers(void *_output,
153 uint32_t output_size,
154 const char *driver_name)
155 {
156 void *output = _output, *output_end = _output + output_size;
157
158 assert(output_size > intel_debug_identifier_size());
159
160 memcpy(output, intel_debug_identifier(), intel_debug_identifier_size());
161 output += intel_debug_identifier_size();
162
163 for (uint32_t id = GEN_DEBUG_BLOCK_TYPE_DRIVER; id < GEN_DEBUG_BLOCK_TYPE_MAX; id++) {
164 switch (id) {
165 case GEN_DEBUG_BLOCK_TYPE_DRIVER: {
166 struct gen_debug_block_driver driver_desc = {
167 .base = {
168 .type = id,
169 },
170 };
171 int len = snprintf(output + sizeof(driver_desc),
172 output_end - (output + sizeof(driver_desc)),
173 "%s " PACKAGE_VERSION " build " MESA_GIT_SHA1,
174 driver_name);
175 driver_desc.base.length = sizeof(driver_desc) + len + 1;
176 memcpy(output, &driver_desc, sizeof(driver_desc));
177 output += driver_desc.base.length;
178 break;
179 }
180
181 case GEN_DEBUG_BLOCK_TYPE_FRAME: {
182 struct gen_debug_block_frame frame_desc = {
183 .base = {
184 .type = GEN_DEBUG_BLOCK_TYPE_FRAME,
185 .length = sizeof(frame_desc),
186 },
187 };
188 memcpy(output, &frame_desc, sizeof(frame_desc));
189 output += sizeof(frame_desc);
190 break;
191 }
192
193 default:
194 unreachable("Missing identifier write");
195 }
196
197 assert(output < output_end);
198 }
199
200 struct gen_debug_block_base end = {
201 .type = GEN_DEBUG_BLOCK_TYPE_END,
202 .length = sizeof(end),
203 };
204 memcpy(output, &end, sizeof(end));
205 output += sizeof(end);
206
207 assert(output < output_end);
208
209 /* Return the how many bytes where written, so that the rest of the buffer
210 * can be used for other things.
211 */
212 return output - _output;
213 }
214
215 void *
intel_debug_get_identifier_block(void * _buffer,uint32_t buffer_size,enum gen_debug_block_type type)216 intel_debug_get_identifier_block(void *_buffer,
217 uint32_t buffer_size,
218 enum gen_debug_block_type type)
219 {
220 void *buffer = _buffer + intel_debug_identifier_size(),
221 *end_buffer = _buffer + buffer_size;
222
223 while (buffer < end_buffer) {
224 struct gen_debug_block_base *item = buffer;
225
226 if (item->type == type)
227 return item;
228 if (item->type == GEN_DEBUG_BLOCK_TYPE_END)
229 return NULL;
230
231 buffer += item->length;
232 }
233
234 return NULL;
235 }
236