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