OpenGL traditionally requires a window. Without a window, OpenGL cannot be used. This implies either X11 or Wayland is installed and running; which can be a problem when running on cloud servers, VMs, embedded devices, and similar environments.
Direct3D11 doesn’t have this flaw, but it does not run on Linux.
Vulkan also doesn’t have this flaw, but its support is new (coming in Ogre 2.3) and is not yet robust and tested enough. Additionally SW implementations have yet to catch up.
Ogre can use the NULL RenderSystem to run as a server without a window, however this doesn’t actually render anything. It’s only useful to pretend there is a screen so that apps (mostly games) can reuse and turn client code into server code. It’s also useful for mesh manipulation and conversion tools which need to read Ogre meshes but don’t actually render anything.
Fortunately, Khronos introduced a workaround with EGL + PBuffers (not to be confused with 2000-era PBuffers which competed against FBOs) where an offscreen dummy ‘window’ could be created to satisfy OpenGL’s shenanigans.
Because PBuffer support in some EGL drivers are not well tested (e.g. sRGB support was only added in EGL 1.5, which Mesa does not support) Ogre creates a 1×1 PBuffer alongside the Context and uses an FBO internally for the ‘Window’ class. By using a dummy 1×1 PBuffer tied with the GL context, OpenGL context creation becomes conceptually free of window interfaces, like in D3D11 and Vulkan.
Switchable interfaces: GLX and EGL
When Ogre is built with both OGRE_GLSUPPORT_USE_GLX and OGRE_GLSUPPORT_USE_EGL_HEADLESS, toggling between GLX and EGL can be done at runtime.
This is how it looks:
Originally the GLX interface will be selected:
But after switching it to EGL Headless, only a couple options appear (since stuff like Resolution, VSync, Full Screen no longer make sense)
And like in D3D11/Vulkan, it is possible to select the GPU. /dev/dri/card0 is a dedicated AMD Radeon HD 7770 GPU, /dev/dri/card1 is a dedicated NVIDIA GeForce 1060. Yes, they can coexist:
NVIDIA seems to expose 2 “devices” belonging to the same card. ‘EGL_NV_device_cuda … #0’ is a headless device. Trying to use ‘EGL_EXT_device_drm #1’ will complain that it can’t run in headless mode. It seems it is meant for use with GLX.
‘EGL_EXT_device_drm #2’ is the AMD card.
EGL_MESA_device_software is SW emulation
We chose not to include the marketing names in device selection because Linux drivers (propietary and open source) have the tendency of changing the exposed OpenGL marketing labels quite often in subtle ways. This could break config settings quite often (i.e. the saved chosen device can no longer be found after a driver upgrade), increasing maintenance burden when this feature is meant for automated testing and similar.
Complete X11 independence
Users who need to be completely free of X11 dependencies can build with OGRE_GLSUPPORT_USE_EGL_HEADLESS + OGRE_CONFIG_UNIX_NO_X11.
This will force-disable OGRE_GLSUPPORT_USE_GLX as it is incompatible. GLX requires X11.
Headless SW Rasterization
It is possible to select the Mesa SW rasterization device. So even if there is no HW support, you can still use SW.
Please note Mesa SW at the time of writing supports up to OpenGL 3.3, which is the bare minimum to run Ogre. Some functionality may not be available.
Update: It has been called to my attention that llvmpipe (aka SW emulation) supports OpenGL 4.5 since Mesa 20.3.0
This new feature seems to be very stable and has been tested on NVIDIA, AMD (Mesa drivers) and Intel. Nonetheless it is disabled by default (i.e. OGRE_GLSUPPORT_USE_EGL_HEADLESS is turned off) which means it should not affect users who are not caring about headless support.
For more details, please see the README of the EglHeadless tutorial.
Running EglHeadless sample should result in a CLI interface:
OpenGL ES 3.x may be around the corner?
With EGL integration, it should be possible to create an EGL window and ask for an ES 3.x context instead of an OpenGL one. There is a lot of similarities between ES 3 and OpenGL 3.3, and we already have workarounds for it as they’re the same ones we use for macOS.
While I don’t have very high hopes for Android, WebGL2 may be another story.
If such feature is added into the roadmap, it would probably be for 2.3 though.
Functions RenderSystem::startGpuDebuggerFrameCapture and RenderSystem::endGpuDebuggerFrameCapture were added to programmatically capture a RenderDoc frame. This was necessary for RenderDoc to work with headless rendering, but it works with all APIs in most platforms.
Users can call RenderSystem::getRenderDocApi if they wish to perform more advanced manipulation:
This work was possible because user Hotshot5000 took my branch, forked it, and advanced it further. The Vulkan port was a daunting, overwhelming task and his contributions greatly helped me figure out the way to make it work.
It also saved me a lot of time. Even though around 40% of his code couldn’t make it into the final version, it was still very important as a proof of concept or as a reference implementation to base from, or as a way to compare new non-working code against a working reference.
Existing applications may need to perform additional work to get Vulkan running (e.g. port shaders to Vulkan). While this isn’t difficult, there is no guide written yet.
The 2.3 preparations ticket has a list of things that have changed that may require a dev’s attention when porting from 2.2 to 2.3
This list is updated at irregular intervals; and once 2.3 is out this page is probably going to be moved somewhere else (in fact it is a draft for the News post whenever we release 2.3). But for the time being that ticket is our hub for checking 2.2 -> 2.3 changes.