dear_imgui_wgpu/
render_resources.rs1use crate::{RendererError, RendererResult, UniformBuffer};
7use std::collections::HashMap;
8use wgpu::*;
9
10pub struct RenderResources {
16 pub sampler: Option<Sampler>,
18 pub uniform_buffer: Option<UniformBuffer>,
20 pub image_bind_groups: HashMap<u64, BindGroup>,
22 pub image_bind_group_layout: Option<BindGroupLayout>,
24}
25
26impl RenderResources {
27 pub fn new() -> Self {
29 Self {
30 sampler: None,
31 uniform_buffer: None,
32 image_bind_groups: HashMap::new(),
33 image_bind_group_layout: None,
34 }
35 }
36
37 pub fn initialize(&mut self, device: &Device) -> RendererResult<()> {
39 #[cfg(feature = "wgpu-27")]
40 fn linear_mipmap_filter() -> FilterMode {
41 FilterMode::Linear
42 }
43 #[cfg(feature = "wgpu-28")]
44 fn linear_mipmap_filter() -> MipmapFilterMode {
45 MipmapFilterMode::Linear
46 }
47
48 let sampler = device.create_sampler(&SamplerDescriptor {
52 label: Some("Dear ImGui Texture Sampler"),
53 address_mode_u: AddressMode::ClampToEdge, address_mode_v: AddressMode::ClampToEdge, address_mode_w: AddressMode::ClampToEdge, mag_filter: FilterMode::Linear, min_filter: FilterMode::Linear, mipmap_filter: linear_mipmap_filter(), anisotropy_clamp: 1, ..Default::default()
61 });
62
63 let uniform_buffer = UniformBuffer::new(device, &sampler);
65
66 let image_bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
68 label: Some("Dear ImGui Image Bind Group Layout"),
69 entries: &[BindGroupLayoutEntry {
70 binding: 0,
71 visibility: ShaderStages::FRAGMENT,
72 ty: BindingType::Texture {
73 multisampled: false,
74 sample_type: TextureSampleType::Float { filterable: true },
75 view_dimension: TextureViewDimension::D2,
76 },
77 count: None,
78 }],
79 });
80
81 self.sampler = Some(sampler);
82 self.uniform_buffer = Some(uniform_buffer);
83 self.image_bind_group_layout = Some(image_bind_group_layout);
84
85 Ok(())
86 }
87
88 pub fn create_image_bind_group(
90 &self,
91 device: &Device,
92 texture_view: &TextureView,
93 ) -> RendererResult<BindGroup> {
94 let layout = self.image_bind_group_layout.as_ref().ok_or_else(|| {
95 RendererError::InvalidRenderState("Image bind group layout not initialized".to_string())
96 })?;
97
98 let bind_group = device.create_bind_group(&BindGroupDescriptor {
99 label: Some("Dear ImGui Image Bind Group"),
100 layout,
101 entries: &[BindGroupEntry {
102 binding: 0,
103 resource: BindingResource::TextureView(texture_view),
104 }],
105 });
106
107 Ok(bind_group)
108 }
109
110 pub fn get_or_create_image_bind_group(
112 &mut self,
113 device: &Device,
114 texture_id: u64,
115 texture_view: &TextureView,
116 ) -> RendererResult<&BindGroup> {
117 if !self.image_bind_groups.contains_key(&texture_id) {
118 let bind_group = self.create_image_bind_group(device, texture_view)?;
119 self.image_bind_groups.insert(texture_id, bind_group);
120 }
121
122 self.image_bind_groups.get(&texture_id).ok_or_else(|| {
123 RendererError::InvalidRenderState("Image bind group missing after creation".to_string())
124 })
125 }
126
127 pub fn remove_image_bind_group(&mut self, texture_id: u64) {
129 self.image_bind_groups.remove(&texture_id);
130 }
131
132 pub fn clear_image_bind_groups(&mut self) {
134 self.image_bind_groups.clear();
135 }
136
137 pub fn sampler(&self) -> Option<&Sampler> {
139 self.sampler.as_ref()
140 }
141
142 pub fn uniform_buffer(&self) -> Option<&UniformBuffer> {
144 self.uniform_buffer.as_ref()
145 }
146
147 pub fn common_bind_group(&self) -> Option<&BindGroup> {
149 self.uniform_buffer.as_ref().map(|ub| ub.bind_group())
150 }
151
152 pub fn image_bind_group_layout(&self) -> Option<&BindGroupLayout> {
154 self.image_bind_group_layout.as_ref()
155 }
156
157 pub fn is_initialized(&self) -> bool {
159 self.sampler.is_some()
160 && self.uniform_buffer.is_some()
161 && self.image_bind_group_layout.is_some()
162 }
163
164 pub fn stats(&self) -> RenderResourcesStats {
166 RenderResourcesStats {
167 image_bind_groups_count: self.image_bind_groups.len(),
168 is_initialized: self.is_initialized(),
169 }
170 }
171}
172
173impl Default for RenderResources {
174 fn default() -> Self {
175 Self::new()
176 }
177}
178
179#[derive(Debug, Clone)]
181pub struct RenderResourcesStats {
182 pub image_bind_groups_count: usize,
183 pub is_initialized: bool,
184}