Skip to content

Commit f633b3d

Browse files
authored
[merge] new demos and API changes
New demos & API additions
2 parents 3de1c79 + 1ce43de commit f633b3d

28 files changed

Lines changed: 984 additions & 297 deletions

File tree

Cargo.lock

Lines changed: 317 additions & 100 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
members = [
55
"lambda",
66
"crates/lambda-platform",
7-
"tools/lambda_rs_demo"
7+
"tools/lambda_rs_demo",
8+
"tools/minimal",
9+
"tools/triangles_demo",
810
]
911

1012
default-members = [

crates/lambda-platform/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ path = "src/lib.rs"
99

1010
[dependencies]
1111
gfx-hal = "=0.9.0"
12-
winit = "=0.26.1"
12+
winit = "=0.27.4"
1313
shaderc = "=0.7"
1414
cfg-if = "=1.0.0"
1515

crates/lambda-platform/src/gfx/api.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
//! implementations to use.
33
44
cfg_if::cfg_if! {
5-
if #[cfg(feature = "with-gl")] {
5+
if #[cfg(feature = "gfx-with-gl")] {
66
pub use gfx_backend_gl as RenderingAPI;
7-
} else if #[cfg(feature = "with-vulkan")] {
7+
} else if #[cfg(feature = "gfx-with-vulkan")] {
88
pub use gfx_backend_vulkan as RenderingAPI;
9-
} else if #[cfg(feature = "with-metal")] {
9+
} else if #[cfg(feature = "gfx-with-metal")] {
1010
pub use gfx_backend_metal as RenderingAPI;
11-
} else if #[cfg(feature = "with-dx11")] {
11+
} else if #[cfg(feature = "gfx-with-dx11")] {
1212
pub use gfx_backend_dx11 as RenderingAPI;
13-
} else if #[cfg(feature = "with-dx12")] {
13+
} else if #[cfg(feature = "gfx-with-dx12")] {
1414
pub use gfx_backend_dx12 as RenderingAPI;
1515
} else if #[cfg(feature = "detect-platform")] {
1616
pub use gfx_platform_backend as RenderingAPI;

crates/lambda-platform/src/gfx/command.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ pub enum Command<RenderBackend: gfx_hal::Backend> {
9090
Draw {
9191
vertices: Range<u32>,
9292
},
93+
PushConstants {
94+
pipeline: Rc<RenderPipeline<RenderBackend>>,
95+
stage: super::pipeline::PipelineStage,
96+
offset: u32,
97+
bytes: Vec<u32>,
98+
},
9399
EndRecording,
94100
}
95101

@@ -167,6 +173,17 @@ impl<'command_pool, RenderBackend: gfx_hal::Backend>
167173
)
168174
}
169175
Command::EndRenderPass => self.command_buffer.end_render_pass(),
176+
Command::PushConstants {
177+
pipeline,
178+
stage,
179+
offset,
180+
bytes,
181+
} => self.command_buffer.push_graphics_constants(
182+
super::pipeline::internal::pipeline_layout_for(pipeline.as_ref()),
183+
stage,
184+
offset,
185+
bytes.as_slice(),
186+
),
170187
Command::Draw { vertices } => self.command_buffer.draw(vertices, 0..1),
171188
Command::EndRecording => self.command_buffer.finish(),
172189
}
@@ -364,8 +381,9 @@ impl<RenderBackend: gfx_hal::Backend> CommandPool<RenderBackend> {
364381
/// Moves the command pool into itself and destroys any command pool and
365382
/// buffer resources allocated on the GPU.
366383
#[inline]
367-
pub fn destroy(self, gpu: &super::gpu::Gpu<RenderBackend>) {
384+
pub fn destroy(mut self, gpu: &super::gpu::Gpu<RenderBackend>) {
368385
unsafe {
386+
self.command_pool.reset(true);
369387
super::gpu::internal::logical_device_for(gpu)
370388
.destroy_command_pool(self.command_pool);
371389
}

crates/lambda-platform/src/gfx/fence.rs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
//! GPU fence & semaphore implementations for rendering synchronizations. These
2-
//! implementations built on top of gfx-hal and are used by the lambda-platform
3-
//! rendering implementations to synchronize GPU operations.
1+
//! GPU synchronization Implementations that are built on top of gfx-hal and
2+
//! are used by the lambda-platform rendering implementations to synchronize
3+
//! GPU operations.
44
55
use gfx_hal::device::Device;
66

@@ -25,6 +25,9 @@ impl RenderSemaphoreBuilder {
2525
}
2626
}
2727

28+
/// Render semaphores are used to synchronize operations happening within the
29+
/// GPU. This allows for us to tell the GPU to wait for a frame to finish
30+
/// rendering before presenting it to the screen.
2831
pub struct RenderSemaphore<RenderBackend: gfx_hal::Backend> {
2932
semaphore: RenderBackend::Semaphore,
3033
}
@@ -75,6 +78,9 @@ impl RenderSubmissionFenceBuilder {
7578
}
7679
}
7780

81+
/// A GPU fence is used to synchronize GPU operations. It is used to ensure that
82+
/// a GPU operation has completed before the CPU attempts to submit commands to
83+
/// it.
7884
pub struct RenderSubmissionFence<RenderBackend: gfx_hal::Backend> {
7985
fence: RenderBackend::Fence,
8086
default_render_timeout: u64,
@@ -95,12 +101,13 @@ impl<RenderBackend: gfx_hal::Backend> RenderSubmissionFence<RenderBackend> {
95101
unsafe {
96102
super::gpu::internal::logical_device_for(gpu)
97103
.wait_for_fence(&self.fence, timeout)
98-
.expect("The GPU ran out of memory or has become detached from the current context.");
104+
}
105+
.expect("The GPU ran out of memory or has become detached from the current context.");
99106

100-
super::gpu::internal::logical_device_for(gpu)
101-
.reset_fence(&mut self.fence)
102-
.expect("The fence failed to reset.");
107+
unsafe {
108+
super::gpu::internal::logical_device_for(gpu).reset_fence(&mut self.fence)
103109
}
110+
.expect("The fence failed to reset.");
104111
}
105112

106113
/// Destroy this fence given the GPU that created it.
@@ -126,4 +133,10 @@ pub mod internal {
126133
) -> &mut RenderBackend::Semaphore {
127134
return &mut semaphore.semaphore;
128135
}
136+
137+
pub fn semaphore_for<RenderBackend: gfx_hal::Backend>(
138+
semaphore: &super::RenderSemaphore<RenderBackend>,
139+
) -> &RenderBackend::Semaphore {
140+
return &semaphore.semaphore;
141+
}
129142
}

crates/lambda-platform/src/gfx/framebuffer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use super::{
1010
};
1111

1212
/// Framebuffer for the given render backend.
13+
#[derive(Debug)]
1314
pub struct Framebuffer<RenderBackend: gfx_hal::Backend> {
1415
frame_buffer: RenderBackend::Framebuffer,
1516
}

crates/lambda-platform/src/gfx/gpu.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl<RenderBackend: gfx_hal::Backend> Gpu<RenderBackend> {
129129
pub fn submit_command_buffer<'render_context>(
130130
&mut self,
131131
command_buffer: &mut CommandBuffer<RenderBackend>,
132-
signal_semaphores: Vec<RenderSemaphore<RenderBackend>>,
132+
signal_semaphores: Vec<&RenderSemaphore<RenderBackend>>,
133133
fence: &mut RenderSubmissionFence<RenderBackend>,
134134
) {
135135
let commands =
@@ -139,7 +139,11 @@ impl<RenderBackend: gfx_hal::Backend> Gpu<RenderBackend> {
139139
self.queue_group.queues[0].submit(
140140
commands,
141141
vec![].into_iter(),
142-
vec![].into_iter(),
142+
// TODO(vmarcella): This was needed to allow the push constants to
143+
// properly render to the screen. Look into a better way to do this.
144+
signal_semaphores.into_iter().map(|semaphore| {
145+
return super::fence::internal::semaphore_for(semaphore);
146+
}),
143147
Some(super::fence::internal::mutable_fence_for(fence)),
144148
);
145149
}

crates/lambda-platform/src/gfx/pipeline.rs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,16 @@ pub mod internal {
2323
) -> &RenderBackend::GraphicsPipeline {
2424
return &pipeline.pipeline;
2525
}
26+
27+
pub fn pipeline_layout_for<RenderBackend: gfx_hal::Backend>(
28+
pipeline: &super::RenderPipeline<RenderBackend>,
29+
) -> &RenderBackend::PipelineLayout {
30+
return &pipeline.pipeline_layout;
31+
}
2632
}
2733

34+
use std::ops::Range;
35+
2836
use gfx_hal::device::Device;
2937

3038
use super::{
@@ -35,14 +43,41 @@ use super::{
3543
/// Builder for a gfx-hal backed render pipeline.
3644
pub struct RenderPipelineBuilder<RenderBackend: internal::Backend> {
3745
pipeline_layout: Option<RenderBackend::PipelineLayout>,
46+
push_constants: Vec<PushConstantUpload>,
3847
}
3948

49+
pub type PipelineStage = gfx_hal::pso::ShaderStageFlags;
50+
51+
pub type PushConstantUpload = (PipelineStage, Range<u32>);
52+
4053
impl<RenderBackend: internal::Backend> RenderPipelineBuilder<RenderBackend> {
4154
pub fn new() -> Self {
4255
return Self {
4356
pipeline_layout: None,
57+
push_constants: Vec::new(),
4458
};
4559
}
60+
61+
/// Adds a push constant to the render pipeline at the set PipelineStage(s)
62+
pub fn with_push_constant(
63+
mut self,
64+
stage: PipelineStage,
65+
bytes: u32,
66+
) -> Self {
67+
self.push_constants.push((stage, 0..bytes));
68+
return self;
69+
}
70+
71+
/// Adds multiple push constants to the render pipeline at their
72+
/// set PipelineStage(s)
73+
pub fn with_push_constants(
74+
mut self,
75+
push_constants: Vec<PushConstantUpload>,
76+
) -> Self {
77+
self.push_constants.extend(push_constants);
78+
return self;
79+
}
80+
4681
/// Builds a render pipeline based on your builder configuration. You can
4782
/// configure a render pipeline to be however you'd like it to be.
4883
pub fn build(
@@ -54,10 +89,13 @@ impl<RenderBackend: internal::Backend> RenderPipelineBuilder<RenderBackend> {
5489
) -> RenderPipeline<RenderBackend> {
5590
// TODO(vmarcella): The pipeline layout should be configurable through the
5691
// RenderPipelineBuilder.
92+
let push_constants = self.push_constants.into_iter();
93+
5794
let pipeline_layout = unsafe {
5895
use internal::Device;
96+
5997
super::internal::logical_device_for(gpu)
60-
.create_pipeline_layout(vec![].into_iter(), vec![].into_iter())
98+
.create_pipeline_layout(vec![].into_iter(), push_constants)
6199
.expect(
62100
"The GPU does not have enough memory to allocate a pipeline layout",
63101
)

crates/lambda-platform/src/gfx/render_pass.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl SubpassBuilder {
125125
};
126126
}
127127

128-
pub fn use_color_attachment(
128+
pub fn with_color_attachment(
129129
mut self,
130130
attachment_index: usize,
131131
layout: ImageLayoutHint,
@@ -224,16 +224,13 @@ impl<'builder> RenderPassBuilder<'builder> {
224224
};
225225

226226
let render_pass = unsafe {
227-
super::internal::logical_device_for(gpu)
228-
.create_render_pass(
229-
attachments.into_iter(),
230-
subpasses.into_iter(),
231-
vec![].into_iter(),
232-
)
233-
.expect(
234-
"The GPU does not have enough memory to allocate a render pass.",
235-
)
236-
};
227+
super::internal::logical_device_for(gpu).create_render_pass(
228+
attachments.into_iter(),
229+
subpasses.into_iter(),
230+
vec![].into_iter(),
231+
)
232+
}
233+
.expect("The GPU does not have enough memory to allocate a render pass.");
237234

238235
return RenderPass { render_pass };
239236
}

0 commit comments

Comments
 (0)