mirror of https://github.com/mosra/magnum.git
23 changed files with 338 additions and 1 deletions
@ -0,0 +1,292 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, |
||||
2020 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <Corrade/Utility/Arguments.h> |
||||
|
||||
#include "Magnum/Vk/Extensions.h" |
||||
#include "Magnum/Vk/ExtensionProperties.h" |
||||
#include "Magnum/Vk/Instance.h" |
||||
#include "Magnum/Vk/LayerProperties.h" |
||||
#include "Magnum/Vk/DeviceProperties.h" |
||||
#include "Magnum/Vk/Version.h" |
||||
|
||||
namespace Magnum { |
||||
|
||||
/** @page magnum-vk-info Magnum Vulkan Info
|
||||
@brief Displays information about Magnum engine Vulkan capabilities |
||||
|
||||
@m_footernavigation |
||||
@m_keywords{magnum-vk-info vk-info} |
||||
|
||||
This utility is built if both `WITH_VK` and `WITH_VK_INFO` is enabled when |
||||
building Magnum. To use this utility with CMake, you need to request the |
||||
`vk-info` component of the `Magnum` package and use the `Magnum::vk-info` |
||||
target for example in a custom command: |
||||
|
||||
@code{.cmake} |
||||
find_package(Magnum REQUIRED vk-info) |
||||
|
||||
add_custom_command(OUTPUT ... COMMAND Magnum::vk-info ...) |
||||
@endcode |
||||
|
||||
See @ref building, @ref cmake and the @ref Vk namespace for more information. |
||||
*/ |
||||
|
||||
} |
||||
|
||||
using namespace Magnum; |
||||
|
||||
int main(int argc, char** argv) { |
||||
Utility::Arguments args; |
||||
args.addBooleanOption("extension-strings").setHelp("extension-strings", "list all extension strings provided by the driver") |
||||
.addBooleanOption("all-extensions").setHelp("all-extensions", "display extensions also for fully supported versions") |
||||
.addSkippedPrefix("magnum", "engine-specific options") |
||||
.setGlobalHelp("Displays information about Magnum engine and Vulkan capabilities.") |
||||
.parse(argc, argv); |
||||
|
||||
/* Setup InstanceCreateInfo before printing anything so --magnum-help has
|
||||
uncluttered output */ |
||||
/** @todo add a NoCreate InstanceInfo that just populates internal state
|
||||
without querying vulkan for anything? or that's stupid? */ |
||||
Vk::LayerProperties layerProperties = Vk::enumerateLayerProperties(); |
||||
Vk::InstanceExtensionProperties instanceExtensionProperties = Vk::enumerateInstanceExtensionProperties({layerProperties.names()}); |
||||
|
||||
Vk::InstanceCreateInfo instanceCreateInfo{argc, argv, &layerProperties, &instanceExtensionProperties}; |
||||
|
||||
Debug{} << ""; |
||||
Debug{} << " +---------------------------------------------------------+"; |
||||
Debug{} << " | Information about Magnum engine Vulkan capabilities |"; |
||||
Debug{} << " +---------------------------------------------------------+"; |
||||
Debug{} << ""; |
||||
|
||||
Debug{} << "Compilation flags:"; |
||||
#ifdef CORRADE_BUILD_DEPRECATED |
||||
Debug{} << " CORRADE_BUILD_DEPRECATED"; |
||||
#endif |
||||
#ifdef CORRADE_BUILD_STATIC |
||||
Debug{} << " CORRADE_BUILD_STATIC"; |
||||
#endif |
||||
#ifdef CORRADE_BUILD_MULTITHREADED |
||||
Debug{} << " CORRADE_BUILD_MULTITHREADED"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_UNIX |
||||
Debug{} << " CORRADE_TARGET_UNIX"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_APPLE |
||||
Debug{} << " CORRADE_TARGET_APPLE"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_IOS |
||||
Debug{} << " CORRADE_TARGET_IOS"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_WINDOWS |
||||
Debug{} << " CORRADE_TARGET_WINDOWS"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_WINDOWS_RT |
||||
Debug{} << " CORRADE_TARGET_WINDOWS_RT"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_ANDROID |
||||
Debug{} << " CORRADE_TARGET_ANDROID"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_X86 |
||||
Debug{} << " CORRADE_TARGET_X86"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_ARM |
||||
Debug{} << " CORRADE_TARGET_ARM"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_POWERPC |
||||
Debug{} << " CORRADE_TARGET_POWERPC"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_BIG_ENDIAN |
||||
Debug{} << " CORRADE_TARGET_BIG_ENDIAN"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_GCC |
||||
Debug{} << " CORRADE_TARGET_GCC"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_CLANG |
||||
Debug{} << " CORRADE_TARGET_CLANG"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_APPLE_CLANG |
||||
Debug{} << " CORRADE_TARGET_APPLE_CLANG"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_CLANG_CL |
||||
Debug{} << " CORRADE_TARGET_CLANG_CL"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_MSVC |
||||
Debug{} << " CORRADE_TARGET_MSVC"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_MINGW |
||||
Debug{} << " CORRADE_TARGET_MINGW"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_LIBCXX |
||||
Debug{} << " CORRADE_TARGET_LIBCXX"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_LIBSTDCXX |
||||
Debug{} << " CORRADE_TARGET_LIBSTDCXX"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_DINKUMWARE |
||||
Debug{} << " CORRADE_TARGET_DINKUMWARE"; |
||||
#endif |
||||
#ifdef CORRADE_TARGET_SSE2 |
||||
Debug{} << " CORRADE_TARGET_SSE2"; |
||||
#endif |
||||
#ifdef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT |
||||
Debug{} << " CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT"; |
||||
#endif |
||||
#ifdef CORRADE_TESTSUITE_TARGET_XCTEST |
||||
Debug{} << " CORRADE_TESTSUITE_TARGET_XCTEST"; |
||||
#endif |
||||
#ifdef CORRADE_UTILITY_USE_ANSI_COLORS |
||||
Debug{} << " CORRADE_UTILITY_USE_ANSI_COLORS"; |
||||
#endif |
||||
#ifdef MAGNUM_BUILD_DEPRECATED |
||||
Debug{} << " MAGNUM_BUILD_DEPRECATED"; |
||||
#endif |
||||
#ifdef MAGNUM_BUILD_STATIC |
||||
Debug{} << " MAGNUM_BUILD_STATIC"; |
||||
#endif |
||||
Debug{} << ""; |
||||
|
||||
const Vk::Version version = Vk::enumerateInstanceVersion(); |
||||
Debug{} << "Reported instance version:" << version; |
||||
Debug{} << "Reported instance layers:"; |
||||
for(UnsignedInt i = 0, max = layerProperties.count(); i != max; ++i) { |
||||
Debug{} << " " << layerProperties.name(i) << "(r" << Debug::nospace << layerProperties.revision(i) << Debug::nospace << ", written against" << layerProperties.version(i) << Debug::nospace << ")"; |
||||
Debug{} << " " << layerProperties.description(i); |
||||
} |
||||
|
||||
constexpr Vk::Version versions[]{ |
||||
Vk::Version::Vk11, |
||||
Vk::Version::Vk12, |
||||
Vk::Version::None |
||||
}; |
||||
std::size_t future = 0; |
||||
|
||||
if(!args.isSet("all-extensions")) |
||||
while(versions[future] != Vk::Version::None && version >= versions[future]) |
||||
++future; |
||||
|
||||
/** @todo do better once implemented in format() */ |
||||
using namespace Containers::Literals; |
||||
constexpr Containers::StringView sixtyfourSpaces = " "_s; |
||||
|
||||
if(args.isSet("extension-strings")) { |
||||
Debug{} << "Reported instance extension strings:"; |
||||
for(std::size_t i = 0, max = instanceExtensionProperties.count(); i != max; ++i) { |
||||
Debug d; |
||||
d << " " << instanceExtensionProperties.name(i) << "(r" << Debug::nospace << instanceExtensionProperties.revision(i) << Debug::nospace; |
||||
const UnsignedInt layer = instanceExtensionProperties.layer(i); |
||||
if(layer != 0) |
||||
d << ", from" << layerProperties.names()[layer - 1] << Debug::nospace; |
||||
d << ")"; |
||||
} |
||||
|
||||
} else for(std::size_t i = future; i != Containers::arraySize(versions); ++i) { |
||||
Containers::ArrayView<const Vk::InstanceExtension> extensions = Vk::InstanceExtension::extensions(versions[i]); |
||||
if(extensions.empty()) continue; |
||||
|
||||
if(versions[i] != Vk::Version::None) |
||||
Debug{} << versions[i] << "instance extension support:"; |
||||
else Debug{} << "Vendor instance extension support:"; |
||||
|
||||
for(const Vk::InstanceExtension& extension: extensions) { |
||||
Debug d; |
||||
d << " " << extension.string() << sixtyfourSpaces.prefix(64 - extension.string().size()); |
||||
|
||||
if(instanceExtensionProperties.isSupported(extension)) |
||||
d << "REV." << Debug::nospace << instanceExtensionProperties.revision(extension); |
||||
else if(version >= extension.requiredVersion()) |
||||
d << " -"; |
||||
else |
||||
d << " n/a"; |
||||
} |
||||
} |
||||
|
||||
Debug{} << ""; |
||||
|
||||
Vk::Instance instance{instanceCreateInfo}; |
||||
|
||||
{ |
||||
Containers::Array<Vk::DeviceProperties> devices = Vk::enumerateDevices(instance); |
||||
Debug{} << "Found" << devices.size() << "devices:"; |
||||
for(Vk::DeviceProperties& device: devices) { |
||||
Debug{} << " " << device.name() << Debug::nospace << "," |
||||
<< device.apiVersion() << Debug::newline |
||||
<< " " << device.type() << Debug::nospace << ", driver" |
||||
<< Debug::packed << device.driverVersion(); |
||||
} |
||||
|
||||
if(devices.empty()) return 0; |
||||
} |
||||
|
||||
Debug{} << ""; |
||||
|
||||
Vk::DeviceProperties device = Vk::pickDevice(instance); |
||||
|
||||
Debug{} << "Picked device" << device.name() << Debug::newline; |
||||
Debug{} << "Reported version:" << device.apiVersion(); |
||||
|
||||
Vk::ExtensionProperties extensionProperties = device.enumerateExtensionProperties(layerProperties.names()); |
||||
|
||||
if(args.isSet("extension-strings")) { |
||||
Debug{} << "Reported extension strings:"; |
||||
for(std::size_t i = 0, max = extensionProperties.count(); i != max; ++i) { |
||||
Debug d; |
||||
d << " " << extensionProperties.name(i) << "(r" << Debug::nospace << extensionProperties.revision(i) << Debug::nospace; |
||||
const UnsignedInt layer = extensionProperties.layer(i); |
||||
if(layer != 0) |
||||
d << ", from" << layerProperties.names()[layer - 1] << Debug::nospace; |
||||
d << ")"; |
||||
} |
||||
|
||||
} else for(std::size_t i = future; i != Containers::arraySize(versions); ++i) { |
||||
Containers::ArrayView<const Vk::Extension> extensions = Vk::Extension::extensions(versions[i]); |
||||
if(extensions.empty()) continue; |
||||
|
||||
if(versions[i] != Vk::Version::None) |
||||
Debug{} << versions[i] << "extension support:"; |
||||
else Debug{} << "Vendor extension support:"; |
||||
|
||||
for(const Vk::Extension& extension: extensions) { |
||||
Debug d; |
||||
d << " " << extension.string() << sixtyfourSpaces.prefix(64 - extension.string().size()); |
||||
|
||||
if(extensionProperties.isSupported(extension)) |
||||
d << "REV." << Debug::nospace << extensionProperties.revision(extension); |
||||
else if(version >= extension.requiredVersion()) |
||||
d << " -"; |
||||
else |
||||
d << " n/a"; |
||||
} |
||||
} |
||||
|
||||
/* If we wanted only extension strings, exit now */ |
||||
if(args.isSet("extension-strings")) return 0; |
||||
|
||||
Debug{} << "Queue families:"; |
||||
for(UnsignedInt i = 0; i != device.queueFamilyCount(); ++i) { |
||||
Debug{} << " " << i << Debug::nospace << ":" << device.queueFamilyFlags(i); |
||||
Debug{} << " " << device.queueFamilySize(i) << "queues"; |
||||
} |
||||
} |
||||
Loading…
Reference in new issue