[Mesa-dev] [PATCH v2] nv50/ir: add debug options for shader replacement
Rhys Perry
pendingchaos02 at gmail.com
Sat May 19 21:28:29 UTC 2018
Changes in v2:
- move "#ifdef DEBUG" from above dumpProgram to above createDumpFilename
Previously, findFirstUse() only considered reads "uses". This fixes that by
making it check both an instruction's sources and definitions. It also shortens
both findFistUse() and findFirstDef() along the way.
---
.../drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 103 ++++++++++-----------
1 file changed, 50 insertions(+), 53 deletions(-)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
index 1f6189890c..c942db3ec9 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
@@ -3618,6 +3618,7 @@ private:
bool insertBarriers(BasicBlock *);
+ bool doesInsnWriteTo(const Instruction *insn, const Value *val) const;
Instruction *findFirstUse(const Instruction *) const;
Instruction *findFirstDef(const Instruction *) const;
@@ -3948,8 +3949,43 @@ SchedDataCalculatorGM107::needWrDepBar(const Instruction *insn) const
return false;
}
-// Find the next instruction inside the same basic block which uses the output
-// of the given instruction in order to avoid RaW hazards.
+// Helper function for findFirstUse() and findFirstDef()
+bool
+SchedDataCalculatorGM107::doesInsnWriteTo(const Instruction *insn,
+ const Value *val) const
+{
+ for (int d = 0; insn->defExists(d); ++d) {
+ The NV50_PROG_DUMP environment variable specifies a (already created) directory
to dump both shader binaries and tgsi code. The NV50_PROG_REPLACE environment
variable specified a (again, already created) directory that is searched to
find replacement binaries. This is all much like MESA_SHADER_DUMP_PATH and
MESA_SHADER_READ_PATH except using shortened SHA1 checksums instead of program
IDs and chip-specific binaries instead of GLSL.
---
src/gallium/drivers/nouveau/codegen/nv50_ir.cpp | 114 ++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp
index c987da9908..aad78fadcf 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.cpp
@@ -23,6 +23,10 @@
#include "codegen/nv50_ir.h"
#include "codegen/nv50_ir_target.h"
#include "codegen/nv50_ir_driver.h"
+#ifdef DEBUG
+#include "tgsi/tgsi_dump.h"
+#include "util/mesa-sha1.h"
+#endif
extern "C" {
#include "nouveau_debug.h"
@@ -1161,6 +1165,111 @@ void Program::releaseValue(Value *value)
mem_Symbol.release(value);
}
+#ifdef DEBUG
+static char*
+createDumpFilename(const char *dir, nv50_ir::Program *prog, const char *ext)
+{
+ char* fname = (char*)malloc(strlen(dir)+13+strlen(ext));
+ if (dir[0] && dir[strlen(dir)-1]=='/')
+ strcpy(fname, dir);
+ else
+ sprintf(fname, "%s/", dir);
+
+ unsigned char sha1_bin[20];
+ char sha1_str[41];
+ _mesa_sha1_compute(prog->code, prog->binSize, sha1_bin);
+ _mesa_sha1_format(sha1_str, sha1_bin);
+ sha1_str[7] = 0;
+ strcat(fname, sha1_str);
+
+ switch (prog->getType()) {
+ case nv50_ir::Program::TYPE_VERTEX:
+ strcat(fname, ".vs");
+ break;
+ case nv50_ir::Program::TYPE_TESSELLATION_CONTROL:
+ strcat(fname, ".tcs");
+ break;
+ case nv50_ir::Program::TYPE_TESSELLATION_EVAL:
+ strcat(fname, ".tes");
+ break;
+ case nv50_ir::Program::TYPE_GEOMETRY:
+ strcat(fname, ".gs");
+ break;
+ case nv50_ir::Program::TYPE_FRAGMENT:
+ strcat(fname, ".fs");
+ break;
+ case nv50_ir::Program::TYPE_COMPUTE:
+ strcat(fname, ".cs");
+ break;
+ }
+
+ strcat(fname, ext);
+
+ return fname;
+}
+
+static void
+dumpProgram(nv50_ir::Program *prog)
+{
+ const char *dump_dir = debug_get_option("NV50_PROG_DUMP", NULL);
+ if (!dump_dir)
+ return;
+
+ char* fname = createDumpFilename(dump_dir, prog, ".bin");
+
+ FILE *fp = fopen(fname, "wb");
+ fwrite(prog->code, prog->binSize, 1, fp);
+ fclose(fp);
+
+ INFO("Dumped code of program %p to %s\n", prog, fname);
+
+ free(fname);
+
+ if (prog->driver->bin.sourceRep == PIPE_SHADER_IR_TGSI) {
+ char* fname = createDumpFilename(dump_dir, prog, ".tgsi.txt");
+ const struct tgsi_token *tokens;
+ tokens = (const struct tgsi_token *)prog->driver->bin.source;
+
+ FILE *fp = fopen(fname, "w");
+ tgsi_dump_to_file(tokens, 0, fp);
+ fclose(fp);
+
+ INFO("Dumped tgsi of program %p to %s\n", prog, fname);
+
+ free(fname);
+ }
+}
+
+static void
+replaceProgram(nv50_ir::Program *prog)
+{
+ const nv50_ir::Target* targ = prog->getTarget();
+
+ const char *replace_dir = debug_get_option("NV50_PROG_REPLACE", NULL);
+ if (!replace_dir)
+ return;
+
+ char* fname = createDumpFilename(replace_dir, prog, ".bin");
+
+ FILE *fp = fopen(fname, "rb");
+ if (!fp)
+ return;
+
+ FREE(prog->code);
+ prog->code = (uint32_t*)MALLOC(65536);
+ prog->binSize = fread(prog->code, 1, 65536, fp);
+
+ unsigned maxGPR = targ->getChipset() >= NVISA_GK20A_CHIPSET ? 254 : 62;
+ prog->maxGPR = MIN2(targ->getFileSize(nv50_ir::FILE_GPR), maxGPR);
+
+ fclose(fp);
+
+ INFO("Replaced code of program %p with that from %s\n", prog, fname);
+
+ free(fname);
+}
+#endif
+
} // namespace nv50_ir
@@ -1270,6 +1379,11 @@ nv50_ir_generate_code(struct nv50_ir_prog_info *info)
goto out;
}
+#ifdef DEBUG
+ nv50_ir::dumpProgram(prog);
+ nv50_ir::replaceProgram(prog);
+#endif
+
out:
INFO_DBG(prog->dbgFlags, VERBOSE, "nv50_ir_generate_code: ret = %i\n", ret);
--
2.14.3
More information about the mesa-dev
mailing list