| #include "nir.h" |
| |
| #include "util/hex.h" |
| #include "util/log.h" |
| #include "util/mesa-blake3.h" |
| #include "util/u_call_once.h" |
| |
| /** @file |
| * Shader bisect support. |
| * |
| * Simply use nir_shader_bisect_select() to control some bad behavior you've |
| * identified (calling a shader pass or executing some bad part of a |
| * shader_pass), then run your application under nir_shader_bisect.py to be |
| * interactively guided through bisecting down to which NIR shader in your |
| * program is being badly affected by the code in question. |
| * |
| * Note that doing this requires (unless someone rigs up cache key handling) |
| * MESA_SHADER_DISABLE_CACHE=1, which is also set by nir_shader_bisect.py. |
| */ |
| |
| /* These are expected to be hex dumps of blake3 bytes, no space and no leading |
| * '0x' |
| */ |
| static const char *nir_shader_bisect_lo = NULL; |
| static const char *nir_shader_bisect_hi = NULL; |
| |
| DEBUG_GET_ONCE_OPTION(nir_shader_bisect_lo, "NIR_SHADER_BISECT_LO", NULL); |
| DEBUG_GET_ONCE_OPTION(nir_shader_bisect_hi, "NIR_SHADER_BISECT_HI", NULL); |
| |
| static void |
| nir_shader_bisect_init(void) |
| { |
| nir_shader_bisect_lo = debug_get_option_nir_shader_bisect_lo(); |
| nir_shader_bisect_hi = debug_get_option_nir_shader_bisect_hi(); |
| if (nir_shader_bisect_lo) |
| assert(strlen(nir_shader_bisect_lo) + 1 == BLAKE3_HEX_LEN); |
| if (nir_shader_bisect_hi) |
| assert(strlen(nir_shader_bisect_hi) + 1 == BLAKE3_HEX_LEN); |
| } |
| |
| bool |
| nir_shader_bisect_select(nir_shader *s) |
| { |
| static once_flag once = ONCE_FLAG_INIT; |
| call_once(&once, nir_shader_bisect_init); |
| |
| if (!nir_shader_bisect_lo && !nir_shader_bisect_hi) |
| return false; |
| |
| char id[BLAKE3_HEX_LEN]; |
| _mesa_blake3_format(id, s->info.source_blake3); |
| |
| if (nir_shader_bisect_lo && strcmp(id, nir_shader_bisect_lo) < 0) |
| return false; |
| |
| if (nir_shader_bisect_hi && strcmp(id, nir_shader_bisect_hi) > 0) |
| return false; |
| |
| uint32_t u32[BLAKE3_OUT_LEN32] = { 0 }; |
| for (unsigned i = 0; i < BLAKE3_OUT_LEN; i++) |
| u32[i / 4] |= (uint32_t)s->info.source_blake3[i] << ((i % 4) * 8); |
| |
| /* Provide feedback of both the source_blake3 and the blake3_format id to the |
| * script of what shaders got affected, so it can bisect on the set of |
| * shaders remaining for the env vars, and print out a final blake3 when we |
| * get down to 1 shader. |
| */ |
| mesa_logi("NIR bisect selected source_blake3: {0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x} (%s)\n", |
| u32[0], u32[1], u32[2], u32[3], |
| u32[4], u32[5], u32[6], u32[7], id); |
| |
| return true; |
| } |