pps: generate forward-looking counters

end-of-interval timestamps are broken by !40233
See https://github.com/google/perfetto/issues/5683 for details.

Reviewed-by: Rob Clark <rob.clark@oss.qualcomm.com>
Reviewed-by: Dylan Baker <dylan.c.baker@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42035>
This commit is contained in:
Caleb Callaway 2026-06-04 19:24:34 +00:00 committed by Marge Bot
parent aabf7b9a94
commit 2e6507f0e8
4 changed files with 29 additions and 1 deletions

View file

@ -34,6 +34,7 @@ public:
void disable_perfcnt() override;
bool dump_perfcnt() override;
uint64_t next() override;
bool sample_timestamps_are_interval_starts() const override { return true; }
uint32_t gpu_clock_id() const override;
uint64_t gpu_timestamp() const override;
bool cpu_gpu_timestamp(uint64_t &cpu_timestamp,

View file

@ -168,6 +168,10 @@ template <typename GpuCounterDescriptor> void add_descriptors(GpuCounterDescript
spec->set_name(counter.name);
spec->set_description(counter.description);
// These counters describe the interval starting at the sample timestamp.
spec->set_value_direction(
GpuCounterDescriptor::GpuCounterSpec::VALUE_DIRECTION_FORWARDS_LOOKING);
auto units = GpuCounterDescriptor::NONE;
switch (counter.units) {
case Counter::Units::Percent:
@ -302,10 +306,27 @@ void GpuDataSource::trace(TraceContext &ctx)
descriptor_gpu_timestamp = driver->gpu_timestamp();
state->was_cleared = false;
state->last_counter_vals.clear();
state->has_prev_sample_end_timestamp = false;
state->prev_sample_end_timestamp = 0;
}
if (driver->dump_perfcnt()) {
while (auto gpu_timestamp = driver->next()) {
while (auto sample_timestamp = driver->next()) {
uint64_t gpu_timestamp = sample_timestamp;
if (!driver->sample_timestamps_are_interval_starts()) {
if (!state->has_prev_sample_end_timestamp) {
state->has_prev_sample_end_timestamp = true;
state->prev_sample_end_timestamp = sample_timestamp;
continue;
}
// Convert end-of-interval timestamps to start-of-interval
// for VALUE_DIRECTION_FORWARDS_LOOKING counters.
gpu_timestamp = state->prev_sample_end_timestamp;
state->prev_sample_end_timestamp = sample_timestamp;
}
if (gpu_timestamp <= descriptor_gpu_timestamp) {
// Do not send counter values before counter descriptors
PPS_LOG_ERROR("Skipping counter values coming before descriptors");

View file

@ -17,6 +17,8 @@ namespace pps
struct GpuIncrementalState {
bool was_cleared = true;
std::unordered_map<uint32_t, double> last_counter_vals;
bool has_prev_sample_end_timestamp = false;
uint64_t prev_sample_end_timestamp = 0;
};
struct GpuDataSourceTraits : public perfetto::DefaultDataSourceTraits {

View file

@ -78,6 +78,10 @@ class Driver
/// @return The GPU timestamp associated to current sample, or 0 if there are no more samples
virtual uint64_t next() = 0;
/// @return True when next() timestamps mark the start of the sampling interval.
/// Drivers returning end-of-interval timestamps should leave this false.
virtual bool sample_timestamps_are_interval_starts() const { return false; }
/// Clock ID in which the values returned by gpu_timestamp() belong
virtual uint32_t gpu_clock_id() const = 0;