godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Implement fallback to OpenGL 3 / Compatibility renderer when Vulkan is not supported #8006

Closed akien-mga closed 1 month ago

akien-mga commented 1 year ago

Describe the project you are working on

Godot, and making it as easy as possible for everyone to use it on any hardware.

Describe the problem or limitation you are having in your project

Godot 4 currently supported Vulkan for its higher end RenderingDevice API (Forward+ and Mobile rendering methods), and OpenGL 3.3 for its Compatibility rendering method.

The Project Manager defaults to OpenGL, so it works on most platforms. But then if the user's GPU / drivers don't support Vulkan, the process is subpar:

image

Users can select Compatibility and thus create a project they can work on, and the last selected option is remembered, so that's good. But they can also keep the default and end up with an error.

image

The dialog provides a workaround, but it's really subpar here too. You have to copy paste the line, open a terminal or create a shortcut and replace the command. And with the latter, this needs to be redone / updated every time you get a new Godot version.

(For the record, to re-create that error dialog on a system that supports Vulkan, you can fake lacking support by running Godot with VK_ICD_FILENAMES= godot (nothing after =).

Describe the feature / enhancement and how it helps to overcome the problem or limitation

We should implement a fallback from RenderingDevice rendering methods to the GL Compatibility renderer, similar to what we had in Godot 3.x with the fallback from GLES3 to GLES2.

We should aim to do it better than it was done in Godot 3.x, which served its role well to let users open a GLES3 project on a system that doesn't support GLES3, but didn't communicate well that this was happening.

I'd envision something like a dialog that notifies the user that the project they're opening requires Vuklan, and that it's not supported by their hardware. And then give them the option to:

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

There are two options we can try. Both might be needed for the best experience:

Project Manager side

We could aim to detect whether Vulkan is supported in the project manager, so that we can change the project creation dialog accordingly, e.g.:

Likewise, when choosing a project to edit in the project manager, we could parse that project's config to know which renderer it's using, and thus show appropriate warnings / dialogs to handle this gracefully (including maybe giving the option to convert the project to OpenGL).

Editor side

Project Manager UX improvements are definitely important, but it's still possible to edit a project directly without going through the project manager. So we need to also be able to handle a fallback from attempting to create a Vulkan renderer (and failing) to creating an OpenGL one.

We have code in the 3.x branch for that, and we also now have code that does this for OpenGL to ANGLE fallbacks, so this can be reworked to include Vulkan to OpenGL.


Aside from those two to improve the editor experience, there are cases to be made for allowing a similar fallback at runtime (in exported projects). This might be a matter for a separate proposal.

If this enhancement will not be used often, can it be worked around with a few lines of script?

n/a

Is there a reason why this should be core and not an add-on in the asset library?

n/a

Zireael07 commented 1 year ago

, there are cases to be made for allowing a similar fallback at runtime (in exported projects). This might be a matter for a separate proposal.

We already kinda sorta have separate proposals for that: #6207, #6177, #6909 and probably some others ;)

lostminds commented 1 year ago

One thing that I think should be considered both when it comes to the editor and exported games is that projects using Vulkan-renderers may rely on and vulkan-only features (like instance shader uniforms). This means that opening them in Compatibility mode might break them and not just look/perform worse. From a distribution point of view I think it can be better to have users with incompatible hardware get a clear message that they just can't run the game, instead of thinking they can due to the automatic fallback and then just getting something that crashes and doesn't work causing bad reviews.

With that in mind I think the automatic fallback to Compatibility mode should be controlled by a project setting for exported games, so that the developer can decide if they want to support this automatic fallback or not. And for the editor I think the project manager approach above is probably best, optionally with a clear warning about opening Vulkan-renderer projects in compatibility mode.

Calinou commented 1 year ago

From a distribution point of view I think it can be better to have users with incompatible hardware get a clear message that they just can't run the game, instead of thinking they can due to the automatic fallback and then just getting something that crashes and doesn't work causing bad reviews.

This is something we already agreed upon – it works this way in Godot 3.x currently :slightly_smiling_face:

The fallback will be enabled by default in the editor[^1], but disabled by default in exported projects. There will be a project setting to enable the fallback in exported projects.

[^1]: This needs to be done in the editor and not just the project manager, as some people open projects directly from the command line or external project manager applications like Hourglass.

lostminds commented 1 year ago

This is something we already agreed upon

That sounds great. I think that currently you get a dialogue that explains you can start the game with an extra argument to run it in compatibility mode? Even if that isn't automatic and will deter most users, it does kind of have the same risk and I don't think this can be disabled? And as RenderingServer.has_feature is not yet implemented, it's not trivial to check yourself if the game has access to all required features to run.

Note that there is also a risk of opening mobile/forward+ projects in the editor. As (again) shaders and materials using instance uniforms will break and become invalid. This also has the unfortunate effect that since they're invalid (I guess?) the editor will discard any such properties set in scenes (unset the material, shader parameters etc related to these materials) if you save a scene in Compatibility mode. So if you then switch back to Mobile/Forward+ and open the scene the offending material properties will be unset. But perhaps this should be considered a separate issue related to https://github.com/godotengine/godot-proposals/issues/6909, and not an argument against automatic Compatibility fallback when opening Mobile/Forward+ projects. If it was possible to avoid this discarding of things that are invalid in the current renderer (but may be supported in another) it would also make it easier to test compatibility by temporarily switching your project to Compatibility mode in the editor.

h0lley commented 5 months ago

This is very much needed not just for Godot users, but also for released games.

If a game is developed primarily for the Forward+ renderer but is also playable & looks presentable with OpenGL 3, then an automatic fallback should be an option (probably project setting), that then potentially provides a much better experience than the window suggesting to try the --rendering-driver command line flag (cannot be expected of players, most would probably just return the game).

Calinou commented 5 months ago

that then potentially provides a much better experience than the window suggesting to try the --rendering-driver command line flag (cannot be expected of players, most would probably just return the game).

You can provide predetermined Steam launch options that (I think) will pass CLI arguments to choose a rendering method at startup. Many released games on Steam do this (even the recently released Selaco :slightly_smiling_face:).

By predetermined launch option, I mean this dialog:

image

Since recently, Steam offers players a checkbox at the bottom of the dialog to permanently choose one of the options (which can be changed later in the game's properties). This way, they don't have to see this dialog every time they start the game.

You could provide options like this:

If Steam can't actually pass CLI arguments and can only launch different executables this way, you could have the second executable be a .bat script that starts the main executable with the appropriate CLI arguments.

h0lley commented 5 months ago

yes, thanks for listing the workarounds Calinou.

still desired as built-in feature none the less. :)

haltingstate commented 2 months ago

Does the OpenGL fallback work in Godot 4.3?

Calinou commented 2 months ago

Does the OpenGL fallback work in Godot 4.3?

No, this requires merging https://github.com/godotengine/godot/pull/91172 and using DisplayServer::can_create_rendering_deviced() at engine initialization time (before any rendering driver is initialized).

Calinou commented 2 months ago

In the meantime, you can force an existing project to use the Compatibility rendering method by adding this at the bottom of its project.godot file:

[rendering]

renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"

(If a rendering section already exists in project.godot, Godot will merge it automatically when the project is saved.)

RpxdYTX commented 1 month ago

One thing that I think should be considered both when it comes to the editor and exported games is that projects using Vulkan-renderers may rely on and vulkan-only features (like instance shader uniforms). This means that opening them in Compatibility mode might break them and not just look/perform worse. From a distribution point of view I think it can be better to have users with incompatible hardware get a clear message that they just can't run the game, instead of thinking they can due to the automatic fallback and then just getting something that crashes and doesn't work causing bad reviews.

With that in mind I think the automatic fallback to Compatibility mode should be controlled by a project setting for exported games, so that the developer can decide if they want to support this automatic fallback or not. And for the editor I think the project manager approach above is probably best, optionally with a clear warning about opening Vulkan-renderer projects in compatibility mode.

Considering that, wouldn't it be better to create an option for allowing the fallback on certain games, because while games could rely on specific vulkan-only features, some games could only have them as complements, and disabling them wouldn't impact gameplay.

If you're certain that your game don't need certain features, but it could be a great optional addition if supported, you could surely use that option to increase the compatibility of your game whilst still experiencing the benefits of modern libraries on the platforms that can support it. Since Vulkan is more performant than OpenGL, it could be an easy performance increase on vulkan platforms, while still retaining compatibility with the devices that don't really have Vulkan support.

Calinou commented 1 month ago

Since Vulkan is more performant than OpenGL

Vulkan in Godot is more high-end-oriented than OpenGL, so it is not guaranteed to be faster than OpenGL when drawing the kinds of visuals that the Compatibility rendering method can achieve. In fact, the opposite is more likely to happen in my experience. One exception is in scenarios where you have a massive amount of draw calls, but these are rare in low-end-oriented projects.

In short, Forward+ and Mobile (the rendering methods that are implemented in Vulkan) have a higher base cost than Compatibility (which is implemented in OpenGL), but they can scale better to high-end visuals.

In general, it's not really possible to say that a graphics API is definitely faster than another one on average, since it depends so much on the use case scenario and how the renderer was implemented.