🌋

VulkanでShaderからprintfする方法

2023/05/17に公開

要約

  1. Vulkan Configulatorを開いてDebug Printf Presetを選択
  2. GLSLでGL_EXT_debug_printfを有効化
  3. debugPrintfEXT()で出力
  4. stdoutで値を確認


stdout に printf してみた様子

なぜShaderでprintfしたいのか

Shaderのデバッグは大変です。デバッガーもありますが今回はプリミティブなデバッグに焦点をあてます。

Fragment shaderであればピクセルの色として中間値を出力して眺めることができるので比較的デバッグしやすいと思います。しかし、Compute shaderやTask/Mesh shader、Ray tracing shaderでは、ピクセル色を使ったデバッグが難しいことがあります。

よってShaderでもprintfで値を直接確認できると嬉しいです。Vulkan/GLSLでは、そのための拡張機能が提供されています。今回は省きますが、HLSLでも使用可能です。

手順

1. Vulkan Configulatorを開いてDebug Printf Presetを選択

GLSL側でdebug printfの設定をするだけでは、printfの結果を確認するすべがありません。そのための方法(下記参考文献を参照)はいくつかありますが、最も簡単なのがVulkan Configulator(以下vkconfig)を開いておくことです。

具体的な手順は以下の通りです。

  • vkconfigはVulkan SDKに含まれているので、普通に起動します。
  • Vulkan Layers ConfigurationsをValidationに変更します。
  • Validation SettingsのプリセットをDebug Printf Presetに変更します。
  • Log Filenameにstdoutを入力します。

2. GLSLでGL_EXT_debug_printfを有効化

1行追加すればOKです。

#extension GL_EXT_debug_printf : enable

3. debugPrintfEXT()で出力

必要な内容を出力します。formatは通常のprintfと似ています。

debugPrintfEXT("Hello from shader!\n");
debugPrintfEXT("int: %d\n", 123);
debugPrintfEXT("float: %f\n", 3.14);

すべてのスレッドから出力するとバッファがあふれてしまうため、必要な箇所のみで使うのがいいでしょう。

4. stdoutで値を確認

実行するとstdoutに値が表示されているはずです。

参考

https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/docs/debug_printf.md

Discussion