Browse Source

Vk: use StringIterable in internal Instance/Device extension init.

This significantly simplifies everything -- because a single type can
now handle both StringView lists and char* lists, we no longer need a
templated private helper to avoid allocating a temporary array of
unified type. Instead, the whole extension initialization can be done
directly in the initialize() helper, by simply iterating over the
argument.

Yay, this is probably the nicest improvement caused by StringIterable so
far.
pull/605/head
Vladimír Vondruš 4 years ago
parent
commit
bc2ad2e14e
  1. 17
      src/Magnum/Vk/Device.cpp
  2. 3
      src/Magnum/Vk/Device.h
  3. 19
      src/Magnum/Vk/Instance.cpp
  4. 3
      src/Magnum/Vk/Instance.h

17
src/Magnum/Vk/Device.cpp

@ -31,6 +31,7 @@
#include <Corrade/Containers/GrowableArray.h> #include <Corrade/Containers/GrowableArray.h>
#include <Corrade/Containers/StaticArray.h> #include <Corrade/Containers/StaticArray.h>
#include <Corrade/Containers/String.h> #include <Corrade/Containers/String.h>
#include <Corrade/Containers/StringIterable.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Corrade/Utility/Algorithms.h> #include <Corrade/Utility/Algorithms.h>
#include <Corrade/Utility/Arguments.h> #include <Corrade/Utility/Arguments.h>
@ -669,12 +670,11 @@ void Device::wrap(Instance& instance, const VkPhysicalDevice physicalDevice, con
_handle = handle; _handle = handle;
_flags = flags; _flags = flags;
_properties.emplace(DeviceProperties::wrap(instance, physicalDevice)); _properties.emplace(DeviceProperties::wrap(instance, physicalDevice));
initializeExtensions(enabledExtensions);
/* Because we have no control over extensions / features, no workarounds /* Because we have no control over extensions / features, no workarounds
are used here -- better to just do nothing than just a partial attempt */ are used here -- better to just do nothing than just a partial attempt */
Containers::Array<std::pair<Containers::StringView, bool>> encounteredWorkarounds = Implementation::disableAllWorkarounds(); Containers::Array<std::pair<Containers::StringView, bool>> encounteredWorkarounds = Implementation::disableAllWorkarounds();
initialize(instance, version, encounteredWorkarounds, enabledFeatures); initialize(instance, version, enabledExtensions, encounteredWorkarounds, enabledFeatures);
} }
void Device::wrap(Instance& instance, const VkPhysicalDevice physicalDevice, const VkDevice handle, const Version version, const std::initializer_list<Containers::StringView> enabledExtensions, const DeviceFeatures& enabledFeatures, const HandleFlags flags) { void Device::wrap(Instance& instance, const VkPhysicalDevice physicalDevice, const VkDevice handle, const Version version, const std::initializer_list<Containers::StringView> enabledExtensions, const DeviceFeatures& enabledFeatures, const HandleFlags flags) {
@ -782,8 +782,7 @@ Result Device::tryCreateInternal(Instance& instance, const DeviceCreateInfo& inf
/* Initialize the enabled extension list and feature-, extension-, /* Initialize the enabled extension list and feature-, extension-,
workaround-dependent function pointers */ workaround-dependent function pointers */
initializeExtensions<const char*>({info->ppEnabledExtensionNames, info->enabledExtensionCount}); initialize(instance, version, Containers::arrayView(info->ppEnabledExtensionNames, info->enabledExtensionCount), encounteredWorkarounds, info._state->enabledFeatures | info._state->implicitFeatures);
initialize(instance, version, encounteredWorkarounds, info._state->enabledFeatures | info._state->implicitFeatures);
/* Print a list of used workarounds */ /* Print a list of used workarounds */
if(!info._state->quietLog) { if(!info._state->quietLog) {
@ -852,22 +851,20 @@ Result Device::tryCreateInternal(Instance& instance, const DeviceCreateInfo& inf
return Result::Success; return Result::Success;
} }
template<class T> void Device::initializeExtensions(const Containers::ArrayView<const T> enabledExtensions) { void Device::initialize(Instance& instance, const Version version, const Containers::StringIterable& enabledExtensions, Containers::Array<std::pair<Containers::StringView, bool>>& encounteredWorkarounds, const DeviceFeatures& enabledFeatures) {
/* Mark all known extensions as enabled */ /* Mark all known extensions as enabled */
for(const T extension: enabledExtensions) { for(const Containers::StringView extension: enabledExtensions) {
for(const Version version: KnownVersionsForExtensions) { for(const Version version: KnownVersionsForExtensions) {
const Containers::ArrayView<const Extension> knownExtensions = const Containers::ArrayView<const Extension> knownExtensions =
Extension::extensions(version); Extension::extensions(version);
const auto found = std::lower_bound(knownExtensions.begin(), knownExtensions.end(), extension, [](const Extension& a, const T& b) { const auto found = std::lower_bound(knownExtensions.begin(), knownExtensions.end(), extension, [](const Extension& a, Containers::StringView b) {
return a.string() < static_cast<const Containers::StringView&>(b); return a.string() < b;
}); });
if(found == knownExtensions.end() || found->string() != extension) continue; if(found == knownExtensions.end() || found->string() != extension) continue;
_enabledExtensions.set(found->index(), true); _enabledExtensions.set(found->index(), true);
} }
} }
}
void Device::initialize(Instance& instance, const Version version, Containers::Array<std::pair<Containers::StringView, bool>>& encounteredWorkarounds, const DeviceFeatures& enabledFeatures) {
/* Init version, features, function pointers */ /* Init version, features, function pointers */
_version = version; _version = version;
_enabledFeatures = enabledFeatures; _enabledFeatures = enabledFeatures;

3
src/Magnum/Vk/Device.h

@ -502,8 +502,7 @@ class MAGNUM_VK_EXPORT Device {
tryCreate(Instance&, DeviceCreateInfo&&) */ tryCreate(Instance&, DeviceCreateInfo&&) */
Result tryCreateInternal(Instance& isntance, const DeviceCreateInfo&, DeviceProperties&&); Result tryCreateInternal(Instance& isntance, const DeviceCreateInfo&, DeviceProperties&&);
template<class T> MAGNUM_VK_LOCAL void initializeExtensions(Containers::ArrayView<const T> enabledExtensions); MAGNUM_VK_LOCAL void initialize(Instance& instance, Version version, const Containers::StringIterable& enabledExtensions, Containers::Array<std::pair<Containers::StringView, bool>>& encounteredWorkarounds, const DeviceFeatures& enabledFeatures);
MAGNUM_VK_LOCAL void initialize(Instance& instance, Version version, Containers::Array<std::pair<Containers::StringView, bool>>& encounteredWorkarounds, const DeviceFeatures& enabledFeatures);
MAGNUM_VK_LOCAL static void getQueueImplementationDefault(Device& self, const VkDeviceQueueInfo2& info, VkQueue& queue); MAGNUM_VK_LOCAL static void getQueueImplementationDefault(Device& self, const VkDeviceQueueInfo2& info, VkQueue& queue);
MAGNUM_VK_LOCAL static void getQueueImplementation11(Device& self, const VkDeviceQueueInfo2& info, VkQueue& queue); MAGNUM_VK_LOCAL static void getQueueImplementation11(Device& self, const VkDeviceQueueInfo2& info, VkQueue& queue);

19
src/Magnum/Vk/Instance.cpp

@ -30,6 +30,7 @@
#include <Corrade/Containers/Optional.h> #include <Corrade/Containers/Optional.h>
#include <Corrade/Containers/GrowableArray.h> #include <Corrade/Containers/GrowableArray.h>
#include <Corrade/Containers/String.h> #include <Corrade/Containers/String.h>
#include <Corrade/Containers/StringIterable.h>
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include <Corrade/Utility/Arguments.h> #include <Corrade/Utility/Arguments.h>
@ -272,8 +273,7 @@ void Instance::wrap(const VkInstance handle, const Version version, const Contai
repeating what was passed to the constructor */ repeating what was passed to the constructor */
_handle = handle; _handle = handle;
_flags = flags; _flags = flags;
initializeExtensions(enabledExtensions); initialize(version, enabledExtensions, 0, nullptr);
initialize(version, 0, nullptr);
} }
void Instance::wrap(const VkInstance handle, const Version version, const std::initializer_list<Containers::StringView> enabledExtensions, const HandleFlags flags) { void Instance::wrap(const VkInstance handle, const Version version, const std::initializer_list<Containers::StringView> enabledExtensions, const HandleFlags flags) {
@ -333,11 +333,10 @@ Result Instance::tryCreate(const InstanceCreateInfo& info) {
return Result(result); return Result(result);
} }
initializeExtensions<const char*>({info->ppEnabledExtensionNames, info->enabledExtensionCount});
if(info._state) if(info._state)
initialize(version, info._state->argc, info._state->argv); initialize(version, Containers::arrayView(info->ppEnabledExtensionNames, info->enabledExtensionCount), info._state->argc, info._state->argv);
else else
initialize(version, 0, nullptr); initialize(version, Containers::arrayView(info->ppEnabledExtensionNames, info->enabledExtensionCount), 0, nullptr);
return Result::Success; return Result::Success;
} }
@ -346,25 +345,23 @@ Result Instance::tryCreate() {
return tryCreate(InstanceCreateInfo{}); return tryCreate(InstanceCreateInfo{});
} }
template<class T> void Instance::initializeExtensions(const Containers::ArrayView<const T> enabledExtensions) { void Instance::initialize(const Version version, const Containers::StringIterable& enabledExtensions, const Int argc, const char* const* const argv) {
/* Mark all known extensions as enabled */ /* Mark all known extensions as enabled */
for(const T extension: enabledExtensions) { for(const Containers::StringView extension: enabledExtensions) {
for(Containers::ArrayView<const InstanceExtension> knownExtensions: { for(Containers::ArrayView<const InstanceExtension> knownExtensions: {
InstanceExtension::extensions(Version::None), InstanceExtension::extensions(Version::None),
/*InstanceExtension::extensions(Version::Vk10), is empty */ /*InstanceExtension::extensions(Version::Vk10), is empty */
InstanceExtension::extensions(Version::Vk11), InstanceExtension::extensions(Version::Vk11),
/*InstanceExtension::extensions(Version::Vk12) is empty */ /*InstanceExtension::extensions(Version::Vk12) is empty */
}) { }) {
const auto found = std::lower_bound(knownExtensions.begin(), knownExtensions.end(), extension, [](const InstanceExtension& a, const T& b) { const auto found = std::lower_bound(knownExtensions.begin(), knownExtensions.end(), extension, [](const InstanceExtension& a, Containers::StringView b) {
return a.string() < static_cast<const Containers::StringView&>(b); return a.string() < b;
}); });
if(found == knownExtensions.end() || found->string() != extension) continue; if(found == knownExtensions.end() || found->string() != extension) continue;
_extensionStatus.set(found->index(), true); _extensionStatus.set(found->index(), true);
} }
} }
}
void Instance::initialize(const Version version, const Int argc, const char* const* const argv) {
/* Init version, function pointers */ /* Init version, function pointers */
_version = version; _version = version;
flextVkInitInstance(_handle, &_functionPointers); flextVkInitInstance(_handle, &_functionPointers);

3
src/Magnum/Vk/Instance.h

@ -435,8 +435,7 @@ class MAGNUM_VK_EXPORT Instance {
Implementation::InstanceState& state() { return *_state; } Implementation::InstanceState& state() { return *_state; }
private: private:
template<class T> MAGNUM_VK_LOCAL void initializeExtensions(Containers::ArrayView<const T> enabledExtensions); MAGNUM_VK_LOCAL void initialize(Version version, const Containers::StringIterable& enabledExtensions, Int argc, const char* const* argv);
MAGNUM_VK_LOCAL void initialize(Version version, Int argc, const char* const* argv);
VkInstance _handle; VkInstance _handle;
HandleFlags _flags; HandleFlags _flags;

Loading…
Cancel
Save