X Tutup
Skip to content

Windows: Make Direct3D 12 the default RD driver for new projects#113213

Merged
akien-mga merged 1 commit intogodotengine:masterfrom
akien-mga:windows-d3d12-default
Nov 27, 2025
Merged

Windows: Make Direct3D 12 the default RD driver for new projects#113213
akien-mga merged 1 commit intogodotengine:masterfrom
akien-mga:windows-d3d12-default

Conversation

@akien-mga
Copy link
Member

@akien-mga akien-mga commented Nov 26, 2025

Direct3D 12 support was added for the Windows platform in Godot 4.3 by @RandomShaper and further refined in later releases by @DarioSamo (both sponsored by W4 Games, so I'll obama-medal-meme my company a bit).
In the 4.6 release cycle, @blueskythlikesclouds focused on fixing known issues with Direct3D 12, with the aim of making it the default RenderingDevice driver for Windows (this time sponsored by the Godot Foundation 🥇).

Why? Mainly because Vulkan support on Windows is giving us a lot of headache, with GPU drivers often being poorly maintained compared to their Direct3D 12 counterparts. We've seen many regressions in Nvidia and AMD drivers that would outright break Godot and games released with it (e.g. #109378 still ongoing). There are other issues such as Vulkan implicit layers which force us to use hacks to work around their harmful impact on Godot.

It's understandable, most Windows games use modern APIs target Direct3D 12 on Windows, and thus these are the drivers GPU vendors put most work and testing into.

So now that Direct3D 12 in Godot has more or less feature parity with Vulkan (see below), we want to try using it as the default option. See godotengine/godot-proposals#12234 for more arguments in favor of defaulting to Direct3D 12.

Some important aspects:

  • Edit: This only impacts new projects created in 4.6 or later. To use this new default in pre-existing Godot 4.5 projects, you should set the rendering/rendering_device/driver.windows project setting to d3d12 manually.
  • Vulkan is still available and can be selected via the rendering/rendering_device/driver.windows project setting, or --rendering-driver vulkan on the command line.
  • This PR attempts to preserve the behavior of pre-existing projects by explicitly setting the driver to vulkan if it was unconfigured (default) prior to upgrading to 4.6. (Uses the approach added by @KoBeWi in Add MeshInstance3D upgrade code #112607.) So by default, only new projects should default to d3d12.
    • Edit: Took a different approach in the end with similar results. Now vulkan stays the default for this setting, but d3d12 is configured automatically for new projects created in 4.6.
    • When upgrading from 4.5, you should therefore change rendering/rendering_device/driver.windows to d3d12 if you want to use the new default (recommended).
  • Compiling from source for Windows will now require downloading the dependencies needed by Direct3D 12. You can do it by running the misc/scripts/install_d3d12_sdk_windows.py script. Alternatively, you can compile with d3d12=no if you don't need it for your development work.
  • For PCVR users, we're aware that the Direct3D 12 backend doesn't have full parity with Vulkan yet (missing VRS and foveated rendering IIUC). So if that's a problem for your needs, you can switch back to Vulkan with the aforementioned project setting.
  • When using Wine to run Windows games on Linux/macOS, note that the system versions of Wine don't support Direct3D 12 by default. Godot should fallback gracefully to Vulkan in that case. On Steam/Proton, it should use Direct3D 12 by default through vkd3d-proton.

For compatibility reasons, `vulkan` is kept as the technical default for the
setting, but projects created in Godot 4.6 and later will set `d3d12` as the
driver automatically.

Users upgrading to 4.6 are recommended to adopt `d3d12` as a default if it
fits their needs.

Enable `d3d12=yes` by default in SCons so that custom Windows builds include
Direct3D 12 support.
Copy link
Member

@bruvzg bruvzg 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. I'm not sure which approach is best for the existing project settings.

@akien-mga akien-mga force-pushed the windows-d3d12-default branch from 9313bdf to b87fcf7 Compare November 27, 2025 09:57
@akien-mga akien-mga requested a review from a team November 27, 2025 09:57
@akien-mga akien-mga changed the title Windows: Make Direct3D 12 the default driver for RenderingDevice Windows: Make Direct3D 12 the default RD driver for new projects Nov 27, 2025
@akien-mga
Copy link
Member Author

akien-mga commented Nov 27, 2025

This PR attempts to preserve the behavior of pre-existing projects by explicitly setting the driver to vulkan if it was unconfigured (default) prior to upgrading to 4.6. (Uses the approach added by @KoBeWi in #112607.)

I changed the implementation to use @Calinou's approach in #105737 instead used for making Jolt Physics the default 3D physics engine only on newly created projects.

So this is now the same for D3D12, projects created in 4.6 will set rendering/rendering_device/driver.windows to d3d12 automatically, but the default stays vulkan for compatibility. This affects projects created either via the Project Manager or touch project.godot, as there's logic applying these changes to empty project.godot files.

This is a conservative approach that lets people use D3D12 by default on new projects but without risk of breaking projects in production. An advantage of this approach is that for users who select D3D12 explicitly in 4.6, and then switch back and forth between 4.5 and 4.6 for any reason, the setting will be preserved. With the former approach where the default value changed, the setting would be lost when it matches the engine version's default.

We could consider going further in 4.7 and fully changing the default to D3D12 without further compatibility code, so all projects would be upgraded by then (and could still select back Vulkan after upgrade).

We should document this well, both in the release page and in the online docs, so users understand that while their pre-existing projects aren't automatically updated, we strongly recommend that they switch to using D3D12 in production from 4.6.

We could consider having some sort of post-upgrade dialog that gives users some options on how to deal with compatibility changes:

  • Switch to Jolt Physics
  • Switch to D3D 12
  • Run the MeshInstance3D upgrade tool for skeleton paths
  • etc.

@lord-muad-dib
Copy link

on my configuration the d3d12 rd doesn't work well, the editor especially is very slow and it also affects every other app i'm running alongside godot, while on vulkan i don't see slowdowns. similar issues using either the igpu (intel u630) or the dgpu (nvidia 1050ti).
i hope the development of the vulkan rd for windows doesn't stop after this.
just my two cents, thanks

@DarioSamo
Copy link
Contributor

DarioSamo commented Nov 27, 2025

i hope the development of the vulkan rd for windows doesn't stop after this. just my two cents, thanks

Godot uses the same Vulkan RD for all platforms, there's no Windows-specific implementation. It can't really stop development.

@lord-muad-dib
Copy link

lord-muad-dib commented Nov 27, 2025

i hope the development of the vulkan rd for windows doesn't stop after this. just my two cents, thanks

Godot uses the same Vulkan RD for all platforms, there's no Windows-specific implementation. It can't really stop development.

yes i understand that, my remark is in context of this pr.. i mean, the team is willing to switch defaults because there are few kinks not working perfectly on windows yet. fine i guess (i might not think this is ready Yet, hence my comment, but i'm not The Community, so). i hope there's still will to keep vulkan on windows getting better, that's it,
best of luck on your work on the d3d12 rd, Dario and bluesky,
thanks

@clayjohn
Copy link
Member

the team is willing to switch defaults because there are few kinks not working perfectly on windows ye

The Vulkan backend works great and is our most polished graphics API backend. The problem we are solving here is the fact that every couple of months AMD and NVidia ship broken Vulkan drivers that break every single Godot game. We can't improve the quality of the drivers shipped by AMD and NVidia, so our only option is to avoid Vulkan on Windows

@akien-mga akien-mga merged commit bb7054c into godotengine:master Nov 27, 2025
20 checks passed
@akien-mga akien-mga deleted the windows-d3d12-default branch November 27, 2025 20:52
@Delsin-Yu
Copy link
Contributor

i hope the development of the vulkan rd for windows doesn't stop after this.

From the conversation here, it appears we are translating SPIRV to DXIL, which might explains the slower start-up time.

@TheAenema
Copy link

I'm working on my engine which is based on Godot and I'm porting the entire render and shader pipeline to D3D12 and HLSL. While moving fully to D3D12 I encountered the same startup performance issue.

Unfortunately, even with the changes @blueskythlikesclouds made, there is still a slowdown at startup. I spent the last two days tracking down the cause and here’s what I found:

The main reason for the slowdown is not the Godot renderer itself, but rather the core design of Godot by running multiple instances from the same executable.

Here's what's happening:

  • It seems Direct3D 12 does not handle running multiple instances of the same .exe name well. Godot maintains its own shader cache on D3D12, but the Direct3D 12 runtime also uses its separate cache system.
  • When the game is launched for the first time, the Direct3D 12 runtime creates a shader cache with the system-wide UID F4EB2D6C-ED2B-4BDD-AD9D-F913287E6768. This entry appears under C:\Users\<Username>\AppData\Local\D3DSCache\<App_Unique_Hash> and the process takes about 5–10 seconds.
  • This <App_Unique_Hash> is generated as a hash of the executable name. I couldn’t find documentation on how this hash is produced, but it seems deterministic with respect to the .exe name. (Example: godot.windows.editor.x86_64.exe36d7303850b645a8)
  • Now that the cache is created at C:\Users\X\AppData\Local\D3DSCache\9a3e6cf38014fb9a\F4EB2D6C-ED2B-4BDD-AD9D-F913287E6768.* a second launch of the game starts much faster because it reuses the D3DSCache. However, if another instance of the engine is already running, whether editor or runtime, it also attempts to access the cache. Since the cache is locked by the first process, the new instance falls back to full shader compilation, which adds another 5–10 seconds to startup.

It doesn’t matter whether we're running the editor, debug mode or runtime first. When one instance is already active, a second instance cannot use the cache in D3DSCache because it is locked by the first process.

I can think of two possible solutions at the moment:

  1. Install low-level hooks to virtualize engine access to the cache files. The flow would look like:
    Engine <-> D3D <-> Virtualized Layer <-> Cache File

  2. Compile the engine as a library (libGodot.dll) and provide two separate executables such as Editor.exe and Runtime.exe (by proxifying entrypoints). In this setup, the editor would launch the game using the Runtime.exe decoy instead of running it directly from itself.

I'm not certain whether implementing pipeline_cache_create would resolve this issue, but it may be worth trying.

bool RenderingDeviceDriverD3D12::pipeline_cache_create(const Vector<uint8_t> &p_data) {
    WARN_PRINT("PSO caching is not implemented yet in the Direct3D 12 driver.");
    return false;
}

void RenderingDeviceDriverD3D12::pipeline_cache_free() {
    ERR_FAIL_MSG("Not implemented.");
}

size_t RenderingDeviceDriverD3D12::pipeline_cache_query_size() {
    ERR_FAIL_V_MSG(0, "Not implemented.");
}

Vector<uint8_t> RenderingDeviceDriverD3D12::pipeline_cache_serialize() {
    ERR_FAIL_V_MSG(Vector<uint8_t>(), "Not implemented.");
}

Related issue: #103844

@lord-muad-dib
Copy link

i hope the development of the vulkan rd for windows doesn't stop after this.

From the conversation here, it appears we are translating SPIRV to DXIL, which might explains the slower start-up time.

if it was just the startup i wouldn't care much, actually....

the interface gets visibly slower, and it greatly affects other running apps aswell. alongside all the well known issues that are getting addressed.

with all due respects, d3d drivers of all manifacturers get regressions all the time, just like in vulkan is getting, and the godot community is just witnessing issues because vulkan was the de facto renderer everyone used so far...

but the choice has been made.. so..

@Mickeon
Copy link
Member

Mickeon commented Nov 29, 2025

but the choice has been made.. so..

The choice has been made just in time for the general public to test it. Feedback is always welcome.

@TheAenema
Copy link

TheAenema commented Nov 30, 2025

Follow up to #113213 (comment)
I implemented suggested solution and it boosted startup speed 6-8x faster.

Before proxifying (7000-12000ms per run) :

D3DSCache-Before-Fix.mp4

After proxifying (800-1500ms per run) :

D3DSCache-After-Fix.mp4

@blueskythlikesclouds
Copy link
Contributor

blueskythlikesclouds commented Nov 30, 2025

I don't understand why D3DSCache would make a difference. That cache gets used to store the output of DXBC -> DXIL conversion the runtime does, but Godot already provides DXIL shaders. On my system, the cache is only a few KBs, which I assume contains shaders from some third-party injection software I used before.

Copy link
Member

@RandomShaper RandomShaper left a comment

Choose a reason for hiding this comment

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

Late to the party, but wanted to express I'm very happy this is possible now

@Matheus49
Copy link

i never cared about vulkan anyways because it doesn't support old hardware so i just sticked with opengl, with this change will i still be able to compile godot without d3d12 support?

@KoBeWi
Copy link
Member

KoBeWi commented Dec 4, 2025

Yes.

@elvisish
Copy link

It's roughly twice as slow using D3D compared to vulcan for me:
image

compared to Vulcan:
image

@blueskythlikesclouds
Copy link
Contributor

It's roughly twice as slow using D3D compared to vulcan for me:

Are your frames limited to 60 FPS? The NVIDIA driver often downclocks the GPU to save power when the frame renders fast enough.

@elvisish
Copy link

It's roughly twice as slow using D3D compared to vulcan for me:

Are your frames limited to 60 FPS? The NVIDIA driver often downclocks the GPU to save power when the frame renders fast enough.

It's not frame limited, I'm on a 165hz screen so it should be rendering at least 165fps.

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

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

Use Direct3D 12 rendering driver by default on Windows
X Tutup