D3D12 Memory Allocator Documentation

repository·master·Indexed 21 days ago

https://github.com/gpuopen-librariesandsdks/d3d12memoryallocator

A high-performance, thread-safe library for simplifying memory management and resource creation in Direct3D 12. It implements sub-allocation from large heaps to reduce overhead and fragmentation. Key features include the Allocator::CreateResource method, linear allocators, defragmentation, custom memory pools, resource aliasing, and a virtual allocator. Includes GpuMemDumpVis, a Python-based tool for visualizing internal memory state via JSON dumps.

Tokens
1.8K
Snippets
4
Records
9
Agent score
27%

What's inside D3D12 Memory Allocator

  1. Advanced memory management features

    master

    Beyond basic resource creation, the library provides several advanced capabilities:

    • Linear Allocator: Create pools using a linear algorithm for high-speed allocations/deallocations in stack, double stack, ring buffer, or free-at-once modes.
    • Defragmentation: Allows the library to move data to compact allocations and free up contiguous memory blocks.
    • Custom Memory Pools: Create pools with specific D3D12_HEAP_PROPERTIES and D3D12_HEAP_FLAGS or fixed maximum sizes.
    • Resource Aliasing: Supports overlapping resources in the same memory.
    • Virtual Allocator: An API to use the core allocation algorithm without actually allocating GPU memory (useful for sub-allocating pieces of a large buffer).
    • Statistics & Debugging:
      • Query global or per-heap statistics (usage, budget, number of allocations).
      • Associate custom void* pPrivateData and LPCWSTR pName with allocations.
      • Export a detailed internal state map via JSON dump.
      • Visualize memory via GpuMemDumpVis using the JSON dump.
  2. How D3D12 Memory Allocator works

    master

    The library manages the complexity of explicit memory management in Direct3D 12 by implementing a sub-allocation strategy. Instead of creating many small ID3D12Heap objects (which is expensive and limited), the library:

    1. Allocates and tracks large memory heaps.
    2. Manages used and unused ranges within those heaps.
    3. Selects the best matching unused range to place new resources.
    4. Automatically respects alignment and size requirements.
    5. Handles different D3D12_RESOURCE_HEAP_TIER requirements (separating resource classes for Tier 1 or allowing them together for Tier 2).

    This approach reduces fragmentation and improves performance compared to using ID3D12Device::CreateCommittedResource for every individual resource.

  3. Use GpuMemDumpVis to visualize memory dumps

    master

    Run the GpuMemDumpVis.py script from the command line to convert a JSON memory dump into an image.

    Input Requirements: The INPUT_FILE must be a JSON file (UTF-8 or UTF-16 encoding) containing the internal state dump generated by either:

    • vmaBuildStatsString() (for Vulkan)
    • D3D12MA::Allocator::BuildStatsString() (for D3D12)

    Output Formats: The image format is determined by the file extension of the OUTPUT_FILE. Supported formats include: BMP, GIF, JPEG, PNG, and TGA.

    python GpuMemDumpVis.py -o OUTPUT_FILE INPUT_FILE
  4. Create a resource with CreateResource()

    master

    The primary way to allocate memory and create resources (buffers or textures) is using the Allocator::CreateResource method. This method simplifies the process by automatically managing large memory heaps, finding suitable unused ranges, and creating the resource as a 'placed resource' within those ranges. It handles size, alignment, and resource heap tier requirements automatically.

    To use it, you need to provide:

    1. An ALLOCATION_DESC specifying the heap type.
    2. A D3D12_RESOURCE_DESC describing the resource (dimension, format, etc.).
    3. The initial resource state.
    4. An output D3D12MA::Allocation* which tracks the memory parameters (offset, size) and a D3D12MA::D3D12Resource* (which wraps the ID3D12Resource).
    D3D12_RESOURCE_DESC resourceDesc = {};
    resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    resourceDesc.Alignment = 0;
    resourceDesc.Width = 1024;
    resourceDesc.Height = 1024;
    resourceDesc.DepthOrArraySize = 1;
    resourceDesc.MipLevels = 1;
    resourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    resourceDesc.SampleDesc.Count = 1;
    resourceDesc.SampleDesc.Quality = 0;
    resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE;
    
    D3D12MA::ALLOCATION_DESC allocDesc = {};
    allocDesc.HeapType = D3D12_HEAP_TYPE_DEFAULT;
    
    D3D12MA::D3D12Resource* resource;
    D3D12MA::Allocation* allocation;
    HRESULT hr = allocator->CreateResource(
        &allocDesc, &resourceDesc,
        D3D12_RESOURCE_STATE_COPY_DEST, NULL,
        &allocation, IID_PPV_ARGS(&resource));
  5. Interpret GpuMemDumpVis visualization legend

    master

    The generated image uses specific colors and patterns to represent different memory allocation types and states:

    Buffers

    • Buffer 1: Usage containing INDIRECT_BUFFER, VERTEX_BUFFER, or INDEX_BUFFER (Vulkan).
    • Buffer 2: Usage containing STORAGE_BUFFER or STORAGE_TEXEL_BUFFER (Vulkan).
    • Buffer 3: Usage containing UNIFORM_BUFFER or UNIFORM_TEXEL_BUFFER (Vulkan).
    • Buffer 4: Other buffer types.

    Images (Optimal Tiling)

    • Image 1: DEPTH_STENCIL_ATTACHMENT (Vulkan) or D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL (D3D12).
    • Image 2: INPUT_ATTACHMENT, TRANSIENT_ATTACHMENT, COLOR_ATTACHMENT, or STORAGE (Vulkan), or D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET or D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS (D3D12).
    • Image 3: SAMPLED (Vulkan) or a texture not containing D3D12_RESOURCE_FLAG_DENY_SHARED_RESOURCE (D3D12).
    • Image 4: Other optimal tiling images/textures.

    Other States

    • Free space: Light gray without border; unused space in a Vulkan device memory block.
    • Image Linear: Image with LINEAR tiling (Vulkan).
    • Image Unknown: Image with tiling unknown to the allocator (Vulkan).
    • Unknown: Allocation of an unknown type.
    • Details: A black bar indicating one or more allocations are too small to be visualized as filled rectangles.

    Warning: The tool currently shows incorrect results when allocations alias (overlap) in memory, as it only considers allocation sizes and not their offsets.