Ogre 2.2.5 Cerberus Released and EGL Headless support!

This is a special release! Most Ogre 2.1.x and 2.2.x releases, it only contains maintenance fixes and no new features.

Thus efforts to port from 2.2.4 to 2.2.5 should be minimum. And this still holds true.

But there is a new feature!

This feature was sponsored by Open Source Robotics Corporation and was written to be used by the Ignition Project

EGL Headless

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

More info

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.

RenderDoc integration

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:

if( rs->loadRenderDocApi() )
    RENDERDOC_API_1_4_1 *apiHandle = rs->getRenderDocApi();

About the 2.2.5 release

For a full list of changes see the Github release

Source and SDK is in the download page.

Discussion in forum thread.

Thanks again to Open Source Robotics Corporation for sponsoring this feature for their Ignition Project

Ogre 2.2.2 Cerberus Released!

This is a maintenance release. Efforts to port from 2.2.1 to 2.2.2 should be minimum.

Notable additions are:

  • Stable PSSM shadows technique added. Use this feature with ‘num_stable_splits 1’ in compositor scripts when defining the shadow node. Stable PSSM shadows tend to improve quality on the first splits, but they can dramatically reduce quality on the last splits of PSSM; thus using num_stable_splits 1 or 2 but not higher than that is recommended
  • D3D11 improved its handling of device lost
  • It is now possible to draw to a cubemap using MSAA, which was an oversight in Ogre 2.2.1. See the updated DynamicCubemap tutorial

For a full list see the Github release

Discussion in forum thread.