intel/tools: Add basic aub_context code and helpers.
authorRafael Antognolli <rafael.antognolli@intel.com>
Fri, 13 Sep 2019 22:13:31 +0000 (15:13 -0700)
committerRafael Antognolli <rafael.antognolli@intel.com>
Thu, 10 Oct 2019 14:08:50 +0000 (14:08 +0000)
v2:
 - Only dump context if there were no erros (Lionel).
 - Store counter for context handles in aub_file (Lionel).
v3:
 - Add a comment about aub_context -> GEM context (Lionel).

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
src/intel/tools/aub_write.c
src/intel/tools/aub_write.h
src/intel/tools/intel_dump_gpu.c

index f928094d35014a2b1790f9226ee1ac829a8db9df..f9fe8db24cbebeb666dcc2f8cbb8b11cd05ea2a9 100644 (file)
@@ -188,6 +188,8 @@ aub_file_init(struct aub_file *aub, FILE *file, FILE *debug, uint16_t pci_id, co
                                      "GGTT PT");
    dword_out(aub, 1);
    dword_out(aub, 0);
+
+   aub->next_context_handle = 1;
 }
 
 void
@@ -611,6 +613,66 @@ aub_write_default_setup(struct aub_file *aub)
    aub->has_default_setup = true;
 }
 
+static struct aub_context *
+aub_context_new(struct aub_file *aub, uint32_t new_id)
+{
+   assert(aub->num_contexts < MAX_CONTEXT_COUNT);
+
+   struct aub_context *ctx = &aub->contexts[aub->num_contexts++];
+
+   ctx->id = new_id;
+   memset(ctx, 0, sizeof(*ctx));
+
+   return ctx;
+}
+
+uint32_t
+aub_write_context_create(struct aub_file *aub, uint32_t *ctx_id)
+{
+   uint32_t new_id = ctx_id ? *ctx_id : aub->next_context_handle;
+
+   aub_context_new(aub, new_id);
+
+   if (!ctx_id)
+      aub->next_context_handle++;
+
+   return new_id;
+}
+
+static struct aub_context *
+aub_context_find(struct aub_file *aub, uint32_t id)
+{
+   for (int i = 0; i < aub->num_contexts; i++) {
+      if (aub->contexts[i].id == id)
+         return &aub->contexts[i];
+   }
+
+   return NULL;
+}
+
+static struct aub_hw_context *
+aub_write_ensure_context(struct aub_file *aub, uint32_t ctx_id,
+                         enum drm_i915_gem_engine_class engine_class)
+{
+   struct aub_context *ctx = aub_context_find(aub, ctx_id);
+   assert(ctx != NULL);
+
+   struct aub_hw_context *hw_ctx = &ctx->hw_contexts[engine_class];
+   if (!hw_ctx->initialized) {
+      /* TODO: initialize context here */
+   }
+
+   return hw_ctx;
+}
+
+static uint64_t
+get_context_descriptor(struct aub_file *aub,
+                       const struct engine *cs,
+                       struct aub_hw_context *hw_ctx)
+{
+   return cs->hw_class | hw_ctx->pphwsp_addr | CONTEXT_FLAGS;
+}
+
 /**
  * Break up large objects into multiple writes.  Otherwise a 128kb VBO
  * would overflow the 16 bits of size field in the packet header and
index 31ca6253e0f411df9c7889248816ba9fad486803..1b0524c38cee2cd318dc0826a861bb8bece9ec79 100644 (file)
 extern "C" {
 #endif
 
+#define MAX_CONTEXT_COUNT 64
+
 struct aub_ppgtt_table {
    uint64_t phys_addr;
    struct aub_ppgtt_table *subtables[512];
 };
 
+struct aub_hw_context {
+   bool initialized;
+   uint64_t ring_addr;
+   uint64_t pphwsp_addr;
+};
+
+/* GEM context, as seen from userspace */
+struct aub_context {
+   uint32_t id;
+   struct aub_hw_context hw_contexts[I915_ENGINE_CLASS_VIDEO + 1];
+};
+
 struct aub_file {
    FILE *file;
 
@@ -64,6 +78,11 @@ struct aub_file {
       uint64_t pphwsp_addr;
       uint64_t descriptor;
    } engine_setup[I915_ENGINE_CLASS_VIDEO_ENHANCE + 1];
+
+   struct aub_context contexts[MAX_CONTEXT_COUNT];
+   int num_contexts;
+
+   uint32_t next_context_handle;
 };
 
 void aub_file_init(struct aub_file *aub, FILE *file, FILE *debug, uint16_t pci_id, const char *app_name);
@@ -97,6 +116,8 @@ void aub_write_exec(struct aub_file *aub, uint64_t batch_addr,
 void aub_write_context_execlists(struct aub_file *aub, uint64_t context_addr,
                                  enum drm_i915_gem_engine_class engine_class);
 
+uint32_t aub_write_context_create(struct aub_file *aub, uint32_t *ctx_id);
+
 #ifdef __cplusplus
 }
 #endif
index f604c6c62f03d1c9af74f0af39d08410b03050ae..cb2bf8b135167fa932ffdef1ee7a044bd5c514a1 100644 (file)
@@ -336,6 +336,23 @@ remove_bo(int fd, int handle)
    bo->map = NULL;
 }
 
+static uint32_t
+dump_create_context(int fd, uint32_t *ctx_id)
+{
+   if (!aub_file.file) {
+      aub_file_init(&aub_file, output_file,
+                    verbose == 2 ? stdout : NULL,
+                    device, program_invocation_short_name);
+      aub_write_default_setup(&aub_file);
+
+      if (verbose)
+         printf("[running, output file %s, chipset id 0x%04x, gen %d]\n",
+                output_filename, device, devinfo.gen);
+   }
+
+   return aub_write_context_create(&aub_file, ctx_id);
+}
+
 __attribute__ ((visibility ("default"))) int
 close(int fd)
 {
@@ -458,6 +475,21 @@ ioctl(int fd, unsigned long request, ...)
          return libc_ioctl(fd, request, argp);
       }
 
+      case DRM_IOCTL_I915_GEM_CONTEXT_CREATE: {
+         uint32_t *ctx_id = NULL;
+         struct drm_i915_gem_context_create *create = argp;
+         ret = 0;
+         if (!device_override) {
+            ret = libc_ioctl(fd, request, argp);
+            ctx_id = &create->ctx_id;
+         }
+
+         if (ret == 0)
+            create->ctx_id = dump_create_context(fd, ctx_id);
+
+         return ret;
+      }
+
       case DRM_IOCTL_I915_GEM_CREATE: {
          struct drm_i915_gem_create *create = argp;