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>
This commit is contained in:
parent
8fef0ffc16
commit
ef78a2e8f9
@ -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.
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -1294,7 +1294,8 @@ public:
|
||||
|
||||
enum Flag {
|
||||
EnableProfiling = 1 << 0,
|
||||
EnableDebugMarkers = 1 << 1
|
||||
EnableDebugMarkers = 1 << 1,
|
||||
PreferSoftwareRenderer = 1 << 2
|
||||
};
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -473,6 +473,10 @@ int main(int argc, char **argv)
|
||||
"(generate a device reset every <count> frames when on D3D11)"),
|
||||
QLatin1String("count"));
|
||||
cmdLineParser.addOption(tdrOption);
|
||||
// Allow testing preferring the software adapter (D3D).
|
||||
QCommandLineOption swOption(QLatin1String("software"), QLatin1String("Prefer a software renderer when choosing the adapter. "
|
||||
"Only applicable with some APIs and platforms."));
|
||||
cmdLineParser.addOption(swOption);
|
||||
|
||||
cmdLineParser.process(app);
|
||||
if (cmdLineParser.isSet(nullOption))
|
||||
@ -534,6 +538,9 @@ int main(int argc, char **argv)
|
||||
if (cmdLineParser.isSet(tdrOption))
|
||||
framesUntilTdr = cmdLineParser.value(tdrOption).toInt();
|
||||
|
||||
if (cmdLineParser.isSet(swOption))
|
||||
rhiFlags |= QRhi::PreferSoftwareRenderer;
|
||||
|
||||
// Create and show the window.
|
||||
Window w;
|
||||
#if QT_CONFIG(vulkan)
|
||||
|
Loading…
x
Reference in New Issue
Block a user