Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions src/gpgmm/vk/FunctionsVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,17 @@
} while (0)

namespace gpgmm::vk {
void VulkanFunctions::LoadInstanceFunctions(VkInstance instance) {
void VulkanFunctions::LoadInstanceFunctions(VkInstance instance,
const VulkanExtensions& vkExtensions,
uint32_t vkApiVersion) {
GPGMM_DYNAMIC_GET_INSTANCE_FUNC(GetDeviceProcAddr);
GPGMM_DYNAMIC_GET_INSTANCE_FUNC(GetPhysicalDeviceMemoryProperties);
GPGMM_DYNAMIC_GET_INSTANCE_FUNC(GetPhysicalDeviceProperties);
// TODO

if (vkExtensions.enableMemoryBudgetEXT || vkApiVersion >= VK_API_VERSION_1_1) {
GPGMM_DYNAMIC_GET_INSTANCE_FUNC(GetPhysicalDeviceMemoryProperties2);
}
}

void VulkanFunctions::LoadDeviceFunctions(VkDevice device) {
Expand All @@ -55,7 +61,7 @@ namespace gpgmm::vk {
// TODO
}

void VulkanFunctions::ImportDeviceFunctions() {
void VulkanFunctions::ImportFunctions(uint32_t vkApiVersion) {
GPGMM_STATIC_GET_FUNC(GetPhysicalDeviceMemoryProperties);
GPGMM_STATIC_GET_FUNC(GetPhysicalDeviceProperties);
GPGMM_STATIC_GET_FUNC(AllocateMemory);
Expand All @@ -69,10 +75,15 @@ namespace gpgmm::vk {
GPGMM_STATIC_GET_FUNC(DestroyBuffer);
GPGMM_STATIC_GET_FUNC(DestroyImage);
// TODO

if (vkApiVersion >= VK_API_VERSION_1_1) {
GPGMM_STATIC_GET_FUNC(GetPhysicalDeviceMemoryProperties2);
}
}

void VulkanFunctions::ImportDeviceFunctions(const VulkanFunctions* vkFunctions) {
void VulkanFunctions::ImportFunctions(const VulkanFunctions* vkFunctions) {
GetPhysicalDeviceMemoryProperties = vkFunctions->GetPhysicalDeviceMemoryProperties;
GetPhysicalDeviceMemoryProperties2 = vkFunctions->GetPhysicalDeviceMemoryProperties2;
GetPhysicalDeviceProperties = vkFunctions->GetPhysicalDeviceProperties;
AllocateMemory = vkFunctions->AllocateMemory;
FreeMemory = vkFunctions->FreeMemory;
Expand All @@ -86,7 +97,9 @@ namespace gpgmm::vk {
DestroyImage = vkFunctions->DestroyImage;
}

void AssertVulkanFunctionsExist(const VulkanFunctions& vkFunctions) {
void AssertVulkanFunctionsExist(const VulkanFunctions& vkFunctions,
const VulkanExtensions& vkExtensions,
uint32_t vkApiVersion) {
ASSERT(vkFunctions.GetPhysicalDeviceMemoryProperties != nullptr);
ASSERT(vkFunctions.GetPhysicalDeviceProperties != nullptr);
ASSERT(vkFunctions.AllocateMemory != nullptr);
Expand All @@ -99,6 +112,10 @@ namespace gpgmm::vk {
ASSERT(vkFunctions.CreateImage != nullptr);
ASSERT(vkFunctions.DestroyBuffer != nullptr);
ASSERT(vkFunctions.DestroyImage != nullptr);

if (vkApiVersion >= VK_API_VERSION_1_1 || vkExtensions.enableMemoryBudgetEXT) {
ASSERT(vkFunctions.GetPhysicalDeviceMemoryProperties2 != nullptr);
}
}

} // namespace gpgmm::vk
21 changes: 17 additions & 4 deletions src/gpgmm/vk/FunctionsVk.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,25 @@

namespace gpgmm::vk {

// Used to determine which dynamically linked functions to load based on the required Vulkan API
// extension.
struct VulkanExtensions {
bool enableMemoryBudgetEXT = false;
};

// Vulkan entrypoints used by GPGMM.
struct VulkanFunctions {
// Used to dynamically set functions from a shared library (DLL or so).
void LoadInstanceFunctions(VkInstance instance);
void LoadInstanceFunctions(VkInstance instance,
const VulkanExtensions& vkExtensions,
uint32_t vkApiVersion);
void LoadDeviceFunctions(VkDevice device);

// Used to statically set functions from a static library (Vulkan loader).
void ImportDeviceFunctions();
void ImportFunctions(uint32_t vkApiVersion);

// Used to import pre-loaded functions set by the user.
void ImportDeviceFunctions(const VulkanFunctions* vkFunctions);
void ImportFunctions(const VulkanFunctions* vkFunctions);

// Order is important: instance must be loaded before device.
PFN_vkGetInstanceProcAddr GetInstanceProcAddr = nullptr;
Expand All @@ -46,9 +54,14 @@ namespace gpgmm::vk {
PFN_vkCreateImage CreateImage = nullptr;
PFN_vkDestroyImage DestroyImage = nullptr;
PFN_vkDestroyBuffer DestroyBuffer = nullptr;

// Core Vulkan 1.1
PFN_vkGetPhysicalDeviceMemoryProperties2 GetPhysicalDeviceMemoryProperties2 = nullptr;
};

// ASSERTs if any Vulkan function is left unset.
void AssertVulkanFunctionsExist(const VulkanFunctions& vkFunctions);
void AssertVulkanFunctionsExist(const VulkanFunctions& vkFunctions,
const VulkanExtensions& vkExtensions,
uint32_t vkApiVersion);

} // namespace gpgmm::vk
23 changes: 14 additions & 9 deletions src/gpgmm/vk/ResourceAllocatorVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,29 +188,34 @@ namespace gpgmm::vk {
// static
VkResult GpResourceAllocator_T::CreateAllocator(const GpAllocatorCreateInfo& info,
GpResourceAllocator* allocatorOut) {
VulkanFunctions vulkanFunctions = {};
VulkanFunctions vkFunctions = {};
{
VulkanExtensions vkExtensionsRequired = {};
vkExtensionsRequired.enableMemoryBudgetEXT =
(info.flags & GP_ALLOCATOR_CREATE_ALWAYS_IN_BUDGET);

if (info.pVulkanFunctions != nullptr) {
vulkanFunctions.ImportDeviceFunctions(info.pVulkanFunctions);
vkFunctions.ImportFunctions(info.pVulkanFunctions);
} else {
#if defined(GPGMM_STATIC_VULKAN_FUNCTIONS)
vulkanFunctions.ImportDeviceFunctions();
vkFunctions.ImportFunctions(info.vulkanApiVersion);
#else // GPGMM_DYNAMIC_VULKAN_FUNCTIONS
vulkanFunctions.LoadInstanceFunctions(info.instance);
vulkanFunctions.LoadDeviceFunctions(info.device);
vkFunctions.LoadInstanceFunctions(info.instance, vkExtensionsRequired,
info.vulkanApiVersion);
vkFunctions.LoadDeviceFunctions(info.device);
#endif
}

#ifndef NDEBUG
AssertVulkanFunctionsExist(vulkanFunctions);
AssertVulkanFunctionsExist(vkFunctions, vkExtensionsRequired, info.vulkanApiVersion);
#endif
}

std::unique_ptr<Caps> caps;
{
Caps* ptr = nullptr;
ReturnIfFailed(Caps::CreateCaps(info.physicalDevice, vulkanFunctions,
info.vulkanApiVersion, &ptr));
ReturnIfFailed(
Caps::CreateCaps(info.physicalDevice, vkFunctions, info.vulkanApiVersion, &ptr));
caps.reset(ptr);
}

Expand All @@ -224,7 +229,7 @@ namespace gpgmm::vk {
: kDefaultFragmentationLimit;

if (allocatorOut != VK_NULL_HANDLE) {
*allocatorOut = new GpResourceAllocator_T(newInfo, vulkanFunctions, std::move(caps));
*allocatorOut = new GpResourceAllocator_T(newInfo, vkFunctions, std::move(caps));
}

return VK_SUCCESS;
Expand Down
8 changes: 8 additions & 0 deletions src/gpgmm/vk/ResourceAllocatorVk.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ namespace gpgmm::vk {
minimal possible GPU memory footprint or debugging OOM failures.
*/
GP_ALLOCATOR_CREATE_ALWAYS_ON_DEMAND = 0x8,

/** \brief Creates resource within budget.

Requires the device extension VK_EXT_memory_budget to be supported before use.
The instance specified in GpAllocatorCreateInfo is also required to support
VK_KHR_get_physical_device_properties2.
*/
GP_ALLOCATOR_CREATE_ALWAYS_IN_BUDGET = 0x10,
};

/** \enum GpAllocatorAlgorithm
Expand Down