Browse Source

Vk: implement VK_KHR_driver_properties.

I'm a bit unsure why there's a device extension that actually gets used
on an instance and doesn't need any enabling (and thus there's
currently no way to disable it to test all code paths, hmm).
pull/234/head
Vladimír Vondruš 6 years ago
parent
commit
8c1b85f519
  1. 2
      doc/vulkan-support.dox
  2. 61
      src/Magnum/Vk/DeviceProperties.cpp
  3. 136
      src/Magnum/Vk/DeviceProperties.h
  4. 8
      src/Magnum/Vk/Test/DevicePropertiesTest.cpp
  5. 27
      src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp
  6. 13
      src/Magnum/Vk/vk-info.cpp

2
doc/vulkan-support.dox

@ -96,7 +96,7 @@ Extension | Status
@vk_extension{KHR,shader_subgroup_extended_types} | | @vk_extension{KHR,shader_subgroup_extended_types} | |
@vk_extension{KHR,8bit_storage} | | @vk_extension{KHR,8bit_storage} | |
@vk_extension{KHR,shader_atomic_int64} | | @vk_extension{KHR,shader_atomic_int64} | |
@vk_extension{KHR,driver_properties} | | @vk_extension{KHR,driver_properties} | mostly
@vk_extension{KHR,shader_float_controls} | | @vk_extension{KHR,shader_float_controls} | |
@vk_extension{KHR,depth_stencil_resolve} | | @vk_extension{KHR,depth_stencil_resolve} | |
@vk_extension{KHR,timeline_semaphore} | | @vk_extension{KHR,timeline_semaphore} | |

61
src/Magnum/Vk/DeviceProperties.cpp

@ -33,11 +33,13 @@
#include <Corrade/Utility/Debug.h> #include <Corrade/Utility/Debug.h>
#include "Magnum/Math/Functions.h" #include "Magnum/Math/Functions.h"
#include "Magnum/Vk/Instance.h"
#include "Magnum/Vk/ExtensionProperties.h" #include "Magnum/Vk/ExtensionProperties.h"
#include "Magnum/Vk/Extensions.h"
#include "Magnum/Vk/Instance.h"
#include "Magnum/Vk/LayerProperties.h" #include "Magnum/Vk/LayerProperties.h"
#include "Magnum/Vk/Memory.h" #include "Magnum/Vk/Memory.h"
#include "Magnum/Vk/Result.h" #include "Magnum/Vk/Result.h"
#include "Magnum/Vk/Version.h"
#include "Magnum/Vk/Implementation/Arguments.h" #include "Magnum/Vk/Implementation/Arguments.h"
#include "Magnum/Vk/Implementation/InstanceState.h" #include "Magnum/Vk/Implementation/InstanceState.h"
@ -45,6 +47,7 @@ namespace Magnum { namespace Vk {
struct DeviceProperties::State { struct DeviceProperties::State {
VkPhysicalDeviceProperties2 properties{}; VkPhysicalDeviceProperties2 properties{};
VkPhysicalDeviceDriverProperties driverProperties{};
VkPhysicalDeviceMemoryProperties2 memoryProperties{}; VkPhysicalDeviceMemoryProperties2 memoryProperties{};
Containers::Array<VkQueueFamilyProperties2> queueFamilyProperties; Containers::Array<VkQueueFamilyProperties2> queueFamilyProperties;
}; };
@ -65,6 +68,21 @@ Containers::StringView DeviceProperties::name() {
return properties().properties.deviceName; return properties().properties.deviceName;
} }
DeviceDriver DeviceProperties::driver() {
/* Ensure the values are populated first */
return properties(), DeviceDriver(_state->driverProperties.driverID);
}
Containers::StringView DeviceProperties::driverName() {
/* Ensure the values are populated first */
return properties(), _state->driverProperties.driverName;
}
Containers::StringView DeviceProperties::driverInfo() {
/* Ensure the values are populated first */
return properties(), _state->driverProperties.driverInfo;
}
const VkPhysicalDeviceProperties2& DeviceProperties::properties() { const VkPhysicalDeviceProperties2& DeviceProperties::properties() {
if(!_state) _state.emplace(); if(!_state) _state.emplace();
@ -72,6 +90,18 @@ const VkPhysicalDeviceProperties2& DeviceProperties::properties() {
if(!_state->properties.sType) { if(!_state->properties.sType) {
_state->properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; _state->properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
Containers::Reference<void*> next = _state->properties.pNext;
/* Device extension properties. Populated only if needed. */
ExtensionProperties extensions{NoCreate};
/* Fetch driver properties, if supported */
if(_instance->isVersionSupported(Version::Vk12) || (extensions = enumerateExtensionProperties()).isSupported<Extensions::KHR::driver_properties>()) {
*next = &_state->driverProperties;
next = _state->driverProperties.pNext;
_state->driverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
}
_instance->state().getPhysicalDevicePropertiesImplementation(*this, _state->properties); _instance->state().getPhysicalDevicePropertiesImplementation(*this, _state->properties);
} }
@ -378,6 +408,35 @@ Debug& operator<<(Debug& debug, const DeviceType value) {
return debug << "(" << Debug::nospace << Int(value) << Debug::nospace << ")"; return debug << "(" << Debug::nospace << Int(value) << Debug::nospace << ")";
} }
Debug& operator<<(Debug& debug, const DeviceDriver value) {
debug << "Vk::DeviceDriver" << Debug::nospace;
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case Vk::DeviceDriver::value: return debug << "::" << Debug::nospace << #value;
_c(Unknown)
_c(AmdOpenSource)
_c(AmdProprietary)
_c(ArmProprietary)
_c(BroadcomProprietary)
_c(GgpProprietary)
_c(GoogleSwiftShader)
_c(ImaginationProprietary)
_c(IntelOpenSourceMesa)
_c(IntelProprietaryWindows)
_c(MesaLlvmpipe)
_c(MesaRadv)
_c(MoltenVk)
_c(NVidiaProprietary)
_c(QualcommProprietary)
#undef _c
/* LCOV_EXCL_STOP */
}
/* Vulkan docs have the values in decimal, so not converting to hex */
return debug << "(" << Debug::nospace << Int(value) << Debug::nospace << ")";
}
Debug& operator<<(Debug& debug, const QueueFlag value) { Debug& operator<<(Debug& debug, const QueueFlag value) {
debug << "Vk::QueueFlag" << Debug::nospace; debug << "Vk::QueueFlag" << Debug::nospace;

136
src/Magnum/Vk/DeviceProperties.h

@ -80,6 +80,75 @@ enum class DeviceType: Int {
*/ */
MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, DeviceType value); MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, DeviceType value);
/**
@brief Physical device driver ID
@m_since_latest
Wraps a @type_vk_keyword{DriverId}.
@see @ref DeviceProperties::driver()
@requires_vk12 Extension @vk_extension{KHR,driver_properties}
@m_enum_values_as_keywords
*/
enum class DeviceDriver: Int {
/**
* Unknown. Returned from @ref DeviceProperties::driver() in case Vulkan
* 1.2 or the @vk_extension{KHR,driver_properties} extension isn't
* supported.
*/
Unknown = 0,
/* Unlike with VkDriverId, which gets allocated sequentially, the rest of
this list is sorted alphabetically for easier lookup. */
/** Open-source AMD */
AmdOpenSource = VK_DRIVER_ID_AMD_OPEN_SOURCE,
/** Proprietary AMD */
AmdProprietary = VK_DRIVER_ID_AMD_PROPRIETARY,
/** Proprietary ARM */
ArmProprietary = VK_DRIVER_ID_ARM_PROPRIETARY,
/** Proprietary Broadcom */
BroadcomProprietary = VK_DRIVER_ID_BROADCOM_PROPRIETARY,
/** Proprietary GGP */
GgpProprietary = VK_DRIVER_ID_GGP_PROPRIETARY,
/** Google SwiftShader */
GoogleSwiftShader = VK_DRIVER_ID_GOOGLE_SWIFTSHADER,
/** Proprietary Imagination */
ImaginationProprietary = VK_DRIVER_ID_IMAGINATION_PROPRIETARY,
/** Open-source Intel Mesa drivers */
IntelOpenSourceMesa = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA,
/** Proprietary Intel driver on Windows */
IntelProprietaryWindows = VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS,
/** Mesa LLVMpipe */
MesaLlvmpipe = VK_DRIVER_ID_MESA_LLVMPIPE,
/** Mesa RADV */
MesaRadv = VK_DRIVER_ID_MESA_RADV,
/** MoltenVK */
MoltenVk = VK_DRIVER_ID_MOLTENVK,
/** Proprietary NVidia */
NVidiaProprietary = VK_DRIVER_ID_NVIDIA_PROPRIETARY,
/** Proprietary Qualcomm */
QualcommProprietary = VK_DRIVER_ID_QUALCOMM_PROPRIETARY,
};
/**
@debugoperatorclassenum{DeviceProperties,DeviceDriver}
@m_since_latest
*/
MAGNUM_VK_EXPORT Debug& operator<<(Debug& debug, DeviceDriver value);
/** /**
@brief Queue flag @brief Queue flag
@m_since_latest @m_since_latest
@ -236,11 +305,19 @@ class MAGNUM_VK_EXPORT DeviceProperties {
/** /**
* @brief Raw device properties * @brief Raw device properties
* *
* Populated lazily on first request. If Vulkan 1.1 or the * Populated lazily on first request. If Vulkan 1.1 is not supported
* @vk_extension{KHR,get_physical_device_properties2} extension is not * and the @vk_extension{KHR,get_physical_device_properties2} extension
* enabled on the originating instance, only the Vulkan 1.0 subset of * is not enabled on the originating instance, only the Vulkan 1.0
* device properties is queried, with the `pNext` member being * subset of device properties is queried, with the `pNext` member
* @cpp nullptr @ce. * being @cpp nullptr @ce. Otherwise:
*
* - If Vulkan 1.2 is supported or the
* @vk_extension{KHR,driver_properties} extension is supported by
* the device, the `pNext` chain contains a
* @type_vk{PhysicalDeviceDriverProperties} structure and the
* @ref driver(), @ref driverName() and @ref driverInfo()
* properties are populated.
*
* @see @fn_vk_keyword{GetPhysicalDeviceProperties2}, * @see @fn_vk_keyword{GetPhysicalDeviceProperties2},
* @fn_vk_keyword{GetPhysicalDeviceProperties} * @fn_vk_keyword{GetPhysicalDeviceProperties}
*/ */
@ -256,6 +333,37 @@ class MAGNUM_VK_EXPORT DeviceProperties {
return Version(properties().properties.apiVersion); return Version(properties().properties.apiVersion);
} }
/**
* @brief Device type
*
* Convenience access to @ref properties() internals, populated lazily
* on first request.
*/
DeviceType type() {
return DeviceType(properties().properties.deviceType);
}
/**
* @brief Device name
*
* Convenience access to @ref properties() internals, populated lazily
* on first request.
*/
Containers::StringView name();
/**
* @brief Driver ID
*
* Convenience access to @ref properties() internals, populated lazily
* on first request. Only present if Vulkan 1.2 is supported or the
* @vk_extension{KHR,driver_properties} extension is supported by the
* device, otherwise returns @ref DeviceDriver::Unknown. Note that
* there might be driver IDs not yet listed in the @ref DeviceDriver
* enum, moreover drivers are allowed to return unregistered IDs as
* well.
*/
DeviceDriver driver();
/** /**
* @brief Driver version * @brief Driver version
* *
@ -267,22 +375,24 @@ class MAGNUM_VK_EXPORT DeviceProperties {
} }
/** /**
* @brief Device type * @brief Driver name
* *
* Convenience access to @ref properties() internals, populated lazily * Convenience access to @ref properties() internals, populated lazily
* on first request. * on first request. Only present if Vulkan 1.2 is supported or the
* @vk_extension{KHR,driver_properties} extension is supported by the
* device, otherwise returns an empty string.
*/ */
DeviceType type() { Containers::StringView driverName();
return DeviceType(properties().properties.deviceType);
}
/** /**
* @brief Device name * @brief Driver info
* *
* Convenience access to @ref properties() internals, populated lazily * Convenience access to @ref properties() internals, populated lazily
* on first request. * on first request. Only present if Vulkan 1.2 is supported or the
* @vk_extension{KHR,driver_properties} extension is supported by the
* device, otherwise returns an empty string.
*/ */
Containers::StringView name(); Containers::StringView driverInfo();
/** /**
* @brief Enumerate device extensions * @brief Enumerate device extensions

8
src/Magnum/Vk/Test/DevicePropertiesTest.cpp

@ -38,6 +38,7 @@ struct DevicePropertiesTest: TestSuite::Tester {
void constructCopy(); void constructCopy();
void debugDeviceType(); void debugDeviceType();
void debugDeviceDriver();
void debugQueueFamilyPropertiesFlag(); void debugQueueFamilyPropertiesFlag();
void debugQueueFamilyPropertiesFlags(); void debugQueueFamilyPropertiesFlags();
void debugMemoryHeapFlag(); void debugMemoryHeapFlag();
@ -49,6 +50,7 @@ DevicePropertiesTest::DevicePropertiesTest() {
&DevicePropertiesTest::constructCopy, &DevicePropertiesTest::constructCopy,
&DevicePropertiesTest::debugDeviceType, &DevicePropertiesTest::debugDeviceType,
&DevicePropertiesTest::debugDeviceDriver,
&DevicePropertiesTest::debugQueueFamilyPropertiesFlag, &DevicePropertiesTest::debugQueueFamilyPropertiesFlag,
&DevicePropertiesTest::debugQueueFamilyPropertiesFlags, &DevicePropertiesTest::debugQueueFamilyPropertiesFlags,
&DevicePropertiesTest::debugMemoryHeapFlag, &DevicePropertiesTest::debugMemoryHeapFlag,
@ -76,6 +78,12 @@ void DevicePropertiesTest::debugDeviceType() {
CORRADE_COMPARE(out.str(), "Vk::DeviceType::DiscreteGpu Vk::DeviceType(-10007655)\n"); CORRADE_COMPARE(out.str(), "Vk::DeviceType::DiscreteGpu Vk::DeviceType(-10007655)\n");
} }
void DevicePropertiesTest::debugDeviceDriver() {
std::ostringstream out;
Debug{&out} << DeviceDriver::MesaLlvmpipe << DeviceDriver(-10007655);
CORRADE_COMPARE(out.str(), "Vk::DeviceDriver::MesaLlvmpipe Vk::DeviceDriver(-10007655)\n");
}
void DevicePropertiesTest::debugQueueFamilyPropertiesFlag() { void DevicePropertiesTest::debugQueueFamilyPropertiesFlag() {
std::ostringstream out; std::ostringstream out;
Debug{&out} << QueueFlag::SparseBinding << QueueFlag(0xdeadcafe); Debug{&out} << QueueFlag::SparseBinding << QueueFlag(0xdeadcafe);

27
src/Magnum/Vk/Test/DevicePropertiesVkTest.cpp

@ -61,6 +61,8 @@ struct DevicePropertiesVkTest: VulkanTester {
void extensionIsSupported(); void extensionIsSupported();
void extensionNamedRevision(); void extensionNamedRevision();
void driverProperties();
void queueFamilies(); void queueFamilies();
void queueFamiliesOutOfRange(); void queueFamiliesOutOfRange();
void queueFamiliesPick(); void queueFamiliesPick();
@ -107,6 +109,8 @@ DevicePropertiesVkTest::DevicePropertiesVkTest(): VulkanTester{NoCreate} {
&DevicePropertiesVkTest::extensionIsSupported, &DevicePropertiesVkTest::extensionIsSupported,
&DevicePropertiesVkTest::extensionNamedRevision, &DevicePropertiesVkTest::extensionNamedRevision,
&DevicePropertiesVkTest::driverProperties,
&DevicePropertiesVkTest::queueFamilies, &DevicePropertiesVkTest::queueFamilies,
&DevicePropertiesVkTest::queueFamiliesOutOfRange, &DevicePropertiesVkTest::queueFamiliesOutOfRange,
&DevicePropertiesVkTest::queueFamiliesPick, &DevicePropertiesVkTest::queueFamiliesPick,
@ -183,6 +187,29 @@ void DevicePropertiesVkTest::wrap() {
CORRADE_COMPARE(wrapped.name(), devices[0].name()); CORRADE_COMPARE(wrapped.name(), devices[0].name());
} }
void DevicePropertiesVkTest::driverProperties() {
Containers::Optional<DeviceProperties> device = tryPickDevice(instance());
CORRADE_VERIFY(device);
Debug{} << "Driver ID:" << device->driver();
ExtensionProperties extensions = device->enumerateExtensionProperties();
if(!instance().isExtensionEnabled<Extensions::KHR::get_physical_device_properties2>() || !extensions.isSupported<Extensions::KHR::driver_properties>()) {
CORRADE_COMPARE(device->driver(), DeviceDriver::Unknown);
CORRADE_COMPARE(device->driverName(), "");
CORRADE_COMPARE(device->driverInfo(), "");
CORRADE_SKIP("KHR_driver_properties not supported.");
}
CORRADE_VERIFY(Int(device->driver()));
CORRADE_VERIFY(!device->driverName().isEmpty());
{
CORRADE_EXPECT_FAIL_IF(device->driver() == DeviceDriver::GoogleSwiftShader,
"SwiftShader reports empty driver info.");
CORRADE_VERIFY(!device->driverInfo().isEmpty());
}
}
void DevicePropertiesVkTest::enumerateExtensions() { void DevicePropertiesVkTest::enumerateExtensions() {
Containers::Array<DeviceProperties> devices = enumerateDevices(instance()); Containers::Array<DeviceProperties> devices = enumerateDevices(instance());
CORRADE_VERIFY(!devices.empty()); CORRADE_VERIFY(!devices.empty());

13
src/Magnum/Vk/vk-info.cpp

@ -250,6 +250,19 @@ int main(int argc, char** argv) {
const Vk::Version deviceVersion = device.apiVersion(); const Vk::Version deviceVersion = device.apiVersion();
Debug{} << "Reported version:" << deviceVersion; Debug{} << "Reported version:" << deviceVersion;
/* Driver info. Print only if the device actually reports something,
otherwise assume VK_KHR_driver_properties are not supported. Due to the
mess that's VK_KHR_get_physical_device_properties2 and the interactions
between instance and driver version it's not possible to easily check
for extension presence. */
if(Int(device.driver())) {
Debug{} << "Driver:" << device.driverName() << "(" << Debug::nospace << device.driver() << Debug::nospace << ")";
Debug{} << "Driver info:" << device.driverInfo() << "(version" << Debug::packed << device.driverVersion() << Debug::nospace << ")";
/* Otherwise just print an Unknown placeholder, indicating the extension
is not supported */
} else Debug{} << "Driver:" << device.driver();
std::size_t deviceFuture = 0; std::size_t deviceFuture = 0;
if(!args.isSet("all-extensions")) if(!args.isSet("all-extensions"))

Loading…
Cancel
Save