intel: add identifier for debug purposes
[mesa.git] / src / intel / dev / gen_debug.c
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 { NULL, 0 }
98 };
99
100 uint64_t
101 intel_debug_flag_for_shader_stage(gl_shader_stage stage)
102 {
103 uint64_t flags[] = {
104 [MESA_SHADER_VERTEX] = DEBUG_VS,
105 [MESA_SHADER_TESS_CTRL] = DEBUG_TCS,
106 [MESA_SHADER_TESS_EVAL] = DEBUG_TES,
107 [MESA_SHADER_GEOMETRY] = DEBUG_GS,
108 [MESA_SHADER_FRAGMENT] = DEBUG_WM,
109 [MESA_SHADER_COMPUTE] = DEBUG_CS,
110 };
111 STATIC_ASSERT(MESA_SHADER_STAGES == 6);
112 return flags[stage];
113 }
114
115 static void
116 brw_process_intel_debug_variable_once(void)
117 {
118 INTEL_DEBUG = parse_debug_string(getenv("INTEL_DEBUG"), debug_control);
119 }
120
121 void
122 brw_process_intel_debug_variable(void)
123 {
124 static once_flag process_intel_debug_variable_flag = ONCE_FLAG_INIT;
125
126 call_once(&process_intel_debug_variable_flag,
127 brw_process_intel_debug_variable_once);
128 }
129
130 static uint64_t debug_identifier[4] = {
131 0xffeeddccbbaa9988,
132 0x7766554433221100,
133 0xffeeddccbbaa9988,
134 0x7766554433221100,
135 };
136
137 void *
138 intel_debug_identifier(void)
139 {
140 return debug_identifier;
141 }
142
143 uint32_t
144 intel_debug_identifier_size(void)
145 {
146 return sizeof(debug_identifier);
147 }
148
149 uint32_t
150 intel_debug_write_identifiers(void *_output,
151 uint32_t output_size,
152 const char *driver_name)
153 {
154 void *output = _output, *output_end = _output + output_size;
155
156 assert(output_size > intel_debug_identifier_size());
157
158 memcpy(output, intel_debug_identifier(), intel_debug_identifier_size());
159 output += intel_debug_identifier_size();
160
161 for (uint32_t id = GEN_DEBUG_BLOCK_TYPE_DRIVER; id < GEN_DEBUG_BLOCK_TYPE_MAX; id++) {
162 switch (id) {
163 case GEN_DEBUG_BLOCK_TYPE_DRIVER: {
164 struct gen_debug_block_driver driver_desc = {
165 .base = {
166 .type = id,
167 },
168 };
169 int len = snprintf(output + sizeof(driver_desc),
170 output_end - (output + sizeof(driver_desc)),
171 "%s " PACKAGE_VERSION " build " MESA_GIT_SHA1,
172 driver_name);
173 driver_desc.base.length = sizeof(driver_desc) + len + 1;
174 memcpy(output, &driver_desc, sizeof(driver_desc));
175 output += driver_desc.base.length;
176 break;
177 }
178
179 default:
180 unreachable("Missing identifier write");
181 }
182
183 assert(output < output_end);
184 }
185
186 struct gen_debug_block_base end = {
187 .type = GEN_DEBUG_BLOCK_TYPE_END,
188 .length = sizeof(end),
189 };
190 memcpy(output, &end, sizeof(end));
191 output += sizeof(end);
192
193 assert(output < output_end);
194
195 /* Return the how many bytes where written, so that the rest of the buffer
196 * can be used for other things.
197 */
198 return output - _output;
199 }
200
201 void *
202 intel_debug_get_identifier_block(void *_buffer,
203 uint32_t buffer_size,
204 enum gen_debug_block_type type)
205 {
206 void *buffer = _buffer + intel_debug_identifier_size(),
207 *end_buffer = _buffer + buffer_size;
208
209 while (buffer < end_buffer) {
210 struct gen_debug_block_base *item = buffer;
211
212 if (item->type == type)
213 return item;
214 if (item->type == GEN_DEBUG_BLOCK_TYPE_END)
215 return NULL;
216
217 buffer += item->length;
218 }
219
220 return NULL;
221 }