【问题标题】:iOS Shader compiled Outside of prewarming phaseiOS Shader 在预热阶段之外编译
【发布时间】:2013-11-15 18:17:08
【问题描述】:

在 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 Analyzer 中运行应用程序会导致数百次出现“在预热阶段之外编译的着色器”问题。 glDrawElements 调用不应该解决这个问题吗?

我了解到像 GL_Blend 这样的更改状态会产生这种影响,因此我编译了两次相同的着色器,一次启用 GL_Blend,一次禁用,但没有任何区别。

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

【问题讨论】:

  • 据我所知,预热是指提前设置渲染管道。对于 GLSL 着色器,如果实现将编译推迟到第一次使用,那么您可能希望使用着色器绘制场景,但实际上并不显示结果。
  • 我们遇到了同样的问题。我们的着色器在主循环之外编译/链接。我们没有在主循环中发生任何着色器编译/链接,但在游戏期间,我们每帧都会看到数百个这样的警告。不知道发生了什么。你找到了吗?

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


【解决方案1】:

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

【讨论】:

  • 感谢答案,我仔细检查过,编译只在开始时按预期完成一次。我对混合模式也有同样的想法,但这就是我在 SO 线程中读到的内容,我目前真的找不到。
【解决方案2】:

仪器细节推荐:

您的应用程序导致了不属于 初始预热阶段。着色器编译可能很耗时 手术。为了避免它们,预热所有用于渲染的着色器。到 这样做,在您的应用程序启动时进行预热,然后 使用每个要使用的着色器程序执行绘图调用, 使用任何 GL 状态设置,着色器程序将用于 与。混合、颜色蒙版、逻辑操作等状态, 多重采样、纹理格式和点原始状态都可以 影响着色器编译。

【讨论】:

    猜你喜欢
    • 2012-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    • 2014-11-14
    • 1970-01-01
    相关资源
    最近更新 更多