khora_core/renderer/traits/
profiler.rs

1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use super::command_recorder::CommandEncoder;
16use std::any::Any;
17
18/// A trait for GPU performance profilers that use timestamp queries.
19///
20/// This trait defines the interface for a system that can measure the execution time
21/// of GPU operations within a frame. It is designed to be stateful and operate
22/// across multiple frames due to the inherent latency of reading back data from the GPU.
23///
24/// An implementation of this trait will typically manage a set of timestamp query sets
25/// and staging buffers to transfer timing data from the GPU to the CPU without stalling
26/// the rendering pipeline.
27///
28/// The `Any` supertrait is required to allow for downcasting to a concrete profiler
29/// type within backend-specific `CommandEncoder` implementations.
30pub trait GpuProfiler: Any + Send + Sync {
31    /// Attempts to read the results from a frame that finished rendering a few frames ago.
32    ///
33    /// This should be called once per frame, typically at the beginning, before any new
34    /// commands are recorded. It checks for completed buffer mappings from previous frames
35    /// and updates the internal timing statistics.
36    fn try_read_previous_frame(&mut self);
37
38    /// Encodes the commands necessary to resolve the current frame's timestamp queries.
39    ///
40    /// This should be called at the end of a `RenderPass` or command buffer where
41    /// profiling queries were written. It converts the raw timestamp data into a
42    /// format that can be read by the CPU.
43    fn resolve_and_copy(&self, encoder: &mut dyn CommandEncoder);
44
45    /// Encodes commands to copy the resolved query data into a CPU-readable staging buffer.
46    ///
47    /// This is typically called at the very end of the frame's command recording.
48    fn copy_to_staging(&self, encoder: &mut dyn CommandEncoder, frame_index: u64);
49
50    /// Schedules the asynchronous mapping of a staging buffer for CPU readback.
51    ///
52    /// This operation is non-blocking. It tells the GPU driver that we intend to
53    /// read this buffer on the CPU in a future frame, once all commands for the
54    /// current frame have been executed.
55    fn schedule_map_after_submit(&mut self, frame_index: u64);
56
57    /// Returns the smoothed duration of the main rendering pass in milliseconds.
58    ///
59    /// This value is typically averaged over several frames to provide a stable reading.
60    fn last_main_pass_ms(&self) -> f32;
61
62    /// Returns the smoothed total duration of the frame on the GPU in milliseconds.
63    ///
64    /// This value is typically averaged over several frames to provide a stable reading.
65    fn last_frame_total_ms(&self) -> f32;
66
67    /// Returns a reference to `self` as a `&dyn Any` trait object.
68    fn as_any(&self) -> &dyn Any;
69
70    /// Returns a mutable reference to `self` as a `&mut dyn Any` trait object.
71    fn as_any_mut(&mut self) -> &mut dyn Any;
72}