2014-05-13 4 views
1

У меня возникла проблема, когда изменения в фрагментаторном шейдере временно прерывают рендеринг. Шейдер компилируется; на этапе компиляции, этапе ссылки или glValidateProgram() не возникает условия ошибки или выхода журнала. Но последующие вызовы glDrawArrays() возвращают GL_INVALID_OPERATION, ничего не нарисовано, и приложение становится очень медленным или не отвечает.Программа GLSL сбой прерывается на некотором оборудовании iOS

Однако, когда я переключаюсь с основного устройства разработки (iPad 2) на другое оборудование (iPhone 5s и iPad Mini), тот же код работает отлично. Как ни странно, если я снова подключился к iPad 2, проблема исчезнет, ​​и я смогу продолжить разработку шейдера на этом устройстве. Этот же цикл повторяется несколько раз: я пересматриваю и добавляю немного нового кода в шейдер и проблему resurfaces. Я переключаюсь на новые устройства, код работает нормально, переключается обратно на iPad 2, проблема таинственно уходит (иногда), и я могу продолжать работать. Как только он снова начнет работать, он, похоже, продолжает работать. Однако с помощью приведенного ниже кода я теперь, похоже, застрял в точке, где обходной путь не помогает.

Моей догадкой (или надеждой) является то, что что-то в моем коде проходит мимо компилятора, но как-то рискованно, так как некоторые аппаратные средства принимают его (A7 и SGX 543), но некоторые не работают (SGX 535). Возможно, прерывистый характер обходного пути - это просто красная селедка. Если ничего подобного не выскочит, я бы приветствовал любые другие рекомендации по устранению неполадок.

Код длинный, поэтому я выписал фрагменты, относящиеся к этой последней итерации проблемы. Предыдущие итерации включали добавление нескольких строк, казалось бы, безобидного кода.

uniform highp vec3 vertexColors[3]; 

mediump vec3 hexagonLayer (highp float edge1, highp float edge2, int layer, mediump vec3 underColor, highp float opacity) { 
    highp float opac = remap (length (faceP - vertexFacePositions[layer]), 0.0, edge1 * 3.0, 1.0, opacity); 

    mediump vec3 shadowColor = pow (underColor, vec3 (2.0)); 
    highp float shadowOpacity = (1.0 - smoothstep (edge1, edge1 + SHADOW_WIDTH, 1.0 - trilinears[layer])) * SHADOW_OPACITY * opac; 
    mediump vec3 color = mix (underColor, shadowColor, shadowOpacity); 

    return mix (color, vertexColors[layer], (1.0 - smoothstep (edge1, edge2, 1.0 - trilinears[layer])) * opac); 
} 
+0

Возможно, вы уже это рассматривали, но прерывистая природа заставляет меня задаться вопросом, является ли проблема с памятью в вашем объектном C-коде, возможно, в буфере вершин. Вы можете попробовать запустить приложение на симуляторе с помощью «Включить Guard Malloc». –

ответ

1

Отвечая на мой вопрос, по крайней мере частично. Моя первая ошибка заключалась в том, что мой код glValidateProgram() никогда не вызывался. Оказывается, у меня было сообщение об ошибке в конце концов, хотя и бесполезно:

Validation Failed: Fragment program failed to compile with current context state. 
Validation Failed: Vertex program failed to compile with current context state. 

Так урок номер один является то, что может быть по-видимому, сбой компиляции, даже если обе GL_COMPILE_STATUS и GL_LINK_STATUS хороши, и оба журнала молчат.

Благодаря подсказке от this question Я начал изучать несоответствующие определители точности и, конечно же, менял все мои средние цвета на highp, решает проблему. Это потому, что я объявил мою форму как highp, а затем mix() между highp и mediump vec3? (Я укоротил код в своем вопросе, чтобы показать соответствующие разделы.)

Мне кажется, что это может случайно работать на новом оборудовании, так как я думаю, что я помню, где-то читал, что аппаратное обеспечение, совместимое с GLES-3 highp и mediump как одна и та же глубина бит. Мне хотелось бы получить подтверждение этого предположения.

+0

Претензионные намеки часто виноваты. – badweasel