bo3b / 3Dmigoto

Chiri's DX11 wrapper to enable fixing broken stereoscopic effects.
Other
785 stars 124 forks source link

Why use 3Dmigoto in game will lead to GPU usage decrease and result in a huge decrease in FPS. #188

Closed StarBobis closed 7 months ago

StarBobis commented 9 months ago

d3dx.ini.txt Sorry to bother you,but i have tried hundreds of times recomplie and test but still can't solve it due to luck of d3d11 knowledge and not familiar with 3dmigoto code.

why use 3Dmigoto will cause a serious GPU usage decrease?

for some game like Naraka Bladepoint which will draw a lots of characters in the same time ,if i inject 3dmigoto into game, even i closed all hunting or logging ,it will also cause a huge GPU usage decrease(just inject into game and don't put anything in Mods or shaderfixes,i mean just a clean 3dmigoto).

Normally if there is only one character in the scence the GPU usage decrease will be 5~10%, lead to a 92% GPU usage. if there is 20 characters in the scence the GPU usage decrease will be around 50%, which lead to a huge FPS decrease (120FPS to 45 FPS).

And if there is 20 characters in the scence but if I turn my sight to a blank scene which don't have characters, i mean turn my head so my character can't see these characters, then the GPU usage will back to 90% , if I turn around to look these 20 characters again, my GPU usage will decrease to 40%~50%.

And this happend even I do not add any mod into game, so it's something under the hood of 3Dmigoto,but I don't know what it is, if i don't use 3dmigoto in game,the GPU usage is always 100%,but inject 3dmigoto will cause this problem.

I have tried to delete part of the functions in 3Dmigoto and recompile and inject and test again and again,but still can't find out where is the real mechanism for this problem, When I ask ChatGPT, it tells me it's due to extra cpu time in 3dmigoto's d3d11 hook functions,so lead to GPU can't run all the time,so GPU usage is decrease.

So can I ask about the underlying operating mechanism of 3DMigoto, as well as the possible reasons why the GPU cannot reach 100% occupancy, is it due to CPU latency or something? If you could tell me which possible codes in 3DMigoto can find relevant adjustments, it would be even better.

leotorrez commented 8 months ago

With all due respect, trusting in ChatGPT for this kind of question is a poor judgement. I advice studying 3dmigoto source code and the usage of debug tools in order to get a better understanding of its innerworkings.

There are several configurations in d3dx.ini that can lessen your issue and they are explicitly mentioned in the same file. I recommend taking a good read of it as well as the wiki of this repository.

StarBobis commented 8 months ago

With all due respect, trusting in ChatGPT for this kind of question is a poor judgement. I advice studying 3dmigoto source code and the usage of debug tools in order to get a better understanding of its innerworkings.

There are several configurations in d3dx.ini that can lessen your issue and they are explicitly mentioned in the same file. I recommend taking a good read of it as well as the wiki of this repository.

Thanks for your advice.

DarkStarSword commented 8 months ago

If you are going to do any profiling yourself, the best tools to consider are:

A few other things to consider:

Feel free to share any findings here - both Bo3b and I have done significant work profiling and optimising 3DMigoto in the past and can help examine / interpret any results.

bo3b commented 8 months ago

I'll add that the ChatGPT advice is generic, and not specific to 3Dmigoto. All the current AI output is generic.

The last time I profiled 3Dmigoto with nothing enabled, just for the hooks themselves, I measured less than 1% of CPU usage as lost to our hooking and following DX11 calls.

StarBobis commented 8 months ago

Thanks for your reply !

After lots of tests between games, i finally find the problem, all config in d3dx.ini is same and the only difference is the NvAPIOverride() , in NarakaBladepoint the NvAPIOverride() function will always fail, seems it will lead the game can't use all functionality in NVDIA so cause a GPU usage decrease but i'm not 100% sure about it.

In NarakaBladepoint the d3d11_log.txt always show: image

But in most of other game,it will success like this: image

So i guess there is some reason lead 3dmigoto can't override NVAPI wrapper, this may caused by it's "NEAC" windows driver anyicheat (i guess 3dmigoto can't get enough privilege on runtime).

I did some performance test on some GPU animation games which also need draw a huge lots of object in the scene and use GPU to do skinning like NBP dose, like GI, HI3,ZZZ, HSR, they both works fine and didn't take too much CPU runtime or cause significant CPU delay,they all works good, the design of 3dmigoto is very awesome at this point.

Thanks for your tips and i think the core problem has been dig out, this issue can be closed if this reason is correct or won't need further more test.

(●'◡'●)

DarkStarSword commented 8 months ago

NvAPIOverride() is a function that our DX11 wrapper uses to tell our NvAPI wrapper that the next call will be from 3DMigoto rather than the game. In normal circumstances it won't do anything - it only has an effect if any of the following have been enabled in the d3dx.ini to block certain NvAPI functions that the game might try to use but still allow them from 3DMigoto:

Only a few games/engines actually need these (in general, ones that attempted to implement their own stereo 3D support but failed miserably, e.g. CryEngine 3), and 99% of games don't really need to use our NvAPI wrapper at all, and we made sure that 3DMigoto would still function if it is missing or fails (e.g. we still need the rest of 3DMigoto's functionality to work on non-NVIDIA systems). I don't know if we ever measured performance in that case though - we do note if the NvAPIOverride() call fails and won't retry it, but perhaps there is something else happening in this case that is problematic.

If the performance impact is truly related to this call failing and/or our NvAPI wrapper being unavailable, I wonder if you would see the same impact if you measure performance on another game after deleting our nvapi64.dll?

StarBobis commented 7 months ago

NvAPIOverride() is a function that our DX11 wrapper uses to tell our NvAPI wrapper that the next call will be from 3DMigoto rather than the game. In normal circumstances it won't do anything

Thanks for the tips, i test it and open or close these params will not influence FPS or GPU usage.

we do note if the NvAPIOverride() call fails and won't retry it, but perhaps there is something else happening in this case that is problematic. After some test i found it's not related with NvAPIOverride() but some otherthings unknown.

If the performance impact is truly related to this call failing and/or our NvAPI wrapper being unavailable, I wonder if you would see the same impact if you measure performance on another game after deleting our nvapi64.dll?

Seems it's not caused by NvAPI wrapper, even I delete nvapi64.dll in other game like GI,HI3 etc,it won't cause a FPS influence, so i turn my focus on other things to test, the first thing I think is: is there a possible that the hook method is incorrect or resource-consuming which in other tools like ReShade just use simple MinHook way, so I try to upgrade Nektra's Deviare-InProc ,compile it to VS2019 X64 Release version and replace the 3Dmigoto's attached one, and the GPU usage get a incredible increase, now it works perfectly good even there is huge lots of characters in game scene, and the FPS can also work good.

In nearly same scene,like around 20 characters in screen,here is the data i tested: Pure 3Dmigoto 1.3.16 without anything added,and just inject into game and do nothing. Same Naraka config: All setting turn to highest,unlimit fps lock, 1920*1080 full screen,turn off other extra settings. GPU: RTX 3060

before upgrade to Deviare-InProc 2019: 
FPS :55~67  GPU usage:40% ~ 55%
after upgrade to Deviare-InProc 2019:
FPS: 70~81  GPU usage:87% ~ 99%

Add mod will also cause fps decrease but i guess the core problem has been found, i don't know why InProc 2019 version can works good in NBP due to bad hook skill but it works good like a miarcle.

Attachment is the compiled version of Nektra Deviare-InProc 2019 version, and i use these to replace the ones in 3Dmigoto solution's "Nektra" folder,and it works fine. original file: https://github.com/nektra/Deviare-InProc/blob/master/NktHookLib_2019.sln

I'm still trying to learn and understand the under mechanism for why a certain hook method will cause CPU-Delay,but it's slow...

Thanks for your help! I guess the core problem has been found now but may still need further performance test. Nektra.zip

DarkStarSword commented 7 months ago

Nice find :)

If you don't mind I'd like to leave this ticket open until we've updated Nektra in the main repository - I've got a few other changes I want to release in the near future as well, so it would make sense to do this at the same time. Updating this will also mean that we'll have to do a bit of regression testing with hook=recommended enabled in several versions of Windows (@bo3b what's your gauge on how many people in the community are still using Windows 7, and how much effort we should continue to put into supporting it? In this case I'm thinking about the need to regression Windows 7 with + without the evil update installed since that is a known case that altered which specific calls were implicated in Nektra hooking crashes in the past. Edit: Also, if you're not already aware the geo-11 fork has broken compatibility with Windows 7 due to calling GetDpiForMonitor() without GetProcAddress() since that wasn't introduced until Windows 8.1 thereby adding a link time dependency that can't be resolved on Windows 7).

I'm a little surprised that Nektra had such a large influence - do you have hook=recommended enabled in the d3dx.ini? That would certainly increase the CPU time it adds since that means every DX call on the device and context will go through an extra trampoline and have to perform a less efficient device/context lookup. If that option is disabled Nektra is still used for a few things, but they typically would only be called a few times when the game initially loads, and generally wouldn't be in a hot path.

Edit: Actually, didn't we add some more hooks on mouse cursor (for the software cursor support) + window size (for upscaling) routines? Some of those might be in the hot path if they are enabled?

bo3b commented 7 months ago

I'm in agreement that this is an interesting find and merits some investigation. I can't really see how there would be a performance difference because Deviare In-Proc uses the same approach as MinHook and Detours with trampolines. It has essentially zero work to do at a given jump.

There is only a single commit from Deviare since we fixed the x64 bugs in Nektra, and that is to add support for VS2019. At e88b91 The change doesn't appear to do anything except add a VS2019 project.

It seems very unlikely that a tooling change would have this big an impact. I think something else besides Nektra is going on. Still, worth double checking and I had this on my list to take a look at.


Regarding Win7 support, I'm not really following the forums or discord, but my very basic impression is that no one uses Win7 today. So I think it's not a problem to remove that dependency. If anyone does still need that support, we will of course leave 1.3.16 up for anyone to use.

DarkStarSword commented 7 months ago

Not entirely sure why the last reply didn't show up here, but summary was that the performance issue was tracked down to the game's anti-cheat system phoning home in certain circumstances.

Closing the ticket since this confirms that the performance issue is not caused by 3DMigoto or Deviare, so there is no pressing reason to update the library.