mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 02:50:09 +01:00
nir: add NIR_DEBUG=progress_validation
Fails if a shader was changed but the pass didn't report progress. Signed-off-by: Rhys Perry <pendingchaos02@gmail.com> Reviewed-by: Marek Olšák <maraeo@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35069>
This commit is contained in:
parent
706ba80057
commit
7538167096
3 changed files with 88 additions and 23 deletions
|
|
@ -51,6 +51,8 @@ static const struct debug_named_value nir_debug_control[] = {
|
|||
"Disable shader validation at each successful lowering/optimization call" },
|
||||
{ "extended_validation", NIR_DEBUG_EXTENDED_VALIDATION,
|
||||
"Validate even if a pass does not make progress and test that it properly preserves most types of metadata. This can be very slow" },
|
||||
{ "progress_validation", NIR_DEBUG_PROGRESS_VALIDATION,
|
||||
"Validate that a shader is unmodified if a pass does not report progress" },
|
||||
{ "invalidate_metadata", NIR_DEBUG_INVALIDATE_METADATA,
|
||||
"Invalidate metadata before passes to try to find passes which don't require metadata that they use. This overrides NIR_DEBUG=extended_validation somewhat" },
|
||||
{ "tgsi", NIR_DEBUG_TGSI,
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ extern bool nir_debug_print_shader[MESA_SHADER_KERNEL + 1];
|
|||
#define NIR_DEBUG_PRINT_PASS_FLAGS (1u << 22)
|
||||
#define NIR_DEBUG_INVALIDATE_METADATA (1u << 23)
|
||||
#define NIR_DEBUG_PRINT_STRUCT_DECLS (1u << 24)
|
||||
#define NIR_DEBUG_PROGRESS_VALIDATION (1u << 25)
|
||||
|
||||
#define NIR_DEBUG_PRINT (NIR_DEBUG_PRINT_VS | \
|
||||
NIR_DEBUG_PRINT_TCS | \
|
||||
|
|
@ -4717,6 +4718,8 @@ void nir_validate_ssa_dominance(nir_shader *shader, const char *when);
|
|||
void nir_metadata_set_validation_flag(nir_shader *shader);
|
||||
void nir_metadata_check_validation_flag(nir_shader *shader);
|
||||
void nir_metadata_require_most(nir_shader *shader);
|
||||
struct blob nir_validate_progress_setup(nir_shader *shader);
|
||||
void nir_validate_progress_finish(nir_shader *shader, struct blob *setup_blob, bool progress, const char *when);
|
||||
|
||||
static inline bool
|
||||
should_skip_nir(const char *name)
|
||||
|
|
@ -4773,6 +4776,19 @@ nir_metadata_require_most(nir_shader *shader)
|
|||
{
|
||||
(void)shader;
|
||||
}
|
||||
static inline struct blob
|
||||
nir_validate_progress_setup(nir_shader *shader)
|
||||
{
|
||||
return (struct blob){};
|
||||
}
|
||||
static inline void
|
||||
nir_validate_progress_finish(nir_shader *shader, struct blob *setup_blob, bool progress, const char *when)
|
||||
{
|
||||
(void)shader;
|
||||
(void)setup_blob;
|
||||
(void)progress;
|
||||
(void)when;
|
||||
}
|
||||
static inline bool
|
||||
should_skip_nir(UNUSED const char *pass_name)
|
||||
{
|
||||
|
|
@ -4808,20 +4824,25 @@ should_print_nir(UNUSED nir_shader *shader)
|
|||
#define NIR_STRINGIZE_INNER(x) #x
|
||||
#define NIR_STRINGIZE(x) NIR_STRINGIZE_INNER(x)
|
||||
|
||||
#define NIR_PASS(progress, nir, pass, ...) _PASS(pass, nir, { \
|
||||
nir_metadata_set_validation_flag(nir); \
|
||||
if (should_print_nir(nir)) \
|
||||
printf("%s\n", #pass); \
|
||||
if (pass(nir, ##__VA_ARGS__)) { \
|
||||
nir_validate_shader(nir, "after " #pass " in " __FILE__ ":" NIR_STRINGIZE(__LINE__)); \
|
||||
UNUSED bool _; \
|
||||
progress = true; \
|
||||
if (should_print_nir(nir)) \
|
||||
nir_print_shader(nir, stdout); \
|
||||
nir_metadata_check_validation_flag(nir); \
|
||||
} else if (NIR_DEBUG(EXTENDED_VALIDATION)) { \
|
||||
nir_validate_shader(nir, "after " #pass " in " __FILE__ ":" NIR_STRINGIZE(__LINE__)); \
|
||||
} \
|
||||
#define NIR_PASS(progress, nir, pass, ...) _PASS(pass, nir, { \
|
||||
nir_metadata_set_validation_flag(nir); \
|
||||
if (should_print_nir(nir)) \
|
||||
printf("%s\n", #pass); \
|
||||
static const char *when = "after " #pass " in " __FILE__ ":" NIR_STRINGIZE(__LINE__); \
|
||||
struct blob blob_before = nir_validate_progress_setup(nir); \
|
||||
if (pass(nir, ##__VA_ARGS__)) { \
|
||||
nir_validate_shader(nir, when); \
|
||||
UNUSED bool _; \
|
||||
progress = true; \
|
||||
if (should_print_nir(nir)) \
|
||||
nir_print_shader(nir, stdout); \
|
||||
nir_metadata_check_validation_flag(nir); \
|
||||
nir_validate_progress_finish(nir, &blob_before, true, when); \
|
||||
} else { \
|
||||
if (NIR_DEBUG(EXTENDED_VALIDATION)) \
|
||||
nir_validate_shader(nir, when); \
|
||||
nir_validate_progress_finish(nir, &blob_before, false, when); \
|
||||
} \
|
||||
})
|
||||
|
||||
#define _NIR_LOOP_PASS(progress, idempotent, skip, nir, pass, ...) \
|
||||
|
|
|
|||
|
|
@ -2151,15 +2151,8 @@ nir_serialize_function(struct blob *blob, const nir_function *fxn)
|
|||
util_dynarray_fini(&ctx.phi_fixups);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize NIR into a binary blob.
|
||||
*
|
||||
* \param strip Don't serialize information only useful for debugging,
|
||||
* such as variable names, making cache hits from similar
|
||||
* shaders more likely.
|
||||
*/
|
||||
void
|
||||
nir_serialize(struct blob *blob, const nir_shader *nir, bool strip)
|
||||
static void
|
||||
serialize_internal(struct blob *blob, const nir_shader *nir, bool strip, bool serialize_info)
|
||||
{
|
||||
write_ctx ctx = { 0 };
|
||||
_mesa_pointer_hash_table_init(&ctx.remap_table, NULL);
|
||||
|
|
@ -2172,6 +2165,8 @@ nir_serialize(struct blob *blob, const nir_shader *nir, bool strip)
|
|||
size_t idx_size_offset = blob_reserve_uint32(blob);
|
||||
|
||||
struct shader_info info = nir->info;
|
||||
if (!serialize_info)
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
enum nir_serialize_shader_flags flags = 0;
|
||||
if (!strip && info.name)
|
||||
|
|
@ -2220,6 +2215,19 @@ nir_serialize(struct blob *blob, const nir_shader *nir, bool strip)
|
|||
util_dynarray_fini(&ctx.phi_fixups);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize NIR into a binary blob.
|
||||
*
|
||||
* \param strip Don't serialize information only useful for debugging,
|
||||
* such as variable names, making cache hits from similar
|
||||
* shaders more likely.
|
||||
*/
|
||||
void
|
||||
nir_serialize(struct blob *blob, const nir_shader *nir, bool strip)
|
||||
{
|
||||
serialize_internal(blob, nir, strip, true);
|
||||
}
|
||||
|
||||
nir_shader *
|
||||
nir_deserialize(void *mem_ctx,
|
||||
const struct nir_shader_compiler_options *options,
|
||||
|
|
@ -2335,3 +2343,37 @@ nir_shader_serialize_deserialize(nir_shader *shader)
|
|||
nir_shader_replace(shader, copy);
|
||||
ralloc_free(dead_ctx);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
struct blob
|
||||
nir_validate_progress_setup(nir_shader *shader)
|
||||
{
|
||||
if (!NIR_DEBUG(PROGRESS_VALIDATION))
|
||||
return (struct blob){};
|
||||
|
||||
struct blob blob_before;
|
||||
blob_init(&blob_before);
|
||||
serialize_internal(&blob_before, shader, false, false);
|
||||
return blob_before;
|
||||
}
|
||||
|
||||
void
|
||||
nir_validate_progress_finish(nir_shader *shader, struct blob *setup_blob, bool progress, const char *when)
|
||||
{
|
||||
if (!NIR_DEBUG(PROGRESS_VALIDATION))
|
||||
return;
|
||||
|
||||
if (!progress) {
|
||||
struct blob blob_after;
|
||||
blob_init(&blob_after);
|
||||
serialize_internal(&blob_after, shader, false, false);
|
||||
if (setup_blob->size != blob_after.size ||
|
||||
memcmp(setup_blob->data, blob_after.data, setup_blob->size)) {
|
||||
fprintf(stderr, "NIR changed but no progress reported %s\n", when);
|
||||
abort();
|
||||
}
|
||||
blob_finish(&blob_after);
|
||||
}
|
||||
blob_finish(setup_blob);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue