Skip to main content

viewport_lib/renderer/
paths.rs

1use super::{FrameData, SceneEffects, ViewportId, ViewportRenderer};
2
3/// Rendering path for applications that own the window loop and wgpu encoder.
4///
5/// Obtained from [`ViewportRenderer::owned`]. The renderer encodes all GPU work
6/// and returns a [`wgpu::CommandBuffer`] for the caller to submit.
7///
8/// Use this with winit, raw wgpu, or any setup where you control the encoder.
9pub struct OwnedPath<'r> {
10    pub(super) renderer: &'r mut ViewportRenderer,
11}
12
13/// Rendering path for framework callbacks that provide a render pass.
14///
15/// Obtained from [`ViewportRenderer::pass`]. Prepare encodes pre-pass work
16/// and returns command buffers to submit before the surface pass. Paint draws
17/// into the caller-provided render pass.
18///
19/// Use this with eframe (`CallbackTrait`), iced, or any framework that hands
20/// you a render pass. For the eframe `paint` callback where only a `&` reference
21/// to the renderer is available, use [`ViewportRenderer::pass_view`] instead.
22pub struct PassPath<'r> {
23    pub(super) renderer: &'r mut ViewportRenderer,
24}
25
26/// Read-only paint view returned by [`ViewportRenderer::pass_view`].
27///
28/// Identical to [`PassPath`] but constructed from a shared reference, making it
29/// usable in framework paint callbacks where only `&` access to the renderer is
30/// available (e.g. eframe's `CallbackTrait::paint`).
31pub struct PassView<'r> {
32    pub(super) renderer: &'r ViewportRenderer,
33}
34
35impl<'r> OwnedPath<'r> {
36    /// Render a single viewport. Runs prepare internally and returns a command buffer to submit.
37    pub fn render(
38        &mut self,
39        device: &wgpu::Device,
40        queue: &wgpu::Queue,
41        output_view: &wgpu::TextureView,
42        frame: &FrameData,
43    ) -> wgpu::CommandBuffer {
44        self.renderer.render(device, queue, output_view, frame)
45    }
46
47    /// Multi-viewport: upload scene-level GPU data shared across all viewports.
48    /// Call once per frame before any `prepare_viewport` or `render_viewport` calls.
49    pub fn prepare_scene(
50        &mut self,
51        device: &wgpu::Device,
52        queue: &wgpu::Queue,
53        frame: &FrameData,
54        scene_effects: &SceneEffects<'_>,
55    ) {
56        self.renderer.prepare_scene(device, queue, frame, scene_effects);
57    }
58
59    /// Multi-viewport: upload per-viewport GPU data for `id`.
60    /// Call after `prepare_scene` and before `render_viewport`.
61    pub fn prepare_viewport(
62        &mut self,
63        device: &wgpu::Device,
64        queue: &wgpu::Queue,
65        id: ViewportId,
66        frame: &FrameData,
67    ) {
68        self.renderer.prepare_viewport(device, queue, id, frame);
69    }
70
71    /// Multi-viewport: encode draw calls for `id` into its own command buffer.
72    /// Call after `prepare_scene` and `prepare_viewport` for this id.
73    pub fn render_viewport(
74        &mut self,
75        device: &wgpu::Device,
76        queue: &wgpu::Queue,
77        output_view: &wgpu::TextureView,
78        id: ViewportId,
79        frame: &FrameData,
80    ) -> wgpu::CommandBuffer {
81        self.renderer.render_viewport(device, queue, output_view, id, frame)
82    }
83}
84
85impl<'r> PassPath<'r> {
86    /// Single viewport: upload uniforms and encode any HDR pre-pass work.
87    ///
88    /// Returns command buffers that must be submitted before the surface render
89    /// pass begins. Returns an empty vec for LDR with no dynamic resolution.
90    pub fn prepare(
91        &mut self,
92        device: &wgpu::Device,
93        queue: &wgpu::Queue,
94        frame: &FrameData,
95    ) -> Vec<wgpu::CommandBuffer> {
96        self.renderer.prepare_callback(device, queue, frame)
97    }
98
99    /// Single viewport: issue draw calls into `render_pass`.
100    ///
101    /// Call after `prepare` for the same frame. Dispatches to the HDR blit,
102    /// dynamic-resolution blit, or direct draw based on which path `prepare`
103    /// activated. The render pass is expected to have a depth-stencil attachment,
104    /// as provided by eframe and most GUI frameworks.
105    pub fn paint<'rp>(&self, render_pass: &mut wgpu::RenderPass<'rp>, frame: &FrameData) {
106        self.renderer.paint_callback(render_pass, frame);
107    }
108
109    /// Multi-viewport: upload scene-level GPU data shared across all viewports.
110    pub fn prepare_scene(
111        &mut self,
112        device: &wgpu::Device,
113        queue: &wgpu::Queue,
114        frame: &FrameData,
115        scene_effects: &SceneEffects<'_>,
116    ) {
117        self.renderer.prepare_scene(device, queue, frame, scene_effects);
118    }
119
120    /// Multi-viewport: upload per-viewport GPU data for `id`.
121    pub fn prepare_viewport(
122        &mut self,
123        device: &wgpu::Device,
124        queue: &wgpu::Queue,
125        id: ViewportId,
126        frame: &FrameData,
127    ) {
128        self.renderer.prepare_viewport(device, queue, id, frame);
129    }
130
131    /// Multi-viewport: issue draw calls for `id` into `render_pass`.
132    ///
133    /// Set the render pass viewport and scissor rect to the correct region
134    /// before calling. Call after `prepare_scene` and `prepare_viewport`.
135    pub fn paint_viewport<'rp>(
136        &self,
137        render_pass: &mut wgpu::RenderPass<'rp>,
138        id: ViewportId,
139        frame: &FrameData,
140    ) {
141        self.renderer.paint_viewport_to(render_pass, id, frame);
142    }
143}
144
145impl<'r> PassView<'r> {
146    /// Single viewport: issue draw calls into `render_pass`.
147    pub fn paint<'rp>(&self, render_pass: &mut wgpu::RenderPass<'rp>, frame: &FrameData) {
148        self.renderer.paint_callback(render_pass, frame);
149    }
150
151    /// Multi-viewport: issue draw calls for `id` into `render_pass`.
152    pub fn paint_viewport<'rp>(
153        &self,
154        render_pass: &mut wgpu::RenderPass<'rp>,
155        id: ViewportId,
156        frame: &FrameData,
157    ) {
158        self.renderer.paint_viewport_to(render_pass, id, frame);
159    }
160}