elishacloud / dxwrapper

Fixes compatibility issues with older games running on Windows 10/11 by wrapping DirectX dlls. Also allows loading custom libraries with the file extension .asi into game processes.
zlib License
1.16k stars 83 forks source link

Option to select which GPU Adapter to use? #159

Closed ArhumMK closed 8 months ago

ArhumMK commented 1 year ago

dxwrapper works great in many games for me like Silent hill 3 and Witcher 1 EE. But there is a common problem I am facing for all the games I use this on. I have a dual-GPU laptop with a weak Intel UHD GPU and a NVIDIA MX series GPU, the one I use for games.

Using dxwrapper causes the games to use my Intel GPU regardless of my preference setting in my NVIDIA Control Panel. (It is set to use the NVIDA card for all applications) Despite that for whatever reason the Intel GPU is selected when I use dxwrapper according to the log files, performance is worse as a result too.

Attached a log for Silent Hill 3, but this happens on all games I have use dxwrapper for (mainly for the d3d8 to 9 feature) So, an option to select/force a certain GPU would be great, If possible that is, thanks for your work as always. dxwrapper-sh3.log

mirh commented 1 year ago

Control panel is just for opengl and vulkan. Directx has to be specified in windows. https://www.nvidia.com/content/Control-Panel-Help/vLatest/en-us/mergedProjects/nv3d/Setting_the_Preferred_Graphics_Processor.htm

elishacloud commented 1 year ago

Part of this has to do with what GPUs you have. In a lot of cases with laptops that have dual built-in GPUs the Intel one must be used for DirectX 8 and older, as the Nvidia one will only support DirectX 9 and newer. Usually there is a screen in the graphics Control Panel that allows you to chose the graphic card to use for DirectX 9 or newer games. See picture below.

As far as adding an option for games that are converted to use DirectX 9, I do have plans to add this feature when I get a chance. I will look into this soon.

image

ArhumMK commented 1 year ago

Ah I see, that's why the control panel has no effect here.

As far as adding an option for games that are converted to use DirectX 9, I do have plans to add this feature when I get a chance. I will look into this soon.

Then I look forward to the update soon! Thanks for looking into this, as dxwrapper opens up so many older games for me to run at anything more than 20 fps lol.

elishacloud commented 1 year ago

@ArhumMK, After looking at this, I am not sure if it is possible for me to change the adapter that is used. Can you try with this build and send me the logs? I need these logs to get some data from your video cards.

Here is the build: dxwrapper.zip

ArhumMK commented 1 year ago

Here's the log. Replaced the .dll, loaded a save and played for a few seconds. Not sure if it chose the other adapter though. I do see mention of the nvidia adapter in the log, idk. (Set to NVIDIA by default in the Control Panel). dxwrapper-sh3.log

elishacloud commented 1 year ago

The game is currently using the Nvidia GPU:

8880 14:57:51.778 m_IDirect3D9Ex::LogAdapterNames Adapter: 0 \\.\DISPLAY1 NVIDIA GeForce MX110

Also, DirectX only sees one GPU so there is no way I can tell the game to use anything other than the Nvidia card.

ArhumMK commented 1 year ago

Ah finally that's good to hear that the NVIDIA card's being used, thanks for implementing the changes!

mirh commented 1 year ago

Isn't newer windows going through Direct3D9ForceHybridEnumeration for device selection?

elishacloud commented 1 year ago

I'm running Windows 10 (latest build) on my laptop with both an Intel and Nvidia GPUs and I don't see that API at all:

image

mirh commented 1 year ago

https://github.com/crosire/reshade/commit/3fe0b050706fb9f3510ed48d619cad71f7cb28f2#diff-74772e50e2921e0bf69f0470e81d072d30c071b6e4b30af8cfd6cda58cf249ee Could the function just being exported by ordinal (and not by name) have anything to do with failures from your tool to detect it? At least last year with 20H2, that was so perilous that it even made for https://github.com/apitrace/apitrace/issues/704.

elishacloud commented 1 year ago

It looks like it works when you access it via the export ordinal. 👍 However, I don't like that though. Wrappers may have an export with the same ordinal but it calls a different function. I will need to make sure to load the System32 dll before calling it this way.

elishacloud commented 1 year ago

It looks like Direct3D9ForceHybridEnumeration only works if you have the integrated graphics card selected in the GPU's Control Panel. For instance, if you have specified the Nvidia graphics card selected in the Nvidia Control Panel it won't switch to the integrated card even if you manually try to switch it using Direct3D9ForceHybridEnumeration.

elishacloud commented 1 year ago

Here is an update that allows you to switch the graphics card. Just set the following:

GraphicsHybridAdapter     = 1

Here is the build: dxwrapper.zip

mirh commented 1 year ago

Did you also try to check what happens with the selection in the windows control panel? Because I'm pretty darn sure that the nvidia control panel did absolutely nothing on my optimus (no dedicated output) laptop.

elishacloud commented 1 year ago

Which windows control panel selection are you referring to? I only know about one open here:

image

mirh commented 1 year ago

https://www.amd.com/en/support/kb/faq/gpu-110 https://www.nvidia.com/content/Control-Panel-Help/vLatest/en-us/mergedProjects/nv3d/Setting_the_Preferred_Graphics_Processor.htm https://www.ghacks.net/2018/11/30/assign-graphics-performance-preferences-windows-10-programs/

elishacloud commented 1 year ago

That option from the Windows Control Panel works the same as the option from the GPU Control Panel on my laptop. Direct3D9ForceHybridEnumeration only works if you have the integrated graphics card selected in the Control Panel. If I have the Nvidia GPU selected then it will always use the Nvidia GPU and the Direct3D9ForceHybridEnumeration won't work to switch it back to the integrated one.

mirh commented 1 year ago

I'm really confident that while I was tinkering with https://github.com/doitsujin/dxvk/issues/1924, I had to go back and forth between the two different control panels.

https://www.nvidia.com/content/Control-Panel-Help/vLatest/en-gb/mergedProjects/nvcplENG/Using_Optimus_Hybrid.htm Maybe you are connected to an external display?

elishacloud commented 1 year ago

I did not have anything plugged into my laptop except a power plug (DC 12 volts) and a USB mouse. Once an application is set to use Nvidia in either control panel it will not use the integrated one by calling Direct3D9ForceHybridEnumeration. The Direct3D9ForceHybridEnumeration API only works to switch from the integrated one to Nvidia, not the other way around.

I can chose either graphics card from the control panel, but from Direct3D9ForceHybridEnumeration it only lets me chose the Nvidia card.

mirh commented 1 year ago

Ok so, I just observed this funny mixed bag (at least with 31.0.101.2115, 531.41 and 22H2):

But as far as api calls go, I'm not really making any claim about when it gets to be used or not (from some source code I could gather, the related GetHybridOverride function would indeed seem to suggest your understanding).

mirh commented 11 months ago

Ok, the first point is actually documented here to be fair (even though, you wonder what changed since 1803 then) But I'd like to point out how much stupid convoluted this could further be for opengl (which I reckon isn't probably your forte, but who knows the ways of the world).

I was in the process of doing some vsync latency tests on my desktop, so I set up a kind of hybrid scenario: the 9600k hooked to the HDMI port of my monitor, and the 2080S hooked to the displayport one. And then I started to check what happens when the rendering of a window isn't happening on the same gpu than the one owning its screen.

When the system main display is the Intel's, everything is nice and dandy as you would expect. You set whatever the hell you want inside Windows' "graphics settings" and you can call it a day with switching. But when the nvidia one is the main.. Fuck it. No matter what you do, their gpu is always gonna be used. There's also no point using NVCP, since they don't offer the "preferred graphics processor" drop down menu on desktops (and neither seems SHIM_RENDERING_MODE, aka "Enable application for Optimus", to be working from within profile inspector).

p.s. I also just discovered of advanced optimus

elishacloud commented 8 months ago

This has been added with the latest release. See here: GraphicsHybridAdapter