diff --git a/docs/gallium/debugging.rst b/docs/gallium/debugging.rst index 7252357a945..34dedff542c 100644 --- a/docs/gallium/debugging.rst +++ b/docs/gallium/debugging.rst @@ -32,6 +32,12 @@ specified file. Paths may be relative or absolute; relative paths are relative to the working directory. For example, setting it to "trace.xml" will cause the trace to be written to a file of the same name in the working directory. +.. envvar:: GALLIUM_TRACE_TC (false) + +If enabled while :ref:`trace` is active, this variable specifies that the threaded context +should be traced for drivers which implement it. By default, the driver thread is traced, +which will include any reordering of the command stream from threaded context. + .. envvar:: GALLIUM_TRACE_TRIGGER ("") If set while :ref:`trace` is active, this variable specifies a filename to monitor. diff --git a/src/gallium/auxiliary/driver_trace/tr_context.c b/src/gallium/auxiliary/driver_trace/tr_context.c index 787db7b5f0b..e64e01a5868 100644 --- a/src/gallium/auxiliary/driver_trace/tr_context.c +++ b/src/gallium/auxiliary/driver_trace/tr_context.c @@ -1028,8 +1028,6 @@ trace_context_sampler_view_destroy(struct pipe_context *_pipe, struct pipe_context *pipe = tr_ctx->pipe; struct pipe_sampler_view *view = tr_view->sampler_view; - assert(_view->context == _pipe); - trace_dump_call_begin("pipe_context", "sampler_view_destroy"); trace_dump_arg(ptr, pipe); diff --git a/src/gallium/auxiliary/driver_trace/tr_context.h b/src/gallium/auxiliary/driver_trace/tr_context.h index 95469e87530..a9d75ce921c 100644 --- a/src/gallium/auxiliary/driver_trace/tr_context.h +++ b/src/gallium/auxiliary/driver_trace/tr_context.h @@ -55,6 +55,8 @@ struct trace_context struct pipe_framebuffer_state unwrapped_state; bool seen_fb_state; + + bool threaded; }; @@ -77,7 +79,8 @@ struct pipe_context * trace_context_create(struct trace_screen *tr_scr, struct pipe_context *pipe); - +struct pipe_context * +trace_context_create_threaded(struct pipe_screen *_screen, struct pipe_context *pipe); #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/driver_trace/tr_screen.c b/src/gallium/auxiliary/driver_trace/tr_screen.c index 2adda8be291..76f947b9386 100644 --- a/src/gallium/auxiliary/driver_trace/tr_screen.c +++ b/src/gallium/auxiliary/driver_trace/tr_screen.c @@ -27,7 +27,9 @@ #include "util/format/u_format.h" #include "util/u_memory.h" +#include "util/hash_table.h" #include "util/simple_list.h" +#include "util/u_threaded_context.h" #include "tr_dump.h" #include "tr_dump_defines.h" @@ -39,6 +41,7 @@ static bool trace = false; +static struct hash_table *trace_screens; static const char * trace_screen_get_name(struct pipe_screen *_screen) @@ -263,6 +266,28 @@ trace_screen_is_format_supported(struct pipe_screen *_screen, } +struct pipe_context * +trace_context_create_threaded(struct pipe_screen *screen, struct pipe_context *pipe) +{ + if (!trace_screens) + return pipe; + + struct hash_entry *he = _mesa_hash_table_search(trace_screens, screen); + if (!he) + return pipe; + struct trace_screen *tr_scr = trace_screen(he->data); + + if (tr_scr->trace_tc) + return pipe; + + struct pipe_context *ctx = trace_context_create(tr_scr, pipe); + if (ctx) { + struct trace_context *tr_ctx = trace_context(ctx); + tr_ctx->threaded = true; + } + return ctx; +} + static struct pipe_context * trace_screen_context_create(struct pipe_screen *_screen, void *priv, unsigned flags) @@ -271,19 +296,20 @@ trace_screen_context_create(struct pipe_screen *_screen, void *priv, struct pipe_screen *screen = tr_scr->screen; struct pipe_context *result; + result = screen->context_create(screen, priv, flags); + trace_dump_call_begin("pipe_screen", "context_create"); trace_dump_arg(ptr, screen); trace_dump_arg(ptr, priv); trace_dump_arg(uint, flags); - result = screen->context_create(screen, priv, flags); - trace_dump_ret(ptr, result); trace_dump_call_end(); - result = trace_context_create(tr_scr, result); + if (result && (tr_scr->trace_tc || result->draw_vbo != tc_draw_vbo)) + result = trace_context_create(tr_scr, result); return result; } @@ -707,6 +733,9 @@ trace_screen_fence_finish(struct pipe_screen *_screen, struct pipe_context *ctx = _ctx ? trace_context(_ctx)->pipe : NULL; int result; + result = screen->fence_finish(screen, ctx, fence, timeout); + + trace_dump_call_begin("pipe_screen", "fence_finish"); trace_dump_arg(ptr, screen); @@ -714,8 +743,6 @@ trace_screen_fence_finish(struct pipe_screen *_screen, trace_dump_arg(ptr, fence); trace_dump_arg(uint, timeout); - result = screen->fence_finish(screen, ctx, fence, timeout); - trace_dump_ret(bool, result); trace_dump_call_end(); @@ -804,6 +831,17 @@ trace_screen_destroy(struct pipe_screen *_screen) trace_dump_arg(ptr, screen); trace_dump_call_end(); + if (trace_screens) { + struct hash_entry *he = _mesa_hash_table_search(trace_screens, screen); + if (he) { + _mesa_hash_table_remove(trace_screens, he); + if (!_mesa_hash_table_num_entries(trace_screens)) { + _mesa_hash_table_destroy(trace_screens, NULL); + trace_screens = NULL; + } + } + } + screen->destroy(screen); FREE(tr_scr); @@ -904,6 +942,12 @@ trace_screen_create(struct pipe_screen *screen) trace_dump_ret(ptr, screen); trace_dump_call_end(); + if (!trace_screens) + trace_screens = _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); + _mesa_hash_table_insert(trace_screens, screen, tr_scr); + + tr_scr->trace_tc = debug_get_bool_option("GALLIUM_TRACE_TC", false); + return &tr_scr->base; error2: diff --git a/src/gallium/auxiliary/driver_trace/tr_screen.h b/src/gallium/auxiliary/driver_trace/tr_screen.h index 65ea4fb6a43..295574d1883 100644 --- a/src/gallium/auxiliary/driver_trace/tr_screen.h +++ b/src/gallium/auxiliary/driver_trace/tr_screen.h @@ -51,6 +51,7 @@ struct trace_screen struct pipe_screen base; struct pipe_screen *screen; + bool trace_tc; }; diff --git a/src/gallium/auxiliary/driver_trace/tr_texture.c b/src/gallium/auxiliary/driver_trace/tr_texture.c index d644e1b08ba..fd9b3d41884 100644 --- a/src/gallium/auxiliary/driver_trace/tr_texture.c +++ b/src/gallium/auxiliary/driver_trace/tr_texture.c @@ -70,7 +70,6 @@ error: void trace_surf_destroy(struct trace_surface *tr_surf) { - trace_context_check(tr_surf->base.context); pipe_resource_reference(&tr_surf->base.texture, NULL); pipe_surface_reference(&tr_surf->surface, NULL); FREE(tr_surf); @@ -91,15 +90,15 @@ trace_transfer_create(struct trace_context *tr_ctx, if (!tr_trans) goto error; - memcpy(&tr_trans->base, transfer, sizeof(struct pipe_transfer)); + memcpy(&tr_trans->base, transfer, tr_ctx->threaded ? sizeof(struct threaded_transfer) : sizeof(struct pipe_transfer)); - tr_trans->base.resource = NULL; + tr_trans->base.b.resource = NULL; tr_trans->transfer = transfer; - pipe_resource_reference(&tr_trans->base.resource, res); - assert(tr_trans->base.resource == res); + pipe_resource_reference(&tr_trans->base.b.resource, res); + assert(tr_trans->base.b.resource == res); - return &tr_trans->base; + return &tr_trans->base.b; error: tr_ctx->pipe->transfer_unmap(tr_ctx->pipe, transfer); @@ -111,7 +110,7 @@ void trace_transfer_destroy(struct trace_context *tr_context, struct trace_transfer *tr_trans) { - pipe_resource_reference(&tr_trans->base.resource, NULL); + pipe_resource_reference(&tr_trans->base.b.resource, NULL); FREE(tr_trans); } diff --git a/src/gallium/auxiliary/driver_trace/tr_texture.h b/src/gallium/auxiliary/driver_trace/tr_texture.h index e5dfc53fdb0..567842a5b22 100644 --- a/src/gallium/auxiliary/driver_trace/tr_texture.h +++ b/src/gallium/auxiliary/driver_trace/tr_texture.h @@ -33,6 +33,7 @@ #include "pipe/p_state.h" #include "tr_screen.h" +#include "util/u_threaded_context.h" struct trace_context; @@ -63,7 +64,7 @@ struct trace_sampler_view struct trace_transfer { - struct pipe_transfer base; + struct threaded_transfer base; struct pipe_transfer *transfer; struct pipe_context *pipe; diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index 56cb4f0de2e..75f75312613 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -30,6 +30,7 @@ #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_upload_mgr.h" +#include "driver_trace/tr_context.h" #include "util/log.h" #include "compiler/shader_info.h" @@ -3091,6 +3092,8 @@ threaded_context_create(struct pipe_context *pipe, } memset(tc, 0, sizeof(*tc)); + pipe = trace_context_create_threaded(pipe->screen, pipe); + assert((uintptr_t)tc % 16 == 0); /* These should be static asserts, but they don't work with MSVC */ assert(offsetof(struct threaded_context, batch_slots) % 16 == 0);