SdlVulkan.Renderer
7.5.2011
dotnet add package SdlVulkan.Renderer --version 7.5.2011
NuGet\Install-Package SdlVulkan.Renderer -Version 7.5.2011
<PackageReference Include="SdlVulkan.Renderer" Version="7.5.2011" />
<PackageVersion Include="SdlVulkan.Renderer" Version="7.5.2011" />
<PackageReference Include="SdlVulkan.Renderer" />
paket add SdlVulkan.Renderer --version 7.5.2011
#r "nuget: SdlVulkan.Renderer, 7.5.2011"
#:package SdlVulkan.Renderer@7.5.2011
#addin nuget:?package=SdlVulkan.Renderer&version=7.5.2011
#tool nuget:?package=SdlVulkan.Renderer&version=7.5.2011
SdlVulkan.Renderer
SDL3 + Vortice.Vulkan rendering library built on DIR.Lib primitives.
Types
SdlVulkanWindow— SDL3 window with Vulkan instance and surface lifecycle. Creates maximized, resizable windows with Vulkan surface.VulkanContext— Vulkan device, command buffers, sync management.MaxFramesInFlight = 2with per-frame vertex buffers. Two construction modes:VulkanContext.Create(instance, surface, w, h, ...)— on-screen path with a swapchain tied to anSdlVulkanWindow.VulkanContext.CreateOffscreen(instance, w, h, ...)— headless path rendering to a standaloneVkImage; no surface, no swapchain, no SDL window. See Headless / offscreen rendering below.
VkRenderer—Renderer<VulkanContext>implementation with FillRectangle, DrawRectangle, FillEllipse, DrawText, plus batched glyph and persistent-vertex-buffer draw APIs. ExposesFontAtlasDirtyso callers can trigger redraws after glyph rasterization. HasBeginFrame/BeginOffscreenFramevariants that match the twoVulkanContextmodes.VkPipelineSet— Vulkan pipeline creation from pre-baked SPIR-V (flat, textured, ellipse, page, stroke, SDF, round-rect, blend variants). Shaders are authored as GLSL 450 and baked bytools/BakeShadersat build time — see Dependencies below.VkFontAtlas— Dynamic bitmap glyph atlas with ManagedFontRasterizer (from DIR.Lib) rasterization and Vulkan texture upload. Supports grow (512→4096), deferred eviction, andskipUnflushedto prevent sampling stale GPU texture data.VkSdfFontAtlas— Signed-distance-field glyph atlas side-car for resolution-independent text.SdfRasterSize = 64(overridable per atlas),fwidth-driven AA in the fragment shader auto-tunes to ±0.5 screen pixels at any zoom. Four-channel R8G8B8A8Unorm MTSDF texture — RGB carry pseudo-distance, which the shader medians to keep corners sharp, and A the true distance. Keyed on(font, size, gid, glyph name): glyph identity rather than code point, so subset fonts that reuse code points don't collide.
Font Atlas Lifecycle
Per frame:
BeginFrame()/BeginOffscreenFrame()— handles deferred eviction, runsOnPreFlush(pre-warm callback), callsFlush(cmd)on both atlases, runsOnPreRenderPass(texture uploads), thenBeginRenderPass.Flush(cmd)— uploads dirty staging region to GPU viavkCmdCopyBufferToImage.DrawText(...)→GetGlyph(...)— cache hit returns UV coords; miss rasterizes into staging.GetGlyph(..., skipUnflushed: true)— in draw loops, returns zero-width for glyphs not yet uploaded. Pair withPreWarmGlyphinOnPreFlushif drawing a glyph that wasn't shown last frame (first-frame glyph flicker). For SDF text,PreWarmSdfGlyphis the equivalent;PreWarmSdfGlyphBatchwarms many glyphs in one call with parallel rasterization — preferred when a page introduces tens-to-hundreds of unique glyphs.
Thread safety: vkDeviceWaitIdle() before reusing the shared upload buffer (prevents race with MaxFramesInFlight = 2).
Diagnostic logging (Console.Error): [FontAtlas] / [VkRenderer] prefixed lines for Flush, Grow, EvictAll, cache miss, Resize. Capture with 2>stderr.log.
Usage
using SdlVulkan.Renderer;
using var window = SdlVulkanWindow.Create("My App", 800, 600);
window.GetSizeInPixels(out var w, out var h);
var ctx = VulkanContext.Create(window.Instance, window.Surface, (uint)w, (uint)h);
var renderer = new VkRenderer(ctx, (uint)w, (uint)h);
while (running)
{
if (!renderer.BeginFrame(bgColor)) { renderer.Resize(w, h); continue; }
renderer.FillRectangle(rect, color);
renderer.DrawText("Hello", fontPath, 14f, white, layout);
renderer.EndFrame();
if (renderer.FontAtlasDirty) needsRedraw = true;
}
Headless / offscreen rendering
VulkanContext.CreateOffscreen builds a context that renders to a single VkImage instead of a swapchain. No VkSurfaceKHR, no SDL window, no VK_KHR_swapchain device extension requested — useful for tests, thumbnail / raster workers, CI without a display server, and server-side rendering.
using SdlVulkan.Renderer;
using Vortice.Vulkan;
using static Vortice.Vulkan.Vulkan;
// Minimal instance — no windowing extensions needed.
vkInitialize().CheckResult();
VkInstanceCreateInfo ici = new();
vkCreateInstance(&ici, null, out var instance).CheckResult();
const uint W = 1920, H = 1080;
using var ctx = VulkanContext.CreateOffscreen(instance, W, H);
using var renderer = new VkRenderer(ctx, W, H);
renderer.BeginOffscreenFrame(new DIR.Lib.RGBAColor32(255, 255, 255, 255));
renderer.FillRectangle(new RectInt(new(100, 100), new(400, 300)), red);
renderer.DrawText("Hello", fontPath, 14f, black, layout);
renderer.EndOffscreenFrame();
ctx.WaitOffscreenFrameComplete();
byte[] rgba = ctx.ReadbackOffscreenRgba(); // top-down, 4 bytes per pixel
// Pipe rgba into PNG encoder / image library of choice.
The offscreen path reuses all existing pipelines, MSAA slots, sync objects, and vertex ring buffers. Only the swapchain acquire/present is replaced by vkCmdCopyImageToBuffer into a host-visible staging buffer.
Runtime requirements (native)
At runtime you need the Vulkan loader plus an ICD (driver). Nothing else: no X11 / Wayland, no SDL native, no DirectX.
- Windows:
vulkan-1.dll(shipped with any modern GPU driver; also installable via the Vulkan SDK). - Linux:
libvulkan.so.1+ an ICD. Options in increasing order of portability:- GPU driver (Mesa
radv/intel_anv/ NVIDIA proprietary) — fastest. - Mesa
lavapipe/llvmpipe— software rasterizer. 5–20× slower but fully headless. Apt:mesa-vulkan-drivers. - Google SwiftShader — alternative software ICD.
- GPU driver (Mesa
- macOS / iOS: MoltenVK (Vulkan on Metal). Untested for offscreen here but no reason it shouldn't work.
SDL3-CS remains a package reference because the on-screen path uses it. Its P/Invokes are lazy — libSDL3.so / SDL3.dll is never loaded if SdlVulkanWindow is not instantiated, so the offscreen path has no SDL runtime dependency.
Android
Android is a first-class target: the package multi-targets net10.0;net10.0-android, the host is
Android/SdlVulkanActivity.cs (abstract class SdlVulkanActivity : Org.Libsdl.App.SDLActivity), and
the Java bridge plus per-ABI libSDL3.so come from SDL3-CS.Android. Two properties of that native
package are load-bearing for every Android consumer, so they live here rather than in any one app:
Pin SDL3-CS.Android to 3.4.10.5 — not 3.4.12.x. 3.4.12.x ships a mismatched pair: a Java bridge
built for 3.4.10 alongside a 3.4.12 native. SDL's runtime C/Java version check rejects the
combination and the app dies at launch (expected 3.4.10, got 3.4.12). 3.4.10.5 is internally
consistent. Both halves are pinned in src/SdlVulkan.Renderer/Directory.Packages.props,
TFM-conditional so desktop stays on the 3.5.0 preview.
The shipped libSDL3.so is not 16 KB page-aligned. Building any Android consumer raises
warning XA0141 for the android-arm64 and android-x64 natives. Android is moving to 16 KB memory
pages, and a native library laid out for 4 KB pages will not load on a device configured that way —
so this is a deadline, not cosmetic noise. It is also not fixable downstream: the .so arrives
prebuilt inside SDL3-CS.Android, so clearing it needs an upstream rebuild with the 16 KB
max-page-size link flag. See Android's page-sizes guide.
Consumers also need dotnet workload install android; the workload supplies the .NET bits but not
the Android SDK, which dotnet build -t:InstallAndroidDependencies -p:AcceptAndroidSDKLicenses=true
will provision. The tooling needs a JDK it can parse — JDK 17; JDK 25 is too new and throws inside
GetJdkRevision.
CI setup
On a fresh Ubuntu runner (GitHub Actions ubuntu-latest, Azure Pipelines, GitLab):
- run: sudo apt-get update && sudo apt-get install -y libvulkan1 mesa-vulkan-drivers vulkan-tools
- run: dotnet test
vulkan-tools is optional but gives you vulkaninfo --summary for sanity-checking which ICD the runner loaded. For deterministic behaviour across runners, pin to lavapipe:
- run: echo "VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json" >> $GITHUB_ENV
Containers: add the same two packages to your image. The offscreen path doesn't require a tty, display variable, or privileged mode.
Native WebView (optional)
Host a native browser view inside an SdlVulkanWindow. The window system composites it
over the Vulkan swapchain as a child surface — it does not go through the Vulkan render
pass. Shipped as separate packages so core renderer consumers pull no webview dependency:
| Package | Purpose |
|---|---|
SdlVulkan.Renderer.WebView |
The INativeWebView abstraction + platform backends. Multi-targets net10.0 (interface, factory + the Linux/WebKitGTK backend) and net10.0-windows (adds the Windows/WebView2 backend + its native dependency). |
SdlVulkan.Renderer.WebView.Native |
WebView2Loader.dll native assets per Windows RID (x64 / arm64 / x86). Pulled in transitively on Windows — no need to reference it directly. |
dotnet add package SdlVulkan.Renderer.WebView
Backends:
- Windows —
Win32WebView, WebView2 (Edge/Chromium) via the WebView2Aot Native-AOT bindings. Needs the Microsoft Edge WebView2 Runtime installed: that runtime is a system component and is not redistributed here; only the loader DLL ships (in the.Nativepackage). - Linux —
GtkWebView, WebKitGTK 4.1 embedded via X11 (XReparentWindowinto SDL's window; GTK runs its own loop on a dedicated thread). Requires the SDL window on the X11 driver — run withSDL_VIDEODRIVER=x11(works under Wayland sessions via XWayland) — and the WebKitGTK 4.1 + GTK3 runtime (apt install libwebkit2gtk-4.1-0on Debian/Ubuntu; present on most desktops). - macOS —
WKWebView; backend is present but not yet implemented.
using SdlVulkan.Renderer;
using SdlVulkan.Renderer.WebView;
using DIR.Lib;
using var window = SdlVulkanWindow.Create("App", 1280, 800);
using var web = NativeWebView.Create(); // platform backend via the factory
web.NavigationCompleted += url => Console.WriteLine($"loaded {url}");
web.ConsoleMessage += (level, text) => Console.WriteLine($"[{level}] {text}");
web.PageError += err => Console.WriteLine($"JS error: {err}");
web.AttachToWindow(window); // parents the webview into the window's HWND
web.Navigate("https://example.com");
window.GetSizeInPixels(out var w, out var h);
web.SetBounds(new RectInt(new PointInt(w, h), new PointInt(0, 0))); // window pixel coords
string href = await web.ExecuteScriptAsync("location.href"); // JSON-encoded result
For two-way native↔web interaction, MessageReceived surfaces the page's
window.chrome.webview.postMessage(...) calls (as raw JSON) and PostMessage(json) sends the
other way (the page receives it on chrome.webview's message event) — build whatever
request/response protocol you want on top. The Linux backend injects a small window.chrome.webview
shim at document-start (mapping to WebKit's messageHandlers), so the same page JS API works on
both backends.
Fit-to-content sizing
SetBounds is host→browser (you position the webview). For the reverse direction — letting the
page's content drive the webview's size — wrap it in a WebViewContentSizer. It injects a small
ResizeObserver reporter after each navigation, surfaces the page's content size (in device
pixels, ready for SetBounds) as ContentSizeChanged, and can drive the bounds for you:
using var web = NativeWebView.Create();
using var sizer = new WebViewContentSizer(web); // construct before navigating
// Grow/shrink the webview's height to fit the page; width stays fixed at `w`, top-left at (0,0).
sizer.EnableAutoSize(origin: new PointInt(0, 0), fixedExtent: new PointInt(w, 0), axis: AutoSizeAxis.Height);
sizer.ContentSizeChanged += size => Console.WriteLine($"content is {size.X}x{size.Y} device px");
web.AttachToWindow(window);
web.NavigateToString("<h1>I size myself</h1>");
AutoSizeAxis.Height is the default and the safe choice: a fixed width never reflows the page, so it
can't oscillate. Width/Both track the other axis but are prone to reflow feedback. The __sdlLayout
message key is reserved for this protocol — layout envelopes are consumed by the sizer and never
reach its MessageReceived, so subscribe to sizer.MessageReceived to get only your app's messages.
No INativeWebView change is involved; the sizer is built entirely on the existing message bridge.
Beyond navigation, both backends surface diagnostics: Trace (redirect/load chain), ConsoleMessage
(console.*), and PageError (uncaught JS exceptions, with stack). On Windows these come from the
WebView2 DevTools Protocol; on Linux from in-page hooks forwarded over dedicated script-message
channels.
Backend notes:
- Windows — WebView2's async creation completes on the Win32 message pump, which SDL's event loop drives, so it composes with the standard render/event loop. Requires an STA thread. Events are raised on the UI thread.
- Linux — GTK runs its own main loop on a dedicated thread; public methods are safe to call from
the SDL event-loop thread (they marshal across via
g_idle_add). Events (MessageReceived,TitleChanged, …) are raised on the GTK thread, so handlers must be thread-safe or marshal back themselves.
Dependencies
- DIR.Lib — Rendering primitives + FreeType glyph rasterization
- SDL3-CS — SDL3 bindings
- SDL3-CS.Android — android TFM only: SDL Java bridge + per-ABI
libSDL3.so(see Android for the version pin) - Vortice.Vulkan — Vulkan bindings
Not a runtime dependency: Vortice.ShaderCompiler (GLSL to SPIR-V) is used only by tools/BakeShaders at build time. Shaders ship pre-baked as embedded SPIR-V, which keeps the shaderc native — it has no Android RID — out of the package entirely.
License
MIT
Rationale: Why SDL3 + Vortice.Vulkan
This library exists because the TianWen project needed a path to HDR display output (HDR10, scRGB, wide color gamut) that its previous Silk.NET + OpenGL stack could not deliver. The investigation below documents the alternatives considered and why SDL3 (via edwardgushchin/SDL3-CS) + Vortice.Vulkan won. This is decision rationale, not documentation of current features — check the types list above for what the library actually does today.
Why OpenGL was a dead end for HDR
- GPU vendors (NVIDIA, AMD) block 10-bit and floating-point pixel formats for OpenGL in windowed mode.
- The Windows HDR compositor (DWM) requires a DXGI swapchain, which only DirectX can drive natively.
- GLFW has no HDR support — glfw issue #890 open since 2016, never implemented.
- GLFW 3.4 (Feb 2024) shipped without it; a proposed
GLFW_FLOAT_PIXEL_TYPEpatch was never merged. - Silk.NET's
WindowHintBoolends atSrgbCapable/DoubleBuffer— no float pixel type or HDR color space.
Why Vulkan
Vulkan supports HDR output via VK_EXT_swapchain_colorspace + HDR10 surface formats.
| Platform | OpenGL | Vulkan | HDR possible? |
|---|---|---|---|
| Windows | Native | Native | Yes (Vulkan HDR swapchain) |
| Linux | Native | Native | Yes (if compositor supports) |
| macOS | Deprecated (frozen at 4.1) | MoltenVK | No (Metal HDR needs separate path) |
| Android | OpenGL ES | Native | Yes (Android 10+) |
| iOS | OpenGL ES (deprecated) | MoltenVK | No (same as macOS) |
| Web/WASM | WebGL | No | No |
Shader migration effort: low. GLSL shaders compile to SPIR-V with minimal mechanical
changes (#version 330 core to #version 450, uniforms packed into UBOs, explicit
layout(binding=N), build-time compile via glslc / glslangValidator or runtime
via Vortice.ShaderCompiler). Shader math (MTF stretch, Hermite soft-knee, WCS
deprojection, histogram) stays identical.
API migration effort: high. The real work was replacing ~2000 lines of OpenGL API calls with swapchain setup, descriptor sets, pipeline objects, command buffers, and synchronization.
Silk.NET status at the time of the decision
- v2.23.0 (Jan 2026) — stable, quarterly maintenance releases.
- 3.0:
develop/3.0branch exists, tracking issue #209 open since June 2020 (5.5+ years). Complete rewrite of bindings generation, no release date, lead developer (Perksey) less active, WebGPU bindings planned. - Silk.NET's prior usage in TianWen was well-contained: 4 source files, 3 NuGet packages, AOT with trimmer warning suppressions.
- Verdict: not dead, but 3.0 had been in development for years; 2.x worked fine for OpenGL but was a dead end for Vulkan/HDR on any near-term horizon.
Known Silk.NET-side blockers
- macOS regression: Silk.NET 2.21+ cannot create GLFW Vulkan windows on macOS (#2440); 2.20 worked.
- MoltenVK not fully conformant: translates Vulkan to Metal, supports Vulkan 1.4 but some features missing; HDR swapchain extensions may not be implemented.
- Web target lost: Vulkan has no browser support (WebGPU would be the path forward).
Alternatives evaluated (March 2026)
Veldrid — avoid (dead project)
- Last commit: March 2024. Latest NuGet: v4.9.0 (Feb 2023). 159 open issues.
- Clean abstraction (Vulkan, D3D11, Metal, OpenGL) but author (mellinoe) has moved on.
- Targets .NET 6 / netstandard2.0, not .NET 10. No AOT testing. No HDR.
Avalonia + GPU interop — consider only if full UI rewrite desired
- 30K+ stars, extremely active. .NET 10 supported.
- Has
GpuInteropsample with Vulkan demo viaCompositionDrawingSurface. - Gives a proper UI framework (menus, panels, dialogs) — could replace hand-built text/panel rendering.
- But: GPU interop is low-level (manage your own Vulkan context inside a compositor callback). HDR depends on the SkiaSharp compositor pipeline (no HDR). Very high migration effort, only worth it if replacing the hand-built UI.
SDL3 (.NET bindings)
- SDL3 itself: 15K stars, actively developed, battle-tested.
- Three competing .NET bindings: ppy/SDL3-CS (osu! team, most production-tested), edwardgushchin/SDL3-CS, flibitijibibo/SDL3-CS.
- SDL3 has native Vulkan surface creation +
SDL_GPUabstraction (Vulkan/D3D12/Metal with automatic shader cross-compilation). - HDR output support at the windowing level.
- SDL3 + keep OpenGL: replaces only GLFW windowing/input. Medium effort. But HDR
is still blocked because SDL3's OpenGL renderer hardcodes
SDL_COLORSPACE_SRGB. - SDL3 + SDL_GPU: higher-level Vulkan-like API with shader translation. Medium-high effort.
Evergine Vulkan.NET — best raw Vulkan bindings, no ecosystem
- 284 stars. Source-generated from Vulkan headers (always up-to-date).
- Targets .NET 8+. Full HDR access via raw swapchain formats.
- Raw bindings only — no windowing, no VMA, no shader compiler. Very high migration effort; 5-10x more code than OpenGL for the same result.
Vortice.Vulkan — best raw Vulkan ecosystem (chosen)
- 371 stars (Vulkan), 1.1K stars (Windows/D3D). Last commit: Feb 2026. Only 2 open issues.
- Explicitly targets net9.0 + net10.0. Pure managed C# bindings (
delegate* unmanagedfunction pointers, no P/Invoke).IsAotCompatible = true. - Bundles VMA (Vulkan Memory Allocator), SPIRV-Cross, and shaderc as companion packages.
- Caveat: single maintainer (bus factor of 1).
WebGPU via wgpu-native — future option, not ready
- wgpu-native: 1.2K stars. Translates to Vulkan/D3D12/Metal.
- .NET bindings immature (Evergine WebGPU.NET Nov 2025, WebGPUSharp 14 stars).
- Shader language is WGSL (GLSL would need porting). HDR not yet in WebGPU spec.
- Revisit when .NET bindings mature.
Why Vortice.Vulkan + edwardgushchin/SDL3-CS
edwardgushchin/SDL3-CS uses LibraryImport (source-generated, AOT-safe) — preferred
over ppy/SDL3-CS which uses old DllImport. SDL3-CS.Native NuGet ships desktop
natives; Android works but needs manual lib bundling.
| Platform | Vulkan | SDL3 native | AOT | HDR |
|---|---|---|---|---|
| Windows x64 | Native | NuGet | Yes | Yes (Vulkan HDR swapchain) |
| Windows ARM64 | Native | NuGet | Yes | Yes |
| Linux x64 | Native (Mesa/NVIDIA) | NuGet | Yes | Possible (Wayland + Vulkan) |
| Linux ARM64 | Native (Mesa) | NuGet | Yes | Limited |
| macOS x64 | MoltenVK | NuGet | Yes | MoltenVK limitations |
| macOS ARM64 | MoltenVK | NuGet | Yes | MoltenVK limitations |
| Android | Native | Manual bundling | Partial | Yes |
| iOS | MoltenVK (must bundle) | Not shipped | Yes | Limited |
SDL3 HDR support: SDL.window.HDR_enabled, SDL.window.SDR_white_level,
SDL.window.HDR_headroom display properties, plus PQ (ST 2084) and HLG transfer
characteristics. Combined with Vulkan VK_COLOR_SPACE_HDR10_ST2084_EXT swapchain,
full HDR output is achievable.
SDL3 Vulkan surface creation: SDL.VulkanLoadLibrary() auto-finds MoltenVK on macOS;
SDL.VulkanCreateSurface() returns a VkSurfaceKHR that pairs directly with
Vortice.Vulkan.
Could we have stayed on Silk.NET by fixing it upstream?
macOS Vulkan regression (#2440) — small PR, uncertain merge timeline
GLFW 3.4 changed Vulkan detection on macOS; glfwVulkanSupported() can't find the
Vulkan loader even though Silk.NET ships it (Silk.NET.Vulkan.Loader.Native). GLFW 3.4
added glfwInitVulkanLoader() which could solve this.
Possible fixes: call glfwInitVulkanLoader() with a custom vkGetInstanceProcAddr
before glfwInit(); set VK_ICD_FILENAMES at the bundled MoltenVK ICD; ensure the
Vulkan loader is on DYLD_LIBRARY_PATH.
Status: no PRs submitted, zero maintainer engagement on the issue. Silk.NET 2.x is in maintenance mode (14-month gap between 2.22 and 2.23), team focused on 3.0. Trivial PRs merge in 0-11 days; no evidence of substantive external feature PRs merging recently.
HDR - not feasible within Silk.NET's GLFW-based windowing
- GLFW has no API for HDR pixel formats, transfer functions, or color spaces.
- GLFW's own HDR issue (#890) open since 2016.
- Silk.NET's Vulkan bindings already cover all HDR swapchain extensions — the blocker is purely windowing.
- Would require replacing GLFW with SDL3 as windowing backend (huge change) or platform-specific code.
| Path | macOS fix | HDR | Effort | Risk |
|---|---|---|---|---|
| Fix Silk.NET upstream | Small PR, may wait months | Blocked by GLFW | Low for macOS, impossible for HDR | PR rot |
| Vortice.Vulkan + SDL3-CS | SDL3 auto-detects MoltenVK | Full HDR built into SDL3 | High (rewrite renderer) | Two active projects |
Comparison matrix
| Option | Maintenance | Vulkan | HDR | AOT | Migration | Shaders kept? |
|---|---|---|---|---|---|---|
| Silk.NET 2.x (stay) | Moderate | Via 3.0 someday | No | Yes | None | Yes |
| Silk.NET 2.x + macOS PR | Moderate | Yes (with fix) | No | Yes | None | Yes |
| SDL3 + OpenGL | Excellent | Surface only | No | Yes | Medium | Yes |
| SDL3 + SDL_GPU | Excellent | Under the hood | Possible | Yes | Medium-high | Rewrite to SDL_GPU |
| Vortice.Vulkan + SDL3 (chosen) | Good | Full | Yes | Yes | Very high | GLSL to SPIR-V |
| Evergine Vulkan.NET + SDL3 | Excellent | Full | Yes | Yes | Very high | GLSL to SPIR-V |
| Avalonia + Vulkan interop | Excellent | Yes (interop) | No | Improving | Very high | Rewrite |
| WebGPU/wgpu | Weak (.NET) | Under the hood | Not yet | Possible | High | GLSL to WGSL |
SDL3 + OpenGL HDR was corrected to No during evaluation: SDL3's OpenGL renderer
hardcodes SDL_COLORSPACE_SRGB as the only accepted output. No float pixel formats,
no scRGB, no HDR10 via OpenGL on any platform.
What to watch
- SDL3_GPU maturity — could simplify Vulkan over time.
- WebGPU .NET bindings — if they mature, a future browser target becomes possible.
- Silk.NET 3.0 — if it ever ships with working Vulkan + a non-GLFW windowing path, the comparison may change.
SDL3-CS.Androidreleases — worth re-testing on each one, because a single bump could clear both Android constraints above. The 16 KB page alignment needs an upstream rebuild, and the Java/native mismatch that forces the 3.4.10.5 pin was last seen in early 3.4.12.x; 3.4.12.6 is the current latest and is several patches past it, so it may already be consistent. Verify by launching on a device — the mismatch fails SDL's version check at startup, not at build time.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-android36.0 is compatible. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- DIR.Lib (>= 7.5.1781)
- SDL3-CS (>= 3.5.0-preview.20260213-150035)
- Vortice.Vulkan (>= 3.2.1)
-
net10.0-android36.0
- DIR.Lib (>= 7.5.1781)
- SDL3-CS (>= 3.4.10.5)
- SDL3-CS.Android (>= 3.4.10.5)
- Vortice.Vulkan (>= 3.2.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on SdlVulkan.Renderer:
| Package | Downloads |
|---|---|
|
SdlVulkan.Renderer.WebView
Cross-platform native WebView (WebView2 / WebKitGTK / WKWebView) hosted inside an SdlVulkan.Renderer window. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 7.5.2011 | 0 | 8/2/2026 |
| 7.5.1991 | 39 | 8/2/2026 |
| 7.5.1981 | 19 | 8/2/2026 |
| 7.5.1941 | 16 | 8/2/2026 |
| 7.5.1921 | 41 | 8/2/2026 |
| 7.4.1891 | 32 | 7/30/2026 |
| 7.3.1882 | 102 | 7/29/2026 |
| 7.2.1871 | 22 | 7/29/2026 |
| 7.1.1861 | 27 | 7/29/2026 |
| 7.0.1851 | 60 | 7/28/2026 |
| 6.33.1841 | 35 | 7/28/2026 |
| 6.32.1821 | 94 | 7/27/2026 |
| 6.32.1801 | 71 | 7/25/2026 |
| 6.32.1781 | 36 | 7/23/2026 |
| 6.31.1771 | 38 | 7/23/2026 |
| 6.30.1761 | 33 | 7/22/2026 |
| 6.30.1741 | 42 | 7/22/2026 |
| 6.29.1721 | 34 | 7/22/2026 |
| 6.28.1671 | 67 | 7/22/2026 |
| 6.27.1651 | 33 | 7/20/2026 |