| 872 | last_prepare_3d_lighting: Option<Lighting3DState>, |
| 873 | last_prepare_3d_draws_revision: u64, |
| 874 | last_prepare_3d_decals_revision: u64, |
| 875 | last_prepare_3d_width: u32, |
| 876 | last_prepare_3d_height: u32, |
| 877 | // Retained-scene fast path: the scene color target (and depth) persist |
| 878 | // across frames, so a frame that provably reproduces the same image can |
| 879 | // skip encoding the scene chain and present the retained texture. |
| 880 | // `retained_scene_valid` is cleared the moment a frame decides to render |
| 881 | // the scene (so an aborted frame cannot leave a stale "valid") and set |
| 882 | // again only after that frame's command buffer is submitted. |
| 883 | retained_scene_valid: bool, |
| 884 | retained_scene_key: RetainedSceneKey, |
| 885 | // Stream-consumption cache for the fast path. Texture *indices* |
| 886 | // (generation dropped, matching how the 3D external material slot is |
| 887 | // keyed) sampled by the passes that write the retained scene texture: 3D |
| 888 | // draws + their material slots, decals, and the 2D scene sprites. Absent |
| 889 | // by design: UI primitives and the late 2D overlay, which both re-encode |
| 890 | // onto the swapchain after the scene texture every frame, so a stream |
| 891 | // only they sample can never make the retained image stale. |
| 892 | main_scene_sampled_texture_slots: ahash::AHashSet<u32>, |
| 893 | // (draws, sprites, decals) revisions the set above was built from; `None` |
| 894 | // forces a rebuild. Also reset on every frame that re-encodes the scene, |
| 895 | // since a material can change its texture slots without moving any of the |
| 896 | // three revisions. |
| 897 | main_scene_sampled_key: Option<(u64, u64, u64)>, |
| 898 | meshlets_enabled: bool, |
| 899 | dev_meshlets: bool, |
| 900 | meshlet_debug_view: bool, |
| 901 | occlusion_culling: OcclusionCullingMode, |
| 902 | ssao: crate::SsaoQuality, |
| 903 | texture_filter: TextureFilterMode, |
| 904 | shader_variant_mode: crate::ShaderVariantMode, |
| 905 | indirect_first_instance_enabled: bool, |
| 906 | multi_draw_indirect_enabled: bool, |
| 907 | /// `Features::MULTI_DRAW_INDIRECT_COUNT` was available and requested. |
| 908 | multi_draw_indirect_count_enabled: bool, |
| 909 | gpu_timer: Option<GpuTimestampTimer>, |
| 910 | // Idle-frame skip state. `last_present` anchors the safety valve; a frame |
| 911 | // is only ever skipped after at least one real present has reached the |
| 912 | // swapchain, so the first visible frame can never be the skipped one. |
| 913 | last_present: Option<Instant>, |
| 914 | presented_once: bool, |
| 915 | // Project virtual canvas for 2D aspect-fit scaling; camera-stream / sub |
| 916 | // view 2D passes use the same world-to-pixel rule as the main view. |
| 917 | virtual_size_2d: [f32; 2], |
| 918 | } |