Vulkan-Hpp
Vulkan-Hpp copied to clipboard
should VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE be exported from vulkan_hpp module?
First off I'm not sure if this is just a compiler issue, apologies if so.
I'm using the Vulkan-Hpp version from the 1.3.296 sdk release Compiler: MSVC 19.42.34435
This issue doesn't seem consistent and I'm not fully sure what conditions cause it to appear.
When using dynamic dispatch, template instantiation of many vk functions sometimes fails with
error C2039: 'defaultDispatchLoaderDynamic': is not a member of 'vk'
I've constructed the following minimal example:
CMakeLists.txt
cmake_minimum_required(VERSION 3.28.0)
project(Test)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
find_package(Vulkan)
add_library(Vulkan-Hpp-Module)
target_sources(Vulkan-Hpp-Module
PUBLIC FILE_SET CXX_MODULES BASE_DIRS ${Vulkan_INCLUDE_DIRS}/vulkan FILES
${Vulkan_INCLUDE_DIRS}/vulkan/vulkan.cppm
)
target_include_directories(Vulkan-Hpp-Module PUBLIC ${Vulkan_INCLUDE_DIRS})
target_compile_definitions(Vulkan-Hpp-Module PUBLIC
VK_NO_PROTOTYPES=1
)
add_executable(Test)
target_link_libraries(Test PUBLIC
Vulkan-Hpp-Module
)
target_sources(Test PRIVATE
modules-example.cpp
storage.cpp
)
storage.cpp
#include <vulkan/vulkan_hpp_macros.hpp>
import vulkan_hpp;
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
modules-example.cpp
#include <compare> // Needed for calls to templated vulkan_hpp functions to compile
import vulkan_hpp;
vk::ImageView create_image(vk::Device device, const vk::ImageViewCreateInfo& view_info);
int main() {
// Enable this line and compilation suddenly works
// vk::Instance instance = vk::createInstance(vk::InstanceCreateInfo{});
}
vk::ImageView create_image(vk::Device device, const vk::ImageViewCreateInfo& view_info) {
return device.createImageView(view_info);
// return nullptr;
}
Building the project as-is fails, with the following compiler output.
[1/2] Building CXX object CMakeFiles\Test.dir\modules-example.cpp.obj
FAILED: CMakeFiles/Test.dir/modules-example.cpp.obj
C:\PROGRA~1\MICROS~1\2022\COMMUN~1\VC\Tools\MSVC\1442~1.344\bin\Hostx64\x64\cl.exe /nologo /TP -DVK_NO_PROTOTYPES=1 -IC:\VulkanSDK\1.3.296.0\Include /DWIN32 /D_WINDOWS /EHsc /Ob0 /Od /RTC1 -std:c++latest -MDd -Zi /showIncludes @CMakeFiles\Test.dir\modules-example.cpp.obj.modmap /FoCMakeFiles\Test.dir\modules-example.cpp.obj /FdCMakeFiles\Test.dir\ /FS -c E:\Source\Repos\VEE\out\test\modules-example.cpp
C:\VulkanSDK\1.3.296.0\Include\vulkan\vulkan_handles.hpp(11098): error C2039: 'defaultDispatchLoaderDynamic': is not a member of 'vk'
C:\VulkanSDK\1.3.296.0\Include\vulkan\vulkan.cppm(28): note: see declaration of 'vk'
C:\VulkanSDK\1.3.296.0\Include\vulkan\vulkan_handles.hpp(11098): note: the template instantiation context (the oldest one first) is
E:\Source\Repos\VEE\out\test\modules-example.cpp(13): note: see instantiation of default argument expression required for 'vk::ImageView vk::Device::createImageView<vk::DispatchLoaderDynamic>(const vk::ImageViewCreateInfo &,vk::Optional<const vk::AllocationCallbacks>,const Dispatch &) const'
with
[
Dispatch=vk::DispatchLoaderDynamic
]
C:\VulkanSDK\1.3.296.0\Include\vulkan\vulkan_handles.hpp(11098): error C2065: 'defaultDispatchLoaderDynamic': undeclared identifier
ninja: build stopped: subcommand failed.
Interestingly enabling the call to vk::createInstance in main will result in a successful compilation.
I'm this issue in my real project at the moment and my current solution is to export VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE in a utility module and import it alongside vulkan_hpp. It seems that including vulkan/vulkan_hpp_macros.hpp also works.
Should this export be added to vulkan.cppm?
In my case, Clang succeeds compilation and GCC fails in both cases. Seems like theres some c++20 module implementation differences here still.
The problem for me seems to stem from the fact that GCC has issues with the defaultDispatchLoaderDynamic being extern in the global module portion of vulkan.cppm. Exporting VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE did not solve this and resulted in vulkan.cppm redefining all standard library symbols..?
Either way, it might make sense to revisit the dynamic dispatch storage for modules specifically as they will always be compiled only once now, unlike the headers from vulkan.hpp. So maybe an additional flag could be set to place the storage directly into the vulkan.cppm module itself, which will vastly simplify the process for most people. Those who need external (or DLL storage) would still be able to do so.
@SquareMan could you check if this issue still exists with the newest version of the headers? We made some changes to the export by now, so I can at this point successfully compiled it with 1.4.321 and higher (both Clang 20 and GCC 15).
Side note: If you want to avoid macros for the dynamic dispatcher (as that sort of clashes with the c++ module idiom), you can use the symbol directly like this:
import vulkan_hpp;
namespace vk::detail {
DispatchLoaderDynamic defaultDispatchLoaderDynamic;
}
Closing this, as it seems to be resolved. Please reopen if not.