ComputeShader一覧

OpenGL の ComputeShader

今回はようやくOpenGLでのComputeShaderを扱ってみます。意外とOpenGLでのComputeShaderって話題になっていないようで、ワクワクしています。

手順

VertexShader, FragmentShader などを生成するように、ComputeShader を生成します。ComputeShaderもまたGLSLで記述するので、今までのシェーダーを生成するような感じでプログラムを記述します。ひとつ違うのは出力する箇所でしょうか、今まではピクセルに出力する感じで out 変数に入れていましたが、ComputeShader では imageXXX というサンプラーっぽい型のuniform変数に値を書き込んでいく感じになります。

C++側のコードは以下のような感じになります。通常のシェーダーと同じようにGLSLをコンパイルして ShaderProgram を作成します。

ComputeShaderからの結果を格納するためのテクスチャを用意しておきます。
このときいつも通りにテクスチャを用意した後、下記のAPIにて設定しておきます。これが Shader Image load store 拡張のAPIになります。これによりテクスチャをUAV化というか書き込み先として利用できるようになります。

通常のメインループにおいては、以下のような感じでコンピュートシェーダーを実行し、結果をテクスチャとして利用して貼り付けています。コンピュートシェーダーの実行は glDispatchCompute で行います。

GL_computeshader

今回は gl_GlobalInvocationID を使って処理しているだけですが、各処理ブロックを識別するのに使える変数がもっとたくさんあります。これらの意味を理解して適切に使っていかないと折角の演算力を生かし切ることができません。
CUDAやDirectComputeのほうでもこれらのパラメータに相当するものがあるようなので、またそれらを試してみたときにどういう対応なのか、どの部分を指し示すのかをまとめてみたいと思います。


OpenGLでComputeShaderを使う前に

OpenGLでComputeShader を使う前に実は知っておくべきことが意外とある、ということで今回はその内容についてです。

ComputeShader は演算のためのシェーダーです。その演算内容をどこかに書き出さなければなりません。OpenGLでは、2種類ほどあるようでそれが以下の物に該当するようです。

  • Shader Image load store
  • Shader Storage buffer object (ssbo)

前者はOpenGL 4.2で取り入れられたもので、後者は 4.3 ではいったもののようです。

Shader Image load storeは、フォーマットが決められた出力先へ記録することができるようです。たとえば float4つの値を2次元テクスチャに記録するとか、そんな感じです。DirectXのほうはよくわかっていませんが RWTexture2D とかそういう系列のものに近いんじゃないかと思います。

Shader Storage buffer object (SSBOと略するらしい) は、フォーマットは比較的自由でGLのシェーダーの中からは Read/WriteできるUniform Buffer Object(UBO)のようなものとしてアクセスができる物のようです。DirectX11のほうでいえば、RWStructuredBuffer に相当するといったところでしょうか。

一方DirectXのRWByteAddressBuffer に相当する物はちょっとわかりませんでした。あまり一般的に使われる物ではない、という位置づけでOpenGLでは入っていないのでしょうか。知っている人がいたら教えて下さい。

言い忘れていましたが、これらUAV相当ということでひとまとめにしてもいいのかもしれません。