use crate::bytemuck_safe::safe_bytes_of_slice;
use crate::engine::dfa::MAX_DFA_MATCHES;
use vyre::error::{Error, Result};
use wgpu::util::DeviceExt;
pub(crate) fn buffer(
device: &wgpu::Device,
label: &'static str,
size: u64,
usage: wgpu::BufferUsages,
) -> wgpu::Buffer {
device.create_buffer(&wgpu::BufferDescriptor {
label: Some(label),
size,
usage,
mapped_at_creation: false,
})
}
pub(crate) fn entry(binding: u32, buffer: &wgpu::Buffer) -> wgpu::BindGroupEntry<'_> {
wgpu::BindGroupEntry {
binding,
resource: buffer.as_entire_binding(),
}
}
pub(crate) fn storage_buffer(
device: &wgpu::Device,
label: &'static str,
data: &[u32],
) -> wgpu::Buffer {
if data.is_empty() {
return buffer(device, label, 4, wgpu::BufferUsages::STORAGE);
}
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some(label),
contents: safe_bytes_of_slice(data),
usage: wgpu::BufferUsages::STORAGE,
})
}
pub(crate) fn buffer_bytes(items: usize) -> Result<u64> {
items
.checked_mul(std::mem::size_of::<u32>())
.map(u64::try_from)
.transpose()
.map_err(|source| Error::Dfa {
message: format!(
"DFA buffer byte count cannot fit u64: {source}. Fix: reduce buffer size."
),
})?
.ok_or_else(|| Error::Dfa {
message: format!(
"DFA buffer item count {items} overflows byte sizing. Fix: reduce buffer size."
),
})
}
pub(crate) fn match_buffer_size(max_matches: u32) -> Result<u64> {
if max_matches > MAX_DFA_MATCHES {
return Err(Error::Dfa {
message: format!(
"DFA max_matches {max_matches} exceeds {MAX_DFA_MATCHES}. Fix: lower max_matches."
),
});
}
u64::from(max_matches)
.checked_mul(3)
.and_then(|items| items.checked_mul(u64::try_from(std::mem::size_of::<u32>()).ok()?))
.ok_or_else(|| Error::Dfa {
message: format!(
"DFA max_matches {max_matches} overflows output buffer sizing. Fix: lower max_matches."
),
})
}
pub(crate) fn gpu_err<T>(message: &str) -> Result<T> {
Err(Error::Dfa {
message: message.to_string(),
})
}