diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-09-11 11:09:05 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-09-12 14:28:23 +0000 |
commit | ef78a2e8f9bade867e43c75892353e38d48c595c (patch) | |
tree | 9d8fb1978ef71e70e095f22b4b8daf74b9e1b6c6 /src/gui/rhi | |
parent | 8fef0ffc16ec9a88169349adfa8aafc9f375e94b (diff) |
rhi: Add a flag to indicate preferring a software adapter
...if there is one and the concept is applicable in the first place.
Change-Id: Iab202c1c1cdd229f4910159de4cae7ce30805ea9
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
Diffstat (limited to 'src/gui/rhi')
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 12 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p.h | 3 | ||||
-rw-r--r-- | src/gui/rhi/qrhid3d11.cpp | 25 | ||||
-rw-r--r-- | src/gui/rhi/qrhivulkan.cpp | 24 |
4 files changed, 60 insertions, 4 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index fbdc90bd1b..585dc8a8fa 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -439,6 +439,18 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general") visible in external GPU debugging tools will not be available and functions like QRhiCommandBuffer::debugMarkBegin() will become a no-op. Avoid enabling in production builds as it may involve a performance penalty. + + \value PreferSoftwareRenderer Indicates that backends should prefer + choosing an adapter or physical device that renders in software on the CPU. + For example, with Direct3D there is typically a "Basic Render Driver" + adapter available with \c{DXGI_ADAPTER_FLAG_SOFTWARE}. Setting this flag + requests the backend to choose that adapter over any other, as long as no + specific adapter was forced by other backend-specific means. With Vulkan + this maps to preferring physical devices with + \c{VK_PHYSICAL_DEVICE_TYPE_CPU}. When not available, or when it is not + possible to decide if an adapter/device is software-based, this flag is + ignored. It may also be ignored with graphics APIs that have no concept and + means of enumerating adapters/devices. */ /*! diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index 51e70af18e..6f0b8e0b04 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -1294,7 +1294,8 @@ public: enum Flag { EnableProfiling = 1 << 0, - EnableDebugMarkers = 1 << 1 + EnableDebugMarkers = 1 << 1, + PreferSoftwareRenderer = 1 << 2 }; Q_DECLARE_FLAGS(Flags, Flag) diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 2350691dc0..0977a3042d 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -119,6 +119,11 @@ QT_BEGIN_NAMESPACE \c{ID3D11Texture2D *}. */ +// help mingw with its ancient sdk headers +#ifndef DXGI_ADAPTER_FLAG_SOFTWARE +#define DXGI_ADAPTER_FLAG_SOFTWARE 2 +#endif + QRhiD3D11::QRhiD3D11(QRhiD3D11InitParams *params, QRhiD3D11NativeHandles *importDevice) : ofr(this), deviceCurse(this) @@ -227,11 +232,29 @@ bool QRhiD3D11::create(QRhi::Flags flags) int requestedAdapterIndex = -1; if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX")) requestedAdapterIndex = qEnvironmentVariableIntValue("QT_D3D_ADAPTER_INDEX"); + + if (requestedAdapterIndex < 0 && flags.testFlag(QRhi::PreferSoftwareRenderer)) { + for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(UINT(adapterIndex), &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + adapter->Release(); + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { + requestedAdapterIndex = adapterIndex; + break; + } + } + } + for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(UINT(adapterIndex), &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) { DXGI_ADAPTER_DESC1 desc; adapter->GetDesc1(&desc); const QString name = QString::fromUtf16(reinterpret_cast<char16_t *>(desc.Description)); - qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (flags 0x%x)", adapterIndex, qPrintable(name), desc.Flags); + qCDebug(QRHI_LOG_INFO, "Adapter %d: '%s' (vendor 0x%X device 0x%X flags 0x%X)", + adapterIndex, + qPrintable(name), + desc.VendorId, + desc.DeviceId, + desc.Flags); if (!adapterToUse && (requestedAdapterIndex < 0 || requestedAdapterIndex == adapterIndex)) { adapterToUse = adapter; qCDebug(QRHI_LOG_INFO, " using this adapter"); diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index 1ed3ffc206..64fea37292 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -388,22 +388,42 @@ bool QRhiVulkan::create(QRhi::Flags flags) qWarning("Failed to enumerate physical devices: %d", err); return false; } + int physDevIndex = -1; int requestedPhysDevIndex = -1; if (qEnvironmentVariableIsSet("QT_VK_PHYSICAL_DEVICE_INDEX")) requestedPhysDevIndex = qEnvironmentVariableIntValue("QT_VK_PHYSICAL_DEVICE_INDEX"); + + if (requestedPhysDevIndex < 0 && flags.testFlag(QRhi::PreferSoftwareRenderer)) { + for (int i = 0; i < int(physDevCount); ++i) { + f->vkGetPhysicalDeviceProperties(physDevs[i], &physDevProperties); + if (physDevProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) { + requestedPhysDevIndex = i; + break; + } + } + } + for (int i = 0; i < int(physDevCount); ++i) { f->vkGetPhysicalDeviceProperties(physDevs[i], &physDevProperties); - qCDebug(QRHI_LOG_INFO, "Physical device %d: '%s' %d.%d.%d", i, + qCDebug(QRHI_LOG_INFO, "Physical device %d: '%s' %d.%d.%d (api %d.%d.%d vendor 0x%X device 0x%X type %d)", + i, physDevProperties.deviceName, VK_VERSION_MAJOR(physDevProperties.driverVersion), VK_VERSION_MINOR(physDevProperties.driverVersion), - VK_VERSION_PATCH(physDevProperties.driverVersion)); + VK_VERSION_PATCH(physDevProperties.driverVersion), + VK_VERSION_MAJOR(physDevProperties.apiVersion), + VK_VERSION_MINOR(physDevProperties.apiVersion), + VK_VERSION_PATCH(physDevProperties.apiVersion), + physDevProperties.vendorID, + physDevProperties.deviceID, + physDevProperties.deviceType); if (physDevIndex < 0 && (requestedPhysDevIndex < 0 || requestedPhysDevIndex == int(i))) { physDevIndex = i; qCDebug(QRHI_LOG_INFO, " using this physical device"); } } + if (physDevIndex < 0) { qWarning("No matching physical device"); return false; |