build: move imgui out of src/intel/tools to be reused
[mesa.git] / src / intel / tools / aubinator_viewer.cpp
index 7ef56aa035f1e4786f4bd94fccc3a1f1988ffd82..4c11fe4b37dbf45d53c8f054498ca9edc2e56ddb 100644 (file)
@@ -97,7 +97,7 @@ handle_mem_write(void *user_data, uint64_t phys_addr,
 }
 
 static void
-handle_ring_write(void *user_data, enum gen_engine engine,
+handle_ring_write(void *user_data, enum drm_i915_gem_engine_class engine,
                   const void *ring_data, uint32_t ring_data_len)
 {
    struct aub_file *file = (struct aub_file *) user_data;
@@ -221,12 +221,13 @@ update_mem_for_exec(struct aub_mem *mem, struct aub_file *file, int exec_idx)
 
 #include <epoxy/gl.h>
 
-#include "imgui.h"
+#include "imgui/imgui.h"
+#include "imgui/imgui_memory_editor.h"
 #include "imgui_impl_gtk3.h"
 #include "imgui_impl_opengl3.h"
 
 #include "aubinator_viewer.h"
-#include "imgui_memory_editor.h"
+#include "aubinator_viewer_urb.h"
 
 struct window {
    struct list_head link; /* link in the global list of windows */
@@ -274,6 +275,15 @@ struct shader_window {
    size_t shader_size;
 };
 
+struct urb_window {
+   struct window base;
+
+   uint32_t end_urb_offset;
+   struct aub_decode_urb_stage_state urb_stages[AUB_DECODE_N_STAGE];
+
+   AubinatorViewerUrb urb_view;
+};
+
 struct batch_window {
    struct window base;
 
@@ -377,16 +387,14 @@ new_shader_window(struct aub_mem *mem, uint64_t address, const char *desc)
    window->base.display = display_shader_window;
    window->base.destroy = destroy_shader_window;
 
-   struct gen_batch_decode_bo shader_bo;
-   if (mem->pml4)
-      shader_bo = aub_mem_get_ppgtt_bo(mem, address);
-   else
-      shader_bo = aub_mem_get_ggtt_bo(mem, address);
-
+   struct gen_batch_decode_bo shader_bo =
+      aub_mem_get_ppgtt_bo(mem, address);
    if (shader_bo.map) {
       FILE *f = open_memstream(&window->shader, &window->shader_size);
       if (f) {
-         gen_disasm_disassemble(context.file->disasm, shader_bo.map, 0, f);
+         gen_disasm_disassemble(context.file->disasm,
+                                (const uint8_t *) shader_bo.map +
+                                (address - shader_bo.addr), 0, f);
          fclose(f);
       }
    }
@@ -396,6 +404,61 @@ new_shader_window(struct aub_mem *mem, uint64_t address, const char *desc)
    return window;
 }
 
+/* URB windows */
+
+static void
+display_urb_window(struct window *win)
+{
+   struct urb_window *window = (struct urb_window *) win;
+   static const char *stages[] = {
+      [AUB_DECODE_STAGE_VS] = "VS",
+      [AUB_DECODE_STAGE_HS] = "HS",
+      [AUB_DECODE_STAGE_DS] = "DS",
+      [AUB_DECODE_STAGE_GS] = "GS",
+      [AUB_DECODE_STAGE_PS] = "PS",
+      [AUB_DECODE_STAGE_CS] = "CS",
+   };
+
+   ImGui::Text("URB allocation:");
+   window->urb_view.DrawAllocation("##urb",
+                                   ARRAY_SIZE(window->urb_stages),
+                                   window->end_urb_offset,
+                                   stages,
+                                   &window->urb_stages[0]);
+}
+
+static void
+destroy_urb_window(struct window *win)
+{
+   struct urb_window *window = (struct urb_window *) win;
+
+   free(window);
+}
+
+static struct urb_window *
+new_urb_window(struct aub_viewer_decode_ctx *decode_ctx, uint64_t address)
+{
+   struct urb_window *window = xtzalloc(*window);
+
+   snprintf(window->base.name, sizeof(window->base.name),
+            "URB view (0x%lx)##%p", address, window);
+
+   list_inithead(&window->base.parent_link);
+   window->base.position = ImVec2(-1, -1);
+   window->base.size = ImVec2(700, 300);
+   window->base.opened = true;
+   window->base.display = display_urb_window;
+   window->base.destroy = destroy_urb_window;
+
+   window->end_urb_offset = decode_ctx->end_urb_offset;
+   memcpy(window->urb_stages, decode_ctx->urb_stages, sizeof(window->urb_stages));
+   window->urb_view = AubinatorViewerUrb();
+
+   list_addtail(&window->base.link, &context.windows);
+
+   return window;
+}
+
 /* Memory editor windows */
 
 static uint8_t
@@ -588,6 +651,15 @@ batch_display_shader(void *user_data, const char *shader_desc, uint64_t address)
    list_add(&shader_window->base.parent_link, &window->base.children_windows);
 }
 
+static void
+batch_display_urb(void *user_data, const struct aub_decode_urb_stage_state *stages)
+{
+   struct batch_window *window = (struct batch_window *) user_data;
+   struct urb_window *urb_window = new_urb_window(&window->decode_ctx, 0);
+
+   list_add(&urb_window->base.parent_link, &window->base.children_windows);
+}
+
 static void
 batch_edit_address(void *user_data, uint64_t address, uint32_t len)
 {
@@ -621,7 +693,7 @@ update_batch_window(struct batch_window *window, bool reset, int exec_idx)
 }
 
 static void
-display_batch_ring_write(void *user_data, enum gen_engine engine,
+display_batch_ring_write(void *user_data, enum drm_i915_gem_engine_class engine,
                          const void *data, uint32_t data_len)
 {
    struct batch_window *window = (struct batch_window *) user_data;
@@ -632,7 +704,8 @@ display_batch_ring_write(void *user_data, enum gen_engine engine,
 }
 
 static void
-display_batch_execlist_write(void *user_data, enum gen_engine engine,
+display_batch_execlist_write(void *user_data,
+                             enum drm_i915_gem_engine_class engine,
                              uint64_t context_descriptor)
 {
    struct batch_window *window = (struct batch_window *) user_data;
@@ -648,19 +721,21 @@ display_batch_execlist_write(void *user_data, enum gen_engine engine,
    uint32_t ring_buffer_head = context_img[5];
    uint32_t ring_buffer_tail = context_img[7];
    uint32_t ring_buffer_start = context_img[9];
+   uint32_t ring_buffer_length = (context_img[11] & 0x1ff000) + 4096;
 
    window->mem.pml4 = (uint64_t)context_img[49] << 32 | context_img[51];
 
    struct gen_batch_decode_bo ring_bo =
       aub_mem_get_ggtt_bo(&window->mem, ring_buffer_start);
    assert(ring_bo.size > 0);
-   void *commands = (uint8_t *)ring_bo.map + (ring_buffer_start - ring_bo.addr);
+   void *commands = (uint8_t *)ring_bo.map + (ring_buffer_start - ring_bo.addr) + ring_buffer_head;
 
    window->uses_ppgtt = true;
 
+   window->decode_ctx.engine = engine;
    aub_viewer_render_batch(&window->decode_ctx, commands,
-                           ring_buffer_tail - ring_buffer_head,
-                           ring_buffer_start);
+                           MIN2(ring_buffer_tail - ring_buffer_head, ring_buffer_length),
+                           ring_buffer_start + ring_buffer_head);
 }
 
 static void
@@ -747,6 +822,7 @@ new_batch_window(int exec_idx)
                               NULL,
                               window);
    window->decode_ctx.display_shader = batch_display_shader;
+   window->decode_ctx.display_urb = batch_display_urb;
    window->decode_ctx.edit_address = batch_edit_address;
 
    update_batch_window(window, false, exec_idx);
@@ -764,7 +840,6 @@ display_registers_window(struct window *win)
    filter.Draw();
 
    ImGui::BeginChild(ImGui::GetID("##block"));
-   struct hash_entry *entry;
    hash_table_foreach(context.file->spec->registers_by_name, entry) {
       struct gen_group *reg = (struct gen_group *) entry->data;
       if (filter.PassFilter(reg->name) &&
@@ -820,7 +895,6 @@ display_commands_window(struct window *win)
    if (ImGui::Button("Dwords")) show_dwords ^= 1;
 
    ImGui::BeginChild(ImGui::GetID("##block"));
-   struct hash_entry *entry;
    hash_table_foreach(context.file->spec->commands, entry) {
       struct gen_group *cmd = (struct gen_group *) entry->data;
       if ((cmd_filter.PassFilter(cmd->name) &&
@@ -919,6 +993,7 @@ display_aubfile_window(struct window *win)
    ImGui::ColorEdit3("error", (float *)&cfg->error_color, cflags); ImGui::SameLine();
    ImGui::ColorEdit3("highlight", (float *)&cfg->highlight_color, cflags); ImGui::SameLine();
    ImGui::ColorEdit3("dwords", (float *)&cfg->dwords_color, cflags); ImGui::SameLine();
+   ImGui::ColorEdit3("booleans", (float *)&cfg->boolean_color, cflags); ImGui::SameLine();
 
    if (ImGui::Button("Commands list") || has_ctrl_key('c')) { show_commands_window(); } ImGui::SameLine();
    if (ImGui::Button("Registers list") || has_ctrl_key('r')) { show_register_window(); } ImGui::SameLine();
@@ -975,8 +1050,7 @@ show_aubfile_window(void)
 
    list_inithead(&window->parent_link);
    window->size = ImVec2(-1, 250);
-   window->position =
-      ImVec2(0, ImGui::GetIO().DisplaySize.y - window->size.y);
+   window->position = ImVec2(0, 0);
    window->opened = true;
    window->display = display_aubfile_window;
    window->destroy = NULL;
@@ -1068,6 +1142,21 @@ unrealize_area(GtkGLArea *area)
    ImGui::DestroyContext();
 }
 
+static void
+size_allocate_area(GtkGLArea *area,
+                   GdkRectangle *allocation,
+                   gpointer user_data)
+{
+   if (!gtk_widget_get_realized(GTK_WIDGET(area)))
+      return;
+
+   /* We want to catch only initial size allocate. */
+   g_signal_handlers_disconnect_by_func(area,
+                                        (gpointer) size_allocate_area,
+                                        user_data);
+   show_aubfile_window();
+}
+
 static void
 print_help(const char *progname, FILE *file)
 {
@@ -1123,12 +1212,11 @@ int main(int argc, char *argv[])
    g_signal_connect(gl_area, "render", G_CALLBACK(repaint_area), NULL);
    g_signal_connect(gl_area, "realize", G_CALLBACK(realize_area), NULL);
    g_signal_connect(gl_area, "unrealize", G_CALLBACK(unrealize_area), NULL);
+   g_signal_connect(gl_area, "size_allocate", G_CALLBACK(size_allocate_area), NULL);
    gtk_container_add(GTK_CONTAINER(context.gtk_window), gl_area);
 
    gtk_widget_show_all(context.gtk_window);
 
-   show_aubfile_window();
-
    gtk_main();
 
    free(context.xml_path);