ir3: add debug option to override shader assembly

IR3_SHADER_DEBUG=vs,tcs,tes... now also prints shader's sha1.

When there is a file named %sha1%.asm in IR3_SHADER_OVERRIDE_PATH
directory - ir3 assembly from file would be parsed, assembled, and
will override the shader with corresponding sha1 hash.

Parsing failure is considered unrecoverable error.
Upon successful override shader's assembly is printed with:
 "Native code (overridden) for unnamed ..."

This debug option allows easier testing of small changes in
assembly without modifying the compiler or using computerator.

Signed-off-by: Danylo Piliaiev <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8388>
This commit is contained in:
Danylo Piliaiev 2021-01-08 15:09:30 +02:00 committed by Marge Bot
parent 64f939020d
commit 39a2da738d
3 changed files with 65 additions and 6 deletions

View file

@ -50,8 +50,10 @@ static const struct debug_named_value shader_debug_options[] = {
};
DEBUG_GET_ONCE_FLAGS_OPTION(ir3_shader_debug, "IR3_SHADER_DEBUG", shader_debug_options, 0)
DEBUG_GET_ONCE_OPTION(ir3_shader_override_path, "IR3_SHADER_OVERRIDE_PATH", NULL)
enum ir3_shader_debug ir3_shader_debug = 0;
const char *ir3_shader_override_path = NULL;
void
ir3_compiler_destroy(struct ir3_compiler *compiler)
@ -66,6 +68,12 @@ ir3_compiler_create(struct fd_device *dev, uint32_t gpu_id)
struct ir3_compiler *compiler = rzalloc(NULL, struct ir3_compiler);
ir3_shader_debug = debug_get_option_ir3_shader_debug();
ir3_shader_override_path =
!__check_suid() ? debug_get_option_ir3_shader_override_path() : NULL;
if (ir3_shader_override_path) {
ir3_shader_debug |= IR3_DBG_NOCACHE;
}
compiler->dev = dev;
compiler->gpu_id = gpu_id;

View file

@ -155,6 +155,7 @@ enum ir3_shader_debug {
};
extern enum ir3_shader_debug ir3_shader_debug;
extern const char *ir3_shader_override_path;
static inline bool
shader_debug_enabled(gl_shader_stage type)

View file

@ -35,6 +35,8 @@
#include "ir3_shader.h"
#include "ir3_compiler.h"
#include "ir3_nir.h"
#include "ir3_assembler.h"
#include "ir3_parser.h"
#include "isa/isa.h"
@ -181,17 +183,65 @@ void * ir3_shader_assemble(struct ir3_shader_variant *v)
return bin;
}
static bool
try_override_shader_variant(struct ir3_shader_variant *v, const char *identifier)
{
assert(ir3_shader_override_path);
char *name = ralloc_asprintf(NULL, "%s/%s.asm", ir3_shader_override_path, identifier);
FILE* f = fopen(name, "r");
if (!f) {
ralloc_free(name);
return false;
}
struct ir3_kernel_info info;
info.numwg = INVALID_REG;
v->ir = ir3_parse(v, &info, f);
fclose(f);
if (!v->ir) {
fprintf(stderr, "Failed to parse %s\n", name);
exit(1);
}
v->bin = ir3_shader_assemble(v);
if (!v->bin) {
fprintf(stderr, "Failed to assemble %s\n", name);
exit(1);
}
ralloc_free(name);
return true;
}
static void
assemble_variant(struct ir3_shader_variant *v)
{
v->bin = ir3_shader_assemble(v);
if (shader_debug_enabled(v->shader->type)) {
fprintf(stdout, "Native code for unnamed %s shader %s:\n",
ir3_shader_stage(v), v->shader->nir->info.name);
if (v->shader->type == MESA_SHADER_FRAGMENT)
fprintf(stdout, "SIMD0\n");
ir3_shader_disasm(v, v->bin, stdout);
bool dbg_enabled = shader_debug_enabled(v->shader->type);
if (dbg_enabled || ir3_shader_override_path) {
unsigned char sha1[21];
char sha1buf[41];
_mesa_sha1_compute(v->bin, v->info.size, sha1);
_mesa_sha1_format(sha1buf, sha1);
bool shader_overridden =
ir3_shader_override_path && try_override_shader_variant(v, sha1buf);
if (dbg_enabled || shader_overridden) {
fprintf(stdout, "Native code%s for unnamed %s shader %s with sha1 %s:\n",
shader_overridden ? " (overridden)" : "",
ir3_shader_stage(v), v->shader->nir->info.name, sha1buf);
if (v->shader->type == MESA_SHADER_FRAGMENT)
fprintf(stdout, "SIMD0\n");
ir3_shader_disasm(v, v->bin, stdout);
}
}
/* no need to keep the ir around beyond this point: */