From 12feafc28eec8dfa5ae7e9a0b90ef0b2b9ea8f00 Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Fri, 13 Sep 2019 15:13:31 -0700 Subject: [PATCH] intel/tools: Add basic aub_context code and helpers. 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 --- src/intel/tools/aub_write.c | 62 ++++++++++++++++++++++++++++++++ src/intel/tools/aub_write.h | 21 +++++++++++ src/intel/tools/intel_dump_gpu.c | 32 +++++++++++++++++ 3 files changed, 115 insertions(+) diff --git a/src/intel/tools/aub_write.c b/src/intel/tools/aub_write.c index f928094d350..f9fe8db24cb 100644 --- a/src/intel/tools/aub_write.c +++ b/src/intel/tools/aub_write.c @@ -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 diff --git a/src/intel/tools/aub_write.h b/src/intel/tools/aub_write.h index 31ca6253e0f..1b0524c38ce 100644 --- a/src/intel/tools/aub_write.h +++ b/src/intel/tools/aub_write.h @@ -37,11 +37,25 @@ 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 diff --git a/src/intel/tools/intel_dump_gpu.c b/src/intel/tools/intel_dump_gpu.c index f604c6c62f0..cb2bf8b1351 100644 --- a/src/intel/tools/intel_dump_gpu.c +++ b/src/intel/tools/intel_dump_gpu.c @@ -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;