diff options
author | Nicolai Hähnle <[email protected]> | 2019-02-26 16:22:53 +0100 |
---|---|---|
committer | Nicolai Hähnle <[email protected]> | 2019-04-25 12:35:19 +0200 |
commit | b7fab7b02db07105a66a45fe7649ab52c1b7cd6e (patch) | |
tree | ef22a7eae12daf0bcdd1ec9b8aca375024672df6 | |
parent | fe0d2b3d372796367ce3ca20589cf8cb34352b0b (diff) |
ddebug: log calls to pipe->flush
This can be useful when internal draws lead to a hang.
Reviewed-by: Marek Olšák <[email protected]>
-rw-r--r-- | src/gallium/auxiliary/driver_ddebug/dd_draw.c | 75 | ||||
-rw-r--r-- | src/gallium/auxiliary/driver_ddebug/dd_pipe.h | 6 |
2 files changed, 61 insertions, 20 deletions
diff --git a/src/gallium/auxiliary/driver_ddebug/dd_draw.c b/src/gallium/auxiliary/driver_ddebug/dd_draw.c index 4eb0dd096f4..bda1891c49b 100644 --- a/src/gallium/auxiliary/driver_ddebug/dd_draw.c +++ b/src/gallium/auxiliary/driver_ddebug/dd_draw.c @@ -283,6 +283,13 @@ dd_dump_shader(struct dd_draw_state *dstate, enum pipe_shader_type sh, FILE *f) } 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) { int sh, i; @@ -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 @@ -1190,6 +1198,33 @@ dd_after_draw(struct dd_context *dctx, struct dd_draw_record *record) } 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) { diff --git a/src/gallium/auxiliary/driver_ddebug/dd_pipe.h b/src/gallium/auxiliary/driver_ddebug/dd_pipe.h index 12da8280aa6..708b2463e2b 100644 --- a/src/gallium/auxiliary/driver_ddebug/dd_pipe.h +++ b/src/gallium/auxiliary/driver_ddebug/dd_pipe.h @@ -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; |