ScreenCapture.NET icon indicating copy to clipboard operation
ScreenCapture.NET copied to clipboard

Desktop duplication on hybrid systems

Open follyfoxe opened this issue 1 year ago • 3 comments

Turns out DirectX's desktop duplication API has a limitation where it cannot run on a discrete GPU on hybrid systems. (For example, laptops with both integrated graphics and a dedicated gpu) This is an issue when you're making a program in WPF or a game engine.

A workaround is to run the app in integrated graphics mode.

  • https://learn.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/error-when-dda-capable-app-is-against-gpu
  • https://www.freemancw.com/2020/11/desktop-duplication-on-hybrid-graphics-systems/
  • https://stackoverflow.com/questions/40221187/directx11-desktop-duplication-not-working-with-nvidia

Figuring this out was quite painful. In my case, I had the preferred device set to the discrete gpu on my nvidia 3d graphics control panel. (So it forced the discrete gpu on everything) I then switched it to automatic, and sure enough, screenCapture.RegisterCaptureZone didn't crash. (The second example in the readme was used)

During this whole thing I've also tried the Windows.Graphics.Capture API and it appears to work without issues; But is annoying to get working on something like WPF.

It would be nice if a remark was added to the readme or somewhere else so that other people in the future don't have to go through the same rabbit hole as I did. DX9 worked fine when I tested it, It's the DX11 provider that is affected by this.

follyfoxe avatar Nov 01 '24 17:11 follyfoxe

Hey, that sounds like a really weird limitation, but it seems like there is not really much to get around it :( I wasn't aware of that. Thanks for reporting, I've added a note to the readme.

DarthAffe avatar Nov 03 '24 14:11 DarthAffe

System.NullReferenceException: Object reference not set to an instance of an object. at Vortice.Direct3D11.ID3D11Device.CreateTexture2D(Texture2DDescription desc, Void* initialData) at Vortice.Direct3D11.ID3D11Device.CreateTexture2D(Texture2DDescription& description) at ScreenCapture.NET.DX11ScreenCapture.InitializeCaptureZone(CaptureZone`1 captureZone) at ScreenCapture.NET.DX11ScreenCapture.RegisterCaptureZone(Int32 x, Int32 y, Int32 width, Int32 height, Int32 downscaleLevel)

yitianlige avatar Apr 26 '25 02:04 yitianlige

    public IMGTOOL(Rectangle captureRegion)
    {
        screenCaptureService = new DX11ScreenCaptureService();
        graphicsCards = screenCaptureService.GetGraphicsCards();
        displays = screenCaptureService.GetDisplays(graphicsCards.First());
        screenCapture = screenCaptureService.GetScreenCapture(displays.First());
        fullscreen = screenCapture.RegisterCaptureZone(captureRegion.X, captureRegion.Y, captureRegion.Width, captureRegion.Height);
    }

yitianlige avatar Apr 26 '25 02:04 yitianlige