LoginSignup
1
0

More than 1 year has passed since last update.

OpenGL - Compute Shader / Compute Buffer に関するメモ書き

Last updated at Posted at 2022-09-11

概要

自分向けのメモです。メモなのでたぶんどこか間違ってます。
以下のルールを守らないと

(nvoglv64.dll) で例外がスローされました

のエラーが発生したり、バッファがおかしくなったりする

ルール

  • ComputeBufferに渡せるデータは、intやfloatといった一般的な型とその構造体のみ。当たり前だがスマートポインタとか自分のクラスをそのまま渡そうとするとエラーになる
    • glm::vec3 val--> float val[3] のように複数型は配列にする
  • OpenGL ComputeBuffer (std430/std140)のvec3は16バイトごとにオフセットする(vec4も16バイト)
    • かなりの沼ポイント
    • そのことを知らずにvec3としてfloat[3]を使用していると段々バッファのオフセットがずれていってGPGPUの挙動がおかしくなる
      • 例えば中心の方に動かないオブジェクトがあったら、vec3を4バイトオフセットとして使用していて最後の方のデータが足りずに0になっている
    • ベクトルを渡すときはvec4を使った方が安全
  • (当たり前だが)Compute ShaderのDispatchの前にshader programをバインドしないといけない
  • バッファをCompute Shaderや通常のShaderにアタッチするとき、glBindBufferBase(OpenGL)やSSBOのbinding(GLSL)にインデックスを指定するが、このインデックスは『各バッファーごとに一つ割り当てて全体で共通(重複なし)なもの』にしなければならない。
    • 例えば、あるCompute ShaderにバッファをglBindBufferBaseで3を指定してアタッチした場合、そのShaderのbindingも3で他のShaderでそのバッファを使う場合も3を指定する
  • メモリのパディングに要注意
    • セルフでパディング入れないとバグるよ
  • デバイスごとのグループ数やスレッド数の最大値に注意
    • 下記の関数で取れる

      • GL_MAX_COMPUTE_WORK_GROUP_COUNT: 最大スレッド数
      • GL_MAX_COMPUTE_WORK_GROUP_COUNT: たぶんローカルサイズに指定できる値の最大値(?)でも下記の値を超えてはいけない
      • GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: ローカルサイズの x, y, zの積の最大値
    int MaxGroupNum[3];
	glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &MaxGroupNum[0]);
	glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &MaxGroupNum[1]);
	glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &MaxGroupNum[2]);
	
	int MaxThreadsSize[3];
	glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &MaxThreadsSize[0]);
	glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &MaxThreadsSize[1]);
	glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &MaxThreadsSize[2]);

	int MaxThreadsNum;
	glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &MaxThreadsNum);

[DEBUG] MaxGroupNum=> x: 2147483647, y: 65535, z: 65535
[DEBUG] MaxThreadsSize=> x: 1024, y: 1024, z: 64
[DEBUG] MaxThreadsNum: 1024

(MaxGroupNumのxってこんなに大きいの?なんか指定間違ってそう)
MaxThreadsNumが1024なので立方体で計算したいなら 8 * 8 * 8 = 512 にするしかない

参考

https://qiita.com/hoboaki/items/b188c4495f4708c19002
https://qiita.com/RT-EGG/items/74b2e68a9bfd4bdfa3ab
https://logicalbeat.jp/blog/4032/
https://www.khronos.org/opengl/wiki/Compute_Shader
https://antongerdelan.net/opengl/compute.html

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0