GLSL代码使iPhone 6 Plus上的应用程序崩溃

时间:2014-12-05 01:51:03

标签: ios iphone opengl-es glsl gpu

我发现一些特殊的GLSL写作风格会让iPhone 6 Plus崩溃而没有任何日志。

例如,如果您编写类似下面的代码的GLSL,它将在glLinkProgram崩溃。

float testFun(float co) {
    return co;
}

float a = testFun(0.1);

void main()
{
    // your code here
}

但是如果你移动" a"的定义进入一个函数,然后它将正常工作。

这不会发生在iPhone5或5s中。

您可以通过

下载示例项目来重现此错误
  

http://www.raywenderlich.com/3664/opengl-tutorial-for-ios-opengl-es-2-0

然后用

替换SimpleFragment.glsl
varying lowp vec4 DestinationColor;

varying lowp vec2 TexCoordOut; // New
uniform sampler2D Texture; // New

precision highp float;

float testFun(float co) {
    return co;
}

float a = testFun(0.1);

void main()
{
    gl_FragColor = vec4(0.7, 0.5, 0.3, 1.0);
}

并在iPhone 6 Plus上运行它。它会立即崩溃。

2 个答案:

答案 0 :(得分:1)

首先,你提到的这3款iPhone有3种不同的GPU:

  
      
  • iPhone 5 - > SGX543
  •   
  • iPhone 5s - > A7
  •   
  • iPhone 6 / Plus - > A8
  •   

这意味着它在iOS中可能有不同的驱动程序,glsl着色器编译工具也可能会有所不同,但没有人真正知道除了Apple的人。在您这边,这意味着您真的需要在真实设备上运行/调试您的应用程序,而不是软模拟器。

另一方面,你的iPhone 5 / 5s / 6 Plus在同一个iOS版本上,对吧? [我假设是的,;)]

回到你的问题,我认为你不应该在你的glsl着色器中使用像c这样的全局变量,因为着色器中没有堆栈/堆存储布局,但大多数变量都是寄存器。

这意味着你的浮动a;将有一个注册地点,这是GPU中有限的资源!我认为不建议在glsl中使用全局变量,或者在大多数程序语言中使用更清晰的变量。

您可以尝试使用下面的函数调用检查着色器的状态,以获取有关着色器编译失败的详细说明:

  

glGetProgramiv(程序,GL_LINK_STATUS和& link_status);
  glGetProgramiv(program,GL_INFO_LOG_LENGTH,& length);
  glGetProgramInfoLog(program,length,NULL,& log [0]);

希望它有所帮助。

答案 1 :(得分:0)

您的着色器代码包含错误。这一行无效:

float a = testFun(0.1);

在ES 2.0 GLSL规范中," 4.3存储限定符"第29页说(重点补充):

  

没有存储限定符或仅使用const限定符的全局变量声明可能包含初始值设定项,在这种情况下,它们将在执行main()的第一行之前初始化。 此类初始值设定项必须是常量表达式

现在问题变成testFun(0.1)是一个常量表达式。 Section" 5.10常量表达式"第49页澄清:

  

以下内容不得用于常量表达式:

     
      
  • 用户定义的功能
  •   

着色器编译器崩溃的事实看起来像Apple bug。用它们归档。