[Mesa-dev] [PATCH 7/7] intel/aubinator: Support json output

Jordan Justen jordan.l.justen at intel.com
Tue Jan 10 01:22:18 UTC 2017


Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
---
 src/intel/tools/aubinator.c | 571 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 485 insertions(+), 86 deletions(-)

diff --git a/src/intel/tools/aubinator.c b/src/intel/tools/aubinator.c
index efd7c0496e3..a234e5a2cee 100644
--- a/src/intel/tools/aubinator.c
+++ b/src/intel/tools/aubinator.c
@@ -58,6 +58,7 @@
 
 static bool option_full_decode = true;
 static bool option_print_offsets = true;
+static bool json = false;
 static enum { COLOR_AUTO, COLOR_ALWAYS, COLOR_NEVER } option_color;
 
 /* state */
@@ -87,6 +88,136 @@ field(uint32_t value, int start, int end)
 
 struct brw_instruction;
 
+#define MAX_STACK_SIZE 10
+static char stack[MAX_STACK_SIZE] = { 0 };
+static bool stack_level_empty[MAX_STACK_SIZE] = { true };
+static int top_of_stack = 0;
+
+static void
+start_of_list_item(char start);
+
+static void
+yield_string_item(const char *str);
+
+static void
+yield_member_val_sep(void);
+
+static void
+enter_level(char start, const char *name)
+{
+   assert(top_of_stack < MAX_STACK_SIZE);
+   stack_level_empty[top_of_stack] = true;
+   stack[top_of_stack] = start;
+   stack[top_of_stack + 1] = 0;
+   if (json) {
+      if (top_of_stack > 0) {
+         start_of_list_item(stack[top_of_stack - 1]);
+      }
+      if (name != NULL) {
+         yield_string_item(name);
+         yield_member_val_sep();
+      }
+      printf("%c", start);
+   }
+   top_of_stack++;
+}
+
+static void
+exit_level(char start, char end)
+{
+   assert(top_of_stack > 0);
+   assert(stack[top_of_stack] == 0 && stack[top_of_stack - 1] == start);
+   stack[--top_of_stack] = 0;
+   if (json) {
+      if (!stack_level_empty[top_of_stack])
+         printf("\n%*s", 2 * top_of_stack, "");
+      fputc(end, stdout);
+   }
+}
+
+static void
+start_of_list_item(char start)
+{
+   const int stack_pos = top_of_stack - 1;
+   assert(stack_pos >= 0 && stack[stack_pos] == start);
+   if (stack_pos < 0)
+      return;
+   if (!stack_level_empty[stack_pos]) {
+      if (json)
+         printf(",");
+   } else {
+      stack_level_empty[stack_pos] = false;
+   }
+   if (json)
+      printf("\n%*s", 2 * top_of_stack, "");
+}
+
+static void
+end_of_list_item(char start, char end)
+{
+   const int stack_pos = top_of_stack - 1;
+   assert(stack_pos >= 0 && stack[stack_pos] == start);
+}
+
+static void
+enter_array(const char *name)
+{
+   enter_level('[', name);
+}
+
+static void
+exit_array()
+{
+   exit_level('[', ']');
+}
+
+static void
+start_of_array_element()
+{
+   start_of_list_item('[');
+}
+
+static void
+end_of_array_element()
+{
+   end_of_list_item('[', ']');
+}
+
+static void
+enter_object(const char *name)
+{
+   enter_level('{', name);
+}
+
+static void
+enter_numbered_object(const char *name, int i)
+{
+   char namebuf[20];
+   int len;
+
+   len = snprintf(namebuf, sizeof(namebuf), "%s %d", name, i);
+   assert(len < sizeof(namebuf));
+   enter_object(namebuf);
+}
+
+static void
+exit_object()
+{
+   exit_level('{', '}');
+}
+
+static void
+start_of_object_element()
+{
+   start_of_list_item('{');
+}
+
+static void
+end_of_object_element()
+{
+   end_of_list_item('{', '}');
+}
+
 static inline int
 valid_offset(uint32_t offset)
 {
@@ -94,7 +225,126 @@ valid_offset(uint32_t offset)
 }
 
 static void
-print_dword_val(struct gen_field_iterator *iter, uint64_t offset,
+yield_raw_string_item(const char *str)
+{
+   fputs(str, stdout);
+}
+
+static void
+yield_string_item(const char *str)
+{
+   if (json)
+      printf("\"%s\"", str);
+   else
+      yield_raw_string_item(str);
+}
+
+static void
+yield_numbered_item(const char *name, unsigned num)
+{
+   if (json)
+      printf("\"%s %u\"", name, num);
+   else
+      printf("%s %u", name, num);
+}
+
+static void
+yield_comment(const char *comment)
+{
+   printf(" %s", comment);
+}
+
+static void
+yield_hex_dword(uint32_t dword)
+{
+   if (json)
+      printf("%d", dword);
+   else
+      printf("%08x", dword);
+}
+
+static void
+yield_member_val_sep(void)
+{
+   printf(": ");
+}
+
+static void
+yield_str_val_desc(const char *name, const char *val, const char *desc)
+{
+   start_of_object_element();
+   yield_string_item(name);
+   yield_member_val_sep();
+   yield_string_item(val);
+   if (!json) {
+      if (desc != NULL && strlen(desc) > 0) {
+         printf(" (%s)", desc);
+      }
+   }
+   end_of_object_element();
+   if (!json)
+      printf("\n");
+}
+
+static void
+yield_str_val(const char *name, const char *val)
+{
+   yield_str_val_desc(name, val, NULL);
+}
+
+static void
+yield_iterator_value(struct gen_field_iterator *iter)
+{
+   if (!json)
+      yield_str_val_desc(iter->name, iter->value, iter->description);
+   else {
+      start_of_object_element();
+      yield_string_item(iter->name);
+      yield_member_val_sep();
+      yield_raw_string_item(iter->value);
+      end_of_object_element();
+   }
+}
+
+static void
+yield_packet_type(const char *ty)
+{
+   if (json)
+      yield_str_val("Type", ty);
+}
+
+static void
+yield_obj_start()
+{
+   printf("\n");
+}
+
+static void
+yield_numbered_dword(const char *name, uint32_t num, uint32_t dword)
+{
+   yield_numbered_item(name, num);
+   yield_member_val_sep();
+   yield_hex_dword(dword);
+}
+
+static void
+yield_named_dword(const char *name, uint32_t dword)
+{
+   start_of_object_element();
+   yield_string_item(name);
+   yield_member_val_sep();
+   yield_hex_dword(dword);
+   end_of_object_element();
+}
+
+static void
+yield_pointer(uint32_t pnum, uint32_t offset)
+{
+   yield_numbered_dword("pointer", pnum, offset);
+}
+
+static void
+yield_dword_val(struct gen_field_iterator *iter, uint64_t offset,
                 int *dword_num)
 {
    struct gen_field *f;
@@ -103,8 +353,9 @@ print_dword_val(struct gen_field_iterator *iter, uint64_t offset,
    const int dword = f->start / 32;
 
    if (*dword_num != dword) {
-      printf("0x%08"PRIx64":  0x%08x : Dword %d\n",
-             offset + 4 * dword,  iter->p[dword], dword);
+      if (!json)
+         printf("0x%08"PRIx64":  0x%08x : Dword %d\n",
+                offset + 4 * dword,  iter->p[dword], dword);
       *dword_num = dword;
    }
 }
@@ -114,12 +365,9 @@ print_iterator_values(struct gen_field_iterator *iter, int *idx)
 {
     char *token = NULL;
     if (strstr(iter->value, "struct") == NULL) {
-       if (strlen(iter->description) > 0) {
-          printf("    %s: %s (%s)\n",
-                 iter->name, iter->value, iter->description);
-       } else {
-          printf("    %s: %s\n", iter->name, iter->value);
-       }
+       if (!json)
+          printf("    ");
+       yield_iterator_value(iter);
     } else {
         token = strtok(iter->value, " ");
         if (token != NULL) {
@@ -128,11 +376,37 @@ print_iterator_values(struct gen_field_iterator *iter, int *idx)
         } else {
             token = NULL;
         }
-        printf("    %s:<struct %s>\n", iter->name, token);
+        if (!json)
+           printf("    %s:<struct %s>\n", iter->name, token);
     }
     return token;
 }
 
+static uint32_t
+get_index_array_element(const void *array, uint32_t type, uint32_t index)
+{
+   assert(type < 3);
+   return type == 0 ? ((uint8_t *)array)[index] :
+      (type == 1 ? ((uint16_t *)array)[index] : ((uint32_t *)array)[index]);
+}
+
+static void
+yield_index_array(const void *array, uint32_t length, uint32_t type)
+{
+   uint32_t i;
+   uint32_t print_length = MIN2(10, length);
+
+   printf("\t");
+
+   for (i = 0; i < print_length; i++) {
+      printf("%3d ", get_index_array_element(array, type, i));
+   }
+   if (print_length < length)
+      printf("...\n");
+   else
+      printf("\n");
+}
+
 static void
 decode_structure(struct gen_spec *spec, struct gen_group *strct,
                  const uint32_t *p)
@@ -148,26 +422,31 @@ decode_structure(struct gen_spec *spec, struct gen_group *strct,
       offset = 0;
 
    gen_field_iterator_init(&iter, strct, p,
-                           option_color == COLOR_ALWAYS, false);
+                           option_color == COLOR_ALWAYS, json);
    while (gen_field_iterator_next(&iter)) {
       idx = 0;
-      print_dword_val(&iter, offset, &dword_num);
+      yield_dword_val(&iter, offset, &dword_num);
       token = print_iterator_values(&iter, &idx);
       if (token != NULL) {
          struct gen_group *struct_val = gen_spec_find_struct(spec, token);
+         enter_object(iter.name);
          decode_structure(spec, struct_val, &p[idx]);
+         exit_object();
          token = NULL;
       }
    }
 }
 
 static void
-handle_struct_decode(struct gen_spec *spec, char *struct_name, uint32_t *p)
+handle_struct_decode(struct gen_spec *spec, char *struct_name, uint32_t *p,
+                     const char *field)
 {
    if (struct_name == NULL)
       return;
    struct gen_group *struct_val = gen_spec_find_struct(spec, struct_name);
+   enter_object(field);
    decode_structure(spec, struct_val, p);
+   exit_object();
 }
 
 static void
@@ -185,54 +464,48 @@ dump_binding_table(struct gen_spec *spec, uint32_t offset)
 
    start = surface_state_base + offset;
    pointers = gtt + start;
+   int count = 0;
+   for (i = 0; i < 16; i++) {
+      if (pointers[i] != 0)
+         count++;
+   }
+   if (count == 0)
+      return;
+
+   bool valid = true;
+   enter_object(NULL);
+   yield_packet_type("RENDER_SURFACE_STATE");
    for (i = 0; i < 16; i++) {
       if (pointers[i] == 0)
          continue;
       start = pointers[i] + surface_state_base;
-      if (!valid_offset(start)) {
-         printf("pointer %u: %08x <not valid>\n",
-                i, pointers[i]);
-         continue;
-      } else {
-         printf("pointer %u: %08x\n", i, pointers[i]);
+      enter_numbered_object("pointer", i);
+      valid = valid_offset(start);
+      if (!json) {
+         yield_pointer(i, pointers[i]);
+         if (!valid)
+            yield_comment("<not valid>");
+         yield_obj_start();
       }
-
-      decode_structure(spec, surface_state, gtt + start);
+      if (valid)
+         decode_structure(spec, surface_state, gtt + start);
+      exit_object();
    }
+   exit_object();
 }
 
 static void
 handle_3dstate_index_buffer(struct gen_spec *spec, uint32_t *p)
 {
    void *start;
-   uint32_t length, i, type, size;
+   uint32_t length, type, size;
 
    start = gtt + p[2];
    type = (p[1] >> 8) & 3;
    size = 1 << type;
    length = p[4] / size;
-   if (length > 10)
-      length = 10;
-
-   printf("\t");
 
-   for (i = 0; i < length; i++) {
-      switch (type) {
-      case 0:
-         printf("%3d ", ((uint8_t *)start)[i]);
-         break;
-      case 1:
-         printf("%3d ", ((uint16_t *)start)[i]);
-         break;
-      case 2:
-         printf("%3d ", ((uint32_t *)start)[i]);
-         break;
-      }
-   }
-   if (length < p[4] / size)
-      printf("...\n");
-   else
-      printf("\n");
+   yield_index_array(start, length, type);
 }
 
 static inline uint64_t
@@ -306,20 +579,49 @@ dump_samplers(struct gen_spec *spec, uint32_t offset)
 
    sampler_state = gen_spec_find_struct(spec, "SAMPLER_STATE");
 
+   enter_object(NULL);
+   yield_packet_type("SAMPLER_STATE");
    start = dynamic_state_base + offset;
    for (i = 0; i < 4; i++) {
-      printf("sampler state %d\n", i);
+      if (!json) {
+         yield_numbered_item("sampler state", i);
+         yield_obj_start();
+      }
+      enter_numbered_object("sampler state", i);
       decode_structure(spec, sampler_state, gtt + start + i * 16);
+      exit_object();
    }
+   exit_object();
 }
 
 static void
-print_gen_disassembly(struct gen_disasm *disasm, void *assembly, int start)
+print_gen_disassembly(struct gen_disasm *disasm, void *assembly, int start,
+                      const char *kernel_type)
 {
    char *disasm_str;
    gen_disasm_disassemble(disasm, assembly, start, &disasm_str);
    if (disasm_str) {
-      fputs(disasm_str, stdout);
+      enter_object(NULL);
+      if (!json)
+         fputs(disasm_str, stdout);
+      else {
+         char *sol = disasm_str, *eol;
+         yield_packet_type("Kernel");
+         yield_str_val("Kernel Type", kernel_type);
+         enter_array("Disassembly");
+         do {
+            eol = strchr(sol, '\n');
+            if (eol != NULL)
+               *eol = '\0';
+            start_of_array_element();
+            yield_string_item(sol);
+            if (eol != NULL)
+               sol = eol + 1;
+            end_of_array_element(); 
+         } while (eol != NULL && *sol != '\0');
+         exit_array();
+      }
+      exit_object();
       free(disasm_str);
    }
 }
@@ -343,19 +645,25 @@ handle_media_interface_descriptor_load(struct gen_spec *spec, uint32_t *p)
    start = dynamic_state_base + p[3];
    descriptors = gtt + start;
    for (i = 0; i < length; i++, descriptors += 8) {
-      printf("descriptor %u: %08x\n", i, *descriptors);
+      if (!json)
+         printf("descriptor %u: %08x\n", i, *descriptors);
+      enter_object(NULL);
+      yield_packet_type("INTERFACE_DESCRIPTOR_DATA");
       decode_structure(spec, descriptor_structure, descriptors);
+      exit_object();
 
       start = instruction_base + descriptors[0];
       if (!valid_offset(start)) {
-         printf("kernel: %08"PRIx64" <not valid>\n", start);
+         if (!json)
+            printf("kernel: %08"PRIx64" <not valid>\n", start);
          continue;
       } else {
-         printf("kernel: %08"PRIx64"\n", start);
+         if (!json)
+            printf("kernel: %08"PRIx64"\n", start);
       }
 
       insns = (struct brw_instruction *) (gtt + start);
-      print_gen_disassembly(disasm, insns, 0);
+      print_gen_disassembly(disasm, insns, 0, "compute");
 
       dump_samplers(spec, descriptors[3] & ~0x1f);
       dump_binding_table(spec, descriptors[4] & ~0x1f);
@@ -394,6 +702,10 @@ handle_3dstate_vertex_buffers(struct gen_spec *spec, uint32_t *p)
    uint64_t offset;
    int n, i, count, stride;
 
+   /* TODO: Output some vertex data with json */
+   if (json)
+      return;
+
    end = (p[0] & 0xff) + p + 2;
    for (s = &p[1], n = 0; s < end; s += 4, n++) {
       if (gen_spec_get_gen(spec) >= gen_make_gen(8, 0)) {
@@ -449,11 +761,12 @@ handle_3dstate_vs(struct gen_spec *spec, uint32_t *p)
    }
 
    if (vs_enable) {
-      printf("instruction_base %08"PRIx64", start %08"PRIx64"\n",
-             instruction_base, start);
+      if (!json)
+         printf("instruction_base %08"PRIx64", start %08"PRIx64"\n",
+                instruction_base, start);
 
       insns = (struct brw_instruction *) (gtt + instruction_base + start);
-      print_gen_disassembly(disasm, insns, 0);
+      print_gen_disassembly(disasm, insns, 0, "vertex");
    }
 }
 
@@ -473,11 +786,12 @@ handle_3dstate_hs(struct gen_spec *spec, uint32_t *p)
    hs_enable = p[2] & 0x80000000;
 
    if (hs_enable) {
-      printf("instruction_base %08"PRIx64", start %08"PRIx64"\n",
-             instruction_base, start);
+      if (!json)
+         printf("instruction_base %08"PRIx64", start %08"PRIx64"\n",
+                instruction_base, start);
 
       insns = (struct brw_instruction *) (gtt + instruction_base + start);
-      print_gen_disassembly(disasm, insns, 0);
+      print_gen_disassembly(disasm, insns, 0, "tessellation control");
    }
 }
 
@@ -488,6 +802,10 @@ handle_3dstate_constant(struct gen_spec *spec, uint32_t *p)
    uint32_t *dw;
    float *f;
 
+   /* TODO: Output some push constant data with json */
+   if (json)
+      return;
+
    for (i = 0; i < 4; i++) {
       length = (p[1 + i / 2] >> (i & 1) * 16) & 0xffff;
       f = (float *) (gtt + p[3 + i * 2] + dynamic_state_base);
@@ -512,6 +830,7 @@ handle_3dstate_ps(struct gen_spec *spec, uint32_t *p)
    struct brw_instruction *insns;
    static const char unused[] = "unused";
    static const char *pixel_type[3] = {"8 pixel", "16 pixel", "32 pixel"};
+   char kernel_desc[20];
    const char *k0, *k1, *k2;
    uint32_t k_mask, k1_offset, k2_offset;
 
@@ -568,24 +887,30 @@ handle_3dstate_ps(struct gen_spec *spec, uint32_t *p)
    }
 
    start = instruction_base + (p[1] & mask);
-   printf("  Kernel[0] %s\n", k0);
+   snprintf(kernel_desc, sizeof(kernel_desc), "Kernel[0] %s", k0);
+   if (!json)
+      printf("  %s\n", kernel_desc);
    if (k0 != unused) {
       insns = (struct brw_instruction *) (gtt + start);
-      print_gen_disassembly(disasm, insns, 0);
+      print_gen_disassembly(disasm, insns, 0, kernel_desc);
    }
 
    start = instruction_base + (p[k1_offset] & mask);
-   printf("  Kernel[1] %s\n", k1);
+   snprintf(kernel_desc, sizeof(kernel_desc), "Kernel[1] %s", k1);
+   if (!json)
+      printf("  %s\n", kernel_desc);
    if (k1 != unused) {
       insns = (struct brw_instruction *) (gtt + start);
-      print_gen_disassembly(disasm, insns, 0);
+      print_gen_disassembly(disasm, insns, 0, kernel_desc);
    }
 
    start = instruction_base + (p[k2_offset] & mask);
-   printf("  Kernel[2] %s\n", k2);
+   snprintf(kernel_desc, sizeof(kernel_desc), "Kernel[2] %s", k2);
+   if (!json)
+      printf("  %s\n", kernel_desc);
    if (k2 != unused) {
       insns = (struct brw_instruction *) (gtt + start);
-      print_gen_disassembly(disasm, insns, 0);
+      print_gen_disassembly(disasm, insns, 0, kernel_desc);
    }
 }
 
@@ -610,10 +935,16 @@ handle_3dstate_viewport_state_pointers_cc(struct gen_spec *spec, uint32_t *p)
    cc_viewport = gen_spec_find_struct(spec, "CC_VIEWPORT");
 
    start = dynamic_state_base + (p[1] & ~0x1fu);
+   enter_object(NULL);
+   yield_packet_type("CC_VIEWPORT");
    for (uint32_t i = 0; i < 4; i++) {
-      printf("viewport %d\n", i);
+      if (!json)
+         printf("viewport %d\n", i);
+      enter_numbered_object("viewport", i);
       decode_structure(spec, cc_viewport, gtt + start + i * 8);
+      exit_object();
    }
+   exit_object();
 }
 
 static void
@@ -626,10 +957,16 @@ handle_3dstate_viewport_state_pointers_sf_clip(struct gen_spec *spec,
    sf_clip_viewport = gen_spec_find_struct(spec, "SF_CLIP_VIEWPORT");
 
    start = dynamic_state_base + (p[1] & ~0x3fu);
+   enter_object(NULL);
+   yield_packet_type("SF_CLIP_VIEWPORT");
    for (uint32_t i = 0; i < 4; i++) {
-      printf("viewport %d\n", i);
+      if (!json)
+         printf("viewport %d\n", i);
+      enter_numbered_object("viewport", i);
       decode_structure(spec, sf_clip_viewport, gtt + start + i * 64);
+      exit_object();
    }
+   exit_object();
 }
 
 static void
@@ -641,7 +978,10 @@ handle_3dstate_blend_state_pointers(struct gen_spec *spec, uint32_t *p)
    blend_state = gen_spec_find_struct(spec, "BLEND_STATE");
 
    start = dynamic_state_base + (p[1] & ~0x3fu);
+   enter_object(NULL);
+   yield_packet_type("BLEND_STATE");
    decode_structure(spec, blend_state, gtt + start);
+   exit_object();
 }
 
 static void
@@ -653,7 +993,10 @@ handle_3dstate_cc_state_pointers(struct gen_spec *spec, uint32_t *p)
    cc_state = gen_spec_find_struct(spec, "COLOR_CALC_STATE");
 
    start = dynamic_state_base + (p[1] & ~0x3fu);
+   enter_object(NULL);
+   yield_packet_type("COLOR_CALC_STATE");
    decode_structure(spec, cc_state, gtt + start);
+   exit_object();
 }
 
 static void
@@ -665,7 +1008,10 @@ handle_3dstate_scissor_state_pointers(struct gen_spec *spec, uint32_t *p)
    scissor_rect = gen_spec_find_struct(spec, "SCISSOR_RECT");
 
    start = dynamic_state_base + (p[1] & ~0x1fu);
+   enter_object(NULL);
+   yield_packet_type("SCISSOR_RECT");
    decode_structure(spec, scissor_rect, gtt + start);
+   exit_object();
 }
 
 static void
@@ -674,9 +1020,15 @@ handle_load_register_imm(struct gen_spec *spec, uint32_t *p)
    struct gen_group *reg = gen_spec_find_register(spec, p[1]);
 
    if (reg != NULL) {
-      printf("register %s (0x%x): 0x%x\n",
-             reg->name, reg->register_offset, p[2]);
+      if (!json)
+         printf("register %s (0x%x): 0x%x\n",
+                reg->name, reg->register_offset, p[2]);
+      enter_object(NULL);
+      yield_packet_type("Load Register Immediate");
+      if (json)
+         yield_str_val("Register Name", reg->name);
       decode_structure(spec, reg, &p[2]);
+      exit_object();
    }
 }
 
@@ -763,11 +1115,23 @@ parse_commands(struct gen_spec *spec, uint32_t *cmds, int size, int engine)
    uint32_t *p, *end = cmds + size / 4;
    unsigned int length, i;
    struct gen_group *inst;
+   const char *inst_name;
 
    for (p = cmds; p < end; p += length) {
       inst = gen_spec_find_instruction(spec, p);
       if (inst == NULL) {
-         printf("unknown instruction %08x\n", p[0]);
+         enter_object(NULL);
+         if (!json)
+            printf("unknown instruction %08x\n", p[0]);
+         else {
+            uint32_t cmd = field(p[0], 29, 31);
+            yield_packet_type("unknown instruction");
+            yield_named_dword("Command", p[0]);
+            yield_named_dword("Command Type", cmd);
+            yield_named_dword("Command Opcode",
+                              field(p[0], cmd == 2 ? 22 : 23, 28));
+         }
+         exit_object();
          length = (p[0] & 0xff) + 2;
          continue;
       }
@@ -795,28 +1159,39 @@ parse_commands(struct gen_spec *spec, uint32_t *cmds, int size, int engine)
       else
          offset = 0;
 
-      printf("%s0x%08"PRIx64":  0x%08x:  %-80s%s\n",
-             color, offset, p[0],
-             gen_group_get_name(inst), reset_color);
+      inst_name = gen_group_get_name(inst);
+      if (!json)
+         printf("%s0x%08"PRIx64":  0x%08x:  %-80s%s\n",
+                color, offset, p[0], inst_name, reset_color);
 
       if (option_full_decode) {
          struct gen_field_iterator iter;
          char *token = NULL;
          int idx = 0, dword_num = 0;
+         bool empty_object = true;
          gen_field_iterator_init(&iter, inst, p,
-                                 option_color == COLOR_ALWAYS, false);
+                                 option_color == COLOR_ALWAYS, json);
          while (gen_field_iterator_next(&iter)) {
             idx = 0;
-            print_dword_val(&iter, offset, &dword_num);
-            if (dword_num > 0)
+            yield_dword_val(&iter, offset, &dword_num);
+            if (dword_num > 0) {
+                if (empty_object) {
+                   enter_object(NULL);
+                   yield_packet_type(inst_name);
+                   empty_object = false;
+                }
                 token = print_iterator_values(&iter, &idx);
+            }
             if (token != NULL) {
-                printf("0x%08"PRIx64":  0x%08x : Dword %d\n",
-                       offset + 4 * idx, p[idx], idx);
-                handle_struct_decode(spec,token, &p[idx]);
+                if (!json)
+                   printf("0x%08"PRIx64":  0x%08x : Dword %d\n",
+                          offset + 4 * idx, p[idx], idx);
+                handle_struct_decode(spec,token, &p[idx], iter.name);
                 token = NULL;
             }
          }
+         if (!empty_object)
+            exit_object();
 
          for (i = 0; i < ARRAY_LENGTH(custom_handlers); i++) {
             if (gen_group_get_opcode(inst) ==
@@ -932,24 +1307,44 @@ handle_trace_header(uint32_t *p)
    if (spec == NULL || disasm == NULL)
       exit(EXIT_FAILURE);
 
-   printf("%sAubinator: Intel AUB file decoder.%-80s%s\n",
-          GREEN_HEADER, "", NORMAL);
+   enter_object(NULL);
+   yield_packet_type("Header");
 
-   if (input_file)
-      printf("File name:        %s\n", input_file);
+   if (!json)
+      printf("%sAubinator: Intel AUB file decoder.%-80s%s\n",
+             GREEN_HEADER, "", NORMAL);
+   else
+      yield_str_val("Aubinator", "Intel AUB file decoder");
 
-   if (aub_pci_id)
-      printf("PCI ID:           0x%x\n", aub_pci_id);
+   if (input_file) {
+      if (!json)
+         printf("File name:        %s\n", input_file);
+      else
+         yield_str_val("File name", input_file);
+   }
+
+   if (aub_pci_id) {
+      if (!json)
+         printf("PCI ID:           0x%x\n", aub_pci_id);
+      else
+         yield_named_dword("PCI ID", aub_pci_id);
+   }
 
    char app_name[33];
    strncpy(app_name, (char *)&p[2], 32);
    app_name[32] = 0;
-   printf("Application name: %s\n", app_name);
+   yield_str_val("Application name", app_name);
 
-   printf("Decoding as:      %s\n", gen_get_device_name(pci_id));
+   if (!json)
+      printf("Decoding as:      %s\n", gen_get_device_name(pci_id));
+   else
+      yield_str_val("Decoding as", gen_get_device_name(pci_id));
 
    /* Throw in a new line before the first batch */
-   printf("\n");
+   if (!json)
+      printf("\n");
+
+   exit_object();
 }
 
 struct aub_file {
@@ -1218,7 +1613,8 @@ print_help(const char *progname, FILE *file)
            "                        if omitted), 'always', or 'never'\n"
            "      --no-pager      don't launch pager\n"
            "      --no-offsets    don't print instruction offsets\n"
-           "      --xml=DIR       load hardware xml description from directory DIR\n",
+           "      --xml=DIR       load hardware xml description from directory DIR\n"
+           "      --json          output results in json format\n",
            progname);
 }
 
@@ -1246,6 +1642,7 @@ int main(int argc, char *argv[])
       { "no-offsets", no_argument,       (int *) &option_print_offsets, false },
       { "gen",        required_argument, NULL,                          'g' },
       { "headers",    no_argument,       (int *) &option_full_decode,   false },
+      { "json",       no_argument,       (int *) &json,                 true },
       { "color",      required_argument, NULL,                          'c' },
       { "xml",        required_argument, NULL,                          'x' },
       { NULL,         0,                 NULL,                          0 }
@@ -1316,6 +1713,7 @@ int main(int argc, char *argv[])
       exit(EXIT_FAILURE);
    }
 
+   enter_array(NULL);
    while (aub_file_more_stuff(file)) {
       switch (aub_file_decode_batch(file)) {
       case AUB_ITEM_DECODE_OK:
@@ -1335,6 +1733,7 @@ int main(int argc, char *argv[])
          exit(EXIT_FAILURE);
       }
    }
+   exit_array();
 
 
    fflush(stdout);
-- 
2.11.0



More information about the mesa-dev mailing list