Use recent version of OpenGL on older machines (using soft pipeline)
Jonathan Fabrizio - 13/11/20
It is sometime necessary to develop/to run OpenGL program that
requires a recent version of OpenGL on an older machine, with a GPU
(or a video driver) that does not support recent enough version of
OpenGL. A solution is to use a software graphical pipeline. The OpenGL
instructions are then executed by the CPU. The performances are
certainly not as efficient as with hardware accelerated pipeline (on
the GPU), but it allows at least to use older hardware. The solution
we propose here has the advantage that the current configuration is
not modified. There is no risk for the configuration.
Il est parfois nécessaire, de développer/exécuter des programmes
OpenGL qui nécessite une version d'OpenGL plus récente que celle
supportée par le GPU (ou le driver video) de la machine utilisée. Une
solution est d'utiliser un pipeline graphique software. Dans ce
cas, les instructions d'OpenGL sont exécutées sur le CPU. Les
performances ne sont certainement pas comparables aux performances
obtenues avec une accélération graphique, mais dans beaucoup de cas,
cela permet au moins de faire des tests sur du matériel plus ancien.
L'avantage de la solution que l'on propose ici est que l'on ne modifie
pas la configuration de la machine. Il n'y a donc aucun risque.
Introduction
Pour utiliser des programmes récents d'OpenGL, il est souvent nécessaire d'avoir une version d'OpenGL suppérieur à 4.0. On peut à ce moment utiliser les derniers types de shaders (tesselation shaders...).
On va prendre pour exemple une machine qui a plus de 10 ans mais qui fonctionne pourtant très correctement. Cette machine est munie un intel i7 930 et une Radeon HD4850 sur laquelle une ubuntu 20.04 est installée.
To use program that relies on advanced Opengl it is necessary to have video drivers that manage OpenGL higher than 4.0. In this case, we can use last type of shaders such as tesselation shaders...
We take here the example of an 10 years old machine but still efficient. This computer has intel i7 930 CPU and a Radeon HD4850 video card with ubuntu 20.04.
jo@imagine:~$ cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 26 model name : Intel(R) Core(TM) i7 CPU 930 @ 2.80GHz stepping : 5 microcode : 0x1d cpu MHz : 1616.273 cache size : 8192 KB physical id : 0 siblings : 8 core id : 0 cpu cores : 4 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 11 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 popcnt lahf_lm pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid dtherm ida flush_l1d bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit bogomips : 5612.82 clflush size : 64 cache_alignment : 64 address sizes : 36 bits physical, 48 bits virtual power management: (...)
jo@imagine:~$ lspci ... 03:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] RV770 [Radeon HD 4850] ...
jo@imagine:~$ glxinfo | grep -i opengl OpenGL vendor string: X.Org OpenGL renderer string: AMD RV770 (DRM 2.50.0 / 5.4.0-52-generic, LLVM 10.0.0) OpenGL core profile version string: 3.3 (Core Profile) Mesa 20.0.8 OpenGL core profile shading language version string: 3.30 OpenGL core profile context flags: (none) OpenGL core profile profile mask: core profile OpenGL core profile extensions: OpenGL version string: 3.0 Mesa 20.0.8 OpenGL shading language version string: 1.30 OpenGL context flags: (none) OpenGL extensions: OpenGL ES profile version string: OpenGL ES 3.0 Mesa 20.0.8 OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.00 OpenGL ES profile extensions:
Ce qui est important de voir, c'est que c'est Mesa 20.0.8 qui est utilisé et il assure la version 3.3 d'OpenGL (core). On ne peut donc pas utiliser les fonctionnalités récentes d'OpenGL
Here we see Mesa 20.0.8 is used and it provides OpenGL 3.3 (core). We then can not use recent advanced OpenGL features
Activate software pipeline
On va remplacer ce driver par un driver qui s'execute entierement sur le CPU. On a plus ou moins le choix. Il y a (entre autre SWR ou llvmpipe). SWR nécessite que le CPU supporte au moins les instructions AVX, ce qui n'est pas le cas du i7 930. Du coup nous allons utiliser llvmpipe (associé à MESA).
We will subs this driver by a driver that relies completly on the CPU. You have multiple choices. There are (but not limited to) SWR or llvmpipe. SWR need AVX instructions, but our i7 930 does not support them. Then we will use llvmpipe (related to MESA).
On peut forcer l'utilisation du pipeline software par :
We can oblige the usage of the software pipeline by:
jo@imagine:~$ export LIBGL_ALWAYS_SOFTWARE=1 jo@imagine:~$ glxinfo | grep -i opengl OpenGL vendor string: VMware, Inc. OpenGL renderer string: llvmpipe (LLVM 10.0.0, 128 bits) OpenGL core profile version string: 3.3 (Core Profile) Mesa 20.0.8 OpenGL core profile shading language version string: 3.30 OpenGL core profile context flags: (none) OpenGL core profile profile mask: core profile OpenGL core profile extensions: OpenGL version string: 3.1 Mesa 20.0.8 OpenGL shading language version string: 1.40 OpenGL context flags: (none) OpenGL extensions: OpenGL ES profile version string: OpenGL ES 3.1 Mesa 20.0.8 OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10 OpenGL ES profile extensions:
On est bien passé sur un rendu software grace à llvmpipe mais on est resté sur une version d'OpenGL trop ancienne (3.3 core).
The software pipeline is well activated and the current driver is now llvmpipe however the supported OpenGL version is still to old (3.3 core).
Note : Vous pouvez essayer de changer de driver :
Note : Vous can easily change the used driver:
jo@imagine:~$ export GALLIUM_DRIVER=swrast jo@imagine:~$ export GALLIUM_DRIVER=llvmpipe ...
Le problème, c'est que la version de MESA associée à la distribution installée, ubuntu 20.04, n'est pas suffisamment récente donc on va devoir compiler la notre pour avoir la toute dernière version de llvmpipe.
Our problem here is that the Mesa version, with our current ubuntu distribution (20.04) is too old. We then will get the latest version of Mesa and compile llvmpipe by ourselves.
Compilation
Dans un premier temps, nous allons récupérer la derniere verion de MESA.
First, we get Mesa source code.
jo@imagine:~/(...)$ git clone https://gitlab.freedesktop.org/mesa/mesa.git
puis nous allons compiler llvmpipe.
secondly we compile llvmpipe.
Pour cela il faut d'abord etre certain d'avoir toutes les dépenaces notamment llvm et meson (E.T. téléphone meson) mais pas que (je liste pas tout, il vous reste du travail...).
To be able to compile llvmpipe we need to solve numerous dependencies: obviously llvm and meson but also many other (that I do not list here, it remains a little work for you...).
Ensuite on va configurer le projet, le compiler et l'installer
then we configure, compile and install the project
jo@imagine:~/(...)$ mkdir build jo@imagine:~/(...)$ cd build jo@imagine:~/(...)$ meson --buildtype=release -Dglx=gallium-xlib ;\ -Dvulkan-drivers= -Ddri-drivers= -Dgallium-drivers=swrast ;\ -Dprefix=/home/jo/.local/lib/x86_64-linux-gnu/ .. jo@imagine:~/(...)$ ninja jo@imagine:~/(...)$ meson install
Pour prefix, vous pouvez mettre le chemin qui vous arrange.
For the prefix, you can set whatever you want.
Usage
On doit dire que l'on veut utiliser le pipeline software :
We must say that we want the software pipeline:
jo@imagine:~/(...)$ export LIBGL_ALWAYS_SOFTWARE=1
Il n'est pas nécessaire de dire que l'on veut le driver llvmpipe, il sera pris par défaut maisvous pouvez le préciser :
It is not necessary to specify llvmpipe driver as it is the one by default but you can:
jo@imagine:~/(...)$ export GALLIUM_DRIVER=llvmpipe
En revanche, il faut pointer vers nos biblithèques fraichement compilées :
However, you must specify the used libraries:
jo@imagine:~/(...)$ export LD_LIBRARY_PATH=/home/jo/.local/lib/x86_64-linux-gnu/
jo@imagine:~$ glxinfo | grep -i opengl OpenGL vendor string: Mesa/X.org OpenGL renderer string: llvmpipe (LLVM 10.0.0, 128 bits) OpenGL core profile version string: 4.5 (Core Profile) Mesa 21.0.0-devel (git-4d72.. OpenGL core profile shading language version string: 4.50 OpenGL core profile context flags: (none) OpenGL core profile profile mask: core profile OpenGL core profile extensions: OpenGL version string: 3.1 Mesa 21.0.0-devel (git-4d727ee913) OpenGL shading language version string: 1.40 OpenGL context flags: (none) OpenGL extensions: OpenGL ES profile version string: OpenGL ES 3.2 Mesa 21.0.0-devel (git-4d727ee913) OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20 OpenGL ES profile extensions:
Bingo ! Apres différents tests, ça fonctionne bien ! Les tessellation shaders fonctionnent bien et le tout sans toucher à la configuration de la machine !
Bingo! After many tests, it works well! Tessellation shaders work and we do not have modified the current configuration.
Conclusion
La solution n'est finalement pas si compliqué et elle fonctionne plutot bien. En plus, elle ne modifie pas configuration du système donc on n'a pas aucun risques que casser quoi que ce soit. Merci aux équipes qui ont bien travailler et qui continue !
The solution is not so difficult and this solution is more efficient than I initially thought. Moreover, we do not change the configuration of the machine, there is no risk to break the current configuration. Many thanks to all members of the development team and contributors, they have made a great job!
Si vous avez un CPU qui supporte les instructions AVX, vous pourrez essayer et comparer avec SWR.
If your CPU manages AVX instructions you can try and compare with SWR.
Viewed 2559 times