From 7dc6fbd5c56c27dc6ec4ffeda2e00979d27e8784 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 13 Feb 2026 12:04:52 -0800 Subject: [PATCH] gallium: Switch TIMESTAMP_RAW back to callback The original MR switched to use a float raw_timestamp_period to scale the raw timestamp outside of the gallium driver. This better matched how vulkan works. But unlike vulkan, gallium has timestamp related queries/APIs that return already scaled time, resulting in small errors if the way the scaling is done differs between driver scaling and frontend scaling. The important thing is that any error introduced by scaling must be the same error across APIs. (In particular, a f64 value cannot preciesly represent an arbitrary u64 value. OTOH the driver's scaling could be simply multiply be an integer. But differing precision errors of the two approachs causes problems when comparing between timestamps that are converted in different ways.) In some, but not all, cases this could be addressed by changing the driver to use the same scaling function, but this is not always possible (if, for ex, the scaling is done on the GPU CP). So switch back to the original approach from !39995, using a pscreen->convert_timestamp() callback, to put the control back in the hands of the driver. Signed-off-by: Rob Clark Part-of: --- docs/gallium/context.rst | 7 +++---- src/gallium/drivers/freedreno/freedreno_screen.c | 11 +++++++++-- src/gallium/include/pipe/p_defines.h | 9 --------- src/gallium/include/pipe/p_screen.h | 8 ++++++++ 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/docs/gallium/context.rst b/docs/gallium/context.rst index 326bfdcfd17..a73a30af219 100644 --- a/docs/gallium/context.rst +++ b/docs/gallium/context.rst @@ -468,10 +468,9 @@ The result is an unsigned 64-bit integer. ``PIPE_QUERY_TIMESTAMP_RAW`` returns a device/driver timestamp, recorded after all commands issued prior to ``end_query`` have been processed. This query does not require a call to ``begin_query``. -The result is an unsigned 64-bit integer. ``pipe_caps.raw_timestamp_period`` -should be set by the driver to provide the scaling factor the raw timestamp -is multiplied by to get nanoseconds. - +The result is an unsigned 64-bit integer. ``pipe_screen::convert_timestamp()`` +should be implemented, to covert the raw timestamp to nanoseconds, if +this query type is supported. ``PIPE_QUERY_TIMESTAMP_DISJOINT`` can be used to check the internal timer resolution and whether the timestamp counter has become unreliable due to things like throttling etc. - only if this is FALSE diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 15b1019890a..156704510b9 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -132,6 +132,12 @@ fd_screen_get_timestamp(struct pipe_screen *pscreen) } } +static uint64_t +fd_screen_convert_timestamp(struct pipe_screen *pscreen, uint64_t raw_timestamp) +{ + return ticks_to_ns(raw_timestamp); +} + static void fd_screen_destroy(struct pipe_screen *pscreen) { @@ -682,8 +688,6 @@ fd_init_screen_caps(struct fd_screen *screen) if (is_a6xx(screen)) { caps->shader_clock = true; - /* PIPE_QUERY_TIMESTAMP_RAW: 19.2MHz RBBM always-on timer */ - caps->raw_timestamp_period = 1000000000.0 / 19200000.0; } } @@ -1074,6 +1078,9 @@ fd_screen_create(int fd, pscreen->get_timestamp = fd_screen_get_timestamp; + if (is_a6xx(screen)) + pscreen->convert_timestamp = fd_screen_convert_timestamp; + pscreen->fence_reference = _fd_fence_ref; pscreen->fence_finish = fd_pipe_fence_finish; pscreen->fence_get_fd = fd_pipe_fence_get_fd; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 1ffb418d335..f1ecef1a21f 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -1169,15 +1169,6 @@ struct pipe_caps { float max_conservative_raster_dilate; float conservative_raster_dilate_granularity; - /** - * If the driver supports PIPE_QUERY_TIMESTAMP_RAW this should - * be set to the scaling factor to multiply the raw timestamp - * by to get nanoseconds. - * - * Should be zero if the driver does not implement the query. - */ - float raw_timestamp_period; - struct pipe_mesh_caps mesh; }; diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 79cf3c4f745..fd458f51e1b 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -164,6 +164,14 @@ struct pipe_screen { */ uint64_t (*get_timestamp)(struct pipe_screen *); + /** + * If the driver supports PIPE_QUERY_TIMESTAMP_RAW, this function + * must be implemented to convert the drivers raw timestamp to ns. + * If the driver does not support PIPE_QUERY_TIMESTAMP_RAW, it should + * not implement this function. + */ + uint64_t (*convert_timestamp)(struct pipe_screen *, uint64_t raw_timestamp); + /** * Return an equivalent canonical format which has the same component sizes * and swizzles as the original, and it is supported by the driver. Gallium