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 intel_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/intel_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 DEBUG_RT }, 100 { "rt", DEBUG_RT }, 101 { NULL, 0 } 102 }; 103 104 uint64_t 105 intel_debug_flag_for_shader_stage(gl_shader_stage stage) 106 { 107 uint64_t flags[] = { 108 [MESA_SHADER_VERTEX] = DEBUG_VS, 109 [MESA_SHADER_TESS_CTRL] = DEBUG_TCS, 110 [MESA_SHADER_TESS_EVAL] = DEBUG_TES, 111 [MESA_SHADER_GEOMETRY] = DEBUG_GS, 112 [MESA_SHADER_FRAGMENT] = DEBUG_WM, 113 [MESA_SHADER_COMPUTE] = DEBUG_CS, 114 115 [MESA_SHADER_RAYGEN] = DEBUG_RT, 116 [MESA_SHADER_ANY_HIT] = DEBUG_RT, 117 [MESA_SHADER_CLOSEST_HIT] = DEBUG_RT, 118 [MESA_SHADER_MISS] = DEBUG_RT, 119 [MESA_SHADER_INTERSECTION] = DEBUG_RT, 120 [MESA_SHADER_CALLABLE] = DEBUG_RT, 121 }; 122 return flags[stage]; 123 } 124 125 static void 126 brw_process_intel_debug_variable_once(void) 127 { 128 intel_debug = parse_debug_string(getenv("INTEL_DEBUG"), debug_control); 129 } 130 131 void 132 brw_process_intel_debug_variable(void) 133 { 134 static once_flag process_intel_debug_variable_flag = ONCE_FLAG_INIT; 135 136 call_once(&process_intel_debug_variable_flag, 137 brw_process_intel_debug_variable_once); 138 } 139 140 static uint64_t debug_identifier[4] = { 141 0xffeeddccbbaa9988, 142 0x7766554433221100, 143 0xffeeddccbbaa9988, 144 0x7766554433221100, 145 }; 146 147 void * 148 intel_debug_identifier(void) 149 { 150 return debug_identifier; 151 } 152 153 uint32_t 154 intel_debug_identifier_size(void) 155 { 156 return sizeof(debug_identifier); 157 } 158 159 uint32_t 160 intel_debug_write_identifiers(void *_output, 161 uint32_t output_size, 162 const char *driver_name) 163 { 164 void *output = _output, *output_end = _output + output_size; 165 166 assert(output_size > intel_debug_identifier_size()); 167 168 memcpy(output, intel_debug_identifier(), intel_debug_identifier_size()); 169 output += intel_debug_identifier_size(); 170 171 for (uint32_t id = INTEL_DEBUG_BLOCK_TYPE_DRIVER; id < INTEL_DEBUG_BLOCK_TYPE_MAX; id++) { 172 switch (id) { 173 case INTEL_DEBUG_BLOCK_TYPE_DRIVER: { 174 struct intel_debug_block_driver driver_desc = { 175 .base = { 176 .type = id, 177 }, 178 }; 179 int len = snprintf(output + sizeof(driver_desc), 180 output_end - (output + sizeof(driver_desc)), 181 "%s " PACKAGE_VERSION " build " MESA_GIT_SHA1, 182 driver_name); 183 driver_desc.base.length = sizeof(driver_desc) + len + 1; 184 memcpy(output, &driver_desc, sizeof(driver_desc)); 185 output += driver_desc.base.length; 186 break; 187 } 188 189 case INTEL_DEBUG_BLOCK_TYPE_FRAME: { 190 struct intel_debug_block_frame frame_desc = { 191 .base = { 192 .type = INTEL_DEBUG_BLOCK_TYPE_FRAME, 193 .length = sizeof(frame_desc), 194 }, 195 }; 196 memcpy(output, &frame_desc, sizeof(frame_desc)); 197 output += sizeof(frame_desc); 198 break; 199 } 200 201 default: 202 unreachable("Missing identifier write"); 203 } 204 205 assert(output < output_end); 206 } 207 208 struct intel_debug_block_base end = { 209 .type = INTEL_DEBUG_BLOCK_TYPE_END, 210 .length = sizeof(end), 211 }; 212 memcpy(output, &end, sizeof(end)); 213 output += sizeof(end); 214 215 assert(output < output_end); 216 217 /* Return the how many bytes where written, so that the rest of the buffer 218 * can be used for other things. 219 */ 220 return output - _output; 221 } 222 223 void * 224 intel_debug_get_identifier_block(void *_buffer, 225 uint32_t buffer_size, 226 enum intel_debug_block_type type) 227 { 228 void *buffer = _buffer + intel_debug_identifier_size(), 229 *end_buffer = _buffer + buffer_size; 230 231 while (buffer < end_buffer) { 232 struct intel_debug_block_base *item = buffer; 233 234 if (item->type == type) 235 return item; 236 if (item->type == INTEL_DEBUG_BLOCK_TYPE_END) 237 return NULL; 238 239 buffer += item->length; 240 } 241 242 return NULL; 243 } 244