protonscr

Root signature long haul [Nvidia]

vkd3dclosed
HansKristian-Work/vkd3d-proton#928 · opened 2021-11-29 by RoyShapiro · updated 2022-01-15 · 3 comments · github
RRoyShapiro 2021-11-29 github

This is more of an annoyance (or seems that way) than an actual bug, but some games,
say Deliver Us The Moon (but there are others), take a very long time to load, with terminal being filled with messages like:
NUMBER:fixme:d3d12_root_signature_init_global: Ignoring root signature flags 0xFU.
Where NUMBER is a decimal number, and FU is a 1 or 2 digit hexadecimal.

Maybe a coincidence, but all of said games are from GOG and thus don't benefit from Steam's shader cache.

This seems to take much longer (speaking of orders of magnitude) on Nvidia cards than on AMD cards.
For example, on an AMD card, the number of such messages can be 10-15, and it only takes 10 seconds, and the hexadecimals don't seem to repeat themselves, while on Nvidia card the same game with the same settings can take upwards of 1 minute 30 seconds, and the hexadecimal numbers seem to cycle multiple times with the number of such lines being in the hundreds.

Taking the naive approach:
At first, considering that the games otherwise run fine, I thought that that's a typical "stdout makes things run slow" kind of issue, so I tried "VKD3D_DEBUG=none" and even commenting out the respective line in the code, but the games still take the same time to load, just without the messages.
And if the whole code block is made to skip root sigs with the same id (like make an array, if it's in array skip it, otherwise do it and add to array), then visual artifacts such as missing objects, textures e.t.c, start to appear en masse indicating some sort of shader failure. So my second hunch that something just loops unnecessarily is also false.

I certainly know precious nothing about root signatures (other that they allow shaders to access resources, but I don't seem to recall that from D3D9 times), so I don't understand how it works.
If anyone can spare a little time to enlighten me as to what is happening during this long load and why it takes so long on Nvidia, it would be wonderful.

Thanks in advance,
Roy

HHansKristian-Work maintainer 2021-11-29 github

Creating a root signature maps to vkCreatePipelineLayout in Vulkan, and I have seen vkCreatePipelineLayout take 5 ms on NV in the past for unknown reasons. It should be closer to 5 microseconds ... If a game spams that call I can see perf taking a hit.

RRoyShapiro 2021-12-02 github

@HansKristian-Work Thank you!
I've made a few naive measurements using gettimeofday (yes, not exactly the "best" tool to measure such a thing, but for a quick & dirty approach...), and on my Nvidia RTX 3090 (power limit of 250 watts imposed, but the same occurs without it too, it might affect measurements, though) it takes between 11ms to 32ms (0.012s being the most common) for each vkCreatePipelineLayout call in problematic games. So, about twice your measurements for NV (O_o).
You're absolutely right: the games that have the problem spam this function like crazy.

RRoyShapiro 2022-01-15 github

If anyone else still has this issue, as @HansKristian-Work points out, it has to do with how Nvidia drivers process vkCreatePipelineLayout calls.
Updating the drivers to the recent 470.94 or 495.46 branches (although the latter one one bugs out with raytracing in any UE games, but that's a whole different story) fixes the problem.
With either driver vkCreatePipelineLayout is virtually instant.

Launch options