ddebug: log calls to pipe->flush
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Tue, 26 Feb 2019 15:22:53 +0000 (16:22 +0100)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Thu, 25 Apr 2019 10:35:19 +0000 (12:35 +0200)
This can be useful when internal draws lead to a hang.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/auxiliary/driver_ddebug/dd_draw.c
src/gallium/auxiliary/driver_ddebug/dd_pipe.h

index 4eb0dd096f4e710b2db32edb72e545f8b4041f4a..bda1891c49bfd24203a4cb09f03d6f367a78ca5b 100644 (file)
@@ -282,6 +282,13 @@ dd_dump_shader(struct dd_draw_state *dstate, enum pipe_shader_type sh, FILE *f)
    fprintf(f, COLOR_SHADER "end shader: %s" COLOR_RESET "\n\n", shader_str[sh]);
 }
 
+static void
+dd_dump_flush(struct dd_draw_state *dstate, struct call_flush *info, FILE *f)
+{
+   fprintf(f, "%s:\n", __func__+8);
+   DUMP_M(hex, info, flags);
+}
+
 static void
 dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE *f)
 {
@@ -557,6 +564,9 @@ static void
 dd_dump_call(FILE *f, struct dd_draw_state *state, struct dd_call *call)
 {
    switch (call->type) {
+   case CALL_FLUSH:
+      dd_dump_flush(state, &call->info.flush, f);
+      break;
    case CALL_DRAW_VBO:
       dd_dump_draw_vbo(state, &call->info.draw_vbo.draw, f);
       break;
@@ -628,6 +638,8 @@ static void
 dd_unreference_copy_of_call(struct dd_call *dst)
 {
    switch (dst->type) {
+   case CALL_FLUSH:
+      break;
    case CALL_DRAW_VBO:
       pipe_so_target_reference(&dst->info.draw_vbo.draw.count_from_stream_output, NULL);
       pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer, NULL);
@@ -1093,13 +1105,23 @@ dd_create_record(struct dd_context *dctx)
 }
 
 static void
-dd_context_flush(struct pipe_context *_pipe,
-                 struct pipe_fence_handle **fence, unsigned flags)
+dd_add_record(struct dd_context *dctx, struct dd_draw_record *record)
 {
-   struct dd_context *dctx = dd_context(_pipe);
-   struct pipe_context *pipe = dctx->pipe;
+   mtx_lock(&dctx->mutex);
+   if (unlikely(dctx->num_records > 10000)) {
+      dctx->api_stalled = true;
+      /* Since this is only a heuristic to prevent the API thread from getting
+       * too far ahead, we don't need a loop here. */
+      cnd_wait(&dctx->cond, &dctx->mutex);
+      dctx->api_stalled = false;
+   }
 
-   pipe->flush(pipe, fence, flags);
+   if (list_empty(&dctx->records))
+      cnd_signal(&dctx->cond);
+
+   list_addtail(&record->list, &dctx->records);
+   dctx->num_records++;
+   mtx_unlock(&dctx->mutex);
 }
 
 static void
@@ -1125,21 +1147,7 @@ dd_before_draw(struct dd_context *dctx, struct dd_draw_record *record)
       pipe->flush(pipe, NULL, 0);
    }
 
-   mtx_lock(&dctx->mutex);
-   if (unlikely(dctx->num_records > 10000)) {
-      dctx->api_stalled = true;
-      /* Since this is only a heuristic to prevent the API thread from getting
-       * too far ahead, we don't need a loop here. */
-      cnd_wait(&dctx->cond, &dctx->mutex);
-      dctx->api_stalled = false;
-   }
-
-   if (list_empty(&dctx->records))
-      cnd_signal(&dctx->cond);
-
-   list_addtail(&record->list, &dctx->records);
-   dctx->num_records++;
-   mtx_unlock(&dctx->mutex);
+   dd_add_record(dctx, record);
 }
 
 static void
@@ -1189,6 +1197,33 @@ dd_after_draw(struct dd_context *dctx, struct dd_draw_record *record)
               dctx->num_draw_calls);
 }
 
+static void
+dd_context_flush(struct pipe_context *_pipe,
+                 struct pipe_fence_handle **fence, unsigned flags)
+{
+   struct dd_context *dctx = dd_context(_pipe);
+   struct pipe_context *pipe = dctx->pipe;
+   struct pipe_screen *screen = pipe->screen;
+   struct dd_draw_record *record = dd_create_record(dctx);
+
+   record->call.type = CALL_FLUSH;
+   record->call.info.flush.flags = flags;
+
+   record->time_before = os_time_get_nano();
+
+   dd_add_record(dctx, record);
+
+   pipe->flush(pipe, &record->bottom_of_pipe, flags);
+   if (fence)
+      screen->fence_reference(screen, fence, record->bottom_of_pipe);
+
+   if (pipe->callback) {
+      pipe->callback(pipe, dd_after_draw_async, record, true);
+   } else {
+      dd_after_draw_async(record);
+   }
+}
+
 static void
 dd_context_draw_vbo(struct pipe_context *_pipe,
                     const struct pipe_draw_info *info)
index 12da8280aa609cfb5f448a00167e0e02bc7e59ab..708b2463e2b710ab6bd86d0602202ca1e66d2af9 100644 (file)
@@ -60,6 +60,7 @@ struct dd_screen
 
 enum call_type
 {
+   CALL_FLUSH,
    CALL_DRAW_VBO,
    CALL_LAUNCH_GRID,
    CALL_RESOURCE_COPY_REGION,
@@ -115,6 +116,10 @@ struct call_generate_mipmap {
    unsigned last_layer;
 };
 
+struct call_flush {
+   unsigned flags;
+};
+
 struct call_draw_info {
    struct pipe_draw_info draw;
    struct pipe_draw_indirect_info indirect;
@@ -170,6 +175,7 @@ struct dd_call
    enum call_type type;
 
    union {
+      struct call_flush flush;
       struct call_draw_info draw_vbo;
       struct pipe_grid_info launch_grid;
       struct call_resource_copy_region resource_copy_region;