Skip to content

Conversation

@vmarcella
Copy link
Member

Summary

This PR changes buffer allocation defaults to favor GPU-optimal residency.

Previously, Properties::default() (and BufferBuilder::new()) defaulted to CPU_VISIBLE, which biases buffers toward CPU-visible memory and implicitly adds COPY_DST. That default is suboptimal for static vertex/index buffers on discrete GPUs because the memory is being allocated on the hosts RAM as opposed to the GPUs VRAM.

Now, buffers default to DEVICE_LOCAL, and callers must opt into CPU_VISIBLE only when they intend to update the buffer from the CPU via Buffer::write_*.

Related Issues

Changes

  • Changed Properties::default() to return Properties::DEVICE_LOCAL.
  • Updated BufferBuilder::new() to inherit the Properties default.
  • Updated BufferBuilder::build_from_mesh to create vertex buffers as DEVICE_LOCAL.
  • Added unit tests covering the new default behavior.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • Feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (updates to docs, specs, tutorials, or comments)
  • Refactor (code change that neither fixes a bug nor adds a feature)
  • Performance (change that improves performance)
  • Test (adding or updating tests)
  • Build/CI (changes to build process or CI configuration)

Affected Crates

  • lambda-rs
  • lambda-rs-platform
  • lambda-rs-args
  • lambda-rs-logging
  • Other:

Checklist

  • Code follows the repository style guidelines (cargo +nightly fmt --all)
  • Code passes clippy (cargo clippy --workspace --all-targets -- -D warnings)
  • Tests pass (cargo test --workspace)
  • New code includes appropriate documentation
  • Public API changes are documented
  • Breaking changes are noted in this PR description

Testing

Commands run:

cargo test -p lambda-rs

Manual verification steps (if applicable):

  1. Run a render demo that uses BufferBuilder::build_from_mesh (static geometry) and confirm it still renders correctly.
  2. Run the uniform-buffer demo to verify CPU-updated buffers still explicitly use CPU_VISIBLE.

Screenshots/Recordings

N/A (no UI change).

Platform Testing

  • macOS
  • Windows
  • Linux

Additional Notes

  • If you relied on implicit CPU visibility (e.g. build a buffer then call Buffer::write_value / write_slice / write_bytes), add .with_properties(Properties::CPU_VISIBLE) when constructing that buffer.

@vmarcella vmarcella requested a review from Copilot February 9, 2026 20:21
@vmarcella vmarcella added lambda-rs Issues pertaining to the core framework render All things render related labels Feb 9, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates lambda-rs render buffer defaults to favor GPU-optimal allocations by making Properties::default() (and thus BufferBuilder::new()) default to DEVICE_LOCAL rather than CPU_VISIBLE, and adjusts docs/tests accordingly.

Changes:

  • Change Properties::default() to Properties::DEVICE_LOCAL and update BufferBuilder::new() to inherit that default.
  • Update BufferBuilder::build_from_mesh to create vertex buffers as DEVICE_LOCAL.
  • Expand documentation around CPU_VISIBLE vs DEVICE_LOCAL and add unit tests for the new defaults.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 291 to 296
/// use lambda::render::buffer::{BufferBuilder, Usage, Properties, BufferType};
/// let vertices: Vec<Vertex> = build_vertices();
/// let vb = BufferBuilder::new()
/// .with_usage(Usage::VERTEX)
/// .with_properties(Properties::DEVICE_LOCAL)
/// // Defaults to `Properties::DEVICE_LOCAL` (recommended for static geometry).
/// .with_buffer_type(BufferType::Vertex)
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doc example still imports Properties but no longer uses it after removing the explicit .with_properties(...) call. To keep the example self-consistent, either drop Properties from the use list or keep an explicit .with_properties(Properties::DEVICE_LOCAL) call (with a comment that it matches the default).

Copilot uses AI. Check for mistakes.
Comment on lines +84 to +90
/// Use `CPU_VISIBLE` for buffers you plan to update from the CPU using
/// `Buffer::write_*` (this enables `wgpu::Queue::write_buffer` by adding the
/// required `COPY_DST` usage).
///
/// Prefer `DEVICE_LOCAL` for static geometry uploaded once and never modified.
/// This is typically the best default for vertex and index buffers on discrete
/// GPUs, where CPU-visible memory may live in system RAM rather than VRAM.
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs here imply CPU_VISIBLE impacts actual memory residency (system RAM vs VRAM). In this codebase, cpu_visible ultimately only adds wgpu::BufferUsages::COPY_DST (see lambda-rs-platform buffer builder) and does not request mapping (e.g., MAP_WRITE), so it likely doesn’t control where the buffer is placed. Suggest rewording to focus on “uploadable via queue writes (COPY_DST)” vs “not uploadable”, and avoid claims about RAM/VRAM placement unless the platform layer truly enforces that.

Copilot uses AI. Check for mistakes.
Comment on lines +84 to +86
/// Use `CPU_VISIBLE` for buffers you plan to update from the CPU using
/// `Buffer::write_*` (this enables `wgpu::Queue::write_buffer` by adding the
/// required `COPY_DST` usage).
Copy link

Copilot AI Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With Properties now defaulting to DEVICE_LOCAL (i.e., no COPY_DST), it becomes easy for callers to create a buffer and then call Buffer::write_*, which will hit a wgpu validation error/panic because Queue::write_buffer requires COPY_DST. Consider making write_bytes/write_value/write_slice return a Result (or adding an explicit runtime check that produces a clear error) when the underlying buffer wasn’t created with CPU_VISIBLE/COPY_DST.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link

github-actions bot commented Feb 9, 2026

✅ Coverage Report

📊 View Full HTML Report (download artifact)

Overall Coverage

Metric Value
Total Line Coverage 76.66%
Lines Covered 10270 / 13396

Changed Files in This PR

File Coverage Lines
crates/lambda-rs/src/render/buffer.rs 87.88% 261/297

PR Files Coverage: 87.87% (261/297 lines)


Generated by cargo-llvm-cov · Latest main coverage

Last updated: 2026-02-09 21:54:54 UTC · Commit: 6071c93

@vmarcella vmarcella merged commit b04f15c into main Feb 9, 2026
10 checks passed
@vmarcella vmarcella deleted the vmrcella/default-buffers-to-device-local branch February 9, 2026 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lambda-rs Issues pertaining to the core framework render All things render related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Default buffer properties to DEVICE_LOCAL for static geometry

1 participant