Skip to main content

dear_imgui_wgpu/
lib.rs

1//! WGPU backend for Dear ImGui
2//!
3//! This crate provides a WGPU-based renderer for Dear ImGui, allowing you to
4//! render Dear ImGui interfaces using the WGPU graphics API.
5//!
6//! # Features
7//!
8//! - **WGPU version selection**: choose exactly one of:
9//!   - `wgpu-30` (default)
10//!   - `wgpu-29`
11//!   - `wgpu-28`
12//!   - `wgpu-27` (for ecosystems pinned to wgpu 27.x, e.g. some Bevy version trains)
13//! - **Diagnostics**: `tracing` emits renderer debug and warning events and is off by default
14//! - **Managed textures**: pointer-free create/update/destroy requests owned by rendered frames
15//! - **External textures**: Register application-owned `wgpu::TextureView` handles for UI display
16//! - **Gamma correction**: Automatic sRGB format detection and gamma correction
17//! - **Epoch-isolated uploads**: Vertex, index, and uniform buffers are never reused across
18//!   render epochs
19//! - **Device object management**: Helpers to recreate device objects (pipelines/buffers/textures) after loss
20//! - **Multi-viewport support**: Support for multiple windows (feature-gated via `multi-viewport-winit` for winit or `multi-viewport-sdl3` for SDL3 on native targets)
21//!
22//! # Example
23//!
24//! ```rust,no_run
25//! use dear_imgui_rs::Context;
26//! use dear_imgui_wgpu::{FramebufferExtent, WgpuInitInfo, WgpuRenderer, wgpu};
27//!
28//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
29//! # let (device, queue) = todo!("initialize a WGPU Device/Queue");
30//!
31//! // Create Dear ImGui context
32//! let mut imgui = Context::create();
33//!
34//! // Create renderer (recommended path)
35//! let init_info = WgpuInitInfo::new(device, queue, wgpu::TextureFormat::Bgra8UnormSrgb);
36//! let mut renderer = WgpuRenderer::new(init_info, &mut imgui)?;
37//!
38//! // In your render loop:
39//! // imgui.new_frame();
40//! // ... build your UI ...
41//! // let frame = imgui.render(renderer.renderer_consumer()?);
42//! // let extent = FramebufferExtent::from_texture(&surface_texture.texture);
43//! // renderer.render(frame, &mut render_pass, extent)?;
44//! # Ok(())
45//! # }
46//! ```
47
48// Select a single wgpu version via features (default: wgpu-30).
49//
50// We keep the public API surface using `wgpu::*` types, but allow downstream crates to opt into a
51// specific major version to better match their ecosystem (e.g. Bevy).
52#[cfg(all(
53    feature = "wgpu-27",
54    any(feature = "wgpu-28", feature = "wgpu-29", feature = "wgpu-30")
55))]
56compile_error!(
57    "Features `wgpu-27`, `wgpu-28`, `wgpu-29`, and `wgpu-30` are mutually exclusive; enable only one."
58);
59#[cfg(all(feature = "wgpu-28", any(feature = "wgpu-29", feature = "wgpu-30")))]
60compile_error!(
61    "Features `wgpu-27`, `wgpu-28`, `wgpu-29`, and `wgpu-30` are mutually exclusive; enable only one."
62);
63#[cfg(all(feature = "wgpu-29", feature = "wgpu-30"))]
64compile_error!(
65    "Features `wgpu-27`, `wgpu-28`, `wgpu-29`, and `wgpu-30` are mutually exclusive; enable only one."
66);
67#[cfg(not(any(
68    feature = "wgpu-27",
69    feature = "wgpu-28",
70    feature = "wgpu-29",
71    feature = "wgpu-30"
72)))]
73compile_error!(
74    "Either feature `wgpu-27`, `wgpu-28`, `wgpu-29`, or `wgpu-30` must be enabled for dear-imgui-wgpu."
75);
76
77#[cfg(all(feature = "wgpu-27", feature = "webgl"))]
78compile_error!(
79    "Feature `webgl` selects the wgpu-30 WebGL route; use `webgl-wgpu27` with `wgpu-27`."
80);
81#[cfg(all(feature = "wgpu-27", feature = "webgpu"))]
82compile_error!(
83    "Feature `webgpu` selects the wgpu-30 WebGPU route; use `webgpu-wgpu27` with `wgpu-27`."
84);
85#[cfg(all(feature = "wgpu-28", feature = "webgl"))]
86compile_error!(
87    "Feature `webgl` selects the wgpu-30 WebGL route; use `webgl-wgpu28` with `wgpu-28`."
88);
89#[cfg(all(feature = "wgpu-28", feature = "webgpu"))]
90compile_error!(
91    "Feature `webgpu` selects the wgpu-30 WebGPU route; use `webgpu-wgpu28` with `wgpu-28`."
92);
93#[cfg(all(feature = "wgpu-29", feature = "webgl"))]
94compile_error!(
95    "Feature `webgl` selects the wgpu-30 WebGL route; use `webgl-wgpu29` with `wgpu-29`."
96);
97#[cfg(all(feature = "wgpu-29", feature = "webgpu"))]
98compile_error!(
99    "Feature `webgpu` selects the wgpu-30 WebGPU route; use `webgpu-wgpu29` with `wgpu-29`."
100);
101#[cfg(all(feature = "wgpu-28", feature = "webgl-wgpu27"))]
102compile_error!(
103    "Feature `webgl-wgpu27` is incompatible with `wgpu-28` (would pull multiple wgpu majors)."
104);
105#[cfg(all(feature = "wgpu-28", feature = "webgpu-wgpu27"))]
106compile_error!(
107    "Feature `webgpu-wgpu27` is incompatible with `wgpu-28` (would pull multiple wgpu majors)."
108);
109#[cfg(all(feature = "wgpu-27", feature = "webgl-wgpu28"))]
110compile_error!(
111    "Feature `webgl-wgpu28` is incompatible with `wgpu-27` (would pull multiple wgpu majors)."
112);
113#[cfg(all(feature = "wgpu-27", feature = "webgpu-wgpu28"))]
114compile_error!(
115    "Feature `webgpu-wgpu28` is incompatible with `wgpu-27` (would pull multiple wgpu majors)."
116);
117#[cfg(all(feature = "wgpu-29", feature = "webgl-wgpu27"))]
118compile_error!(
119    "Feature `webgl-wgpu27` is incompatible with `wgpu-29` (would pull multiple wgpu majors)."
120);
121#[cfg(all(feature = "wgpu-29", feature = "webgpu-wgpu27"))]
122compile_error!(
123    "Feature `webgpu-wgpu27` is incompatible with `wgpu-29` (would pull multiple wgpu majors)."
124);
125#[cfg(all(feature = "wgpu-29", feature = "webgl-wgpu28"))]
126compile_error!(
127    "Feature `webgl-wgpu28` is incompatible with `wgpu-29` (would pull multiple wgpu majors)."
128);
129#[cfg(all(feature = "wgpu-29", feature = "webgpu-wgpu28"))]
130compile_error!(
131    "Feature `webgpu-wgpu28` is incompatible with `wgpu-29` (would pull multiple wgpu majors)."
132);
133#[cfg(all(feature = "wgpu-30", feature = "webgl-wgpu27"))]
134compile_error!(
135    "Feature `webgl-wgpu27` is incompatible with `wgpu-30` (would pull multiple wgpu majors)."
136);
137#[cfg(all(feature = "wgpu-30", feature = "webgpu-wgpu27"))]
138compile_error!(
139    "Feature `webgpu-wgpu27` is incompatible with `wgpu-30` (would pull multiple wgpu majors)."
140);
141#[cfg(all(feature = "wgpu-30", feature = "webgl-wgpu28"))]
142compile_error!(
143    "Feature `webgl-wgpu28` is incompatible with `wgpu-30` (would pull multiple wgpu majors)."
144);
145#[cfg(all(feature = "wgpu-30", feature = "webgpu-wgpu28"))]
146compile_error!(
147    "Feature `webgpu-wgpu28` is incompatible with `wgpu-30` (would pull multiple wgpu majors)."
148);
149#[cfg(all(feature = "wgpu-30", feature = "webgl-wgpu29"))]
150compile_error!(
151    "Feature `webgl-wgpu29` is incompatible with `wgpu-30` (would pull multiple wgpu majors)."
152);
153#[cfg(all(feature = "wgpu-30", feature = "webgpu-wgpu29"))]
154compile_error!(
155    "Feature `webgpu-wgpu29` is incompatible with `wgpu-30` (would pull multiple wgpu majors)."
156);
157#[cfg(all(feature = "wgpu-27", feature = "webgl-wgpu29"))]
158compile_error!(
159    "Feature `webgl-wgpu29` is incompatible with `wgpu-27` (would pull multiple wgpu majors)."
160);
161#[cfg(all(feature = "wgpu-27", feature = "webgpu-wgpu29"))]
162compile_error!(
163    "Feature `webgpu-wgpu29` is incompatible with `wgpu-27` (would pull multiple wgpu majors)."
164);
165#[cfg(all(feature = "wgpu-28", feature = "webgl-wgpu29"))]
166compile_error!(
167    "Feature `webgl-wgpu29` is incompatible with `wgpu-28` (would pull multiple wgpu majors)."
168);
169#[cfg(all(feature = "wgpu-28", feature = "webgpu-wgpu29"))]
170compile_error!(
171    "Feature `webgpu-wgpu29` is incompatible with `wgpu-28` (would pull multiple wgpu majors)."
172);
173#[cfg(all(feature = "wgpu-27", feature = "webgl-wgpu30"))]
174compile_error!(
175    "Feature `webgl-wgpu30` is incompatible with `wgpu-27` (would pull multiple wgpu majors)."
176);
177#[cfg(all(feature = "wgpu-27", feature = "webgpu-wgpu30"))]
178compile_error!(
179    "Feature `webgpu-wgpu30` is incompatible with `wgpu-27` (would pull multiple wgpu majors)."
180);
181#[cfg(all(feature = "wgpu-28", feature = "webgl-wgpu30"))]
182compile_error!(
183    "Feature `webgl-wgpu30` is incompatible with `wgpu-28` (would pull multiple wgpu majors)."
184);
185#[cfg(all(feature = "wgpu-28", feature = "webgpu-wgpu30"))]
186compile_error!(
187    "Feature `webgpu-wgpu30` is incompatible with `wgpu-28` (would pull multiple wgpu majors)."
188);
189#[cfg(all(feature = "wgpu-29", feature = "webgl-wgpu30"))]
190compile_error!(
191    "Feature `webgl-wgpu30` is incompatible with `wgpu-29` (would pull multiple wgpu majors)."
192);
193#[cfg(all(feature = "wgpu-29", feature = "webgpu-wgpu30"))]
194compile_error!(
195    "Feature `webgpu-wgpu30` is incompatible with `wgpu-29` (would pull multiple wgpu majors)."
196);
197
198#[cfg(feature = "wgpu-27")]
199pub extern crate wgpu27 as wgpu;
200#[cfg(feature = "wgpu-28")]
201pub extern crate wgpu28 as wgpu;
202#[cfg(feature = "wgpu-29")]
203pub extern crate wgpu29 as wgpu;
204#[cfg(feature = "wgpu-30")]
205pub extern crate wgpu30 as wgpu;
206
207// Module declarations
208mod data;
209mod error;
210mod frame_resources;
211mod render_resources;
212mod renderer;
213mod shaders;
214mod texture;
215mod uniforms;
216
217#[cfg(doctest)]
218mod removed_public_contracts {
219    /// ```compile_fail
220    /// use dear_imgui_wgpu::WgpuRenderer;
221    /// let _ = WgpuRenderer::empty;
222    /// ```
223    ///
224    /// ```compile_fail
225    /// use dear_imgui_wgpu::WgpuRenderer;
226    /// let _ = WgpuRenderer::new_without_font_atlas;
227    /// ```
228    ///
229    /// ```compile_fail
230    /// use dear_imgui_wgpu::WgpuRenderer;
231    /// let _ = WgpuRenderer::init_with_context;
232    /// ```
233    ///
234    /// ```compile_fail
235    /// use dear_imgui_wgpu::WgpuRenderer;
236    /// let _ = WgpuRenderer::default();
237    /// ```
238    ///
239    /// ```compile_fail
240    /// use dear_imgui_wgpu::WgpuRenderer;
241    /// let _ = WgpuRenderer::is_initialized;
242    /// ```
243    ///
244    /// ```compile_fail
245    /// use dear_imgui_wgpu::WgpuRenderer;
246    /// let _ = WgpuRenderer::texture_manager;
247    /// ```
248    struct TwoPhaseRendererInitialization;
249
250    /// ```compile_fail
251    /// use dear_imgui_wgpu::WgpuRenderer;
252    /// let _ = WgpuRenderer::new_frame;
253    /// ```
254    struct ManualFramePreparation;
255
256    /// ```compile_fail
257    /// use dear_imgui_wgpu::FrameResources;
258    /// ```
259    ///
260    /// ```compile_fail
261    /// use dear_imgui_wgpu::RenderResources;
262    /// ```
263    ///
264    /// ```compile_fail
265    /// use dear_imgui_wgpu::ShaderManager;
266    /// ```
267    ///
268    /// ```compile_fail
269    /// use dear_imgui_wgpu::UniformBuffer;
270    /// ```
271    ///
272    /// ```compile_fail
273    /// use dear_imgui_wgpu::Uniforms;
274    /// ```
275    ///
276    /// ```compile_fail
277    /// use dear_imgui_wgpu::WgpuTextureManager;
278    /// ```
279    ///
280    /// ```compile_fail
281    /// use dear_imgui_wgpu::WgpuTexture;
282    /// ```
283    struct RendererInternals;
284
285    /// ```compile_fail
286    /// use dear_imgui_wgpu::WgpuRenderer;
287    /// let _ = WgpuRenderer::register_external_texture_with_sampler;
288    /// ```
289    ///
290    /// ```compile_fail
291    /// use dear_imgui_wgpu::WgpuRenderer;
292    /// let _ = WgpuRenderer::update_external_texture_sampler;
293    /// ```
294    ///
295    /// ```compile_fail
296    /// use dear_imgui_wgpu::WgpuRenderer;
297    /// let _ = WgpuRenderer::update_external_texture_view;
298    /// ```
299    ///
300    /// ```compile_fail
301    /// use dear_imgui_wgpu::WgpuRenderer;
302    /// let _ = WgpuRenderer::unregister_texture;
303    /// ```
304    struct PerTextureSamplers;
305}
306
307pub use data::{
308    WgpuInitInfo, WgpuRenderState, WgpuRenderStateAccessError, WgpuViewportSurfaceConfig,
309};
310pub use error::{RendererError, RendererResult};
311pub use renderer::{FramebufferExtent, WgpuRenderer};
312pub use texture::ExternalTextureId;
313
314pub(crate) use data::{WgpuBackendData, WgpuRenderStateStorage};
315pub(crate) use frame_resources::{FrameResourceArena, FrameResources};
316pub(crate) use render_resources::RenderResources;
317pub(crate) use shaders::ShaderManager;
318pub(crate) use texture::WgpuTextureManager;
319pub(crate) use uniforms::{UniformBuffer, Uniforms};
320
321// Re-export multi-viewport helpers when enabled
322#[cfg(feature = "multi-viewport-winit")]
323pub use renderer::multi_viewport;
324#[cfg(feature = "multi-viewport-sdl3")]
325pub use renderer::multi_viewport_sdl3;
326
327/// Gamma correction mode for the WGPU renderer
328#[derive(Debug, Clone, Copy, PartialEq, Eq)]
329pub enum GammaMode {
330    /// Automatically pick gamma based on render target format (default)
331    Auto,
332    /// Force linear output (gamma = 1.0)
333    Linear,
334    /// Force gamma 2.2 curve (gamma = 2.2)
335    Gamma22,
336}