Skip to main content

ascending_graphics/systems/
layout.rs

1use crate::{AHashMap, GpuDevice};
2use bytemuck::{Pod, Zeroable};
3use std::{
4    any::{Any, TypeId},
5    sync::Arc,
6};
7
8/// Trait used to Create and Store [`wgpu::BindGroupLayout`] within a HashMap.
9///
10pub trait Layout: Pod + Zeroable {
11    /// Creates the [`wgpu::BindGroupLayout`] to be added to the HashMap
12    ///
13    fn create_layout(
14        &self,
15        gpu_device: &mut GpuDevice,
16    ) -> wgpu::BindGroupLayout;
17
18    /// Gives a Hashable Key of the [`wgpu::BindGroupLayout`] to use to Retrieve it from the HashMap.
19    ///
20    fn layout_key(&self) -> (TypeId, Vec<u8>) {
21        let type_id = self.type_id();
22        let bytes: Vec<u8> =
23            bytemuck::try_cast_slice(&[*self]).unwrap_or(&[]).to_vec();
24
25        (type_id, bytes)
26    }
27}
28
29/// [`wgpu::BindGroupLayout`] Storage within a HashMap
30///
31#[derive(Debug)]
32pub struct LayoutStorage {
33    pub(crate) bind_group_map:
34        AHashMap<(TypeId, Vec<u8>), Arc<wgpu::BindGroupLayout>>,
35}
36
37impl LayoutStorage {
38    /// Creates a new [`LayoutStorage`] with Default HashMap.
39    ///
40    pub fn new() -> Self {
41        Self {
42            bind_group_map: AHashMap::default(),
43        }
44    }
45
46    /// Creates a new [`wgpu::BindGroupLayout`] from [`Layout`] and adds it to the internal map.
47    /// Returns an Rc<wgpu::BindGroupLayout>
48    pub fn create_layout<K: Layout>(
49        &mut self,
50        device: &mut GpuDevice,
51        layout: K,
52    ) -> Arc<wgpu::BindGroupLayout> {
53        let key = layout.layout_key();
54
55        let layout = self
56            .bind_group_map
57            .entry(key)
58            .or_insert_with(|| Arc::new(layout.create_layout(device)));
59
60        Arc::clone(layout)
61    }
62
63    pub fn get_layout<K: Layout>(
64        &self,
65        layout: K,
66    ) -> Option<Arc<wgpu::BindGroupLayout>> {
67        let key = layout.layout_key();
68
69        self.bind_group_map.get(&key).map(Arc::clone)
70    }
71}
72
73impl Default for LayoutStorage {
74    fn default() -> Self {
75        Self::new()
76    }
77}