mirror of
https://github.com/KhronosGroup/Vulkan-Hpp.git
synced 2024-10-14 16:32:17 +00:00
Add support for a full volk replacement by supporting a global DispatchLoaderDynamic. The global dynamic dispatcher will be available if either the define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC is set to 1 or if VK_NO_PROTOTYPES is defined. In those cases it is required to add VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE; to any compilation unit of the project to allocate storage for the dispatcher. (#390)
This commit is contained in:
parent
9df0fac638
commit
e26cb8113a
@ -1100,13 +1100,13 @@ void VulkanHppGenerator::appendDispatchLoaderDynamic(std::string & str)
|
||||
|
||||
#if !defined(VK_NO_PROTOTYPES)
|
||||
// This interface is designed to be used for per-device function pointers in combination with a linked vulkan library.
|
||||
DispatchLoaderDynamic(vk::Instance const& instance, vk::Device const& device = {})
|
||||
DispatchLoaderDynamic(vk::Instance const& instance, vk::Device const& device)
|
||||
{
|
||||
init(instance, device);
|
||||
}
|
||||
|
||||
// This interface is designed to be used for per-device function pointers in combination with a linked vulkan library.
|
||||
void init(vk::Instance const& instance, vk::Device const& device = {})
|
||||
void init(vk::Instance const& instance, vk::Device const& device)
|
||||
{
|
||||
init(static_cast<VkInstance>(instance), ::vkGetInstanceProcAddr, static_cast<VkDevice>(device), device ? ::vkGetDeviceProcAddr : nullptr);
|
||||
}
|
||||
@ -1134,47 +1134,75 @@ void VulkanHppGenerator::appendDispatchLoaderDynamic(std::string & str)
|
||||
}
|
||||
|
||||
// This interface does not require a linked vulkan library.
|
||||
void init( VkInstance instance, PFN_vkGetInstanceProcAddr getInstanceProcAddr, VkDevice device = VK_NULL_HANDLE, PFN_vkGetDeviceProcAddr getDeviceProcAddr = nullptr )
|
||||
void init( VkInstance instance, PFN_vkGetInstanceProcAddr getInstanceProcAddr, VkDevice device = VK_NULL_HANDLE, PFN_vkGetDeviceProcAddr /*getDeviceProcAddr*/ = nullptr )
|
||||
{
|
||||
VULKAN_HPP_ASSERT(instance && getInstanceProcAddr);
|
||||
vkGetInstanceProcAddr = getInstanceProcAddr;
|
||||
vkGetDeviceProcAddr = getDeviceProcAddr ? getDeviceProcAddr : PFN_vkGetDeviceProcAddr( vkGetInstanceProcAddr( instance, "vkGetDeviceProcAddr") );
|
||||
init( vk::Instance(instance) );
|
||||
if (device) {
|
||||
init( vk::Device(device) );
|
||||
}
|
||||
}
|
||||
|
||||
void init( vk::Instance instance )
|
||||
{
|
||||
)";
|
||||
|
||||
std::string strDeviceFunctions;
|
||||
std::string strDeviceFunctionsInstance;
|
||||
std::string strInstanceFunctions;
|
||||
for (auto const& handle : m_handles)
|
||||
{
|
||||
for (auto const& command : handle.second.commands)
|
||||
{
|
||||
if ((command.first != "vkGetDeviceProcAddr") && (command.first != "vkGetInstanceProcAddr"))
|
||||
if ((command.first != "vkGetInstanceProcAddr"))
|
||||
{
|
||||
std::string enter, leave;
|
||||
appendPlatformEnter(enter, command.second.platform);
|
||||
appendPlatformLeave(leave, command.second.platform);
|
||||
|
||||
str += enter;
|
||||
if (!command.second.params.empty()
|
||||
&& m_handles.find(command.second.params[0].type.type) != m_handles.end()
|
||||
&& command.second.params[0].type.type != "VkInstance"
|
||||
&& command.second.params[0].type.type != "VkPhysicalDevice")
|
||||
{
|
||||
str += " " + command.first + " = PFN_" + command.first
|
||||
+ "( device ? vkGetDeviceProcAddr( device, \"" + command.first + "\" ) : vkGetInstanceProcAddr( instance, \"" + command.first + "\" ) );\n";
|
||||
strDeviceFunctions += enter;
|
||||
strDeviceFunctions += " " + command.first + " = PFN_" + command.first
|
||||
+ "( vkGetDeviceProcAddr( device, \"" + command.first + "\" ) );\n";
|
||||
strDeviceFunctions += leave;
|
||||
|
||||
strDeviceFunctionsInstance += enter;
|
||||
strDeviceFunctionsInstance += " " + command.first + " = PFN_" + command.first
|
||||
+ "( vkGetInstanceProcAddr( instance, \"" + command.first + "\" ) );\n";
|
||||
strDeviceFunctionsInstance += leave;
|
||||
}
|
||||
else
|
||||
{
|
||||
str += " " + command.first + " = PFN_" + command.first + "( vkGetInstanceProcAddr( instance, \"" + command.first + "\" ) );\n";
|
||||
}
|
||||
str += leave;
|
||||
strInstanceFunctions += enter;
|
||||
strInstanceFunctions += " " + command.first + " = PFN_" + command.first + "( vkGetInstanceProcAddr( instance, \"" + command.first + "\" ) );\n";
|
||||
strInstanceFunctions += leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
str += " }\n"
|
||||
" };\n";
|
||||
}
|
||||
|
||||
str += strInstanceFunctions;
|
||||
str += strDeviceFunctionsInstance;
|
||||
str += " }\n\n";
|
||||
str += " void init( vk::Device device )\n {\n";
|
||||
str += strDeviceFunctions;
|
||||
str += R"( }
|
||||
};
|
||||
|
||||
#define VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE namespace vk { DispatchLoaderDynamic defaultDispatchLoaderDynamic; }
|
||||
|
||||
)";
|
||||
}
|
||||
|
||||
void VulkanHppGenerator::appendDispatchLoaderStatic(std::string & str)
|
||||
{
|
||||
str += R"(
|
||||
#if !defined(VK_NO_PROTOTYPES)
|
||||
class DispatchLoaderStatic
|
||||
{
|
||||
public:)";
|
||||
@ -1211,19 +1239,35 @@ void VulkanHppGenerator::appendDispatchLoaderStatic(std::string & str)
|
||||
appendPlatformLeave(str, command.second.platform);
|
||||
}
|
||||
}
|
||||
str += " };\n";
|
||||
str += " };\n#endif\n";
|
||||
}
|
||||
|
||||
void VulkanHppGenerator::appendDispatchLoaderDefault(std::string & str)
|
||||
{
|
||||
str += "\n"
|
||||
"#if !defined(VK_NO_PROTOTYPES)";
|
||||
appendDispatchLoaderStatic(str);
|
||||
str += R"(
|
||||
typedef DispatchLoaderStatic DispatchLoaderDefault;
|
||||
#else // !defined(VK_NO_PROTOTYPES)
|
||||
class NeedExplicitDispatchLoader;
|
||||
typedef NeedExplicitDispatchLoader DispatchLoaderDefault;
|
||||
R"( class DispatchLoaderDynamic;
|
||||
#if !defined(VULKAN_HPP_DISPATCH_LOADER_DYNAMIC)
|
||||
# if defined(VK_NO_PROTOTYPES)
|
||||
# define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
|
||||
# else
|
||||
# define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(VULKAN_HPP_DEFAULT_DISPATCHER)
|
||||
# if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1
|
||||
#define VULKAN_HPP_DEFAULT_DISPATCHER ::vk::defaultDispatchLoaderDynamic
|
||||
# else
|
||||
# define VULKAN_HPP_DEFAULT_DISPATCHER ::vk::DispatchLoaderStatic()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(VULKAN_HPP_DEFAULT_DISPATCHER_TYPE)
|
||||
# if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1
|
||||
#define VULKAN_HPP_DEFAULT_DISPATCHER_TYPE ::vk::DispatchLoaderDynamic
|
||||
# else
|
||||
# define VULKAN_HPP_DEFAULT_DISPATCHER_TYPE ::vk::DispatchLoaderStatic
|
||||
# endif
|
||||
#endif
|
||||
)";
|
||||
}
|
||||
@ -1950,7 +1994,7 @@ void VulkanHppGenerator::appendFunctionHeaderArgumentsEnhanced(std::string & str
|
||||
str += "Dispatch const &d";
|
||||
if (withDefaults && !withAllocator)
|
||||
{
|
||||
str += " = Dispatch()";
|
||||
str += " = VULKAN_HPP_DEFAULT_DISPATCHER";
|
||||
}
|
||||
str += " ";
|
||||
}
|
||||
@ -1977,7 +2021,7 @@ void VulkanHppGenerator::appendFunctionHeaderArgumentsStandard(std::string & str
|
||||
str += "Dispatch const &d";
|
||||
if (withDefaults)
|
||||
{
|
||||
str += " = Dispatch() ";
|
||||
str += " = VULKAN_HPP_DEFAULT_DISPATCHER ";
|
||||
}
|
||||
}
|
||||
|
||||
@ -2087,7 +2131,7 @@ void VulkanHppGenerator::appendFunctionHeaderTemplate(std::string & str, std::st
|
||||
str += ", ";
|
||||
}
|
||||
}
|
||||
str += std::string("typename Dispatch") + (withDefault ? " = DispatchLoaderDefault" : "") + ">\n";
|
||||
str += std::string("typename Dispatch") + (withDefault ? " = VULKAN_HPP_DEFAULT_DISPATCHER_TYPE" : "") + ">\n";
|
||||
}
|
||||
|
||||
void VulkanHppGenerator::appendHandle(std::string & str, std::pair<std::string, HandleData> const& handleData, std::set<std::string> & listedHandles) const
|
||||
@ -2908,7 +2952,7 @@ void VulkanHppGenerator::appendUniqueTypes(std::string & str, std::string const&
|
||||
std::string deleterPool = handleIt->second.deletePool.empty() ? "" : ", " + stripPrefix(handleIt->second.deletePool, "Vk");
|
||||
str += "\n"
|
||||
" template <typename Dispatch> class UniqueHandleTraits<" + type + ", Dispatch> { public: using deleter = " + deleterType + deleterAction + "<" + deleterParent + deleterPool + ", Dispatch>; };\n"
|
||||
" using Unique" + type + " = UniqueHandle<" + type + ", DispatchLoaderDefault>;";
|
||||
" using Unique" + type + " = UniqueHandle<" + type + ", VULKAN_HPP_DEFAULT_DISPATCHER_TYPE>;";
|
||||
}
|
||||
str += "\n"
|
||||
"#endif /*VULKAN_HPP_NO_SMART_HANDLE*/\n";
|
||||
@ -4501,7 +4545,7 @@ int main( int argc, char **argv )
|
||||
class ObjectDestroy
|
||||
{
|
||||
public:
|
||||
ObjectDestroy( OwnerType owner = OwnerType(), Optional<const AllocationCallbacks> allocationCallbacks = nullptr, Dispatch const &dispatch = Dispatch() )
|
||||
ObjectDestroy( OwnerType owner = OwnerType(), Optional<const AllocationCallbacks> allocationCallbacks = nullptr, Dispatch const &dispatch = VULKAN_HPP_DEFAULT_DISPATCHER )
|
||||
: m_owner( owner )
|
||||
, m_allocationCallbacks( allocationCallbacks )
|
||||
, m_dispatch( &dispatch )
|
||||
@ -4529,7 +4573,7 @@ int main( int argc, char **argv )
|
||||
class ObjectDestroy<NoParent,Dispatch>
|
||||
{
|
||||
public:
|
||||
ObjectDestroy( Optional<const AllocationCallbacks> allocationCallbacks = nullptr, Dispatch const &dispatch = Dispatch() )
|
||||
ObjectDestroy( Optional<const AllocationCallbacks> allocationCallbacks = nullptr, Dispatch const &dispatch = VULKAN_HPP_DEFAULT_DISPATCHER )
|
||||
: m_allocationCallbacks( allocationCallbacks )
|
||||
, m_dispatch( &dispatch )
|
||||
{}
|
||||
@ -4554,7 +4598,7 @@ int main( int argc, char **argv )
|
||||
class ObjectFree
|
||||
{
|
||||
public:
|
||||
ObjectFree( OwnerType owner = OwnerType(), Optional<const AllocationCallbacks> allocationCallbacks = nullptr, Dispatch const &dispatch = Dispatch() )
|
||||
ObjectFree( OwnerType owner = OwnerType(), Optional<const AllocationCallbacks> allocationCallbacks = nullptr, Dispatch const &dispatch = VULKAN_HPP_DEFAULT_DISPATCHER )
|
||||
: m_owner( owner )
|
||||
, m_allocationCallbacks( allocationCallbacks )
|
||||
, m_dispatch( &dispatch )
|
||||
@ -4600,7 +4644,7 @@ int main( int argc, char **argv )
|
||||
class PoolFree
|
||||
{
|
||||
public:
|
||||
PoolFree( OwnerType owner = OwnerType(), PoolType pool = PoolType(), Dispatch const &dispatch = Dispatch() )
|
||||
PoolFree( OwnerType owner = OwnerType(), PoolType pool = PoolType(), Dispatch const &dispatch = VULKAN_HPP_DEFAULT_DISPATCHER )
|
||||
: m_owner( owner )
|
||||
, m_pool( pool )
|
||||
, m_dispatch( &dispatch )
|
||||
@ -5290,6 +5334,7 @@ namespace std
|
||||
+ classOptional
|
||||
+ classStructureChain
|
||||
+ classUniqueHandle;
|
||||
generator.appendDispatchLoaderStatic(str);
|
||||
generator.appendDispatchLoaderDefault(str);
|
||||
str += classObjectDestroy
|
||||
+ classObjectFree
|
||||
|
@ -15,47 +15,41 @@
|
||||
// VulkanHpp Samples : DispatchLoaderDynamic
|
||||
// Compile test on DispatchLoaderDynamic functions
|
||||
|
||||
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#include "vulkan/vulkan.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
static char const* AppName = "DispatchLoaderDynamic";
|
||||
static char const* EngineName = "Vulkan.hpp";
|
||||
|
||||
|
||||
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE;
|
||||
|
||||
int main(int /*argc*/, char ** /*argv*/)
|
||||
{
|
||||
try
|
||||
{
|
||||
vk::DispatchLoaderDynamic dld0;
|
||||
vk::DynamicLoader dl;
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = dl.getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
|
||||
|
||||
// empty DispatchLoaderDynamic, used for init calls later on
|
||||
vk::DispatchLoaderDynamic dld_boot(vkGetInstanceProcAddr);
|
||||
vk::Instance instance = vk::createInstance({}, nullptr, dld_boot);
|
||||
vk::Instance instance = vk::createInstance({}, nullptr);
|
||||
|
||||
vk::DispatchLoaderDynamic dld1(instance, vkGetInstanceProcAddr);
|
||||
|
||||
// compare to the empty dispatcher, and init the empty dispatcher the same way
|
||||
assert(memcmp(&dld0, &dld1, sizeof(vk::DispatchLoaderDynamic)) != 0);
|
||||
dld0.init(instance, vkGetInstanceProcAddr);
|
||||
assert(memcmp(&dld0, &dld1, sizeof(vk::DispatchLoaderDynamic)) == 0);
|
||||
// initialize function pointers for instance
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
|
||||
|
||||
// create a dispatcher, based on additional vkDevice/vkGetDeviceProcAddr
|
||||
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices(dld1);
|
||||
|
||||
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
|
||||
assert(!physicalDevices.empty());
|
||||
|
||||
vk::Device device = physicalDevices[0].createDevice({}, nullptr, dld1);
|
||||
vk::Device device = physicalDevices[0].createDevice({}, nullptr);
|
||||
|
||||
// device specialization functions
|
||||
vk::DispatchLoaderDynamic dld2(instance, vkGetInstanceProcAddr, device);
|
||||
|
||||
|
||||
// compare to "simpler" dispatcher and make them equal
|
||||
assert(memcmp(&dld0, &dld2, sizeof(vk::DispatchLoaderDynamic)) != 0);
|
||||
dld0.init(instance, vkGetInstanceProcAddr, device);
|
||||
assert(memcmp(&dld0, &dld2, sizeof(vk::DispatchLoaderDynamic)) == 0);
|
||||
// function pointer specialization for device
|
||||
VULKAN_HPP_DEFAULT_DISPATCHER.init(device);
|
||||
}
|
||||
catch (vk::SystemError err)
|
||||
{
|
||||
|
4387
vulkan/vulkan.hpp
4387
vulkan/vulkan.hpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user