Skip to main content

EguiIntegration

Struct EguiIntegration 

Source
pub struct EguiIntegration {
Show 19 fields device: Device, pipeline: SpecializedLitPipeline, textures: HashMap<TextureKey, TextureSlot>, texture_options: HashMap<TextureKey, TextureOptions>, samplers: Vec<(TextureOptions, ResHandle<Sampler>)>, materials: Vec<(MaterialKey, ResHandle<BindGroup>)>, vertices: Option<Buffer>, indices: Option<Buffer>, vertex_node: Option<ResHandle<Buffer>>, index_node: Option<ResHandle<Buffer>>, instance: Buffer, vertex_capacity: usize, index_capacity: usize, frame_vertices: usize, vertex_staging: StagingBuffer, index_staging: StagingBuffer, draws: Vec<UiDraw>, packed_vertices: Vec<u8>, packed_indices: Vec<u8>,
}
Available on crate feature egui only.
Expand description

Draws tessellated egui output with the built-in lit pipeline.

The UI’s GPU resources are registered in a ResourceGraph the caller supplies — normally the one kept alongside the RenderAttachments — so the whole frame shares one ledger. Every method that touches the graph takes it as an argument: the renderer holds only the bookkeeping (ids, keys) that maps egui’s world onto graph nodes.

Fields§

§device: Device

Kept to build the resources a frame turns out to need.

§pipeline: SpecializedLitPipeline§textures: HashMap<TextureKey, TextureSlot>

Graph nodes of every allocated texture slot, keyed by origin and id.

§texture_options: HashMap<TextureKey, TextureOptions>

The sampling options egui last stated for each texture.

Kept separately from the texture itself because every ImageDelta carries the options that apply to the whole texture, and the draw that samples it has to name the matching sampler: Self::sampler keys its cache on exactly these options, so a texture uploaded as nearest samples nearest.

§samplers: Vec<(TextureOptions, ResHandle<Sampler>)>

One sampler per distinct set of egui sampling options seen, with its graph node.

§materials: Vec<(MaterialKey, ResHandle<BindGroup>)>

One material bind group per (texture, options) pair, with its graph node; the node depends on the texture’s view and the sampler.

§vertices: Option<Buffer>

Positions, then interleaved UVs and colors.

§indices: Option<Buffer>

Uint32 indices.

§vertex_node: Option<ResHandle<Buffer>>

Graph node of the vertex buffer, replaced in place when it grows.

§index_node: Option<ResHandle<Buffer>>

Graph node of the index buffer, replaced in place when it grows.

§instance: Buffer

One default MeshInstance, bound at INSTANCE_SLOT by every draw.

The built-in pipeline always declares the instance stream, and a UI draw reads no instance state, so one identity record serves every draw. It never changes, so it needs no graph node.

§vertex_capacity: usize

Vertices the vertex buffer holds room for.

§index_capacity: usize

Indices the index buffer holds room for.

§frame_vertices: usize

Vertices the most recently uploaded frame holds. This is where its two vertex streams meet, so Self::scene has to split at the same point Self::upload_geometry packed at — which is not the capacity whenever the buffer has room to spare.

§vertex_staging: StagingBuffer

Staging buffer for the per-frame vertex uploads, reused across frames.

§index_staging: StagingBuffer

Staging buffer for the per-frame index uploads, reused across frames.

§draws: Vec<UiDraw>

Layout of the frame most recently uploaded.

§packed_vertices: Vec<u8>

Packing scratch for the vertex stream — positions then interleaved UVs and colors — kept so a steady UI reuses one allocation instead of taking a fresh one every frame.

§packed_indices: Vec<u8>

Packing scratch for the index stream, reused the same way.

Implementations§

Source§

impl EguiIntegration

Source

pub fn new(device: &Device, pipeline: SpecializedLitPipeline) -> Self

Build the UI integration around a caller-supplied pipeline, registering the UI’s per-texture resources in graph.

pipeline is the built-in lit pipeline the UI draws with, configured for the target the pass renders into — its color format, sample count and blend state. The caller builds it up front, so the UI does not compile a pipeline of its own.

The global bind group — the camera, the frame globals and the view — is the caller’s, and it is handed to Self::scene rather than kept here: the frame owns the uniforms and builds one group per camera and viewport its draws name, so a source can draw the same UI through two cameras without owning either group. Everything else the UI overlays is the caller’s too: the integration owns only egui’s textures and the geometry they are drawn with. Sharing the caller’s graph — usually the one kept alongside the crate::render_attachments::RenderAttachments — means those resources live in the same ledger as the rest of the frame’s, with the same dependency tracking.

Source

pub fn update( &mut self, graph: &mut ResourceGraph, queue: &Queue, encoder: &mut CommandEncoder, ctx: &Context, output: FullOutput, screen: ScreenDescriptor, )

Apply output’s texture updates and upload its tessellated shapes, ready for Self::scene.

The vertex and index bytes change every frame, so they are staged through encoder: scene’s pass is recorded into the same encoder afterwards, and one submission carries the upload and the draw that reads it. Texture updates still go through queue.

screen tells egui how to rasterise text and scales the tessellated points and their clip rectangles; see ScreenDescriptor.

This tessellates output with ctx, which is right when the context and the drawing share a world. A caller whose shapes were laid out elsewhere — in another world, by another context — uses Self::update_with and tessellates where the context lives.

Source

pub fn update_with( &mut self, graph: &mut ResourceGraph, queue: &Queue, encoder: &mut CommandEncoder, sources: &mut [UiFrame<'_>], screen: ScreenDescriptor, )

Apply texture updates and upload primitives from every source, ready for Self::scene.

Tessellation needs the [egui::Context] that produced the shapes — its font atlas and tessellation options — so a UI laid out in one world and drawn in another cannot be tessellated by the drawing side. Such a caller tessellates where each context lives and hands each result over with the Source it came from.

A source is a namespace, not an identity: every context allocates its texture ids from zero, so the same id names different images in different sources. Keys carry the pair, and the ids a frame arrived with are the ids it is drawn by — nothing rewrites them.

One call per frame: the integration packs one vertex and index buffer, and the two vertex streams meet at a single split point, so a second call would overwrite the first.

Each textures delta is applied and then cleared, so the caller may drop it afterwards: egui panics when a delta is dropped unapplied.

Source

pub fn release(&mut self)

Forget every graph node the integration registered, and its bookkeeping.

The ids this drops are the last references the graph holds to the two geometry buffers, every texture, view, sampler and material, so the next ResourceGraph::maintain collects them — and, once the material nodes go, the views and textures they were the last holders of. No graph is needed here: giving a resource up is dropping its id.

After this the integration is back to its freshly built state and may be reused against the same graph.

Source

fn upload_geometry<'a>( &mut self, encoder: &mut CommandEncoder, primitives: impl IntoIterator<Item = (Source, &'a ClippedPrimitive)>, screen: ScreenDescriptor, counts: GeometryCounts, )

Pack primitives into the vertex and index buffers, staging the bytes through encoder, and fill Self::draws with where each one landed.

The primary and secondary streams go into two regions of the one buffer: wgpu binds one stride per slot, and the two streams differ.

Source

pub fn scene(&self, graph: &ResourceGraph, global: &BindGroup) -> Scene

The frame most recently uploaded, as a scene.

Every draw sets a scissor rectangle, and a scissor stays set for the rest of the pass, so record this after the draws it overlays.

The materials the frame needs were built by Self::update, so this only reads the graph — a scene can therefore be taken while the graph is shared with whatever else the frame is drawing.

global is the caller’s global bind group for the camera, the frame globals and the view this frame draws through; the UI binds it at GLOBAL_GROUP for every draw.

Source

fn reserve(&mut self, graph: &mut ResourceGraph, counts: GeometryCounts)

Reallocate the buffers when they cannot hold counts, registering any new buffer in graph.

Source

fn material<'a>( &self, graph: &'a ResourceGraph, texture: TextureKey, options: TextureOptions, ) -> Option<&'a BindGroup>

The material bind group for (id, options), if it exists.

Source

fn build_material( &mut self, graph: &mut ResourceGraph, texture: TextureKey, options: TextureOptions, )

Build the material bind group for (id, options) if it does not exist, registered in the graph as a dependent of its texture’s view and its sampler.

The group is built once here and rebuilt by ResourceGraph::maintain whenever the view or the sampler is replaced: the recipe reads both back out of the graph by id, so a texture which patches itself into a new handle is picked up without the material being rebuilt by hand.

Source

fn sampler( &mut self, graph: &mut ResourceGraph, options: TextureOptions, ) -> ResHandle<Sampler>

The sampler for options, created and registered on first use.

Source

fn apply_textures( &mut self, graph: &mut ResourceGraph, queue: &Queue, source: Source, delta: &TexturesDelta, )

Source

fn upload_texture( &mut self, graph: &mut ResourceGraph, queue: &Queue, key: TextureKey, delta: &ImageDelta, )

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Downcast<T> for T

§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

§

impl<T, S> SimdFrom<T, S> for T
where S: Simd,

§

fn simd_from(_simd: S, value: T) -> T

§

impl<F, T, S> SimdInto<T, S> for F
where T: SimdFrom<F, S>, S: Simd,

§

fn simd_into(self, simd: S) -> T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> Upcast<T> for T

§

fn upcast(&self) -> Option<&T>

§

impl<T> WasmNotSend for T
where T: Send,

§

impl<T> WasmNotSendSync for T
where T: WasmNotSend + WasmNotSync,

§

impl<T> WasmNotSync for T
where T: Sync,

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more