diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index 79755eaf97c..f1db89dab12 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -311,7 +311,8 @@ struct mali_single_framebuffer panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count); mali_ptr -panfrost_fragment_job(struct panfrost_batch *batch, bool has_draws); +panfrost_fragment_job(struct panfrost_batch *batch, bool has_draws, + struct mali_job_descriptor_header **header_cpu); void panfrost_shader_compile( diff --git a/src/gallium/drivers/panfrost/pan_fragment.c b/src/gallium/drivers/panfrost/pan_fragment.c index b6bbce391c4..c03df51fafa 100644 --- a/src/gallium/drivers/panfrost/pan_fragment.c +++ b/src/gallium/drivers/panfrost/pan_fragment.c @@ -49,7 +49,8 @@ panfrost_initialize_surface( * presentations, this is supposed to correspond to eglSwapBuffers) */ mali_ptr -panfrost_fragment_job(struct panfrost_batch *batch, bool has_draws) +panfrost_fragment_job(struct panfrost_batch *batch, bool has_draws, + struct mali_job_descriptor_header **header_cpu) { struct panfrost_screen *screen = pan_screen(batch->ctx->base.screen); @@ -108,5 +109,6 @@ panfrost_fragment_job(struct panfrost_batch *batch, bool has_draws) struct panfrost_transfer transfer = panfrost_allocate_transient(batch, sizeof(header) + sizeof(payload)); memcpy(transfer.cpu, &header, sizeof(header)); memcpy(transfer.cpu + sizeof(header), &payload, sizeof(payload)); + *header_cpu = (struct mali_job_descriptor_header *)transfer.cpu; return transfer.gpu; } diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index e2e54aff216..3116d294632 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -807,7 +807,8 @@ panfrost_batch_draw_wallpaper(struct panfrost_batch *batch) static int panfrost_batch_submit_ioctl(struct panfrost_batch *batch, mali_ptr first_job_desc, - uint32_t reqs) + uint32_t reqs, + struct mali_job_descriptor_header *header) { struct panfrost_context *ctx = batch->ctx; struct pipe_context *gallium = (struct pipe_context *) ctx; @@ -877,6 +878,26 @@ panfrost_batch_submit_ioctl(struct panfrost_batch *batch, return errno; } + if (pan_debug & PAN_DBG_SYNC) { + u32 status; + + /* Wait so we can get errors reported back */ + drmSyncobjWait(screen->fd, &batch->out_sync->syncobj, 1, + INT64_MAX, 0, NULL); + + status = header->exception_status; + + if (status && status != 0x1) { + fprintf(stderr, "Job %" PRIx64 " failed: source ID: 0x%x access: %s exception: 0x%x (exception_status 0x%x) fault_pointer 0x%" PRIx64 " \n", + first_job_desc, + (status >> 16) & 0xFFFF, + pandecode_exception_access((status >> 8) & 0x3), + status & 0xFF, + status, + header->fault_pointer); + } + } + /* Trace the job if we're doing that */ if (pan_debug & PAN_DBG_TRACE) { /* Wait so we can get errors reported back */ @@ -892,17 +913,19 @@ static int panfrost_batch_submit_jobs(struct panfrost_batch *batch) { bool has_draws = batch->first_job.gpu; + struct mali_job_descriptor_header *header; int ret = 0; if (has_draws) { - ret = panfrost_batch_submit_ioctl(batch, batch->first_job.gpu, 0); + header = (struct mali_job_descriptor_header *)batch->first_job.cpu; + ret = panfrost_batch_submit_ioctl(batch, batch->first_job.gpu, 0, header); assert(!ret); } if (batch->first_tiler.gpu || batch->clear) { - mali_ptr fragjob = panfrost_fragment_job(batch, has_draws); + mali_ptr fragjob = panfrost_fragment_job(batch, has_draws, &header); - ret = panfrost_batch_submit_ioctl(batch, fragjob, PANFROST_JD_REQ_FS); + ret = panfrost_batch_submit_ioctl(batch, fragjob, PANFROST_JD_REQ_FS, header); assert(!ret); } diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index 3aa5f05cd5e..c9bf9bcc7eb 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -59,6 +59,7 @@ static const struct debug_named_value debug_options[] = { {"trace", PAN_DBG_TRACE, "Trace the command stream"}, {"deqp", PAN_DBG_DEQP, "Hacks for dEQP"}, {"afbc", PAN_DBG_AFBC, "Enable non-conformant AFBC impl"}, + {"sync", PAN_DBG_SYNC, "Wait for each job's completion and check for any GPU fault"}, DEBUG_NAMED_VALUE_END }; diff --git a/src/gallium/drivers/panfrost/pan_util.h b/src/gallium/drivers/panfrost/pan_util.h index 24c71d59ba0..b51b88d2e1a 100644 --- a/src/gallium/drivers/panfrost/pan_util.h +++ b/src/gallium/drivers/panfrost/pan_util.h @@ -32,6 +32,7 @@ #define PAN_DBG_TRACE 0x0002 #define PAN_DBG_DEQP 0x0004 #define PAN_DBG_AFBC 0x0008 +#define PAN_DBG_SYNC 0x0010 extern int pan_debug; diff --git a/src/panfrost/pandecode/decode.c b/src/panfrost/pandecode/decode.c index d112f104b43..c266f82fae8 100644 --- a/src/panfrost/pandecode/decode.c +++ b/src/panfrost/pandecode/decode.c @@ -490,7 +490,7 @@ pandecode_block_format(enum mali_block_format fmt) #undef DEFINE_CASE #define DEFINE_CASE(name) case MALI_EXCEPTION_ACCESS_## name: return ""#name -static char * +char * pandecode_exception_access(enum mali_exception_access access) { switch (access) { diff --git a/src/panfrost/pandecode/public.h b/src/panfrost/pandecode/public.h index c68dbe6a2ea..89e6c3e02d4 100644 --- a/src/panfrost/pandecode/public.h +++ b/src/panfrost/pandecode/public.h @@ -49,4 +49,8 @@ pandecode_inject_mmap(uint64_t gpu_va, void *cpu, unsigned sz, const char *name) int pandecode_jc(uint64_t jc_gpu_va, bool bifrost, unsigned gpu_id); +char * +pandecode_exception_access(enum mali_exception_access access); + + #endif /* __MMAP_TRACE_H__ */