1

I have an application that does some drawing via Direct2D and captures screen contents via the Desktop Duplication API. It is a C# application, but I have custom layered windows to do my displaying and I am rendering via Direct2D to get around the "smart" drawing in WPF that was previously causing my application to not compete very aggressively for graphics resources.

If I run this application at the same time as a DirectX game that takes lots of graphics resources, then the behavior I get is as follows:

  1. if my application is the foreground application, it works ok

  2. if my application is visible but not the foreground application, then the calls to Map Subresource and Copy Resource take highly variable amounts of time, sometimes blocking for hundreds of milliseconds (according to the profiler.) I am not sure I believe the outliers in the hundreds, but certainly Map Subresource averages 50ms so the capture rate drops to below 20FPS. When running in the foreground, the same call takes 4ms on average.

I already checked if manipulating process and thread priorities can do anything, but it does not. It appears that DirectX is throttling my stuff when I am not foreground, independent of priorities. This is a problem because my application needs to run full frame rate without being foreground.

If it is strictly prioritizing GPU commands from the foreground application, then I could see that maybe my app is being starved out on the channels to/from the GPU, because that would explain stalling out like that. If I could somehow exempt this application from such policing, that would be optimal. Like for example some sort of manifest entry or DirectX call that notifies the driver (or stack) not to consider my application to be background?

I compared the code of OBS (as far as I can work it out) and I don't see what they do different. How does OBS manage to continue duplicating / capturing even though they are clearly not the foreground application when streaming even demanding games?

[edit]

The game in question is DCS, which always uses all available GPU resources if you let it, and uses about 1.5 cores. When I say it starts to slow down when not in foreground, I am literally talking about clicking on a window from my app versus clicking in the game window (not even minimizing or anything.) When I am in foreground, DCS slows down as I consume resources. If DCS is in the foreground, it continues to render at its full rate and uses all resources and my capture slows way down.

I have found that I can make things work well if I just limit DCS to 60 FPS via vsync, so that it can't use all resources. Then everything works perfectly fine. Obviously, that does not solve the problem, but it further shows this is some resource contention most likely. I am fine competing for the resources, but it does seem to prioritize the foreground app in DirectX (or Nvidia's driver?)

[/edit]

Ammo Goettsch
  • 838
  • 8
  • 11
  • This is quite unexpected. Are you sure you don't have any 3rd party that would do this? Is it doing the same with the official Microsoft sample (https://github.com/microsoft/Windows-classic-samples/tree/master/Samples/DXGIDesktopDuplication)? Have you tried another graphics card hardware (NVidia vs AMD vs Intel vs Software)? Another PC? Another game? Have you enabled the DirectX debug layer and check you don't have messages? – Simon Mourier Nov 23 '20 at 07:33
  • @SimonMourier that's some good advice. The example program is structurally different, in that it does not pull back the captured frame to the CPU for editing, but just uses the texture to render each dirty rect as a textured rectangle. That means it can technically stay on the card, if the same video card is displaying the output and capturing. I don't have the ability to test with other video cards, since I just have a pile of nvidia ones :). Making it work with another game would not help me, really, since I write an add-on to this particular game. [see edit to question] – Ammo Goettsch Nov 23 '20 at 14:58
  • PS: to be clear: yes I did test the sample program and it doesn't have the same problem, but then it isn't trying to map the texture back to the CPU – Ammo Goettsch Nov 23 '20 at 15:06
  • Nothing from DirectX debug either. My next step will be to hack up the native sample app to do basically what I do and see if I observe the same slow down / contention. – Ammo Goettsch Nov 23 '20 at 15:41
  • If official sample works fine, it's probably your code that causes this for some reason. Difficult to say more w/o some reproducing bits. – Simon Mourier Nov 23 '20 at 17:27

1 Answers1

2

I Encountered Exact same issue and Found that it's because of Window's Gamemode feature. Turning it off and rebooting fixed it for me.

Also, I was using Direct x video processor for scaling my images And It's performance is highly inconsistent with various driver updates so for now i've decided to use "as is" without scaling.