Приложение OpenGL ES 3.1 продолжает мигать на ARM Mali GPU
Я написал приложение OpenGL ES 3.1 для Android и борюсь с проблемами на одной конкретной платформе, ARM Mali GPU. Программа работает правильно на графических процессорах Adreno и PowerVR.
Один кадр состоит из нескольких проходов рендеринга. Проходы рендеринга связываются с помощью объекта буфера хранилища шейдеров и атомных счетчиков. Все выглядит так:
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% кадров выглядят правильно, но очень часто произвольное подмножество Объектов исчезает, и появляется снова в следующем кадре.
############################################Проблема в том, что я понятия не имею, что может быть причиной исчезновения Объектов. До сих пор я пытался удалить код, чтобы убедиться, что ошибка все еще существует - в попытке найти самый короткий фрагмент кода, который воспроизводит проблему. Этот подход не работает, потому что чем больше кода я удаляю, тем труднее будет воспроизвести ошибку. Первоначально это происходит примерно два раза в секунду, после нескольких проходов удаления различных битов я могу воспроизводить его только один раз в минуту, и, в конечном счете, я больше не могу его воспроизводить, но я понятия не имею, происходит ли это потому, что я только что удалил код, вызывающий сбой, или потому что Я только что преодолел некоторый порог, и ошибка все еще существует, но теперь очень трудно воспроизвести.
Второе, что я попробовал, это измерить ошибку, взглянув на 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-минутный экран и посмотрел этот кадр за кадром, он исчез). Это происходит, даже если я вообще не проверяю буфер на процессоре, я просто отображаю его и сразу же удаляю его с карты (какой AFAIK должен иметь тот же эффект, что и memoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)??). Это вызывает подозрение, что, возможно, glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT) в Мали глючит, поэтому я написал тестовую программу, чтобы увидеть - и этот проверенный glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT) работает просто отлично.
У меня также есть Mali Graphics Debugger, и я могу подключить его к телефону, но когда я это сделаю, ошибка сразу исчезает. Я прекращаю трассировку - он снова начинает мигать один-два раза в секунду.
Не могли бы вы дать совет, как подойти к такому вопросу?
Код - GPL v2, и он полностью доступен для загрузки - хотя это 45k строк Java, XML и GLSL. Если кто-то хочет взглянуть, вот оно:
http://distorted.org/redmine/projects/distorted-android/wiki/How_to_compile_and_run_the_example_code
(необходимо проверить ветку 'order-independent-прозрачность'; мастер работает нормально)