iOS12 导致 Metal Command Buffer 执行出错,渲染出现故障或未发生

Posted

技术标签:

【中文标题】iOS12 导致 Metal Command Buffer 执行出错,渲染出现故障或未发生【英文标题】:iOS12 is causing an error on Metal Command Buffer execution, render is glitchy or doesn't occur 【发布时间】:2019-02-26 20:43:45 【问题描述】:

我们有一个使用Metal 进行渲染的应用。此应用程序可在运行 ios11 的设备上正常运行。在运行 iOS12 的设备上使用相同的应用程序时,我们开始出现故障,有时会在渲染中挂起。我们还尝试为 iOS12 重新编译并得到相同的不良行为。在控制台上,我们收到以下不同的消息:

2018-09-22 09:22:29.508576-0500 OurApp [1286:84481] 由于执行期间出现错误,命令缓冲区的执行被中止。丢弃(GPU 错误/恢复的受害者)(IOAF 代码 5)

2018-09-22 09:29:55.654426-0500 OurApp [1286:84625] 由于执行期间出现错误,命令缓冲区的执行被中止。导致 GPU 挂起错误(IOAF 代码 3)

2018-09-22 09:34:37.718054-0500 OurApp [1286:87354] 由于执行期间出现错误,命令缓冲区的执行被中止。忽略(用于导致先前/过多的 GPU 错误)(IOAF 代码 4)

对于前两条消息,渲染似乎有问题,出现一个空白屏幕,然后最终渲染出现在屏幕上。最后一条消息实际上并没有发生渲染,消息会继续显示,直到我们移动到不同的视图。

此应用使用SceneKit,实例化SCNView 并使用默认CIContext。它还使用基于物理的光照模型,该模型强制使用Metal 渲染器。该应用程序有一个简单的SCNNode 几何图形,一个圆柱体。圆柱体的每个几何对象都有一个法线纹理(总共 3 个)。相同的漫反射、金属度和粗糙度值应用于圆柱体的所有几何对象。

有人遇到过这个问题吗?如果有,你是怎么解决的?

谢谢

更新:问题似乎是当使用图像作为场景的照明环境时引起的:

let scene = SCNScene()
scene.lightingEnvironment.contents = UIImage(named: "ourLightingEnvironmentImage")

如果不使用照明环境,问题就会消失。这开始看起来像一个 Apple 错误,我们将提交一个。我们被困住了,因为我们需要光照环境来为我们应用中的模型产生逼真的反射。

【问题讨论】:

在加载在 SceneKit 编辑器中创建的简单场景时,我在某些但不是所有 iOS 12 设备上遇到了同样的问题。感谢您的更新,当我将闪电环境更改为远离默认的“Procedural Sky”时,问题就消失了。与您的观察相反,当使用我自己的一张图像作为闪电环境时,它没有挂起。请提交错误,并在 Apple 修复后在此处报告。 这似乎只是 iPhone 6 的问题。我们已向 Apple 提交了该错误。 Apple 的错误报告机制的问题在于,错误的优先级取决于他们获得的重复次数,其次,您永远不会收到有关错误状态的任何更新或反馈。 对我来说,Apple 似乎已经完全打破了 iOS 12 的闪电。我看到了多个问题,还有雾、视距、穿过迷宫时的黑色区域......我还检查了多台设备:所有装有 iOS 11.4.3 的设备都运行良好,所有装有 iOS 12 的设备都显示伪影:-( 在 iOS 12.0.1 上使用 iPhone 6 和 iPad Mini 运行我们的 SceneKit 应用程序时遇到同样的问题。 iOS 11.4 没有问题。 @LenK 请向 Apple 记录错误报告。似乎他们只关注有重复的错误。谢谢 【参考方案1】:

我暂时可以通过选择 OpenGL ES 作为渲染模式来解决我的问题:

【讨论】:

感谢 Stefan,使用 OpenGL over Metal 解决了错误问题。问题是我们的应用需要具有环境光照的基于物理的光照模型,而这仅在 Metal 中可用。【参考方案2】:

我刚刚收到了我向 Apple 提交的错误的更新:

Apple 开发者关系

我们相信此问题已在最新的 iOS 12.2 测试版中得到解决。请使用最新的 iOS 测试版进行测试。如果您仍有问题,请使用任何有助于我们调查的相关日志或信息更新您的错误报告。 iOS 测试版https://developer.apple.com/download/"

【讨论】:

由于执行过程中出现错误,命令缓冲区的执行被中止。导致 GPU 挂起错误(IOAF 代码 3)由于执行期间的错误,命令缓冲区的执行被中止。丢弃(GPU 错误/恢复的受害者)(IOAF 代码 5)[断言] 无法在非主线程上使用 asCopy = NO 调用。 [BoringSSL] nw_protocol_boringssl_get_output_frames(1301) [C15.1:2][0x10b30da00] 获取输出帧失败,状态 8196 TIC 读取状态 [15:0x0]:1:57 在 IOS 12.3.1 和 iPhone X 中也出现同样的问题。【参考方案3】:

我似乎遇到了完全相同的问题。同样使用 ARKit 和默认的 sceneKit 编辑器,当屏幕冻结时,我不断收到 IOAF 代码 4 错误。

我通过将环境从“Procedural Sky”更改为“None”解决了我的问题。不再滞后或冻结,但这几乎不是解决方案,因为我的 AR 对象现在没有照明或环境。我相信 iOS 12.2 Beta 中会有修复,但尚未更新。

希望我的解决方案对其他人有所帮助。

【讨论】:

【参考方案4】:

这是一个错误,由高分辨率环境闪电图像引起。

解决方案是调整这些图像的大小,我们现在使用的是 1000x500。完美运行。

【讨论】:

我也遇到了这个问题,并且仍然在 iOS 12.4 中 - 在检查了使用 Apples ARKit 模板(我在 ARKit 中遇到问题)文件的默认环境地图之后,我说地图的分辨率是太高了。像超过 4000 x 2000 像素。我将分辨率降低到 1024x512,错误立即消失。 (我还观察到,整个场景设置越复杂,抛出的错误就越多)

以上是关于iOS12 导致 Metal Command Buffer 执行出错,渲染出现故障或未发生的主要内容,如果未能解决你的问题,请参考以下文章

icb 的支持平台

Metal2新特性:光栅顺序组(ROG,Raster Order Groups)

Metal(iOS)中的多重采样/锯齿状边缘

未找到 iOS Metal 默认库

在大纹理上渲染小纹理时,Metal 比 OpenGL 慢得多

为 iOS 模拟器目标构建时忽略 .metal 文件