fyrox_graphics/query.rs
1//! A query object is used to fetch some data from rendering operations asynchronously. See
2//! [`GpuQueryTrait`] docs for more info.
3
4#![warn(missing_docs)]
5
6use crate::define_shared_wrapper;
7use fyrox_core::define_as_any_trait;
8use std::fmt::Debug;
9
10/// Kind of a GPU query.
11#[derive(Copy, Clone, Debug)]
12pub enum QueryKind {
13 /// Queries a number of rendered pixels; any pixel that passed all pipeline tests counts.
14 SamplesPassed,
15
16 /// Queries a flag that defines whether the rendering operation produced any pixels or not.
17 AnySamplesPassed,
18}
19
20/// Result of a query.
21#[derive(Debug)]
22pub enum QueryResult {
23 /// Number of rendered pixels; any pixel that passed all pipeline tests counts.
24 SamplesPassed(u32),
25
26 /// A flag that defines whether the rendering operation produced any pixels or not.
27 AnySamplesPassed(bool),
28}
29
30define_as_any_trait!(GpuQueryAsAny => GpuQueryTrait);
31
32/// A query object is used to fetch some data from rendering operations asynchronously. Usually it
33/// is used to perform occlusion queries.
34///
35/// ## Examples
36///
37/// The following examples shows how to create a new GPU query, run it and fetch the result.
38///
39/// ```rust
40/// use fyrox_graphics::{
41/// error::FrameworkError,
42/// query::{QueryKind, QueryResult},
43/// server::GraphicsServer,
44/// };
45///
46/// fn query(server: &dyn GraphicsServer) -> Result<(), FrameworkError> {
47/// // Initialization.
48/// let query = server.create_query()?;
49///
50/// // Somewhere in the rendering loop.
51/// if !query.is_started() {
52/// query.begin(QueryKind::AnySamplesPassed);
53///
54/// // Draw something.
55///
56/// query.end();
57/// } else if let Some(QueryResult::AnySamplesPassed(any_samples_passed)) =
58/// query.try_get_result()
59/// {
60/// println!("{any_samples_passed}");
61/// }
62///
63/// Ok(())
64/// }
65/// ```
66///
67/// Keep in mind that you should always re-use the queries instead of creating them on the fly!
68/// This is much more efficient, because it removes all redundant memory allocations and calls
69/// to the GPU driver.
70pub trait GpuQueryTrait: GpuQueryAsAny + Debug {
71 /// Begins a query of the given kind. All drawing commands must be enclosed withing a pair of
72 /// this method and [`Self::end`] calls. See [`QueryKind`] for more info.
73 fn begin(&self, kind: QueryKind);
74
75 /// Ends the query. Must be called after and in pair with [`Self::begin`].
76 fn end(&self);
77
78 /// Returns `true` if the query is started ([`Self::begin`] was called).
79 fn is_started(&self) -> bool;
80
81 /// Tries to fetch the query result without blocking. The query object guarantees that the
82 /// result will be stored until the next call of [`Self::begin`], so consecutive calls of this
83 /// method are allowed.
84 fn try_get_result(&self) -> Option<QueryResult>;
85}
86
87define_shared_wrapper!(GpuQuery<dyn GpuQueryTrait>);