GPGMM is a General-Purpose GPU Memory Management C++ library used by GPU application run-times or middleware APIs that rely on low-level graphics and compute APIs (D3D12 or Vulkan) for "explicit" memory management. GPGMM is a fast, multi-threaded Video Memory Manager (VidMM) implementation that replaces what older APIs accomplished through the GPU driver (D3D11 or OpenGL).
GPGMM uses the Chromium build system and dependency management so you need to install depot_tools and add it to the PATH.
Notes:
- On Windows, you'll need to set the environment variable
DEPOT_TOOLS_WIN_TOOLCHAIN=0
. This tells depot_tools to use your locally installed version of Visual Studio (by default, depot_tools will try to download a Google-internal version).
Get the source code as follows:
# Clone the repo as "GPGMM"
> git clone https://github.com/intel/GPGMM.git GPGMM && cd GPGMM
# Bootstrap the gclient configuration
> cp scripts/standalone.gclient .gclient
# Fetch external dependencies and toolchains with gclient
> gclient sync
Generate build files using gn args out/Debug
or gn args out/Release
.
A text editor will appear asking build arguments, the most common argument is is_debug=true/false
; otherwise gn args out/Release --list
shows all the possible options.
To build with a backend, please set the corresponding argument from following table.
Backend | Build argument |
---|---|
DirectX 12 | gpgmm_enable_d3d12=true (default on winos) |
Vulkan | gpgmm_enable_vulkan=true |
Then use ninja -C out/Release
or ninja -C out/Debug
to build.
Run unit tests:
> out/Debug/gpgmm_unittests
Run end2end tests:
> out/Debug/gpgmm_end2end_tests
Run capture replay tests:
> out/Debug/gpgmm_capture_replay_tests
To allocate, you create an allocator then create allocations from it:
D3D12_FEATURE_DATA_ARCHITECTURE arch = {};
device->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, &arch, sizeof(arch)
D3D12_FEATURE_DATA_D3D12_OPTIONS options = {};
device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options)));
gpgmm::d3d12::ALLOCATOR_DESC allocatorDesc = {};
allocatorDesc.Adapter = adapter;
allocatorDesc.Device = device;
allocatorDesc.IsUMA = arch.UMA;
allocatorDesc.ResourceHeapTier = options.ResourceHeapTier;
ComPtr<gpgmm::d3d12::ResourceAllocator> allocator;
gpgmm::d3d12::ResourceAllocator::CreateAllocator(desc, &allocator);
/* Fill this out */
D3D12_RESOURCE_DESC& resourceDesc = {...};
D3D12_RESOURCE_STATES initialState = {...}
gpgmm::d3d12::ALLOCATION_DESC allocationDesc = {};
allocationDesc.HeapType = heapType;
ComPtr<gpgmm::d3d12::ResourceAllocation> allocation;
allocator->CreateResource(allocationDesc, resourceDesc, initialState, /*pOptimizedClear*/nullptr, &allocation);
Then de-allocate:
/* Must make sure GPU is finished using it */
allocation.Release();
To use basic residency:
- Create a
d3d12::ResourceAllocator
withALLOCATOR_FLAG_ALWAYS_IN_BUDGET
flag. - Use
d3d12::ResourceAllocator::CreateResource
for every resource you want residency managed. - Create a
d3d12::ResidencySet
to track a collection of allocations that should be resident for a given command-list (1:1 relationship). d3d12::ResourceAllocation::UpdateResidency
tracks the underlying heap for the resident set.- Use
d3d12::ResidencyManager::ExecuteCommandLists
with the residency set, queue, and command list.
What about residency for other heaps (SV descriptor or query heaps)?
- Sub-class
d3d12::Heap
. - Call
d3d12::ResidencyManager::InsertHeap
on it after creation. - Use
d3d12::ResidencyManager::Lock
ord3d12::ResidencyManager::UnlockHeap
to keep heap resident or not, respectively.
GPGMM has built-in GN or CMake build targets.
BUILD.gn
source_set("proj") {
deps = [ "${gpgmm_dir}:gpgmm" ]
}
Create build_overrides/gpgmm.gni
file in root directory.
CMakeLists.txt
add_subdirectory(gpgmm)
target_include_directories(proj PRIVATE gpgmm/src/include gpgmm/src)
target_link_libraries(proj PRIVATE gpgmm ...)
Dynamic Linked Library (DLL)
Use is_clang=false gpgmm_shared_library=true
when Setting up the build.
Then use ninja -C out/Release gpgmm
or ninja -C out/Debug gpgmm
to build the shared library (DLL).
Copy the DLL into the $(OutputPath)
folder and configure the VS build:
- Highlight project in the Solution Explorer, and then select Project > Properties.
- Under Configuration Properties > C/C++ > General, add
gpgmm\src
andgpgmm\src\include
to Additional Include Directories. - Under Configuration Properties > Linker > Input, add
gpgmm.dll.lib
to Additional Dependencies. - Under Configuration Properties > Linker > General, add the folder path to
out\Release
to Additional Library Directories.
Then import:
#include <gpgmm_d3d12.h> // or gpgmm_vulkan.h
- Error handing uses API error codes (
HRESULT
andVkResult
for D3D12 and Vulkan, respectively).
Apache 2.0 Public License, please see LICENSE.