wgpu_profiler/
profiler_query.rs

1use std::{ops::Range, thread::ThreadId};
2
3use crate::profiler::{
4    GpuTimerQueryTreeHandle, QueryPairUsageState, ReservedTimerQueryPair, ROOT_QUERY_HANDLE,
5};
6
7/// The result of a gpu timer scope.
8#[derive(Debug, Clone)]
9pub struct GpuTimerQueryResult {
10    /// Label that was specified when opening the scope.
11    pub label: String,
12
13    /// The process id of the process that opened this scope.
14    pub pid: u32,
15
16    /// The thread id of the thread that opened this scope.
17    pub tid: ThreadId,
18
19    /// Time range of this scope in seconds.
20    ///
21    /// Meaning of absolute value is not defined.
22    /// If timestamp writing was disabled for this scope, this is None.
23    pub time: Option<Range<f64>>,
24
25    /// Scopes that were opened while this scope was open.
26    pub nested_queries: Vec<GpuTimerQueryResult>,
27}
28
29/// An inflight query for the profiler.
30///
31/// If timer queries are enabled, this represents a reserved timer query pair on
32/// one of the profiler's query sets.
33/// *Must* be closed by calling [`GpuProfiler::end_query`].
34///
35/// Emitted by [`GpuProfiler::begin_query`]/[`GpuProfiler::begin_pass_query`] and consumed by [`GpuProfiler::end_query`].
36///
37/// [`GpuProfiler::begin_pass_query`]: crate::GpuProfiler::begin_pass_query
38/// [`GpuProfiler::begin_query`]: crate::GpuProfiler::begin_query
39/// [`GpuProfiler::end_query`]: crate::GpuProfiler::end_query
40pub struct GpuProfilerQuery {
41    /// The label assigned to this query.
42    /// Will be moved into [`GpuProfilerQuery::label`] once the query is fully processed.
43    pub label: String,
44
45    /// The process id of the process that opened this query.
46    pub pid: u32,
47
48    /// The thread id of the thread that opened this query.
49    pub tid: ThreadId,
50
51    /// The actual query on a query pool if any (none if disabled for this type of query).
52    pub(crate) timer_query_pair: Option<ReservedTimerQueryPair>,
53
54    /// Handle which identifies this query, used for building the tree of queries.
55    pub(crate) handle: GpuTimerQueryTreeHandle,
56
57    /// Which query this query is a child of.
58    pub(crate) parent_handle: GpuTimerQueryTreeHandle,
59
60    /// Whether a debug group was opened for this scope.
61    pub(crate) has_debug_group: bool,
62
63    #[cfg(feature = "tracy")]
64    pub(crate) tracy_scope: Option<tracy_client::GpuSpan>,
65}
66
67impl GpuProfilerQuery {
68    /// Use the reserved query for render pass timestamp writes if any.
69    ///
70    /// Use this only for a single render/compute pass, otherwise results will be overwritten.
71    /// Only ever returns `Some` for queries that were created using [`GpuProfiler::begin_pass_query`].
72    ///
73    /// [`GpuProfiler::begin_pass_query`]: crate::GpuProfiler::begin_pass_query
74    pub fn render_pass_timestamp_writes(&self) -> Option<wgpu::RenderPassTimestampWrites> {
75        self.timer_query_pair.as_ref().and_then(|query| {
76            (query.usage_state == QueryPairUsageState::ReservedForPassTimestampWrites).then(|| {
77                wgpu::RenderPassTimestampWrites {
78                    query_set: &query.pool.query_set,
79                    beginning_of_pass_write_index: Some(query.start_query_idx),
80                    end_of_pass_write_index: Some(query.start_query_idx + 1),
81                }
82            })
83        })
84    }
85
86    /// Use the reserved query for compute pass timestamp writes if any.
87    ///
88    /// Use this only for a single render/compute pass, otherwise results will be overwritten.
89    /// Only ever returns `Some` for queries that were created using [`GpuProfiler::begin_pass_query`].
90    ///
91    /// [`GpuProfiler::begin_pass_query`]: crate::GpuProfiler::begin_pass_query
92    pub fn compute_pass_timestamp_writes(&self) -> Option<wgpu::ComputePassTimestampWrites> {
93        self.timer_query_pair.as_ref().and_then(|query| {
94            (query.usage_state == QueryPairUsageState::ReservedForPassTimestampWrites).then(|| {
95                wgpu::ComputePassTimestampWrites {
96                    query_set: &query.pool.query_set,
97                    beginning_of_pass_write_index: Some(query.start_query_idx),
98                    end_of_pass_write_index: Some(query.start_query_idx + 1),
99                }
100            })
101        })
102    }
103
104    /// Makes this scope a child of the passed scope.
105    #[inline]
106    pub fn with_parent(self, parent: Option<&GpuProfilerQuery>) -> Self {
107        Self {
108            parent_handle: parent.map_or(ROOT_QUERY_HANDLE, |p| p.handle),
109            ..self
110        }
111    }
112}