mirror of
https://github.com/spoopyghosty0/frameport.git
synced 2026-10-25 03:02:48 +01:00
The Climb 1/2 start again: the dormant foveation diagnostic stays out of CryEngine's renderer (#432, #449)
1.3.0 linked libVkLayer_fdm_darken.so into every arm64 game's engine library; in libCryRenderVulkan.so CrySystem initialization then fails right after the renderer lists its Vulkan device extensions, and the shutdown crashes (SIGSEGV in CSystem::ShutDown). Bisected headless on the dev Frame by swapping libraries between the September known-good APK and a current build: only the modified renderer breaks it. Climb 2's private VrApi bridge still loads the layer itself (72 fps headless with this change). frame.adapter package revision 3 for both games; triage cryengine-init-failed.
This commit is contained in:
1 parent
a08d46a1b7
commit
a8e01c01dc
6 files changed
+43
-1
No files matched your search
@@ -31,6 +31,12 @@ signatures:
|
||||
severity: warning
|
||||
diagnosis: A Khronos loader loaded the system runtime without FrameBridge. A statically linked loader may bypass the bundled loader chain; analyze again, enable the embedded OpenXR loader patch when detected, then rebuild and reinstall to write its per-game manifest.
|
||||
suggest: [frame.static_openxr_loader]
|
||||
- id: cryengine-init-failed
|
||||
pattern: 'Cry\s*:[^\r\n]*Engine initialization failed![^\r\n]*CrySystem initialization failed'
|
||||
severity: fatal
|
||||
diagnosis: CryEngine's start-up failed (CrySystem initialization), and the crash that follows comes from its shutdown. FramePort 1.3.0 builds of The Climb 1/2 failed like this because a dormant diagnostic layer was linked into CryEngine's renderer; a newer FramePort leaves it out, so update FramePort and press Update on Frame. Otherwise attach the diagnostics zip to a report.
|
||||
report: true
|
||||
suggest: []
|
||||
- id: swapchain-limit-reached
|
||||
pattern: 'FrameBridge:\s+xrCreateSwapchain [^\r\n]*\bresult=-10\b'
|
||||
severity: error
|
||||
|
||||
@@ -83,6 +83,7 @@ version is `catalog/triage.yaml` (used by `frameport test` / the Job screen); ke
|
||||
| A game from an AXRB download starts and stops at once (Steam shows Resume), no OBB on the Frame; or a SideQuest backup adds a second game named after an APK in its `obb/` folder (reddit 2026-10-11) | AXRB keeps its own PC builds in `AXRB/patched/<package>/*-axrb.apk` (OVRPort-converted for its runtime, no OBBs); the scan added them over the original `AXRB/<app id>/<binary id>/base.apk`. SideQuest's VR4 backup has Unreal's `VR4-Android-Shipping-arm64.apk` next to the OBBs | `quest_dump._axrb_patched` skips AXRB's patched copies; a rescan replaces entries made from them; AXRB downloads send every non-APK file next to `base.apk` (DLC, assets) and are named after the package; APKs inside another game's data folder are ignored; SideQuest backups are named after the package folder, not the backup time. docs/FAQ.md has both layouts |
|
||||
| Game hangs at start / never loads although its .obb files are right there: next to the APK, in an `obb` folder beside an `apk` folder inside a `<package>` folder, or a SideQuest backup (`<timestamp>_<versionCode>.apk`) (GitHub #85, #91) | No folder named after the package, so the folder-layout checks found nothing and no OBB was uploaded | `quest_dump.find_data` then looks for the files by name, `(main\|patch).<versionCode>.<package>.obb` (any case), in the APK's folder, its parent and up to 3 levels below each (folders with their own APKs are other games); prefers the folder and files of the APK's own versionCode, else the newest older, else any version. When that folder also holds other things (the APK itself, other games' OBBs), the library entry gets `data_files` and only those files are uploaded, counted and deleted with the game. Add the folder again |
|
||||
| CryEngine game: `Powered by CRYENGINE`, then SIGTRAP in `libAndroidLauncher.so` during `CreateSystemInterface`, before any OpenXR instance (GitHub #238, The Climb 666.0) | Installed without its OBB: the SideQuest backup has `apk/com.crytek.climb.apk` + `obb/main.com.crytek.climb.obb`, but the scan required a versionCode in the OBB name and skipped it. The reported backtrace's fatal-error call formats `Engine initialization failed: Open Engine Paks: Unable to find "engine" pak files (%s)` | `quest_dump.find_data` accepts `(main\|patch).<package>.obb` as well as numbered names, keeping the original filename. Update on Frame finds the previously skipped data; a rescan finds it too. Analysis version 12 recognizes monolithic CryEngine through `assets/game.cryproject`, Vulkan through `assets/system.cfg` (`r_Driver = vk`), and an expected OBB through the launcher's expansion-path format strings; a missing OBB now gets the existing `missing-obb` warning/finding. This fixes the original missing-content startup failure; the rendering failures below were found once the data was installed |
|
||||
| CryEngine game (The Climb 1/2) on FramePort 1.3.0: `Messagebox: cap: Engine initialization failed! text:CrySystem initialization failed!` right after the renderer lists its Vulkan device extensions, then SIGSEGV in `CSystem::ShutDown` (GitHub #432/#449) | 1.3.0 links the dormant foveation diagnostic `libVkLayer_fdm_darken.so` into every arm64 game's engine library; in CryEngine's `libCryRenderVulkan.so` that stops CrySystem from starting. Bisected headless on the dev Frame: the new build runs once only its renderer is the unmodified one | `foveation.diagnostic_support` skips `libCryRender*` (Climb 2's private VrApi bridge still loads the layer); `frame.adapter` package revision 3 for both Climb games marks their builds for Update on Frame. Triage `cryengine-init-failed` |
|
||||
| The Climb 666.0: audio with no headset picture, `OVRPortVrApi: Unsupported frame flags or swap interval`; then SIGSEGV in `vulkan.freedreno.so` during `vkCmdEndRenderPass` once frames are accepted (GitHub #238) | The game submits the obsolete Quest texture-density debug flag (`0x100`), which the bridge rejected. It also binds the bridge's full-rate texture as a fragment-density attachment even though foveation support is reported off; Turnip reads density maps on the CPU, but an ordinary sampled image has no mapped backing memory | Updated `frame.vrapi_bridge` accepts the compositor debug/volume flags and creates the compatibility texture with `VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT`. Do not gate that usage on the advertised format features (the Frame reports R8G8_UNORM without the density bit). `device.files` selects `r_vr_foveated = 0` when the engine contains that cvar; The Climb 2 keeps `r_variable_rate_shading = 0`. Triage `vrapi-frame-rejected` marks rejected frames as fatal despite pacing logs. Picture confirmed on the headset. With the corrected config, an uncapped launch stayed running for over four minutes at a median 72 fps with no native crash or GPU fault. The user confirmed working menus and gameplay on 2026-10-12 |
|
||||
| Unreal game: `JNI_OnLoad` (OVRPlugin), then silence: no OpenXR instance, no crash, no frames (GitHub #85 TRIANGLE STRATEGY; launch-test finding `missing-obb`) | Installed without its OBB: the manifest says `com.epicgames.ue4.GameActivity.bHasOBBFiles` = true (UE5: `com.epicgames.unreal.…`) but the library has no data folder (`data_dir` null, `data_bytes` 0) | Put the .obb files in a `<package>` (or `obb/`) folder next to the APK, add the folder again, reinstall. Analysis `extra.expects_obb`; the game page, the install question and `frameport scan`/`install` warn; launch tests that sent no frames get the `missing-obb` finding from the library (the game logs nothing). Unity split-binary builds count too (`extra.unity_split`, `analysis/unity_split.py`): an XR-plugin build (Oculus XR Plugin / Unity OpenXR library) without `assets/bin/Data/UnitySubsystems/` in the APK, or BuildSettings listing more scenes than the APK has `levelN` files (globalgamemanagers loose or read from the head of data.unity3d); exact on the 48 Unity APKs of the dumps (13 split, 17 full games; OBBs of full builds are asset bundles or sound banks) |
|
||||
| Unreal game: launch.log ends with `ActivityTaskManager: START u0 {… cmp=<pkg>/.DownloaderActivity}` and `Displayed <pkg>/.DownloaderActivity`, then nothing: no OpenXR instance, no crash (GitHub #159 Contractors; triage `unreal-obb-check-stuck`, also when the OBB is on the Frame) | Epic's DownloaderActivity (started by GameActivity.onResume before the engine's main init) checks every OBB's name + size compiled into the APK (OBBData); with manifest meta-data `com.epicgames.ue4.GameActivity.bVerifyOBBOnStartUp=true` it then reads the whole OBB and compares each entry's CRC32 (cached in `files/cacheFile.txt` by the OBB's mtime). Its progress and error screens are invisible in Lepton (headless VR); a CRC mismatch waits for a button forever. A missing / wrong-size OBB starts Google Play's downloader (or a "No Google Play Store Key" dialog) and also waits | `frame.unreal_skip_obb_check` (suggested by analysis `unreal_verify_obb`): sets that meta-data to false (one boolean in the manifest, `axml.set_meta_data_bool`), which skips only the CRC pass. Still stuck: the OBB doesn't match the APK version (name `main.<versionCode>.<pkg>.obb` and its size) - copy APK + OBB from the same install |
|
||||
|
||||
@@ -24,7 +24,9 @@ def settings_text(recipe_patches: dict) -> bytes:
|
||||
|
||||
class FrameBridgeAdapter(Patch):
|
||||
id = "frame.adapter"
|
||||
package_revisions = {"com.camouflaj.manta": 3} # above revision 2: Batman builds before #389 are outdated
|
||||
# above revision 2: Batman builds before #389 are outdated; The Climb 1/2 builds with the diagnostic layer linked
|
||||
# into CryEngine's renderer don't start (#432/#449)
|
||||
package_revisions = {"com.camouflaj.manta": 3, "com.crytek.climb": 3, "com.crytek.climb2": 3}
|
||||
a32 = True # also for 32-bit games on the bridge
|
||||
title = "FrameBridge OpenXR adapter"
|
||||
description = (
|
||||
|
||||
@@ -20,6 +20,7 @@ LAYER = "libVkLayer_fdm_darken.so"
|
||||
BATMAN_ORIGINAL = "76cafa25c2243c2bc065e30d83d7083b8546153dc6a3c39227235fbabe13c969"
|
||||
CLIMB_RENDERER = "31a121dbfae692fdc0e54853e0640eed820f07826893fa0d905767c9620023a0"
|
||||
CLIMB_BRIDGE = "libvrapi_foveation.so"
|
||||
CRYENGINE_RENDERER = "libCryRender"
|
||||
STORAGE_WORDS = ((0x21c778, 0x5298000b, 0x5290000b),
|
||||
(0x21c77c, 0x5288000c, 0x5280000c),
|
||||
(0x21df50, 0x52980009, 0x52900009))
|
||||
@@ -142,6 +143,10 @@ def validate(ctx):
|
||||
def diagnostic_support(ws):
|
||||
"""The diagnostic constructor is dormant without FRAMEPORT_FOVEATION_TEST=1."""
|
||||
lib = engine_lib(ws) or "libopenxr_loader_generic.so"
|
||||
if lib.startswith(CRYENGINE_RENDERER):
|
||||
# Linked into CryEngine's renderer, The Climb 1/2 fail CrySystem initialization at start (GitHub #432/#449,
|
||||
# headless on the dev Frame). Climb 2's private VrApi bridge loads the layer itself.
|
||||
return False
|
||||
data = ws.read_lib(lib)
|
||||
changed = False
|
||||
if LAYER not in elf.needed(data):
|
||||
|
||||
@@ -201,3 +201,23 @@ def test_installed_only_dialog_reads_supported_level(monkeypatch, level, expecte
|
||||
app = SimpleNamespace(target=target, run_bg=lambda fn: fn())
|
||||
ad.show_adapter_dialog(app, "test.game")
|
||||
assert received == [{"mode": "tracked", "level": expected, "test": False}]
|
||||
|
||||
|
||||
def test_dormant_diagnostic_stays_out_of_cryengine_renderers(monkeypatch):
|
||||
# GitHub #432/#449: linked into libCryRenderVulkan.so, The Climb 2 failed CrySystem initialization at start
|
||||
from frameport.patches.frame import adapter, foveation
|
||||
|
||||
class Ws:
|
||||
abi = "arm64-v8a"
|
||||
written = []
|
||||
|
||||
def read_lib(self, name):
|
||||
raise AssertionError(f"read {name}")
|
||||
|
||||
def put(self, *a):
|
||||
self.written.append(a)
|
||||
|
||||
monkeypatch.setattr(foveation, "engine_lib", lambda ws: "libCryRenderVulkan.so")
|
||||
ws = Ws()
|
||||
assert foveation.diagnostic_support(ws) is False and not ws.written
|
||||
assert adapter.FrameBridgeAdapter().revision_for("com.crytek.climb2") > adapter.FrameBridgeAdapter.revision
|
||||
@@ -658,3 +658,11 @@ def test_swapchain_count_limit_signature():
|
||||
for other in (line.replace("result=-10", "result=0"), line.replace("result=-10", "result=-100"),
|
||||
line.replace("FrameBridge:", "Other:"), "FrameBridge: xrEndFrame result=-10"):
|
||||
assert "swapchain-limit-reached" not in {f.id for f in triage(other, "RUNNING").findings}
|
||||
|
||||
|
||||
def test_cryengine_init_failure_is_named():
|
||||
# GitHub #432/#449: The Climb 2 on FramePort 1.3.0, then SIGSEGV in CSystem::ShutDown
|
||||
log = ("10-23 16:21:18.880 1170 1198 I Cry : Messagebox: cap: Engine initialization failed! "
|
||||
"text:CrySystem initialization failed!\n"
|
||||
"10-23 16:21:18.886 1170 1198 F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0\n")
|
||||
assert "cryengine-init-failed" in [f.id for f in triage(log, package="com.crytek.climb2").findings]
|
||||
Reference in new issue
Block a user