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.
| Chapter | Adds | Expected result |
|---|---|---|
| Setup | Toolchain, project, shader build | Both targets configure and build on Windows |
| Device and swap chain | Window, device, queue, targets | A native presentation surface |
| First triangle | Root constants, PSO, geometry, draw | A color-interpolated triangle |
| Resources and descriptors | Explicit binding and allocation rules | Explain the sample’s resource ownership |
| Texture loading | WIC decode, padded staging, SRV | A rotating textured cube |
| Mesh loading | Import contracts and default buffers | Extend built-in geometry toward imported assets |
| Synchronization | Per-slot completion and retirement | Safe overlapping CPU/GPU work |
| Building a renderer | RenderWorld and RenderGraph | A 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#
Set up the native project
Install the Windows toolchain, compile HLSL with DXC, configure CMake, and run the shared teaching samples.
Explore chapter DirectX 12 / CHAPTERDevice, window & swap chain
Create the native objects that turn recorded GPU work into an image the window can present.
Explore chapter DirectX 12 / CHAPTERYour first triangle
Build the full pipeline contract: shader inputs, root constants, pipeline state, vertex/index data, command recording, and a visible draw.
Explore chapter DirectX 12 / CHAPTERResources & descriptors
Separate memory allocations from views, shader bindings, frame-owned updates, and safe descriptor retirement.
Explore chapter DirectX 12 / CHAPTERLoad a texture, end to end
Decode an image with WIC, honor upload footprints, copy to a default texture, publish an SRV, and sample it on indexed geometry.
Explore chapter DirectX 12 / CHAPTERMesh loading & GPU buffers
Extend the indexed cube into an import pipeline with validated vertex data, material slots, bounds, and GPU-local storage.
Explore chapter DirectX 12 / CHAPTERSynchronization without guesswork
Understand queue execution, state barriers, fence values, allocator reuse, frame contexts, and multi-queue retirement.
Explore chapter DirectX 12 / CHAPTERFrom sample to renderer
Keep the explicit contracts while adding scene extraction, pass dependencies, asynchronous assets, frame arenas, profiling, and backend boundaries.
Explore chapterOfficial 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.