私は Android 用の OpenGL ES 3.1 アプリを作成しましたが、特定のプラットフォームである ARM Mali GPU で問題と戦っています。プログラムは、Adreno および PowerVR GPU で正しく実行されているようです。
1 つのフレームは、複数のレンダー パスで構成されます。レンダー パスは、シェーダー ストレージ バッファー オブジェクトとアトミック カウンターを使用して通信します。全体は次のようになります。
Pass1_Initialize_SSBO_and_Atomic();
glMemoryBarrier(GL_ALL_BARRIER_BITS);
Pass2_Fill_SSBO_With_initial_Data();
glMemoryBarrier(GL_ALL_BARRIER_BITS);
for(i=0;i<N;i++)
{
Pass3_Render_Object(i);
glMemoryBarrier(GL_ALL_BARRIER_BITS);
}
Pass4_Compose_Everything();
問題は、マリでは画面が点滅し続けることです。私は多くの記録を作成し、それらをフレームごとに見ました。何が起こるかというと、フレームの約 95% は正しいように見えますが、オブジェクトの任意のサブセットが消えて、次のフレームで再表示されることがよくあります。
############################################問題は、オブジェクトが消える原因が何なのかわかりません。私がこれまでに試みたのは、コードを削除し続けて、バグがまだ存在するかどうかを確認することです。これは、問題を再現する最短のコードを見つけようとする試みです。削除するコードが多いほど、バグの再現が難しくなるため、このアプローチは失敗します。最初は毎秒約2回発生し続け、さまざまなビットを数回削除した後、1分に1回しか再現できず、最終的にはもう再現できませんが、問題のあるコードを削除しただけなのか、それともあるしきい値を超えたところですが、バグはまだ残っていますが、再現するのは非常に困難です。
2 番目に試みたのは、SSBO を見てバグを測定することです。パス間の特定の瞬間にそれを CPU にメモリ マップし、必要なものが実際に含まれていることを確認します。残念ながら、追加するとすぐに
glBindBuffer(GL_SHADER_STORAGE_BUFFER, mSSBO[0] );
glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, length, GL_MAP_READ_BIT);
(...) // print the buffer
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
アプリケーション コードのほぼどこでも、バグは単純に消えます。
特に、最初の glMemoryBarrier() を削除して上記のものに置き換えると、バグは完全に消えます (10 分間分の画面を記録し、これをフレームごとに見たところ、消えてしまいました)。これは、CPU のバッファーをまったく検査しなくても発生します。マップしてすぐにマップ解除するだけです (私の知る限り、memoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT) と同じ効果があるはずです??)。 (GL_SHADER_STORAGE_BARRIER_BIT) on Mali はバグがあるので、確認するテスト プログラムを作成しました。これにより、glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT) が正常に動作することが証明されました。
Mali Graphics Debugger も持っていて、電話に接続できますが、接続するとすぐにバグが消えます。トレースを停止すると、再び 1 秒に 1 回から 2 回点滅し始めます。
このような問題にアプローチする方法について何かアドバイスはありますか?
コードは GPL v2 で、完全にダウンロードできます。Java、XML、および GLSL の 45,000 行です。誰かが見たい場合は、ここにあります:
http://distorted.org/redmine/projects/distorted-android/wiki/How_to_compile_and_run_the_example_code
('order-independent-transparency' ブランチをチェックアウトする必要があります; マスターは正常に動作します)