mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +01:00
[dxgi] Be more robust against monitor enumeration issues.
If there are monitors on the system that are not associated with any adapter, enumerate all monitors for all adatpers. May solve some issues if device filter options are used on multi-GPU systems.
This commit is contained in:
parent
80f7d2abd8
commit
14eb469005
@ -162,7 +162,7 @@ namespace dxvk {
|
||||
|
||||
auto linkedAdapter = m_adapter->linkedIGPUAdapter();
|
||||
|
||||
/* If either LUID is not valid enumerate all monitors. */
|
||||
// If either LUID is not valid, enumerate all monitors.
|
||||
if (numLUIDs && linkedAdapter != nullptr) {
|
||||
const auto& deviceId = linkedAdapter->devicePropertiesExt().vk11;
|
||||
|
||||
@ -172,6 +172,10 @@ namespace dxvk {
|
||||
numLUIDs = 0;
|
||||
}
|
||||
|
||||
// Enumerate all monitors if the robustness fallback is active.
|
||||
if (m_factory->UseMonitorFallback())
|
||||
numLUIDs = 0;
|
||||
|
||||
HMONITOR monitor = wsi::enumMonitors(adapterLUIDs.data(), numLUIDs, Output);
|
||||
|
||||
if (monitor == nullptr)
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "dxgi_factory.h"
|
||||
#include "dxgi_surface.h"
|
||||
#include "dxgi_swapchain.h"
|
||||
@ -48,13 +50,55 @@ namespace dxvk {
|
||||
|
||||
|
||||
DxgiFactory::DxgiFactory(UINT Flags)
|
||||
: m_instance (g_dxvkInstance.acquire()),
|
||||
m_interop (this),
|
||||
m_options (m_instance->config()),
|
||||
m_monitorInfo (this, m_options),
|
||||
m_flags (Flags) {
|
||||
for (uint32_t i = 0; m_instance->enumAdapters(i) != nullptr; i++)
|
||||
m_instance->enumAdapters(i)->logAdapterInfo();
|
||||
: m_instance (g_dxvkInstance.acquire()),
|
||||
m_interop (this),
|
||||
m_options (m_instance->config()),
|
||||
m_monitorInfo (this, m_options),
|
||||
m_flags (Flags),
|
||||
m_monitorFallback (false) {
|
||||
// Be robust against situations where some monitors are not
|
||||
// associated with any adapter. This can happen if device
|
||||
// filter options are used.
|
||||
std::vector<HMONITOR> monitors;
|
||||
|
||||
for (uint32_t i = 0; ; i++) {
|
||||
HMONITOR hmon = wsi::enumMonitors(i);
|
||||
|
||||
if (!hmon)
|
||||
break;
|
||||
|
||||
monitors.push_back(hmon);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; m_instance->enumAdapters(i) != nullptr; i++) {
|
||||
auto adapter = m_instance->enumAdapters(i);
|
||||
adapter->logAdapterInfo();
|
||||
|
||||
// Remove all monitors that are associated
|
||||
// with the current adapter from the list.
|
||||
const auto& vk11 = adapter->devicePropertiesExt().vk11;
|
||||
|
||||
if (vk11.deviceLUIDValid) {
|
||||
auto luid = reinterpret_cast<const LUID*>(&vk11.deviceLUID);
|
||||
|
||||
for (uint32_t j = 0; ; j++) {
|
||||
HMONITOR hmon = wsi::enumMonitors(&luid, 1, j);
|
||||
|
||||
if (!hmon)
|
||||
break;
|
||||
|
||||
auto entry = std::find(monitors.begin(), monitors.end(), hmon);
|
||||
|
||||
if (entry != monitors.end())
|
||||
monitors.erase(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If any monitors are left on the list, enable the
|
||||
// fallback to always enumerate all monitors.
|
||||
if ((m_monitorFallback = !monitors.empty()))
|
||||
Logger::warn("DXGI: Found monitors not associated with any adapter, using fallback");
|
||||
}
|
||||
|
||||
|
||||
|
@ -158,6 +158,10 @@ namespace dxvk {
|
||||
HRESULT STDMETHODCALLTYPE UnregisterAdaptersChangedEvent(
|
||||
DWORD Cookie);
|
||||
|
||||
BOOL UseMonitorFallback() const {
|
||||
return m_monitorFallback;
|
||||
}
|
||||
|
||||
Rc<DxvkInstance> GetDXVKInstance() const {
|
||||
return m_instance;
|
||||
}
|
||||
@ -177,6 +181,7 @@ namespace dxvk {
|
||||
DxgiOptions m_options;
|
||||
DxgiMonitorInfo m_monitorInfo;
|
||||
UINT m_flags;
|
||||
BOOL m_monitorFallback;
|
||||
|
||||
HWND m_associatedWindow = nullptr;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user