-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nvapi-gpu: Add NvAPI_GPU_GetMemoryInfo/Ex #198
Conversation
10b8746
to
6ed4be8
Compare
cc @SveSop since you are the original author. |
Does not seem like an obvious way to get available memory, although it should be doable i would think. Maybe if DXVK has "used" memory and just a simple calculation. |
Isn't available memory pretty much the same thing as |
src/nvapi_gpu.cpp
Outdated
case NV_DISPLAY_DRIVER_MEMORY_INFO_VER_1: { | ||
auto pMemoryInfoV1 = reinterpret_cast<NV_DISPLAY_DRIVER_MEMORY_INFO_V1*>(pMemoryInfo); | ||
pMemoryInfoV1->dedicatedVideoMemory = adapter->GetVRamSize(); | ||
pMemoryInfoV1->availableDedicatedVideoMemory = 0; // Not found in DXVK | ||
pMemoryInfoV1->systemVideoMemory = adapter->GetDedicatedSystemRamSize(); | ||
pMemoryInfoV1->sharedSystemMemory = adapter->GetSharedSystemRamSize(); | ||
break; | ||
} | ||
case NV_DISPLAY_DRIVER_MEMORY_INFO_VER_2: { | ||
auto pMemoryInfoV2 = reinterpret_cast<NV_DISPLAY_DRIVER_MEMORY_INFO_V2*>(pMemoryInfo); | ||
pMemoryInfoV2->dedicatedVideoMemory = adapter->GetVRamSize(); | ||
pMemoryInfoV2->availableDedicatedVideoMemory = 0; // Not found in DXVK | ||
pMemoryInfoV2->systemVideoMemory = adapter->GetDedicatedSystemRamSize(); | ||
pMemoryInfoV2->sharedSystemMemory = adapter->GetSharedSystemRamSize(); | ||
pMemoryInfoV2->curAvailableDedicatedVideoMemory = 0; // Not found in DXVK | ||
break; | ||
} | ||
case NV_DISPLAY_DRIVER_MEMORY_INFO_VER_3: { | ||
auto pMemoryInfoV3 = reinterpret_cast<NV_DISPLAY_DRIVER_MEMORY_INFO_V3*>(pMemoryInfo); | ||
pMemoryInfoV3->dedicatedVideoMemory = adapter->GetVRamSize(); | ||
pMemoryInfoV3->availableDedicatedVideoMemory = 0; // Not found in DXVK | ||
pMemoryInfoV3->systemVideoMemory = adapter->GetDedicatedSystemRamSize(); | ||
pMemoryInfoV3->sharedSystemMemory = adapter->GetSharedSystemRamSize(); | ||
pMemoryInfoV3->curAvailableDedicatedVideoMemory = 0; // Not found in DXVK | ||
pMemoryInfoV3->dedicatedVideoMemoryEvictionsSize = 0; | ||
pMemoryInfoV3->dedicatedVideoMemoryEvictionCount = 0; | ||
break; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder, can we just use the given pointer as-it without reinterpret-casting it? I think it should be possible because the offset of each member appears to be the same in every struct version in which it's present. That should allow us to make this a bit more DRY, if you don't mind some classic switch fallthrough:
case NV_DISPLAY_DRIVER_MEMORY_INFO_VER_1: { | |
auto pMemoryInfoV1 = reinterpret_cast<NV_DISPLAY_DRIVER_MEMORY_INFO_V1*>(pMemoryInfo); | |
pMemoryInfoV1->dedicatedVideoMemory = adapter->GetVRamSize(); | |
pMemoryInfoV1->availableDedicatedVideoMemory = 0; // Not found in DXVK | |
pMemoryInfoV1->systemVideoMemory = adapter->GetDedicatedSystemRamSize(); | |
pMemoryInfoV1->sharedSystemMemory = adapter->GetSharedSystemRamSize(); | |
break; | |
} | |
case NV_DISPLAY_DRIVER_MEMORY_INFO_VER_2: { | |
auto pMemoryInfoV2 = reinterpret_cast<NV_DISPLAY_DRIVER_MEMORY_INFO_V2*>(pMemoryInfo); | |
pMemoryInfoV2->dedicatedVideoMemory = adapter->GetVRamSize(); | |
pMemoryInfoV2->availableDedicatedVideoMemory = 0; // Not found in DXVK | |
pMemoryInfoV2->systemVideoMemory = adapter->GetDedicatedSystemRamSize(); | |
pMemoryInfoV2->sharedSystemMemory = adapter->GetSharedSystemRamSize(); | |
pMemoryInfoV2->curAvailableDedicatedVideoMemory = 0; // Not found in DXVK | |
break; | |
} | |
case NV_DISPLAY_DRIVER_MEMORY_INFO_VER_3: { | |
auto pMemoryInfoV3 = reinterpret_cast<NV_DISPLAY_DRIVER_MEMORY_INFO_V3*>(pMemoryInfo); | |
pMemoryInfoV3->dedicatedVideoMemory = adapter->GetVRamSize(); | |
pMemoryInfoV3->availableDedicatedVideoMemory = 0; // Not found in DXVK | |
pMemoryInfoV3->systemVideoMemory = adapter->GetDedicatedSystemRamSize(); | |
pMemoryInfoV3->sharedSystemMemory = adapter->GetSharedSystemRamSize(); | |
pMemoryInfoV3->curAvailableDedicatedVideoMemory = 0; // Not found in DXVK | |
pMemoryInfoV3->dedicatedVideoMemoryEvictionsSize = 0; | |
pMemoryInfoV3->dedicatedVideoMemoryEvictionCount = 0; | |
break; | |
} | |
case NV_DISPLAY_DRIVER_MEMORY_INFO_VER_3: | |
pMemoryInfo->dedicatedVideoMemoryEvictionsSize = 0; | |
pMemoryInfo->dedicatedVideoMemoryEvictionCount = 0; | |
[[fallthrough]]; | |
case NV_DISPLAY_DRIVER_MEMORY_INFO_VER_2: | |
pMemoryInfo->curAvailableDedicatedVideoMemory = …; | |
[[fallthrough]]; | |
case NV_DISPLAY_DRIVER_MEMORY_INFO_VER_1: | |
pMemoryInfo->dedicatedVideoMemory = adapter->GetVRamSize(); | |
pMemoryInfo->availableDedicatedVideoMemory = …; | |
pMemoryInfo->systemVideoMemory = adapter->GetDedicatedSystemRamSize(); | |
pMemoryInfo->sharedSystemMemory = adapter->GetSharedSystemRamSize(); | |
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, this looks cool, we should probably do this for other places too.
6ed4be8
to
cd4d980
Compare
See last WIP commit, I'm also thinking/playing in that direction, with thanks to @SveSop for his hint this morning.
|
@@ -48,17 +58,19 @@ namespace dxvk { | |||
private: | |||
Vulkan& m_vulkan; | |||
Nvml& m_nvml; | |||
Com<IDXGIAdapter3> m_dxgiAdapter; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess no way around to keep an adapter alive. I hope this won't give us tear down issues in titles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless adapters are singletons (which I don't think they are) it should be fine. But if it proves to be a problem we can always try switching to manual usage of VK_EXT_memory_budget
on our own.
src/nvapi_gpu.cpp
Outdated
pMemoryInfoV2->availableDedicatedVideoMemory = adapter->GetVideoMemory().Budget; | ||
pMemoryInfoV2->systemVideoMemory = adapter->GetVideoMemory().DedicatedSystemMemory; | ||
pMemoryInfoV2->sharedSystemMemory = adapter->GetVideoMemory().SharedSystemMemory; | ||
pMemoryInfoV2->curAvailableDedicatedVideoMemory = adapter->GetVideoMemory().Budget - adapter->GetVideoMemory().CurrentUsage; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure about this one. The others seem to roughly match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I understand correctly that:
dedicatedVideoMemory
is simply the total size of device-local heap and should probably never change,availableDedicatedVideoMemory
is how much of above is left for the application to allocate, sodedicatedVideoMemory
reduced by other application's allocations and areas reserved for private use by the driver, if any (and current application allocating memory shouldn't affect this),curAvailableDedicatedVideoMemory
is how much of above is left for the application to allocate after we include allocations it already made, soavailableDedicatedVideoMemory
reduced by application's own allocated memory size?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is indeed more or less how I understood the terminology, based on the nvapi headers and @SveSop 's numbers:
NvU64 dedicatedVideoMemory; //!< Size(in bytes) of the physical framebuffer. Refers to the dedicated video memory on discrete GPUs.
//! It is more performant for GPU operations than the reserved systemVideoMemory.
NvU64 availableDedicatedVideoMemory; //!< Size(in bytes) of the available physical framebuffer for allocating video memory surfaces.
NvU64 systemVideoMemory; //!< Size(in bytes) of system memory the driver allocates at load time. It is a substitute for dedicated video memory.
//!< Typically used with integrated GPUs that do not have dedicated video memory.
NvU64 sharedSystemMemory; //!< Size(in bytes) of shared system memory that driver is allowed to commit for surfaces across all allocations.
//!< On discrete GPUs, it is used to utilize system memory for various operations. It does not need to be reserved during boot.
//!< It may be used by both GPU and CPU, and has an �on-demand� type of usage.
NvU64 curAvailableDedicatedVideoMemory; //!< Size(in bytes) of the current available physical framebuffer for allocating video memory surfaces.
Co-authored-by: Sveinar Søpler <cybermax@dexter.no>
cd4d980
to
10c9fe6
Compare
@@ -48,17 +58,19 @@ namespace dxvk { | |||
private: | |||
Vulkan& m_vulkan; | |||
Nvml& m_nvml; | |||
Com<IDXGIAdapter3> m_dxgiAdapter; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless adapters are singletons (which I don't think they are) it should be fine. But if it proves to be a problem we can always try switching to manual usage of VK_EXT_memory_budget
on our own.
src/nvapi_gpu.cpp
Outdated
pMemoryInfoV2->availableDedicatedVideoMemory = adapter->GetVideoMemory().Budget; | ||
pMemoryInfoV2->systemVideoMemory = adapter->GetVideoMemory().DedicatedSystemMemory; | ||
pMemoryInfoV2->sharedSystemMemory = adapter->GetVideoMemory().SharedSystemMemory; | ||
pMemoryInfoV2->curAvailableDedicatedVideoMemory = adapter->GetVideoMemory().Budget - adapter->GetVideoMemory().CurrentUsage; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I understand correctly that:
dedicatedVideoMemory
is simply the total size of device-local heap and should probably never change,availableDedicatedVideoMemory
is how much of above is left for the application to allocate, sodedicatedVideoMemory
reduced by other application's allocations and areas reserved for private use by the driver, if any (and current application allocating memory shouldn't affect this),curAvailableDedicatedVideoMemory
is how much of above is left for the application to allocate after we include allocations it already made, soavailableDedicatedVideoMemory
reduced by application's own allocated memory size?
10c9fe6
to
3fa7e84
Compare
3fa7e84
to
b587d3c
Compare
@Saancreed |
b587d3c
to
e7a34cc
Compare
Me thinks the calculation of Then again, On windows i get on my 2070 8GB card: 8192MB, but using dxvk-nvapi i get 8438MB. Might be some method that DXVK calculates this as it might be adding some extra "heap" stuff-whatever? (Safeguards or whatnot) I have a small test proggy i have compiled that runs some nvapi tests that i attach. |
Thanks for the explanation @SveSop. Interestingly, for me nvapi system tests print
so dedicated video memory matches exactly. This also matches how Vulkan memory heaps are reported, which afaik is what DXVK sums up when reporting memory budget info:
As another data point,
So yeah, there is ~378 MiB of VRAM that's reserved for the driver and GPU firmware which we should probably subtract from |
Unless it is too inconvenient we could use nvml for this, and just use |
I'm reaching the same conclusion. What we have now is: pMemoryInfoV1->dedicatedVideoMemory = vidMemInfo.DedicatedVideoMemory;
pMemoryInfoV1->systemVideoMemory = vidMemInfo.DedicatedSystemMemory;
pMemoryInfoV1->sharedSystemMemory = vidMemInfo.SharedSystemMemory;
pMemoryInfoV1->availableDedicatedVideoMemory = curVidMemInfo.Budget;
pMemoryInfoV1->curAvailableDedicatedVideoMemory = curVidMemInfo.Budget - curVidMemInfo.CurrentUsage; but what we actually want to have is: ...
pMemoryInfoV1->availableDedicatedVideoMemory = vidMemInfo.DedicatedVideoMemory - vidMemInfo.Reseverd;
... But since we don't have ...
pMemoryInfoV1->availableDedicatedVideoMemory = vidMemInfo.DedicatedVideoMemory;
... is indeed the best we can do (that is, without NVML). That way we have a stable number, but we are also overshooting. Just blindly subtracting 2% from |
e7a34cc
to
d981335
Compare
I suggest to create two follow up issues for picking up after this PR:
|
d981335
to
47d8f3e
Compare
PS: Still not completely sure if it should be pMemoryInfoV1->curAvailableDedicatedVideoMemory = curVidMemInfo.Budget - curVidMemInfo.CurrentUsage; or pMemoryInfoV1->curAvailableDedicatedVideoMemory = curVidMemInfo.Budget; So, does |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One comment and we should really check if we should subtract usage from budget because I would guess we shouldn't but otherwise LGTM.
Yes, sleeping a night over it, I also think that we should not. This would also better fit terminology since |
68d3705
to
283e5f9
Compare
283e5f9
to
bda44be
Compare
TODO:
Closes #197