Как устранить неполадки OpenGL в Ubuntu под Windows 10 (WSL)

Как устранить неполадки OpenGL в Ubuntu под Windows 10 (WSL)

Я установил Ubuntu на Windows 10 с помощью подсистемы Windows для Linux (WSL). Я пытаюсь заставить работать графику OpenGL. Моя конечная цель — запустить симулятор Gazebo для Robot OS (ROS), который требует OpenGL. В качестве первого шага я пытаюсь убедиться, что графика OpenGL работает так, как должна.

В соответствии сэтот уроки многих других, для запуска ROS и Gazebo мне нужно установить VcXsrv и запустить X-сервер с отключенной опцией «Native OpenGL», что я и делаю.

Моя непосредственная проблема в том, что OpenGL, похоже, работает не совсем правильно. Я установил утилиты Mesa, и когда я запускаю, glxgearsя вижу графическое окно, но анимация очень медленная. Я бы оценил, что шестерни вращаются со скоростью около 1 оборота в минуту. Я могу переориентировать шестерни с помощью клавиш со стрелками, но, опять же, обновление происходит очень медленно. (Время от времени наблюдается видимый «скачок», если это имеет значение.)

Для сравнения я попробовал запустить glxgearsUbuntu на машине VirtualBox. К моему удивлению, анимация происходит гораздо быстрее; шестеренки совершают полный оборот примерно каждые 4 секунды, по сравнению с одним оборотом каждые (может быть, 60 секунд, но я потерял терпение) при запуске под Windows с WSL. Это большой сюрприз, так как я ожидал, что VirtualBox будет намного медленнее.

На Windows с WSL glxgearsутверждается, что работает очень быстро — от 800 до 1700 FPS. В VirtualBox glxgearsсообщается о 900-1000FPS.

Информация о версии glxgears и OpenGL:

xxxx@DESKTOP-8U2MCOG:~$ glxgears -info
GL_RENDERER   = Software Rasterizer
GL_VERSION    = 1.4 (2.1 Mesa 19.2.0-devel (git-cdf42f5eaa))
GL_VENDOR     = Mesa Project
GL_EXTENSIONS = GL_ARB_depth_texture GL_ARB_fragment_program GL_ARB_fragment_program_shadow GL_ARB_occlusion_query GL_ARB_texture_env_dot3 GL_ARB_transpose_matrix GL_EXT_draw_range_elements GL_EXT_multi_draw_arrays GL_NV_depth_clamp GL_NV_fog_distance GL_NV_point_sprite GL_SUN_multi_draw_arrays
VisualID 183, 0xb7
20311 frames in 5.0 seconds = 4062.197 FPS

Почему glxgearsWSL работает так медленно? Если он должен работать быстрее, то как мне это сделать?

ОБНОВЛЯТЬ

На основании ответа от @allquixotic ниже я сделал еще одну попытку запустить с опцией wgl, которую я сделал, оставив второй флажок "Native opengl" отмеченным. Я пробовал это раньше, но оказалось, что мне нужно было сделать этопосле перезагрузкичтобы это вступило в силу. Когда я запускаю glxgearsэту настройку, я получаю немного другой вывод на консоли:

xxxx@DESKTOP-8U2MCOG:~$ glxgears
Running synchronized to the vertical refresh.  The framerate should be
approximately the same as the monitor refresh rate.
23633 frames in 7.5 seconds = 3147.913 FPS
10395 frames in 6.8 seconds = 1529.523 FPS
10395 frames in 6.9 seconds = 1512.829 FPS

Теперь я почти уверен, что мой монитор не работает с вертикальной частотой развертки 1500 Гц! Так что я думаю, что это может быть показателем того, что на самом деле происходит; какая-то странность с системой косвенного рендеринга. Также я заметил, что когда я нажимаю CTRL+C, чтобы завершить программу, окно GL продолжает работать и анимироваться в течение добрых 10-11 секунд после того, как я завершил программу — и это если я запустил программу всего на 3-4 секунды. Так что я должен предположить, что в очереди находится куча сообщений или что-то в этом роде...?

решение1

Что на самом деле сработало:

По непонятным мне причинам моя система сработала, когда я пошел против (весьма разумной) рекомендации @allquixotic.

1. Отключить LIBGL_ALWAYS_INDIRECT:

Это оказалось действительно сложным, просто потому, что мне нужно было найти, где это происходит:

  • В папке /etc/profile.dбыл файл wsl-integration.sh.
  • Приведенный выше файл на самом деле был символической ссылкой; фактический файл был/usr/share/wslu/wsl-integration.sh
  • В этом файле была задана переменная LIBGL_ALWAYS_INDIRECT, поэтому я закомментировал эту строку.

2. Делатьнетиспользуйте -wglаргумент командной строки (или его эквивалент в графическом интерфейсе) для VcXsrv:

Поскольку я запускал VcXsrv из графического клиента, это означало, что мне пришлось оставить второй флажок под названием «Native OpenGL» неотмеченным.

Только после того, как я внес оба эти изменения (и выполнил новую перезагрузку, чтобы убедиться, что старые настройки VcXsrv не сохранились), шестеренки glxgearsначали вращаться с нормальной скоростью, и я смог переориентировать их с помощью клавиш со стрелками, как и должно быть.

решение2

На самом деле пытаюсь решить вашу проблему

  1. Прежде чем запускать программы Robot OS, требующие аппаратного ускорения, например glxgears, запустите export LIBGL_ALWAYS_INDIRECT=1.
  2. При запуске VcXsrv (или любого X-сервера в Windows) передайте -wglаргумент командной строки серверу в качестве аргумента командной строки.
  3. Если это не сработает, попробуйте использовать платную версию Xming вместо VcXsrv.
  4. Если это все еще не сработало, вам не повезло. Читайте ниже, чтобы узнать, почему.

Объяснение того, что находится под капотом

В гостевой ОС Windows Subsystem for Linux (WSL) или Hyper-V аппаратное ускорение OpenGL возможно только черезкосвенная визуализация.

GLX — это расширение протокола для клиент-серверного протокола X11. Клиент-серверный протокол X11 — это сетевой протокол, используемый для связи междуклиенты(программы, создающие X-окна) исерверы(программы, которые отображают эти окна на экране, физическом или виртуальном).

Нарабочий столLinux, GLX — это стандартный механизм доступа к OpenGL. Из клиентской программы это в основном двухэтапный процесс: (1) общение с GLX, затем (2) общение с OpenGL. Второй шаг зависит от того, используете ли вы косвенный или прямой рендеринг (т. е. косвенный или прямой GLX).

  • Косвенная визуализация:

    • Поддерживает только OpenGL до версии 1.4 (без GLSL и т.п.)
    • LIBGL_ALWAYS_INDIRECT=1Для использования большинству программ требуется переменная окружения , в противном случае по умолчанию используется прямой рендеринг.
    • Отправляет все команды OpenGL на X-сервер с помощью GLXпротокол.
    • Бэкэнд X-сервера использует локальную реализацию OpenGL для завершения рендеринга в окне.
    • Является сетевым прозрачным, то есть работает как через сетевые соединения и сокеты домена UNIX, так и локально.
  • Прямой рендеринг:

    • Поддерживает любую версию OpenGL, поддерживаемую графическим драйвером, вплоть до OpenGL 4.x или выше, если OpenGL когда-либо выпустит новую версию.
    • Требует, чтобы переменная окружения LIBGL_ALWAYS_INDIRECTбылане установлен.
    • Отправляет все команды OpenGL с помощью динамической загрузки в доступные символы libGL.so(с соответствующей версией на конце, например, libGL.so.1 и т. д.) — это собственные вызовы функций.
    • X-сервер напрямую не «видит» команды рендеринга OpenGL. Все, что он видит, — это прямоугольная область, которую он выделяет в буфере кадра для графического драйвера, чтобы он рендерил ее. Он не знаетчтоотображается толькогде.
    • Не является сетевым, то есть работает только локально на одном компьютере.

Тамявляетсяреализация OpenGL, которая поддерживает прямой рендеринг GLX, но — без ведома X-сервера — передает вызовы OpenGL по сети на аппаратно-ускоренный удаленный компьютер. Этот продукт называется VirtualGL. Но VirtualGL не имеет компонента сервера Windows, поэтому нет возможности использовать VirtualGL с хостом Windows. Если вы используете хост Linux и гостевую Linux в виртуализации, вы можете использовать VirtualGL из гостя в хост, чтобы получить прямой рендеринг в госте с использованием видеокарты хоста.

Я не знаю, что такое "Robot OS", но если для нее требуются только команды OpenGL версии 1.4 или старше, то она должна работать, если вы запустите X-сервер на своем хосте Windows с помощью этой -wglкоманды. X-сервер должен поддерживать этот флаг. Я сам никогда не заставлял его работать с VcXsrv, но я знаю, что платная версия Xming работает.

Есть несколько X-серверов, работающих на Windows. Я протестировал большинство из них, за исключением действительно дорогих коммерческих реализаций. По моему мнению, лучшей для OpenGL является платная версия Xming. Бесплатная версия довольно устарела и не так хороша.

Однако не существует...не могусуществует -- реализация сервера Windows X, которая будет поддерживать более чем OpenGL 1.4 в режиме косвенного рендеринга (из клиента WSL или Hyper-V), поскольку GLXсам протоколне определяет вызовы OpenGL выше версии 1.4.

Итак, если Robot OS требует больше, чем OpenGL 1.4, естьникоим образомчтобы запустить его в WSL или Hyper-V и получить аппаратно ускоренный рендеринг на сервере Windows X. Вам придется использовать что-то вроде VMware Workstation.

решение3

Столкнулся с той же проблемой и выяснил, что glxgears, скорее всего, просто перегружает VcXsrv запросами на отрисовку так быстро, что тот не успевает ничего отрисовать.

Подробности и модифицированная версия glxgears с возможностью ограничения частоты кадров здесь:

https://github.com/tobecodex/glxgears

Используя эту версию, я могу легко получить > 800 кадров в секунду для передач на Surface Book 2.

Я предполагаю, что отсутствие настоящей скорости VSYNC на современных дисплеях заставляет glxgears спамить сервер так быстро, как только может, что убивает VcXsrv.

Я заметил, что MeshLab и подобные приложения работают нормально, а у Xming такой проблемы нет (хотя у него также нет аппаратного ускорения).

Так что в ответ на ваш вопрос: не беспокойтесь об этом. Gazebo, скорее всего, будет работать нормально. Проблема существует только для glxgears и, возможно, приложений похожего возраста.

Кстати, я обнаружил, что: export LIBGL_ALWAYS_INDIRECTи -wglв любой комбинации не оказывают на меня большого эффекта. Возможно, стоит поиграть с ними снова, поскольку результаты почти наверняка будут отличаться от тех, что вы видели для glxgears.

Связанный контент