protonscr

DCS World smoke effect

dxvkclosed bugd3d11
doitsujin/dxvk#4327 · opened 2024-10-06 by muff11n · updated 2026-03-29 · 14 comments · github
1 matching comments, n / p to jump
Mmuff11n 2024-10-06 github

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

dcs1
dcs2

Did some "googling" and found 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.

BBlisto91 2024-10-07 github

@muff11n Hi there. Are you able to get a apitrace of the issue?

Mmuff11n 2024-10-07 github

@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

BBlisto91 2024-10-11 github

Apitrace made on Windows that reproduces the issue: https://drive.proton.me/urls/3TEP1NY8VC#9rHPLoXNgrqJ

Mmuff11n 2025-07-12 github

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

BbwRavencl 2025-07-12 github

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.

Ddoitsujin maintainer 2025-07-16 github

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.

FFell 2025-07-23 github

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:

Image

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.

Ddoitsujin maintainer 2025-07-23 github

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.

Mmuff11n 2025-07-24 github

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

thank you very much Fell and doitsujin

FFell 2025-07-24 github

Fix confirmed! 🎉

Image

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! ❤️

Mmuff11n 2025-07-24 github

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/
Mmbriar 2025-07-24 github

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.

Llogicmagix 2026-03-23 github

This issue has been resolved with kernel 6.14+ Wine 11.0 and GE Proton 10-9+. I am testing the standalone ChaosRifle DCS-on-Linux on Lutris 0.5.22 with GE-Proton 10-33, Wine 11.0, ntsync, kernel 6.19.9 (hand rolled) and nvidia drivers 595.44.03. Argument values and keys for Lutris under Game execution > Environment variables are MOUSE_RELATIVE_SCALING=1 PROTON_NO_FSYNC=1 PROTON_USE_NTSYNC=1 UMU_ID=1 WINE_NO_DELAYED_RPC_EVENTS=1 WINE_RT_PRIO_SERVER=1 WINE_SIMULATE_WRITECOPY=1 __GL_SHADER_DISK_CACHE=1 __GL_SHADER_DISK_CACHE_PATH=/home/$USER/

Image
Ssilentcobralord 2026-03-29 github

i have the exact same problem with my DCS