godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
86.82k stars 19.43k forks source link

Godot Editor engages dedicated 3d card on laptop, against both windows and nvidia driver settings. #81870

Open mrcharles opened 10 months ago

mrcharles commented 10 months ago

Godot version

v4.1.1.stable.mono.official [bd6af8e0e]

System information

Godot v4.1.1.stable.mono - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 2060 with Max-Q Design (NVIDIA; 31.0.15.3187) - Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz (16 Threads)

Issue description

When developing on my laptop, I force engines to use the intel integrated video card to save battery when I am not plugged in.

I do this either with Windows' Graphics Settings Performance Preferences (Godot executable set to "power saving"), or NVidia's own Control Panel (Manage 3D settings -> Program Settings -> Godot executable set to prefer Integrated Graphics.)

However, neither of these systems work. They work for most software and game engines (including Unity).

I have found that if you manually change your project settings renderer to GL_Compatibility, the editor will no longer engage the dedicated graphics card, however, this is a project level setting and is not something a user should have to swap in order to choose a graphics card on a laptop.

Steps to reproduce

No sample code needed, on a laptop with both dedicated and integrated graphics, launch godot, create a new project, choose any renderer other than 'compatibility', note that dedicated 3d card is now engaged.

Minimal reproduction project

N/A

Zireael07 commented 10 months ago

Do other Vulkan apps also engage the dedicated card? Try a Vulkan benchmarking app

lewispollard-ctwo commented 10 months ago

https://github.com/godotengine/godot/blob/e3e2528ba7f6e85ac167d687dd6312b35f558591/drivers/vulkan/vulkan_context.cpp#L1200

It does seem that godot is intentionally choosing to favour discrete over integrated devices for the vulkan initialisation, rather than taking the preference from the OS. However the comment mentions this is due to an issue observed on Linux.

mrcharles commented 10 months ago

Do other Vulkan apps also engage the dedicated card? Try a Vulkan benchmarking app

Can you recommend one? I'll try it as a debugging step, but I don't expect this to be representative of the issue, as an intentional attempt to run vulcan should ignore an integrated card in favor of dedicated, but a tool running on windows should do what the user has requested.

Calinou commented 10 months ago

When using Vulkan, Godot always prefers the dedicated GPU when it finds one. This is intended behavior, but we should find a way to make it obey system preferences if possible. Is there an API to query these preferences?

I would check other Vulkan-based apps/games to see if they obey this preference. You can try vkcube that is part of the Vulkan SDK, for instance. You could also test GZDoom's Vulkan renderer option (it's not the default), with Freedoom game data.

See also https://github.com/godotengine/godot/pull/81752, which aims to expose GPU selection but the way it's done is currently not suitable for merging. What we can do as a temporary solution is to add a project setting to choose whether integrated graphics or dedicated graphics should be preferred when both are available, but this is only really suitable for non-game applications where you know you won't need high levels of 3D performance.

It does seem that godot is intentionally choosing to favour discrete over integrated devices for the vulkan initialisation, rather than taking the preference from the OS. However the comment mentions this is due to an issue observed on Linux.

This was also done as most games expect to be using the dedicated GPU for performance reasons. Accidentally using integrated graphics is a common pain point with hybrid graphics, and we found it better to err on the side of performance (as it's what people usually expect).

Zireael07 commented 10 months ago

@mrcharles Vk cube that @Calinou recommended is proably the fastest/easiest to check

mrcharles commented 10 months ago

Yes, the vkcube.exe does also ignore system preferences, as I expected.

mrcharles commented 10 months ago

This was also done as most games expect to be using the dedicated GPU for performance reasons. Accidentally using integrated graphics is a common pain point with hybrid graphics, and we found it better to err on the side of performance (as it's what people usually expect).

As a developer I entirely understand this, and definitely Windows/Nvidia settings are not good at picking sane defaults, but on the flipside, as a user, I will often force games to use integrated when I know they aren't going to be stressing my laptop, just to keep it cooler, and this usually works just fine.

I would be happy if there was simply a global setting for the godot editor to not use dedicated graphics, or even more ideally, not use dedicated graphics UNLESS running an instance of the game. That being said if the game window when you choose run is part of the same program as the godot editor, I understand that this in particular would be difficult.

Calinou commented 10 months ago

That being said if the game window when you choose run is part of the same program as the godot editor, I understand that this in particular would be difficult.

The running project is an entirely separate process, so it's feasible to run it on a different GPU. Once https://github.com/godotengine/godot-proposals/issues/7213 is implemented though, it may not be possible to use separate GPUs for the editor and running project due to shared memory communication limitations (unless you run them in separate windows again).

You can already force the editor to run on a specific GPU by running it with the --gpu-index N command line argument, where N is an index starting from 0. You can see the list of detected devices by running Godot with --verbose.

sakrel commented 10 months ago

When using Vulkan, Godot always prefers the dedicated GPU when it finds one. This is intended behavior, but we should find a way to make it obey system preferences if possible. Is there an API to query these preferences?

According to the Vulkan loader docs, the first device listed in vkEnumeratePhysicalDevices should already be the system preference on Windows:

On Windows, the loader will attempt to sort these objects so that the system preference will be listed first. This mechanism does not force an application to use any particular GPU — it merely changes the order in which they are presented.

https://github.com/KhronosGroup/Vulkan-Loader/blob/main/docs/LoaderDriverInterface.md#physical-device-sorting

As for the vk cube, it looks a lot like vk cube is also hard-coded to prefer dedicated GPUs. https://github.com/KhronosGroup/Vulkan-Tools/blob/main/cube/cube.c#L3656-L3685

KoTeYkA23 commented 10 months ago

According to the Vulkan loader docs, the first device listed in vkEnumeratePhysicalDevices should already be the system preference on Windows

That not always the case, I have desktop system with 2 GPUs (6700xt and 1070 specifically), and no matter what I chose in windows graphics settings the primary GPU will be always Nvidia one, I encounter it in my Unreal Engine game project too, so that Vulkan specific bug (or windows). And yes, windows graphics settings affect DX applications and 6700xt always default GPU

mrcharles commented 10 months ago

You can already force the editor to run on a specific GPU by running it with the --gpu-index N command line argument, where N is an index starting from 0. You can see the list of detected devices by running Godot with --verbose.

@Calinou this command line does not appear to propagate past the project manager to opening a project itself. It starts with the intel device, and then as soon as I load a project, it switches to vulkan.

image

KoTeYkA23 commented 10 months ago

@Calinou this command line does not appear to propagate past the project manager to opening a project itself. It starts with the intel device, and then as soon as I load a project, it switches to vulkan.

In 4.1.1 stable no, but in souce from main branch does.

pgrohe commented 9 months ago

I also noticed this issue on a laptop with AMD integrated + NVIDIA dedicated GPU.

I'd like to add that the --gpu-index N option does not work at all for me on Godot_v4.1.1-stable_win64. My device indices are 0 for AMD integrated, 1 for NVIDIA. Even when launching with --gpu-index 0 Godot will use the NVIDIA dedicated card. Both for the project manager and the editor itself.

The only way I've succeeded in getting Godot to use the AMD integrated graphics is by disabling the NVIDIA card entirely in the laptop's BIOS.

Calinou commented 9 months ago

I also noticed this issue on a laptop with AMD integrated + NVIDIA dedicated GPU.

This is a consequence of https://github.com/godotengine/godot/pull/73450, which had to be done due to outdated graphics drivers (which are unfortunately still common out there).

We could make it so the DISABLE_LAYER_AMD_SWITCHABLE_GRAPHICS_1 environment variable is only overridden if it's unset, not if it's explicitly set to 0. This way, you can set it to 0 manually.

alvinhochun commented 1 week ago

When using Vulkan, Godot always prefers the dedicated GPU when it finds one. This is intended behavior, but we should find a way to make it obey system preferences if possible. Is there an API to query these preferences?

According to https://stackoverflow.com/a/59732413, it isn't documented but apparently the GPU preferences are stored in registry under HKEY_CURRENT_USER\SOFTWARE\Microsoft\DirectX\UserGpuPreferences as REG_SZ with the name being the EXE path. The data is in the form GpuPreference=1;, with the values matching the DXGI_GPU_PREFERENCE enum - 1 being integrated and 2 being dedicated.

Someone claims the Default value applies to all programs (despite it not being an option in Windows Settings), but I haven't been able to verify it as I'm not sure if that requires a restart to take effect and I don't want to try that now.