ios - GLSL 代码使应用程序在 iPhone 6 Plus 上崩溃

标签 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 上运行它。它会立即崩溃。

最佳答案

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

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

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

另一方面,您的 iPhone 5/5s/6 Plus 是相同的 iOS 版本,对吗? [我想是的,;)]

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

这意味着你的 float a;将保留一个寄存器位置,这是 GPU 中的有限资源!我认为不建议在 glsl 中使用全局变量,或者更明确地说,在大多数程序语言中。

您可以尝试使用如下函数调用来检查有关着色器的状态,以获取有关着色器编译失败的更多详细信息:

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

希望对您有所帮助。

关于ios - GLSL 代码使应用程序在 iPhone 6 Plus 上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27307508/

相关文章:

ios - 如何仅使用 iOS 10 捕获 iOS Swift 3.0 中的崩溃

ios - 将iOS应用程序从一个开发者帐户转移到另一个?

ios - canOpenURL : failed for URL: "instagram://app" - error: "This app is not allowed to query for scheme instagram"

iphone - 如何删除所有项目并向 UICollectionView 添加新项目?

iphone - 发行时NSString崩溃

iphone - 在 iOS OpenGL 应用程序中,使用 ivar 而不是属性会显着提高性能吗?

iOS SceneKit 到 UIView 投影问题

ios - ViewModel 能否返回其他 ViewModel

ios - UINavigationController 中的 UITabBarController 中的 UITableViewController

iPhone - 在 UITableView 上拖动会停止在后台渲染 OpenGL