@@ -7,8 +7,7 @@ keywords: "directx 12, d3d12, hlsl, descriptor heap, root signature, pso, dxr, m
77tags:: index, graphics-programming, advanced-graphics, c++, windows
88title:: DirectX
99
10- - # DirectX 12 — The Complete Masterclass
11- collapsed:: true
10+ - # DirectX 12 — The Roadmap
1211 - > [!info] How to Read This Page
1312 > DirectX 12 (D3D12) is Microsoft's explicit, low-level graphics API for Windows 10/11 and Xbox.
1413 > Like Vulkan, it strips away all driver "magic" and requires you to manage memory, synchronization, and pipeline states yourself.
@@ -19,32 +18,28 @@ title:: DirectX
1918 > → Swapchain → Descriptor Heaps → Command Lists → Root Signature
2019 > → Pipeline State Object (PSO) → Render Loop → [Advanced Topics]
2120 > ```
22-
2321 - ## DirectX 12 vs Vulkan Side-by-Side
2422 collapsed:: true
25- -
26- | Concept | Vulkan | DirectX 12 |
27- |---|---|---|
28- | GPU representation | `VkDevice` | `ID3D12Device` |
29- | Command recording | `VkCommandBuffer` | `ID3D12GraphicsCommandList` |
30- | Command memory | `VkCommandPool` | `ID3D12CommandAllocator` |
31- | Submission queue | `VkQueue` | `ID3D12CommandQueue` |
32- | Render targets | `VkRenderPass` + `VkFramebuffer` | `OMSetRenderTargets()` (no formal pass) |
33- | Shader bindings schema | `VkDescriptorSetLayout` | `ID3D12RootSignature` |
34- | Shader bindings data | `VkDescriptorSet` | Descriptor Heap + GPU handles |
35- | Baked pipeline object | `VkPipeline` | `ID3D12PipelineState` |
36- | CPU–GPU sync | `VkFence` | `ID3D12Fence` |
37- | GPU–GPU sync | `VkSemaphore` | `ID3D12Fence` (on separate queue) |
38- | Resource state | Image Layout Transition | Resource Barrier |
39- | Memory allocation | `vkAllocateMemory` | Heap Types (Default, Upload, Readback) |
40- | Window system | `VkSurfaceKHR` | `IDXGISwapChain` |
41- | Shader language | GLSL → SPIR-V | HLSL → DXBC / DXIL |
42- | Ray Tracing | `VK_KHR_ray_tracing_pipeline` | DirectX Raytracing (DXR) |
43-
23+ | Concept | Vulkan | DirectX 12 |
24+ |---|---|---|
25+ | GPU representation | `VkDevice` | `ID3D12Device` |
26+ | Command recording | `VkCommandBuffer` | `ID3D12GraphicsCommandList` |
27+ | Command memory | `VkCommandPool` | `ID3D12CommandAllocator` |
28+ | Submission queue | `VkQueue` | `ID3D12CommandQueue` |
29+ | Render targets | `VkRenderPass` + `VkFramebuffer` | `OMSetRenderTargets()` (no formal pass) |
30+ | Shader bindings schema | `VkDescriptorSetLayout` | `ID3D12RootSignature` |
31+ | Shader bindings data | `VkDescriptorSet` | Descriptor Heap + GPU handles |
32+ | Baked pipeline object | `VkPipeline` | `ID3D12PipelineState` |
33+ | CPU–GPU sync | `VkFence` | `ID3D12Fence` |
34+ | GPU–GPU sync | `VkSemaphore` | `ID3D12Fence` (on separate queue) |
35+ | Resource state | Image Layout Transition | Resource Barrier |
36+ | Memory allocation | `vkAllocateMemory` | Heap Types (Default, Upload, Readback) |
37+ | Window system | `VkSurfaceKHR` | `IDXGISwapChain` |
38+ | Shader language | GLSL → SPIR-V | HLSL → DXBC / DXIL |
39+ | Ray Tracing | `VK_KHR_ray_tracing_pipeline` | DirectX Raytracing (DXR) |
4440- # 1 — Setup and COM Pointers
4541 collapsed:: true
4642 - ## Windows COM Interface
47- collapsed:: true
4843 - DirectX uses **COM (Component Object Model)** interfaces. Every D3D12 object is a COM interface (`ID3D12Something`). You must use `Microsoft::WRL::ComPtr<T>` instead of raw pointers — it auto-releases when it goes out of scope (like `shared_ptr` for COM objects).
4944 - ```cpp
5045 #include <d3d12.h>
@@ -65,9 +60,8 @@ title:: DirectX
6560 // device.GetAddressOf() → &device (for creation functions)
6661 // device.Reset() → explicit release
6762 ```
68-
63+ -
6964 - ## Enabling the Debug Layer
70- collapsed:: true
7165 - The D3D12 Debug Layer validates every API call and catches mistakes. Always enable it in debug builds.
7266 - ```cpp
7367 #if defined(_DEBUG)
@@ -85,7 +79,8 @@ title:: DirectX
8579 #endif
8680 ```
8781 - > [!warning] Enable **before** creating any other D3D12 object. The debug layer must be active at creation time to instrument objects.
88-
82+ -
83+ -
8984- # 2 — DXGI Factory and Adapter (Finding a GPU)
9085 collapsed:: true
9186 - ## DXGI — The Hardware Bridge
@@ -123,19 +118,17 @@ title:: DirectX
123118 }
124119 }
125120 ```
126-
121+ -
127122- # 3 — Creating the D3D12 Device
128123 collapsed:: true
129124 - ## Feature Levels
130125 collapsed:: true
131- -
132- | Feature Level | GPU Requirement | Features |
126+ - | Feature Level | GPU Requirement | Features |
133127 |---|---|---|
134128 | `D3D_FEATURE_LEVEL_11_0` | Very old GPUs | SM 5.0, basic compute |
135129 | `D3D_FEATURE_LEVEL_12_0` | Modern discrete GPUs | Tier 1 resource binding, VP, DXR optional |
136130 | `D3D_FEATURE_LEVEL_12_1` | NVIDIA Maxwell+ / AMD GCN+ | Tier 2 resource binding |
137131 | `D3D_FEATURE_LEVEL_12_2` | NVIDIA Ampere+ / AMD RDNA2+ | DXR Tier 1.1, Mesh Shaders, VRS |
138-
139132 - ## Creating the Device
140133 collapsed:: true
141134 - ```cpp
@@ -164,7 +157,7 @@ title:: DirectX
164157 D3D12_FEATURE_DATA_SHADER_MODEL shaderModel{ D3D_SHADER_MODEL_6_6 };
165158 device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shaderModel, sizeof(shaderModel));
166159 ```
167-
160+ -
168161- # 4 — Command Queue, Allocator, and List
169162 collapsed:: true
170163 - ## The Three-Part Command System
@@ -179,7 +172,6 @@ title:: DirectX
179172 CL -->|"commandList->Close()"| CQ
180173 CQ -->|"commandQueue->ExecuteCommandLists()"| GPU["GPU: executes async"]
181174 ```
182-
183175 - ## Creating Each Component
184176 collapsed:: true
185177 - ```cpp
@@ -212,7 +204,7 @@ title:: DirectX
212204 commandList->Close(); // Must be closed before reset
213205 ```
214206 - > [!tip] Create one `CommandAllocator` per frame-in-flight AND per thread. A command allocator cannot be reset while the GPU is still reading from it. The command list itself is cheap and can be shared across frames after resetting.
215-
207+ -
216208- # 5 — Swapchain
217209 collapsed:: true
218210 - ## Creating the Swapchain
@@ -249,7 +241,7 @@ title:: DirectX
249241
250242 UINT currentFrameIndex = swapChain->GetCurrentBackBufferIndex();
251243 ```
252-
244+ -
253245- # 6 — Descriptor Heaps
254246 collapsed:: true
255247 - ## What Are Descriptor Heaps?
@@ -265,17 +257,14 @@ title:: DirectX
265257
266258 Resource --> View --> Heap --> Shader
267259 ```
268-
269260 - ## The Four Heap Types
270261 collapsed:: true
271- -
272- | Heap Type | Holds | GPU Visible? | Usage |
262+ - | Heap Type | Holds | GPU Visible? | Usage |
273263 |---|---|---|---|
274264 | `CBV_SRV_UAV` | Constant Buffer Views, Shader Resource Views, Unordered Access Views | YES | All shader-readable data and textures |
275265 | `SAMPLER` | Texture sampling configurations | YES | How textures are filtered |
276266 | `RTV` | Render Target Views | NO | Back buffer / G-Buffer color targets |
277267 | `DSV` | Depth Stencil Views | NO | Depth and stencil buffers |
278-
279268 - ## Creating Descriptor Heaps
280269 collapsed:: true
281270 - ```cpp
@@ -320,19 +309,17 @@ title:: DirectX
320309 ComPtr<ID3D12DescriptorHeap> srvHeap;
321310 device->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&srvHeap));
322311 ```
323-
312+ -
324313- # 7 — Resources and Memory (Heaps)
325314 collapsed:: true
326315 - ## D3D12 Memory Heap Types
327316 collapsed:: true
328- -
329- | Heap Type | CPU Access | GPU Access | Use Case |
317+ - | Heap Type | CPU Access | GPU Access | Use Case |
330318 |---|---|---|---|
331319 | `HEAP_TYPE_DEFAULT` | None | Fast read/write | Textures, vertex buffers, render targets (VRAM) |
332320 | `HEAP_TYPE_UPLOAD` | CPU write | GPU read | Staging buffer, per-frame uniform data |
333321 | `HEAP_TYPE_READBACK` | CPU read | GPU write | GPU → CPU readback (screenshots, compute results) |
334322 | `HEAP_TYPE_CUSTOM` | Configurable | Configurable | Advanced: unified memory (laptop discrete) |
335-
336323 - ## Creating a Buffer Resource
337324 collapsed:: true
338325 - D3D12 uses `CreateCommittedResource` (simple, one allocation = one heap) or `CreatePlacedResource` (manual heap management, advanced).
@@ -380,13 +367,11 @@ title:: DirectX
380367 // Issue GPU copy command
381368 commandList->CopyResource(vertexBuffer.Get(), uploadBuffer.Get());
382369 ```
383-
384370 - ## Resource Barriers — The Most Important Concept
385371 collapsed:: true
386372 - Resource barriers are D3D12's way of telling the GPU: **"The resource's usage is changing."**
387373 - Without a barrier, the GPU doesn't know to flush its caches or wait for dependent passes to finish.
388- -
389- | Resource State | How it's Used |
374+ - | Resource State | How it's Used |
390375 |---|---|
391376 | `D3D12_RESOURCE_STATE_PRESENT` | On screen — about to be displayed |
392377 | `D3D12_RESOURCE_STATE_RENDER_TARGET` | Being drawn to (color output) |
@@ -427,7 +412,7 @@ title:: DirectX
427412 D3D12_RESOURCE_STATE_PRESENT);
428413 commandList->ResourceBarrier(1, &barrierBack);
429414 ```
430-
415+ -
431416- # 8 — Root Signatures
432417 collapsed:: true
433418 - ## What Is a Root Signature?
@@ -445,7 +430,6 @@ title:: DirectX
445430 RS --> RD
446431 RS --> DT
447432 ```
448-
449433 - ## Creating a Root Signature
450434 collapsed:: true
451435 - ```cpp
@@ -504,7 +488,7 @@ title:: DirectX
504488 serializedRootSig->GetBufferSize(),
505489 IID_PPV_ARGS(&rootSignature));
506490 ```
507-
491+ -
508492- # 9 — HLSL Shaders
509493 collapsed:: true
510494 - ## Writing a Vertex Shader
@@ -553,7 +537,6 @@ title:: DirectX
553537 return output;
554538 }
555539 ```
556-
557540 - ## Writing a Pixel Shader
558541 collapsed:: true
559542 - ```hlsl
@@ -588,7 +571,6 @@ title:: DirectX
588571 return float4(result, albedo.a);
589572 }
590573 ```
591-
592574 - ## Compiling HLSL at Runtime
593575 collapsed:: true
594576 - ```cpp
@@ -613,7 +595,7 @@ title:: DirectX
613595 // IDxcCompiler3 from dxcompiler.dll
614596 // Supports: WaveIntrinsics, Bindless, Raytracing, Mesh Shaders, SPIR-V output
615597 ```
616-
598+ -
617599- # 10 — Pipeline State Object (PSO)
618600 collapsed:: true
619601 - ## The Immutable Pipeline
@@ -668,7 +650,7 @@ title:: DirectX
668650 ComPtr<ID3D12PipelineState> pso;
669651 device->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&pso));
670652 ```
671-
653+ -
672654- # 11 — Drawing and the Render Loop
673655 collapsed:: true
674656 - ## Synchronization with Fences
@@ -693,7 +675,6 @@ title:: DirectX
693675 fenceValues[frameIndex]++;
694676 }
695677 ```
696-
697678 - ## The Complete D3D12 Frame
698679 collapsed:: true
699680 - ```cpp
@@ -771,7 +752,7 @@ title:: DirectX
771752 swapChain->Present(1, 0); // 1 = V-Sync, 0 = flags
772753 }
773754 ```
774-
755+ -
775756- # 12 — HLSL Compute Shaders
776757 collapsed:: true
777758 - ## Compute Shader Basics
@@ -829,7 +810,7 @@ title:: DirectX
829810 commandList->SetComputeRoot32BitConstants(1, 4, &simConstants, 0);
830811 commandList->Dispatch((particleCount + 63) / 64, 1, 1); // Ceiling division
831812 ```
832-
813+ -
833814- # 13 — DirectX Raytracing (DXR)
834815 collapsed:: true
835816 - ## DXR Overview
@@ -853,7 +834,6 @@ title:: DirectX
853834 SBT --> RMiss
854835 RGen -->|"TraceRay()"| RHit & RMiss
855836 ```
856-
857837 - ## HLSL Ray Generation Shader
858838 collapsed:: true
859839 - ```hlsl
@@ -920,14 +900,13 @@ title:: DirectX
920900 payload.color = float4(ndotl, ndotl, ndotl, 1);
921901 }
922902 ```
923-
903+ -
924904- # 14 — Mesh Shaders
925905 collapsed:: true
926906 - ## What Are Mesh Shaders?
927907 collapsed:: true
928908 - Mesh Shaders replace the entire Vertex → Tessellation → Geometry pipeline with a compute-like two-stage process. They were designed to solve GPU vertex processing inefficiencies.
929- -
930- | Stage | Role | Analogy |
909+ - | Stage | Role | Analogy |
931910 |---|---|---|
932911 | **Amplification Shader (AS)** | Runs first. For each meshlet, decides: render or cull? If render, spawns Mesh Shader threads. | The manager who checks: "which chunks are visible?" |
933912 | **Mesh Shader (MS)** | Processes one meshlet. Outputs vertices and primitives. | The worker who actually converts a chunk to triangles. |
@@ -971,38 +950,34 @@ title:: DirectX
971950 }
972951 }
973952 ```
974-
953+ -
975954- # 15 — Performance and Debugging
976955 collapsed:: true
977956 - ## Performance Best Practices
978957 collapsed:: true
979- -
980- | Practice | Why it Matters |
958+ - | Practice | Why it Matters |
981959 |---|---|
982960 | **Cache PSOs to disk** (`ID3D12PipelineLibrary`) | Loading a game with 10,000 PSOs? Cache to disk so compile only happens once. |
983961 | **Use Root Constants for hot data** | Zero CPU overhead — 12 DWORDs written directly into the command stream. |
984962 | **Bucket resources by update frequency** | Frequent: per-draw → Push Constants. Per-frame: → Root Descriptor. Rare: → Descriptor Table |
985963 | **Multi-thread command recording** | Frame 1 → thread 1 records geometry. Thread 2 records shadows. Merge before submit. |
986964 | **Indirect Draw** (`ExecuteIndirect`) | GPU fills the draw arguments. Zero CPU-side draw call loop needed. |
987965 | **Use the enhanced barriers API (D3D12 Agility SDK)** | `D3D12_BARRIER` (new) has less overhead and more precision than `ResourceBarrier()` |
988-
989966 - ## Debugging Tools
990967 collapsed:: true
991- -
992- | Tool | What it Does |
968+ - | Tool | What it Does |
993969 |---|---|
994970 | **PIX for Windows** | Microsoft's official D3D12 frame debugger. Shows every resource, barrier, and shader in real time. |
995971 | **RenderDoc** | Cross-platform frame capture. Works on D3D12 too. |
996972 | **NVIDIA Nsight** | GPU perf counters, shader occupancy, memory bandwidth |
997973 | **D3D12 Debug Layer** | API misuse detection. Always enable in development! |
998974 | **GPU-Based Validation (GBV)** | Detects GPU-timeline errors like OOB reads — much slower but catches hard bugs |
999-
975+ -
1000976- # 16 — Complete Object Reference
1001977 collapsed:: true
1002978 - ## Every D3D12 Object Explained
1003979 collapsed:: true
1004- -
1005- | D3D12 Object | Category | What It Does |
980+ - | D3D12 Object | Category | What It Does |
1006981 |---|---|---|
1007982 | `ID3D12Device` | Core | The logical GPU. Create all other objects from here. |
1008983 | `IDXGIAdapter4` | DXGI | Physical GPU representation. Enumerated via factory. |
@@ -1018,18 +993,12 @@ title:: DirectX
1018993 | `ID3D12Fence` | Sync | Signal from GPU → waited on by CPU or another queue. |
1019994 | `ID3D12StateObject` | Ray Tracing | Ray tracing pipeline object (replaces PSO for RT). |
1020995 | `ID3D12StateObjectProperties` | Ray Tracing | Query shader identifiers from a state object. |
1021-
1022- - # 🔗 Related Pages
1023- - [[Advanced Graphics]] — GPU architecture and API comparisons.
1024- - [[Vulkan]] — Vulkan equivalent for every DX12 concept.
1025- - [[Shader Programming]] — Deep dive into HLSL, semantics, and advanced shader techniques.
1026- - [[Unreal Engine]] — UE5 uses DX12 as its primary Windows renderer (Nanite uses Mesh Shaders).
1027- - [[C++]] — COM patterns, RAII, and smart pointers needed for clean DX12 code.
1028-
996+ -
997+ -
1029998- # More Learn — Free Resources
1030999 - [Microsoft DX12 Programming Guide](https://learn.microsoft.com/en-us/windows/win32/direct3d12/directx-12-programming-guide) - Official reference.
10311000 - [Frank Luna's "3D Game Programming with DX12"](https://d3dcoder.net/) - The essential beginner book.
10321001 - [DirectX-Graphics-Samples (GitHub)](https://github.com/microsoft/DirectX-Graphics-Samples) - Microsoft's D3D12 sample programs.
10331002 - [PIX for Windows (Free)](https://devblogs.microsoft.com/pix/) - Frame capture and GPU profiler.
10341003 - [DXR Tutorial](https://developer.nvidia.com/rtx/raytracing/dxr/dx12-raytracing-tutorial-part-1) - NVIDIA's official DXR walkthrough.
1035- - [D3D12 Mesh Shader Samples](https://github.com/microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12MeshShaders) - Mesh shader example project.
1004+ - [D3D12 Mesh Shader Samples](https://github.com/microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12MeshShaders) - Mesh shader example project.
0 commit comments