追加のコピーなしで、計算シェーダーを使用して圧縮テクスチャに書き込む


8

コンピューティングシェーダーを使用してOpenGLテクスチャを生成する最善の方法を理解しようとしています。これまでのところ、ピクセルバッファーオブジェクトは非ブロッキングCPU-> GPU転送に適していること、およびコンピューティングシェーダーは、どのようにバインドされているかに関係なく、バッファーを読み書きできることを確認しました。理想的には、できるだけ多くのコピーを避けたいと思います。つまり、GPUにバッファーを割り当て、圧縮されたテクスチャデータをGPUに書き込み、そのバッファーをシェーダーのテクスチャオブジェクトとして使用します。

現在、私のコードは次のようになります。

GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, tex_size_in_bytes, 0, 0);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

// Bind buffer to resource in compute shader
// execute compute shader

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
glCompressedTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, tex_size_in_bytes, 0);

これは正しいです?同期の保証についてもどこかで読みました。バッファオブジェクトからコピーする前に、コンピュートシェーダーが実行を完了させるために何を追加する必要がありますか?


使用するテクスチャ圧縮形式を指定しますか?私は推測していますが、あなたの答えはおそらく計算モードのテクスチャ圧縮ルーチンを含むでしょう。
ap_

回答:


3

しばらく調べたところ、いくつかのことがわかりました。

  1. memcpyを回避することはできません。OpenGLAPI呼び出しのみを使用して、圧縮テクスチャに割り当てられたテクスチャストレージに直接書き込むことはできません。つまりglCompressedTexImage2D、バインドされたPBO を使用してへの呼び出しを回避することはできません。つまり、16ビットRGBAテクスチャとGLSL画像タイプをコンピュートシェーダーで使用できる場合があります。

  2. メモリを同期する必要があります。コンピュートシェーダーがストレージバッファーへの書き込みを確実に完了するためには、そのバッファーへのすべての読み取りと書き込みが完了することを確認する必要があります。これは、を使用glMemoryBarrierして呼び出しGL_SHADER_STORAGE_BARRIER_BITます。

圧縮されたテクスチャとして使用されるバッファに書き込むものの完全なコードは、次のようになります。

GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, tex_size_in_bytes, 0, 0);

glUseProgram(compute_shader_prog);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, compute_shader_bind_point, buffer);
glDispatchCompute(wg_x, wg_y, wg_z);
glMemoryBarrier(GL_SHADER_STORAGE_BUFFER_BIT);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
glCompressedTexImage2D(GL_TEXTURE_2D, 0, fmt, w, h, 0, tex_size_in_bytes, 0);

「16ビットRGBAテクスチャとaを使用できるかもしれません」そしてA WHAT ??? :)
Nathan Reed、

2
これは、タブを開いたままにして後で完了するとどうなるかです。編集。
Mokosha 2015

1
GL_SHADER_STORAGE_BARRIER_BIT間違ったバリア。指定したバリア、メモリの使用方法を示します。シェーダーがそれに書き込んだ方法ではありません。ピクセル転送を行っているため、使用する必要がありますGL_TEXTURE_UPDATE_BARRIER_BIT
Nicol Bolas

1
本気ですか?docsによるとGL_TEXTURE_UPDATE_BARRIER_BIT呼び出しを同期するときにglTexImage使用され、ストレージバッファーで使用されるメモリとは何の関係もありません。あなたが意味したと思いますGL_PIXEL_BUFFER_BARRIER_BITか?
Mokosha 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.