H-uru / Plasma

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

Display Helpers #1566

Open colincornaby opened 7 months ago

colincornaby commented 7 months ago

Looking for feedback on this concept. Direct3D is funny in that it directly includes display mode queries as part of its API. For Metal - and OpenGL particularly - things are a bit more interesting. The display mode API is separate from the graphics API.

This PR adds display helpers as a structure to try to bridge a specific renderer to a platform specific implementation.

I'm not sure how this fits with enumerations - it's possible that this integration needs to happen at a deeper level in the code.

dpogue commented 7 months ago

A few high-level thoughts:

colincornaby commented 2 months ago

Digging this PR back out - @dpogue I think you are right. One issue is that the client makes a lot of decisions about resolution - but it does it before the pipeline is necessarily available.

One possible issue is the divergent views on if resolution selection is part of the graphics API or the platform API. Apple feels that it's platform API, but Microsoft sees it as a graphics API issue at least under D3D9.

Other pipelines like OpenGL/Vulkan could cause further chaos, especially if you had one accelerator that supported one set of APIs and another adapter that supported a different set.

There are probably Win32 APIs to map a display to resolutions that I'm not aware of. That might be a good solution. But the display helper still includes some graphics API related code to check capabilities.

colincornaby commented 2 months ago

There's also overlap going on between this display helper class and DeviceEnumerator.

dpogue commented 1 month ago

I have mostly avoided thinking about this because (as you mentioned) with OpenGL is becomes a complicated nightmare that can't really be done at the driver level.

I agree with the idea that the display mode stuff should be at the plClient/windowing level rather than the pipeline level, although I see how we might still want to filter that list of modes based on capabilities of the pipeline render device.

The original Direct3D renderer used exclusive fullscreen, which presumably is where it's important to use the driver to enumerate the supported modes. We replaced that with fake-fullscreen though, so it might be less important to use that now vs using standard Win32 APIs to ask for the supported resolutions.

I'm imagining something like plClient::GetAvailableDisplayResolutions() being a per-platform implementation that fills in part of the hsG3DDeviceSelector stuff that gets passed in to the pipeline constructor, and then plPipeline::GetSupportedDisplayModes returning a filtered/constrained list based on the capabilities of the active rendering device. Does that sound like it would work?

colincornaby commented 1 month ago

I'm imagining something like plClient::GetAvailableDisplayResolutions() being a per-platform implementation that fills in part of the hsG3DDeviceSelector stuff that gets passed in to the pipeline constructor, and then plPipeline::GetSupportedDisplayModes returning a filtered/constrained list based on the capabilities of the active rendering device. Does that sound like it would work?

We might need a display handle to go along with that (along with a re-review of where else this concept is already encapsulated in the pipeline.) Resolutions are going to be per display - and it would be good to clean that whole thing up while we're putting in new plumbing.

The client will probably need to vend which display the window is currently on, and broadcast any changes.