summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>2021-11-07 23:41:05 +0200
committerMarge Bot <emma+marge@anholt.net>2021-11-22 11:52:46 +0000
commit8657fa6b868880021046b0ef73a4a8a20648d93a (patch)
treefeda3858cc41c03429c8469df793da256e2af774 /src
parent457dbb81f5c3bc86d4968c6f099154abd39c829e (diff)
pps: allow drivers to report timestamps in their own time domain
For this each driver must : - report its clock_id (if no particular clock just default to cpu boottime one) - be able to sample its clock (gpu_timestamp()) The PPSDataSource will then emit timestamp correlation events in the trace ensuring perfetto is able to display GPU & CPU events appropriately on its timeline. Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Reviewed-by: Antonio Caggiano <antonio.caggiano@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13831>
Diffstat (limited to 'src')
-rw-r--r--src/freedreno/ds/fd_pps_driver.cc12
-rw-r--r--src/freedreno/ds/fd_pps_driver.h2
-rw-r--r--src/intel/ds/intel_pps_driver.cc10
-rw-r--r--src/intel/ds/intel_pps_driver.h3
-rw-r--r--src/panfrost/ds/pan_pps_driver.cc10
-rw-r--r--src/panfrost/ds/pan_pps_driver.h2
-rw-r--r--src/tool/pps/pps_datasource.cc66
-rw-r--r--src/tool/pps/pps_datasource.h8
-rw-r--r--src/tool/pps/pps_driver.h8
9 files changed, 109 insertions, 12 deletions
diff --git a/src/freedreno/ds/fd_pps_driver.cc b/src/freedreno/ds/fd_pps_driver.cc
index 88697bf6111..97305c911ae 100644
--- a/src/freedreno/ds/fd_pps_driver.cc
+++ b/src/freedreno/ds/fd_pps_driver.cc
@@ -389,4 +389,16 @@ FreedrenoDriver::counter(std::string name, Counter::Units units,
return counter;
}
+uint32_t
+FreedrenoDriver::gpu_clock_id() const
+{
+ return perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
+}
+
+uint64_t
+FreedrenoDriver::gpu_timestamp() const
+{
+ return perfetto::base::GetBootTimeNs().count();
+}
+
} // namespace pps
diff --git a/src/freedreno/ds/fd_pps_driver.h b/src/freedreno/ds/fd_pps_driver.h
index 8a738e26dbd..29f738b313e 100644
--- a/src/freedreno/ds/fd_pps_driver.h
+++ b/src/freedreno/ds/fd_pps_driver.h
@@ -28,6 +28,8 @@ public:
void disable_perfcnt() override;
bool dump_perfcnt() override;
uint64_t next() override;
+ uint32_t gpu_clock_id() const override;
+ uint64_t gpu_timestamp() const override;
private:
struct fd_device *dev;
diff --git a/src/intel/ds/intel_pps_driver.cc b/src/intel/ds/intel_pps_driver.cc
index 6c79acd0ad0..6966db8fdc1 100644
--- a/src/intel/ds/intel_pps_driver.cc
+++ b/src/intel/ds/intel_pps_driver.cc
@@ -400,4 +400,14 @@ uint64_t IntelDriver::next()
return cpu_next();
}
+uint32_t IntelDriver::gpu_clock_id() const
+{
+ return perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
+}
+
+uint64_t IntelDriver::gpu_timestamp() const
+{
+ return perfetto::base::GetBootTimeNs().count();
+}
+
} // namespace pps
diff --git a/src/intel/ds/intel_pps_driver.h b/src/intel/ds/intel_pps_driver.h
index 5df48e2f4ec..cac029a973e 100644
--- a/src/intel/ds/intel_pps_driver.h
+++ b/src/intel/ds/intel_pps_driver.h
@@ -51,7 +51,10 @@ class IntelDriver : public Driver
void disable_perfcnt() override;
bool dump_perfcnt() override;
uint64_t next() override;
+ uint32_t gpu_clock_id() const override;
+ uint64_t gpu_timestamp() const override;
+ private:
/// @brief Requests the next perf sample
/// @return The sample GPU timestamp
uint32_t gpu_next();
diff --git a/src/panfrost/ds/pan_pps_driver.cc b/src/panfrost/ds/pan_pps_driver.cc
index fbe9263748d..0453475b46d 100644
--- a/src/panfrost/ds/pan_pps_driver.cc
+++ b/src/panfrost/ds/pan_pps_driver.cc
@@ -157,4 +157,14 @@ void PanfrostDriver::disable_perfcnt()
enabled_counters.clear();
}
+uint32_t PanfrostDriver::gpu_clock_id() const
+{
+ return perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
+}
+
+uint64_t PanfrostDriver::gpu_timestamp() const
+{
+ return perfetto::base::GetBootTimeNs().count();
+}
+
} // namespace pps
diff --git a/src/panfrost/ds/pan_pps_driver.h b/src/panfrost/ds/pan_pps_driver.h
index de764b18aae..f6476d9dee3 100644
--- a/src/panfrost/ds/pan_pps_driver.h
+++ b/src/panfrost/ds/pan_pps_driver.h
@@ -41,6 +41,8 @@ class PanfrostDriver : public Driver
void disable_perfcnt() override;
bool dump_perfcnt() override;
uint64_t next() override;
+ uint32_t gpu_clock_id() const override;
+ uint64_t gpu_timestamp() const override;
uint64_t last_dump_ts = 0;
diff --git a/src/tool/pps/pps_datasource.cc b/src/tool/pps/pps_datasource.cc
index 3b5a083b80f..9eac41b9ade 100644
--- a/src/tool/pps/pps_datasource.cc
+++ b/src/tool/pps/pps_datasource.cc
@@ -18,6 +18,8 @@
// Minimum supported sampling period in nanoseconds
#define MIN_SAMPLING_PERIOD_NS 50000
+#define CORRELATION_TIMESTAMP_PERIOD (1000000000ull)
+
namespace pps
{
static std::string driver_name;
@@ -232,11 +234,37 @@ void add_samples(perfetto::protos::pbzero::GpuCounterEvent &event, const Driver
}
}
+void add_timestamp(perfetto::protos::pbzero::ClockSnapshot *event, const Driver *driver)
+{
+ uint32_t gpu_clock_id = driver->gpu_clock_id();
+ if (perfetto::protos::pbzero::BUILTIN_CLOCK_BOOTTIME == gpu_clock_id)
+ return;
+
+ // Send a correlation event between GPU & CPU timestamps
+ uint64_t cpu_ts = perfetto::base::GetBootTimeNs().count();
+ uint64_t gpu_ts = driver->gpu_timestamp();
+
+ {
+ 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);
+ }
+}
+
void GpuDataSource::trace(TraceContext &ctx)
{
using namespace perfetto::protos::pbzero;
- if (auto state = ctx.GetIncrementalState(); state->was_cleared) {
+ auto state = ctx.GetIncrementalState();
+ if (state->was_cleared) {
// Mark any incremental state before this point invalid
{
auto packet = ctx.NewTracePacket();
@@ -248,14 +276,23 @@ void GpuDataSource::trace(TraceContext &ctx)
descriptor_timestamp = perfetto::base::GetBootTimeNs().count();
packet->set_timestamp(descriptor_timestamp);
- auto event = packet->set_gpu_counter_event();
- event->set_gpu_id(driver->drm_device.gpu_num);
+ {
+ auto event = packet->set_gpu_counter_event();
+ event->set_gpu_id(driver->drm_device.gpu_num);
- auto &groups = driver->groups;
- auto &counters = driver->enabled_counters;
- PPS_LOG("Sending counter descriptors");
- add_descriptors(event, groups, counters, *driver);
+ auto &groups = driver->groups;
+ auto &counters = driver->enabled_counters;
+ PPS_LOG("Sending counter descriptors");
+ add_descriptors(event, groups, counters, *driver);
+ }
+ {
+ last_correlation_timestamp = perfetto::base::GetBootTimeNs().count();
+ auto event = packet->set_clock_snapshot();
+ add_timestamp(event, driver);
+ }
+
+ descriptor_gpu_timestamp = driver->gpu_timestamp();
state->was_cleared = false;
}
@@ -272,15 +309,16 @@ void GpuDataSource::trace(TraceContext &ctx)
sched_setscheduler(0, sched_policy, &priority_param);
if (driver->dump_perfcnt()) {
- while (auto timestamp = driver->next()) {
- if (timestamp <= descriptor_timestamp) {
+ while (auto gpu_timestamp = driver->next()) {
+ if (gpu_timestamp <= descriptor_gpu_timestamp) {
// Do not send counter values before counter descriptors
PPS_LOG_ERROR("Skipping counter values coming before descriptors");
continue;
}
auto packet = ctx.NewTracePacket();
- packet->set_timestamp(timestamp);
+ packet->set_timestamp_clock_id(driver->gpu_clock_id());
+ packet->set_timestamp(gpu_timestamp);
auto event = packet->set_gpu_counter_event();
event->set_gpu_id(driver->drm_device.gpu_num);
@@ -289,6 +327,14 @@ void GpuDataSource::trace(TraceContext &ctx)
}
}
+ uint64_t cpu_ts = perfetto::base::GetBootTimeNs().count();
+ if ((cpu_ts - last_correlation_timestamp) > CORRELATION_TIMESTAMP_PERIOD) {
+ auto packet = ctx.NewTracePacket();
+ auto event = packet->set_clock_snapshot();
+ add_timestamp(event, driver);
+ last_correlation_timestamp = cpu_ts;
+ }
+
// Reset normal scheduler
sched_setscheduler(0, prev_sched_policy, &prev_priority_param);
}
diff --git a/src/tool/pps/pps_datasource.h b/src/tool/pps/pps_datasource.h
index 96a83b5ae97..f2946cbd6a5 100644
--- a/src/tool/pps/pps_datasource.h
+++ b/src/tool/pps/pps_datasource.h
@@ -53,12 +53,18 @@ class GpuDataSource : public perfetto::DataSource<GpuDataSource, GpuDataSourceTr
/// Used to check whether the datasource is quick enough
std::chrono::nanoseconds time_to_trace;
+ /// Last CPU timestamp at which we correlated CPU/GPU timestamps
+ uint64_t last_correlation_timestamp = 0;
+
/// A data source supports one driver at a time, but if you need more
/// than one gpu datasource you can just run another producer
Driver *driver = nullptr;
- /// Timestamp of packet sent with counter descriptors
+ /// CPU timestamp of packet sent with counter descriptors
uint64_t descriptor_timestamp = 0;
+
+ /// GPU timestamp of packet sent with counter descriptors
+ uint64_t descriptor_gpu_timestamp = 0;
};
} // namespace pps
diff --git a/src/tool/pps/pps_driver.h b/src/tool/pps/pps_driver.h
index 55849d07ada..8d1c59631ac 100644
--- a/src/tool/pps/pps_driver.h
+++ b/src/tool/pps/pps_driver.h
@@ -72,9 +72,15 @@ class Driver
/// @brief After dumping performance counters, with this function you can iterate
/// through the samples collected.
- /// @return The CPU timestamp associated to current sample, or 0 if there are no more samples
+ /// @return The GPU timestamp associated to current sample, or 0 if there are no more samples
virtual uint64_t next() = 0;
+ /// Clock ID in which the values returned by gpu_timestamp() belong
+ virtual uint32_t gpu_clock_id() const = 0;
+
+ /// Sample a timestamp from the GPU
+ virtual uint64_t gpu_timestamp() const = 0;
+
DrmDevice drm_device;
/// List of counter groups