nir: add NIR_DEBUG envvar

Move all the NIR related debug environmental variables in a single
NIR_DEBUG one.

Use NIR_DEBUG=help to print all the available options.

v2:
 - Use a macro to simplify (Marcin, Jason)
 - Remove wrong changes (Marcin)

v3 (Marcin):
 - Remove rendundant NIR mentioning in option descriptions.
 - Unwrap option descriptions.
 - Ensure the constant is unsigned.
 - Use extern array to remove switch.

v4:
 - Add missing kernel shader (Jason).
 - Add unlikely() (Marcin).

Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Marcin Ślusarz <marcin.slusarz@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13840>
This commit is contained in:
Juan A. Suarez Romero 2021-11-17 16:10:52 +01:00 committed by Marge Bot
parent cc7db1fc53
commit f77ccdfb4a
11 changed files with 154 additions and 67 deletions

View File

@ -68,7 +68,7 @@ for var in \
MESA_GL_VERSION_OVERRIDE \
MESA_VK_IGNORE_CONFORMANCE_WARNING \
MINIO_HOST \
NIR_VALIDATE \
NIR_DEBUG \
PAN_I_WANT_A_BROKEN_VULKAN_DRIVER \
PAN_MESA_DEBUG \
PIGLIT_FRACTION \

View File

@ -33,7 +33,7 @@ trap "exit \$exit_code" INT TERM
trap "exit_code=\$?; kill $ERR_TAIL_PID $OUT_TAIL_PID" EXIT
# We aren't testing LLVMPipe here, so we don't need to validate NIR on the host
NIR_VALIDATE=0 LIBGL_ALWAYS_SOFTWARE="true" GALLIUM_DRIVER="$CROSVM_GALLIUM_DRIVER" stdbuf -oL crosvm run \
NIR_DEBUG="novalidate" LIBGL_ALWAYS_SOFTWARE="true" GALLIUM_DRIVER="$CROSVM_GALLIUM_DRIVER" stdbuf -oL crosvm run \
--gpu "$CROSVM_GPU_ARGS" \
-m 4096 \
-c 2 \

View File

@ -207,15 +207,11 @@ The following are only applicable for drivers that uses NIR, as they
modify the behavior for the common ``NIR_PASS`` and ``NIR_PASS_V`` macros,
that wrap calls to NIR lowering/optimizations.
:envvar:`NIR_PRINT`
If defined, the resulting NIR shader will be printed out at each
successful NIR lowering/optimization call.
:envvar:`NIR_TEST_CLONE`
If defined, cloning a NIR shader would be tested at each successful
NIR lowering/optimization call.
:envvar:`NIR_TEST_SERIALIZE`
If defined, serialize and deserialize a NIR shader would be tested at
each successful NIR lowering/optimization call.
:envvar:`NIR_DEBUG`
a comma-separated list of debug options to apply to NIR
shaders. Use `NIR_DEBUG=help` to print a list of available options.
:envvar:`NIR_SKIP`
a comma-separated list of optimization/lowering passes to skip.
Mesa Xlib driver environment variables
--------------------------------------

View File

@ -38,6 +38,81 @@
#include "main/menums.h" /* BITFIELD64_MASK */
#ifndef NDEBUG
uint32_t nir_debug = ~0;
bool nir_debug_print_shader[MESA_SHADER_KERNEL + 1] = { 0 };
static const struct debug_named_value nir_debug_control[] = {
{ "clone", NIR_DEBUG_CLONE,
"Test cloning a shader at each successful lowering/optimization call" },
{ "serialize", NIR_DEBUG_SERIALIZE,
"Test serialize and deserialize shader at each successful lowering/optimization call" },
{ "novalidate", NIR_DEBUG_NOVALIDATE,
"Disable shader validation at each successful lowering/optimization call" },
{ "validate_ssa_dominance", NIR_DEBUG_VALIDATE_SSA_DOMINANCE,
"Validate SSA dominance in shader at each successful lowering/optimization call" },
{ "tgsi", NIR_DEBUG_TGSI,
"Dump NIR/TGSI shaders when doing a NIR<->TGSI translation" },
{ "print", NIR_DEBUG_PRINT,
"Dump resulting shader after each successful lowering/optimization call" },
{ "print_vs", NIR_DEBUG_PRINT_VS,
"Dump resulting vertex shader after each successful lowering/optimization call" },
{ "print_tcs", NIR_DEBUG_PRINT_TCS,
"Dump resulting tessellation control shader after each successful lowering/optimization call" },
{ "print_tes", NIR_DEBUG_PRINT_TES,
"Dump resulting tessellation evaluation shader after each successful lowering/optimization call" },
{ "print_gs", NIR_DEBUG_PRINT_GS,
"Dump resulting geometry shader after each successful lowering/optimization call" },
{ "print_fs", NIR_DEBUG_PRINT_FS,
"Dump resulting fragment shader after each successful lowering/optimization call" },
{ "print_cs", NIR_DEBUG_PRINT_CS,
"Dump resulting compute shader after each successful lowering/optimization call" },
{ "print_ts", NIR_DEBUG_PRINT_TS,
"Dump resulting task shader after each successful lowering/optimization call" },
{ "print_ms", NIR_DEBUG_PRINT_MS,
"Dump resulting mesh shader after each successful lowering/optimization call" },
{ "print_rgs", NIR_DEBUG_PRINT_RGS,
"Dump resulting raygen shader after each successful lowering/optimization call" },
{ "print_ahs", NIR_DEBUG_PRINT_AHS,
"Dump resulting any-hit shader after each successful lowering/optimization call" },
{ "print_chs", NIR_DEBUG_PRINT_CHS,
"Dump resulting closest-hit shader after each successful lowering/optimization call" },
{ "print_mhs", NIR_DEBUG_PRINT_MHS,
"Dump resulting miss-hit shader after each successful lowering/optimization call" },
{ "print_is", NIR_DEBUG_PRINT_IS,
"Dump resulting intersection shader after each successful lowering/optimization call" },
{ "print_cbs", NIR_DEBUG_PRINT_CBS,
"Dump resulting callable shader after each successful lowering/optimization call" },
{ "print_ks", NIR_DEBUG_PRINT_KS,
"Dump resulting kernel shader after each successful lowering/optimization call" },
{ NULL }
};
DEBUG_GET_ONCE_FLAGS_OPTION(nir_debug, "NIR_DEBUG", nir_debug_control, 0)
static void
nir_process_debug_variable(void)
{
if (unlikely(nir_debug == ~0)) {
nir_debug = debug_get_option_nir_debug();
nir_debug_print_shader[MESA_SHADER_VERTEX] = NIR_DEBUG(PRINT_VS);
nir_debug_print_shader[MESA_SHADER_TESS_CTRL] = NIR_DEBUG(PRINT_TCS);
nir_debug_print_shader[MESA_SHADER_TESS_EVAL] = NIR_DEBUG(PRINT_TES);
nir_debug_print_shader[MESA_SHADER_GEOMETRY] = NIR_DEBUG(PRINT_GS);
nir_debug_print_shader[MESA_SHADER_FRAGMENT] = NIR_DEBUG(PRINT_FS);
nir_debug_print_shader[MESA_SHADER_COMPUTE] = NIR_DEBUG(PRINT_CS);
nir_debug_print_shader[MESA_SHADER_TASK] = NIR_DEBUG(PRINT_TS);
nir_debug_print_shader[MESA_SHADER_MESH] = NIR_DEBUG(PRINT_MS);
nir_debug_print_shader[MESA_SHADER_RAYGEN] = NIR_DEBUG(PRINT_RGS);
nir_debug_print_shader[MESA_SHADER_ANY_HIT] = NIR_DEBUG(PRINT_AHS);
nir_debug_print_shader[MESA_SHADER_CLOSEST_HIT] = NIR_DEBUG(PRINT_CHS);
nir_debug_print_shader[MESA_SHADER_MISS] = NIR_DEBUG(PRINT_MHS);
nir_debug_print_shader[MESA_SHADER_INTERSECTION] = NIR_DEBUG(PRINT_IS);
nir_debug_print_shader[MESA_SHADER_CALLABLE] = NIR_DEBUG(PRINT_CBS);
nir_debug_print_shader[MESA_SHADER_KERNEL] = NIR_DEBUG(PRINT_KS);
}
}
#endif
/** Return true if the component mask "mask" with bit size "old_bit_size" can
* be re-interpreted to be used with "new_bit_size".
@ -120,6 +195,10 @@ nir_shader_create(void *mem_ctx,
nir_shader *shader = rzalloc(mem_ctx, nir_shader);
ralloc_set_destructor(shader, nir_shader_destructor);
#ifndef NDEBUG
nir_process_debug_variable();
#endif
exec_list_make_empty(&shader->variables);
shader->options = options;

View File

@ -62,6 +62,52 @@
extern "C" {
#endif
extern uint32_t nir_debug;
extern bool nir_debug_print_shader[MESA_SHADER_KERNEL + 1];
#ifndef NDEBUG
#define NIR_DEBUG(flag) unlikely(nir_debug & (NIR_DEBUG_ ## flag))
#else
#define NIR_DEBUG(flag) false
#endif
#define NIR_DEBUG_CLONE (1u << 0)
#define NIR_DEBUG_SERIALIZE (1u << 1)
#define NIR_DEBUG_NOVALIDATE (1u << 2)
#define NIR_DEBUG_VALIDATE_SSA_DOMINANCE (1u << 3)
#define NIR_DEBUG_TGSI (1u << 4)
#define NIR_DEBUG_PRINT_VS (1u << 5)
#define NIR_DEBUG_PRINT_TCS (1u << 6)
#define NIR_DEBUG_PRINT_TES (1u << 7)
#define NIR_DEBUG_PRINT_GS (1u << 8)
#define NIR_DEBUG_PRINT_FS (1u << 9)
#define NIR_DEBUG_PRINT_CS (1u << 10)
#define NIR_DEBUG_PRINT_TS (1u << 11)
#define NIR_DEBUG_PRINT_MS (1u << 12)
#define NIR_DEBUG_PRINT_RGS (1u << 13)
#define NIR_DEBUG_PRINT_AHS (1u << 14)
#define NIR_DEBUG_PRINT_CHS (1u << 15)
#define NIR_DEBUG_PRINT_MHS (1u << 16)
#define NIR_DEBUG_PRINT_IS (1u << 17)
#define NIR_DEBUG_PRINT_CBS (1u << 18)
#define NIR_DEBUG_PRINT_KS (1u << 19)
#define NIR_DEBUG_PRINT (NIR_DEBUG_PRINT_VS | \
NIR_DEBUG_PRINT_TCS | \
NIR_DEBUG_PRINT_TES | \
NIR_DEBUG_PRINT_GS | \
NIR_DEBUG_PRINT_FS | \
NIR_DEBUG_PRINT_CS | \
NIR_DEBUG_PRINT_TS | \
NIR_DEBUG_PRINT_MS | \
NIR_DEBUG_PRINT_RGS | \
NIR_DEBUG_PRINT_AHS | \
NIR_DEBUG_PRINT_CHS | \
NIR_DEBUG_PRINT_MHS | \
NIR_DEBUG_PRINT_IS | \
NIR_DEBUG_PRINT_CBS | \
NIR_DEBUG_PRINT_KS)
#define NIR_FALSE 0u
#define NIR_TRUE (~0u)
#define NIR_MAX_VEC_COMPONENTS 16
@ -4118,37 +4164,15 @@ should_skip_nir(const char *name)
return comma_separated_list_contains(list, name);
}
static inline bool
should_clone_nir(void)
{
static int should_clone = -1;
if (should_clone < 0)
should_clone = env_var_as_boolean("NIR_TEST_CLONE", false);
return should_clone;
}
static inline bool
should_serialize_deserialize_nir(void)
{
static int test_serialize = -1;
if (test_serialize < 0)
test_serialize = env_var_as_boolean("NIR_TEST_SERIALIZE", false);
return test_serialize;
}
static inline bool
should_print_nir(nir_shader *shader)
{
static int should_print = -1;
if (should_print < 0)
should_print = env_var_as_unsigned("NIR_PRINT", 0);
if (shader->info.internal ||
shader->info.stage < 0 ||
shader->info.stage > MESA_SHADER_KERNEL)
return false;
if (should_print == 1)
return !shader->info.internal;
return should_print;
return unlikely(nir_debug_print_shader[shader->info.stage]);
}
#else
static inline void nir_validate_shader(nir_shader *shader, const char *when) { (void) shader; (void)when; }
@ -4156,9 +4180,7 @@ static inline void nir_validate_ssa_dominance(nir_shader *shader, const char *wh
static inline void nir_metadata_set_validation_flag(nir_shader *shader) { (void) shader; }
static inline void nir_metadata_check_validation_flag(nir_shader *shader) { (void) shader; }
static inline bool should_skip_nir(UNUSED const char *pass_name) { return false; }
static inline bool should_clone_nir(void) { return false; }
static inline bool should_serialize_deserialize_nir(void) { return false; }
static inline bool should_print_nir(nir_shader *shader) { return false; }
static inline bool should_print_nir(UNUSED nir_shader *shader) { return false; }
#endif /* NDEBUG */
#define _PASS(pass, nir, do_pass) do { \
@ -4167,11 +4189,11 @@ static inline bool should_print_nir(nir_shader *shader) { return false; }
break; \
} \
do_pass \
if (should_clone_nir()) { \
if (NIR_DEBUG(CLONE)) { \
nir_shader *clone = nir_shader_clone(ralloc_parent(nir), nir); \
nir_shader_replace(nir, clone); \
} \
if (should_serialize_deserialize_nir()) { \
if (NIR_DEBUG(SERIALIZE)) { \
nir_shader_serialize_deserialize(nir); \
} \
} while (0)

View File

@ -1630,7 +1630,7 @@ validate_function_impl(nir_function_impl *impl, validate_state *state)
static int validate_dominance = -1;
if (validate_dominance < 0) {
validate_dominance =
env_var_as_boolean("NIR_VALIDATE_SSA_DOMINANCE", false);
NIR_DEBUG(VALIDATE_SSA_DOMINANCE);
}
if (validate_dominance)
validate_ssa_dominance(impl, state);
@ -1707,10 +1707,7 @@ dump_errors(validate_state *state, const char *when)
void
nir_validate_shader(nir_shader *shader, const char *when)
{
static int should_validate = -1;
if (should_validate < 0)
should_validate = env_var_as_boolean("NIR_VALIDATE", true);
if (!should_validate)
if (NIR_DEBUG(NOVALIDATE))
return;
validate_state state;
@ -1761,10 +1758,7 @@ nir_validate_shader(nir_shader *shader, const char *when)
void
nir_validate_ssa_dominance(nir_shader *shader, const char *when)
{
static int should_validate = -1;
if (should_validate < 0)
should_validate = env_var_as_boolean("NIR_VALIDATE", true);
if (!should_validate)
if (NIR_DEBUG(NOVALIDATE))
return;
validate_state state;

View File

@ -123,7 +123,7 @@ typedef struct shader_info {
/* Descriptive name provided by the client; may be NULL */
const char *label;
/* Shader is internal, and should be ignored by things like NIR_PRINT */
/* Shader is internal, and should be ignored by things like NIR_DEBUG=print */
bool internal;
/* SHA1 of the original source, used by shader detection in drivers. */

View File

@ -3061,7 +3061,6 @@ nir_to_tgsi(struct nir_shader *s,
{
struct ntt_compile *c;
const void *tgsi_tokens;
bool debug = env_var_as_boolean("NIR_TO_TGSI_DEBUG", false);
nir_variable_mode no_indirects_mask = ntt_no_indirects_mask(s, screen);
bool native_integers = screen->get_shader_param(screen,
pipe_shader_type_from_mesa(s->info.stage),
@ -3142,7 +3141,7 @@ nir_to_tgsi(struct nir_shader *s,
NIR_PASS_V(s, nir_lower_locals_to_regs);
NIR_PASS_V(s, nir_opt_dce);
if (debug) {
if (NIR_DEBUG(TGSI)) {
fprintf(stderr, "NIR before translation to TGSI:\n");
nir_print_shader(s, stderr);
}
@ -3192,7 +3191,7 @@ nir_to_tgsi(struct nir_shader *s,
tgsi_tokens = ureg_get_tokens(c->ureg, NULL);
if (debug) {
if (NIR_DEBUG(TGSI)) {
fprintf(stderr, "TGSI after translation from NIR:\n");
tgsi_dump(tgsi_tokens, 0);
}

View File

@ -2563,7 +2563,6 @@ tgsi_to_nir(const void *tgsi_tokens,
struct nir_shader *s = NULL;
uint8_t key[CACHE_KEY_SIZE];
unsigned processor;
bool debug = env_var_as_boolean("TGSI_TO_NIR_DEBUG", false);
if (allow_disk_cache)
cache = screen->get_disk_shader_cache(screen);
@ -2581,7 +2580,7 @@ tgsi_to_nir(const void *tgsi_tokens,
if (s)
return s;
if (debug) {
if (NIR_DEBUG(TGSI)) {
fprintf(stderr, "TGSI before translation to NIR:\n");
tgsi_dump(tgsi_tokens, 0);
}
@ -2593,7 +2592,7 @@ tgsi_to_nir(const void *tgsi_tokens,
ttn_finalize_nir(c, screen);
ralloc_free(c);
if (debug) {
if (NIR_DEBUG(TGSI)) {
mesa_logi("NIR after translation from TGSI:\n");
nir_log_shaderi(s);
}

View File

@ -35,8 +35,7 @@ deqp_args = [
[deqp.env]
# Stress test NIR clone/serialization for GLES3.1 (which should cover most of the featureset).
# Costs about 30% extra runtime.
NIR_TEST_CLONE = "true"
NIR_TEST_SERIALIZE = "true"
NIR_DEBUG="clone,serialize"
# Note that KHR-GL3* test sets include all tests from the previous
# version, so we only need to run one test list (unlike dEQP-GLES,

View File

@ -21,8 +21,7 @@ lavapipe-nir-stress:
- .lavapipe-test
variables:
DEQP_FRACTION: 100
NIR_TEST_CLONE: "true"
NIR_TEST_SERIALIZE: "true"
NIR_DEBUG: "clone,serialize"
lavapipe-vk-asan:
extends: