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);
 }
 
+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;
+}
+
+#ifdef DEBUG
+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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to