use std::collections::BTreeMap;
use iridia_interface::ConstantBufferBinding;
use crate::{Interface, ResourceId, ResourceKind};
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct BoundSizes(BTreeMap<ResourceId, u32>);
impl BoundSizes {
pub fn new() -> BoundSizes {
BoundSizes::default()
}
pub fn of(constant_buffers: &[ConstantBufferBinding]) -> BoundSizes {
BoundSizes(
constant_buffers
.iter()
.filter_map(|c| c.bound_size.map(|bytes| (c.resource, bytes)))
.collect(),
)
}
pub fn set(&mut self, resource: ResourceId, bytes: u32) {
self.0.insert(resource, bytes);
}
pub fn get(&self, resource: ResourceId) -> Option<u32> {
self.0.get(&resource).copied()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn apply(&self, interface: &mut Interface) -> Result<(), String> {
for (&id, &bytes) in &self.0 {
let Some(resource) = interface.resources.iter_mut().find(|r| r.id == id) else {
return Err(format!(
"a bound size for resource {}, which the program does not have",
id.0
));
};
let ResourceKind::ConstantBuffer { layout } = &mut resource.kind else {
return Err(format!(
"a bound size for resource {}, which is not a constant buffer",
id.0
));
};
if bytes < layout.size {
return Err(format!(
"resource {} is bound at {bytes} bytes, below the {} its program declares",
id.0, layout.size
));
}
layout.size = bytes;
}
Ok(())
}
}