Skip to content

D3D12: implement backend#1410

Draft
oviano wants to merge 2 commits into
floooh:masterfrom
oviano:d3d12-backend
Draft

D3D12: implement backend#1410
oviano wants to merge 2 commits into
floooh:masterfrom
oviano:d3d12-backend

Conversation

@oviano

@oviano oviano commented Jan 12, 2026

Copy link
Copy Markdown
Contributor

Hello @floooh

Long-time sokol user here. Thanks for the great library!

I know you've mentioned D3D12 is better suited for sokol_gfx2. That said, I had a need for it and have a complete implementation that passes all samples. Offering it in case it's useful, with no expectation to merge.

Even if it's not right for mainline, others may find it helpful?

Summary

  • Full D3D12 backend implementation for sokol_gfx.h
  • Supports all existing sokol features including compute shaders
  • Passes all unit tests and samples (d3d12-specific samples in separate sokol-samples PR)
  • Shader compilation via d3dcompiler_47.dll (same approach as D3D11)
  • Performance: ~5-25% faster than D3D11 depending on workload

Design

The implementation follows D3D12 best practices rather than being a thin wrapper over D3D11 patterns:

  • Double-buffered frames - per-frame command allocators for CPU/GPU overlap
  • Fence-based synchronization - application provides fence via sg_environment
  • Root signatures - per-pipeline, using descriptor tables and root CBVs
  • Pipeline state objects - full PSO with caching and deferred release
  • Descriptor heaps - CPU-side for creation, GPU-visible for binding (configurable sizes)
  • Uniform buffer ring - per-frame with 256-byte alignment
  • Upload ring buffer - per-frame staging for image updates
  • Resource barriers - automatic state tracking and transitions
  • Deferred release queue - fence-based safe resource cleanup

Written in C99-compatible style consistent with the other backends.

Implementation size: ~4,600 lines (compared to D3D11's ~2,300 lines). The larger size reflects D3D12's explicit resource management model.

Changes

  • sokol_gfx.h - D3D12 backend implementation
  • sokol_app.h - D3D12 swapchain/window integration
  • sokol_glue.h - D3D12 environment/swapchain helpers
  • util/sokol_*.h - D3D12 support in utility headers
  • tests/ - D3D12 test configurations and presets

Testing

  • All 322 unit tests pass (Debug)
  • Static analysis clean (clang --analyze)
  • Tested on Windows with NVIDIA RTX 3060

Note

The language binding examples (sokol-odin, sokol-rust, etc.) will need their switch/match statements updated to handle the new D3D12 backend case.

Related PRs

floooh/sokol-samples#188
floooh/sokol-tools#206

@floooh

floooh commented Jan 12, 2026

Copy link
Copy Markdown
Owner

Impressive work, but this is too big to review/merge (as you expected though ;)

I'll keep the PR open though for other people to reference, and maybe also as reference for a time when an official D3D12 backend might be implemented.

PS: when I got some more time I'll try to play around with the PR a bit. E.g. when the performance is comparable to the D3D11 backend, that might be a good reason to start thinking about replacing the D3D11 backend with D3D12 - mainly because D3D12 has a more modern shader compiler infrastructure...

@floooh floooh marked this pull request as draft January 12, 2026 16:53
@floooh

floooh commented Jan 12, 2026

Copy link
Copy Markdown
Owner

PS: the failing CI is about missing switch-prongs for a switch on the backend enum in some of the language samples... nothing critical.

@oviano

oviano commented Jan 12, 2026

Copy link
Copy Markdown
Contributor Author

Yup, all understood and that makes sense.

Essentially...use it as you see fit (or not!).

@oviano

oviano commented Jan 13, 2026

Copy link
Copy Markdown
Contributor Author

I added my stress test to a new branch, which might be useful if/when you come to experiment.

https://github.com/oviano/sokol/tree/d3d12-backend-with-stress-test

@kassane kassane mentioned this pull request Jan 31, 2026
6 tasks
The Zig binding generator cannot handle uint64_t* pointer types.
Changed to void* with internal cast, matching other pointer fields.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants