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

Expose RenderingServer methods to get rendering driver and method name #85430

Merged

Conversation

Calinou
Copy link
Member

@Calinou Calinou commented Nov 27, 2023

This is useful for troubleshooting purposes and debug menus, as it obeys automatic fallbacks and CLI arguments unlike when reading the project settings.

This also improves related documentation in ProjectSettings.

PS: --headless doesn't use the dummy driver that is listed in the list of valid rendering drivers when using --rendering-driver list. Is that expected? For this reason, I didn't list it in the documentation.

bin/godot.linuxbsd.editor.x86_64 --path /tmp/4/ --headless
Godot Engine v4.2.rc.custom_build.5df986796 - https://godotengine.org

Rendering driver: vulkan
Rendering method: forward_plus

@Calinou Calinou requested review from a team as code owners November 27, 2023 11:44
@Calinou Calinou added this to the 4.3 milestone Nov 27, 2023
@Calinou Calinou force-pushed the os-expose-rendering-driver-method branch 2 times, most recently from 7d43035 to 91cb11d Compare December 3, 2023 17:29
doc/classes/OS.xml Outdated Show resolved Hide resolved
doc/classes/OS.xml Outdated Show resolved Hide resolved
@Calinou Calinou force-pushed the os-expose-rendering-driver-method branch from 91cb11d to 7ae69b7 Compare December 6, 2023 22:11
@akien-mga
Copy link
Member

akien-mga commented Dec 7, 2023

Exposing this makes sense to me, but I wonder why we put it in OS originally. This isn't really OS specific, but more something that reflects the engine configuration.

Wouldn't it be more appropriate in Engine, or in ProjectSettings?

We could still move the C++ OS implementation which wasn't exposed yet, the only potential compat breakage would be for C++ modules.

@Calinou Calinou force-pushed the os-expose-rendering-driver-method branch 2 times, most recently from c006e7f to c8c72e9 Compare December 12, 2023 15:49
@Calinou
Copy link
Member Author

Calinou commented Dec 12, 2023

Exposing this makes sense to me, but I wonder why we put it in OS originally. This isn't really OS specific, but more something that reflects the engine configuration.

I've moved the exposed method to Engine in a separate commit (should be squashed before merging). It still works after testing.

I chose to keep the internal method in OS to avoid any risk of regressions and preserve compatibility. The rendering driver has OS-specific interactions in particular, with ANGLE, Direct3D, etc.

@SheepYhangCN
Copy link
Contributor

Should Metal be added into the document since its support was added in #88199 ?

@Calinou Calinou changed the title Expose OS methods to get rendering driver and method name Expose Engine methods to get rendering driver and method name Aug 31, 2024
@Calinou Calinou force-pushed the os-expose-rendering-driver-method branch from c8c72e9 to eeebd19 Compare August 31, 2024 04:35
@Calinou
Copy link
Member Author

Calinou commented Aug 31, 2024

Should Metal be added into the document since its support was added in #88199 ?

Done (I also added a mention of d3d12).

@huwpascoe
Copy link
Contributor

Should this be removed?
https://docs.godotengine.org/en/stable/classes/class_os.html#enum-os-renderingdriver
I can't find anything that actually references it.

@SheepYhangCN
Copy link
Contributor

Should this be removed?
https://docs.godotengine.org/en/stable/classes/class_os.html#enum-os-renderingdriver
I can't find anything that actually references it.

This enum is useless for now, there is nothing using this.
So yeah this should be remove since the method will return string directly.

Copy link
Contributor

@huwpascoe huwpascoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably this enum should be deleted
https://docs.godotengine.org/en/stable/classes/class_os.html#enum-os-renderingdriver

And then it's good

Copy link
Member

@adamscott adamscott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine to me!

@akien-mga
Copy link
Member

akien-mga commented Sep 5, 2024

I've moved the exposed method to Engine in a separate commit (should be squashed before merging). It still works after testing.

I chose to keep the internal method in OS to avoid any risk of regressions and preserve compatibility. The rendering driver has OS-specific interactions in particular, with ANGLE, Direct3D, etc.

The problem with that is that we now have a discrepancy between the core C++ API (method in OS) and the scripting API (method in Engine). Which is a bit confusing for people using both, but also breaks the expectation for godot-cpp that the C++ extension API is as close as possible to the C++ one, allowing a (relatively) easy path between C++ modules and C++ extensions.

So if it can't be moved from OS to Engine in core, I'd keep it exposed in OS to be consistent. But I don't see a problem with moving it from OS to Engine, rendering code can include core/config/engine.h just fine, no?

@mubinulhaque
Copy link

So if it can't be moved from OS to Engine in core, I'd keep it exposed in OS to be consistent. But I don't see a problem with moving it from OS to Engine, rendering code can include core/config/engine.h just fine, no?

Is this the only merge blocker? Testing games is getting harder, now that the RD renderers support multiple drivers. For example, a common problem is that some GPUs come with bad Vulkan drivers, but good D3D12 drivers. Being able to know the currently used rendering driver is important for end-users to know how best to play our games.

@akien-mga
Copy link
Member

The problem with that is that we now have a discrepancy between the core C++ API (method in OS) and the scripting API (method in Engine). Which is a bit confusing for people using both, but also breaks the expectation for godot-cpp that the C++ extension API is as close as possible to the C++ one, allowing a (relatively) easy path between C++ modules and C++ extensions.

These are the changes needed to keep things consistent: akien-mga@3a1117c

WDYT @clayjohn?

Alternatively, we can keep it in OS and expose it in OS to scripting.

@akien-mga akien-mga modified the milestones: 4.x, 4.4 Sep 26, 2024
@clayjohn
Copy link
Member

clayjohn commented Oct 1, 2024

We discussed in the rendering meeting. We think that we should investigate exposing it through the RenderingServer as that is the most natural place for these methods to exist.

While the indirection is awkward, it should be much nicer from a user point of view

@Calinou
Copy link
Member Author

Calinou commented Oct 2, 2024

We discussed in the rendering meeting. We think that we should investigate exposing it through the RenderingServer as that is the most natural place for these methods to exist.

Done.

While I'm thinking about it, I wonder if I should name the exposed methods as such:

  • RenderingServer.get_current_rendering_driver_name()
  • RenderingServer.get_current_rendering_method_name()

Right now, we have the following which is inconsistent:

  • RenderingServer.get_current_rendering_driver_name()
  • RenderingServer.get_current_rendering_method()

We don't have exposed enums for the rendering drivers and methods (an unexposed enum for the rendering driver already exists). We should probably add one for the rendering method and expose both enums. This would allow creating and exposing the following enum-based methods:

  • RenderingServer.get_current_rendering_driver()
  • RenderingServer.get_current_rendering_method()

This would allow users to make comparisons that are not string-based, therefore not being prone to typos (while also allowing for autocompletion to work). We should probably decide on this before merging the PR, as changing method names later on would break compatibility.

What do you think?

This is useful for troubleshooting purposes and debug menus.
@Calinou Calinou force-pushed the os-expose-rendering-driver-method branch from eeebd19 to 4a70ac2 Compare October 2, 2024 14:08
@Calinou Calinou requested a review from a team as a code owner October 2, 2024 14:08
@Calinou Calinou changed the title Expose Engine methods to get rendering driver and method name Expose RenderingServer methods to get rendering driver and method name Oct 2, 2024
@akien-mga
Copy link
Member

TIWAGOS and I'd let the rendering team decide, but yes I feel exposing an enum version of those methods might make sense. And our internal code should likely also be refactored to use the enums, the string comparisons we have throughout the rendering code are a bit awkward.

@SheepYhangCN
Copy link
Contributor

Is it worth to make it enum?
If we made it enum, then it should replace all of the original strings, otherwise I don't think it is worth to do
And it will be a lot of work to replace all of it

@huwpascoe
Copy link
Contributor

Regardless of the outcome, there's an existing enum that despite being exposed, doesn't seem to be referenced anywhere:
https://docs.godotengine.org/en/stable/classes/class_os.html#enum-os-renderingdriver

@Calinou
Copy link
Member Author

Calinou commented Oct 2, 2024

Regardless of the outcome, there's an existing enum that despite being exposed, doesn't seem to be referenced anywhere: docs.godotengine.org/en/stable/classes/class_os.html#enum-os-renderingdriver

Ah, that's what I meant actually. The enum is exposed, it's just not usable anywhere in the scripting API since no methods return it.

@clayjohn
Copy link
Member

clayjohn commented Oct 2, 2024

We discussed using enums for a very long time during the initial 4.0 rewrite. I was in favour of them at the time. But the consensus was that we wanted to eventually allow people to add new rendering methods and rendering drivers through GDextensions. Having a closed enum would make that very challenging.

@kisg
Copy link
Contributor

kisg commented Oct 17, 2024

I agree, that using Strings allows for future expansion and adding additional renderers at runtime using GDExtensions. However, it would be great to have a way to validate the string values. An option would be to have a
Dictionary RenderingServer::get_supported_rendering_drivers()

and

Dictionary RenderingServer::get_supported_rendering_methods()

In these dictionaries the keys would be the valid settings of the get_current_rendering_*() methods, while the values could be an additional Dictionaries with information specific to the driver / rendering methods (could even be reserved for future use).

That said, I think that this should be implemented in a separate PR.

@Chubercik
Copy link
Contributor

I'd like to chime in if I may: I was researching whether or not it was possible to check the rendering method idiomatically, because I wanna use a feature unavailable in the Compatibility renderer on Mobile and Forward+ builds, but also have a fallback to a feature that's supported, to have feature-complete web builds. Am I right to believe this isn't achievable as of 4.3 without something like supporting two scene duplicates at once, one for desktop/mobile and one for web, but with this PR it's possible to spawn different nodes depending on the platform programmatically?

@Calinou
Copy link
Member Author

Calinou commented Nov 8, 2024

Am I right to believe this isn't achievable as of 4.3

This can be achieved in 4.3 with the following code:

if ProjectSettings.get_setting_with_override("rendering/renderer/rendering_method") == "gl_compatibility":
	print("Using Compatibility")
else:
	print("Using Forward+/Mobile")

The _with_override() is important here, as we want to get the setting's value taking feature tags into account. The web platform always uses gl_compatibility since it has a .web override for the Rendering Method project setting.

The downside of this approach is that it doesn't take CLI argument overrides into account, nor automatic fallbacks that may happen on unsupported GPUs (but this isn't implemented in 4.3 anyway, only 4.4).

Comment on lines +2070 to +2073
String RenderingServer::get_current_rendering_driver_name() const {
// Needs to remain in OS, since it's actually OS that interacts with it, but it's better exposed here.
return ::OS::get_singleton()->get_current_rendering_driver_name();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would still challenge this comment. In what way does OS interact with this? It just seems like the value was parked there for ease of access, but it could as well be in RenderingServer a priori. It's mostly set from DisplayServer implementations which should have access to both singletons.

I'll have a look to confirm.

Copy link
Member

@akien-mga akien-mga Nov 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've confirmed these can be moved to RenderingServer without problems with akien-mga@3a94368.
So I think we should do it properly (amending in my commit should do the trick).

And also moved OS::_is_gles_over_gl that similarly doesn't need to be in OS, and removed the getter for _display_driver_id, was never used since it was added in 2020.

Copy link
Member

@akien-mga akien-mga Nov 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually some CI tests are failing with my branch. I'll look into it further. Seems like the editor crashes on start.

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still insist we do this properly by moving the C++ members to RenderingServer too.

Comment on lines +2070 to +2073
String RenderingServer::get_current_rendering_driver_name() const {
// Needs to remain in OS, since it's actually OS that interacts with it, but it's better exposed here.
return ::OS::get_singleton()->get_current_rendering_driver_name();
}
Copy link
Member

@akien-mga akien-mga Nov 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've confirmed these can be moved to RenderingServer without problems with akien-mga@3a94368.
So I think we should do it properly (amending in my commit should do the trick).

And also moved OS::_is_gles_over_gl that similarly doesn't need to be in OS, and removed the getter for _display_driver_id, was never used since it was added in 2020.

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I admit defeat for now, would need to look a bit more into why the editor crashes if the C++ getter is moved to RenderingServer. I still think this could be done, but requires more work, which could be done later.

@Repiteo Repiteo merged commit 4b447ec into godotengine:master Nov 11, 2024
19 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Nov 11, 2024

Thanks!

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

Successfully merging this pull request may close these issues.

Expose methods to get the current rendering driver/method in use