intel/compiler: Get rid of struct gen_disasm
[mesa.git] / src / intel / tools / aubinator_viewer_decoder.cpp
index 273bc2da376f06ba4c666ad8ebfd8f427296003e..8d63eaa6b06439edea8f1a42bac2b7dc7b228478 100644 (file)
@@ -31,9 +31,9 @@ void
 aub_viewer_decode_ctx_init(struct aub_viewer_decode_ctx *ctx,
                            struct aub_viewer_cfg *cfg,
                            struct aub_viewer_decode_cfg *decode_cfg,
+                           const struct gen_device_info *devinfo,
                            struct gen_spec *spec,
-                           struct gen_disasm *disasm,
-                           struct gen_batch_decode_bo (*get_bo)(void *, uint64_t),
+                           struct gen_batch_decode_bo (*get_bo)(void *, bool, uint64_t),
                            unsigned (*get_state_size)(void *, uint32_t),
                            void *user_data)
 {
@@ -42,11 +42,12 @@ aub_viewer_decode_ctx_init(struct aub_viewer_decode_ctx *ctx,
    ctx->get_bo = get_bo;
    ctx->get_state_size = get_state_size;
    ctx->user_data = user_data;
+   ctx->devinfo = devinfo;
+   ctx->engine = I915_ENGINE_CLASS_RENDER;
 
    ctx->cfg = cfg;
    ctx->decode_cfg = decode_cfg;
    ctx->spec = spec;
-   ctx->disasm = disasm;
 }
 
 static void
@@ -65,7 +66,7 @@ aub_viewer_print_group(struct aub_viewer_decode_ctx *ctx,
          if (last_dword != iter_dword) {
             for (int i = last_dword + 1; i <= iter_dword; i++) {
                ImGui::TextColored(ctx->cfg->dwords_color,
-                                  "0x%08" PRIx64 ":  0x%08x : Dword %d",
+                                  "0x%012" PRIx64 ":  0x%012x : Dword %d",
                                   address + 4 * i, iter.p[i], i);
             }
             last_dword = iter_dword;
@@ -73,7 +74,12 @@ aub_viewer_print_group(struct aub_viewer_decode_ctx *ctx,
       }
       if (!gen_field_is_header(iter.field)) {
          if (ctx->decode_cfg->field_filter.PassFilter(iter.name)) {
-            ImGui::Text("%s: %s", iter.name, iter.value);
+            if (iter.field->type.kind == gen_type::GEN_TYPE_BOOL && iter.raw_value) {
+               ImGui::Text("%s: ", iter.name); ImGui::SameLine();
+               ImGui::TextColored(ctx->cfg->boolean_color, "true");
+            } else {
+               ImGui::Text("%s: %s", iter.name, iter.value);
+            }
             if (iter.struct_desc) {
                int struct_dword = iter.start_bit / 32;
                uint64_t struct_address = address + 4 * struct_dword;
@@ -86,7 +92,7 @@ aub_viewer_print_group(struct aub_viewer_decode_ctx *ctx,
 }
 
 static struct gen_batch_decode_bo
-ctx_get_bo(struct aub_viewer_decode_ctx *ctx, uint64_t addr)
+ctx_get_bo(struct aub_viewer_decode_ctx *ctx, bool ppgtt, uint64_t addr)
 {
    if (gen_spec_get_gen(ctx->spec) >= gen_make_gen(8,0)) {
       /* On Broadwell and above, we have 48-bit addresses which consume two
@@ -98,7 +104,7 @@ ctx_get_bo(struct aub_viewer_decode_ctx *ctx, uint64_t addr)
       addr &= (~0ull >> 16);
    }
 
-   struct gen_batch_decode_bo bo = ctx->get_bo(ctx->user_data, addr);
+   struct gen_batch_decode_bo bo = ctx->get_bo(ctx->user_data, ppgtt, addr);
 
    if (gen_spec_get_gen(ctx->spec) >= gen_make_gen(8,0))
       bo.addr &= (~0ull >> 16);
@@ -138,9 +144,10 @@ ctx_disassemble_program(struct aub_viewer_decode_ctx *ctx,
                         uint32_t ksp, const char *type)
 {
    uint64_t addr = ctx->instruction_base + ksp;
-   struct gen_batch_decode_bo bo = ctx_get_bo(ctx, addr);
+   struct gen_batch_decode_bo bo = ctx_get_bo(ctx, true, addr);
    if (!bo.map) {
-      ImGui::TextColored(ctx->cfg->missing_color, "Shader unavailable");
+      ImGui::TextColored(ctx->cfg->missing_color,
+                         "Shader unavailable addr=0x%012" PRIx64, addr);
       return;
    }
 
@@ -158,15 +165,33 @@ handle_state_base_address(struct aub_viewer_decode_ctx *ctx,
    struct gen_field_iterator iter;
    gen_field_iterator_init(&iter, inst, p, 0, false);
 
+   uint64_t surface_base = 0, dynamic_base = 0, instruction_base = 0;
+   bool surface_modify = 0, dynamic_modify = 0, instruction_modify = 0;
+
    while (gen_field_iterator_next(&iter)) {
       if (strcmp(iter.name, "Surface State Base Address") == 0) {
-         ctx->surface_base = iter.raw_value;
+         surface_base = iter.raw_value;
       } else if (strcmp(iter.name, "Dynamic State Base Address") == 0) {
-         ctx->dynamic_base = iter.raw_value;
+         dynamic_base = iter.raw_value;
       } else if (strcmp(iter.name, "Instruction Base Address") == 0) {
-         ctx->instruction_base = iter.raw_value;
+         instruction_base = iter.raw_value;
+      } else if (strcmp(iter.name, "Surface State Base Address Modify Enable") == 0) {
+         surface_modify = iter.raw_value;
+      } else if (strcmp(iter.name, "Dynamic State Base Address Modify Enable") == 0) {
+         dynamic_modify = iter.raw_value;
+      } else if (strcmp(iter.name, "Instruction Base Address Modify Enable") == 0) {
+         instruction_modify = iter.raw_value;
       }
    }
+
+   if (dynamic_modify)
+      ctx->dynamic_base = dynamic_base;
+
+   if (surface_modify)
+      ctx->surface_base = surface_base;
+
+   if (instruction_modify)
+      ctx->instruction_base = instruction_base;
 }
 
 static void
@@ -188,11 +213,11 @@ dump_binding_table(struct aub_viewer_decode_ctx *ctx, uint32_t offset, int count
    }
 
    struct gen_batch_decode_bo bind_bo =
-      ctx_get_bo(ctx, ctx->surface_base + offset);
+      ctx_get_bo(ctx, true, ctx->surface_base + offset);
 
    if (bind_bo.map == NULL) {
       ImGui::TextColored(ctx->cfg->missing_color,
-                         "binding table unavailable addr=0x%08" PRIx64,
+                         "binding table unavailable addr=0x%012" PRIx64,
                          ctx->surface_base + offset);
       return;
    }
@@ -203,18 +228,22 @@ dump_binding_table(struct aub_viewer_decode_ctx *ctx, uint32_t offset, int count
          continue;
 
       uint64_t addr = ctx->surface_base + pointers[i];
-      struct gen_batch_decode_bo bo = ctx_get_bo(ctx, addr);
+      struct gen_batch_decode_bo bo = ctx_get_bo(ctx, true, addr);
       uint32_t size = strct->dw_length * 4;
 
       if (pointers[i] % 32 != 0 ||
           addr < bo.addr || addr + size >= bo.addr + bo.size) {
          ImGui::TextColored(ctx->cfg->missing_color,
-                            "pointer %u: %08x <not valid>", i, pointers[i]);
+                            "pointer %u: %012x <not valid>", i, pointers[i]);
          continue;
       }
 
-      ImGui::Text("pointer %u: %08x", i, pointers[i]);
-      aub_viewer_print_group(ctx, strct, addr, (const uint8_t *) bo.map + (addr - bo.addr));
+      const uint8_t *state = (const uint8_t *) bo.map + (addr - bo.addr);
+      if (ImGui::TreeNodeEx(&pointers[i], ImGuiTreeNodeFlags_Framed,
+                            "pointer %u: %012x", i, pointers[i])) {
+         aub_viewer_print_group(ctx, strct, addr, state);
+         ImGui::TreePop();
+      }
    }
 }
 
@@ -227,12 +256,12 @@ dump_samplers(struct aub_viewer_decode_ctx *ctx, uint32_t offset, int count)
       count = update_count(ctx, offset, strct->dw_length, 4);
 
    uint64_t state_addr = ctx->dynamic_base + offset;
-   struct gen_batch_decode_bo bo = ctx_get_bo(ctx, state_addr);
+   struct gen_batch_decode_bo bo = ctx_get_bo(ctx, true, state_addr);
    const uint8_t *state_map = (const uint8_t *) bo.map;
 
    if (state_map == NULL) {
       ImGui::TextColored(ctx->cfg->missing_color,
-                         "samplers unavailable addr=0x%08" PRIx64, state_addr);
+                         "samplers unavailable addr=0x%012" PRIx64, state_addr);
       return;
    }
 
@@ -242,8 +271,11 @@ dump_samplers(struct aub_viewer_decode_ctx *ctx, uint32_t offset, int count)
    }
 
    for (int i = 0; i < count; i++) {
-      ImGui::Text("sampler state %d", i);
-      aub_viewer_print_group(ctx, strct, state_addr, state_map);
+      if (ImGui::TreeNodeEx(state_map, ImGuiTreeNodeFlags_Framed,
+                            "sampler state %d", i)) {
+         aub_viewer_print_group(ctx, strct, state_addr, state_map);
+         ImGui::TreePop();
+      }
       state_addr += 16;
       state_map += 16;
    }
@@ -271,17 +303,17 @@ handle_media_interface_descriptor_load(struct aub_viewer_decode_ctx *ctx,
    }
 
    uint64_t desc_addr = ctx->dynamic_base + descriptor_offset;
-   struct gen_batch_decode_bo bo = ctx_get_bo(ctx, desc_addr);
+   struct gen_batch_decode_bo bo = ctx_get_bo(ctx, true, desc_addr);
    const uint32_t *desc_map = (const uint32_t *) bo.map;
 
    if (desc_map == NULL) {
       ImGui::TextColored(ctx->cfg->missing_color,
-                         "interface descriptors unavailable addr=0x%08" PRIx64, desc_addr);
+                         "interface descriptors unavailable addr=0x%012" PRIx64, desc_addr);
       return;
    }
 
    for (int i = 0; i < descriptor_count; i++) {
-      ImGui::Text("descriptor %d: %08x", i, descriptor_offset);
+      ImGui::Text("descriptor %d: %012x", i, descriptor_offset);
 
       aub_viewer_print_group(ctx, desc, desc_addr, desc_map);
 
@@ -332,7 +364,7 @@ handle_3dstate_vertex_buffers(struct aub_viewer_decode_ctx *ctx,
       if (iter.struct_desc != vbs)
          continue;
 
-      uint64_t buffer_addr;
+      uint64_t buffer_addr = 0;
 
       struct gen_field_iterator vbs_iter;
       gen_field_iterator_init(&vbs_iter, vbs, &iter.p[iter.start_bit / 32], 0, false);
@@ -343,7 +375,7 @@ handle_3dstate_vertex_buffers(struct aub_viewer_decode_ctx *ctx,
             pitch = vbs_iter.raw_value;
          } else if (strcmp(vbs_iter.name, "Buffer Starting Address") == 0) {
             buffer_addr = vbs_iter.raw_value;
-            vb = ctx_get_bo(ctx, buffer_addr);
+            vb = ctx_get_bo(ctx, true, buffer_addr);
          } else if (strcmp(vbs_iter.name, "Buffer Size") == 0) {
             vb_size = vbs_iter.raw_value;
             ready = true;
@@ -358,11 +390,11 @@ handle_3dstate_vertex_buffers(struct aub_viewer_decode_ctx *ctx,
          if (!ready)
             continue;
 
-         ImGui::Text("vertex buffer %d, size %d", index, vb_size);
+         ImGui::Text("vertex buffer %d, size %d, pitch %d", index, vb_size, pitch);
 
          if (vb.map == NULL) {
             ImGui::TextColored(ctx->cfg->missing_color,
-                               "buffer contents unavailable addr=0x%08" PRIx64, buffer_addr);
+                               "buffer contents unavailable addr=0x%012" PRIx64, buffer_addr);
             continue;
          }
 
@@ -395,7 +427,7 @@ handle_3dstate_index_buffer(struct aub_viewer_decode_ctx *ctx,
          format = iter.raw_value;
       } else if (strcmp(iter.name, "Buffer Starting Address") == 0) {
          buffer_addr = iter.raw_value;
-         ib = ctx_get_bo(ctx, buffer_addr);
+         ib = ctx_get_bo(ctx, true, buffer_addr);
       } else if (strcmp(iter.name, "Buffer Size") == 0) {
          ib_size = iter.raw_value;
       }
@@ -403,7 +435,7 @@ handle_3dstate_index_buffer(struct aub_viewer_decode_ctx *ctx,
 
    if (ib.map == NULL) {
       ImGui::TextColored(ctx->cfg->missing_color,
-                         "buffer contents unavailable addr=0x%08" PRIx64,
+                         "buffer contents unavailable addr=0x%012" PRIx64,
                          buffer_addr);
       return;
    }
@@ -546,10 +578,10 @@ decode_3dstate_constant(struct aub_viewer_decode_ctx *ctx,
          if (read_length[i] == 0)
             continue;
 
-         struct gen_batch_decode_bo buffer = ctx_get_bo(ctx, read_addr[i]);
+         struct gen_batch_decode_bo buffer = ctx_get_bo(ctx, true, read_addr[i]);
          if (!buffer.map) {
             ImGui::TextColored(ctx->cfg->missing_color,
-                               "constant buffer %d unavailable addr=0x%08" PRIx64,
+                               "constant buffer %d unavailable addr=0x%012" PRIx64,
                                i, read_addr[i]);
             continue;
          }
@@ -606,8 +638,6 @@ decode_dynamic_state_pointers(struct aub_viewer_decode_ctx *ctx,
                               struct gen_group *inst, const uint32_t *p,
                               const char *struct_type,  int count)
 {
-   struct gen_group *state = gen_spec_find_struct(ctx->spec, struct_type);
-
    uint32_t state_offset = 0;
 
    struct gen_field_iterator iter;
@@ -620,22 +650,38 @@ decode_dynamic_state_pointers(struct aub_viewer_decode_ctx *ctx,
    }
 
    uint64_t state_addr = ctx->dynamic_base + state_offset;
-   struct gen_batch_decode_bo bo = ctx_get_bo(ctx, state_addr);
+   struct gen_batch_decode_bo bo = ctx_get_bo(ctx, true, state_addr);
    const uint8_t *state_map = (const uint8_t *) bo.map;
 
    if (state_map == NULL) {
       ImGui::TextColored(ctx->cfg->missing_color,
-                         "dynamic %s state unavailable addr=0x%08" PRIx64,
+                         "dynamic %s state unavailable addr=0x%012" PRIx64,
                          struct_type, state_addr);
       return;
    }
 
+   struct gen_group *state = gen_spec_find_struct(ctx->spec, struct_type);
+   if (strcmp(struct_type, "BLEND_STATE") == 0) {
+      /* Blend states are different from the others because they have a header
+       * struct called BLEND_STATE which is followed by a variable number of
+       * BLEND_STATE_ENTRY structs.
+       */
+      ImGui::Text("%s", struct_type);
+      aub_viewer_print_group(ctx, state, state_addr, state_map);
+
+      state_addr += state->dw_length * 4;
+      state_map += state->dw_length * 4;
+
+      struct_type = "BLEND_STATE_ENTRY";
+      state = gen_spec_find_struct(ctx->spec, struct_type);
+   }
+
    for (int i = 0; i < count; i++) {
       ImGui::Text("%s %d", struct_type, i);
-      aub_viewer_print_group(ctx, state, state_offset, state_map);
+      aub_viewer_print_group(ctx, state, state_addr, state_map);
 
       state_addr += state->dw_length * 4;
-      state_map += state->dw_length;
+      state_map += state->dw_length * 4;
    }
 }
 
@@ -843,38 +889,25 @@ struct custom_decoder info_decoders[] = {
    { "3DSTATE_CONSTANT_PS", handle_urb_constant, AUB_DECODE_STAGE_PS, },
 };
 
-static inline uint64_t
-get_address(struct gen_spec *spec, const uint32_t *p)
-{
-   /* Addresses are always guaranteed to be page-aligned and sometimes
-    * hardware packets have extra stuff stuffed in the bottom 12 bits.
-    */
-   uint64_t addr = p[0] & ~0xfffu;
-
-   if (gen_spec_get_gen(spec) >= gen_make_gen(8,0)) {
-      /* On Broadwell and above, we have 48-bit addresses which consume two
-       * dwords.  Some packets require that these get stored in a "canonical
-       * form" which means that bit 47 is sign-extended through the upper
-       * bits. In order to correctly handle those aub dumps, we need to mask
-       * off the top 16 bits.
-       */
-      addr |= ((uint64_t)p[1] & 0xffff) << 32;
-   }
-
-   return addr;
-}
-
 void
 aub_viewer_render_batch(struct aub_viewer_decode_ctx *ctx,
                         const void *_batch, uint32_t batch_size,
-                        uint64_t batch_addr)
+                        uint64_t batch_addr, bool from_ring)
 {
    struct gen_group *inst;
-   const uint32_t *p, *batch = (const uint32_t *) _batch, *end = batch + batch_size;
+   const uint32_t *p, *batch = (const uint32_t *) _batch, *end = batch + batch_size / sizeof(uint32_t);
    int length;
 
+   if (ctx->n_batch_buffer_start >= 100) {
+      ImGui::TextColored(ctx->cfg->error_color,
+                         "0x%08" PRIx64 ": Max batch buffer jumps exceeded", batch_addr);
+      return;
+   }
+
+   ctx->n_batch_buffer_start++;
+
    for (p = batch; p < end; p += length) {
-      inst = gen_spec_find_instruction(ctx->spec, p);
+      inst = gen_spec_find_instruction(ctx->spec, ctx->engine, p);
       length = gen_group_get_length(inst, p);
       assert(inst == NULL || length > 0);
       length = MAX2(1, length);
@@ -883,7 +916,7 @@ aub_viewer_render_batch(struct aub_viewer_decode_ctx *ctx,
 
       if (inst == NULL) {
          ImGui::TextColored(ctx->cfg->error_color,
-                            "x%08" PRIx64 ": unknown instruction %08x",
+                            "0x%012" PRIx64 ": unknown instruction %012x",
                             offset, p[0]);
          continue;
       }
@@ -901,7 +934,7 @@ aub_viewer_render_batch(struct aub_viewer_decode_ctx *ctx,
       if (ctx->decode_cfg->command_filter.PassFilter(inst->name) &&
           ImGui::TreeNodeEx(p,
                             ImGuiTreeNodeFlags_Framed,
-                            "0x%08" PRIx64 ":  %s",
+                            "0x%012" PRIx64 ":  %s",
                             offset, inst->name)) {
          aub_viewer_print_group(ctx, inst, offset, p);
 
@@ -922,25 +955,30 @@ aub_viewer_render_batch(struct aub_viewer_decode_ctx *ctx,
       }
 
       if (strcmp(inst_name, "MI_BATCH_BUFFER_START") == 0) {
-         struct gen_batch_decode_bo next_batch = {};
-         bool second_level;
+         uint64_t next_batch_addr = 0xd0d0d0d0;
+         bool ppgtt = false;
+         bool second_level = false;
          struct gen_field_iterator iter;
          gen_field_iterator_init(&iter, inst, p, 0, false);
          while (gen_field_iterator_next(&iter)) {
             if (strcmp(iter.name, "Batch Buffer Start Address") == 0) {
-               next_batch = ctx_get_bo(ctx, iter.raw_value);
+               next_batch_addr = iter.raw_value;
             } else if (strcmp(iter.name, "Second Level Batch Buffer") == 0) {
                second_level = iter.raw_value;
+            } else if (strcmp(iter.name, "Address Space Indicator") == 0) {
+               ppgtt = iter.raw_value;
             }
          }
 
+         struct gen_batch_decode_bo next_batch = ctx_get_bo(ctx, ppgtt, next_batch_addr);
+
          if (next_batch.map == NULL) {
             ImGui::TextColored(ctx->cfg->missing_color,
-                               "Secondary batch at 0x%08" PRIx64 " unavailable",
-                               next_batch.addr);
+                               "Secondary batch at 0x%012" PRIx64 " unavailable",
+                               next_batch_addr);
          } else {
             aub_viewer_render_batch(ctx, next_batch.map, next_batch.size,
-                                    next_batch.addr);
+                                    next_batch.addr, false);
          }
          if (second_level) {
             /* MI_BATCH_BUFFER_START with "2nd Level Batch Buffer" set acts
@@ -949,7 +987,7 @@ aub_viewer_render_batch(struct aub_viewer_decode_ctx *ctx,
              * MI_BATCH_BUFFER_END.
              */
             continue;
-         } else {
+         } else if (!from_ring) {
             /* MI_BATCH_BUFFER_START with "2nd Level Batch Buffer" unset acts
              * like a goto.  Nothing after it will ever get processed.  In
              * order to prevent the recursion from growing, we just reset the
@@ -961,4 +999,6 @@ aub_viewer_render_batch(struct aub_viewer_decode_ctx *ctx,
          break;
       }
    }
+
+   ctx->n_batch_buffer_start--;
 }