Skip to content

Commit 29f073a

Browse files
committed
[update] high level renderer to re apply the swapchain every frame, update the demo application.
1 parent 18d7631 commit 29f073a

7 files changed

Lines changed: 130 additions & 53 deletions

File tree

lambda/src/core/kernel.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pub trait Kernel {
2-
fn on_start(&self);
3-
fn on_stop(&self);
2+
fn on_start(&mut self);
3+
fn on_stop(&mut self);
44
fn run(self);
55
}
66

@@ -13,7 +13,7 @@ pub fn build_and_start_kernel<T: Default + Kernel>() {
1313
}
1414

1515
/// Simple function for starting any prebuilt Runnable.
16-
pub fn start_kernel<T: Kernel>(kernel: T) {
16+
pub fn start_kernel<T: Kernel>(mut kernel: T) {
1717
kernel.on_start();
1818
kernel.run();
1919
}

lambda/src/core/render/command.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ pub enum RenderCommand {
3030
viewports: Vec<super::viewport::Viewport>,
3131
},
3232
SetPipeline {
33-
pipeline: super::pipeline::RenderPipeline,
33+
pipeline: Rc<super::pipeline::RenderPipeline>,
3434
},
3535
/// Begins the render pass.
3636
BeginRenderPass {
37-
render_pass: super::render_pass::RenderPass,
37+
render_pass: Rc<super::render_pass::RenderPass>,
3838
viewport: super::viewport::Viewport,
3939
},
4040
/// Ends the render pass.
@@ -78,17 +78,21 @@ impl RenderCommand {
7878
let surface = surface_for_context(render_context);
7979
let render_pass = render_pass.into_gfx_render_pass();
8080
let frame_buffer =
81-
render_context.allocate_and_get_frame_buffer(&render_pass);
81+
render_context.allocate_and_get_frame_buffer(render_pass.as_ref());
8282

8383
PlatformRenderCommand::BeginRenderPass {
84-
render_pass,
85-
surface,
86-
frame_buffer,
84+
render_pass: render_pass.clone(),
85+
surface: surface.clone(),
86+
frame_buffer: frame_buffer.clone(),
8787
viewport: viewport.into_gfx_viewport(),
8888
}
8989
}
9090
RenderCommand::EndRenderPass => PlatformRenderCommand::EndRenderPass,
91-
RenderCommand::SetPipeline { pipeline } => todo!(),
91+
RenderCommand::SetPipeline { pipeline } => {
92+
PlatformRenderCommand::AttachGraphicsPipeline {
93+
pipeline: pipeline.into_platform_render_pipeline(),
94+
}
95+
}
9296
RenderCommand::Draw { vertices } => {
9397
PlatformRenderCommand::Draw { vertices }
9498
}

lambda/src/core/render/mod.rs

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ use lambda_platform::gfx::{
9090

9191
use self::{
9292
command::RenderCommand,
93+
pipeline::RenderPipeline,
9394
render_pass::RenderPass,
9495
};
9596

@@ -124,8 +125,9 @@ impl RenderContextBuilder {
124125

125126
let mut instance = internal::InstanceBuilder::new()
126127
.build::<internal::RenderBackend>(name.as_str());
127-
let mut surface =
128-
internal::SurfaceBuilder::new().build(&instance, window.window_handle());
128+
let mut surface = Rc::new(
129+
internal::SurfaceBuilder::new().build(&instance, window.window_handle()),
130+
);
129131

130132
// Build a GPU with a 3D Render queue that can render to our surface.
131133
let mut gpu = internal::GpuBuilder::new()
@@ -151,21 +153,23 @@ impl RenderContextBuilder {
151153
.with_size(dimensions[0], dimensions[1])
152154
.build(&gpu, &surface);
153155

154-
surface
155-
.apply_swapchain(&gpu, swapchain, 1_000_000_000)
156+
Rc::get_mut(&mut surface)
157+
.expect("Failed to get mutable reference to surface.")
158+
.apply_swapchain(&gpu, swapchain, self.render_timeout)
156159
.expect("Failed to apply the swapchain to the surface.");
157160

158161
return RenderContext {
159162
name,
160163
instance,
161164
gpu,
162-
surface: Rc::new(surface),
165+
surface: surface.clone(),
163166
frame_buffer: None,
164167
submission_fence: Some(submission_fence),
165168
render_semaphore: Some(render_semaphore),
166169
command_pool: Some(command_pool),
167170
viewports: vec![],
168171
render_passes: vec![],
172+
render_pipelines: vec![],
169173
};
170174
}
171175
}
@@ -183,6 +187,7 @@ pub struct RenderContext {
183187
render_semaphore: Option<internal::RenderSemaphore<internal::RenderBackend>>,
184188
command_pool: Option<internal::CommandPool<internal::RenderBackend>>,
185189
render_passes: Vec<Option<RenderPass>>,
190+
render_pipelines: Vec<Option<RenderPipeline>>,
186191
viewports: Vec<ViewPort>,
187192
}
188193

@@ -195,13 +200,22 @@ impl RenderContext {
195200
self.submission_fence.take().unwrap().destroy(&self.gpu);
196201
self.render_semaphore.take().unwrap().destroy(&self.gpu);
197202

203+
// Destroy render passes.
198204
let mut render_passes = vec![];
199205
swap(&mut self.render_passes, &mut render_passes);
200206

201207
for render_pass in &mut render_passes {
202208
render_pass.take().unwrap().destroy(&self);
203209
}
204210

211+
// Destroy render pipelines.
212+
let mut render_pipelines = vec![];
213+
swap(&mut self.render_pipelines, &mut render_pipelines);
214+
215+
for render_pipeline in &mut render_pipelines {
216+
render_pipeline.take().unwrap().destroy(&self);
217+
}
218+
205219
// Takes the inner surface and destroys it.
206220
let mut surface = Rc::try_unwrap(self.surface).ok().unwrap();
207221
surface.remove_swapchain(&self.gpu);
@@ -211,15 +225,12 @@ impl RenderContext {
211225
pub fn allocate_and_get_frame_buffer(
212226
&mut self,
213227
render_pass: &internal::RenderPass<internal::RenderBackend>,
214-
) -> Rc<
215-
lambda_platform::gfx::framebuffer::Framebuffer<
216-
lambda_platform::gfx::api::RenderingAPI::Backend,
217-
>,
218-
> {
228+
) -> Rc<lambda_platform::gfx::framebuffer::Framebuffer<internal::RenderBackend>>
229+
{
219230
let frame_buffer = FramebufferBuilder::new().build(
220231
&mut self.gpu,
221232
&render_pass,
222-
&self.surface,
233+
self.surface.as_ref(),
223234
);
224235

225236
// TODO(vmarcella): Update the framebuffer allocation to not be so hacky.
@@ -231,6 +242,20 @@ impl RenderContext {
231242

232243
/// Allocates a command buffer and records commands to the GPU.
233244
pub fn render(&mut self, commands: Vec<RenderCommand>) {
245+
let dimensions = self
246+
.surface
247+
.size()
248+
.expect("Surface has no size configured.");
249+
250+
let swapchain = SwapchainBuilder::new()
251+
.with_size(dimensions[0], dimensions[1])
252+
.build(&self.gpu, &self.surface);
253+
254+
Rc::get_mut(&mut self.surface)
255+
.expect("Failed to get mutable reference to surface.")
256+
.apply_swapchain(&self.gpu, swapchain, 1_000_000_000)
257+
.expect("Failed to apply the swapchain to the surface.");
258+
234259
let platform_command_list = commands
235260
.into_iter()
236261
.map(|command| command.into_platform_command(self))

lambda/src/core/render/pipeline.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::rc::Rc;
2+
13
use lambda_platform::gfx::shader::{
24
ShaderModuleBuilder,
35
ShaderModuleType,
@@ -7,21 +9,34 @@ use super::{
79
internal::{
810
gpu_from_context,
911
mut_gpu_from_context,
12+
RenderBackend,
1013
},
1114
render_pass::internal::platform_render_pass_from_render_pass,
1215
shader::Shader,
1316
RenderContext,
1417
};
18+
19+
#[derive(Debug)]
1520
pub struct RenderPipeline {
16-
pipeline: lambda_platform::gfx::pipeline::RenderPipeline<
17-
super::internal::RenderBackend,
21+
pipeline: Rc<
22+
lambda_platform::gfx::pipeline::RenderPipeline<
23+
super::internal::RenderBackend,
24+
>,
1825
>,
1926
}
2027

2128
impl RenderPipeline {
2229
/// Destroy the render pipeline with the render context that created it.
2330
pub fn destroy(self, render_context: &RenderContext) {
24-
self.pipeline.destroy(gpu_from_context(render_context));
31+
Rc::try_unwrap(self.pipeline)
32+
.expect("Failed to destroy render pipeline")
33+
.destroy(gpu_from_context(render_context));
34+
}
35+
36+
pub fn into_platform_render_pipeline(
37+
&self,
38+
) -> Rc<lambda_platform::gfx::pipeline::RenderPipeline<RenderBackend>> {
39+
return self.pipeline.clone();
2540
}
2641
}
2742

@@ -64,7 +79,7 @@ impl RenderPipelineBuilder {
6479
fragment_shader_module.destroy(mut_gpu_from_context(render_context));
6580

6681
return RenderPipeline {
67-
pipeline: render_pipeline,
82+
pipeline: Rc::new(render_pipeline),
6883
};
6984
}
7085
}

lambda/src/core/render/render_pass.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
1+
use std::rc::Rc;
2+
13
use lambda_platform::gfx::render_pass;
24

35
use super::{
46
internal::gpu_from_context,
57
RenderContext,
68
};
9+
10+
#[derive(Debug)]
711
pub struct RenderPass {
8-
render_pass: render_pass::RenderPass<super::internal::RenderBackend>,
12+
render_pass: Rc<render_pass::RenderPass<super::internal::RenderBackend>>,
913
}
1014

1115
impl RenderPass {
1216
/// Destroy the render pass with the render context that created it.
1317
pub fn destroy(self, render_context: &RenderContext) {
14-
self.render_pass.destroy(gpu_from_context(render_context));
18+
Rc::try_unwrap(self.render_pass)
19+
.expect("Failed to destroy render pass. Is something holding a reference to it?")
20+
.destroy(gpu_from_context(render_context));
1521
}
1622

1723
/// Converts
1824
pub fn into_gfx_render_pass(
19-
self,
20-
) -> render_pass::RenderPass<super::internal::RenderBackend> {
21-
return self.render_pass;
25+
&self,
26+
) -> Rc<render_pass::RenderPass<super::internal::RenderBackend>> {
27+
return self.render_pass.clone();
2228
}
2329
}
2430

@@ -34,7 +40,9 @@ impl RenderPassBuilder {
3440
let render_pass =
3541
lambda_platform::gfx::render_pass::RenderPassBuilder::new()
3642
.build(gpu_from_context(render_context));
37-
return RenderPass { render_pass };
43+
return RenderPass {
44+
render_pass: Rc::new(render_pass),
45+
};
3846
}
3947
}
4048

lambda/src/kernels/mod.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,7 @@ impl Kernel for LambdaKernel {
202202
WinitEvent::DeviceEvent { device_id, event } => {}
203203
WinitEvent::UserEvent(lambda_event) => {
204204
match lambda_event {
205-
Event::Initialized => {
206-
for component in &mut component_stack {
207-
component.on_attach();
208-
component
209-
.on_renderer_attached(active_render_api.as_mut().unwrap());
210-
}
211-
}
205+
Event::Initialized => {}
212206
Event::Shutdown => {
213207
// Once this has been set, the ControlFlow can no longer be
214208
// modified.
@@ -239,11 +233,15 @@ impl Kernel for LambdaKernel {
239233
});
240234
}
241235

242-
fn on_start(&self) {
243-
println!("Starting {}", self.name)
236+
fn on_start(&mut self) {
237+
println!("Starting {}", self.name);
238+
for component in &mut self.component_stack {
239+
component.on_attach();
240+
component.on_renderer_attached(&mut self.render_api);
241+
}
244242
}
245243

246-
fn on_stop(&self) {
244+
fn on_stop(&mut self) {
247245
println!("Stopping {}", self.name)
248246
}
249247
}

0 commit comments

Comments
 (0)