From 81cafc9ddf3f2e9d012cc8b4cc3e861474bf5d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 10 Jul 2020 15:35:37 +0200 Subject: [PATCH] Vk: querying device queue family properties. --- doc/vulkan-mapping.dox | 2 +- src/Magnum/Vk/CMakeLists.txt | 2 +- src/Magnum/Vk/DeviceProperties.cpp | 108 ++++++++++++++++ src/Magnum/Vk/DeviceProperties.h | 118 +++++++++++++++++- .../Vk/Implementation/InstanceState.cpp | 3 + src/Magnum/Vk/Implementation/InstanceState.h | 1 + src/Magnum/Vk/Test/DevicePropertiesTest.cpp | 18 ++- src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp | 73 +++++++++++ src/Magnum/Vk/Vk.h | 5 +- 9 files changed, 324 insertions(+), 6 deletions(-) diff --git a/doc/vulkan-mapping.dox b/doc/vulkan-mapping.dox index 0475c0f96..7013bc575 100644 --- a/doc/vulkan-mapping.dox +++ b/doc/vulkan-mapping.dox @@ -209,7 +209,7 @@ Vulkan function | Matching API @fn_vk{GetPhysicalDeviceImageFormatProperties}, \n @fn_vk{GetPhysicalDeviceImageFormatProperties2} @m_class{m-label m-flat m-success} **KHR, 1.1** | | @fn_vk{GetPhysicalDeviceMemoryProperties}, \n @fn_vk{GetPhysicalDeviceMemoryProperties2} @m_class{m-label m-flat m-success} **KHR, 1.1** | | @fn_vk{GetPhysicalDeviceProperties}, \n @fn_vk{GetPhysicalDeviceProperties2} @m_class{m-label m-flat m-success} **KHR, 1.1** | @ref DeviceProperties -@fn_vk{GetPhysicalDeviceQueueFamilyProperties}, \n @fn_vk{GetPhysicalDeviceQueueFamilyProperties2} @m_class{m-label m-flat m-success} **KHR, 1.1** | | +@fn_vk{GetPhysicalDeviceQueueFamilyProperties}, \n @fn_vk{GetPhysicalDeviceQueueFamilyProperties2} @m_class{m-label m-flat m-success} **KHR, 1.1** | @ref DeviceProperties::queueFamilyProperties() @fn_vk{GetPhysicalDeviceSparseImageFormatProperties}, \n @fn_vk{GetPhysicalDeviceSparseImageFormatProperties2} @m_class{m-label m-flat m-success} **KHR, 1.1** | | @fn_vk{GetPipelineCacheData} | | @fn_vk{GetQueryPoolResults} | | diff --git a/src/Magnum/Vk/CMakeLists.txt b/src/Magnum/Vk/CMakeLists.txt index bde2ccd7f..19a56b0b8 100644 --- a/src/Magnum/Vk/CMakeLists.txt +++ b/src/Magnum/Vk/CMakeLists.txt @@ -27,7 +27,6 @@ find_package(Vulkan REQUIRED) set(MagnumVk_SRCS - DeviceProperties.cpp Extensions.cpp Handle.cpp Instance.cpp @@ -38,6 +37,7 @@ set(MagnumVk_SRCS Implementation/InstanceState.cpp) set(MagnumVk_GracefulAssert_SRCS + DeviceProperties.cpp Enums.cpp ExtensionProperties.cpp LayerProperties.cpp) diff --git a/src/Magnum/Vk/DeviceProperties.cpp b/src/Magnum/Vk/DeviceProperties.cpp index 54ebb33fd..5aabb18e1 100644 --- a/src/Magnum/Vk/DeviceProperties.cpp +++ b/src/Magnum/Vk/DeviceProperties.cpp @@ -26,6 +26,7 @@ #include "DeviceProperties.h" #include +#include #include #include #include @@ -42,6 +43,7 @@ namespace Magnum { namespace Vk { struct DeviceProperties::State { VkPhysicalDeviceProperties2 properties{}; + Containers::Array queueFamilyProperties; }; DeviceProperties::DeviceProperties(NoCreateT) noexcept: _instance{}, _handle{} {} @@ -96,6 +98,84 @@ ExtensionProperties DeviceProperties::enumerateExtensionProperties(std::initiali return enumerateExtensionProperties(Containers::arrayView(layers)); } +Containers::ArrayView DeviceProperties::queueFamilyProperties() { + if(!_state) _state.emplace(); + + /* Fetch if not already */ + if(_state->queueFamilyProperties.empty()) { + UnsignedInt count; + _instance->state().getPhysicalDeviceQueueFamilyPropertiesImplementation(*this, count, nullptr); + + _state->queueFamilyProperties = Containers::Array{Containers::ValueInit, count}; + for(VkQueueFamilyProperties2& i: _state->queueFamilyProperties) + i.sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2; + _instance->state().getPhysicalDeviceQueueFamilyPropertiesImplementation(*this, count, _state->queueFamilyProperties); + CORRADE_INTERNAL_ASSERT(count == _state->queueFamilyProperties.size()); + } + + return _state->queueFamilyProperties; +} + +void DeviceProperties::getQueueFamilyPropertiesImplementationDefault(DeviceProperties& self, UnsignedInt& count, VkQueueFamilyProperties2* properties) { + (**self._instance).GetPhysicalDeviceQueueFamilyProperties(self._handle, &count, reinterpret_cast(properties)); + + /* "Sparsen" the returned data to the version 2 structure layout. If the + pointer is null we were just querying the count. */ + if(properties) { + Containers::ArrayView src{reinterpret_cast(properties), count}; + Containers::ArrayView dst{properties, count}; + /* Go backwards so we don't overwrite the yet-to-be-processed data, + additionally copy the VkQueueFamilyProperties first so we don't + overwrite them by setting sType and pNext. */ + for(std::size_t i = count; i != 0; --i) { + dst[i - 1].queueFamilyProperties = src[i - 1]; + dst[i - 1].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2; + dst[i - 1].pNext = nullptr; + } + } +} + +void DeviceProperties::getQueueFamilyPropertiesImplementationKHR(DeviceProperties& self, UnsignedInt& count, VkQueueFamilyProperties2* properties) { + return (**self._instance).GetPhysicalDeviceQueueFamilyProperties2KHR(self._handle, &count, properties); +} + +void DeviceProperties::getQueueFamilyPropertiesImplementation11(DeviceProperties& self, UnsignedInt& count, VkQueueFamilyProperties2* properties) { + return (**self._instance).GetPhysicalDeviceQueueFamilyProperties2(self._handle, &count, properties); +} + +UnsignedInt DeviceProperties::queueFamilyCount() { + return queueFamilyProperties().size(); +} + +UnsignedInt DeviceProperties::queueFamilySize(const UnsignedInt id) { + const Containers::ArrayView properties = queueFamilyProperties(); + CORRADE_ASSERT(id < properties.size(), + "Vk::DeviceProperties::queueFamilySize(): index" << id << "out of range for" << properties.size() << "entries", {}); + return properties[id].queueFamilyProperties.queueCount; +} + +QueueFlags DeviceProperties::queueFamilyFlags(const UnsignedInt id) { + const Containers::ArrayView properties = queueFamilyProperties(); + CORRADE_ASSERT(id < properties.size(), + "Vk::DeviceProperties::queueFamilyFlags(): index" << id << "out of range for" << properties.size() << "entries", {}); + return QueueFlag(properties[id].queueFamilyProperties.queueFlags); +} + +UnsignedInt DeviceProperties::pickQueueFamily(const QueueFlags flags) { + Containers::Optional id = tryPickQueueFamily(flags); + if(id) return *id; + std::exit(1); /* LCOV_EXCL_LINE */ +} + +Containers::Optional DeviceProperties::tryPickQueueFamily(const QueueFlags flags) { + const Containers::ArrayView properties = queueFamilyProperties(); + for(UnsignedInt i = 0; i != properties.size(); ++i) + if(QueueFlag(properties[i].queueFamilyProperties.queueFlags) >= flags) return i; + + Error{} << "Vk::DeviceProperties::tryPickQueueFamily(): no" << flags << "found among" << properties.size() << "queue families"; + return {}; +} + Containers::Array enumerateDevices(Instance& instance) { /* Retrieve total device count */ UnsignedInt count; @@ -189,4 +269,32 @@ Debug& operator<<(Debug& debug, const DeviceType value) { return debug << "(" << Debug::nospace << Int(value) << Debug::nospace << ")"; } +Debug& operator<<(Debug& debug, const QueueFlag value) { + debug << "Vk::QueueFlag" << Debug::nospace; + + switch(value) { + /* LCOV_EXCL_START */ + #define _c(value) case Vk::QueueFlag::value: return debug << "::" << Debug::nospace << #value; + _c(Graphics) + _c(Compute) + _c(Transfer) + _c(SparseBinding) + _c(Protected) + #undef _c + /* LCOV_EXCL_STOP */ + } + + /* Flag bits should be in hex, unlike plain values */ + return debug << "(" << Debug::nospace << reinterpret_cast(UnsignedInt(value)) << Debug::nospace << ")"; +} + +Debug& operator<<(Debug& debug, const QueueFlags value) { + return Containers::enumSetDebugOutput(debug, value, "Vk::QueueFlags{}", { + Vk::QueueFlag::Graphics, + Vk::QueueFlag::Compute, + Vk::QueueFlag::Transfer, + Vk::QueueFlag::SparseBinding, + Vk::QueueFlag::Protected}); +} + }} diff --git a/src/Magnum/Vk/DeviceProperties.h b/src/Magnum/Vk/DeviceProperties.h index 9ab5caf6d..4e94bbb34 100644 --- a/src/Magnum/Vk/DeviceProperties.h +++ b/src/Magnum/Vk/DeviceProperties.h @@ -26,7 +26,7 @@ */ /** @file - * @brief Class @ref Magnum::Vk::DeviceProperties, enum @ref Magnum::Vk::DeviceType, function @ref Magnum::Vk::enumerateDevices(), @ref Magnum::Vk::pickDevice(), @ref Magnum::Vk::tryPickDevice() + * @brief Class @ref Magnum::Vk::DeviceProperties, enum @ref Magnum::Vk::DeviceType, @ref Magnum::Vk::QueueFlag, enum set @ref Magnum::Vk::QueueFlags, function @ref Magnum::Vk::enumerateDevices(), @ref Magnum::Vk::pickDevice(), @ref Magnum::Vk::tryPickDevice() * @m_since_latest */ @@ -80,12 +80,61 @@ enum class DeviceType: Int { */ MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, DeviceType value); +/** +@brief Queue flag +@m_since_latest + +Wraps a @type_vk_keyword{QueueFlagBits}. +@see @ref QueueFlags, @ref DeviceProperties::queueFamilyFlags() +@m_enum_values_as_keywords +*/ +enum class QueueFlag: UnsignedInt { + /** Supports graphics operations */ + Graphics = VK_QUEUE_GRAPHICS_BIT, + + /** Supports compute operations */ + Compute = VK_QUEUE_COMPUTE_BIT, + + /** Supports transfer operations */ + Transfer = VK_QUEUE_TRANSFER_BIT, + + /** Supports sparse memory management operations */ + SparseBinding = VK_QUEUE_SPARSE_BINDING_BIT, + + /** Supports protected memory operations */ + Protected = VK_QUEUE_PROTECTED_BIT +}; + +/** +@debugoperatorclassenum{DeviceProperties,QueueFlag} +@m_since_latest +*/ +MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, QueueFlag value); + +/** +@brief Queue flags +@m_since_latest + +Type-safe wrapper for @type_vk_keyword{QueueFlags}. +@see @ref DeviceProperties::queueFamilyFlags() +*/ +typedef Containers::EnumSet QueueFlags; + +CORRADE_ENUMSET_OPERATORS(QueueFlags) + +/** +@debugoperatorclassenum{DeviceProperties,QueueFlags} +@m_since_latest +*/ +MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, QueueFlags value); + /** @brief Physical device properties @m_since_latest Wraps a @type_vk_keyword{PhysicalDevice} along with its (lazy-populated) -properties. +properties such as @type_vk_keyword{PhysicalDeviceProperties2} and +@type_vk_keyword{GetPhysicalDeviceQueueFamilyProperties2}. @see @ref enumerateDevices() */ class MAGNUM_VK_EXPORT DeviceProperties { @@ -197,6 +246,67 @@ class MAGNUM_VK_EXPORT DeviceProperties { /** @overload */ ExtensionProperties enumerateExtensionProperties(std::initializer_list layers); + /** + * @brief Queue family properties + * + * Populated lazily on first request. If Vulkan 1.1 or the + * @vk_extension{KHR,get_physical_device_properties2} extension is not + * enabled on the originating instance, only the Vulkan 1.0 subset of + * device properties is queried. + * @see @fn_vk_keyword{GetPhysicalDeviceQueueFamilyProperties2}, + * @fn_vk_keyword{GetPhysicalDeviceQueueFamilyProperties} + */ + Containers::ArrayView queueFamilyProperties(); + + /** + * @brief Queue family count + * + * Convenience access to @ref queueFamilyProperties() internals, + * populated lazily on first request. + */ + UnsignedInt queueFamilyCount(); + + /** + * @brief Queue count in given family + * @param queueFamily Queue family index, expected to be smaller than + * @ref queueFamilyCount() + * + * Convenience access to @ref queueFamilyProperties() internals, + * populated lazily on first request. + */ + UnsignedInt queueFamilySize(UnsignedInt queueFamily); + + /** + * @brief Queue family flags + * @param queueFamily Queue family index, expected to be smaller than + * @ref queueFamilyCount() + * + * Convenience access to @ref queueFamilyProperties() internals, + * populated lazily on first request. + */ + QueueFlags queueFamilyFlags(UnsignedInt queueFamily); + + /** + * @brief Pick a queue family satisfying given flags + * @return Queue family index for use in @ref queueFamilySize() and + * @ref queueFamilyFlags() + * + * Queries queue family properties using @ref queueFamilyProperties() + * and tries to find the first that contains all @p flags. If it is not + * found, exits. See @ref tryPickQueueFamily() for an alternative that + * doesn't exit on failure. + */ + UnsignedInt pickQueueFamily(QueueFlags flags); + + /** + * @brief Try to pick a queue family satisfying given flags + * + * Compared to @ref pickQueueFamily() the function returns + * @ref Containers::NullOpt if a desired family isn't found instead of + * exiting. + */ + Containers::Optional tryPickQueueFamily(QueueFlags flags); + private: friend Implementation::InstanceState; @@ -212,6 +322,10 @@ class MAGNUM_VK_EXPORT DeviceProperties { MAGNUM_VK_LOCAL static void getPropertiesImplementationKHR(DeviceProperties& self, VkPhysicalDeviceProperties2& properties); MAGNUM_VK_LOCAL static void getPropertiesImplementation11(DeviceProperties& self, VkPhysicalDeviceProperties2& properties); + MAGNUM_VK_LOCAL static void getQueueFamilyPropertiesImplementationDefault(DeviceProperties& self, UnsignedInt& count, VkQueueFamilyProperties2* properties); + MAGNUM_VK_LOCAL static void getQueueFamilyPropertiesImplementationKHR(DeviceProperties& self, UnsignedInt& count, VkQueueFamilyProperties2* properties); + MAGNUM_VK_LOCAL static void getQueueFamilyPropertiesImplementation11(DeviceProperties& self, UnsignedInt& count, VkQueueFamilyProperties2* properties); + /* Can't be a reference because of the NoCreate constructor */ Instance* _instance; diff --git a/src/Magnum/Vk/Implementation/InstanceState.cpp b/src/Magnum/Vk/Implementation/InstanceState.cpp index 5c151b5f4..1b780ae73 100644 --- a/src/Magnum/Vk/Implementation/InstanceState.cpp +++ b/src/Magnum/Vk/Implementation/InstanceState.cpp @@ -34,10 +34,13 @@ namespace Magnum { namespace Vk { namespace Implementation { InstanceState::InstanceState(Instance& instance, Int argc, const char** argv): argc{argc}, argv{argv} { if(instance.isVersionSupported(Version::Vk11)) { getPhysicalDevicePropertiesImplementation = &DeviceProperties::getPropertiesImplementation11; + getPhysicalDeviceQueueFamilyPropertiesImplementation = &DeviceProperties::getQueueFamilyPropertiesImplementation11; } else if(instance.isExtensionEnabled()) { getPhysicalDevicePropertiesImplementation = &DeviceProperties::getPropertiesImplementationKHR; + getPhysicalDeviceQueueFamilyPropertiesImplementation = &DeviceProperties::getQueueFamilyPropertiesImplementationKHR; } else { getPhysicalDevicePropertiesImplementation = DeviceProperties::getPropertiesImplementationDefault; + getPhysicalDeviceQueueFamilyPropertiesImplementation = &DeviceProperties::getQueueFamilyPropertiesImplementationDefault; } } diff --git a/src/Magnum/Vk/Implementation/InstanceState.h b/src/Magnum/Vk/Implementation/InstanceState.h index f746de43a..04ff8b61d 100644 --- a/src/Magnum/Vk/Implementation/InstanceState.h +++ b/src/Magnum/Vk/Implementation/InstanceState.h @@ -37,6 +37,7 @@ struct InstanceState { const char** argv; void(*getPhysicalDevicePropertiesImplementation)(DeviceProperties&, VkPhysicalDeviceProperties2&); + void(*getPhysicalDeviceQueueFamilyPropertiesImplementation)(DeviceProperties&, UnsignedInt&, VkQueueFamilyProperties2*); }; }}} diff --git a/src/Magnum/Vk/Test/DevicePropertiesTest.cpp b/src/Magnum/Vk/Test/DevicePropertiesTest.cpp index 3aab323d6..4cce9baba 100644 --- a/src/Magnum/Vk/Test/DevicePropertiesTest.cpp +++ b/src/Magnum/Vk/Test/DevicePropertiesTest.cpp @@ -38,13 +38,17 @@ struct DevicePropertiesTest: TestSuite::Tester { void constructCopy(); void debugDeviceType(); + void debugQueueFamilyPropertiesFlag(); + void debugQueueFamilyPropertiesFlags(); }; DevicePropertiesTest::DevicePropertiesTest() { addTests({&DevicePropertiesTest::constructNoCreate, &DevicePropertiesTest::constructCopy, - &DevicePropertiesTest::debugDeviceType}); + &DevicePropertiesTest::debugDeviceType, + &DevicePropertiesTest::debugQueueFamilyPropertiesFlag, + &DevicePropertiesTest::debugQueueFamilyPropertiesFlags}); } void DevicePropertiesTest::constructNoCreate() { @@ -68,6 +72,18 @@ void DevicePropertiesTest::debugDeviceType() { CORRADE_COMPARE(out.str(), "Vk::DeviceType::DiscreteGpu Vk::DeviceType(-10007655)\n"); } +void DevicePropertiesTest::debugQueueFamilyPropertiesFlag() { + std::ostringstream out; + Debug{&out} << QueueFlag::SparseBinding << QueueFlag(0xdeadcafe); + CORRADE_COMPARE(out.str(), "Vk::QueueFlag::SparseBinding Vk::QueueFlag(0xdeadcafe)\n"); +} + +void DevicePropertiesTest::debugQueueFamilyPropertiesFlags() { + std::ostringstream out; + Debug{&out} << (QueueFlag::Compute|QueueFlag::Graphics) << QueueFlags{}; + CORRADE_COMPARE(out.str(), "Vk::QueueFlag::Graphics|Vk::QueueFlag::Compute Vk::QueueFlags{}\n"); +} + }}}} CORRADE_TEST_MAIN(Magnum::Vk::Test::DevicePropertiesTest) diff --git a/src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp b/src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp index 2a6d6f765..339622c7b 100644 --- a/src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp +++ b/src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp @@ -60,6 +60,11 @@ struct DevicePropertiesVkTest: TestSuite::Tester { void extensionIsSupported(); void extensionNamedRevision(); + void queueFamilies(); + void queueFamiliesOutOfRange(); + void queueFamiliesPick(); + void queueFamiliesPickFailed(); + void pickDevice(); void pickDeviceIndex(); void pickDeviceType(); @@ -94,6 +99,11 @@ DevicePropertiesVkTest::DevicePropertiesVkTest(): _instance{InstanceCreateInfo{a &DevicePropertiesVkTest::extensionIsSupported, &DevicePropertiesVkTest::extensionNamedRevision, + &DevicePropertiesVkTest::queueFamilies, + &DevicePropertiesVkTest::queueFamiliesOutOfRange, + &DevicePropertiesVkTest::queueFamiliesPick, + &DevicePropertiesVkTest::queueFamiliesPickFailed, + &DevicePropertiesVkTest::pickDevice, &DevicePropertiesVkTest::pickDeviceIndex, &DevicePropertiesVkTest::pickDeviceType}); @@ -254,6 +264,69 @@ void DevicePropertiesVkTest::extensionNamedRevision() { TestSuite::Compare::GreaterOrEqual); } +void DevicePropertiesVkTest::queueFamilies() { + Containers::Array devices = enumerateDevices(_instance); + CORRADE_VERIFY(!devices.empty()); + + Debug{} << "Available queue family count:" << devices[0].queueFamilyCount(); + + CORRADE_COMPARE_AS(devices[0].queueFamilyCount(), 0, + TestSuite::Compare::Greater); + + for(std::size_t i = 0; i != devices[0].queueFamilyCount(); ++i) { + CORRADE_ITERATION(i); + CORRADE_ITERATION(devices[0].queueFamilyFlags(i)); + + CORRADE_VERIFY(devices[0].queueFamilyFlags(i) != QueueFlags{}); + CORRADE_COMPARE(devices[0].queueFamilyFlags(i), QueueFlag(devices[0].queueFamilyProperties()[i].queueFamilyProperties.queueFlags)); + + CORRADE_COMPARE_AS(devices[0].queueFamilySize(i), 0, + TestSuite::Compare::Greater); + CORRADE_COMPARE(devices[0].queueFamilySize(i), devices[0].queueFamilyProperties()[i].queueFamilyProperties.queueCount); + } +} + +void DevicePropertiesVkTest::queueFamiliesOutOfRange() { + Containers::Array devices = enumerateDevices(_instance); + CORRADE_VERIFY(!devices.empty()); + + const UnsignedInt count = devices[0].queueFamilyCount(); + + std::ostringstream out; + Error redirectError{&out}; + devices[0].queueFamilySize(count); + devices[0].queueFamilyFlags(count); + CORRADE_COMPARE(out.str(), Utility::formatString( + "Vk::DeviceProperties::queueFamilySize(): index {0} out of range for {0} entries\n" + "Vk::DeviceProperties::queueFamilyFlags(): index {0} out of range for {0} entries\n", count)); +} + +void DevicePropertiesVkTest::queueFamiliesPick() { + Containers::Array devices = enumerateDevices(_instance); + CORRADE_VERIFY(!devices.empty()); + + Containers::Optional id = devices[0].tryPickQueueFamily(QueueFlag::Compute|QueueFlag::Graphics); + CORRADE_VERIFY(id); + CORRADE_COMPARE_AS(*id, devices[0].queueFamilyCount(), TestSuite::Compare::Less); + CORRADE_COMPARE_AS(devices[0].queueFamilyFlags(*id), + QueueFlag::Compute|QueueFlag::Graphics, + TestSuite::Compare::GreaterOrEqual); + + /* Pick should return the same ID, and shouldn't exit */ + CORRADE_COMPARE(devices[0].pickQueueFamily(QueueFlag::Compute|QueueFlag::Graphics), id); +} + +void DevicePropertiesVkTest::queueFamiliesPickFailed() { + Containers::Array devices = enumerateDevices(_instance); + CORRADE_VERIFY(!devices.empty()); + + std::ostringstream out; + Error redirectError{&out}; + CORRADE_VERIFY(!devices[0].tryPickQueueFamily(QueueFlag(0xc0ffeee0))); + CORRADE_COMPARE(out.str(), Utility::formatString( + "Vk::DeviceProperties::tryPickQueueFamily(): no Vk::QueueFlag(0xc0ffeee0) found among {} queue families\n", devices[0].queueFamilyCount())); +} + void DevicePropertiesVkTest::pickDevice() { /* Default behavior */ Containers::Optional device = tryPickDevice(_instance); diff --git a/src/Magnum/Vk/Vk.h b/src/Magnum/Vk/Vk.h index 5fe7b1ca4..1b618f40e 100644 --- a/src/Magnum/Vk/Vk.h +++ b/src/Magnum/Vk/Vk.h @@ -29,6 +29,8 @@ * @brief Forward declarations for the @ref Magnum::Vk namespace */ +#include + #include "Magnum/Magnum.h" namespace Magnum { namespace Vk { @@ -45,7 +47,8 @@ class InstanceCreateInfo; class InstanceExtension; class InstanceExtensionProperties; class LayerProperties; - +enum class QueueFlag: UnsignedInt; +typedef Containers::EnumSet QueueFlags; enum class Result: Int; enum class Version: UnsignedInt; #endif