diff --git a/src/Magnum/Vk/Instance.cpp b/src/Magnum/Vk/Instance.cpp index ed033f387..eaece5549 100644 --- a/src/Magnum/Vk/Instance.cpp +++ b/src/Magnum/Vk/Instance.cpp @@ -26,12 +26,14 @@ #include "Instance.h" #include +#include #include #include #include #include #include "Magnum/Vk/Extensions.h" +#include "Magnum/Vk/ExtensionProperties.h" #include "Magnum/Vk/Handle.h" #include "Magnum/Vk/Result.h" #include "Magnum/Vk/Version.h" @@ -55,7 +57,7 @@ struct InstanceCreateInfo::State { const char** argv; }; -InstanceCreateInfo::InstanceCreateInfo(const Int argc, const char** const argv, const LayerProperties* const layerProperties, const InstanceExtensionProperties* const extensionProperties, const Flags flags): _info{}, _applicationInfo{} { +InstanceCreateInfo::InstanceCreateInfo(const Int argc, const char** const argv, const LayerProperties* const layerProperties, const InstanceExtensionProperties* extensionProperties, const Flags flags): _info{}, _applicationInfo{} { Utility::Arguments args = Implementation::arguments(); args.parse(argc, argv); @@ -68,8 +70,7 @@ InstanceCreateInfo::InstanceCreateInfo(const Int argc, const char** const argv, } _info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - /** @todo filter out magnum-specific flags once there are any */ - _info.flags = VkInstanceCreateFlags(flags); + _info.flags = VkInstanceCreateFlags(flags & ~Flag::NoImplicitExtensions); _info.pApplicationInfo = &_applicationInfo; _applicationInfo.pEngineName = "Magnum"; /** @todo magnum version? 2020 can't fit into Vulkan's version @@ -120,7 +121,23 @@ InstanceCreateInfo::InstanceCreateInfo(const Int argc, const char** const argv, /** @todo use this (enabling debug layers etc.) */ static_cast(layerProperties); - static_cast(extensionProperties); + + /* Enable implicit extensions unless that's forbidden */ + /** @todo move this somewhere else as this will grow significantly? */ + if(!(flags & Flag::NoImplicitExtensions)) { + if(!_state) _state.emplace(); + + /* Fetch searchable extension properties if not already */ + Containers::Optional extensionPropertiesStorage; + if(!extensionProperties) { + extensionPropertiesStorage = enumerateInstanceExtensionProperties(); + extensionProperties = &*extensionPropertiesStorage; + } + + /* Only if we don't have Vulkan 1.1, on which this is core */ + if(_state->version < Version::Vk11 && extensionProperties->isSupported()) + addEnabledExtensions(); + } } InstanceCreateInfo::InstanceCreateInfo(NoInitT) noexcept {} diff --git a/src/Magnum/Vk/Instance.h b/src/Magnum/Vk/Instance.h index 352592d0b..f04356a9c 100644 --- a/src/Magnum/Vk/Instance.h +++ b/src/Magnum/Vk/Instance.h @@ -63,7 +63,22 @@ class MAGNUM_VK_EXPORT InstanceCreateInfo { * Wraps @type_vk_keyword{InstanceCreateFlagBits}. * @see @ref Flags, @ref InstanceCreateInfo(Int, const char**, const LayerProperties*, const InstanceExtensionProperties*, Flags) */ - enum class Flag: UnsignedInt {}; + enum class Flag: UnsignedInt { + /* Any magnum-specific flags added here have to be filtered out + when passing them to _info.flags in the constructor. Using the + highest bits in a hope to prevent conflicts with Vulkan instance + flags added in the future. */ + + /** + * Don't implicitly enable any extensions. + * + * By default, the engine enables various extensions such as + * @vk_extension{KHR,get_physical_device_properties2} to provide a + * broader functionality. If you want to have a complete control + * over what gets enabled, set this flag. + */ + NoImplicitExtensions = 1u << 31 + }; /** * @brief Instance creation flags diff --git a/src/Magnum/Vk/Test/InstanceTest.cpp b/src/Magnum/Vk/Test/InstanceTest.cpp index d42be6ffa..8b5c8016d 100644 --- a/src/Magnum/Vk/Test/InstanceTest.cpp +++ b/src/Magnum/Vk/Test/InstanceTest.cpp @@ -49,7 +49,8 @@ InstanceTest::InstanceTest() { } void InstanceTest::createInfoConstructNoInit() { - InstanceCreateInfo info; + InstanceCreateInfo info{NoInit}; + info->sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; new(&info) InstanceCreateInfo{NoInit}; CORRADE_COMPARE(info->sType, VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); diff --git a/src/Magnum/Vk/Test/InstanceVkTest.cpp b/src/Magnum/Vk/Test/InstanceVkTest.cpp index 672b35829..999fc16c1 100644 --- a/src/Magnum/Vk/Test/InstanceVkTest.cpp +++ b/src/Magnum/Vk/Test/InstanceVkTest.cpp @@ -46,6 +46,7 @@ struct InstanceVkTest: TestSuite::Tester { explicit InstanceVkTest(); void createInfoConstructDefault(); + void createInfoConstructNoImplicitExtensions(); void createInfoApplicationInfo(); void createInfoLayers(); void createInfoExtensions(); @@ -147,6 +148,7 @@ struct { InstanceVkTest::InstanceVkTest() { addTests({&InstanceVkTest::createInfoConstructDefault, + &InstanceVkTest::createInfoConstructNoImplicitExtensions, &InstanceVkTest::createInfoApplicationInfo, &InstanceVkTest::createInfoLayers, &InstanceVkTest::createInfoExtensions, @@ -174,6 +176,21 @@ void InstanceVkTest::createInfoConstructDefault() { CORRADE_VERIFY(!info->pNext); CORRADE_VERIFY(!info->ppEnabledLayerNames); CORRADE_COMPARE(info->enabledLayerCount, 0); + /* Extensions might or might not be enabled */ + + CORRADE_VERIFY(info->pApplicationInfo); + CORRADE_COMPARE(Version(info->pApplicationInfo->apiVersion), enumerateInstanceVersion()); + CORRADE_COMPARE(info->pApplicationInfo->applicationVersion, 0); + CORRADE_COMPARE(info->pApplicationInfo->engineVersion, 0); + CORRADE_COMPARE(info->pApplicationInfo->pEngineName, "Magnum"_s); +} + +void InstanceVkTest::createInfoConstructNoImplicitExtensions() { + InstanceCreateInfo info{InstanceCreateInfo::Flag::NoImplicitExtensions}; + CORRADE_VERIFY(info->sType); + CORRADE_VERIFY(!info->pNext); + CORRADE_VERIFY(!info->ppEnabledLayerNames); + CORRADE_COMPARE(info->enabledLayerCount, 0); CORRADE_VERIFY(!info->ppEnabledExtensionNames); CORRADE_COMPARE(info->enabledExtensionCount, 0); @@ -231,7 +248,7 @@ void InstanceVkTest::createInfoLayers() { } void InstanceVkTest::createInfoExtensions() { - InstanceCreateInfo info; + InstanceCreateInfo info{InstanceCreateInfo::Flag::NoImplicitExtensions}; CORRADE_VERIFY(!info->ppEnabledExtensionNames); CORRADE_COMPARE(info->enabledExtensionCount, 0); @@ -259,7 +276,7 @@ void InstanceVkTest::createInfoCopiedStrings() { Containers::StringView globalButNotNullTerminated = "VK_LAYER_KHRONOS_validation3"_s.except(1); Containers::String localButNullTerminated = Extensions::KHR::external_memory_capabilities::string(); - InstanceCreateInfo info; + InstanceCreateInfo info{InstanceCreateInfo::Flag::NoImplicitExtensions}; info.setApplicationInfo(localButNullTerminated, {}) .addEnabledLayers({globalButNotNullTerminated}) .addEnabledExtensions({localButNullTerminated}); @@ -332,7 +349,8 @@ void InstanceVkTest::constructCommandLineDisable() { std::ostringstream out; Warning redirectWarning{&out}; Debug redirectOutput{&out}; - Instance instance{InstanceCreateInfo{Int(data.argsDisable.size()), data.argsDisable} + Instance instance{InstanceCreateInfo{Int(data.argsDisable.size()), data.argsDisable, + InstanceCreateInfo::Flag::NoImplicitExtensions} .setApplicationInfo("InstanceVkTest", version(0, 0, 1)) .addEnabledLayers({"VK_LAYER_KHRONOS_validation"_s}) .addEnabledExtensions