1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//! Frame graph rendering system for composable render pipelines.
//!
//! Build complex rendering pipelines by declaring passes and their resource dependencies:
//!
//! - [`RenderGraph`]: Main graph structure that schedules and executes render passes
//! - [`PassNode`]: Trait for implementing custom render passes
//! - [`PassExecutionContext`]: Runtime context for accessing resources during execution
//! - [`ResourceId`]: Handle to a graph-managed texture or buffer
//!
//! The render graph automatically handles:
//! - Pass ordering based on resource dependencies
//! - Transient resource allocation and aliasing
//! - Load/store operation optimization
//! - Dead pass culling
//!
//! # Basic Graph Setup
//!
//! ```ignore
//! use nightshade::render::wgpu::rendergraph::{RenderGraph, PassNode, PassExecutionContext};
//!
//! let mut graph = RenderGraph::new();
//!
//! // Declare resources
//! let depth = render_graph_add_depth_texture(&mut graph, "depth")
//! .size(1920, 1080)
//! .clear_depth(0.0)
//! .transient();
//!
//! let scene_color = render_graph_add_color_texture(&mut graph, "scene_color")
//! .format(wgpu::TextureFormat::Rgba16Float)
//! .size(1920, 1080)
//! .clear_color(wgpu::Color::BLACK)
//! .transient();
//!
//! let swapchain = render_graph_add_color_texture(&mut graph, "swapchain")
//! .format(wgpu::TextureFormat::Bgra8UnormSrgb)
//! .external(); // Provided each frame
//!
//! // Add passes with their resource bindings
//! graph.add_pass(Box::new(scene_pass), &[
//! ("color", scene_color),
//! ("depth", depth),
//! ])?;
//!
//! graph.add_pass(Box::new(post_process_pass), &[
//! ("input", scene_color),
//! ("output", swapchain),
//! ])?;
//!
//! render_graph_compile(&mut graph)?;
//! ```
//!
//! # Implementing a Custom Pass
//!
//! ```ignore
//! struct MyPass {
//! pipeline: wgpu::RenderPipeline,
//! }
//!
//! impl PassNode for MyPass {
//! fn name(&self) -> &str { "my_pass" }
//!
//! fn reads(&self) -> Vec<&str> { vec!["input"] }
//! fn writes(&self) -> Vec<&str> { vec!["output"] }
//!
//! fn execute<'r, 'e>(
//! &mut self,
//! ctx: PassExecutionContext<'r, 'e>,
//! ) -> Result<Vec<SubGraphRunCommand<'r>>> {
//! let (output_view, load_op, store_op) = ctx.get_color_attachment("output")?;
//! let input_view = render_graph_get_texture_view(&ctx, "input")?;
//!
//! let mut pass = ctx.encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
//! color_attachments: &[Some(wgpu::RenderPassColorAttachment {
//! view: output_view,
//! resolve_target: None,
//! ops: wgpu::Operations { load: load_op, store: store_op },
//! })],
//! ..Default::default()
//! });
//!
//! pass.set_pipeline(&self.pipeline);
//! // Bind input_view to a bind group...
//! pass.draw(0..3, 0..1);
//!
//! Ok(vec![])
//! }
//! }
//! ```
//!
//! # Executing the Graph
//!
//! ```ignore
//! // Each frame:
//! render_graph_set_external_texture(&mut graph, swapchain_id, surface_view, width, height);
//!
//! let command_buffers = render_graph_execute(&mut graph, &device, &queue, &world)?;
//! queue.submit(command_buffers);
//! ```
//!
//! # Resource Types
//!
//! | Type | Description |
//! |------|-------------|
//! | Transient | Graph allocates/manages lifetime, can be aliased |
//! | External | Provided each frame (swapchain, imported textures) |
//!
//! # Pass Methods
//!
//! | Method | Description |
//! |--------|-------------|
//! | `name()` | Unique identifier for the pass |
//! | `reads()` | Slots this pass reads from |
//! | `writes()` | Slots this pass writes to |
//! | `reads_writes()` | Slots used for both read and write |
//! | `prepare()` | Called before execute, for uploading uniforms |
//! | `execute()` | Record GPU commands |
//!
//! # Context Methods
//!
//! | Method | Description |
//! |--------|-------------|
//! | `get_texture_view(slot)` | Get texture view for reading |
//! | `get_color_attachment(slot)` | Get view + load/store ops for color output |
//! | `get_depth_attachment(slot)` | Get view + load/store ops for depth output |
//! | `get_buffer(slot)` | Get buffer for compute passes |
//! | `get_texture_size(slot)` | Get dimensions of a texture |
//!
//! # Customizing the Engine's Render Graph
//!
//! Override [`State::configure_render_graph`](crate::run::State::configure_render_graph)
//! to modify or extend the default pipeline:
//!
//! ```ignore
//! impl State for MyGame {
//! fn configure_render_graph(
//! &mut self,
//! graph: &mut RenderGraph<World>,
//! device: &wgpu::Device,
//! ) {
//! // Disable a built-in pass
//! render_graph_set_pass_enabled(&mut graph, "bloom_pass", false);
//!
//! // Or add your own post-process pass
//! // graph.add_pass(Box::new(MyEffect::new(device)), &[...]);
//! }
//! }
//! ```
pub use ;
pub use ;
pub use ;
pub use ;