MonoGame / MonoGame

One framework for creating powerful cross-platform games.
http://www.monogame.net
Other
11.3k stars 2.9k forks source link

Lowering DesktopGL OpenGL requirements for SpriteBatch games? #5580

Open mrhelmut opened 7 years ago

mrhelmut commented 7 years ago

Hello there,

I haven't checked if this is really possible, but we would have a relevant benefit from trying to lower the OpenGL requirements for DesktopGL games running on Windows.

We have a lot of players unable to run our games because of the bad OpenGL support of the Intel drivers. While Intel GPU, even 10 years old, mostly all supports Direct3D 10, they hardly have drivers for OpenGL 1.5 while they should be 3.0 capable, or at worst 2.1 (except on Linux where 2.1 is common place, because reasons). Intel never really cared about it and discontinued hardware are doomed to stick to this support. That's a problem because on the same hardware, a Direct3D game could work while it's DesktopGL version wouldn't.

I know that we can't support all hardware, but there's a relevant number of players to be miss for games which run only on SpriteBatch (particularly when considering emerging countries).

Hence, I'm wondering if we could think of a way to manage the loading of the OpenGL entry points differently, by ordering them by feature sets or GL versions, and trying to load their extensions equivalent if not found (like what's done for ARB_framebuffer_object), as well as not blocking the initialization on non-SpriteBatch critical functions.

@Jjagg @cra0zy @dellis1972

dellis1972 commented 7 years ago

It would be nice to expose an API which would allow developers to know if things like RenderTargets are supported. I believe there is an issue on this already,

But then again is this what the GraphicsProfile is for? Should the Reach profile be this lower end stuff, we need to specifically say which features are not available. For example I don't think custom shaders worked on reach. Not sure about RenderTargets.

I'd back this change btw. similar to what was done with ARB_framebuffer_object.

Thoughts @tomspilman.

On 14 March 2017 at 10:27, Thomas Altenburger notifications@github.com wrote:

Hello there,

I haven't checked if this is really possible, but we would have a relevant benefit from trying to lower the OpenGL requirements for DesktopGL games running on Windows.

We have a lot of players unable to run our games because of the bad OpenGL support of the Intel drivers. While Intel GPU, even 10 years old, mostly all supports Direct3D 10, they hardly have drivers for OpenGL 1.5 while they should be 3.0 capable, or at worst 2.1 (except on Linux where 2.1 is common place, because reasons). Intel never really cared about it and discontinued hardware are doomed to stick to this support. That's a problem because on the same hardware, a Direct3D game could work while it's DesktopGL version wouldn't.

I know that we can't support all hardware, but there's a relevant number of players to be miss for games which run only on SpriteBatch (particularly when considering emerging countries).

Hence, I'm wondering if we could think of a way to manage the loading of the OpenGL entry points differently, by ordering them by feature sets or GL versions, and trying to load their extensions equivalent if not found (like what's done for ARB_framebuffer_object), as well as not blocking the initialization on non-SpriteBatch critical functions.

@Jjagg https://github.com/Jjagg @cra0zy https://github.com/cra0zy @dellis1972 https://github.com/dellis1972

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/MonoGame/MonoGame/issues/5580, or mute the thread https://github.com/notifications/unsubscribe-auth/AAxeeSldeZ7BxUwLeStzz8wxPMudMvXWks5rlmuCgaJpZM4McYXL .

nkast commented 7 years ago

@mrhelmut A good starting point would be to implement GraphicsAdapter.IsProfileSupported() for OpenGL (#5312) (check whether the Card/Adapter or the Driver supports certain features). Then enforce those limitations by checking GraphicsCapabilities. Perhaps #5451 would be enough. Maybe you need extra checks during openGL initialization, i don't know...

The developer could then check the supported profile and if HiDef is not supported, then fallback to a Reach renderer.

Jjagg commented 7 years ago

Sounds like a good idea. We just need someone to check what extensions we can take advantage of.

IMO GraphicsProfile is not related here. To figure out the capabilities of the device we can just check what entry points did not get loaded. It doesn't matter how we can support a certain feature, it just matter if we can support it.

nkast commented 7 years ago

I think we have the chicken-egg issue on OpenGL. Should we populate GraphicsCapabilities from Profile or determine profile from GraphicsCapabilities. (or maybe we have to implement both individually for OpenGL platform?)

I am not very familiar on the OpenGL code, I assume this can be determined by how the initialization sequence goes on this platform. Specifically, IsProfileSupported() is coupled to a specific Adapter, and GraphicsCapabilities has to be about the current Adapter selected by the user after PreparingDeviceSettings event. From what I get from this issue, IsProfileSupported() should also account for the installed extensions or driver version.

Jjagg commented 7 years ago

There are two ways to check if a certain feature is supported. Try and load the entry point and see if that works or check the gl version and the extensions. I think the best way to go about this is to first try to load all entry points - and try extensions when that fails - and then to figure out the GraphicsCapabilities by checking what delegates did not get loaded.

Specifically, IsProfileSupported() is coupled to a specific Adapter, and GraphicsCapabilities has to be about the current Adapter selected by the user after PreparingDeviceSettings event.

I think a nice way to go about this is to associate a GraphicsCapabilities instance with each adapter that holds the actual capabilities of the adapter. The GraphicsCapabilities of a GraphicsDevice is just what the user wants it to be. We can then check if the caps for creating a device are a subset of the caps of the adapter.

I looked into selecting a specific adapter for OpenGL stuff before, and it seems it's not that straightforward to select a specific one :( Though there are extensions for NVIDIA and AMD cards (only Windows and specific cards support it).

nkast commented 7 years ago

I think a nice way to go about this is to associate a GraphicsCapabilities instance with each adapter that holds the actual capabilities of the adapter.

That's a good idea. Adapter already has 2 Query methods (QueryBackBufferFormat(), QueryRenderTargetFormat() so in principle looks like the best place to be.

I see a distinction here, while Adapter.Capabilities returns the Maximum supported capabilities, the device could return the capabilities restricted by the selected profile. Someday we could make them both public and add an Unrestricted profile if we wish to break away from XNA profile concept.

mrhelmut commented 7 years ago

I have listed the requirements for each OpenGL entry points: https://docs.google.com/spreadsheets/d/1hyA5Llqhoit6UKOyWKJtLRr3BY0V77YRVG9JbdKAu0w/edit?usp=sharing

There seems to be an issue with the use of glGetQueryObjectivARB: it's an extension (ARB_occlusion_query) not always present while its core version glGetQueryObjectiv is OpenGL 2.0. This is a potential compatibility issue. I'll push a PR to fix this soon.

The only feature requiring more than OpenGL 2.0 is the RenderTarget support, which we could make optional.

But right now, MonoGame is working on any computer with a 2.0 support + ARB_frame_buffer_object extension, which can hardly get lower.

Other point to verify: against which version the stock shaders are compiled? As far as I have verified, they do not define a #version directive, and according the OpenGL documentation means that the lowest compiler version is used (which is GLSL 1.10, the base version of OpenGL 2.0).

Jjagg commented 7 years ago

Other point to verify: against which version the stock shaders are compiled? As far as I have verified, they do not define a #version directive

MojoShader generates this. It uses #version 110 regardless of HLSL shader profile (you can let it target 120 too, but MG doesn't do that).

mrhelmut commented 7 years ago

Thanks for verifying! Looking good.

tomspilman commented 7 years ago

I'm no OGL expert... so i'm not sure what is best here.

I have seen some OGL bindings have a "fallback" entrypoint like this:

LoadEntryPoint<GetQueryObjectDelegate>("glGetQueryObjectiv", "glGetQueryObjectivARB"); 

The idea being if one fails it tries the other.

Not sure if this technique helps in these cases or not.

mrhelmut commented 7 years ago

glGetQueryObjectiv is a core function of 2.0, so I believe we're good. I think that bindings falling back to the ARB extension are for 1.5 compatibility, which we cannot achieve, hence we should be good with the core version. I'm going to look for info about it to be sure.

Jjagg commented 6 years ago

Before 3.0 MG SpriteBatch supported older OpenGL versions by having an alternative implementation of DrawBatch in SpriteBatcher that does not use SpriteEffect (https://github.com/MonoGame/MonoGame/blob/v2.5.0.0/MonoGame.Framework/Graphics/SpriteBatcher.cs#L191-L253). We could restore that code and make RenderTargets optional if we want to support OpenGL < 2.0. Though there's a lot of functionality of MG that would break and it would be a pain to gracefully handle all the errors.

KonajuGames commented 6 years ago

I'm not sure about expending the effort to add support for an ever decreasing fraction of the market.

mrhelmut commented 6 years ago

It would be a lot of hassle for little gain, I believe. 2.0 is pretty common now, so I believe that 100% SpriteBatch games are good with that. The thing is that render target support tries to load the required 3.0 entry points even when not using render targets (which still makes 3.0 to be a hard requirement). If it can be made optional, that would be cool for sprite batch games.

harry-cpp commented 5 years ago

Recently I have been thinking of doing the exact opposite of this issue, bumping up the required version to OpenGL 3.3 core profile.

mrhelmut commented 5 years ago

I believe it would cause a lot of incompatibilities issues. I am still very surprised by the number of players on Steam who are still running barely 3.0 capable machines (mostly Intel GPU on Windows 10).

I still get daily reports of machines having core 2.0, and sometime even missing ARB_framebuffer_object extension.