OpenGL ES 3.1应用程序在ARM Mali GPU上保持闪烁

时间:2018-06-08 20:47:35

标签: android opengl-es mali

我已经为Android编写了一个OpenGL ES 3.1应用程序,我正在与一个特定平台ARM Mali GPU上的问题作斗争。该程序似乎在Adreno和PowerVR GPU上正常运行。

一帧由几个渲染过程组成。渲染过程通过着色器存储缓冲区对象和原子计数器进行通信。整件事看起来像这样:

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%的帧看起来是正确的,但每隔一段时间,对象的任意子集都会消失,并在下一帧中重新出现。

############################################

问题是,我不知道是什么导致消失的物体。到目前为止我所尝试的是继续删除代码以查看错误是否仍然存在 - 试图找出能够重现问题的最短代码。这种方法失败了,因为我删除的代码越多,bug就越难以重现。最初它每秒发生大约两次,经过几次删除各种位后,我每分钟只能再现一次,最终我再也无法重现它,但我不知道这是因为我刚删除了有问题的代码还是因为我刚刚通过了一些门槛,但仍然存在错误,但现在很难再现。

我尝试的第二件事是通过查看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);

几乎在应用程序代码的任何地方,bug都会消失。

特别是,当我删除第一个glMemoryBarrier()并用上面的替换它时,这个bug就完全消失了(我记录了10分钟的屏幕并逐帧观看,它已经消失了)。即使我根本不检查CPU上的缓冲区,也会发生这种情况,我只是映射它并立即取消映射(哪个AFAIK应该具有与memoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)相同的效果?)这引起了人们的怀疑,即glMemoryBarrier关于马里的(GL_SHADER_STORAGE_BARRIER_BIT)是错误的,所以我写了一个测试程序来看 - 这证明了glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)工作得很好。

我还有一个Mali Graphics Debugger,我可以将它连接到手机,但是当我这样做时,bug会立即消失。我停止追踪 - 它再次开始每秒闪烁两次。

您对如何处理此类问题有什么建议吗?

代码是GPL v2,完全可以下载 - 它是45k行的Java,XML和GLSL。如果有人想看看,这里是:

http://distorted.org/redmine/projects/distorted-android/wiki/How_to_compile_and_run_the_example_code

(需要查看“与订单无关的透明度”分支;主人运行正常)

0 个答案:

没有答案