Build Config | Build Status |
---|---|
GN/Clang | |
CMake/MSVC |
GPGMM is a General-Purpose GPU Memory Management C++ library used by GPU applications/runtimes that use modern graphics and compute APIs (D3D12 or Vulkan) that allow low-level memory management. GPGMM is a fast, multi-threaded, full-fledged GPU Memory Manager (GMM) implementation that replaces what older graphics and compute APIs (D3D11 or OpenGL) had accomplished through the GPU driver.
- Error handing uses GPU API error codes (
HRESULT
andVkResult
for D3D12 and Vulkan, respectively).
First create an allocator then create allocations from it:
#include <gpgmm_d3d12.h>
// Required
gpgmm::d3d12::ALLOCATOR_DESC allocatorDesc = {};
allocatorDesc.Device = Device;
allocatorDesc.Adapter = Adapter;
ComPtr<gpgmm::d3d12::IResidencyManager> residency; // Optional
ComPtr<gpgmm::d3d12::IResourceAllocator> allocator;
gpgmm::d3d12::CreateResourceAllocator(desc, &allocator, &residency);
D3D12_RESOURCE_DESC& resourceDesc = {};
D3D12_RESOURCE_STATES initialState = {}
gpgmm::d3d12::ALLOCATION_DESC allocationDesc = {};
ComPtr<gpgmm::d3d12::IResourceAllocation> allocation;
allocator->CreateResource(allocationDesc, resourceDesc, initialState, nullptr, &allocation);
GPUs do not support page-faulting, so it's up the GPU application to avoid using too much physical GPU memory. GPGMM integrates residency into the resource allocators to simplify and optimize allocation:
ComPtr<gpgmm::d3d12::IResidencyList> list;
CreateResidencyList(&list);
list->Add(allocation->GetMemory());
residency->ExecuteCommandList(&queue, &commandList, &list, 1);
// Prepare for next frame.
list->Reset();
Residency also works for non-resources too:
gpgmm::d3d12::HEAP_DESC shaderVisibleHeap = {};
shaderVisibleHeap.SizeInBytes = kHeapSize;
shaderVisibleHeap.MemorySegmentGroup = DXGI_MEMORY_SEGMENT_GROUP_LOCAL;
ComPtr<gpgmm::d3d12::IHeap> descriptorHeap;
CreateHeapContext createHeapContext(heapDesc);
gpgmm::d3d12::CreateHeap(shaderVisibleHeap, residencyManager,
createHeapContext, &CreateHeapContext::CreateHeapCallbackWrapper,
&descriptorHeap);
// Shader-visible heaps should be locked or always resident.
residency->LockHeap(descriptorHeap.get());
To clean-up, simply call Release()
once the is GPU is finished.
#include <gpgmm_vk.h>
gpgmm::vk::GpAllocatorCreateInfo allocatorInfo = {};
gpgmm::vk::GpResourceAllocator resourceAllocator;
gpgmm::vk::gpCreateResourceAllocator(allocatorInfo, &resourceAllocator)
VkBufferCreateInfo bufferInfo = {};
VkBuffer buffer;
gpgmm::vk::GpResourceAllocation allocation;
gpgmm::vk::GpResourceAllocationCreateInfo allocationInfo = {};
gpgmm::vk::gpCreateBuffer(resourceAllocator, &bufferInfo, &buffer, &allocationInfo, &allocation)
Then to clean-up:
gpgmm::vk::gpDestroyBuffer(resourceAllocator, buffer, allocation); // Make sure GPU is finished!
gpgmm::vk::gpDestroyResourceAllocator(resourceAllocator);
Aside from DirectX or Vulkan libraries, GPGMM has no additional dependencies when deployed. GPGMM is distributed for use as source-only. It is recommended to use the built-in GN or CMake build targets. Alternatively, a shared library can be built to enable other build systems.
Allows GPGMM to be added as a source-package dependency to an existing build system.
BUILD.gn
source_set("proj") {
deps = [ "${gpgmm_dir}:src/gpgmm" ]
}
Create build_overrides/gpgmm.gni
file in root directory.
To build with a backend, add the corresponding argument from following table in ``build_overrides/gpgmm.gni`:
Backend | Build override argument |
---|---|
DirectX 12 | gpgmm_enable_d3d12=true |
Vulkan | gpgmm_enable_vk=true |
CMakeLists.txt
Using CMake 3.14 or newer:
include(FetchContent)
FetchContent_Declare(gpgmm
GIT_REPOSITORY https://github.com/intel/gpgmm.git
GIT_TAG main
)
# Specify GPGMM build options (see below).
...
FetchContent_MakeAvailable(gpgmm)
Or alternatively, manually fetch:
git clone https://github.com/intel/gpgmm.git third_party/gpgmm
And make available:
add_subdirectory(third_party/gpgmm)
...
# Specify GPGMM build options (see below).
...
Then add:
target_link_libraries(proj PRIVATE gpgmm)
Allows GPGMM to be built as a library-binary then linked as build-dependency.
First install vcpkg then run install gpgmm
.
vcpkg install gpgmm
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.
cmake -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Debug .
cmake --build . --config Debug
- 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\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.
Building GPGMM for development.
GPGMM uses the Chromium build system and dependency management so you need to install depot_tools and add it to the PATH. Then install visual studio with the SDK and “Debugging Tools For Windows” package.
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.
Then use ninja -C out/Release
or ninja -C out/Debug
to build.
GPGMM uses CMake 3.14 or higher for the build system and dependency management, so you need to install cmake and add it to the PATH.
Generate build files using cmake . -DCMAKE_BUILD_TYPE=Debug
or cmake . -DCMAKE_BUILD_TYPE=Release
.
To build with a backend, please specify the corresponding argument from following table.
Backend | Build argument |
---|---|
DirectX 12 | GPGMM_ENABLE_D3D12=ON |
Vulkan | GPGMM_ENABLE_VK=ON |
For example, adding -DGPGMM_ENABLE_VK=OFF
builds without Vulkan.
Additional build options further configure GPGMM:
Build option | Build argument |
---|---|
Disable compilation of tests | GPGMM_ENABLE_TESTS=OFF |
GPGMM is NOT being built in GPGMM repo | GPGMM_STANDALONE=OFF |
Compile GPGMM as shared library | BUILD_SHARED_LIBS |
For example, adding -dGPGMM_STANDALONE=OFF
, and -dBUILD_SHARED_LIBS
builds GPGMM as a shared DLL.
Notes: CMake 3.14 or higher is required for GPGMM_ENABLE_TESTS
or GPGMM_ENABLE_VK
.
The following build options are only available when GPGMM_ENABLE_VK=ON
:
Build option | Build argument |
---|---|
Import Vulkan functions statically | GPGMM_ENABLE_VK_STATIC_FUNCTIONS=ON |
For example, adding -dGPGMM_ENABLE_VK_STATIC_FUNCTIONS=ON
will use Vulkan by statically linking functions (from the built-in Vulkan Loader).
cmake --build .
- Unit tests check the front-end code in isolation or without a GPU.
- End2End tests check both the front AND backend code with a GPU.
- Capture replay checks using pre-recorded memory patterns with a GPU.
- Fuzzer checks using random memory patterns with a GPU.
> cd out/Debug # or out/Release
> gpgmm_unittests
> gpgmm_end2end_tests
> gpgmm_capture_replay_tests
To re-generate the capture:
gpgmm_capture_replay_tests.exe --gtest_filter=*Replay/* --event-mask=0x3 --disable-memory-playback
> gpgmm_*_fuzzer -max_total_time=<seconds_to_run>
> cd Debug # or Release
> cmake --build . --target RUN_TESTS
Apache 2.0 Public License, please see LICENSE.