Skip to content

feat(platform): add SDL windowing provider and Switch Vulkan feasibility PoC - #661

Merged
aram-devdocs merged 5 commits into
mainfrom
codex/issue-337-sdl-switch-platform
Apr 3, 2026
Merged

feat(platform): add SDL windowing provider and Switch Vulkan feasibility PoC#661
aram-devdocs merged 5 commits into
mainfrom
codex/issue-337-sdl-switch-platform

Conversation

@aram-devdocs

Copy link
Copy Markdown
Owner

Overview

Type: feature

Summary: Add two new platform backends following the Xbox GDK PoC pattern: an SDL2-based windowing provider with real window creation and input mapping, and a Nintendo Switch Vulkan feasibility stub with a comprehensive findings report.

Related Issues: Closes #337, Closes #341


Changes Made

Engine Core (goud_engine/src/)

  • Added sdl-window and switch-vulkan feature flags to Cargo.toml
  • Extended WindowBackendKind enum with SdlWindow = 3 and SwitchVulkan = 4 variants
  • Extended PlatformBackend trait cfg gates to include new features
  • Added SdlPlatform implementing PlatformBackend with real SDL2 window creation, event pump, keyboard/mouse/scroll input mapping via scancode-to-KeyCode table
  • Added SwitchVulkanPlatform stub (always returns BackendNotSupported)
  • Added SdlWindowHandle using SDL2's raw-window-handle 0.6 support for wgpu surface creation
  • Added SwitchWindowHandle stub (always returns HandleError::Unavailable)
  • Added wgpu Vulkan init paths: WgpuBackend::new_from_sdl_handle() and new_from_switch_handle()
  • Extended detect_best_backend(), validate_native_backend_pair(), and create_native_runtime() for both new pairs
  • Fixed NativeRenderBackend::Wgpu cfg gates in native_backend/mod.rs to include new features

FFI Layer (goud_engine/src/ffi/)

No changes

C# SDK (sdks/csharp/)

No changes

Python SDK (sdks/python/)

No changes

TypeScript SDK (sdks/typescript/)

No changes

Codegen Pipeline (codegen/)

No changes

Proc Macros (goud_engine_macros/)

No changes

Tools (tools/)

No changes

WASM (goud_engine/src/wasm/)

No changes

Examples (examples/)

No changes

Documentation

  • Added docs/findings/switch-vulkan-poc.md — comprehensive feasibility report covering wgpu Vulkan compatibility, 7 blocking issues, audio/input/filesystem gaps, build toolchain requirements, and 12-18 week estimated effort

Architectural Compliance

  • Rust-first: All logic lives in Rust; SDKs are thin wrappers
  • FFI boundary: No new FFI exports (internal platform modules only)
  • Dependency flow: Imports follow layer hierarchy (down only)
  • SDK parity: N/A — no FFI surface exposed
  • Unsafe discipline: All unsafe blocks have // SAFETY: comments
  • File size: No file exceeds 500 lines

Testing

  • cargo test passes (4740 passed, 0 failed, 28 ignored)
  • cargo clippy -- -D warnings is clean
  • cargo clippy --features sdl-window -- -D warnings is clean
  • cargo clippy --features switch-vulkan -- -D warnings is clean
  • cargo fmt --all -- --check passes
  • cargo check --features sdl-window passes
  • cargo check --features switch-vulkan passes
  • cargo check (default features) passes

Code Quality

  • No todo!() or unimplemented!() in production code
  • No #[allow(unused)] without justification comment
  • Error handling uses Result, not unwrap()/expect() in library code
  • Public items have doc comments

Documentation

  • Added findings report for Switch Vulkan feasibility
  • Updated module doc comments where applicable

Breaking Changes

None

  • API changes: None
  • FFI signature changes: None
  • SDK interface changes: None

Version Bump

Bump type: none
Justification: Feature-gated PoC modules, no public API changes


Security

  • All unsafe impl Send/Sync blocks have // SAFETY: comments and are necessary
  • No new FFI pointer parameters
  • No new dependencies with known advisories
  • No secrets or credentials in committed files

Performance

N/A — feature-gated PoC modules behind opt-in flags, no impact on default build path.


Deployment

  • Native library builds on all targets (verified via cargo check with all feature combinations)

Reviewer Notes

  • SDL2 windowing creates a real SDL2 window with input mapping. The sdl2 crate with bundled feature compiles SDL2 from source. Auto-detection prefers SDL only on Linux; manual selection works on all desktops.
  • Switch Vulkan is a pure stub (no NintendoSDK available). The findings report covers all known blockers and estimates 12-18 dev weeks for a playable demo.
  • Both init files (sdl_init.rs, switch_init.rs) duplicate the wgpu initialization boilerplate from xbox_init.rs. A shared helper should be extracted before promoting any PoC to production.
  • The SwitchWindowHandle's unsafe impl Send + Sync on *mut c_void is flagged for mandatory re-audit when NintendoSDK integration begins.

aram-devdocs and others added 2 commits April 2, 2026 19:09
…ity PoC

Implement two new platform backends following the Xbox GDK PoC pattern:

SDL2 windowing (#337):
- Feature flag: `--features sdl-window` with sdl2 0.37 (bundled + raw-window-handle)
- Real SDL2 initialization with window creation, event pump, and input mapping
- SdlWindowHandle extracts raw handles via SDL2's raw-window-handle 0.6 support
- wgpu Vulkan init path via WgpuBackend::new_from_sdl_handle()
- Full PlatformBackend implementation with keyboard, mouse, scroll, fullscreen

Nintendo Switch Vulkan (#341):
- Feature flag: `--features switch-vulkan`
- Stub SwitchVulkanPlatform (no SDK available, returns BackendNotSupported)
- SwitchWindowHandle with dummy raw-window-handle implementation
- wgpu Vulkan init path via WgpuBackend::new_from_switch_handle()
- Feasibility report at docs/findings/switch-vulkan-poc.md

Both backends integrate into native_runtime.rs (detection, validation,
construction) and extend WindowBackendKind (SdlWindow=3, SwitchVulkan=4).

Closes #337, Closes #341

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…d cfg gates

The Wgpu enum variant and all its match arms in native_backend/mod.rs
were missing the sdl-window and switch-vulkan features, which would
cause compilation failures when those features are enabled standalone.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Claude finished @aram-devdocs's task in 2m 44s —— View job


PR Review: feat(platform): add SDL windowing provider and Switch Vulkan feasibility PoC

Todo List

  • Gather context (CLAUDE.md, PR body, changed files list)
  • Phase 1: Context gathering
  • Phase 2: Architecture validation
  • Phase 3: Anti-pattern scan
  • Phase 4: Quality assessment
  • Phase 5: Security review (unsafe blocks)
  • Phase 6: Scope verification
  • Phase 7: Final review output

Verdict: ✅ APPROVED (with warnings)

The implementation is well-structured, follows the existing Xbox GDK pattern exactly, is properly feature-gated, all unsafe blocks have // SAFETY: comments, tests pass, and the scope is correctly limited to internal platform modules with no FFI surface changes.


BLOCKERS

None.


WARNINGS (should fix, non-blocking)

# Location Issue
W1 sdl_init.rs + switch_init.rs ~270/295 lines are byte-for-byte identical. PR acknowledges this in TODO comments, but this duplication will accrete if a third platform is added.
W2 sdl_init.rs:74, switch_init.rs:74 unwrap_or(caps.formats[0]) panics if caps.formats is empty. Consistent with existing init.rs but the same latent bug is now in two more places.
W3 sdl_init.rs:89, switch_init.rs:89 caps.alpha_modes[0] panics if alpha_modes is empty. Same existing pattern concern, now duplicated.
W4 sdl_surface.rs:52-59 unsafe impl Send + Sync SAFETY comment says handles are "owned by the SDL2 window... kept alive in SdlPlatform." More precisely: SdlWindowHandle stores copied raw pointer values, not a reference to the SDL2 window. Safety relies on wgpu consuming the handle Arc during create_surface before SdlPlatform can drop. Consider tightening the comment to reflect the actual lifetime argument.
W5 switch_surface.rs:28-34 unsafe impl Send + Sync on *mut c_void (currently null_mut()). SAFETY comment references the nn::vi runtime which doesn't exist yet. This is a forward-declaration of safety for code that doesn't run — fine for a PoC, but flag for mandatory re-audit before any real NintendoSDK integration.
W6 sdl_platform.rs:221-277 map_sdl_scancode is missing F1–F12. Not a bug for the PoC, but games routinely use F-keys (pause, debug overlays). Leave a // TODO(sdl-window): comment noting the gap so it's not forgotten.
W7 platform/mod.rs:8-16 ASCII diagram in module doc still shows only GlfwPlatform | WinitPlatform. Minor, but the doc no longer matches the module.
W8 switch_vulkan_platform.rs:23 SwitchVulkanPlatform struct fields (should_close, width, height, last_frame, handle) are unreachable — both new_inner branches return Err. The struct body exists purely for type-checking. The #[allow(dead_code)] covers it, but a comment clarifying "fields are placeholder; constructors are stubs" would help reviewers.

Positive Observations

  • Pattern consistency: Follows the Xbox GDK PoC structure exactly (sdl_init.rs mirrors xbox_init.rs, sdl_platform.rs mirrors xbox_gdk_platform.rs). No architectural surprises.
  • unsafe discipline: Every unsafe block has a // SAFETY: comment — sdl_surface.rs:65,73, switch_surface.rs (trait impls), sdl_surface.rs:56-59. Compliant with FFI patterns rules.
  • No todo!()/unimplemented!() macros in production code. TODO comments are acceptable markers.
  • Feature gating is thoroughcfg guards are consistent across platform/mod.rs, native_backend/mod.rs, wgpu_backend/mod.rs, and Cargo.toml. No leakage into default builds.
  • Test coverage: Pure-logic functions have unit tests (map_sdl_scancode_covers_wasd, map_sdl_mouse_button_covers_basics). Tests requiring a display server are correctly #[ignore]d per testing conventions.
  • Findings report (docs/findings/switch-vulkan-poc.md) is thorough: 7 blocking issues catalogued, 12-18 week estimate with phase breakdown, certification requirements noted.
  • detect_best_backend priority is documented in a comment ("auto-detect prefers it only on Linux"). The SDL → Winit fallback on macOS/Windows is intentional and understood.
  • sdl2 = { ..., features = ["bundled", "raw-window-handle"] } in Cargo.toml is correct — bundled compiles SDL2 from source eliminating the system lib dependency, and raw-window-handle enables the 0.6 handle extraction used in sdl_surface.rs.

Detail: The Duplication Problem (W1)

sdl_init.rs and switch_init.rs are structurally identical except for:

  • Function names (new_from_sdl_handle / new_from_switch_handle, new_sdl_async / new_switch_async)
  • Handle type (Arc<SdlWindowHandle> / Arc<SwitchWindowHandle>)
  • Backend name label ("wgpu-sdl" / "wgpu-switch")
  • Error message string ("wgpu SDL surface" / "wgpu Switch surface")

Both already duplicate xbox_init.rs. A shared generic helper (e.g., WgpuBackend::new_from_raw_handle_inner(handle: impl HasWindowHandle + HasDisplayHandle + Send + Sync + 'static, ...)) would reduce this to ~20 lines each. The PR correctly scopes this as out-of-PoC-phase, but it should be tracked. Fix this →


Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/XL and removed size/XL labels Apr 3, 2026
sdl2 0.37's bundled SDL2 build fails on CI runners with newer CMake
versions that dropped compatibility with cmake_minimum_required < 3.5.
sdl2 0.38 ships a newer SDL2 source that works with modern CMake.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/XL and removed size/XL labels Apr 3, 2026
sdl2-sys bundles SDL2 source with cmake_minimum_required(VERSION 3.1.3).
CMake 4.0+ on CI runners removed compatibility with policies < 3.5.
Setting CMAKE_POLICY_VERSION_MINIMUM=3.5 restores it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added size/XL and removed size/XL labels Apr 3, 2026
@aram-devdocs
aram-devdocs merged commit 615e3b1 into main Apr 3, 2026
45 checks passed
aram-devdocs added a commit that referenced this pull request Apr 3, 2026
Incorporate PR #661 (SDL windowing/Switch PoC) changes.
No conflicts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
aram-devdocs added a commit that referenced this pull request Apr 3, 2026
Apply the same vsync parameter pattern to new_from_sdl_handle() and
new_from_switch_handle() introduced by PR #661, ensuring vsync config
is respected across all platform backends.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

F20-06: Nintendo Switch Vulkan feasibility F20-05: SDL windowing provider

1 participant