pixel10 从Binary 创建shader program崩溃

pixel10 手机 opengles 驱动版本 OpenGL ES 3.2 build 25.3@6908880 第二次进入游戏后,通过binary 创建 shader program的时候会崩溃 . 附件图片中是崩溃堆栈。如果还想用binary,请问有什么解决办法吗?

[Attachment Removed]

重现步骤
pixel10 手机 opengles 驱动版本 OpenGL ES 3.2 build 25.3@6908880 第二次进入游戏后,通过binary 创建 shader program的时候会崩溃 ​.

[Attachment Removed]

Hi,

我们内部有一个类似记录,在Pixel 9和Xiaomi Redmi Note 10S上崩溃,有几个现象,一个是这些设备的驱动都比较老,小米的驱动是r26的(你们的情况是r25),我们用一台三星S10,Android版本比Xiaomi的老,但是驱动版本是r32的,就不崩溃。第二个现象是,我们改用deferred后,也不崩溃了,只有Forward崩溃。

我感觉如果要找原因的话,需要先定位到这个binary来自那个vs和ps,然后确认一下输入输出部分有什么特别的,大概率是某种格式这个驱动支持不好。如果驱动能返回失败,不要直接崩溃,至少有机会用源码重新link。

后续如果有线索,可以继续交流。

[Attachment Removed]

你好, 我们现在能确定是驱动层bug ,关于bug 信息摘要如下 :

使用 OpenGL ES 3.1 的 Unreal Engine 4.26 应用在 Pixel 10 上,第二次及以后启动时于 glLinkProgram(或 glProgramBinary)内部以 SIGSEGV 崩溃。

崩溃模块:/vendor/lib64/egl/libGLESv2_powervr.so 崩溃函数:CreateProgramShaderBridgeVariant 首次安装后的首次启动从未崩溃。

崩溃原因(已由在线调试与内存 dump 证实)

  1. 驱动从 Android EGL blob cache 反序列化已链接 program 时(LoadLinkedProgramFromBlobCache → RGXBS_Unpack*),只回写 const-load 表(UNIFLEX_CONST_LOAD 数组)每条记录的 16 位索引,不清零、不还原记录的其余字段。
  2. 对 eFormat == UNIFLEX_CONST_FORMAT_STATIC 的记录则完全不写值,其 uStaticVal / uSrcShift 保留分配前的堆残留。
  3. 随后 CreateProgramShaderBridgeVariant 的 uniform 桥接循环不检查 eFormat,把每条记录 +4 处的低 16 位一律当作 uniform 索引,去读一张 300 项的表;残留值低 16 位较大时即读到未映射页,触发 SIGSEGV。

为什么只在缓存命中时崩溃

源码编译路径,同样的 STATIC 记录值恒为 0,不会越界。因此崩溃只出现在 blob 命中路径,且随堆残留内容与堆布局呈概率性。

所以请教下面几个问题 :

  1. 我们打算使用uniform buffer OpenGL.UseEmulatedUBs=0 规避这个崩溃问题, 我们想知道使用Uniform buffer 对性能,内存开销 相比 EmulatedUBs 模式下 有多大的负面影响 ,有没有其他团队的UE4 项目使用过 这个方案 ?
  2. 使用 Android 17 自带的 Angle 转vulkan, 这个方案的是否可行 ,有没有其他项目使用过这个方案,请你们给一些建议 ?
  3. 使用UE4 自带的vulkan , 除此三个方案外,还有没有其他方案可规避这个问题 ?
    [Attachment Removed]

Hi,

我们在很早以前就评估过,OpenGL用UniformBuffer会导致性能和内存的问题,我们的理解是,虽然UB理论上应该是全局一份,所有Program如果用同一个UB应该是同一份,但实际上应该是每个Program一份UB,并且UB开启后,性能会有明显的下降。

Angle转Vulkan不是很确定,因为老的设备对Vulkan的支持也不是很好。

有没有可能在这种设备上关掉Binary Cache?或者如果能确定哪些Program会造成崩溃,就把特定的Program通过link的方式创建。

[Attachment Removed]