Windows Default RHI Selection chooses DX12 on older, incompatible devices

On an HD4000, we see flashing on our particle effects, though otherwise the game runs.

On a GT 730, we get a crash after an attempt to allocate a crazy amount of memory:

Transient allocator failed to allocate Texture SceneDepthZ. Extent: (2560, 1440), Depth: 1, ArraySize: 1, NumMips: 1. Allocation Size: 18446744073709551615, Allocation Alignment 65536

[Attachment Removed]

Steps to Reproduce
We get graphics issues when we run TFT on a low-end windows machine with an intel HD4000 or Nvidia GT 730 using the Default RHI for Windows. We were expecting the default setting to choose DX11 when appropriate, DX12 otherwise. But on these devices, the engine is choosing DX12, but we find the issues go away and the game runs just fine if we manually run with DX11. What are our options for managing this? Can device profiles be used to match based on GPU specific overrides? How do Fortnite or other projects manage this on windows?

[Attachment Removed]

Attached are some logs that illustrate what’s happening, this time with a Intel HD 520 + NVIDIA GeForce 940M. Even when windows/NVIDIA control panel specifying the NVIDA as the preferred GPU, the integrated GPU is chosen, which fails to allocate the depth/stencil render target.

With the default RHI (TFTDX12.log), the engine checks with DX12, which identifies the NVIDIA GPU as ‘basic render driver’, but the HD 520 presents itself as a valid option. So it selects the integrated GPU, which then fails a call to D3D12GetResourceAllocationInfo.

If we force it to DX11 via the command line, it appropriately picks the NVIDIA GPU, which functions just fine.

[Attachment Removed]

[Attachment Removed]

Hi Tommy,

Unfortunately, there is no concept of a “default” RHI per device, so it does not mean the engine will pick DX11 for older GPUs. The engine picks an RHI by iterating through a list of supported RHIs, with DX12 first. (see WindowsDynamicRHI.cpp:115). The HD4000 and GT730 GPUs both report DX12 feature-level 11_0 support, so DX12 wins. If you want to set a given RHI per GPU, you can take a look at the WindowsConfigRules system, which allows you to write a set of rules that are matched to the GPU vendor at runtime. We don’t have any public docs for the Windows side, but the Android guide is essentially the same: https://dev.epicgames.com/documentation/unreal\-engine/using\-the\-android\-configuration\-rules\-system\-in\-unreal\-engine. Just make sure you are compiling WITH_WINDOWS_CONFIGRULES set and check that WindowsDynamicRHI::ChoosePreferredRHI is properly picking DX11 over DX12. I hope that makes sense, but please let me know if you need any further info.

[Attachment Removed]

It looks like maybe that’s a 5.8 feature? I don’t see any WITH_WINDOWS_CONFIGRULES when searching the codebase. How is this configured in 5.7?

[Attachment Removed]

Sorry, I overlooked that you are currently on 5.7. If you plan on sticking to that version, you can create a DefaultHardware.ini file and list out the preferred RHI per GPU as seen below:

[Devices]
+DeviceForceRHIList=(RHI="D3D11_ES31", DeviceName="Intel(R) HD Graphics 4000")
...

Just so you know, this will permanently set the RHI for the device, and users cannot change it afterward. Since this list is cooked into the final game, an update to the list will require patching your game. With Windows Config rules, you can hot fix this list instead.

[Attachment Removed]

That sets both the RHI to DX11 and the feature level to ES31. Is there a particular reason to favor that over DX11 + SM5? Forcing it via command line still allows for the SM5 feature level. It would be easy enough for us to make an engine modification to mimic the DeviceForceRHIList logic, but only forcing DX11, not the feature level.

[Attachment Removed]

The snippet was merely an example from one of our own titles. Setting the RHI and feature level that low will use the mobile renderer path, which we have noticed players tend to prefer to get the most FPS. However, don’t take that as a source of truth, and feel free to go with DX11 feature level 11_0.

[Attachment Removed]

This one is the log when we force DX11.

[Attachment Removed]