DCS World smoke effect
System information
- GPU: 7800XT
- Driver: admgpu vulkan-radeon or amdvlk
- Wine version: Proton - GE-Proton9-15 or older, Wine latest or older
- DXVK version: latest or older
DCS smoke effect is not smooth/continuous, it's like running in a loop of repeating smoke effects/particles
Did some "googling" and find out it might have something to do with tessellation on AMD cards (on Windows you can force higher tessellation via Adrenalin, haven't found an option how to do it in linux).
Can't confirm if this issue also is present on NVIDIA cards.
@muff11n Hi there. Are you able to get a apitrace of the issue?
@muff11n Hi there. Are you able to get a apitrace of the issue?
yes, will provide one this week
so update: game crashes at the start when I was following this: https://github.com/doitsujin/dxvk/wiki/Using-Apitrace
and empty trace file was created
Apitrace made on Windows that reproduces the issue: https://drive.proton.me/urls/3TEP1NY8VC#9rHPLoXNgrqJ
tested with NVIDIA 5080, same issue
does dxvk.conf work with proton, tried to force d3d11.maxTessFactor = 64, but it hasn't fixed the issue
tested with NVIDIA 5080, same issue
does dxvk.conf work with proton, tried to force d3d11.maxTessFactor = 64, but it hasn't fixed the issue
You can simply set the environment variable DXVK_CONFIG="d3d11.maxTessFactor = 64;".
It doesn't make a difference though, as I understand it d3d11.maxTessFactor is meant to set a maximum tesselation factor to improve performance with certain applications., be default it is set to 0, i.e. no max. limit.
Correct, the option is an upper limit. The default upper limit is essentially 64 anyway.
FWIW, I have looked into this at some point in the past, but there's a huge mess of tessellation and geometry shaders involved in rendering these, and it's not really debuggable. Haven't seen anything outright suspicious though, so there is that.
I think I found it.
What I think is wrong
I think something is wrong about how the SV_TessFactor semantic is interpreted/populated for isoline tesselation domains. I think the order of the two values may be wrong.
Why I think that
DCS World comes with all its shaders in plain text in the DCSWorld/Bazar/shaders/ directory. It even inludes a VSCode workspace file. I took a good look at them and was able to identify that pipeSmoke.fx is responsible for rendering the chimney smoke, which is also effected by this puffyness bug. I verified that making changes to the file also changed the appearance of the chimney smoke in game.
DCS uses an isoline tesselation domain to turn a number of points into a wobbly spline of smoke.
Tesselation shaders have a patch constant function which sets the tesselation factor value SV_TessFactor. In DCS's case, the relevant member is called edges.
struct HS_PATCH_OUTPUT {
float edges[2] : SV_TessFactor;
float4 orderOffset: TEXCOORD7;
};
Now, all of their tesselation shaders look somewhat like this:
HS_PATCH_OUTPUT o;
o.edges[0] = 1; // detail factor
o.edges[1] = clamp(…, 1.0, 64.0);
Notice how they always set the first value to 1. They call that "detail factor". That comment is actually in the file. The second value is calculated somehow and then clamped between 1 and 64.
However, the Microsoft documentation states:
For an isoline, the first value in SV_TessFactor is the line-density tessellation factor, the second value is the line-detail tessellation factor.
So Microsoft says the detail factor is the second value, but DCS's shader code assumes it's the first. I think that DXVK simply follows the Microsoft documentation and that the documentation is just plain wrong in this case.
Dirty Hack Fix
I replaced all occurences of o.edges[0] = 1 with o.edges[0] = 64 in the entire Bazar/shaders directory and that actually fixed the chimney smoke:
I have not tested this hack with actual gameplay yet and I don't know what side effects it may have. DCS checks the shader files for modifications in multiplayer, so be careful if you want to apply this workaround for yourself.
I've found this independently too while working on dxbc-spirv stuff and it seems that we simply have an enum in the wrong order: https://github.com/doitsujin/dxvk/blob/629a5f0d2bb8f7d7241833cfcd1a9d9032c3bfe0/src/dxbc/dxbc_compiler.cpp#L6719-L6720
I don't know if flipping those lines round is really how it's supposed to work though, it's borderline impossible to test tessellation stuff and documentation sucks.
thanks for the dirty fix, I applied it on whole shaders folder, just 7 files and it fixed the smoke + F16 and I assume all the other stuff as well, need to test, but for now it looks very good, here a script for that:
--complete the whole path in the find
for file in $(find ".../DCS/Bazar/shaders" -type f -exec grep -l "o.edges\[0\] = 1; // detail factor" {} \;); do
echo ${file}
cp ${file} ${file}_original
sed -i 's/o.edges\[0\]\ =\ 1;\ \/\/\ detail\ factor/o.edges\[0\]\ =\ 64;\ \/\/\ detail\ factor/g' ${file}
done
Fix confirmed! 🎉
I built DXVK from source to confirm this. You can undo the shader modifications by running DCS_updater.exe repair. The smoke trails look even more correct now with the proper fix in place. My dirty hack definitely generated too many particles.
I'm so happy about this. Being able to see missile trails is a crucial part of DCS gameplay. Thank you so much for the record time fix @doitsujin! ❤️
does this also work in GE proton?
did download the newest build, copied the libraries to specified folders, set in protontricks winecfg libraries to native, but still have the bug
of course returned the bazar files to original state
and DXVK_HUD works
edit:
thank you very much (post below), that was it, just replaced the files in GE Proton directory:
sudo cp x64/*.dll ${HOME}/.local/share/Steam/compatibilitytools.d/GE-Proton10-8/files/lib/wine/dxvk/x86_64-windows/
sudo cp x32/*.dll ${HOME}/.local/share/Steam/compatibilitytools.d/GE-Proton10-8/files/lib/wine/dxvk/i386-windows/
For any kind of proton usage you have to replace the dxvk dlls of the proton distribution. Anything you do to the wine prefix gets undone by the proton launch script on game launch. But there is no need to mess with protontricks or winecfg library overrides in any way.