Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement changing RenderingDevice at runtime #6423

Open
SeleDreams opened this issue Mar 4, 2023 · 7 comments
Open

Implement changing RenderingDevice at runtime #6423

SeleDreams opened this issue Mar 4, 2023 · 7 comments

Comments

@SeleDreams
Copy link

SeleDreams commented Mar 4, 2023

Describe the project you are working on

I'm working on a 3D platformer on Godot 4

Describe the problem or limitation you are having in your project

Currently, the rendering device is defined at startup by godot with no ability to change it except through CLI directly at startup. This is inconvenient. lots of games allow to change the backend in the graphics settings at runtime.

One advantage would be to allow the game to start in the compatibility mode like opengl 3 at first to guarantee that the game will properly start and then allow to move to vulkan at runtime

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

Adding a function allowing to select the RenderingDevice to use at runtime

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

a function such as RenderingDevice.select(VULKAN_FORWARD) etc

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

I am not aware of workarounds apart from making a separate program that would start the game with CLI arguments

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

This is a core aspect of godot's hardware abstraction layer

@Calinou
Copy link
Member

Calinou commented Mar 4, 2023

This requires refactoring the renderers to be able to cleanly start and shut down while the engine is running (similar to /vid_restart in id Tech games).

This is a worthwhile effort and will help in many situations (e.g. suspend on Linux or restoring context on Android/iOS), but it's a lot of work to get right. If we also recreate the main window (which will most likely be needed), this is also an opportunity to allow switching DisplayServers and rendering methods at run-time.

The current workarounds available are:

  • Write a project settings override file from your project, and make sure its path is specified in the Project Settings before exporting the project (or use the default path). This can be done with the help of the ConfigFile class, as the syntax is the same. See Overriding in the ProjectSettings class documentation.
  • Use OS.set_restart_on_exit() with the --rendering-method forward_plus|mobile|gl_compatibility CLI argument specified. If the user has specified a non-default rendering method in their settings beforehand, restart the game with those arguments as soon as it starts.
    • Alternatively, you can provide several launch options on Steam, each of them mapping to a rendering method. (Steam now allows choosing a launch option permanently, so it's not as annoying these days.)

@Calinou Calinou changed the title Changing RenderingDevice at runtime Implement changing RenderingDevice at runtime Mar 4, 2023
@OverloadedOrama
Copy link
Contributor

OverloadedOrama commented Mar 4, 2023

@Calinou the workaround doesn't appear to be working if the project has been exported with the compatibility renderer. Running it with either --rendering-method forward_plus or --rendering-method mobile with gives an error ERROR: Cannot instantiate RenderingDevice-based renderer with renderer type gl_compatibility and crashes with a segmentation fault. Not sure if this is a bug or intended behavior (should a bug report be opened for this?). This is a deal breaker, since devices that don't support Vulkan will not be able to run a project that uses Vulkan by default at all, without manually messing with CLI first, which isn't user friendly. A better workaround for this proposal would be this godotengine/godot#58927.

@Calinou
Copy link
Member

Calinou commented Mar 8, 2023

Running it with either --rendering-method forward_plus or --rendering-method mobile with gives an error ERROR: Cannot instantiate RenderingDevice-based renderer with renderer type gl_compatibility and crashes with a segmentation fault. Not sure if this is a bug or intended behavior (should a bug report be opened for this?).

This sounds like a bug. The rendering driver should be changed automatically if using a rendering method that requires a different rendering driver.

In the meantime, use --rendering-method forward_plus --rendering-driver vulkan. Note that there's no way to query whether the graphics card supports Vulkan from scripting, so you need to make sure to have a "safe mode" that always boots the game in OpenGL (e.g. a Steam launch option).

@trollusk
Copy link

Describe the project you are working on

I'm working on a 3D platformer on Godot 4

Describe the problem or limitation you are having in your project

Currently, the rendering device is defined at startup by godot with no ability to change it except through CLI directly at startup. This is inconvenient. lots of games allow to change the backend in the graphics settings at runtime.

One advantage would be to allow the game to start in the compatibility mode like opengl 3 at first to guarantee that the game will properly start and then allow to move to vulkan at runtime

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

Adding a function allowing to select the RenderingDevice to use at runtime

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

a function such as RenderingDevice.select(VULKAN_FORWARD) etc

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

I am not aware of workarounds apart from making a separate program that would start the game with CLI arguments

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

This is a core aspect of godot's hardware abstraction layer

I started working on a Godot 4 project on one computer, then tried to open the project on another computer only to be told "Your video card drivers seem not to support the required Vulkan version". Impossible to open the project for editing, unless I manually fiddle with project.godot in a text editor.

It should just say "Would you like to use OpenGL instead?"

I'm no expert on these matters, but why does the choice of graphics driver need to be hardcoded into each project? Wouldn't it make more sense for it to be an editor-specific option, and only finalise it for your project when building a distributable version?

@Calinou
Copy link
Member

Calinou commented Mar 24, 2023

@trollusk This is unrelated: godotengine/godot#58927

I'm no expert on these matters, but why does the choice of graphics driver need to be hardcoded into each project? Wouldn't it make more sense for it to be an editor-specific option, and only finalise it for your project when building a distributable version?

Different rendering methods have different visual outputs (due to a different feature set for each). Offering a fallback requires careful planning and work put into every rendering method (on your side), so you don't end up with broken visual outputs when the project is running with certain rendering methods. For instance, SDFGI and VoxelGI are only available when using the Forward+ rendering method, not Mobile or Compatibility. Even without those GI techniques, lighting output can differ significantly between rendering methods.

Like in Godot 3.x, this will be supported once the OpenGL fallback is added, but it'll have to be something you enable explicitly for exported projects (due to the visual differences you need to cater for).

@snan9
Copy link

snan9 commented Aug 20, 2023

* Use `OS.set_restart_on_exit()` with the `--rendering-method forward_plus|mobile|gl_compatibility` CLI argument specified. If the user has specified a non-default rendering method in their settings beforehand, restart the game with those arguments as soon as it starts.

@Calinou, OS.set_restart_on_exit(true, ["--headless"]) works fine for me. As does OS.set_restart_on_exit(true, ["--quit"]).

OS.set_restart_on_exit(true, ["--rendering-method gl_compatibility]) doesn't work though. It just restarts like normal with Forward Plus. I also tried with the equal sign, like so: OS.set_restart_on_exit(true, ["--rendering-method=gl_compatibility"])

It seems like key=value arguments do not work for me. I tried some other key=value arguments and they're also ignored. All the command line arguments work fine if I launch the game in the Linux terminal though.

Is this a bug or am I doing something wrong?

@Calinou
Copy link
Member

Calinou commented Aug 20, 2023

It seems like key=value arguments do not work for me. I tried some other key=value arguments and they're also ignored. All the command line arguments work fine if I launch the game in the Linux terminal though.

You need to use ["--rendering-method", "gl_compatibility"]. Godot currently doesn't support = syntax in engine CLI arguments, but user arguments may implement support for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants