ちなみに環境はUbuntu 19.04 + Radeon RX 580です。
OpenGLに疲れた
最近OpenGLに疲れはて、Vulkanに乗り換えようかと思っています。
- メインスレッドからしか叩け無い制限。
- bindというグローバル変数より邪悪な概念。
- 関数を呼び出した後にglGetError()を毎回叩かなけばならない苦痛(叩き忘れるといつエラーになったのか、わからん)。
- シェーダーへ変数へ渡すためのあの無限の関数群。
- OpenGLのバージョンによって今では利用が必須だったり、逆に使えなかったりする「拡張機能」。
- IndexBufferObjectだのElementArrayBufferだのVertexArrayObjectという意味不明な命名(これ…何だと思う?)。
- 同じ関数でもOpenGLバージョンによってたまに意味が違ったりするあのややこしさ。
- ググって出てきた情報の「今では使えなさ」(だいたいそのままコピペしても動かない)
- GLSLのバージョンごとの気まぐれさ。
- 結局何が起こるのかよくわからん関数のドキュメント。
- Core ProfileだのCompat Profileだの
…ぼくもう疲れたよパトラッシュ。
そんな感じで最近Vulkanでなんとかする方向でやってこうと思ってまして、で最近引っかかった問題の解放を備忘録代わりにメモっておきます。
VulkanにはLayerなるものがあるらしい
Vulkanではある種の拡張機能を「Layer」といいます1。
たとえば、標準ではこんなLayerがあるんだってさ(LunarGのサイトから引用。CC=BY=ND):
Layer Name | Layer Type | Description |
---|---|---|
VK_LAYER_LUNARG_api_dump |
utility | print API calls and their parameters and values |
VK_LAYER_LUNARG_assistant_layer |
utility | highlight potential application issues that are not specifically prohibited by the Vulkan spec, but which can still create problems |
VK_LAYER_KHRONOS_validation |
validation | the main, comprehensive Khronos validation layer — this layer encompasses the entire functionality of the deprecated layers listed below, and supercedes them. As the other layers are deprecated this layer should be used for all validation going forward. |
VK_LAYER_LUNARG_device_simulation |
utility | allows modification of an actual device’s reported features, limits, and capabilities |
VK_LAYER_LUNARG_monitor |
utility | outputs the frames-per-second of the target application in the applications title bar |
VK_LAYER_LUNARG_screenshot |
utility | outputs specified frames to an image file as they are presented |
VK_LAYER_KHRONOS_validation、便利そうだなー使いたいなー。
環境によってはこれ以外のLayerも使えるらしく、実際にどんなレイヤーが使えるか列挙して調べるためのvkEnumerateInstanceLayerPropertiesという関数があります。
で、これを使って実際に列挙してみました。
std::vector<VkLayerProperties> vk::enumerateInstanceLayerProperties() { uint32_t numProps = 0; { VkResult const result = vkEnumerateInstanceLayerProperties(&numProps, nullptr); if(result != VK_SUCCESS) { return std::vector<VkLayerProperties>(); } } std::vector<VkLayerProperties> props; props.resize(numProps); VkResult const result = vkEnumerateInstanceLayerProperties(&numProps, props.data()); if(result != VK_SUCCESS) { return std::vector<VkLayerProperties>(); } return std::move(props); }
が、これを動かしても空配列しか返ってこない。エラーではなく、成功した上で0個です。たぶん呼ぶタイミングを間違ったりはしてない。
うーん、おかしい。さっきの6つのレイヤーは、Vulkanの仕様上必ず入っているはずなのです。
ためしにググって見た所、こんな感じだったので、みんな困ってんだろなーと思って解法を書いておきます:
解法:sudo apt install vulkan-validationlayers-devしろ
apt search vulkanと入れると
libvulkan-dev/disco,now 1.1.101.0-2 amd64 [installed] Vulkan loader library -- development files
が出てくるのでこれだけいれときゃOK、Vulkanが全部使えるようになるんだぜ!と思いきや、実はこれだけではUbuntu 19.04ではLayerは入りません。
正解はこちらも入れることです:
vulkan-validationlayers-dev/disco,now 1.1.101.0-1 amd64 Vulkan validation layers -- development files
要するに黙ってsudo apt install vulkan-validationlayers-dev
しろ。
結果
ちゃんと6つ返ってきました:
[2019/10/30 20:43:35 DEBUG] Layer: VK_LAYER_LUNARG_parameter_validation (spec=4198501, impl=1) :: LunarG Validation Layer [2019/10/30 20:43:35 DEBUG] Layer: VK_LAYER_LUNARG_object_tracker (spec=4198501, impl=1) :: LunarG Validation Layer [2019/10/30 20:43:35 DEBUG] Layer: VK_LAYER_GOOGLE_unique_objects (spec=4198501, impl=1) :: Google Validation Layer [2019/10/30 20:43:35 DEBUG] Layer: VK_LAYER_LUNARG_standard_validation (spec=4198501, impl=1) :: LunarG Standard Validation [2019/10/30 20:43:35 DEBUG] Layer: VK_LAYER_LUNARG_core_validation (spec=4198501, impl=1) :: LunarG Validation Layer [2019/10/30 20:43:35 DEBUG] Layer: VK_LAYER_GOOGLE_threading (spec=4198501, impl=1) :: Google Validation Layer
あれ、ちょっとまって、名前全然ちがくない?GOOGLEってなんや??
今日のところはVK_LAYER_LUNARG_standard_validation使って勘弁しといたるわ。
Vulkan難しい
Vulkanとの対話は続く…。
- この時点で若干OpenGL時代の命名規則センスを感じヤバみは感じる… [↩]