Skip to content

Commit f991c62

Browse files
committed
[update] the render_context framebuffer implementation to use Rc for managing it's lifetime.
1 parent d980206 commit f991c62

2 files changed

Lines changed: 71 additions & 12 deletions

File tree

lambda/src/core/render/command.rs

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1-
use std::ops::Range;
1+
use std::{
2+
ops::Range,
3+
rc::Rc,
4+
};
25

3-
use lambda_platform::gfx::viewport::ViewPort as PlatformViewPort;
6+
use lambda_platform::gfx::{
7+
framebuffer::FramebufferBuilder,
8+
viewport::ViewPort as PlatformViewPort,
9+
};
410

511
use super::{
6-
internal::surface_for_context,
12+
internal::{
13+
gpu_from_context,
14+
mut_gpu_from_context,
15+
surface_for_context,
16+
},
717
PlatformRenderCommand,
818
RenderContext,
919
};
@@ -38,7 +48,7 @@ impl RenderCommand {
3848
// TODO(vmarcella): implement this using Into<PlatformRenderCommand>
3949
pub fn into_platform_command(
4050
self,
41-
render_context: &RenderContext,
51+
render_context: &mut RenderContext,
4252
) -> PlatformRenderCommand {
4353
return match self {
4454
RenderCommand::SetViewports {
@@ -64,15 +74,24 @@ impl RenderCommand {
6474
RenderCommand::BeginRenderPass {
6575
render_pass,
6676
viewport,
67-
} => PlatformRenderCommand::BeginRenderPass {
68-
render_pass: render_pass.into_gfx_render_pass(),
69-
surface: surface_for_context(render_context),
70-
frame_buffer: todo!("FrameBuffer"),
71-
viewport: viewport.into_gfx_viewport(),
72-
},
73-
RenderCommand::EndRenderPass => todo!(),
77+
} => {
78+
let surface = surface_for_context(render_context);
79+
let render_pass = render_pass.into_gfx_render_pass();
80+
let frame_buffer =
81+
render_context.allocate_and_get_frame_buffer(&render_pass);
82+
83+
PlatformRenderCommand::BeginRenderPass {
84+
render_pass,
85+
surface,
86+
frame_buffer,
87+
viewport: viewport.into_gfx_viewport(),
88+
}
89+
}
90+
RenderCommand::EndRenderPass => PlatformRenderCommand::EndRenderPass,
7491
RenderCommand::SetPipeline { pipeline } => todo!(),
75-
RenderCommand::Draw { vertices } => todo!(),
92+
RenderCommand::Draw { vertices } => {
93+
PlatformRenderCommand::Draw { vertices }
94+
}
7695
};
7796
}
7897
}

lambda/src/core/render/mod.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub mod internal {
2828
RenderSubmissionFence,
2929
RenderSubmissionFenceBuilder,
3030
},
31+
framebuffer::Framebuffer,
3132
gpu::{
3233
Gpu,
3334
GpuBuilder,
@@ -82,6 +83,7 @@ use lambda_platform::gfx::{
8283
CommandBufferFeatures,
8384
CommandBufferLevel,
8485
},
86+
framebuffer::FramebufferBuilder,
8587
surface::SwapchainBuilder,
8688
viewport::ViewPort,
8789
};
@@ -158,6 +160,7 @@ impl RenderContextBuilder {
158160
instance,
159161
gpu,
160162
surface: Rc::new(surface),
163+
frame_buffer: None,
161164
submission_fence: Some(submission_fence),
162165
render_semaphore: Some(render_semaphore),
163166
command_pool: Some(command_pool),
@@ -174,6 +177,7 @@ pub struct RenderContext {
174177
instance: internal::Instance<internal::RenderBackend>,
175178
gpu: internal::Gpu<internal::RenderBackend>,
176179
surface: Rc<internal::Surface<internal::RenderBackend>>,
180+
frame_buffer: Option<Rc<internal::Framebuffer<internal::RenderBackend>>>,
177181
submission_fence:
178182
Option<internal::RenderSubmissionFence<internal::RenderBackend>>,
179183
render_semaphore: Option<internal::RenderSemaphore<internal::RenderBackend>>,
@@ -204,6 +208,27 @@ impl RenderContext {
204208
surface.destroy(&self.instance);
205209
}
206210

211+
pub fn allocate_and_get_frame_buffer(
212+
&mut self,
213+
render_pass: &internal::RenderPass<internal::RenderBackend>,
214+
) -> Rc<
215+
lambda_platform::gfx::framebuffer::Framebuffer<
216+
lambda_platform::gfx::api::RenderingAPI::Backend,
217+
>,
218+
> {
219+
let frame_buffer = FramebufferBuilder::new().build(
220+
&mut self.gpu,
221+
&render_pass,
222+
&self.surface,
223+
);
224+
225+
// TODO(vmarcella): Update the framebuffer allocation to not be so hacky.
226+
// FBAs can only be allocated once a render pass has begun, but must be
227+
// cleaned up after commands have been submitted forcing us
228+
self.frame_buffer = Some(Rc::new(frame_buffer));
229+
return self.frame_buffer.as_ref().unwrap().clone();
230+
}
231+
207232
/// Allocates a command buffer and records commands to the GPU.
208233
pub fn render(&mut self, commands: Vec<RenderCommand>) {
209234
let platform_command_list = commands
@@ -216,7 +241,12 @@ impl RenderContext {
216241
.with_feature(CommandBufferFeatures::ResetEverySubmission)
217242
.build(self.command_pool.as_mut().unwrap(), "primary");
218243

244+
// Start recording commands, issue the high level render commands
245+
// that came from an application, and then submit the commands to the GPU
246+
// for rendering.
247+
command_buffer.issue_command(PlatformRenderCommand::BeginRecording);
219248
command_buffer.issue_commands(platform_command_list);
249+
command_buffer.issue_command(PlatformRenderCommand::EndRecording);
220250

221251
self.gpu.submit_command_buffer(
222252
&mut command_buffer,
@@ -231,6 +261,16 @@ impl RenderContext {
231261
self.render_semaphore.as_mut().unwrap(),
232262
)
233263
.expect("Failed to render to the surface");
264+
265+
match self.frame_buffer {
266+
Some(_) => {
267+
Rc::try_unwrap(self.frame_buffer.take().unwrap())
268+
.ok()
269+
.unwrap()
270+
.destroy(&self.gpu);
271+
}
272+
None => {}
273+
}
234274
}
235275
}
236276

0 commit comments

Comments
 (0)