Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3ad80b0
[add] presentation mode abstraction.
vmarcella Dec 11, 2025
16e3bae
[add] color attachments abstraction and inline surface calls.
vmarcella Dec 11, 2025
e6c8e2b
[fix] texture usages implementation to exist within the texture.rs
vmarcella Dec 11, 2025
df944d9
[update] TextureFormat to be the defacto API for all texture/surface …
vmarcella Dec 11, 2025
afb144c
[update] configure_raw to not be public.
vmarcella Dec 11, 2025
4932f60
[add] high level texture usages abstraction.
vmarcella Dec 11, 2025
3103b09
[add] initial implementations for high level surface types.
vmarcella Dec 11, 2025
53c8a9f
[add] high level texture view and frame implementations.
vmarcella Dec 11, 2025
8aadd36
[add] ColorAttachmentTexture and DepthTextures to the high level API.
vmarcella Dec 11, 2025
c9e8162
[fix] cfg flag.
vmarcella Dec 11, 2025
039c9f2
[add] command encoder to begin abstracting the command processing aw…
vmarcella Dec 12, 2025
068c6b8
[update] encoder to use render pass over the render pass config.
vmarcella Dec 13, 2025
ccb573d
[update] render context to use the new render pass encoder.
vmarcella Dec 14, 2025
700f51f
[remove] depth op converstions from render context.
vmarcella Dec 14, 2025
b5c8aca
[remove] encode_pass function and handle all command processing insid…
vmarcella Dec 14, 2025
8793194
[remove] import.
vmarcella Dec 14, 2025
1ff0eac
[update] name.
vmarcella Dec 14, 2025
36d6363
[remove] duplicate present mode.
vmarcella Dec 14, 2025
5b5c64f
[add] platform conversions to depth/stencil ops directly.
vmarcella Dec 14, 2025
1020d1e
[add] first high level implementation for render targets and gpu.
vmarcella Dec 14, 2025
7125638
[update] builders to accept the gpu and other resources directly to p…
vmarcella Dec 15, 2025
d401b8b
[update] documentation to reflect new changes to the render context.
vmarcella Dec 15, 2025
c60c667
[update] spacing.
vmarcella Dec 15, 2025
302f28c
[add] high level instance type to use for configuring render targets …
vmarcella Dec 15, 2025
af2f7f3
[update] gpu and render context to use the window surface.
vmarcella Dec 15, 2025
68f96e8
[update] from_platform to be private.
vmarcella Dec 15, 2025
7b6edbf
[fix] into_raw to only be visible to the crate.
vmarcella Dec 15, 2025
3de0312
[fix] obj-loader.
vmarcella Dec 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions crates/lambda-rs-platform/src/wgpu/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub struct CommandBuffer {
}

impl CommandBuffer {
/// Convert to the raw wgpu command buffer.
pub(crate) fn into_raw(self) -> wgpu::CommandBuffer {
self.raw
}
Expand All @@ -32,10 +33,10 @@ impl CommandEncoder {
}

/// Internal helper for beginning a render pass. Used by the render pass builder.
pub(crate) fn begin_render_pass_raw<'view>(
&'view mut self,
desc: &wgpu::RenderPassDescriptor<'view>,
) -> wgpu::RenderPass<'view> {
pub(crate) fn begin_render_pass_raw<'pass>(
&'pass mut self,
desc: &wgpu::RenderPassDescriptor<'pass>,
) -> wgpu::RenderPass<'pass> {
return self.raw.begin_render_pass(desc);
}

Expand Down
20 changes: 10 additions & 10 deletions crates/lambda-rs-platform/src/wgpu/gpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,10 @@ pub struct Gpu {
}

impl Gpu {
/// Whether the provided surface format supports the sample count for render attachments.
pub fn supports_sample_count_for_surface(
/// Whether the provided texture format supports the sample count for render attachments.
pub fn supports_sample_count_for_format(
&self,
format: super::surface::SurfaceFormat,
format: texture::TextureFormat,
sample_count: u32,
) -> bool {
return self.supports_sample_count(format.to_wgpu(), sample_count);
Expand Down Expand Up @@ -350,11 +350,11 @@ mod tests {
}
};
let surface_format =
surface::SurfaceFormat::from_wgpu(wgpu::TextureFormat::Bgra8UnormSrgb);
texture::TextureFormat::from_wgpu(wgpu::TextureFormat::Bgra8UnormSrgb);
let depth_format = texture::DepthFormat::Depth32Float;

assert!(gpu.supports_sample_count_for_surface(surface_format, 1));
assert!(gpu.supports_sample_count_for_surface(surface_format, 0));
assert!(gpu.supports_sample_count_for_format(surface_format, 1));
assert!(gpu.supports_sample_count_for_format(surface_format, 0));
assert!(gpu.supports_sample_count_for_depth(depth_format, 1));
assert!(gpu.supports_sample_count_for_depth(depth_format, 0));
}
Expand All @@ -372,10 +372,10 @@ mod tests {
}
};
let surface_format =
surface::SurfaceFormat::from_wgpu(wgpu::TextureFormat::Bgra8Unorm);
texture::TextureFormat::from_wgpu(wgpu::TextureFormat::Bgra8Unorm);
let depth_format = texture::DepthFormat::Depth32Float;

assert!(!gpu.supports_sample_count_for_surface(surface_format, 3));
assert!(!gpu.supports_sample_count_for_format(surface_format, 3));
assert!(!gpu.supports_sample_count_for_depth(depth_format, 3));
}

Expand All @@ -393,7 +393,7 @@ no compatible GPU adapter"
}
};
let surface_format =
surface::SurfaceFormat::from_wgpu(wgpu::TextureFormat::Bgra8UnormSrgb);
texture::TextureFormat::from_wgpu(wgpu::TextureFormat::Bgra8UnormSrgb);
let features = gpu
.adapter
.get_texture_format_features(surface_format.to_wgpu());
Expand All @@ -405,7 +405,7 @@ no compatible GPU adapter"
.contains(wgpu::TextureFormatFeatureFlags::MULTISAMPLE_X4);

assert_eq!(
gpu.supports_sample_count_for_surface(surface_format, 4),
gpu.supports_sample_count_for_format(surface_format, 4),
expected
);
}
Expand Down
10 changes: 6 additions & 4 deletions crates/lambda-rs-platform/src/wgpu/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ pub use crate::wgpu::vertex::VertexStepMode;
use crate::wgpu::{
bind,
gpu::Gpu,
surface::SurfaceFormat,
texture::DepthFormat,
texture::{
DepthFormat,
TextureFormat,
},
vertex::ColorFormat,
};

Expand Down Expand Up @@ -378,8 +380,8 @@ impl<'a> RenderPipelineBuilder<'a> {
return self;
}

/// Set single color target for fragment stage from a surface format.
pub fn with_surface_color_target(mut self, format: SurfaceFormat) -> Self {
/// Set single color target for fragment stage from a texture format.
pub fn with_color_target(mut self, format: TextureFormat) -> Self {
self.color_target_format = Some(format.to_wgpu());
return self;
}
Expand Down
26 changes: 18 additions & 8 deletions crates/lambda-rs-platform/src/wgpu/render_pass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
//! `CommandEncoder` and texture view. The returned `RenderPass` borrows the
//! encoder and remains valid until dropped.

use wgpu::{
self,
RenderPassColorAttachment,
};
use wgpu;

use super::{
bind,
Expand Down Expand Up @@ -301,7 +298,11 @@ impl RenderPassBuilder {
}
}

/// Attach a debug label to the render pass.
/// Attach a debug label to the render pass (used only for debugging during
/// builder setup, the actual label must be passed to `build`).
#[deprecated(
note = "The label must be passed directly to build() for proper lifetime management"
)]
pub fn with_label(mut self, label: &str) -> Self {
self.config.label = Some(label.to_string());
return self;
Expand Down Expand Up @@ -337,13 +338,22 @@ impl RenderPassBuilder {
/// Build (begin) the render pass on the provided encoder using the provided
/// color attachments list. The attachments list MUST outlive the returned
/// render pass value.
///
/// # Arguments
/// * `encoder` - The command encoder to begin the pass on.
/// * `attachments` - Color attachments for the pass.
/// * `depth_view` - Optional depth view.
/// * `depth_ops` - Optional depth operations.
/// * `stencil_ops` - Optional stencil operations.
/// * `label` - Optional debug label (must outlive the pass).
pub fn build<'view>(
&'view self,
self,
encoder: &'view mut command::CommandEncoder,
attachments: &'view mut RenderColorAttachments<'view>,
depth_view: Option<crate::wgpu::surface::TextureViewRef<'view>>,
depth_ops: Option<DepthOperations>,
stencil_ops: Option<StencilOperations>,
label: Option<&'view str>,
) -> RenderPass<'view> {
let operations = match self.config.color_operations.load {
ColorLoadOp::Load => wgpu::Operations {
Expand Down Expand Up @@ -417,8 +427,8 @@ impl RenderPassBuilder {
}
});

let desc: wgpu::RenderPassDescriptor<'view> = wgpu::RenderPassDescriptor {
label: self.config.label.as_deref(),
let desc = wgpu::RenderPassDescriptor {
label,
color_attachments: attachments.as_slice(),
depth_stencil_attachment,
timestamp_writes: None,
Expand Down
96 changes: 19 additions & 77 deletions crates/lambda-rs-platform/src/wgpu/surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,30 @@ use wgpu::rwh::{
use super::{
gpu::Gpu,
instance::Instance,
texture::{
TextureFormat,
TextureUsages,
},
};
use crate::winit::WindowHandle;

/// Present modes supported by the surface.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
///
/// This wrapper hides the underlying `wgpu` type from higher layers while
/// preserving the same semantics.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PresentMode {
/// Vsync enabled; frames wait for vertical blanking interval.
Fifo,
/// Vsync with relaxed timing; may tear if frames miss the interval.
FifoRelaxed,
/// No Vsync; immediate presentation (may tear).
Immediate,
/// Triple-buffered presentation when supported.
Mailbox,
/// Automatic Vsync selection by the platform.
AutoVsync,
/// Automatic non-Vsync selection by the platform.
AutoNoVsync,
}

Expand Down Expand Up @@ -48,98 +58,30 @@ impl PresentMode {
}
}

/// Wrapper for texture usage flags used by surfaces.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct TextureUsages(wgpu::TextureUsages);

impl TextureUsages {
/// Render attachment usage.
pub const RENDER_ATTACHMENT: TextureUsages =
TextureUsages(wgpu::TextureUsages::RENDER_ATTACHMENT);
/// Texture binding usage.
pub const TEXTURE_BINDING: TextureUsages =
TextureUsages(wgpu::TextureUsages::TEXTURE_BINDING);
/// Copy destination usage.
pub const COPY_DST: TextureUsages =
TextureUsages(wgpu::TextureUsages::COPY_DST);
/// Copy source usage.
pub const COPY_SRC: TextureUsages =
TextureUsages(wgpu::TextureUsages::COPY_SRC);

pub(crate) fn to_wgpu(self) -> wgpu::TextureUsages {
return self.0;
}

pub(crate) fn from_wgpu(flags: wgpu::TextureUsages) -> Self {
return TextureUsages(flags);
}

/// Check whether this flags set contains another set.
pub fn contains(self, other: TextureUsages) -> bool {
return self.0.contains(other.0);
}
}

impl std::ops::BitOr for TextureUsages {
type Output = TextureUsages;

fn bitor(self, rhs: TextureUsages) -> TextureUsages {
return TextureUsages(self.0 | rhs.0);
}
}

/// Wrapper around a surface color format.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SurfaceFormat(wgpu::TextureFormat);

impl SurfaceFormat {
/// Common sRGB swapchain format used for windowed rendering.
pub const BGRA8_UNORM_SRGB: SurfaceFormat =
SurfaceFormat(wgpu::TextureFormat::Bgra8UnormSrgb);

pub(crate) fn to_wgpu(self) -> wgpu::TextureFormat {
return self.0;
}

pub(crate) fn from_wgpu(fmt: wgpu::TextureFormat) -> Self {
return SurfaceFormat(fmt);
}

/// Whether this format is sRGB.
pub fn is_srgb(self) -> bool {
return self.0.is_srgb();
}

/// Return the sRGB variant of the format when applicable.
pub fn add_srgb_suffix(self) -> Self {
return SurfaceFormat(self.0.add_srgb_suffix());
}
}

/// Public, engine-facing surface configuration that avoids exposing `wgpu`.
#[derive(Clone, Debug)]
pub struct SurfaceConfig {
pub width: u32,
pub height: u32,
pub format: SurfaceFormat,
pub format: TextureFormat,
pub present_mode: PresentMode,
pub usage: TextureUsages,
pub view_formats: Vec<SurfaceFormat>,
pub view_formats: Vec<TextureFormat>,
}

impl SurfaceConfig {
pub(crate) fn from_wgpu(config: &wgpu::SurfaceConfiguration) -> Self {
return SurfaceConfig {
width: config.width,
height: config.height,
format: SurfaceFormat::from_wgpu(config.format),
format: TextureFormat::from_wgpu(config.format),
present_mode: PresentMode::from_wgpu(config.present_mode),
usage: TextureUsages::from_wgpu(config.usage),
view_formats: config
.view_formats
.iter()
.copied()
.map(SurfaceFormat::from_wgpu)
.map(TextureFormat::from_wgpu)
.collect(),
};
}
Expand Down Expand Up @@ -267,7 +209,7 @@ pub struct Surface<'window> {
label: String,
surface: wgpu::Surface<'window>,
configuration: Option<SurfaceConfig>,
format: Option<SurfaceFormat>,
format: Option<TextureFormat>,
}

impl<'window> Surface<'window> {
Expand All @@ -287,19 +229,19 @@ impl<'window> Surface<'window> {
}

/// Preferred surface format if known (set during configuration).
pub fn format(&self) -> Option<SurfaceFormat> {
pub fn format(&self) -> Option<TextureFormat> {
return self.format;
}

/// Configure the surface and cache the result for queries such as `format()`.
pub(crate) fn configure_raw(
fn configure_raw(
&mut self,
device: &wgpu::Device,
config: &wgpu::SurfaceConfiguration,
) {
self.surface.configure(device, config);
self.configuration = Some(SurfaceConfig::from_wgpu(config));
self.format = Some(SurfaceFormat::from_wgpu(config.format));
self.format = Some(TextureFormat::from_wgpu(config.format));
}

/// Configure the surface using common engine defaults:
Expand Down
Loading
Loading