doitsujin / dxvk

Vulkan-based implementation of D3D8, 9, 10 and 11 for Linux / Wine
zlib License
12.97k stars 832 forks source link

NvAPI testing #853

Closed SveSop closed 5 years ago

SveSop commented 5 years ago

Since @pchome made that standalone meson compile version of nvapi, i have been experimenting a wee bit with various stuff there. The question could be if there is something to be done to "fix" nvapi so it more or less gets useful for those weird nvapi cases.

I do not own a game that have any serious issues with this, and searching here kinda ended up in a non-conclusive 100% way to recreate problems (for me), cos i dont want to buy 4-5-6 games just to test. I would lub some feedback on what game "is the worst" if you are not faking AMD card, and setting dll-overrides for nvapi to "disabled".

What i have experienced so far, is as ppl have described, and that is even if you fake AMD card, and the nvapi.dll exist, it will end up being used anyway.

I have added a few fake things to the nvapi source, and i know it wont actually DO any hardware setting changes, but maybe faking calls and returning "sane" answers is enough for a few games? Worth a test in my book i guess.

https://github.com/SveSop/nvapi_standalone

Grab it, compile it and test it. (Script explanation in the README).

The absolutely awesome thing about this standalone source (big thanks pchome) is that when installed via dll-overrides, you just compile and replace the install folder to test a "new version", so its easy to fiddle with.

As of now, I have just faked as much of my GTX970 as possible (easily changed, and if interested i can explain how). I do not think it really matters much tho, but its a fun experiment. I have zero coding experience, so if obvious errors or ways to do things easier is spotted, tips are most welcome :+1:

What i would love tho, is for a comparison of WINEDEBUG="-all,+nvapi" logs between the regular staging nvapi and mine, especially for games that have huge issues with this. Probably best to post it as issues on my GIT. Eg. "wine-staging.log" "wine-nvapi-standalone.log", so i can try to pinpoint if there is anything obvious that COULD help.

Not saying it actually will solve anything, but hey.. fun project nevertheless.

PS. To make sure the game/app does what it can to use nvapi, you should put this in the dxvk.conf file: dxgi.nvapiHack = False (Requires RECENT git - cf9de54 or newer) Or ofc you can override it with:

dxgi.customDeviceId = 10de
dxgi.customVendorId = 13c2

in the dxvk.conf file.

SveSop commented 5 years ago

@pchome Well.. its not easy for me because i am stupid. Could i have a snippid from your top meson.build file where you declare such things as widl = find_program('widl')? Cos i suspect you might have some nvapi_dll = declare_dependency or something there that actually generate the dxvk.h file... Cos just adding idl_generator.process('dxvk.idl'), to the dlls/nvapi/meson.build file does not seem to actually generate anything useful for me i think?

I did NOT put the dxvk.h header in /include, as you say it should be generated from meson. :)

Or i could just generate it manually and copy it manually to /include rather than fiddle with meson (that i have no clue what i am doing it seems) for endless hours :)

pchome commented 5 years ago

Could i have a snippid from your top meson.build file where you declare such things as widl = find_program('widl')?

cpu_family   = target_machine.cpu_family()
target_arch  = cpu_family == 'x86_64' ? '-m64' : '-m32'
widl         = find_program('widl')

idl_generator = generator(widl,
  output    : [ '@BASENAME@.h' ],
  arguments : [ target_arch, '-o', '@OUTPUT@', '-D__WINESRC__', '@EXTRA_ARGS@', '@INPUT@' ])

Or i could just generate it manually and copy it manually to /include rather than fiddle with meson (that i have no clue what i am doing it seems) for endless hours :)

this

SveSop commented 5 years ago

@pchome Thanks :) I must have done some typo or some shiat, but redoing from fresh it worked. Sorry for the noise.

This was the commit i ended up with: https://github.com/SveSop/nvapi_standalone/commit/3e6bcc5c1984648bd1dabc0eb9aec04ee2cc1c6b

So, i did some testing with Monster Hunter Benchmark with DXVK https://github.com/doitsujin/dxvk/commit/1dadba3cce86547bce07cfc3a9edbcbb2bc24696 , and the logs read stuff like

004e:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x13c8238, 1, 0.988695, 0.992234): dxvk
004e:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x13c8238, 0, 0.000000, 1.000000): dxvk
004e:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x13c8238, 1, 0.929018, 0.981536): dxvk
004e:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x13c8238, 0, 0.000000, 1.000000): dxvk
004e:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x13c8238, 1, 0.998172, 0.998413): dxvk
004e:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x13c8238, 0, 0.000000, 1.000000): dxvk

So i think its atleast doing something so far.

Comparably i got these results: Monster hunter benchmark w/nvapi disabled : score: 21430, avg: 97.9 fps, min: 58.4 fps Monster hunter benchmark w/this option: score: 21665, avg: 98.9 fps, min: 57.5 fps

Probably within the error margin, so i am interested in tweaking this some more :)

Is there a game that is "broken" with current staging implementation of nvapi and dxvk that "must" fake AMD card via dxvk?

K0bin commented 5 years ago

I don't know if those are broken (probably are) but generally all things UE4 try to use NvAPI.

doitsujin commented 5 years ago

Unreal Engine 4 requires nvapi to be present, I'm not sure if the staging implementation is broken or not. Probably is because UE4 uses the depth bounds test.

SveSop commented 5 years ago

Would "Redout" be a possible test candidate for this? https://github.com/ValveSoftware/Proton/issues/1374 This is afaik default "spoofed as AMD" atm right? But is it a UE4 game? (Is not listed on the https://wiki.unrealengine.com/Unreal_Engine_Games#Unreal_Engine_4 list tho).

Or would something like https://www.techpowerup.com/download/unreal-engine-4-elemental-tech-demo/ suffice as a test?

doitsujin commented 5 years ago

The tech demo tends to be fine. I think one of the first games where issues started popping up was Dragon Quext XI.

SveSop commented 5 years ago

https://www.techpowerup.com/download/unreal-engine-4-elemental-tech-demo/ Although interesting as a test, it does not seem to use any nvapi calls at all. Log reports LogSynthBenchmark:Display: Adapter Name: 'GeForce RTX 2070' so it is registering a nVidia adapter, but no calls to nvapi.dll is being made.

If anyone want to test for laughs & gigglez, download it on the page, and extract to wherever you find useful in your wineprefix. Run Elemental.exe to start it. You should edit ./Elemental/Saved/Config/WindowsNoEditor/GameUserSettings.ini with your resolution, and add this:

[/Script/Engine.Engine]
bSmoothFrameRate=false
MinSmoothedFrameRate=0
MaxSmoothedFrameRate=0

to the ./Elemental/Saved/Config/WindowsNoEditor/Engine.ini file to avoid capping at 62fps.

pchome commented 5 years ago

I recently checked EffectsCave, RealisticRendering, Reflections, ShooterGame and Temple Mobile UE4 tech demos, but none of them using Depth bounds test.

There is The Awesome Adventures of Captain Spirit is a free preview to Life is Strange 2 which uses NvAPI_D3D11_SetDepthBoundsTest.

Also, here is the UE4 games list.

p.s. don't forget about dxgi.nvapiHack = False

SveSop commented 5 years ago

Strange.. I set up a new wineprefix with dxvk and custom nvapi. I have checked that nvapi is doing what it does by running a small nvapi test proggy i have made that does some calls and print the values. (If interested, i can provide source if anyone is into testing nvapi). I have mainly used this to compare what a "real" machine responds when doing the calls.

Anyway. I installed Steam, and then installed https://store.steampowered.com/app/845070/The_Awesome_Adventures_of_Captain_Spirit/. The game starts and runs just fine.

However, there is no nvapi calls being made while the game runs. I do get some nvapi calls when Steam starts up:

0030:trace:nvapi:DllMain (0x7c420000, 1, (nil))
0030:trace:nvapi:nvapi_QueryInterface (150e828)
0030:trace:nvapi:NvAPI_Initialize ()
0030:trace:nvapi:nvapi_QueryInterface (33c7358c)
0030:trace:nvapi:nvapi_QueryInterface (593e8644)
0030:trace:nvapi:nvapi_QueryInterface (694d52e)
0030:trace:nvapi:get_thunk_function (694d52e)
0030:fixme:nvapi:unimplemented_stub function 0x694d52e is unimplemented!
0030:trace:nvapi:nvapi_QueryInterface (375dbd6b)
0030:trace:nvapi:get_thunk_function (375dbd6b)
0030:fixme:nvapi:unimplemented_stub function 0x375dbd6b is unimplemented!
0030:trace:nvapi:nvapi_QueryInterface (d22bdd7e)
0030:trace:nvapi:NvAPI_Unload ()
0030:trace:nvapi:DllMain (0x7c420000, 0, (nil))

Ending in NVAPI_Unload means Steam app is unloading it tho, so maybe, just maybe i need to create something for those functions.

So far, it seems that these are the functions: nvapi_QueryInterface (33c7358c) = /* NvAPI_Diag_ReportCallStart, not needed */ This function is disabled, so i dunno what it does. Same with: nvapi_QueryInterface (593e8644) = /* NvAPI_Diag_ReportCallReturn, not needed */ Dunno if "not needed" actually IS not needed tho :)

The next calls: nvapi_QueryInterface (694d52e) = NvAPI_DRS_CreateSession I have not made a function for this, so the call goes "unanswered" really.. but i think that this is the profile loading bit (nVidia gaming profiles). NVAPI_INTERFACE NvAPI_DRS_CreateSession | ( | NvDRSSessionHandle * | phSession | ) And nvapi_QueryInterface (375dbd6b) = NvAPI_DRS_LoadSettings NVAPI_INTERFACE NvAPI_DRS_LoadSettings | ( | NvDRSSessionHandle | hSession | )

I dunno if loading those profiles is "needed", but i would not really think so. Other than that, no nvapi calls are being made after i actually start the game. I did not test this with Proton, but might set that up if you actually KNOW NvAPI_D3D11_SetDepthBoundsTest is being used for the free game.

(And yes, dxgi.nvapiHack = False is set in my config file)

pchome commented 5 years ago

I made a log file backup for +nvapi trace, during last run. Since all those TRACE outputs ended w/ "dxvk" : $ grep dxvk ~/.log/Proton/steam-845070-nvidia.log | wc -l

72448

"Random" lines: $ grep dxvk ~/.log/Proton/steam-845070-nvidia.log | tail -n 100 | head -n 5

0068:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x7dffed90, 1, 0.001787, 0.002176): dxvk
0068:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x7dffed90, 0, 0.000000, 1.000000): dxvk
0068:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x7dffed90, 1, 0.003107, 0.004313): dxvk
0068:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x7dffed90, 0, 0.000000, 1.000000): dxvk
0068:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x7dffed90, 1, 0.003470, 0.003621): dxvk

I used the vanilla nvapi patches + depth bounds patch for testing. +loaddll to check what was actually loaded. d3dcompiler_47 and force_gpu=nvidia(this) winetricks verbs. No other specific changes was made for this game.

pchome commented 5 years ago

Some thoughts about measuring fps changes in a real game: Wine's WINEDEBUG="+fps" likely will not work, so maybe modified DXVK Hud or Vulkan monitor layer will do the same.

Like:

p.s. vkconfig useful tool for quick "load/unload" an layer.

SveSop commented 5 years ago

Right. When launching a game directly in a wineprefix that will launch steam "to run", it seems as some wine process crashes, but the game actually continues launching. The problem then is ofc that no log data is created.

Same thing happens if i launch steam, and then launch the game in the same prefix for some reason. In windows this is no problem ofc, but everything wine tends to blow donkey balls, so yeah.. guess i will have to do some manual juggling with proton that i would rather not "customize". (No, i do not currently have a custom-compile-setup for making my own proton)

SveSop commented 5 years ago

Time to hit the sack i think.. Game starts if i do no debug logging, but as soon as i put "WINEDEBUG": "+nvapi", in the user_settings.py file, the game just exits upon launching and nothing happens.

Some spam of:

0051:fixme:dbghelp:elf_search_auxv can't find symbol in module
0051:fixme:dbghelp:elf_search_auxv can't find symbol in module
0051:fixme:dbghelp:elf_search_auxv can't find symbol in module
0051:fixme:dbghelp:elf_search_auxv can't find symbol in module
0051:fixme:dbghelp:elf_search_auxv can't find symbol in module
0051:fixme:dbghelp:elf_search_auxv can't find symbol in module
0051:fixme:dbghelp:elf_search_auxv can't find symbol in module
pid 18053 != 18052, skipping destruction (fork without exec?)

in the steam-845070.log file.

This is with Proton 4.2-9 tho.

pchome commented 5 years ago

Try to compile nvapi for Proton 4.2 using proton's winegcc. Well, that's a problem w/o custom proton. Wine 4.2 probably could help.

FYI, anyway I already wrote this ... You don't need custom proton or so, don't make things overcomplicated. 1. Make sure you using windows version (e.g. 845070 have native version, so you may want to force Steam Play in game's configuration window) 2. Try to copy/symlink nvapi.dll into game's directory
or patch proton ```patch --- a/proton +++ b/proton @@ -208,7 +213,10 @@ else: env[ld_path_var] = lib64dir + ":" + libdir -env["WINEDLLPATH"] = lib64dir + "/wine:" + libdir + "/wine" +if "WINEDLLPATH" in os.environ: + env["WINEDLLPATH"] = os.environ["WINEDLLPATH"] + ":" + lib64dir + "/wine:" + libdir + "/wine" +else: + env["WINEDLLPATH"] = lib64dir + "/wine:" + libdir + "/wine" if "PATH" in os.environ: env["PATH"] = bindir + ":" + os.environ["PATH"] ```
and use e.g. `WINEDLLPATH="/path/to/lib64/nvapi:/path/to/lib/nvapi"` 3. Make sure you have `WINEDEBUG="+navpi"` set in `user_settings.py` (copy from `user_settings.sample.py`) 4. `$ tail -F /tmp/dumps/*.txt ~/steam-845070.log` in separate terminal for immediate output
pchome commented 5 years ago

@pchome

  • do several hundreds →
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/extensions/XTest.h>

int main() {
  Display *dpy = XOpenDisplay(NULL);
  KeyCode keycode = XKeysymToKeycode(dpy, XK_D);

  for (int i=0; i<10; i++) {
    XTestFakeKeyEvent(dpy, keycode, True, 0);
    XTestFakeKeyEvent(dpy, keycode, False, 0);
    XFlush(dpy);
  }
  XCloseDisplay(dpy);
  return 0;
}

$ gcc key.c -o key_test -lXtst -lX11 $ ./key_test

dddddddddd

Maybe this will work directly from the Vulkan layer.

SveSop commented 5 years ago

Try to compile nvapi for Proton 4.2 using proton's winegcc. Well, that's a problem w/o custom proton. Wine 4.2 probably could help.

I will try this, maybe some bindings nvapi <-> winedebug that does not exist when proton is built without this perhaps? Ill experiment a bit with this. I could try retrofitting the custom nvapi set with wine-devel and see if the logging crashes then aswell as a test :)

SveSop commented 5 years ago

Well, i dunno how to "use proton's winegcc", as this is something you need to build when building Proton from scratch i think? (I do not have any winegcc in ~/.steam/steam/steamapps/common/Proton 4.2/dist/bin)

Cos there is some debug changes between my regular winegcc and proton's then ref:

0028:trace:loaddll:load_builtin_dll Loaded L"C:\\windows\\system32\\nvapi64.dll" at 0x7f5024670000: builtin
wine: Call from 0x7bc612cc to unimplemented function ntdll.dll.__wine_dbg_header, aborting
wine: Call from 0x7bc612cc to unimplemented function ntdll.dll.__wine_dbg_header, aborting

Bah... guess i will need to spend some time setting up a proton build when i get the time to do it.. Never touched Archlinux tho, but that is perhaps the best bet? https://github.com/Tk-Glitch/PKGBUILDS/tree/master/proton-tkg

So, see you in 2-3 months when i figure that out...

pchome commented 5 years ago

Use Wine 4.2 to build, I bet it will work.

Also, I posted my builds in Proton's issues : winelib nvapi, in case you want to test depth bounds code as is.

EDIT: If you ever built Wine from sources -- try https://github.com/ValveSoftware/wine/tree/proton_4.2 sources, no big difference. Or even just configure and build tools only.

pchome commented 5 years ago

@pchome

  • do several hundreds →

    Maybe this will work directly from the Vulkan layer.

https://gist.github.com/pchome/d921830565d91514654093593a4a0483 Adjusted sample, can run in background and wait for Shift + d, then will "press" more "d"s in current window. Not tested in real game, though.

SveSop commented 5 years ago

Use Wine 4.2 to build, I bet it will work.

Also, I posted my builds in Proton's issues : winelib nvapi, in case you want to test depth bounds code as is.

EDIT: If you ever built Wine from sources -- try https://github.com/ValveSoftware/wine/tree/proton_4.2 sources, no big difference. Or even just configure and build tools only.

I "only" build wine from source (i say "only" cos i also have the system installed, but dont really ever use it), so if proton_4.2 source can be built just as "regular" wine ill do that and see if the debug problem is solved. Thx for the tip :)

pchome commented 5 years ago

fps_log_util.zip - key.c sample and sample script to calculate min/avg/max fps from an log file (e.g. 1976.00 / 2226.33 / 2332.00). fps_log_layer.zip - modified monitor layer, should log strings like monitor:13508 FPS = 2204.00 (first number is a current frame).

I'll try to combine everything and test on "Captain Spirit" later.

SveSop commented 5 years ago

@pchome Oki.. i must be doing something horribly wrong i guess.. I am kinda dumb like that, and need to be spoonfed whatever minor info :)

I compiled the wine-4.2 version from the git link you gave (from proton git). No problems with that. I then replaced my systems /opt/wine-devel folder with this new 4.2 compile from proton. Upon compiling nvapi, i get all kinds of missing header files, and a multitude of missing .idl files.

My SYSTEM installed wine, is wine-devel-4.11 (yes, ofc i moved the WineHQ version back to /opt/wine-devel after the testcompile). This is what meson.build finds when it finds winegcc, widl and so on. Maybe something ELSE is at play when it comes to the "proton" source of this winetree?

I tested running "GPU Caps Viewer" program in my regular testing wineprefix, with the proton-4.2 wine version, and nvapi got the same debug error, and did not work there. Nvapi works fine if i use wine-devel-4.11 from WineHQ tho, so me thinks there is more at play other than 4.2->4.11 no?

SveSop commented 5 years ago

@pchome I did figure it out, and it was some include files in my nvapi source that was "too new" and thus pointing to other include files that i guess exist in wine > 4.10 or something..

I am going to work on making a "lite" version of the custom nvapi i have been fiddling with, cos for gaming one would not need temps/fanspeeds+++, but i am going to keep getting the REAL adaptername and driver and such, cos there are incidents where "GTX-999" or whatever staging nvapi "fakes" is not usable, aswell as the rather low driver version also make games complain at times. Grabbing the real version would imo be a +

Next thing would ofc also be to make a reproducible benchmark to tweak this SetDepthBoundsTest too :)

pchome commented 5 years ago

I am going to work on making a "lite" version of the custom nvapi ...

So maybe it worth to backport and PR some of your changes to wine-staging nvapi, as this "lite" version. Then you'll probably get more feedback and support.

Also, the REAL driver version actually isn't REAL, games will expect Windows driver version.

p.s.


@pchome

  • do several hundreds →

    Adjusted sample, can run in background and wait for Shift + d, then will "press" more "d"s in current window.

Again :smile: . Playing with gamepad I completely forgot that "D" key is a "shuffle right", not the "rotation" :man_shrugging:

Also, the game don't even reacting on "zero" delay (int XTestFakeKeyEvent(display, keycode, is_press, delay)). Some kind of threshold, I suppose. The key should be "pressed" for mush longer time.

So, probably XTestFakeRelativeMotionEvent should be used instead. Maybe +/- rel to X (REL_X event). I'll fix and share this, eventually.

SveSop commented 5 years ago

I am going to work on making a "lite" version of the custom nvapi ...

So maybe it worth to backport and PR some of your changes to wine-staging nvapi, as this "lite" version. Then you'll probably get more feedback and support.

Also, the REAL driver version actually isn't REAL, games will expect Windows driver version.

Well.. i am willing to bet that when a game checks driver versions, it is in a > X version manner, and not a list of "approved drivers". A "set list" of drivers would mean constant updates, and that is just not happening.

Unless you can provide an example of a game that requires a particular driver and nothing else, i feel it is the proper way to do this. "Faking" a driver version in nvapi would mean constant updates... (And you see how well that has gone for wine-staging version of nvapi and its driver version).

SveSop commented 5 years ago

I found a nvapi function that this game (Awesome Adventures of Captain Spirit) calls for. NvAPI_D3D11_IsNvShaderExtnOpCodeSupported https://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/group__dx.html#ga02b540450d23167169998182787e92ea

I am not sure how to figure out HLSL support vs vulkan and whatnot..

https://github.com/SveSop/nvapi_standalone/blob/lite/dlls/nvapi/nvapi.c#L1075-L1095

Basically its a call from the game asking if a certain "opcode" is supported. https://docs.nvidia.com/gameworks/content/gameworkslibrary/coresdk/nvapi/nvShaderExtnEnums_8h.html

jp7677 commented 5 years ago

I played a bit with nvapi too and tried to create something based on dxvk-ags. To my own surprise it even enables depth bounds test for the one UE4 game I have. I'm not sure if it really is faster since there is no in-game benchmark, but at least it hasn't gotten worse ;) For the curious:: https://github.com/jp7677/dxvk-nvapi

doitsujin commented 5 years ago

Depth bounds test usually only has a minor impact on performance (e.g. in Resident Evil 2 it's only 2-3%).

jp7677 commented 5 years ago

Yes, very likely that this is here also the case, though would be cool to have some confirmation that it does have effect. My only actual confirmation now are lot of log statements when the call has succeeded (when adding such a log line) ;)

SveSop commented 5 years ago

The only benchmark i know that utilizes the depth bounds test is Monster Hunter Online Benchmark from https://www.guru3d.com/files-details/monster-hunter-official-benchmark-download.html

When i have tested with the nvapi implementation i´ve been diddling with, i have found it <1% difference, and that might just aswell be within the margin of error.

@jp7677 You could do some testing with that benchmark if you want? Compare with and without the nvapi implementation, changing dxgi.nvapiHack setting as a comparison (and probably disable nvapi.dll´s to be sure)

jp7677 commented 5 years ago

@K0bin Do you remember which UE4 version uses NvAPI_D3D11_BeginUAVOverlap/NvAPI_D3D11_EndUAVOverlap and/or what the condition are for using them? The one UE4 game I have (ACC) is based on 4.22, there I haven't seen any calls for these methods.

pchome commented 5 years ago

CAT Interstellar - one more "small" UE4 game for testing depth bounds test. Currently free-to-play.

pchome commented 5 years ago

Game: The Flame in the Flood (318600) Engine: UE4 NvAPI calls: uses only NvAPI_D3D11_SetDepthBoundsTest function (after initialization).

I tested patched nvapi from wine-staging and dxvk-nvapi. Both winelib builds, both gave +2fps boost (in some places).

NvAPI_Initialize DXVK-NVAPI-a232b4b+: OK
NvAPI_D3D11_SetDepthBoundsTest: Succeeded
0058:trace:nvapi:DllMain (0x7f61f41e0000, 1, (nil))
0058:trace:nvapi:nvapi_QueryInterface (150e828)
0058:trace:nvapi:NvAPI_Initialize ()
0058:trace:nvapi:nvapi_QueryInterface (33c7358c)
0058:trace:nvapi:nvapi_QueryInterface (593e8644)
0058:trace:nvapi:nvapi_QueryInterface (7aaf7a04)
0058:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x5555564645e0, 1, 0.011925, 0.013000): dxvk
0058:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x5555564645e0, 0, 0.000000, 1.000000): dxvk
0058:trace:nvapi:NvAPI_D3D11_SetDepthBoundsTest (0x5555564645e0, 1, 0.011972, 0.013263): dxvk
...

@doitsujin Any chance we can get more information from DXVK in the similar way (interfaces)? For example:

  1. NvAPI hack status (?)
  2. Video memory size (including the limit from corresponding dxvk.conf option, if any)
  3. GPU info (GPU name, driver version, etc.)

Would be good if we could avoid additional dependencies.

doitsujin commented 5 years ago

You can get all the information from IDXGIAdapter::GetDesc (not so much the nvapi hack, but the vendor id and that really should be enough in this case). You can retrieve the dxgi adapter by first querying IDXGIDevice from the d3d11 device and then using IDXGIDevice::GetParent.

jp7677 commented 5 years ago

@pchome Thanks a lot for confirming the few fps extra. Regarding your second question, I don't think that's a good idea. NVAPI has a lot (really a lot) methods to query the device topology. It would be a hell of a job to implement this. Even when doing so, what would you eventually gain? Looking at UE4 Engine, this game uses NVAPI only for querying SLI and HDR status. Both are not supported with DXVK, thus returning "not-implemented" is much saner than e.g. pretending that DXVK knows about SLI. In my opinion an NVAPI on top of DXVK should really just support the extensions DXVK provides for running games faster/better, but no extra bling-bling. UE4 engine handles "not-implemented" correctly, dunno about other engines.

jp7677 commented 5 years ago

@pchome as a sidenote, I'm seeing in your dxvk-nvapi git describe status (DXVK-NVAPI-a232b4b+) that you have local modifications. Should I add some ignores or did you really edited something? I'm building using docker, so I'm not sure if the current ignores are sufficient.

pchome commented 5 years ago

@doitsujin Thanks for the info, I'll try.

@jp7677 I have no plans to implement whole nvapi API, just basic functions, required by the other games/engines to reach NvAPI_D3D11_SetDepthBoundsTest. Or just "good to have", like IIRC Unigine Superposition launcher, which should display VRAM size.

I also have no plans to support my wine-staging nvapi hacks, I'll happily use dxvk-nvapi, if you plan to support it and it became good enough to not fail here and there.

For example, I tested Monster Hunter Online using your implementation, and it fails. While runs fine with wine-staging nvapi (patched). So it's either my fault (incomplete winelib hack) or missed functionality, I'll try to figure out.

Should I add some ignores or did you really edited something?

I added some code and files in the local repo clone, required for winelib build (I have no mingw installed). Just ignore this status.

jp7677 commented 5 years ago

For example, I tested Monster Hunter Online using your implementation, and it fails. While runs fine with wine-staging nvapi (patched). So it's either my fault (incomplete winelib hack) or missed functionality, I'll try to figure out.

Please let me know if you know where it fails.

jp7677 commented 5 years ago

@pchome To actually reply: thanks for providing your "real" use case, that already sounds much more sane than what your initial question suggested ;).

dxvk-nvapi is for now just a personal experiment for me. It works for ACC, thus likely also for other UE4 games, I haven't looked much further cause all other games in my library (not that big) already run very much perfectly graphics-wise. I have though looked briefly into Batman Arkham Knight, but implementing the CUDA-DX11 interop is way out of my league.

pchome commented 5 years ago

@jp7677

that already sounds much more sane than what your initial question suggested ;).

Sorry for my bad English :man_shrugging: I guess, almost all my questions/suggestions on github are much more sane than what I wrote by the words :smile:

Please let me know if you know where it fails.

Just a guess, before I'll actually figure out where is the problem, but unlike UE4 some games doing a lot of calls on nvapi initialization, and for unimplemented functions there is NvAPI_Status CDECL unimplemented_stub(unsigned int offset) call, which return NVAPI_ERROR, not just nullptr directly. Or, maybe, an other "magic" in void* get_thunk_function(unsigned int offset).

For MHO benchmark (the very beginning, "..." is the stub for non-nvapi log part):

0009:trace:nvapi:DllMain (0xf7800000, 1, (nil))
0009:trace:nvapi:nvapi_QueryInterface (150e828)
0009:trace:nvapi:NvAPI_Initialize ()
0009:trace:nvapi:nvapi_QueryInterface (33c7358c)
0009:trace:nvapi:nvapi_QueryInterface (593e8644)
0009:trace:nvapi:nvapi_QueryInterface (5e8f0bec)
0009:trace:nvapi:get_thunk_function (5e8f0bec)
0009:fixme:nvapi:unimplemented_stub function 0x5e8f0bec is unimplemented!
...
0009:trace:nvapi:nvapi_QueryInterface (f951a4d1)
0009:trace:nvapi:NvAPI_GetDisplayDriverVersion ((nil), 0x34e044)
0009:trace:nvapi:nvapi_QueryInterface (9abdd40d)
0009:trace:nvapi:NvAPI_EnumNvidiaDisplayHandle (0, 0x34e024)
0009:trace:nvapi:NvAPI_EnumNvidiaDisplayHandle (1, 0x34e024)
0009:trace:nvapi:nvapi_QueryInterface (4b708b54)
0009:trace:nvapi:NvAPI_D3D_GetCurrentSLIState (0xe6114164, 0x34e028)
...
0009:trace:nvapi:nvapi_QueryInterface (150e828)
0009:trace:nvapi:NvAPI_Initialize ()
0009:trace:nvapi:nvapi_QueryInterface (6c2d048c)
0009:trace:nvapi:get_thunk_function (6c2d048c)
0009:trace:nvapi:nvapi_QueryInterface (1053fa5)
0009:trace:nvapi:nvapi_QueryInterface (f951a4d1)
0009:trace:nvapi:nvapi_QueryInterface (9abdd40d)
0009:trace:nvapi:nvapi_QueryInterface (20de9260)
0009:trace:nvapi:get_thunk_function (20de9260)
...
SveSop commented 5 years ago

There is mostly pointless to actually implement ALL of nvapi functions imo... BUT there are examples out there of games that query the driver version and card id if nvapi is found, so SOME functions is needed.

There was a case with someone running World of Warcraft with wine-staging a while back, and WoW stopped complaining about "too old driver". This is because the staging implementation of nvapi have some old 388.xx or whatnot driver version (cant remember on the top of my head).

The nvapi implementation i did queries a lot of stuff like gpu temp, frequency and whatnot, and was mostly for proof of concept, but is not really useful for other than testing. The "lite" branch i put up only have driver version, card id + "disabled sli" and stuff like that. (And the NvAPI_D3D11_SetDepthBoundsTest implementation).

Having a "slimmed down" version that provides the basics of needed stuff could be useful, but only if it actually gives a performance advantage. 2-5% increase would imo warrant implementation, but probably needs some more testing.

Game engines probably have sparse documentation of what it actually implements and the impact of such implementation is tho. So far i only know of UE4 and Cryengine actually using this for something performancewise, but there are other games (like WoW) that uses it to grab driver info and some other things. Using DXVK to provide this info would perhaps not have a huge overhead like using NVML library have?

@jp7677 Since i have repeatedly been told by someone important in here what an utter asshat i am at reading c++ code, i fear i cannot contribute much to your code, but you are free to gander whatever source i have to get some ideas :)

jp7677 commented 5 years ago

MHO is unfortunately x86. I did the meson bits for an x86 build, but the benchmark isn't calling NvAPI_Initialize here, just loading nvapi and then unloading.

0009:trace:loaddll:load_native_dll Loaded L"C:\\Program Files (x86)\\Monster Hunter Online Benchmark\\Monster Hunter Online Benchmark\\Bin32\\nvapi.dll" at 0x65040000: native
NvAPI_DllMain
NvAPI_DllMain
0009:trace:loaddll:free_modref Unloaded module L"C:\\Program Files (x86)\\Monster Hunter Online Benchmark\\Monster Hunter Online Benchmark\\Bin32\\nvapi.dll" : native

No idea why it is doing that. (Nvapi hack is false) (The DXVK issue list is probably not the best place to discuss this any further since this is getting somewhat off-topic.)

jp7677 commented 5 years ago

@pchome I've added the bit and pieces for an x32 build. Together with https://github.com/jp7677/dxvk-nvapi/commit/da83a256ec0d2d1b05f555d8823eebe7af12a100 nvapi.dll is loaded correctly and SetDepthBoundsTest is correctly used.

NvAPI_Initialize DXVK-NVAPI-da83a25: OK
NvAPI_D3D_GetCurrentSLIState: Not implemented
NvAPI_D3D11_SetDepthBoundsTest: Succeeded
pchome commented 5 years ago

@jp7677 I can confirm successful launch for winelib build too.

_BTW, my hacks to wine-staging nvapi implementation was focused on hardware PhysX support, and was created/collected based on "real" games/apps requirements (FluidMark, GPU_CapsViewer and a few PhysX games from my library). But, I guess, dxvk-nvapi is good enough for me to use with DXVK. I'll try to use it by default.

p.s. just in case you want to add winelib build support: dxvk-nvapi.winelib.patch.txt You probably may want to polish this hack a bit, also *.spec and cross files required (can be found in known places). Note: additional compiler flags: --no-gnu-unique -DNOMINMAX -fpermissive either in the cross files or meson.build.

jp7677 commented 5 years ago

@pchome Well, I'm feeling honored ;) Regarding winelib support, to be honest I would prefer to keep the build system limited as it is now.

Ski-lleR commented 4 years ago

Hi,

Any idea on how to get Beyond Two Souls working ? Actually it get the "0180:err:nvapi:NvAPI_D3D11_SetDepthBoundsTest Failed to get wined3d device handle!".

I tried to disable nvapihack, and use jp7677 native nvapi64, but if i do this i get another error : "warn: D3D11DeviceContext::QueryInterface: Unknown interface query"

I'm on wine-staging 5.10 with dxvk 1.7 (i tried with 1.6 too for now but not work either). Will try older version awaiting response

jp7677 commented 4 years ago

@Ski-lleR I can't comment on the game itself, but are you sure that you are using the native version of nvapi64? Do you see any console output from nvapi, e.g. from initialization (from https://github.com/jp7677/dxvk-nvapi/blob/master/src/nvapi.cpp#L88)?

Ski-lleR commented 4 years ago

Yeah i do have the output from nvapi, here what i get in first : NvAPI_QueryInterface 0xad298d3f: Called with unknown offset NvAPI_Initialize DXVK-NVAPI-v0.1.2: OK

Well i tried with old wine version, actually the game just work fine with wine-stating 5.9 without dxvk, just have to bisect to found the regression.

But i would also like to find why it not work with dxvk ^^

Edit : actually i just caused the problem myself, it's the prefix upgrade from 5.9 to 5.10 who caused the problem. I cleaned up the prefix, now it work fine on 5.10 staging with dxvk.

SveSop commented 4 years ago

@Ski-lleR You could also try my nvapi "lite" version for DXVK that have the SetDepthBoundsTest function. https://github.com/SveSop/nvapi_standalone/releases/tag/0.2L

I would say it requires newer nVidia driver (typically of the 440 branch), and probably wine-staging-5.9 or thereabouts. Either compile yourself (require meson/ninja ++), or try the binaries. Setup with WINEPREFIX=/your/wine/prefix ./setup_nvapi.sh install (kind of same as installing DXVK with symlinks).

There is also fake-dll's included in case there is a game that actually checks version of the nvapi.dll's and such (that i think may happen in rare cases). This requires a bit more fiddling (replacing wineprefix fake-dll's + copy the dll.so's into your binary wine folder and such).

Other than that, the other solution is probably to make sure your dxvk.conf file contains: dxgi.nvapiHack = True , or not at all, since the default is "True". Further you should also disable the following .dll's

nvapi.dll
nvapi64.dll
nvcuda.dll
nvcuvid.dll
nvencodeapi.dll
nvencodeapi64.dll

(Or build wine without nvapi support at all) This is because SOME games load the .dll's if they are found regardless of detected AMD gfx card.

Some games can gain something like 1-2% performance increase by using the nvapi library, but mostly it is of no huge benefit, and creates more hassle than just disabling nvapi altogether... and this is why this is not really "snapped up" as a thing...