Files
NazaraEngine/src/Nazara/Vulkan/VkLoader.cpp
Lynix da401af52c Vulkan/VkLoader: Add EnumerateInstance[Extension|Layer]Properties helper
Former-commit-id: a7cfc73816266cef944f7cb3c668be0b86bbfcbf
2016-04-24 04:37:31 +02:00

118 lines
3.7 KiB
C++

// Copyright (C) 2016 Jérôme Leclercq
// This file is part of the "Nazara Engine - Vulkan"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Vulkan/VkLoader.hpp>
#include <Nazara/Vulkan/Debug.hpp>
namespace Nz
{
namespace Vk
{
bool Loader::EnumerateInstanceExtensionProperties(std::vector<VkExtensionProperties>* properties, const char* layerName)
{
NazaraAssert(properties, "Invalid device vector");
// First, query physical device count
UInt32 propertyCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t
s_lastErrorCode = vkEnumerateInstanceExtensionProperties(layerName, &propertyCount, properties->data());
if (s_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to get instance extension properties count");
return false;
}
// Now we can get the list of the available physical device
properties->resize(propertyCount);
s_lastErrorCode = vkEnumerateInstanceExtensionProperties(layerName, &propertyCount, properties->data());
if (s_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to enumerate instance extension properties");
return false;
}
return true;
}
bool Loader::EnumerateInstanceLayerProperties(std::vector<VkLayerProperties>* properties)
{
NazaraAssert(properties, "Invalid device vector");
// First, query physical device count
UInt32 propertyCount = 0; // Remember, Nz::UInt32 is a typedef on uint32_t
s_lastErrorCode = vkEnumerateInstanceLayerProperties(&propertyCount, properties->data());
if (s_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to get instance layer properties count");
return false;
}
// Now we can get the list of the available physical device
properties->resize(propertyCount);
s_lastErrorCode = vkEnumerateInstanceLayerProperties(&propertyCount, properties->data());
if (s_lastErrorCode != VkResult::VK_SUCCESS)
{
NazaraError("Failed to enumerate instance layer properties");
return false;
}
return true;
}
bool Loader::Initialize()
{
#ifdef NAZARA_PLATFORM_WINDOWS
s_vulkanLib.Load("vulkan-1.dll");
#elif defined(NAZARA_PLATFORM_LINUX)
s_vulkanLib.Load("libvulkan.so");
#else
#error Unhandled platform
#endif
if (!s_vulkanLib.IsLoaded())
{
NazaraError("Failed to open vulkan library: " + s_vulkanLib.GetLastError());
return false;
}
// vkGetInstanceProcAddr is the only function that's garantee to be exported
vkGetInstanceProcAddr = reinterpret_cast<PFN_vkGetInstanceProcAddr>(s_vulkanLib.GetSymbol("vkGetInstanceProcAddr"));
if (!vkGetInstanceProcAddr)
{
NazaraError("Failed to get symbol \"vkGetInstanceProcAddr\": " + s_vulkanLib.GetLastError());
return false;
}
// all other functions should be loaded using vkGetInstanceProcAddr
#define NAZARA_VULKAN_LOAD_GLOBAL(func) func = reinterpret_cast<PFN_##func>(vkGetInstanceProcAddr(nullptr, #func))
NAZARA_VULKAN_LOAD_GLOBAL(vkCreateInstance);
NAZARA_VULKAN_LOAD_GLOBAL(vkEnumerateInstanceExtensionProperties);
NAZARA_VULKAN_LOAD_GLOBAL(vkEnumerateInstanceLayerProperties);
#undef NAZARA_VULKAN_LOAD_GLOBAL
s_lastErrorCode = VkResult::VK_SUCCESS;
return true;
}
#define NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL(func) PFN_##func Loader::func = nullptr
NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL(vkCreateInstance);
NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL(vkEnumerateInstanceExtensionProperties);
NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL(vkEnumerateInstanceLayerProperties);
NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL(vkGetInstanceProcAddr);
#undef NAZARA_VULKAN_GLOBAL_FUNCTION_IMPL
DynLib Loader::s_vulkanLib;
VkResult Loader::s_lastErrorCode;
void Loader::Uninitialize()
{
s_vulkanLib.Unload();
}
}
}