use crate::render_graph::{PASS_COUNT, PassId};
pub const SLOTS_PER_FRAME: usize = 2 * (PASS_COUNT + 1);
pub const FRAME_BLOCK_BYTES: u64 = (SLOTS_PER_FRAME * 8) as u64;
pub const fn whole_frame_pair(frame: usize) -> (u32, u32) {
let base = (frame * SLOTS_PER_FRAME) as u32;
(base, base + 1)
}
pub const fn pass_pair(frame: usize, pass: PassId) -> (u32, u32) {
let base = (frame * SLOTS_PER_FRAME + 2 + 2 * (pass as usize)) as u32;
(base, base + 1)
}
pub const fn frame_resolve_start(frame: usize) -> u32 {
(frame * SLOTS_PER_FRAME) as u32
}
pub const fn frame_readback_byte_offset(frame: usize) -> u64 {
(frame * SLOTS_PER_FRAME * 8) as u64
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn layout_preserves_legacy_whole_frame_indexing() {
assert_eq!(whole_frame_pair(0), (0, 1));
assert_eq!(
whole_frame_pair(1),
(SLOTS_PER_FRAME as u32, SLOTS_PER_FRAME as u32 + 1)
);
assert_eq!(frame_resolve_start(0), 0);
assert_eq!(frame_resolve_start(1), SLOTS_PER_FRAME as u32);
assert_eq!(frame_readback_byte_offset(0), 0);
assert_eq!(frame_readback_byte_offset(1), FRAME_BLOCK_BYTES);
}
#[test]
fn pass_pair_skips_the_whole_frame_pair() {
let (a, b) = pass_pair(0, PassId::Cull);
assert_eq!((a, b), (2, 3));
}
#[test]
fn pass_pairs_are_unique_within_a_frame() {
use hashbrown::HashSet;
let mut seen: HashSet<u32> = HashSet::new();
seen.insert(0);
seen.insert(1);
for variant in [
PassId::Cull,
PassId::Shadow,
PassId::SsrPrepass,
PassId::SsaoPrepass,
PassId::SsaoKernel,
PassId::SsaoBlur,
PassId::Main,
PassId::AutoExposure,
PassId::Decals,
PassId::Fog,
PassId::ParticlesSim,
PassId::ParticlesDraw,
PassId::SsrResolve,
PassId::Velocity,
PassId::TaaResolve,
PassId::Bloom,
PassId::Composite,
PassId::FogFroxel,
PassId::Upscale,
PassId::Transparent,
PassId::Raymarch,
] {
let (s, e) = pass_pair(0, variant);
assert!(seen.insert(s), "duplicate start slot for {variant:?}");
assert!(seen.insert(e), "duplicate end slot for {variant:?}");
assert!((s as usize) < SLOTS_PER_FRAME);
assert!((e as usize) < SLOTS_PER_FRAME);
}
}
}