Skip to content

Commit

Permalink
fix: choose EGL device based on nvidia extension
Browse files Browse the repository at this point in the history
this is useful on headless systems as the default
egl display may need to connect to Wayland or X11.
Explicitly choosing an Nvidia device ensures EGL
can run on systems without a display server if
Nvidia drivers are installed.
  • Loading branch information
DavidPL1 committed Dec 5, 2024
1 parent 7fcd1a1 commit 25ef3ea
Showing 1 changed file with 29 additions and 1 deletion.
30 changes: 29 additions & 1 deletion mujoco_ros/src/offscreen_rendering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

#if RENDER_BACKEND == EGL_BACKEND
#include <EGL/egl.h>
#include <EGL/eglext.h>
#endif

namespace mujoco_ros {
Expand Down Expand Up @@ -183,6 +184,33 @@ void MujocoEnv::initializeRenderResources()
bool MujocoEnv::InitGL()
{
ROS_DEBUG("Initializing EGL...");

EGLDeviceEXT egl_devices[4];
EGLint num_devices;

// Get devices
PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT =
reinterpret_cast<PFNEGLQUERYDEVICESEXTPROC>(eglGetProcAddress("eglQueryDevicesEXT"));
if (eglQueryDevicesEXT(4, egl_devices, &num_devices) != EGL_TRUE) {
ROS_ERROR_STREAM("Failed to query EGL devices. Error type: " << eglGetError());
return false;
}
ROS_DEBUG_STREAM("Found " << num_devices << " EGL devices");

PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT =
reinterpret_cast<PFNEGLQUERYDEVICESTRINGEXTPROC>(eglGetProcAddress("eglQueryDeviceStringEXT"));
const char *extensions;
int choose_device = 0;
for (int i = 0; i < num_devices; i++) {
extensions = eglQueryDeviceStringEXT(egl_devices[i], EGL_EXTENSIONS);
ROS_DEBUG_STREAM("Device " << i << " has extensions: " << extensions);
if (strstr(extensions, "EGL_NV_device_cuda")) {
ROS_DEBUG_STREAM("Choosing device " << i << " for CUDA support");
choose_device = i;
break;
}
}

// clang-format off
const EGLint config[] = {
EGL_RED_SIZE, 8,
Expand All @@ -198,7 +226,7 @@ bool MujocoEnv::InitGL()
// clang-format on

// Get Display
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
EGLDisplay display = eglGetPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, egl_devices[choose_device], nullptr);
if (display == EGL_NO_DISPLAY) {
ROS_ERROR_STREAM("Failed to get EGL display. Error type: " << eglGetError());
return false;
Expand Down

0 comments on commit 25ef3ea

Please sign in to comment.