Jonathan Fabrizio
Visitor

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 2335 times