[Mesa-dev] [PATCH 15/16] intel/tools: add command line GEN shader disassembler tool

kevin.rogovin at intel.com kevin.rogovin at intel.com
Tue Dec 12 07:44:16 UTC 2017


From: Kevin Rogovin <kevin.rogovin at intel.com>

Signed-off-by: Kevin Rogovin <kevin.rogovin at intel.com>
---
 src/intel/Makefile.tools.am               |  21 ++-
 src/intel/tools/.gitignore                |   1 +
 src/intel/tools/gen_shader_disassembler.c | 213 ++++++++++++++++++++++++++++++
 3 files changed, 234 insertions(+), 1 deletion(-)
 create mode 100644 src/intel/tools/gen_shader_disassembler.c

diff --git a/src/intel/Makefile.tools.am b/src/intel/Makefile.tools.am
index a86e76653b..1ccf5a35cc 100644
--- a/src/intel/Makefile.tools.am
+++ b/src/intel/Makefile.tools.am
@@ -32,7 +32,8 @@ intellib_LTLIBRARIES = \
 
 intelbin_PROGRAMS = tools/i965_batchbuffer_dump_show \
 	tools/i965_batchbuffer_dump_show_xml \
-	tools/i965_batchbuffer_dump_show_json
+	tools/i965_batchbuffer_dump_show_json \
+	tools/gen_shader_disassembler
 
 intelbin_SCRIPTS = tools/i965_batchbuffer_logger_sh
 CLEANFILES += $(intelbin_SCRIPTS)
@@ -111,3 +112,21 @@ tools_i965_batchbuffer_dump_show_xml_SOURCES = \
 
 tools_i965_batchbuffer_dump_show_json_SOURCES = \
 	tools/i965_batchbuffer_dump_show_json.cpp
+
+tools_gen_shader_disassembler_SOURCES = \
+	tools/gen_shader_disassembler.c \
+	tools/disasm.c \
+	tools/gen_disasm.h
+
+tools_gen_shader_disassembler_LDADD = \
+	common/libintel_common.la \
+	compiler/libintel_compiler.la \
+	$(top_builddir)/src/util/libmesautil.la \
+	$(PTHREAD_LIBS) \
+	$(EXPAT_LIBS) \
+	$(ZLIB_LIBS)
+
+tools_gen_shader_disassembler_CFLAGS = \
+	$(AM_CFLAGS) \
+	$(EXPAT_CFLAGS) \
+	$(ZLIB_CFLAGS)
diff --git a/src/intel/tools/.gitignore b/src/intel/tools/.gitignore
index ea4dc23c20..e9b22c89aa 100644
--- a/src/intel/tools/.gitignore
+++ b/src/intel/tools/.gitignore
@@ -4,3 +4,4 @@
 /i965_batchbuffer_dump_show
 /i965_batchbuffer_dump_show_xml
 /i965_batchbuffer_dump_show_json
+/gen_shader_disassembler
diff --git a/src/intel/tools/gen_shader_disassembler.c b/src/intel/tools/gen_shader_disassembler.c
new file mode 100644
index 0000000000..070c588d54
--- /dev/null
+++ b/src/intel/tools/gen_shader_disassembler.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright © 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <getopt.h>
+#include <strings.h>
+
+#include "compiler/brw_inst.h"
+#include "compiler/brw_eu.h"
+
+static void
+print_opcodes(const void *data, int data_sz,
+              struct gen_device_info *devinfo,
+              bool print_offsets)
+{
+   for (int offset = 0; offset < data_sz;) {
+      const brw_inst *insn = data + offset;
+      bool compacted;
+      brw_inst uncompacted;
+      enum opcode opcode;
+      const struct opcode_desc *desc;
+
+      if (print_offsets) {
+         printf("0x%08x: ", offset);
+      }
+
+      compacted = brw_inst_cmpt_control(devinfo, insn);
+      if (compacted) {
+         brw_compact_inst *compacted_insn = (brw_compact_inst *)insn;
+         brw_uncompact_instruction(devinfo, &uncompacted, compacted_insn);
+         insn = &uncompacted;
+         offset += 8;
+      } else {
+         offset += 16;
+      }
+
+      opcode = brw_inst_opcode(devinfo, insn);
+      desc = brw_opcode_desc(devinfo, opcode);
+      if (desc) {
+         printf("(0x%08x) %s", opcode, desc->name);
+      } else {
+         printf("(0x%08x) UnknownOpcode", opcode);
+      }
+
+      if (compacted) {
+         printf(" {compacted}");
+      }
+
+      printf("\n");
+   }
+}
+
+static void
+print_disassembly(const void *data, int data_sz,
+                  struct gen_device_info *devinfo,
+                  bool print_offsets)
+{
+   struct disasm_info *disasm_info = disasm_initialize(devinfo, NULL);
+   disasm_new_inst_group(disasm_info, 0);
+   disasm_new_inst_group(disasm_info, data_sz);
+
+   brw_validate_instructions(devinfo, data, 0, data_sz, disasm_info);
+
+   foreach_list_typed_safe(struct inst_group, group, link,
+                           &disasm_info->group_list) {
+      if (exec_node_is_tail_sentinel(exec_node_get_next(&group->link)))
+         break;
+
+      struct inst_group *next =
+         exec_node_data(struct inst_group,
+                        exec_node_get_next(&group->link), link);
+
+      int start_offset = group->offset;
+      int end_offset = next->offset;
+
+      brw_disassemble(devinfo, data, start_offset,
+                      end_offset, print_offsets, stdout);
+
+      if (group->error) {
+         fputs(group->error, stdout);
+      }
+   }
+
+   ralloc_free(disasm_info);
+}
+
+static
+void
+print_help(FILE *p, const char *argv0)
+{
+   fprintf(p, "Usage: %s [OPTION] ShaderBinary\n"
+           "  -p   PCI ID of GPU for which shader binary was generated, must be given;\n"
+           "       if the value is of the form 0xVALUE, then read the value as hex;\n"
+           "       if the value is of the form 0VALUE, then read the value as oct;\n"
+           "       otherwise read the value as decimal\n"
+           "  -c   Print opcodes only instead of disassembly\n"
+           "  -o   Print offsets into ShaderBinary\n"
+           "  -h   Print this help message and quit\n", argv0);
+}
+
+int
+main(int argc, char **argv)
+{
+   const char *short_options = "p:och";
+   FILE *file;
+   void *data;
+   int data_sz, pci_id, data_read;
+   bool pci_id_provided = false, print_opcodes_only = false;
+   bool print_offsets = false;
+   struct gen_device_info devinfo;
+
+   int opt;
+   while ((opt = getopt(argc, argv, short_options)) != -1) {
+      switch(opt) {
+      case 'p':
+         pci_id_provided = true;
+         pci_id = strtol(optarg, NULL, 0);
+         break;
+      case 'c':
+         print_opcodes_only = true;
+         break;
+      case 'o':
+         print_offsets = true;
+         break;
+      case 'h':
+         print_help(stdout, argv[0]);
+         return 0;
+      default:
+         fprintf(stderr, "Unknown option '%c'\n", (char)opt);
+         print_help(stderr, argv[0]);
+         return -1;
+      }
+   }
+
+   if (optind >= argc) {
+      fprintf(stderr, "Need to proviade ShaderBinary file.\n");
+      print_help(stderr, argv[0]);
+      return -1;
+   }
+
+   if (!pci_id_provided) {
+      fprintf(stderr, "Need to provide PCI ID with -p option\n");
+      return -1;
+   }
+
+   if(!gen_get_device_info(pci_id, &devinfo)) {
+      fprintf(stderr, "Bad PCIID 0x%x given, aborting\n", pci_id);
+      return -1;
+   }
+
+   file = fopen(argv[optind], "r");
+   if (file == NULL) {
+      fprintf(stderr, "Unable to open file \"%s\" for reading, aborting\n",
+              argv[optind]);
+      return -1;
+   }
+
+   fseek(file, 0, SEEK_END);
+   data_sz = ftell(file);
+   fseek(file, 0, SEEK_SET);
+
+   data = malloc(data_sz);
+   if (data == NULL) {
+      fprintf(stderr,
+              "Failed to allocate %d bytes to hold file contents.\n",
+              data_sz);
+      return -1;
+   }
+
+   data_read = fread(data, 1, data_sz, file);
+   if (data_read != data_sz) {
+      fprintf(stderr,
+              "Failed to read entire file \"%s\", read %d of %d bytes\n",
+              argv[optind], data_read, data_sz);
+      free(data);
+      fclose(file);
+      return -1;
+   }
+
+   brw_init_compaction_tables(&devinfo);
+   if (print_opcodes_only) {
+      print_opcodes(data, data_sz, &devinfo, print_offsets);
+   } else {
+      print_disassembly(data, data_sz, &devinfo, print_offsets);
+   }
+
+   free(data);
+   fclose(file);
+   return 0;
+}
-- 
2.15.0



More information about the mesa-dev mailing list