iOS Shader е компилиран извън фазата на предварително загряване

В моята програма 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