use awsm_renderer_core::{
buffers::{BufferDescriptor, BufferUsage},
command::CommandEncoder,
error::AwsmCoreError,
renderer::AwsmRendererWebGpu,
};
pub const COUNTS_STRIDE_BYTES: usize = 4;
const INITIAL_CAPACITY: u32 = 1024;
pub struct CoverageBuffers {
pub counts_buffer: web_sys::GpuBuffer,
pub readback_buffer: web_sys::GpuBuffer,
pub size_bytes: usize,
pub capacity: u32,
}
impl CoverageBuffers {
pub fn new(gpu: &AwsmRendererWebGpu) -> Result<Self, AwsmCoreError> {
Self::with_capacity(gpu, INITIAL_CAPACITY)
}
fn with_capacity(gpu: &AwsmRendererWebGpu, capacity: u32) -> Result<Self, AwsmCoreError> {
let capacity = capacity.max(1);
let size_bytes = capacity as usize * COUNTS_STRIDE_BYTES;
let counts_buffer = gpu.create_buffer(
&BufferDescriptor::new(
Some("CoverageCounts"),
size_bytes,
BufferUsage::new()
.with_storage()
.with_copy_src()
.with_copy_dst(),
)
.into(),
)?;
let readback_buffer = gpu.create_buffer(
&BufferDescriptor::new(
Some("CoverageReadback"),
size_bytes,
BufferUsage::new().with_map_read().with_copy_dst(),
)
.into(),
)?;
Ok(Self {
counts_buffer,
readback_buffer,
size_bytes,
capacity,
})
}
pub fn ensure_capacity(
&mut self,
gpu: &AwsmRendererWebGpu,
needed: u32,
) -> Result<bool, AwsmCoreError> {
if needed <= self.capacity {
return Ok(false);
}
let new_capacity = needed.saturating_mul(2).max(needed);
*self = Self::with_capacity(gpu, new_capacity)?;
Ok(true)
}
pub fn reset_counts(&self, encoder: &CommandEncoder) {
encoder.clear_buffer(&self.counts_buffer, None, None);
}
}