use std::sync::atomic::AtomicU32;
use std::sync::{Arc, Mutex};
use concinnity_core::profile::RenderStats;
use super::InitGpu;
use crate::metal::context::{Diagnostics, FrameRings};
use crate::metal::frame_rings::{JointRing, TransientRing};
use crate::metal::material_params::MaterialParamRing;
use crate::metal::pass_timing::PassTimingResources;
pub(super) fn build_rings(
gpu: &InitGpu<'_>,
material_params: Vec<concinnity_core::gfx::render_types::GpuMaterialParams>,
) -> FrameRings {
let frames_in_flight = gpu.frames_in_flight;
FrameRings {
object: TransientRing::new(frames_in_flight.max(1) + 1),
draw_args: TransientRing::new(frames_in_flight.max(1) + 1),
model_history: TransientRing::new(frames_in_flight),
bindless_tex: TransientRing::new(frames_in_flight.max(1)),
probe_records: TransientRing::new(frames_in_flight.max(1) + 1),
joint: JointRing::new(frames_in_flight.max(1) + 1),
object_scratch: Vec::new(),
draw_args_scratch: Vec::new(),
material_params: MaterialParamRing::new(material_params, frames_in_flight.max(1) + 1),
}
}
pub(super) fn build_diagnostics(gpu: &InitGpu<'_>) -> Diagnostics {
let pass_timing = PassTimingResources::new(&gpu.hw.device);
tracing::info!(
"pass-timing: per-pass GPU sample buffers {}",
if pass_timing.is_some() {
"ready"
} else {
"unavailable (no MTLCommonCounterSetTimestamp)"
}
);
Diagnostics {
frame_stats: RenderStats::default(),
gpu_time_us: Arc::new(AtomicU32::new(0)),
device_error: Arc::new(Mutex::new(None)),
pass_timing,
pass_times_us: Arc::new(std::array::from_fn(|_| AtomicU32::new(0))),
draw_calls_accum: AtomicU32::new(0),
}
}