Graphics APIs
Vulkan, Metal and DirectX 12 drive the same hardware and were designed in the same five years, from the same frustration with the drivers that came before. They agree about far more than their spellings suggest. These notes learn the agreement first, then the three dialects.
How this folder is split
Three pillars for what every API has, one folder per API for what only it has.
- resources — what the GPU reads from: buffers, textures, the memory under them, and how a shader is told where to find them.
- pipeline — how vertices become pixels: the shader stages, the fixed-function state wrapped around them, and the render targets they write to.
- commands — how work is handed over: recording, queues, synchronisation, and getting a finished image onto a screen.
The pillars carry the concept, defined once and named in the neutral term. The API folders carry the spelling, the object model, and the places where that API genuinely differs rather than merely renames.
graph TD
HUB["Graphics APIs<br/><i>hub</i>"]
subgraph concepts["The concepts · one note each"]
RES["resources"]
PIPE["pipeline"]
CMD["commands"]
end
subgraph dialects["The dialects"]
VK["Vulkan"]
MTL["Metal"]
DX["DirectX 12"]
end
HUB --> concepts
HUB --> dialects
VK -.->|"names, does not redefine"| concepts
MTL -.->|"names, does not redefine"| concepts
DX -.->|"names, does not redefine"| conceptsAn API note never redefines what a vertex buffer is. It says what this API calls one, what it makes you do that the others do not, and links back.
The correspondence
The table I actually reopen. Everything below is the same idea under three names; where a cell is missing, the API folded that responsibility into something else, and that absence is usually the interesting part.
| Concept | Vulkan | Metal | DirectX 12 |
|---|---|---|---|
| Device | VkDevice | MTLDevice | ID3D12Device |
| Queue | VkQueue | MTLCommandQueue | ID3D12CommandQueue |
| Command recording | VkCommandBuffer | MTLCommandBuffer + encoders | ID3D12GraphicsCommandList |
| Command backing memory | VkCommandPool | — (the queue owns it) | ID3D12CommandAllocator |
| Buffer | VkBuffer | MTLBuffer | ID3D12Resource |
| Texture | VkImage + VkImageView | MTLTexture | ID3D12Resource + a view |
| Memory | VkDeviceMemory | MTLHeap (or implicit) | ID3D12Heap |
| Sampler | VkSampler | MTLSamplerState | a sampler descriptor |
| Shader unit | VkShaderModule | MTLFunction in a MTLLibrary | a DXIL blob |
| Graphics pipeline | VkPipeline | MTLRenderPipelineState | ID3D12PipelineState |
| Binding layout | VkPipelineLayout | argument buffer layout | ID3D12RootSignature |
| Binding group | VkDescriptorSet | argument buffer | descriptor table |
| Descriptor storage | VkDescriptorPool | — (a plain buffer) | ID3D12DescriptorHeap |
| Render targets | VkRenderPass / dynamic rendering | MTLRenderPassDescriptor | OMSetRenderTargets |
| Presentation | VkSwapchainKHR | CAMetalLayer / CAMetalDrawable | IDXGISwapChain |
| GPU → CPU signal | VkFence | completion handler | ID3D12Fence |
| GPU → GPU signal | VkSemaphore | MTLEvent | ID3D12Fence |
| Shading language | GLSL / HLSL → SPIR-V | MSL → AIR | HLSL → DXIL |
Two rows are worth staring at. Command backing memory: Metal has no allocator because its driver owns the lifetime, which is one less thing to get wrong and one less thing to tune. GPU → CPU / GPU → GPU: D3D12 uses one object for both, Vulkan splits them in two, Metal gives you a callback for one and an event for the other — the same problem, solved at three levels of explicitness.
Not written yet
The concepts each pillar owes. Each is a note that will live in the pillar folder, not here.
- resources —
buffer,vertex-buffer,index-buffer,uniform-buffer,texture-resource,device-memory,resource-binding - pipeline —
vertex-shader,fragment-shader,vertex-input,pipeline-state,render-target - commands —
command-buffer,queue,gpu-synchronisation,swapchain
The dialects
- Vulkan — the explicit one, and the one gamegine is built on.
- Metal — Apple only, and the one that hides the most without lying about it.
- DirectX 12 — Windows and Xbox, descriptor heaps and root signatures.