How DirectX 12 Handles GPU Virtual Addresses
DirectX 12 implements low-level memory virtualization by exposing 64-bit GPU Virtual Addresses (GPUVA) directly to applications, decoupling the logical layout of resources from physical video memory. By shifting memory management away from legacy, opaque driver abstractions to an explicit virtual address space governed by Windows Display Driver Model (WDDM) 2.0 and the hardware GPU Memory Management Unit (IOMMU/MMU), developers can directly manipulate addresses, reuse physical allocations, and perform efficient sparse memory binding.
The GPU Virtual Address Space
In DirectX 12, every resource allocated on the GPU is assigned a
64-bit virtual memory address represented by the
D3D12_GPU_VIRTUAL_ADDRESS type. Rather than referring to
memory through driver-managed resource handles, shaders and command
lists can reference allocations through raw memory pointers.
The underlying operating system memory manager (VidMm via WDDM 2.0) works with the GPU's hardware page tables to map these virtual addresses to actual physical segments, whether located in dedicated VRAM (local memory) or system RAM (non-local memory). This virtualization prevents memory fragmentation at the API level, ensures application sandboxing, and allows the GPU to use a flat, uniform memory model.
Explicit Resource Backing Models
DirectX 12 provides three primary patterns for mapping GPU virtual addresses to physical backing stores, granting varying levels of control over virtualization:
- Committed Resources: The simplest model, created
via
CreateCommittedResource. The API simultaneously allocates a contiguous range of GPU virtual address space and commits physical memory pages to back it. - Placed Resources: Created via
CreatePlacedResourcewithin a pre-allocatedID3D12Heap. This decouples the allocation of physical memory from the virtual address assignment, allowing multiple resources with distinct GPU virtual addresses to overlap and share the same physical memory footprint (aliasing) over different lifecycles. - Reserved Resources (Sparse/Tiled): Created via
CreateReservedResource. This reserves a span of GPU virtual address space without allocating any backing physical memory. Physical 64KB pages can later be mapped, unmapped, or remapped to these virtual addresses dynamically usingUpdateTileMappingsorCopyTileMappings.
The GPU Memory Management Unit and Page Tables
Hardware-level virtualization is executed by the GPU MMU. When a
command list references a D3D12_GPU_VIRTUAL_ADDRESS, the
GPU MMU traverses a multi-level page table hierarchy similar to a CPU
MMU:
- Page Directory Entry (PDE): Resolves the base address of the relevant page table.
- Page Table Entry (PTE): Points to the physical 4KB or 64KB page in VRAM or system memory, while storing status flags such as read/write permissions and residency states.
- Fault Handling: If an address is accessed while its
corresponding page is not resident, the GPU triggers a page fault. In
WDDM 2.0, this causes device removal
(
DXGI_ERROR_DEVICE_REMOVED), making residency management viaID3D12Device::MakeResidentan explicit responsibility of the application.
Practical Implications for Modern Rendering
Exposing virtual addresses directly unlocks performance optimizations that were impossible under traditional abstractions:
- Root Descriptors: Developers can bypass descriptor
heaps for buffers by passing raw GPU virtual addresses directly into the
root signature via
SetComputeRootShaderResourceVieworSetGraphicsRootConstantBufferView. - Buffer Pointers in Shaders: GPU virtual addresses can be stored inside other buffers, enabling GPU-driven rendering techniques where the GPU traverses data structures (such as bounding volume hierarchies or linked lists) using pointer chasing without CPU intervention.
- Ray Tracing Acceleration Structures: DirectX Raytracing (DXR) relies extensively on GPU virtual addresses to reference Bottom-Level and Top-Level Acceleration Structures (BLAS/TLAS), allowing dynamic linking of geometry instances directly within shader code.