You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
My name is Daniel Isheden, and I'm a rendering engineer at CCP Games. We are currently working on implementing a wide variety of upscaling techniques into EVE Online. This includes DLSS 3 through Streamline, both for DX11 and DX12. While DLSS is working fine on DX12, (including with frame generation), we are seeing a significant memory leak on DX11 when we recreate the D3D11 device, which we believe is caused by Streamline.
The memory leak issue
Due to the vastly different requirements of different upscaling techniques (for example FSR3 and DLSS3 requiring control over the devices and swapchains), we completely destroy and reinitialize a new device whenever we need to change upscaling methods or upscaling settings. The memory leak seems to be caused by Streamline incorrectly holding on to the D3D11 device which we pass in, preventing it from being destroyed. This causes us to leak the entire device, along with a large amount of VRAM, around 200-500 MBs depending on screen resolution and settings. We can see that when we call Release() on the device, the ref count is significantly higher after we have passed the device to Streamline using slSetD3DDevice().
Here are the relevant commands that we do to initialize Streamline.
Initialize Streamline using slInit().
Create the D3D11 device using D3D11CreateDeviceAndSwapChain().
Attach the device to Streamline using slSetD3DDevice().
When we're done, we call slShutdown().
As soon as we have called slSetD3DDevice() with the D3D11 device, the device will not be correctly released by Streamline, even if we never actually do anything with Streamline beyond calling slShutdown() after that. There doesn't seem to be a way to get Streamline to correctly release the device. Again, this problem only occurs for DX11. This is not a problem in DX12.
Apart from the memory leak, DLSS itself works correctly on DX11 for us. Also, this memory leak goes away completely if we just skip calling slSetD3DDevice(), but this unfortunately breaks DLSS (see below).
Do we need to call slSetD3DDevice()?
The Streamline Programming Guide says:
"IMPORTANT When using d3d11 it is important to note that calling D3D11CreateDeviceAndSwapChain will result in that device being automatically assigned to SL."
We are indeed using D3D11CreateDeviceAndSwapChain() to create our device and swapchain, so according to this spec, we shouldn't need to call slSetD3DDevice() at all. Skipping the call to slSetD3DDevice() does indeed fix the memory leak, which seems to imply that the problem is that we're essentially setting the device "twice", once implicitly with D3D11CreateDeviceAndSwapChain() and once explicitly with slSetD3DDevice(). Then when we call slShutdown(), the device is only released once, causing the reference count to never reach 0.
Unfortunately, there seems to be a separate bug here which prevents DLSS from functioning without calling slSetD3DDevice() manually. While we are able to turn on DLSS using slSetFeatureLoaded(), when we actually try to call slDLSSGetOptimalSettings(), we get a eErrorMissingOrInvalidAPI error, along with the following error in the console:
"[17-24-37][streamline][error][tid:52156][14s:954ms:054us]dlssentry.cpp:815[slGetData] NGX context is missing, please make sure DLSSContext feature is enabled and supported on the platform"
This error goes away and DLSS works correctly if we call slSetD3DDevice() with our device, but again, according to the documentation we shouldn't need to. It makes no sense that setting the device "twice" both fixes this error AND causes a memory leak.
We have also tried to do slSetD3DDevice(nullptr) in an attempt to clear the implicitly set device, then set it explicitly again, but slSetD3DDevice(nullptr) always causes an access violation inside of Streamline.
I am working to put together a repro program for this issue, which I will provide through a different channel early next week! In the meanwhile, I wanted to provide as much information as I could through this ticket, as I believe this issue should be relatively easy to reproduce.
The text was updated successfully, but these errors were encountered:
jake-nv
added
bug
Something isn't working
ack
Acknowledged. We may or may not do something, but won’t commit either way.
labels
Aug 8, 2024
Hello!
My name is Daniel Isheden, and I'm a rendering engineer at CCP Games. We are currently working on implementing a wide variety of upscaling techniques into EVE Online. This includes DLSS 3 through Streamline, both for DX11 and DX12. While DLSS is working fine on DX12, (including with frame generation), we are seeing a significant memory leak on DX11 when we recreate the D3D11 device, which we believe is caused by Streamline.
The memory leak issue
Due to the vastly different requirements of different upscaling techniques (for example FSR3 and DLSS3 requiring control over the devices and swapchains), we completely destroy and reinitialize a new device whenever we need to change upscaling methods or upscaling settings. The memory leak seems to be caused by Streamline incorrectly holding on to the D3D11 device which we pass in, preventing it from being destroyed. This causes us to leak the entire device, along with a large amount of VRAM, around 200-500 MBs depending on screen resolution and settings. We can see that when we call Release() on the device, the ref count is significantly higher after we have passed the device to Streamline using slSetD3DDevice().
Here are the relevant commands that we do to initialize Streamline.
As soon as we have called slSetD3DDevice() with the D3D11 device, the device will not be correctly released by Streamline, even if we never actually do anything with Streamline beyond calling slShutdown() after that. There doesn't seem to be a way to get Streamline to correctly release the device. Again, this problem only occurs for DX11. This is not a problem in DX12.
Apart from the memory leak, DLSS itself works correctly on DX11 for us. Also, this memory leak goes away completely if we just skip calling slSetD3DDevice(), but this unfortunately breaks DLSS (see below).
Do we need to call slSetD3DDevice()?
The Streamline Programming Guide says:
We are indeed using D3D11CreateDeviceAndSwapChain() to create our device and swapchain, so according to this spec, we shouldn't need to call slSetD3DDevice() at all. Skipping the call to slSetD3DDevice() does indeed fix the memory leak, which seems to imply that the problem is that we're essentially setting the device "twice", once implicitly with D3D11CreateDeviceAndSwapChain() and once explicitly with slSetD3DDevice(). Then when we call slShutdown(), the device is only released once, causing the reference count to never reach 0.
Unfortunately, there seems to be a separate bug here which prevents DLSS from functioning without calling slSetD3DDevice() manually. While we are able to turn on DLSS using slSetFeatureLoaded(), when we actually try to call slDLSSGetOptimalSettings(), we get a eErrorMissingOrInvalidAPI error, along with the following error in the console:
This error goes away and DLSS works correctly if we call slSetD3DDevice() with our device, but again, according to the documentation we shouldn't need to. It makes no sense that setting the device "twice" both fixes this error AND causes a memory leak.
We have also tried to do slSetD3DDevice(nullptr) in an attempt to clear the implicitly set device, then set it explicitly again, but slSetD3DDevice(nullptr) always causes an access violation inside of Streamline.
I am working to put together a repro program for this issue, which I will provide through a different channel early next week! In the meanwhile, I wanted to provide as much information as I could through this ticket, as I believe this issue should be relatively easy to reproduce.
The text was updated successfully, but these errors were encountered: