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