pub struct FrameStats {Show 33 fields
pub total_objects: u32,
pub visible_objects: u32,
pub culled_objects: u32,
pub draw_calls: u32,
pub instanced_batches: u32,
pub per_object_items: u32,
pub per_object_bind_groups_built: u32,
pub batches_reuploaded: u32,
pub batches_skipped: u32,
pub decal_uploads: u32,
pub decal_reused: u32,
pub triangles_submitted: u64,
pub shadow_draw_calls: u32,
pub cpu_prepare_ms: f32,
pub prepare_breakdown: PrepareBreakdown,
pub cpu_paint_ms: f32,
pub gpu_frame_ms: Option<f32>,
pub gpu_breakdown: GpuBreakdown,
pub total_frame_ms: f32,
pub render_scale: f32,
pub missed_budget: bool,
pub upload_bytes: u64,
pub gpu_culling_active: bool,
pub gpu_visible_instances: Option<u32>,
pub gpu_culled_total: Option<u32>,
pub gpu_frustum_visible: Option<u32>,
pub shadows_skipped: bool,
pub volume_quality_reduced: bool,
pub effects_throttled: bool,
pub lod_items_resolved: u32,
pub lod_switches: u32,
pub lod_culled: u32,
pub lod_items_reduced: u32,
}Expand description
Per-frame rendering statistics returned by crate::ViewportRenderer::prepare.
Fields§
§total_objects: u32Total objects considered for rendering.
visible_objects: u32Objects that passed visibility and frustum tests.
culled_objects: u32Objects culled by frustum or visibility.
draw_calls: u32Number of draw calls issued in the main pass.
instanced_batches: u32Number of instanced batches (0 when using per-object path).
per_object_items: u32Visible items that miss the instanced fast path and are drawn one at a time through the per-object path.
An item is non-instanceable when it uses a styled back-face policy
(different-colour/tint/pattern) or is two-sided and transparent, uses a
matcap, has a scalar attribute or parameter visualization, carries a
position/normal override, has per-instance deform data (skinning), or is
hit by a compute filter. Each such item costs a uniform write and a bind-group
build in prepare, so a large count here means prepare is paying
per-object cost across much of the scene rather than batching it.
per_object_bind_groups_built: u32Per-object bind groups actually (re)built this frame.
The per-object path caches bind groups and skips the rebuild when the
item’s textures, attributes, and overrides are unchanged. A value near
per_object_items means the cache is missing most frames (for example
because items move between slots); a value near zero means the remaining
per-object cost is the uniform writes, not the bind-group builds.
batches_reuploaded: u32Instanced batches whose GPU sub-range was re-uploaded this frame.
Non-zero only on cache-miss frames where at least one batch’s instance
data changed. Zero on cache-hit frames and when the per-object path is
active. Together with batches_skipped, this lets callers measure how
effective the dirty-flagging optimisation is for their scene.
batches_skipped: u32Instanced batches whose GPU sub-range was reused unchanged this frame.
Non-zero only on cache-miss frames where at least one batch compared equal to the cached data and its write was skipped. Zero on cache-hit frames (no upload attempted at all) and when the per-object path is active.
decal_uploads: u32Decals whose GPU buffer + bind group were built this frame (cache miss).
Non-zero only when a decal is new or its content changed. In steady state with static decals this is zero after the first frame: a persistent value near the decal count means the cache is missing every frame.
decal_reused: u32Decals served from the cross-frame cache this frame (cache hit).
Together with decal_uploads this shows how effective the decal resource
cache is: decal_reused should equal the visible decal count and
decal_uploads should be zero once decals are settled.
triangles_submitted: u64Total triangles submitted to the GPU.
shadow_draw_calls: u32Number of draw calls in the shadow pass.
cpu_prepare_ms: f32CPU time spent in prepare(), in milliseconds.
prepare_breakdown: PrepareBreakdownPer-phase split of cpu_prepare_ms. See PrepareBreakdown.
cpu_paint_ms: f32CPU time spent encoding the paint pass (draw-call recording) in
milliseconds, separate from cpu_prepare_ms.
Measured around the render/paint encode and latched after it, so
last_frame_stats() reflects the current frame once render has run.
The value carried in the FrameStats returned by prepare() is the
previous frame’s paint, since paint runs after prepare. For
multi-viewport rendering this reflects the most recently painted
viewport, not the sum.
gpu_frame_ms: Option<f32>GPU scene-pass time in milliseconds, if timestamp queries are available.
Measured with TIMESTAMP_QUERY around the main scene render pass.
None on backends that do not support TIMESTAMP_QUERY (e.g. WebGL).
Note: this value reflects the previous frame’s GPU cost due to async readback. The value lags by one frame and should not be used by the adaptation controller across mode transitions.
gpu_breakdown: GpuBreakdownPer-pass split of GPU frame time. See GpuBreakdown.
Populated under the same conditions as gpu_frame_ms (requires
TIMESTAMP_QUERY); all fields are 0.0 otherwise. scene_ms matches
gpu_frame_ms.
total_frame_ms: f32Wall-clock duration since the previous prepare() call, in milliseconds.
Approximates the full frame interval. Zero on the first frame.
render_scale: f32Current internal render scale (1.0 = native resolution).
Reflects the value tracked by the adaptation controller. Values below 1.0
cause the scene to render into a scaled intermediate texture that is
bilinearly upscaled to the surface (requires allow_dynamic_resolution).
missed_budget: boolTrue if the last frame exceeded the target frame budget.
Requires target_fps to be set in the PerformancePolicy. Always
false when no target is configured.
upload_bytes: u64Bytes of geometry data uploaded to the GPU since the previous
prepare() call.
Counts full buffer reallocations triggered by
crate::DeviceResources::replace_mesh_data and initial uploads
via upload_mesh_data / upload_mesh. Uniform buffer writes are not
counted.
gpu_culling_active: boolTrue when GPU-driven culling is active this frame.
False when the device does not support INDIRECT_FIRST_INSTANCE or
culling has been disabled via disable_gpu_driven_culling().
gpu_visible_instances: Option<u32>Number of instances that passed GPU culling and were submitted for drawing.
This is the count after both the frustum and occlusion tests. Populated
only when gpu_culling_active is true. None on the first frame or when
GPU culling is off. Lags by one frame due to async readback.
gpu_culled_total: Option<u32>Total instances considered by the main-camera cull this frame, before
any test. Same readback and None conditions as gpu_visible_instances.
gpu_frustum_visible: Option<u32>Instances that survived the frustum test, before the HiZ occlusion test.
gpu_culled_total - gpu_frustum_visible is the frustum-culled count, and
gpu_frustum_visible - gpu_visible_instances is the occlusion-culled
count. When occlusion culling is off, this equals gpu_visible_instances.
Same readback and None conditions as gpu_visible_instances.
shadows_skipped: boolTrue when the shadow depth pass was skipped this frame.
Set when allow_shadow_reduction is true and the previous frame missed
the target budget. Always false in RuntimeMode::Capture.
volume_quality_reduced: boolTrue when volume raymarch step size was doubled this frame.
Set when allow_volume_quality_reduction is true and the previous frame
missed the target budget. Always false in RuntimeMode::Capture.
effects_throttled: boolTrue when SSAO, contact shadows, and bloom were skipped this frame.
Set when allow_effect_throttling is true and the previous frame missed
the target budget. Always false in RuntimeMode::Capture.
lod_items_resolved: u32Objects that resolved through a LOD group this frame.
Counts SceneRenderItems with a lod_group set, plus each individual
MeshInstanceItem instance whose level was selected. Zero when nothing
uses LOD.
lod_switches: u32LOD objects whose chosen level changed from the previous frame.
Counts both scene items and individual mesh instances that moved to a
different level. Only objects with a pick_id are tracked across frames,
so this counts switches among those. A high value relative to
lod_items_resolved suggests thresholds are being crossed often (camera
motion, or thresholds spaced too tightly for the hysteresis margin).
lod_culled: u32Objects dropped this frame because they fell below their LOD group’s cull
size. Counts hidden SceneRenderItems plus individual mesh instances that
were left out of every batch. Zero unless a group sets cull_below.
lod_items_reduced: u32LOD objects drawn this frame at a reduced level (level index > 0, i.e. below full detail). Counts scene items plus individual mesh instances.
Unlike lod_switches, this does not need per-object
tracking, so it is accurate for objects with no pick_id. It is the
reliable signal for “is LOD actually reducing geometry”: if it stays near
zero while distant objects fill the view, either the heavy meshes are not
in LOD groups or the min_screen_size thresholds never trigger, and the
triangle count is not coming down.
Trait Implementations§
Source§impl Clone for FrameStats
impl Clone for FrameStats
Source§fn clone(&self) -> FrameStats
fn clone(&self) -> FrameStats
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for FrameStats
Source§impl Debug for FrameStats
impl Debug for FrameStats
Source§impl Default for FrameStats
impl Default for FrameStats
Source§fn default() -> FrameStats
fn default() -> FrameStats
Auto Trait Implementations§
impl Freeze for FrameStats
impl RefUnwindSafe for FrameStats
impl Send for FrameStats
impl Sync for FrameStats
impl Unpin for FrameStats
impl UnsafeUnpin for FrameStats
impl UnwindSafe for FrameStats
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.