dear_imgui_wgpu/texture.rs
1//! Texture management for the WGPU renderer
2//!
3//! Application-owned texture views use opaque [`ExternalTextureId`] handles. Context-owned
4//! textures are keyed by pointer-free [`SnapshotTextureId`] values and are only changed by owned
5//! renderer requests.
6
7mod cache;
8mod cleanup;
9mod manager;
10mod resource;
11#[cfg(test)]
12mod tests;
13mod upload;
14
15use crate::{RenderResources, RendererError, RendererResult};
16use dear_imgui_rs::{
17 TextureId,
18 render::{SnapshotTextureId, TextureFeedback, TextureOp, TextureRequest, TextureUploadRect},
19 texture::{TextureFormat as ImGuiTextureFormat, TextureRect},
20};
21use std::{collections::HashMap, num::NonZeroU64};
22use wgpu::*;
23
24pub(crate) use cleanup::ManagedRequestOutcome;
25pub(crate) use manager::WgpuTextureManager;
26pub(crate) use resource::OwnedWgpuTexture;
27#[cfg(test)]
28pub(crate) use tests::{external_test_texture, request_test_device};
29
30/// Opaque handle for an application-owned WGPU texture view registered with a renderer.
31///
32/// The handle can be passed to Dear ImGui through [`Self::texture_id`], but cannot be forged from
33/// an arbitrary [`TextureId`]. Registration owns a clone of the WGPU view handle; the application
34/// remains responsible for the texture contents and must not explicitly destroy the underlying
35/// GPU resource while it is registered.
36#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
37#[repr(transparent)]
38pub struct ExternalTextureId(TextureId);
39
40impl ExternalTextureId {
41 pub(super) const fn new(texture_id: TextureId) -> Self {
42 Self(texture_id)
43 }
44
45 /// Returns the Dear ImGui texture identifier used by image widgets and draw-list commands.
46 #[must_use]
47 pub const fn texture_id(self) -> TextureId {
48 self.0
49 }
50}
51
52impl From<ExternalTextureId> for TextureId {
53 fn from(texture: ExternalTextureId) -> Self {
54 texture.texture_id()
55 }
56}
57
58/// One version of the WGPU view bound to an external texture registration.
59///
60/// Registration starts at revision one. Every successful view replacement advances the revision,
61/// including replacement with the same view handle. A binding is owned metadata: retaining it
62/// neither keeps a registration alive nor owns a GPU resource. The revision describes the view
63/// mapping, not the application's texture contents or engine frame number.
64#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
65pub struct ExternalTextureBinding {
66 /// The external registration used by Dear ImGui draw commands.
67 pub texture: ExternalTextureId,
68 /// The nonzero view-mapping revision observed when the binding was captured.
69 pub revision: NonZeroU64,
70}
71
72/// External texture dependencies observed while preparing executable draw commands.
73///
74/// Bindings appear once, in first-use order, after index validation, framebuffer clipping, and
75/// image-bind-group preparation succeed. Zero-count and fully clipped commands contribute no
76/// bindings. Managed textures and the renderer's default texture are not external dependencies.
77/// This metadata describes prepared commands; recording, submission, and presentation must be
78/// tracked separately.
79#[derive(Clone, Debug, Default, Eq, PartialEq)]
80pub struct WgpuDrawDependencies {
81 /// External view mappings used by prepared element commands.
82 pub external_bindings: Vec<ExternalTextureBinding>,
83 /// Whether a non-standard raw callback may use additional, unobservable GPU resources.
84 ///
85 /// Standard reset and sampler-selection callbacks do not make the dependency list incomplete.
86 pub contains_unknown_callback_dependencies: bool,
87}