nvfancontrol
nvfancontrol copied to clipboard
RTX Fan Control Windows
Hello,
I was trying your controller in windows. I have multiple GPUs.
Found 8 available GPU(s)
GPU #0: GeForce GTX 1070
COOLER-0
It doesn't seem like they all show up.
So I tried to set a fan speed:
nvfan -g 1 -l 40,50
WARN - No config file found; using default curve
thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1', /rustc/a53f9df32fbb0b5f4382caaad8f1a46f36ea887c\src\libcore\slice\mod.rs:2695:10
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
So I tried -g 0 (but instructions say must be > 0 )
nvfan -g 0 -l 40,50
WARN - No config file found; using default curve
INFO - NVIDIA driver version: 430.86
INFO - NVIDIA graphics adapter #0: GeForce GTX 1070
INFO - GPU #0 coolers: COOLER-0
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "NvAPI_GPU_GetFullName() failed; error -101"', src\libcore\result.rs:999:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
Am I using it wrong? I placed the recent nvapi .dll's in source directory, just like instructions.
Setup:
Mixture of RTX & GTX cards (8 total). I am trying to find a command line tool that will set fan speed for both. 64-bit Windows 10
Oh- Gpu 0 in the example is a gtx card. #1 on the bus is an rtx.
However, if I am reading your script right, it looks like you came up with a way to handle dual fan control of rtx cards, which if that is the case, if I can get this to work- You would ne my hero
I have been spending days trying to write c++ script that will work for rtx cards, with no luck.
Hi! Unfortunately testing is lacking on Windows and things tend to break. I only have one card and most people use nvfancontrol on Linux. There is room for improvement if you're willing to test!!
It is a bit troubling than only one device is enumerated although all of them are detected. This is probably some bug I need to identify.
Coolers being individually controllable depends both on the card, and the VBIOS of the card. Most RTX cards should allow that though.
Would it be possible to give me an overview of your system setup? For instance what kind of cards you have and in what sequence, ie. how they appear on the windows device manager. Can you also repeat the above scenarios with the debug flag (-d
) enabled? It might give us some more insight.
It's more just finding a command line tool that works in Windows, that supports RTX cards. I have went through many. It seems no one has been able to figure out how the hidden NVAPI methods for the cards, the only thing I have found is that the reason is likely because RTX cards have dual fan control.
C:\Users\Mayna\Documents\GitHub\nvfancontrol\target\release>nvfan.exe -p -d
Found 8 available GPU(s)
GPU #0: GeForce GTX 1070
COOLER-0
C:\Users\Mayna\Documents\GitHub\nvfancontrol\target\release>nvfan.exe -g 0 -l 40,50 -d
WARN - No config file found; using default curve
DEBUG - Default configuration loaded
DEBUG - [[gpus]]
id = 0
enabled = true
points = [[41, 20], [49, 30], [57, 45], [66, 55], [75, 63], [78, 72], [80, 80]]
DEBUG - Curve points: [(41, 20), (49, 30), (57, 45), (66, 55), (75, 63), (78, 72), (80, 80)]
INFO - NVIDIA driver version: 430.86
INFO - NVIDIA graphics adapter #0: GeForce GTX 1070
INFO - GPU #0 coolers: COOLER-0
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "NvAPI_GPU_GetFullName() failed; error -101"', src\libcore\result.rs:999:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
DEBUG - Resetting fan control
C:\Users\Mayna\Documents\GitHub\nvfancontrol\target\release>nvfan.exe -g 1 -l 40,50 -d
WARN - No config file found; using default curve
DEBUG - Default configuration loaded
DEBUG - [[gpus]]
id = 1
enabled = true
points = [[41, 20], [49, 30], [57, 45], [66, 55], [75, 63], [78, 72], [80, 80]]
thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1', /rustc/a53f9df32fbb0b5f4382caaad8f1a46f36ea887c\src\libcore\slice\mod.rs:2695:10
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
I am a programmer myself, I wrote a C++ command line script that works for AMD, that controls fans. I just am not hugely familiar with rust, but if there is something you need me to try to or look at code-wise, I am familiar with how NVAPI works at this point, and have been picking apart the script enough to understand the basics of it.
I believe I found where the error is. It seems like GPU handles are not properly allocated here so NvAPI_GPU_GetFullName
fails because it cannot find a correct handle for any GPU past 0, hence the -101
error which is exactly that: NVAPI_EXPECTED_PHYSICAL_GPU_HANDLE
. This will probably be the same for all functions that access the Physical GPU handles. I will try to put out a debug build for you to test hopefully within the weekend!
No problem. I found the C# NVAPIwrapper github, and build a simple program to control fans. It seems like it worked fine for GTX, but the dual fans in RTX cards were not responding. I'm pretty sure they are using the same methods as your NVAPI wrapper.
https://github.com/falahati/NvAPIWrapper
GPU.PhysicalGPU.CoolerInformation
I don't think your rust wrapper will work with RTX series cards, regardless of it is working or not. NVIDIA has the methods for RTX fan control in Windows locked down/hidden good. Its frustrating.
NVAPI is a mess of semi-hidden stuff with minimal documentation. However per-GPU coolers are essentially an array of length NVAPI_MAX_COOLERS_PER_GPU
; presently 3
so technically information is retrieved (and hopefully applied on a per-cooler basis).
internal const int MaxNumberOfCoolersPerGPU = 3;
Nvapiwrapper has it set.
What I get when running their method on RTX cards is NVAPI_NOT_SUPPORTED
, and it looks like it is very similar to your function.
It seems that its not that its not an issue of targeting coolers, but that the method is not available for RTX GPU entirely. Or maybe NVAPIWrapper coded it wrong, but theirs works on GTX cards no problem. I think NVIDIA may have a new method to set coolers for RTX cards. I am going to consult linux nvctrl.h, and see if they have a separate function for it, with a different address or something as homework.
Address=00A54220
ClientFanCoolers_SetControl( struct NvPhysicalGpuHandle__ *, unsigned long *,unsigned long *, int *, unsigned long *, int *)
This is what I see I when I set fan with a manufacturer controller.
Just thought I would share.
One thing at a time! I think I fixed the issue where not all of the GPUs are enumerated. Can you please try this build and let me know of the output?
If you want to build from source here's the patch to master.
C:\Users\Mayna\Desktop\nvfancontrol> nvfancontrol.exe -g 0 -l 40,50 -d
WARN - No config file found; using default curve
DEBUG - Default configuration loaded
DEBUG - [[gpus]]
id = 0
enabled = true
points = [[41, 20], [49, 30], [57, 45], [66, 55], [75, 63], [78, 72], [80, 80]]
DEBUG - Curve points: [(41, 20), (49, 30), (57, 45), (66, 55), (75, 63), (78, 72), (80, 80)]
INFO - NVIDIA driver version: 430.86
INFO - NVIDIA graphics adapter #0: GeForce GTX 1070
INFO - GPU #0 coolers: COOLER-0
INFO - NVIDIA graphics adapter #1: GeForce RTX 2070
WARN - Could not get GPU cooler indices or unsupported OS
INFO - NVIDIA graphics adapter #2: GeForce GTX 1070
INFO - GPU #2 coolers: COOLER-0
INFO - NVIDIA graphics adapter #3: GeForce GTX 1050 Ti
INFO - GPU #3 coolers: COOLER-0
INFO - NVIDIA graphics adapter #4: GeForce RTX 2070
WARN - Could not get GPU cooler indices or unsupported OS
INFO - NVIDIA graphics adapter #5: GeForce RTX 2070
WARN - Could not get GPU cooler indices or unsupported OS
INFO - NVIDIA graphics adapter #6: GeForce RTX 2070
WARN - Could not get GPU cooler indices or unsupported OS
INFO - NVIDIA graphics adapter #7: GeForce RTX 2070
WARN - Could not get GPU cooler indices or unsupported OS
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Temp: 38; Speed: [0] RPM ([0]%); Load: 0%; Mode: Auto
DEBUG - Interrupt signal
DEBUG - Exiting
DEBUG - Resetting fan control
C:\Users\Mayna\Desktop\nvfancontrol> nvfancontrol.exe -g 1 -l 40,50 -d
WARN - No config file found; using default curve
DEBUG - Default configuration loaded
DEBUG - [[gpus]]
id = 1
enabled = true
points = [[41, 20], [49, 30], [57, 45], [66, 55], [75, 63], [78, 72], [80, 80]]
thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1', /rustc/a53f9df32fbb0b5f4382caaad8f1a46f36ea887c\src\libcore\slice\mod.rs:2695:10
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
First one is gpu 0, which is GTX card. It doesn't change speed, but no errors. Second is GPU 1, which is an RTX card- Fails with error.
May I also have the output of nvfancontrol -p
?
For the GTX 1070 is normal that the fan is at 0 since by default it will kick in once T ≥ 41C. Otherwise is a bit strange that no fans are found for the RTXs. I'm wondering if this is problem with my code or NVAPI. Need to investigate further...
C:\Users\Mayna\Desktop\nvfancontrol>nvfancontrol.exe -p -d
Found 8 available GPU(s)
GPU #0: GeForce GTX 1070
COOLER-0
GPU #1: GeForce RTX 2070
What I have found from poking at manufacturer software, is that there is two different calls for NVIDIA fans. GTX uses a call like yours:
SetFanSpeed(int,unsigned long)
While RTX uses a different call:
ClientFanCoolers_SetControl( struct NvPhysicalGpuHandle__ *, unsigned long *,unsigned long *, int *, unsigned long *, int *)
Both of them proceed:
IsMultiGpuFanControlLockingEnabled(void)
and
IsFanControLocked(void)
Likely to determine fan control state needs to be set to manual, and which function to use (old or new).
It is probably the case that the handling of per-fan speed is different for RTX. However we should still be able to enumerate the fans regardless but listing of fans fails (that's why the output of -p
fails after the first RTX). I should try to fix that first before anything else.
That being said the signature ClientFanCooler_SetControl
is slightly more complicated than I would've expected. I guess one is the cooler id and the other the actual speed but it's not clear what the rest of the arguments are.
I was wrong
For GTX the function call is this:
GpuGetCoolerSettings(struct NvPhysicalGpuHandle__ *,unsigned long,struct NV_GPU_GETCOOLER_SETTINGS_V4 *)
GpuSetCoolerLevels(struct NvPhysicalGpuHandle__ *,unsigned long,struct NV_GPU_SETCOOLER_LEVEL_V2 *)
For RTX, it goes straight to this:
ClientFanCoolers_SetControl(struct NvPhysicalGpuHandle__ *,unsigned long *,unsigned long *,int *,unsigned long *,int *)
I assume the unsigned long are meant to simulate NVU32 values. I'm not sure what the rest are.
https://github.com/falahati/NvAPIWrapper/issues/10
I have also been talking about it here, if it interests you.
I give up. Stupid NVIDIA ...We can't control our own fans in Windows, thought its as simple as pie in linux.
The only thing I have figured out I believe is 100% is:
ClientFanCoolers_SetControl( [gpu handle] , ?, ?, [fan speed %] , ?, ? )
NvAPI_QueryInterface(0x814B209F)
I spent waaaay too much time on this at this point. Its frustrating that NVIDIA has to be so annoying and not release methods. Most people want to keep their cards cooler than their factory settings.
https://github.com/falahati/NvAPIWrapper/issues/10
We figured out new fan methods in windows. He solved in his wrapper, and I confirmed it works for him.
Just letting you know, if you wanted to make a Rust version. If you write something and need testing, just tag me.
Yes I was monitoring the other thread. There are indeed different functions for RTX cards. I will try to code that path in once I have some time over the next few days. I'm definitely going to need some help testing.
Following from #23 a test binary should print all fans for the card and their current levels and RPMs.
Paging @Gordin
I'm attaching a build with initial support for the new client API functions. I've done some light testing and it seems like it's working but I'd appreciate a couple more tests before merging in the changes. If you're compiling from source please use the rtx
branch and compile with cargo build --features=rtx
.
Ideally I'd like to have the following
- The output of
nvfancontrol -p
: this should print GPUs and their coolers - The output of
nvfancontrol -d -m
: this should periodically print the temperatures, load and fan settings as well as control mode (manual or auto) - The output of
nvfancontrol -d -f
: this should do what the previous command does and additionally manage the fans according to the specified curve. Please make sure there isn't any other program trying to access the fans because funny things may happen! - If you have access to older GPUs (say 8xx, 9xx, 10xx) please try to run this build of
nvfancontrol
and check if it behaves as expected.
Again thanks for helping me debug this!!
I compiled it myself and it seems to be working. The first -m and -f was with afterburner still running, the second ones are without afterburner. The values all seem to be correct. The alternating 0 and 1XXX values are because the card has flickering issue when going from 0 to anything below ~38%. Should the anti-flickering stuff work with this build? That's what I wanted to use nvfancontrol for in the first place ^^
PS C:\Users\Gordin\Documents\code\nvfancontrol> .\target\debug\nvfancontrol.exe -d -p
Found 1 available GPU(s)
GPU #0: GeForce RTX 2070 SUPER
COOLER-0
PS C:\Users\Gordin\Documents\code\nvfancontrol> .\target\debug\nvfancontrol.exe -d -m
WARN - No config file found; using default curve
DEBUG - Default configuration loaded
DEBUG - [[gpu]]
id = 0
enabled = true
points = [[41, 20], [49, 30], [57, 45], [66, 55], [75, 63], [78, 72], [80, 80]]
INFO - NVIDIA driver version: 445.87
INFO - NVIDIA graphics adapter #0: GeForce RTX 2070 SUPER
INFO - GPU #0 coolers: COOLER-0
INFO - Option "-m" is present; curve will have no actual effect
DEBUG - Temp: 30; Speed: [1240] RPM ([28]%); Load: 2%; Mode: Manual
DEBUG - Temp: 30; Speed: [1189] RPM ([28]%); Load: 2%; Mode: Manual
DEBUG - Temp: 30; Speed: [1005] RPM ([28]%); Load: 1%; Mode: Manual
DEBUG - Temp: 30; Speed: [1197] RPM ([28]%); Load: 1%; Mode: Manual
DEBUG - Temp: 30; Speed: [0] RPM ([28]%); Load: 1%; Mode: Manual
DEBUG - Temp: 30; Speed: [1288] RPM ([28]%); Load: 1%; Mode: Manual
DEBUG - Temp: 30; Speed: [0] RPM ([28]%); Load: 1%; Mode: Manual
DEBUG - Temp: 30; Speed: [1441] RPM ([28]%); Load: 1%; Mode: Manual
DEBUG - Temp: 30; Speed: [0] RPM ([28]%); Load: 2%; Mode: Manual
DEBUG - Temp: 30; Speed: [1486] RPM ([28]%); Load: 2%; Mode: Manual
DEBUG - Temp: 30; Speed: [0] RPM ([28]%); Load: 7%; Mode: Manual
DEBUG - Temp: 30; Speed: [1249] RPM ([28]%); Load: 3%; Mode: Manual
DEBUG - Temp: 30; Speed: [1032] RPM ([28]%); Load: 3%; Mode: Manual
DEBUG - Interrupt signal
DEBUG - Exiting
DEBUG - Resetting fan control
PS C:\Users\Gordin\Documents\code\nvfancontrol> .\target\debug\nvfancontrol.exe -d -f
DEBUG - Default configuration loaded
DEBUG - [[gpu]]
id = 0
enabled = true
points = [[41, 20], [49, 30], [57, 45], [66, 55], [75, 63], [78, 72], [80, 80]]
DEBUG - Curve points: [(41, 20), (49, 30), (57, 45), (66, 55), (75, 63), (78, 72), (80, 80)]
INFO - NVIDIA driver version: 445.87
INFO - NVIDIA graphics adapter #0: GeForce RTX 2070 SUPER
INFO - GPU #0 coolers: COOLER-0
DEBUG - Temp: 30; Speed: [1381] RPM ([28]%); Load: 2%; Mode: Auto
DEBUG - Temp: 30; Speed: [1309] RPM ([28]%); Load: 1%; Mode: Auto
DEBUG - Temp: 30; Speed: [0] RPM ([28]%); Load: 1%; Mode: Auto
DEBUG - Temp: 30; Speed: [1215] RPM ([28]%); Load: 1%; Mode: Auto
DEBUG - Temp: 30; Speed: [1278] RPM ([28]%); Load: 1%; Mode: Auto
DEBUG - Temp: 30; Speed: [1283] RPM ([28]%); Load: 1%; Mode: Auto
DEBUG - Interrupt signal
DEBUG - Exiting
DEBUG - Resetting fan control
PS C:\Users\Gordin\Documents\code\nvfancontrol> .\target\debug\nvfancontrol.exe -d -f
WARN - No config file found; using default curve
DEBUG - Default configuration loaded
DEBUG - [[gpu]]
id = 0
enabled = true
points = [[41, 20], [49, 30], [57, 45], [66, 55], [75, 63], [78, 72], [80, 80]]
DEBUG - Curve points: [(41, 20), (49, 30), (57, 45), (66, 55), (75, 63), (78, 72), (80, 80)]
INFO - NVIDIA driver version: 445.87
INFO - NVIDIA graphics adapter #0: GeForce RTX 2070 SUPER
INFO - GPU #0 coolers: COOLER-0
DEBUG - Temp: 30; Speed: [0] RPM ([0]%); Load: 2%; Mode: Auto
DEBUG - Temp: 30; Speed: [0] RPM ([0]%); Load: 1%; Mode: Auto
DEBUG - Temp: 30; Speed: [0] RPM ([0]%); Load: 1%; Mode: Auto
DEBUG - Temp: 30; Speed: [0] RPM ([0]%); Load: 1%; Mode: Auto
DEBUG - Temp: 30; Speed: [0] RPM ([0]%); Load: 2%; Mode: Auto
DEBUG - Temp: 30; Speed: [0] RPM ([0]%); Load: 1%; Mode: Auto
DEBUG - Temp: 30; Speed: [0] RPM ([0]%); Load: 1%; Mode: Auto
DEBUG - Temp: 30; Speed: [0] RPM ([0]%); Load: 1%; Mode: Auto
DEBUG - Interrupt signal
DEBUG - Exiting
DEBUG - Resetting fan control
PS C:\Users\Gordin\Documents\code\nvfancontrol> .\target\debug\nvfancontrol.exe -d -m
WARN - No config file found; using default curve
DEBUG - Default configuration loaded
DEBUG - [[gpu]]
id = 0
enabled = true
points = [[41, 20], [49, 30], [57, 45], [66, 55], [75, 63], [78, 72], [80, 80]]
DEBUG - Curve points: [(41, 20), (49, 30), (57, 45), (66, 55), (75, 63), (78, 72), (80, 80)]
INFO - NVIDIA driver version: 445.87
INFO - NVIDIA graphics adapter #0: GeForce RTX 2070 SUPER
INFO - GPU #0 coolers: COOLER-0
INFO - Option "-m" is present; curve will have no actual effect
DEBUG - Temp: 31; Speed: [0] RPM ([0]%); Load: 4%; Mode: Auto
DEBUG - Temp: 31; Speed: [0] RPM ([0]%); Load: 1%; Mode: Auto
DEBUG - Temp: 31; Speed: [0] RPM ([0]%); Load: 1%; Mode: Auto
DEBUG - Temp: 31; Speed: [0] RPM ([0]%); Load: 1%; Mode: Auto
DEBUG - Temp: 31; Speed: [0] RPM ([0]%); Load: 2%; Mode: Auto
DEBUG - Temp: 31; Speed: [0] RPM ([0]%); Load: 2%; Mode: Auto
DEBUG - Interrupt signal
DEBUG - Exiting
DEBUG - Resetting fan control
I have access to a 970 and a 1070, but no second PC and I'd rather not swap around the cards all day unless you think you're close to having everything work ^^
The cards had no problem Afterburner though. I looked at the SetFanSpeed
call in Afterburner in a x32dbg, and it looks like (in the Graph) the only thing they are checking to decide whether to use the new API or not is the result from ClientFanCoolers_IsSupported
. For me it goes to the right to the ClientFanCoolers_SetControl
part, while for other cards it will use GpuSetCoolerLevels
.
You can probably search for all calls of *Supported
to figure out what calls to make. I don't use debuggers much but it looks like it could be easy for someone with experience. All the calls to nvapi have wrappers that look very similiar. There seem to be 10 different calls with "Supported" (that Afterburner uses):
Address Type Ordinal Symbol Symbol (undecorated)
008141C0 Export 498 ?ClientFanCoolers_IsSupported@CNVAPIWrapper@@QAEHXZ public: int __thiscall CNVAPIWrapper::ClientFanCoolers_IsSupported(void)
00813520 Export 1881 ?IsCoreClockControlSupported@CNVAPIWrapper@@QAEHXZ public: int __thiscall CNVAPIWrapper::IsCoreClockControlSupported(void)
00813760 Export 1937 ?IsFramerateLimitControlSupported@CNVAPIWrapper@@QAEHXZ public: int __thiscall CNVAPIWrapper::IsFramerateLimitControlSupported(void)
00813520 Export 2035 ?IsMemoryClockControlSupported@CNVAPIWrapper@@QAEHXZ public: int __thiscall CNVAPIWrapper::IsMemoryClockControlSupported(void)
00816AF0 Export 2072 ?IsPerfClocksTestSupported@CNVAPIWrapper@@QAEHXZ public: int __thiscall CNVAPIWrapper::IsPerfClocksTestSupported(void)
00813720 Export 2082 ?IsPerfPolicySupported@CNVAPIWrapper@@QAEHK@Z public: int __thiscall CNVAPIWrapper::IsPerfPolicySupported(unsigned long)
00816560 Export 2131 ?IsShaderClockControlSupported@CNVAPIWrapper@@QAEHK@Z public: int __thiscall CNVAPIWrapper::IsShaderClockControlSupported(unsigned long)
00814C70 Export 2354 ?PS20_IsRelVoltageSupported@CNVAPIWrapper@@QAEHXZ public: int __thiscall CNVAPIWrapper::PS20_IsRelVoltageSupported(void)
00813510 Export 2355 ?PS20_IsSupported@CNVAPIWrapper@@QAEHXZ public: int __thiscall CNVAPIWrapper::PS20_IsSupported(void)
00813D80 Export 2868 ?VFCurve_IsSupported@CNVAPIWrapper@@QAEHXZ public: int __thiscall CNVAPIWrapper::VFCurve_IsSupported(void)
OK so it looks like it's working but could you please actually produce some load on the GPU so that the curve kicks in? That's the only way to check if the *Set
command is actually working and if it's working as intended.
The IsSupported
should check for the new API. Need to find out what's its signature.
As for the flicker bit: please check. I don't have this issue with my card (fan is always ON) so I can't test it. All the lower level bits are abstracted away so if the curve is applied I can't see any reason why it won't work.
OK, I tested with load and Reading the Coolers works, but Setting does not. When I first tested it, it looked like nvfancontrol was competing with Afterburner in setting the fan speed to 0, so I assumed it was working. As soon as it tries to set a value I'm getting
ERROR - Could not update fan speed: NvAPI_GPU_SetCoolerLevels() failed; error -104
but that's expected I guess because my card wants the ClientFanCoolers_SetControl
This is with -d -f
Yes, obviously because I did not update set_fanspeed
! Will post an updated binary soon.
It works now :)
The anti fan flickering also works but I guess that doesn't have anything to do with the actual nvapi calls anyway. Although, (this is really just a not very important feature request...), it would be nice to be able to configure the steps it uses, I'm ramping up to 38% and then down to 25%, so right now it goes down by 1% each tick which takes 13 seconds but when I do it manually I can just go down to 32% and then to 25% with a second apart and it will still work.
This is from -d -f -r 25,35
DEBUG - Temp: 38; Speed: [774] RPM ([25]%); Load: 36%; Mode: Manual
DEBUG - FanFlickerFix: preventing fan-off
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(25) to InRange(25) (decrease), staying at 25%
DEBUG - Temp: 38; Speed: [776] RPM ([25]%); Load: 35%; Mode: Manual
DEBUG - FanFlickerFix: preventing fan-off
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(25) to InRange(25) (decrease), staying at 25%
DEBUG - Temp: 36; Speed: [777] RPM ([25]%); Load: 4%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(25) to Below(23) (decrease), staying at 25%
DEBUG - Temp: 44; Speed: [775] RPM ([25]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(25) to InRange(25) (decrease), staying at 25%
DEBUG - Temp: 45; Speed: [776] RPM ([25]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(25) to InRange(26) (increase), setting 26%
DEBUG - Temp: 46; Speed: [774] RPM ([25]%); Load: 95%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(26) to InRange(27) (increase), setting 27%
DEBUG - Temp: 47; Speed: [803] RPM ([26]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(27) to InRange(28) (increase), setting 28%
DEBUG - Temp: 48; Speed: [838] RPM ([27]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(28) to InRange(28) (decrease), staying at 28%
DEBUG - Temp: 48; Speed: [871] RPM ([28]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(28) to InRange(30) (increase), setting 30%
DEBUG - Temp: 49; Speed: [872] RPM ([28]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(30) to InRange(31) (increase), setting 31%
DEBUG - Temp: 50; Speed: [923] RPM ([30]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(31) to InRange(31) (decrease), staying at 31%
DEBUG - Temp: 50; Speed: [960] RPM ([31]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(31) to InRange(33) (increase), setting 33%
DEBUG - Temp: 50; Speed: [966] RPM ([31]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(33) to InRange(33) (decrease), staying at 33%
DEBUG - Temp: 51; Speed: [1022] RPM ([33]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(33) to InRange(35) (increase), setting 35%
DEBUG - Temp: 51; Speed: [1026] RPM ([33]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(35) to InRange(35) (decrease), staying at 35%
DEBUG - Temp: 52; Speed: [1080] RPM ([35]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from InRange(35) to Above(37) (increase), setting 37%
DEBUG - Temp: 53; Speed: [1088] RPM ([35]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(37) to Above(37) (decrease), staying at 37%
DEBUG - Temp: 53; Speed: [1147] RPM ([37]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(37) to Above(37) (decrease), staying at 37%
DEBUG - Temp: 53; Speed: [1151] RPM ([37]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(37) to Above(39) (increase), setting 39%
DEBUG - Temp: 54; Speed: [1147] RPM ([37]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(39) to Above(39) (decrease), staying at 39%
DEBUG - Temp: 54; Speed: [1214] RPM ([39]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(39) to Above(41) (increase), setting 41%
DEBUG - Temp: 55; Speed: [1214] RPM ([39]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(41) to Above(41) (decrease), staying at 41%
DEBUG - Temp: 55; Speed: [1267] RPM ([41]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(41) to Above(41) (decrease), staying at 41%
DEBUG - Temp: 55; Speed: [1274] RPM ([41]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(41) to Above(43) (increase), setting 43%
DEBUG - Temp: 56; Speed: [1274] RPM ([41]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(43) to Above(43) (decrease), staying at 43%
DEBUG - Temp: 56; Speed: [1334] RPM ([43]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(43) to Above(43) (decrease), staying at 43%
DEBUG - Temp: 56; Speed: [1335] RPM ([43]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(43) to Above(43) (decrease), staying at 43%
DEBUG - Temp: 56; Speed: [1336] RPM ([43]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(43) to Above(43) (decrease), staying at 43%
DEBUG - Temp: 56; Speed: [1336] RPM ([43]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(43) to Above(45) (increase), setting 45%
DEBUG - Temp: 57; Speed: [1333] RPM ([43]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(45) to Above(45) (decrease), staying at 45%
DEBUG - Temp: 57; Speed: [1398] RPM ([45]%); Load: 98%; Mode: Manual
DEBUG - FanFlickerFix [25, 35]: requested change from Above(45) to Above(45) (decrease), staying at 45%
That's good! We're getting closer. It's still unclear whether there is indeed a NVAPI call for the IsSupported
function or Afterburner uses some logic to determine it. In any case if there is a function for that it's going to take a while to debug afterburner to find its magic code. Unfortunately everything in the NVAPI is hidden behind the nvapi_QueryInterface
function which takes a magic number and returns a pointer to a function. For anything that's not on the public API you will have to go through debuggers and I'm not really familiar with them especially on Windows. In any case I'll try to provide a unified solution and then merge the changes so there might be another binary for you to test soon.
For fanflicker we should probably involve @tzh1043 as the original author of that code, but this is not relevant to this issue; open a new issue if you want to pursue it further.
Hm, from what I've seen in the debugger I think it is an NVAPI call. All the NVAPI calls from afterburner have the same structure, and they all have the magic number value hardcoded in them. I'll see if I have time today to look at this again, I can probably find the magic value and at least the number of arguments.
Nevermind, ClientFanCoolers_IsSupported
is not n NVAPI call it's just (X + 0x1538) >> 6 & 1
. Not sure what X is yet...
Edit: (X + 0x1538) is obviously a pointer to something, I'm bad at this (: