iOS Shader编译在prewarming阶段之外

时间:2013-11-15 18:17:09

标签: ios compilation opengl-es-2.0 shader instruments

在我的iOS上的OpenGL ES 2.0程序中,我按如下方式编译着色器:

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分析仪中运行应用程序会产生数百个“在预热阶段之外编译的着色器”问题。 glDrawElements调用不应该处理这个吗?

我已经读过像GL_Blend那样改变状态会产生这种影响,所以我正在编译两次相同的着色器,一次启用GL_Blend并且一次禁用,但它没有任何区别。

这里有什么问题?我也发现很难找到关于这个预热的东西的信息,到目前为止我已经收集到着色器只是在第一次绘制调用之后才真正编译,这就是我最终绘制四边形的原因。

2 个答案:

答案 0 :(得分:1)

这是在你的主渲染循环中吗?您只需编译一次着色器,然后使用带有着色器名称的glUseProgram调用在需要再次使用时将其绑定。从事物的外观来看,你每次抽奖都要编译一次,因此有数百个警告。此外,我很确定OpenGL ES着色器程序不包含渲染管道的不同部分的状态,如混合模式,因此您的第二次编译很可能也是不必要的。

答案 1 :(得分:-1)

仪器详细建议:

  

您的应用程序导致着色器编译不属于   初始预热阶段。着色器编译可能非常耗时   操作。为了避免它们,预热所有用于渲染的着色器。至   这样做,当你的应用程序启动时,做一个预热的通道   使用每个要使用的着色器程序执行绘图调用,   使用任何GL状态设置将使用着色器程序   与...结合。混合,颜色掩模,逻辑运算,   多重放大,纹理格式和点原始状态都可以   影响着色器编译。