perfetto: Deduplicate clock sync packet emit from renderstage sources.

This is way more horrifying than I hoped -- I can't figure out a way to
have the method be on TraceContext, so it's a static method of the
datasource, but then you have to name the templated types over and over.
You have to pass in a TraceContext because intel emits the clock sync
packet within a Trace(), and perfetto just silently corrupts the trace if
you Trace() in a Trace().

Reviewed-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22157>
This commit is contained in:
Emma Anholt 2023-03-16 13:21:44 -07:00 committed by Marge Bot
parent 3fd825d3e2
commit 9c364a346f
4 changed files with 58 additions and 66 deletions

View file

@ -340,32 +340,15 @@ sync_timestamp(struct tu_device *dev)
return;
}
gpu_max_timestamp = gpu_ts;
TuRenderpassDataSource::Trace([=](TuRenderpassDataSource::TraceContext tctx) {
auto packet = tctx.NewTracePacket();
packet->set_timestamp(cpu_ts);
auto event = packet->set_clock_snapshot();
{
auto clock = event->add_clocks();
clock->set_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
clock->set_timestamp(cpu_ts);
}
{
auto clock = event->add_clocks();
clock->set_clock_id(gpu_clock_id);
clock->set_timestamp(gpu_ts);
}
sync_gpu_ts = gpu_ts;
next_clock_sync_ns = cpu_ts + 30000000;
TuRenderpassDataSource::Trace([=](auto tctx) {
MesaRenderpassDataSource<TuRenderpassDataSource,
TuRenderpassTraits>::EmitClockSync(tctx, cpu_ts,
gpu_ts, gpu_clock_id);
});
gpu_max_timestamp = gpu_ts;
sync_gpu_ts = gpu_ts;
next_clock_sync_ns = cpu_ts + 30000000;
}
static void

View file

@ -306,30 +306,14 @@ sync_timestamp(struct fd_context *ctx)
/* convert GPU ts into ns: */
gpu_ts = ctx->ts_to_ns(gpu_ts);
FdRenderpassDataSource::Trace([=](FdRenderpassDataSource::TraceContext tctx) {
auto packet = tctx.NewTracePacket();
packet->set_timestamp(cpu_ts);
auto event = packet->set_clock_snapshot();
{
auto clock = event->add_clocks();
clock->set_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
clock->set_timestamp(cpu_ts);
}
{
auto clock = event->add_clocks();
clock->set_clock_id(gpu_clock_id);
clock->set_timestamp(gpu_ts);
}
sync_gpu_ts = gpu_ts;
next_clock_sync_ns = cpu_ts + 30000000;
FdRenderpassDataSource::Trace([=](auto tctx) {
MesaRenderpassDataSource<FdRenderpassDataSource,
FdRenderpassTraits>::EmitClockSync(tctx, cpu_ts,
gpu_ts, gpu_clock_id);
});
sync_gpu_ts = gpu_ts;
next_clock_sync_ns = cpu_ts + 30000000;
}
static void

View file

@ -128,24 +128,8 @@ sync_timestamp(IntelRenderpassDataSource::TraceContext &ctx,
device->sync_gpu_ts = gpu_ts;
device->next_clock_sync_ns = cpu_ts + 1000000000ull;
auto packet = ctx.NewTracePacket();
packet->set_timestamp_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
packet->set_timestamp(cpu_ts);
auto event = packet->set_clock_snapshot();
{
auto clock = event->add_clocks();
clock->set_clock_id(perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
clock->set_timestamp(cpu_ts);
}
{
auto clock = event->add_clocks();
clock->set_clock_id(device->gpu_clock_id);
clock->set_timestamp(gpu_ts);
}
MesaRenderpassDataSource<IntelRenderpassDataSource, IntelRenderpassTraits>::EmitClockSync(ctx,
cpu_ts, gpu_ts, device->gpu_clock_id);
}
static void

View file

@ -29,7 +29,12 @@ using perfetto::DataSource;
template <typename DataSourceType, typename DataSourceTraits>
class MesaRenderpassDataSource
: public perfetto::DataSource<DataSourceType, DataSourceTraits> {
public:
typedef typename perfetto::DataSource<DataSourceType,
DataSourceTraits>::TraceContext
TraceContext;
void OnSetup(const perfetto::DataSourceBase::SetupArgs &) override
{
// Use this callback to apply any custom configuration to your data
@ -59,6 +64,42 @@ class MesaRenderpassDataSource
ctx.Flush();
});
}
/* Emits a clock sync trace event. Perfetto uses periodic clock events
* like this to sync up our GPU render stages with the CPU on the same
* timeline, since clocks always drift over time. Note that perfetto
* relies on gpu_ts being monotonic, and will perform badly if it goes
* backwards -- see tu_perfetto.cc for an example implemntation of handling
* going backwards.
*/
static void EmitClockSync(TraceContext &ctx,
uint64_t cpu_ts,
uint64_t gpu_ts,
uint32_t gpu_clock_id)
{
auto packet = ctx.NewTracePacket();
packet->set_timestamp_clock_id(
perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
packet->set_timestamp(cpu_ts);
auto event = packet->set_clock_snapshot();
{
auto clock = event->add_clocks();
clock->set_clock_id(
perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME);
clock->set_timestamp(cpu_ts);
}
{
auto clock = event->add_clocks();
clock->set_clock_id(gpu_clock_id);
clock->set_timestamp(gpu_ts);
}
}
};
/* Begin the C API section. */