• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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