use std::sync::{Arc, Mutex};
use crate::WgpuResidentSegment;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct BufferRange {
pub offset: u64,
pub bytes: u64,
}
impl From<&WgpuResidentSegment> for BufferRange {
fn from(segment: &WgpuResidentSegment) -> Self {
Self {
offset: segment.offset,
bytes: segment.bytes,
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct PhysicalSubmissionEvidence {
pub submissions: u64,
pub uploaded_bytes: u64,
pub full_readbacks: u64,
pub scalar_syncs: u64,
pub segments_touched: Vec<BufferRange>,
}
#[derive(Clone, Debug, Default)]
pub(crate) struct WgpuPhysicalCounters {
inner: Arc<Mutex<PhysicalSubmissionEvidence>>,
}
impl WgpuPhysicalCounters {
pub(crate) fn snapshot(&self) -> PhysicalSubmissionEvidence {
self.inner
.lock()
.expect("wgpu physical counters poisoned")
.clone()
}
pub(crate) fn record_upload(&self, bytes: u64) {
let mut evidence = self.inner.lock().expect("wgpu physical counters poisoned");
evidence.uploaded_bytes = evidence.uploaded_bytes.saturating_add(bytes);
}
pub(crate) fn record_submit(&self, segments: &[WgpuResidentSegment]) {
let mut evidence = self.inner.lock().expect("wgpu physical counters poisoned");
evidence.submissions = evidence.submissions.saturating_add(1);
evidence
.segments_touched
.extend(segments.iter().map(BufferRange::from));
}
pub(crate) fn record_full_readback(&self) {
let mut evidence = self.inner.lock().expect("wgpu physical counters poisoned");
evidence.full_readbacks = evidence.full_readbacks.saturating_add(1);
}
pub(crate) fn record_scalar_sync(&self) {
let mut evidence = self.inner.lock().expect("wgpu physical counters poisoned");
evidence.scalar_syncs = evidence.scalar_syncs.saturating_add(1);
}
}