Skip to main content

jag_draw/
allocator.rs

1use std::collections::HashMap;
2use std::sync::Arc;
3
4#[derive(Debug)]
5pub struct OwnedTexture {
6    pub texture: wgpu::Texture,
7    pub view: wgpu::TextureView,
8    pub key: TexKey,
9}
10
11#[derive(Debug)]
12pub struct OwnedBuffer {
13    pub buffer: wgpu::Buffer,
14    pub key: BufKey,
15}
16
17#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
18pub struct TexKey {
19    pub width: u32,
20    pub height: u32,
21    pub format: wgpu::TextureFormat,
22    pub usage: wgpu::TextureUsages,
23}
24
25#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
26pub struct BufKey {
27    pub size: u64,
28    pub usage: wgpu::BufferUsages,
29}
30
31/// Simple render allocator with basic pooling for textures and buffers.
32pub struct RenderAllocator {
33    device: Arc<wgpu::Device>,
34    texture_pool: HashMap<TexKey, Vec<wgpu::Texture>>,
35    buffer_pool: HashMap<BufKey, Vec<wgpu::Buffer>>,
36}
37
38impl RenderAllocator {
39    pub fn new(device: Arc<wgpu::Device>) -> Self {
40        Self {
41            device,
42            texture_pool: HashMap::new(),
43            buffer_pool: HashMap::new(),
44        }
45    }
46
47    pub fn begin_frame(&mut self) {
48        // placeholder for any per-frame bookkeeping
49    }
50
51    pub fn end_frame(&mut self) {
52        // placeholder for returning transients automatically in the future
53    }
54
55    pub fn allocate_texture(&mut self, key: TexKey) -> OwnedTexture {
56        let entry = self.texture_pool.entry(key).or_default();
57        let texture = entry.pop().unwrap_or_else(|| {
58            self.device.create_texture(&wgpu::TextureDescriptor {
59                label: Some("alloc:tex"),
60                size: wgpu::Extent3d {
61                    width: key.width,
62                    height: key.height,
63                    depth_or_array_layers: 1,
64                },
65                mip_level_count: 1,
66                sample_count: 1,
67                dimension: wgpu::TextureDimension::D2,
68                format: key.format,
69                usage: key.usage,
70                view_formats: &[],
71            })
72        });
73        let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
74        OwnedTexture { texture, view, key }
75    }
76
77    pub fn release_texture(&mut self, tex: OwnedTexture) {
78        self.texture_pool
79            .entry(tex.key)
80            .or_default()
81            .push(tex.texture);
82    }
83
84    pub fn allocate_buffer(&mut self, key: BufKey) -> OwnedBuffer {
85        let entry = self.buffer_pool.entry(key).or_default();
86        let buffer = entry.pop().unwrap_or_else(|| {
87            self.device.create_buffer(&wgpu::BufferDescriptor {
88                label: Some("alloc:buf"),
89                size: key.size,
90                usage: key.usage,
91                mapped_at_creation: false,
92            })
93        });
94        OwnedBuffer { buffer, key }
95    }
96
97    pub fn release_buffer(&mut self, buf: OwnedBuffer) {
98        self.buffer_pool
99            .entry(buf.key)
100            .or_default()
101            .push(buf.buffer);
102    }
103}