H-uru / Plasma

Cyan Worlds's Plasma game engine
http://h-uru.github.io/Plasma/
GNU General Public License v3.0
202 stars 80 forks source link

Direct3D Pipeline Does Not Handle Multiple Displays Properly #1514

Open colincornaby opened 8 months ago

colincornaby commented 8 months ago

This is a Direct3D specific extension of #1502. The discussion about how video modes should operate on macOS and OpenGL led to an investigation of how Direct3D handles video modes.

Background

The Windows/D3D client does not handle multiple displays properly. It will only go full screen on the main display, and won't acknowledge any video modes of the second display. In windowed mode - it will still only acknowledge video modes of the primary display.

I spent some time tracing what was going on - and I think I found the root of where this all started. Sorting through comments - it seems Cyan may have misunderstood an aspect of the Direct3D API. The term "adapter" in Direct3D means monitor - not the 3D accelerator. plDXEnumerate is enumerating displays. If there are multiple displays running on multiple different cards - it will happen to enumerate multiple cards and multiple drivers as well. But adapter enumeration is display based - not card based. The code - dating back to the original Cyan drop - uses the term "driver" as to what it's enumerating. But it's enumerating displays.

This means Plasma isn't properly handling multiple displays. Because it thinks it's only picking a rendering device - it picks one and then ignores the others.

Implementation path

Unwinding this could be tricky. What Cyan should have done is enumerated all the adapters - and let the user pick which adapter/monitor Plasma should be associated with. That would allow the user to "focus" a display.

The concept of virtual display modes in #1502 would also cut Plasma off from the concept of video modes and is another work around. However - if display enumeration was fixed for Windows it might make display enumeration in macOS more clean to implement.

Erata

Most my time spent on this has been documentation research - I have not done a deep debugger dive to see how the D3D9 enumeration behaves with multiple displays attached.

I don't know if this issue has carried to the other renderers. My impression is the other renderers are also enumerating cards and not displays. (The Metal one certainly is.)

I've observed my Windows box still changing the output resolution of my displays. When you alt tab to the desktop everything is the wrong resolution. I am not sure why.

colincornaby commented 8 months ago

Just to finish this up, I did spend some time debugging on Windows this morning. plDXEnumerate does indeed enumerate displays, not graphics cards or renderers.

When I have two displays attached, it finds two adapters:

(Just for clarity I am not lucky enough to have two RTX 4090s in my Windows box.)

My hunch as to what happened here is that when Classic Direct3D was originally designed - graphics cards only could output to a single display. So Microsoft used the term adapter and display interchangeably. Around 2000 the first dual head cards started to ship. Microsoft probably just extended the adapter API to iterate displays instead of GPUs because that was the quickest fix.

There is some evidence that maybe Cyan was aware something had shifted in the comments,. but I don't think they quite understood the implications. (Also dual displays was still really uncommon at the time so they may not have cared.)

/// Loop through the "adapters" (we don't call them drivers anymore)

It's a weird code comment because it implies they understood that drivers were not adapters - but also they still didn't seem to fully understand that adapters actually meant displays.

This does mean:

Technically the DX pipeline works in sort of an accidental way. If you have one display and one GPU everything is great because their assumption holds. If you have multiple displays - Plasma just won't work properly with any secondary display - but maybe no one cares. But as we add more pipelines and we do actually start to worry about proper multiple display support this is not right.