mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[d3d9] Enumerate adapters by display
WPF expects us to return an adapter for every display attached otherwise it decides to device reset every frame. Closes #1459
This commit is contained in:
parent
d424fb87aa
commit
0e353895fd
@ -32,10 +32,12 @@ namespace dxvk {
|
||||
D3D9Adapter::D3D9Adapter(
|
||||
D3D9InterfaceEx* pParent,
|
||||
Rc<DxvkAdapter> Adapter,
|
||||
UINT Ordinal)
|
||||
UINT Ordinal,
|
||||
UINT DisplayIndex)
|
||||
: m_parent (pParent)
|
||||
, m_adapter (Adapter)
|
||||
, m_ordinal (Ordinal)
|
||||
, m_displayIndex (DisplayIndex)
|
||||
, m_modeCacheFormat (D3D9Format::Unknown)
|
||||
, m_d3d9Formats (Adapter, m_parent->GetOptions()) {
|
||||
m_adapter->logAdapterInfo();
|
||||
@ -52,11 +54,11 @@ namespace dxvk {
|
||||
|
||||
const auto& props = m_adapter->deviceProperties();
|
||||
|
||||
::MONITORINFOEXA monInfo;
|
||||
monInfo.cbSize = sizeof(monInfo);
|
||||
DISPLAY_DEVICEA device = { };
|
||||
device.cb = sizeof(device);
|
||||
|
||||
if (!::GetMonitorInfoA(GetDefaultMonitor(), reinterpret_cast<MONITORINFO*>(&monInfo))) {
|
||||
Logger::err("D3D9Adapter::GetAdapterIdentifier: Failed to query monitor info");
|
||||
if (!::EnumDisplayDevicesA(nullptr, m_displayIndex, &device, 0)) {
|
||||
Logger::err("D3D9Adapter::GetAdapterIdentifier: Failed to query display info");
|
||||
return D3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
@ -68,7 +70,7 @@ namespace dxvk {
|
||||
const char* driver = GetDriverDLL(DxvkGpuVendor(vendorId));
|
||||
|
||||
std::strncpy(pIdentifier->Description, desc, countof(pIdentifier->Description));
|
||||
std::strncpy(pIdentifier->DeviceName, monInfo.szDevice, countof(pIdentifier->DeviceName)); // The GDI device name. Not the actual device name.
|
||||
std::strncpy(pIdentifier->DeviceName, device.DeviceName, countof(pIdentifier->DeviceName)); // The GDI device name. Not the actual device name.
|
||||
std::strncpy(pIdentifier->Driver, driver, countof(pIdentifier->Driver)); // This is the driver's dll.
|
||||
|
||||
pIdentifier->DeviceIdentifier = guid;
|
||||
|
@ -18,7 +18,8 @@ namespace dxvk {
|
||||
D3D9Adapter(
|
||||
D3D9InterfaceEx* pParent,
|
||||
Rc<DxvkAdapter> Adapter,
|
||||
UINT Ordinal);
|
||||
UINT Ordinal,
|
||||
UINT DisplayIndex);
|
||||
|
||||
HRESULT GetAdapterIdentifier(
|
||||
DWORD Flags,
|
||||
@ -101,6 +102,7 @@ namespace dxvk {
|
||||
|
||||
Rc<DxvkAdapter> m_adapter;
|
||||
UINT m_ordinal;
|
||||
UINT m_displayIndex;
|
||||
|
||||
std::vector<D3DDISPLAYMODEEX> m_modes;
|
||||
D3D9Format m_modeCacheFormat;
|
||||
|
@ -12,9 +12,45 @@ namespace dxvk {
|
||||
: m_instance ( new DxvkInstance() )
|
||||
, m_extended ( bExtended )
|
||||
, m_d3d9Options ( nullptr, m_instance->config() ) {
|
||||
m_adapters.reserve(m_instance->adapterCount());
|
||||
for (uint32_t i = 0; i < m_instance->adapterCount(); i++)
|
||||
m_adapters.emplace_back(this, m_instance->enumAdapters(i), i);
|
||||
// D3D9 doesn't enumerate adapters like physical adapters...
|
||||
// only as connected displays.
|
||||
|
||||
// Let's create some "adapters" for the amount of displays we have.
|
||||
// We'll go through and match up displays -> our adapters in order.
|
||||
// If we run out of adapters, then we'll just make repeats of the first one.
|
||||
// We can't match up by names on Linux/Wine as they don't match at all
|
||||
// like on Windows, so this is our best option.
|
||||
if (m_d3d9Options.enumerateByDisplays) {
|
||||
DISPLAY_DEVICEA device = { };
|
||||
device.cb = sizeof(device);
|
||||
|
||||
uint32_t adapterOrdinal = 0;
|
||||
uint32_t i = 0;
|
||||
while (::EnumDisplayDevicesA(nullptr, i++, &device, 0)) {
|
||||
// If we aren't attached, skip over.
|
||||
if (!(device.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
|
||||
continue;
|
||||
|
||||
// If we are a mirror, skip over this device.
|
||||
if (device.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)
|
||||
continue;
|
||||
|
||||
Rc<DxvkAdapter> adapter = adapterOrdinal >= m_instance->adapterCount()
|
||||
? m_instance->enumAdapters(0)
|
||||
: m_instance->enumAdapters(adapterOrdinal);
|
||||
|
||||
if (adapter != nullptr)
|
||||
m_adapters.emplace_back(this, adapter, adapterOrdinal++, i - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint32_t adapterCount = m_instance->adapterCount();
|
||||
m_adapters.reserve(adapterCount);
|
||||
|
||||
for (uint32_t i = 0; i < adapterCount; i++)
|
||||
m_adapters.emplace_back(this, m_instance->enumAdapters(i), i, 0);
|
||||
}
|
||||
|
||||
if (m_d3d9Options.dpiAware) {
|
||||
Logger::info("Process set as DPI aware");
|
||||
|
@ -67,6 +67,7 @@ namespace dxvk {
|
||||
this->forceAspectRatio = config.getOption<std::string>("d3d9.forceAspectRatio", "");
|
||||
this->allowDoNotWait = config.getOption<bool> ("d3d9.allowDoNotWait", true);
|
||||
this->allowDiscard = config.getOption<bool> ("d3d9.allowDiscard", true);
|
||||
this->enumerateByDisplays = config.getOption<bool> ("d3d9.enumerateByDisplays", true);
|
||||
|
||||
// If we are not Nvidia, enable general hazards.
|
||||
this->generalHazards = adapter == nullptr || !adapter->matchesDriver(DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0);
|
||||
|
@ -125,6 +125,9 @@ namespace dxvk {
|
||||
|
||||
/// Allow D3DLOCK_DISCARD
|
||||
bool allowDiscard;
|
||||
|
||||
/// Enumerate adapters by displays
|
||||
bool enumerateByDisplays;
|
||||
};
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user