RADV で最新 Vulkan を使うため, Mesa をコンパイルするメモ

## 背景

最新 RADV(オープンソースの amdgpu 向け Vulkan 実装)を使いたい.

ROCm で RADV で Vulkan(compute kernel) を使うメモ
https://qiita.com/syoyo/items/ce3943757281acbdba49

の続きです.

Mesa 21.3 or later,
Ubuntu 20.04 + AMD GPU(Radeon VII or later)を想定します.

## Meson

mesa は scons(!) などでビルドできるようですが, ナウでヤングな若人さまでしたら meson かと思います.
(Mesa(freedesktop project?)は meson に移行しつつあるようですね)

従いまして meson でビルドします.

Ubuntu apt で入る meson は古くて libdrm, mesa がビルドができないので, meson 最新版(0.51 as of Dec 20th, 2019) を https://github.com/mesonbuild/meson/releases から取得してパスを通しておきます.

## libdrm

mesa の amdgpu(radeon) モジュールが libdrm 2.4.100 を要求します. 現時点(2019/12/20)では apt で入る libdrm は古いので, まずは libdrm 2.4.100 をコンパイルします. このステップはいずれ ubuntu 側で libdrm 2.4.100 にアップデートされたら不要です.

https://dri.freedesktop.org/libdrm/

libdrm のビルドには libpciaccess が必要です.

```
$ sudo apt install libpciaccess-dev
```

```
$ cd $libdrm
$ mkdir build
$ cd build
$ meson ..

...

Message:
Message: libdrm will be compiled with:
Message:
Message:   libkms         true
Message:   Intel API      true
Message:   vmwgfx API     true
Message:   Radeon API     true
Message:   AMDGPU API     true
Message:   Nouveau API    true
Message:   OMAP API       false
Message:   EXYNOS API     false
Message:   Freedreno API  false (kgsl: false)
Message:   Tegra API      false
Message:   VC4 API        false
Message:   Etnaviv API    false
Message:
Build targets in project: 
```

と AMDGPU が true を確認しておきます.

```
$ sudo ninja install
```

`/usr/local/` にインストールされます. 

```
$ pkg-config --libs libdrm
```

で `/usr/local` のほうのライブラリが使われているか確認しましょう.

local にインストールしたい場合は, `meson --prefix /path/to/dir` でインストール先を指定して, `PKG_CONFIG_PATH` に設定すれば後続の mesa ビルドでも見つけてくれると思われます. 

## Mesa build

**ビルドのドキュメントが全く無い**です.

https://www.mesa3d.org/install.html

オフィシャルのドキュメントは全く役に立ちませんし, Linux ビルドについて何も書かれていません. **オフィシャルのドキュメントは無視しましょう.**

まずは依存ライブラリを入れます.

テンプレートから C/C++ コード生成(?)のために python mako を使っていますので, pip あたりで入れます.

```
$ pip install mako
```

他に python 関連で依存があるかもしれませんので適宜 pip install します.

その後, apt でビルドに必要なのを入れます.

llvm は 11 が必要です.
Ubuntu 20.04.03 は現時点では 10 がデフォルトです. meson では `llvm-config` しか見ないようなので,

```
$ sudo update-alternatives --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-11 10
```

としておきます.

X11 関係の依存関係がおおくてつらくてぴえん :cry: :cry: :cry:

```
$ sudo apt install libelf-dev bison byacc flex 
$ sudo apt install libx11-dev libxext-dev libxdamage-dev libxfixes-dev libxcb-glx0-dev libx11-xcb-dev libxcb-dri2-0-dev libxcb-dri3-dev libxcb-present-dev libxshmfence-dev libxxf86vm-dev libxrandr-dev
$ sudo apt install libwayland-dev wayland-protocols libwayland-egl-backend-dev
$ sudo apt install libxcb-shm0-dev libxcb-sync-dev
```

他, 足りないの出てきたら適宜 apt で入れます
(`.gitlab/container/debian/` あたりのビルドスクリプト参照)

Vulkan 使う場合は dri3 必須です.

wayland は頑張れば disable できるかもしれませんが, ドキュメントが無いのでどうすれば設定できるか不明ですので諦めて wayland ありでビルドします.

meson で bootstrap 成功すれば, あとは ninja で普通にビルド通るはずです.

mesa は install すると GL や Vulkan などのヘッダをインストールするため, システムのヘッダファイルを上書きしないように, 適当な local dir にインストールするようにします. `$HOME/local` は適宜変更ください.

```bash
$ mkdir build
$ cd build
$ meson --prefix $HOME/local ..
$ ninja
$ ninja install
```

これで `$HOME/local` にインストールされます.

## 動かす

カーネルモジュールの drm はそのままでいけます. 

`VK_ICD_FILENAMES` 環境変数で, 使う libvulkan を今回ビルドしたものに設定します.

```
$ export VK_ICD_FILENAMES=$HOME/local/share/vulkan/icd.d/radeon_icd.x86_64.json
```

あとは普通に vulkan アプリを動かします. vulkaninfo してみます


```
$ vulkaninfo

GPU0
VkPhysicalDeviceProperties:
===========================
        apiVersion     = 0x40106b  (1.1.107)
        driverVersion  = 79704065 (0x4c03001)
        vendorID       = 0x1002
        deviceID       = 0x66af
        deviceType     = DISCRETE_GPU
        deviceName     = AMD RADV VEGA20 (LLVM 8.0.1)

...

       VK_KHR_shader_float16_int8          : extension revision  1

...
```

Super cooool! :tada:

`VK_KHR_shader_float16_int8` が使えるようになりました!

## 追記(Mesa 20)

Mesa 20(2020/Feb/19) で, RADV で Vulkan 1.2 が使えるようになりました.

https://www.mesa3d.org/relnotes/20.0.0.html

HLSL でシェーダ記述もできるものと思われます.

## 追記(Mesa 21.3)

21.3 でレイトレ機能が experimental で使えるようになりました.


`VK_ICD_FILENAMES` で使う Vulkan ドライバを指定しても, `amdgpu-pro` を入れているとなぜか 32bit 版の amdvlk32 を見に行ってしまうようです. amdgpu-pro(closed source 版 Vulkan ドライバ)を入れている場合は削除しておきましょう.


また, デフォルトではレイトレ拡張出てきません.

環境変数で `RADV_PERFTEST=rt` を指定する必要があります.
(念の為, `vulkaninfo` などで, RADV が使われているのをを確認しましょう)

https://docs.mesa3d.org/envvars.html

## offscreen で動かす

`video` group を追加すれば, offscreen(ssh でログインなど)で動かせます.
 
```
$ sudo usermod -aG video $USER
```

## TODO

* [ ] デフォルトでは OpenGL 関連もビルドされるので, RADV(libvulkan)だけビルドするようにする
* [ ] libdrm をユーザディレクトリにインストールして mesa ビルドできるようにする
* [ ] Docker ビルドを用意する(オフィシャルには無いっぽい)