Шейдер iOS скомпилирован вне фазы предварительного прогрева

В моей программе OpenGL ES 2.0 на iOS я компилирую свои шейдеры следующим образом:

setShaderState(state);//enables or disables GL_BLEND
GLuint vertexShader = compileShaderPart(vertexShader, GL_VERTEX_SHADER, state);
GLuint fragmentShader = compileShaderPart(fragmentShader, GL_FRAGMENT_SHADER, state);

//linking
GLuint programHandle = glCreateProgram();
Assert(programHandle != 0, "Program handle 0");

for(auto shaderAttribute : shaderAttributeList){
  if(isVertexAttribute(shaderAttribute.attribute())){
    glBindAttribLocation(programHandle, shaderAttribute.attribute(), shaderAttribute.attributeName(1).c_str());
  }
}


glAttachShader(programHandle, vertexShader);
glAttachShader(programHandle, fragmentShader);
glLinkProgram(programHandle);
Assert(glGetError() == GL_NO_ERROR, "Could not link program");

GLint linkSuccess;
glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);
if (linkSuccess == GL_FALSE) {
  GLchar messages[256];
  glGetProgramInfoLog(programHandle, sizeof(messages), 0, &messages[0]);
  ELog << messages;
  Assert(0, "Error compiling shader");
}

ShaderUniformHandleMap shaderUniformMap;    
Shader *shader = new Shader(programHandle, availableShader.name, shaderUniformMap, state);

glUseProgram(programHandle);
auto mesh = Mesh::load("quad");
shader->bindMesh(mesh);
auto temp_texture = Texture2D::load("checker");
for(auto uniform : shader->texture){
  glUniform1i(uniform.handle, shader->bindTexture(temp_texture->textureId()));
}
glDrawElements(GL_TRIANGLES, mesh->indexDataSize(), GL_UNSIGNED_SHORT, 0);

Я исключил унифицированную часть чтения для удобочитаемости, а функция compileShaderPart настолько прямолинейна, насколько это возможно.

Запуск приложения в openGL ES Analyzer в инструментах приводит к сотням случаев возникновения проблемы «Шейдер, скомпилированный вне фазы предварительного прогрева». Разве вызов glDrawElements не должен позаботиться об этом?

Я читал, что изменение состояний, таких как GL_Blend, может иметь такое влияние, поэтому я компилирую один и тот же шейдер дважды, один раз с включенным GL_Blend и один раз с отключенным, но это не имело никакого значения.

В чем проблема? Мне также трудно найти информацию об этом предварительном прогреве, пока я понял, что шейдер действительно компилируется только после первого вызова отрисовки, поэтому я рисую этот четырехугольник в конце.


person cboe    schedule 15.11.2013    source источник
comment
Насколько я понимаю, предварительное прогревание означает предварительную настройку конвейера рендеринга. В случае с шейдерами GLSL, если реализация откладывает компиляцию до первого использования, вы захотите нарисовать свою сцену с помощью шейдера, но фактически не отображать результаты.   -  person Andon M. Coleman    schedule 17.11.2013
comment
Мы сталкиваемся с той же проблемой. Наши шейдеры компилируются/связываются вне основного цикла. У нас нет компиляции/связывания шейдера внутри основного цикла, и тем не менее мы видим сотни таких предупреждений в каждом кадре на протяжении всей игры. Не уверен, что происходит. Удалось узнать?   -  person Samaursa    schedule 20.02.2015


Ответы (2)


Это в вашем основном цикле рендеринга? Вам нужно скомпилировать шейдер только один раз, а затем вы используете вызов glUseProgram с именем шейдера, чтобы привязать его, когда вам нужно использовать его снова. Судя по всему, вы компилируете его один раз при каждом вызове отрисовки, отсюда и сотни предупреждений. Кроме того, я почти уверен, что шейдерные программы OpenGL ES не содержат состояния различных частей конвейера рендеринга, таких как режимы наложения, поэтому ваша вторая компиляция, скорее всего, также не нужна.

person Ben Pious    schedule 16.11.2013
comment
спасибо за ответ, я дважды проверил, компиляция выполняется только один раз в начале, как и ожидалось. Я думал то же самое о режимах наложения, но это то, что я прочитал в теме SO, которую я действительно не могу найти в данный момент. - person cboe; 16.11.2013

рекомендация по деталям инструмента:

Ваше приложение вызвало компиляцию шейдера, которая не является частью начальной фазы предварительного прогрева. Компиляция шейдера может занять много времени. Чтобы их избежать, предварительно прогрейте все шейдеры, используемые для рендеринга. Для этого выполните предварительный проход при запуске приложения и выполните вызов отрисовки с каждой из программ шейдера, которые будут использоваться, используя любые настройки состояния GL, с которыми программа шейдера будет использоваться в сочетании. Такие состояния, как смешивание, цветовая маска, логические операции, множественная выборка, форматы текстур и состояние точечных примитивов, могут влиять на компиляцию шейдера.

person velkyel    schedule 24.01.2015