DirectX 12 / PRIMARY BACKEND

The DirectX 12 handbook

Build a native window, a first triangle, and a textured cube, then extend those contracts into a scheduled renderer.

Learn the machinery beneath a draw#

DirectX 12 gives the application explicit responsibility for GPU resources, command recording, bindings, and synchronization. That control helps an engine organize work, but it also means a convenient draw function cannot hide every lifetime decision. This track uses C++20, HLSL Shader Model 6.0, a Windows SDK, CMake, and the official DirectX Shader Compiler. Matrices use row vectors and row-major storage; the camera uses a left-handed convention. The same choices appear in every core sample.

The connected source#

The complete samples live in samples/dx12. CMake builds qubic_triangle and qubic_texture from the same main.cpp, with TEXTURED choosing the geometry, depth, and texture path. This keeps window creation, queue ownership, resizing, and frame fences identical across the two examples.

ChapterAddsExpected result
SetupToolchain, project, shader buildBoth targets configure and build on Windows
Device and swap chainWindow, device, queue, targetsA native presentation surface
First triangleRoot constants, PSO, geometry, drawA color-interpolated triangle
Resources and descriptorsExplicit binding and allocation rulesExplain the sample’s resource ownership
Texture loadingWIC decode, padded staging, SRVA rotating textured cube
Mesh loadingImport contracts and default buffersExtend built-in geometry toward imported assets
SynchronizationPer-slot completion and retirementSafe overlapping CPU/GPU work
Building a rendererRenderWorld and RenderGraphA scalable reference design

Before the advanced renderer#

The teaching path deliberately has one uncompressed texture mip, simple face tints, upload-heap geometry, and a small root signature. Those choices reduce unrelated machinery. The engine chapters describe how cooked mips, GPU-local geometry, materials, skinning, and multiple passes extend that path. Every larger excerpt is labeled reference code. Helpers in the complete sample are defined in main.cpp: Check validates HRESULT, Heap constructs heap properties, BufferDesc constructs a buffer description, Transition records a state barrier, and ReadBytes loads compiled shaders. Sample owns all native resources and FrameContext stores one allocator and its last completion value.

Open a chapter#

Official foundations#

Read Microsoft’s component flow, resource uploads, and allocator reset requirements. The code here uses real queue Signal and fence event APIs, rather than sample-only pseudocode methods.

Search titles and full article text.