Como solucionar problemas de OpenGL no Ubuntu no Windows 10 (WSL)

Como solucionar problemas de OpenGL no Ubuntu no Windows 10 (WSL)

Instalei o Ubuntu no Windows 10 usando o Windows Subsystem for Linux (WSL). Estou tentando fazer com que os gráficos OpenGL funcionem. Meu objetivo final é poder rodar o simulador Gazebo para Robot OS (ROS), que requer OpenGL. Como primeiro passo, estou tentando garantir que os gráficos OpenGL estejam funcionando como deveriam.

De acordo comeste tutoriale muitos outros, para rodar ROS e Gazebo eu deveria instalar o VcXsrv e rodar o servidor X com a opção "Native OpenGL" desabilitada, então estou fazendo isso.

Meu problema imediato é que o OpenGL não parece estar funcionando bem. Instalei os utilitários Mesa e quando executo glxgearsvejo a janela gráfica, mas a animação é extremamente lenta. Eu estimaria que as engrenagens giram a cerca de 1 revolução por minuto. Posso reorientar as engrenagens usando as teclas de seta, mas novamente a atualização é extremamente lenta. (De vez em quando há um “salto” visível, se isso importa.)

Para efeito de comparação, tentei rodar glxgearsno Ubuntu rodando em uma máquina VirtualBox. Para minha surpresa, a animação é muito mais rápida; as engrenagens fazem uma rotação completa cerca de uma vez a cada 4 segundos, em comparação com uma vez a cada (talvez 60 segundos, mas perdi a paciência) ao executar no Windows com WSL. Esta é uma grande surpresa, pois espero que o VirtualBox seja muito mais lento.

No Windows com WSL, glxgearsafirma que está rodando muito rápido – entre 800 e 1700 FPS. No VirtualBox glxgearsrelata cerca de 900-1000FPS.

Informações de versão em glxgears e 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

Por que o WSL está glxgearstão lento? Se ele for capaz de rodar mais rápido, então como faço para que isso aconteça?

ATUALIZAR

Com base na resposta de @allquixotic abaixo, fiz outra tentativa de executar a wglopção, o que fiz deixando a segunda caixa de seleção "Native opengl" marcada. Eu já havia tentado isso antes, mas descobri que precisava fazer issodepois de uma reinicializaçãopara que entre em vigor. Quando executo glxgearsesta configuração, recebo uma leitura ligeiramente diferente no console:

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

Agora tenho quase certeza de que meu monitor não funciona a uma taxa de varredura vertical de 1500 Hz! Então acho que isso pode ser um indicador do que realmente está acontecendo; alguma estranheza com o sistema de renderização indireta. Também noto que quando eu CTRL+C para finalizar o programa, a janela GL continua rodando e animando por uns bons 10-11 segundos depois de encerrar o programa - e isso se eu tiver executado o programa apenas por 3- 4 segundos. Então eu teria que adivinhar que há uma tonelada de mensagens na fila, ou algo assim...?

Responder1

O que realmente acabou funcionando:

Por motivos que não entendo, meu sistema funcionou quando contrariei a recomendação (bastante sensata) de @allquixotic.

1. Desative LIBGL_ALWAYS_INDIRECT:

Isso acabou sendo muito difícil, simplesmente porque tive que descobrir onde estava definido:

  • Na pasta /etc/profile.dhavia um arquivo wsl-integration.sh.
  • O arquivo acima era na verdade um link simbólico; o arquivo real era/usr/share/wslu/wsl-integration.sh
  • Nesse arquivo a variável LIBGL_ALWAYS_INDIRECTfoi definida, então comentei essa linha.

faça 2nãouse o -wglargumento de linha de comando (ou seu equivalente GUI) para VcXsrv:

Como eu estava iniciando o VcXsrv a partir de um cliente GUI, isso significava deixar a segunda caixa de opção, intitulada "Native OpenGL", desmarcada.

Somente depois que eu fiz essas duas alterações (e fiz uma nova reinicialização para garantir que nenhuma configuração antiga do VcXsrv persistisse), as engrenagens glxgearsestavam girando em uma taxa normal e eu pude reorientá-las usando as teclas de seta, assim como elas ' deveria funcionar.

Responder2

Na verdade tentando resolver seu problema

  1. Antes de executar programas do Robot OS que precisam ser acelerados por hardware, como glxgears, execute export LIBGL_ALWAYS_INDIRECT=1.
  2. Ao iniciar o VcXsrv (ou qualquer servidor X no Windows), passe o -wglargumento da linha de comando para o servidor como um argumento de linha de comando.
  3. Se isso não funcionar, tente usar a versão paga do Xming em vez do VcXsrv.
  4. Se isso ainda não funcionar, você está sem sorte. leia abaixo para ver o porquê.

Explicação sob o capô

Dentro de um subsistema Windows para Linux (WSL) ou convidado Hyper-V, OpenGL acelerado por hardware só é possível por meio derenderização indireta.

GLX é uma extensão de protocolo para o protocolo cliente-servidor X11. O protocolo cliente-servidor X11 é o protocolo de rede usado para comunicação entreclientes(programas que criam janelas X) eservidores(programas que renderizam essas janelas em uma tela, seja física ou virtual).

SobreÁrea de TrabalhoLinux, GLX é o mecanismo padrão para acessar OpenGL. Em um programa cliente, é basicamente um processo de duas etapas: (1) falar com o GLX e (2) falar com o OpenGL. A segunda etapa varia dependendo se você está usando renderização indireta ou direta (ou seja, GLX indireto ou direto).

  • Renderização indireta:

    • Suporta apenas até OpenGL versão 1.4 (sem GLSL, etc.)
    • Requer a variável de ambiente LIBGL_ALWAYS_INDIRECT=1para a maioria dos programas usá-la, caso contrário, o padrão é a renderização direta.
    • Envia todos os comandos OpenGL para o servidor X usando o GLXprotocolo.
    • O backend do servidor X usa a implementação OpenGL local para o servidor X para completar a renderização na janela.
    • É transparente para a rede, o que significa que funciona em conexões de rede e soquetes de domínio UNIX, bem como localmente.
  • Renderização direta:

    • Suporta qualquer versão de OpenGL suportada pelo driver gráfico, que pode ser até OpenGL 4.x ou superior se o OpenGL lançar uma nova versão.
    • Requer que a variável de ambiente LIBGL_ALWAYS_INDIRECTsejadesarmar.
    • Envia todos os comandos OpenGL usando carregamento dinâmico para os símbolos disponíveis libGL.so(com a versão apropriada no final, como libGL.so.1, etc.) - estas são chamadas de funções nativas.
    • O servidor X não "vê" diretamente os comandos de renderização do OpenGL. Tudo o que ele vê é uma região retangular que ele reserva no buffer de quadros para o driver gráfico renderizar. Não sabeo queé renderizado, apenasonde.
    • Não é transparente para a rede, o que significa que só funciona localmente no mesmo computador.

éuma implementação de OpenGL que suporta renderização direta GLX, mas - sem o conhecimento do servidor X - canaliza as chamadas OpenGL pela rede para um controle remoto acelerado por hardware. Este produto é denominado VirtualGL. Mas o VirtualGL não possui um componente de servidor Windows, portanto não há como usar o VirtualGL com um host Windows. Se você estivesse executando um host Linux e um convidado Linux na virtualização, poderia usar o VirtualGL do convidado para o host para obter renderização direta no convidado usando a placa gráfica do host.

Não sei o que é "Robot OS", mas se requer apenas comandos OpenGL da versão 1.4 ou anterior, deve funcionar se você executar um servidor X em seu host Windows usando o -wglcomando. O servidor X precisa suportar este sinalizador. Eu nunca fiz funcionar com o VcXsrv, mas sei que a versão paga do Xming funciona.

Existem vários servidores X que rodam no Windows. Testei a maioria deles, exceto as implementações comerciais realmente caras. Na minha opinião, o melhor para OpenGL é a versão paga do Xming. A versão gratuita está bastante desatualizada e não tão boa.

No entanto, não existe -não podeexiste - uma implementação de um servidor Windows X que suportará mais do que OpenGL 1.4 no modo de renderização indireta (de um cliente WSL ou Hyper-V) porque o GLXprotocolo em sinão especifica chamadas OpenGL acima da versão 1.4.

Portanto, se o Robot OS exigir mais do que OpenGL 1.4, háde jeito nenhumpara executá-lo em WSL ou Hyper-V e obter renderização acelerada por hardware em um servidor Windows X. Você teria que usar algo como VMware Workstation.

Responder3

Encontrei o mesmo problema e descobri que o glxgears provavelmente está sobrecarregando o VcXsrv com solicitações de desenho tão rápidas que nunca consegue renderizar nada.

Detalhes e uma versão modificada do glxgears com uma opção de limitação de taxa de quadros aqui:

https://github.com/tobecodex/glxgears

Usando esta versão, posso obter facilmente> 800 fps para engrenagens em um Surface Book 2.

Suponho que a falta de uma taxa VSYNC verdadeira em monitores modernos faz com que o glxgears envie spam para o servidor o mais rápido possível, o que mata o VcXsrv.

Percebi que o MeshLab e similares funcionaram bem e que o Xming não tem esse problema (também não tem aceleração de HW).

Então, em resposta à sua pergunta: não se preocupe com isso. O Gazebo provavelmente funcionará bem. O problema existe apenas para glxgears e provavelmente aplicativos de safra semelhante.

Aliás, descobri que: export LIBGL_ALWAYS_INDIRECTe -wglem qualquer combinação têm pouco efeito para mim. Pode valer a pena brincar com eles novamente, pois os resultados quase certamente serão diferentes daqueles que você viu no glxgears.

informação relacionada