SpecialKO / SpecialK

Lovingly referred to as the Swiss Army Knife of PC gaming, Special K does a bit of everything.
https://www.special-k.info/
GNU General Public License v3.0
796 stars 48 forks source link

EnableVulkanBridge has some odd behaviors #82

Open mirh opened 1 year ago

mirh commented 1 year ago

So, first of all, I'd like to say that I believe the thing should only be doing "something" if vulkan is detected. Secondly it seems like only value -1 is able to disable the "will be enabled, a restart is required" request (0 still has the dialog triggering).

Last but not least.. for the longest time when putting together mass effect 1 with dgvoodoo and specialk (put aside like basic settings like TraceLoadLibrary=true or Force10bpcSDR=false) I always had to disable d3d9 and d3d9ex detection for SK to even show up at all. Yet if the vulkan bridge prompt comes out, somehow this last step isn't needed.

So it feels like either the popup is tampering with something that is should not, or that the there's something that could be improved in the API hooks logic.

Aemony commented 1 year ago

I'm not sure I'm following... Vulkan bridge should only be enabled if DXVK is being detected -- not dgVoodoo or D3D9 on their own?

Kaldaien commented 1 year ago

It should only be doing "something" if you set it to a value other than -1 and the driver profile for the game you're running doesn't have the necessary setup.

Driver resets this property every time you update Windows or install a new driver, so that's why SK keeps the =0 or =1 value in its INI, so that the next time you launch your game it knows to check whether the driver changed this setting behind our backs.


-1 is: Do Not Care 0 is: Disable 1 is: Enable

Only a value of -1 will ignore whatever setting the driver has for the game, the other two will ensure that the driver is set to enable or disable and they will prompt you to change the driver setting if, and only if, it does not match the preference in the INI.


For D3D9 games using DXVK, SK automatically sets everything up, the Vulkan Bridge, the disabled D3D9/D3D9Ex hooks, etc. Nothing's being tampered with, this is how it is designed to work. If the D3D9 hooks were not turned off, then SK would see the original game in D3D9, parts of the game in Vulkan, the driver interop layer in D3D11.

It needs to decide on an API to use, and ideally you don't want SK hooking into the original D3D9 code or the Vulkan code, cause all the important stuff it does is D3D11.

mirh commented 1 year ago

This makes sense.. but even though my local SK installation "had survived a previous run with DXVK and HDR", this time nothing of that was being used/loaded. So, the setting still tripping in a non-vulkan situation doesn't seem intuitive to me (it would be as if, I don't know, having AllowTearingInDWM=true blocked the game or something when just running in plain d3d9 mode).


As for the other problem I'll try to be even more clear:

d3d9=true
d3d9ex=true
EnableVulkanBridge=-1

this situation doesn't show the UI in-game

d3d9=true
d3d9ex=true
EnableVulkanBridge=0 (or 1)

this one instead, has everything working just fine. So, underlining again that no DXVK was present here, I hope you can understand why it's strange.

Kaldaien commented 1 year ago

Yes, if you remove DXVK then SK's no longer configured to use D3D9. You must reset the config file or set D3D9=true and D3D9Ex=true.

It's tripping because you set EnableVulkanBridge to a value other than -1, so it's always going to ensure the driver's configured to match that state, irrespective of any APIs the game uses. The only times EnableVulkanBridge is setup automatically are:

  1. Emulators known to use Vulkan
  2. Games known to use Vulkan
  3. DXVK's D3D9 DLL is installed locally

1 and 2 require intervention on my part, there's only a handful of games and emulators that offer that. Otherwise, it's up to you to turn it on. I can't simply turn this feature on by detecting that vulkan-1.dll has been loaded, because there are so many false positives.

mirh commented 1 year ago

Are there? Well, you are the boss. Even though the point was more about it being turned off when vulkan-1.dll isn't loaded, so if any any spurious detection would just give you back the current situation (or is there some way in heaven that vulkan could be used without the dll?😨)

Yes, if you remove DXVK then SK's no longer configured to use D3D9.

Yet it still works with it? And also with D3D11.

giias commented 1 year ago

Yet it still works with it?

It should, yes, if you reset the config file or set D3D9=true and D3D9Ex=true as kal mentioned.

if you still have D3D9=false and D3D9Ex=false from when the vulkanbridge option set them that way after you accepted the prompt at some point... then SK's no longer configured to use d3d9 (for that game at least), and without the DXVK dll, sk's not going to work in that d3d9 game anymore (unless you edit or reset your SK config basically). Check/edit the [API.Hook] section in the SpecialK.ini config and/or reset your SpecialK.ini config for the game.

mirh commented 1 year ago

if you still have D3D9=false and D3D9Ex=false from when the vulkanbridge option set them

Vulkanbridge does not set anything AFAICT (and I cannot understand what K meant with "no longer configured"). I am.

And I have to disable d3d9 for SK to work with dgvoodoo's d3d11. Normally. Except when vulkanbridge is engaged (yet of no use whatsoever because as I said there is no dxvk here) this extra step isn't needed then.

Aemony commented 1 year ago

if you still have D3D9=false and D3D9Ex=false from when the vulkanbridge option set them

Vulkanbridge does not set anything AFAICT (and I cannot understand what K meant with "no longer configured"). I am.

And I have to disable d3d9 for SK to work with dgvoodoo's d3d11. Normally. Except when vulkanbridge is engaged (yet of no use whatsoever because as I said there is no dxvk here) this extra step isn't needed then.

I am not sure I follow? This is a standard D3D9 game with SK:

[API.Hook]
LastKnown=8
ddraw=true
d3d8=true
d3d9=true
d3d9ex=true
dxvk9=-1
d3d11=true
d3d12=true
OpenGL=true

[NVIDIA.API]
DisableHDR=false
EnableVulkanBridge=-1
Disable=false

This is the same game after SK has detected the presence of DXVK and enabled the Vulkan Bridge:

[API.Hook]
LastKnown=64
ddraw=true
d3d8=true
d3d9=false
d3d9ex=false
dxvk9=1
d3d11=true
d3d12=true
OpenGL=true

[NVIDIA.API]
DisableHDR=false
EnableVulkanBridge=1
Disable=false

As Kal mentioned, SK's no longer configured to use D3D9 or D3D9Ex because its parameters are set to false. Removing DXVK won't restore the values of those parameters -- that needs to be done manually by the user (typically by removing the config file).

Aemony commented 1 year ago

The whole thing is controlled in the block of code below. If the user hits "Yes" to the "Enable native DXVK support?" prompt, SK changes the d3d9 and d3d9ex parameters to false, forced window mode, sets the dxvk9 and EnableVulkanBridge parameters to 1. It then saves the SK config and then runs the elevated call against the NVAPI to set the necessary parameters in the display drivers.

https://github.com/SpecialKO/SpecialK/blob/ced5f13e44e2d0dc8dcf0487c063867ebd183e89/src/render/render_backend.cpp#L154-L188

Aemony commented 1 year ago

Also, just using EnableVulkanBridge=1 will also disable the D3D9 and D3D9Ex parameters since SK_NvAPI_EnableVulkanBridge always sets those parameters to the opposite of what EnableVulkanBridge is set to.

It's basically a way to enforce that SK doesn't hook the native D3D9 API of a game when using the Vulkan Bridge (which means a DXGI interop layer will be used to present the game on the display).

https://github.com/SpecialKO/SpecialK/blob/ced5f13e44e2d0dc8dcf0487c063867ebd183e89/src/nvapi.cpp#L2360-L2369

Aemony commented 1 year ago

To summarize, I think what none of us here understand is why you're trying to use or otherwise enable the Vulkan Bridge when not using DXVK. Enabling Vulkan Bridge will disable D3D9/D3D9Ex for the game, yes, since the Vulkan Bridge is only relevant in those scenarios when using DXVK. It's not relevant in D3D11 scenarios or when using dgVoodoo 2.

mirh commented 1 year ago

This is the same game after SK has detected the presence of DXVK and enabled the Vulkan Bridge

Ok, I see now what kind of configuration we were talking about. Maybe I had missed that step when I first experimented with dxvk 2 months ago, and I was manually configuring the ini. That only happens with EnableVulkanBridge=1 though, now that I checked it.

It's not relevant in D3D11 scenarios or when using dgVoodoo 2.

I dissent (and I just figured the trick). Depending on whether your nvapi is configured for the EnableVulkanBridge=0 (0x20324987 2a5) or EnableVulkanBridge=1 (0x20324987 802a5) situations, when you switch to the other one of the "please do care" states in the SK .ini this will of course cause the dialog to come out. If you turn it down (i.e. meaning you press "cancel" and the game proceeds normally), When EnableVulkanBridge=0 SK will still internally process/work as if d3d9=false and d3d9ex=false despite the fact that both are enabled in the .ini and reported enabled in the UI (or if not any, dgvoodoo can work in this scenario).

In fact, I also just found something even wronger happening when you do actually use DXVK. I can see DXVK overlay and all (so I'm most definitively using vulkan) yet SK acts like the game was pure d3d9 (regardless of the state of dxvk9).

mirh commented 1 year ago

Ok, I think I solved the mystery now, after accidentally ending up reading a part of the changelog file. It is AsyncInit=false (which I understand the vulkan bridge to "imply" automatically) to make d3d11 work even without disabling the d3d9 hooks, not some other wrong voodoo.

So to sum up this mess, with the (very lowbrow) doubts that I'm left: