Current state and solutions for OpenGL over Windows Remote

SairesArt picture SairesArt · Aug 6, 2018 · Viewed 32.4k times · Source

OpenGL and Windows Remote don't play along nicely.

Solutions for this are dependent on the use case and answers are fragmented across the vast depths of the net. This is a write-up I wish existed when I started researching this, both for coders and non-coders.

Problem:

A RDP session of Windows does not expose the graphics card, at least not directly. For instance you cannot change the desktop resolution and GraphicsCard drivers usually just disable their setting menus. Starting a OpenGL context higher than v1.1 fails because of this. The, especially in support IRCs, often suggested "Don't use WindowsRemote" is unfortunately not an option for many. In many corporate environments Windows Remote is a constantly used tool and an app has to work there as well.

Non-Coder workarounds

You can start the OpenGL program, allowing it to see the graphics card, create an opengl context and then connect via WindowsRemote. This always works, as Windows remote just transfers the window content. This can be accomplished by:

  • A batch script, that closes the session and starts the program, allowing you to connect to the program already running. (Source)
  • Using VNC or other to remote into the machine, start the program and then switch to Windows Remote. (Simple VNC programm, also with a portable client)

Coder workarounds

(Only for OpenGL ES)Translate OpenGL to DirectX. DirectX works under Windows Remote flawselly and even has a Software rendering fallback built into DX11 if something fails.

  • Use the ANGLE Project to do this at run-time. This is what QT officially suggests you do and how Chrome and Firefox implement WebGL. (Source)

Switch to software rendering as a fall back. Some CAD software like 3dsMax does this for instance:

  • Under SDL2 you can use SDL_CreateSoftwareRenderer (Source)
  • Under GLFW version 3.3 will release OSMesa (Mesa's off screen rendering), in the mean time you can build the Github version with -DGLFW_USE_OSMESA=TRUE, but I personally still struggle to get that running (Source)
  • Directly use Mesa's LLVM pipe for a fast OpenGL implementation. (Source)

Misc:

  • Use OpenGL 1.1: Windows has a built in implementation of OpenGL 1.1 and earlier. Some game engines have a built in fall back to this and thus work under Windows Remote.
  • Apparently there is a middle-ware, that allows for even OpenGL 4 over Windows Remote, but it's part of a bigger package and is a commercial solution. (Source)

Any other solutions or corrections are greatly appreciated.

Answer

quetzalcoatl picture quetzalcoatl · May 4, 2020

According to this article it seems that now RDP handles newer versions of Direct3D and OpenGL on Windows 10 and Windows Server 2016, but by default it is disabled by Group Policy.

I suppose that for performance reasons, using a hardware graphics card is disabled, and RDP uses a software-emulated graphics card driver that provides only some baseline features.

I stumbled upon this problem when trying to run Ultimaker CURA over standard Remote Desktop from a Windows 10 client to a Windows 10 host. Cura shouted "cannot initialize OpenGL 2.0 context". I also noticed that Repetier Host's "preview" window runs terribly slow, and Repetier detects only an OpenGL 1.1 card. Pretty much fits the "only baseline features" description.

By running gpedit.msc then navigating to

Local Computer Policy\Computer Configuration\Administrative Templates\Windows Components\Remote Desktop Services\Remote Desktop Session Host\Remote Session Environment

and changing the value of

Use hardware graphics adapters for all Remote Desktop Services sessions

I was able to successfully run Ultimaker CURA via with no issues, and Repetier-Host now displays OpenGL 4.6, and everything finally runs fast as it should.


Note from genpfault: As usual, this Policy is kept in the HKLM registry group in

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services

Set REG_DWORD:bEnumerateHWBeforeSW to 1 to turn ON using GPUs in RDP.