2014-12-05 52 views
0

我发现一些特殊的GLSL书写风格会使iPhone 6 Plus在没有任何日志的情况下崩溃。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。

你可以通过复制下载示例项目这个bug在

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

然后用

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); 
} 

取代SimpleFragment.glsl并在您的iPhone 6 Plus上运行它。它会立即崩溃。

+0

你的问题是什么?这看起来更像是一个错误报告。这可能应该去苹果公司。 – 2014-12-05 02:06:41

+0

非常感谢。已经向Apple报告 – chenxiao07 2014-12-19 06:00:07

回答

0

着色器代码包含错误。这条线是无效的:

float a = testFun(0.1); 

在ES 2.0 GLSL属,节“4.3存储限定符”第29页说,(强调):

全局的

声明没有存储限定符,或者与只是const限定符,可能包含初始化程序,在这种情况下,它们将在执行main()的第一行之前被初始化。 这样的初始值设定项必须是一个常量表达式

现在问题就变成了如果testFun(0.1)是一个常量表达式。部“5.10常量表达式” 49页上的澄清:

以下可以不恒定表达式中使用:

  • 用户定义的函数

的事实,即着色器编译器崩溃看起来像一个Apple bug。与他们一起归档。

1

起初,你提到的这些3 iPhone有3个不同的GPU:

  • iPhone 5 - > SGX543
  • iPhone 5S - > A7
  • iPhone 6 /加 - > A8

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

另一方面,你的iPhone 5/5s/6 Plus是在同一个iOS版本,对不对? [我想是的,;]]

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

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

您可以尝试使用类似下面的函数调用进行更详细的检查一下你的shader状态有关着色器的编译失败解释:

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

希望它有帮助。