Port upstream improvements from deadinside28/bloodborne_pc (commit 8185b88):
1. Launcher GPU Selection & Complete 21-Language Support (#249):
- Added `--gpus` CLI argument to `tools/gpu_capabilities.c` to enumerate all available
Vulkan physical devices with vendor ID, device type, name, and default ranking.
- Added a "GPU Adapter" dropdown under "Draw Prep Workers" in the launcher UI
to allow explicit device selection on multi-GPU systems and laptops.
- Expanded the launcher's Game Text Language selector to include all 21 localized
PS4 text languages supported by Bloodborne.
- Choices persist in configuration and pass `BB_GPU_ID` and `BB_LANGUAGE` to the
engine runtime.
2. Crash 0xa0020007 (Code 23) Blur Kernel Clamp:
- Implemented `raise_exception` in `src/runtime_kernel.c` bound to NIDs
`OMDRKKAZ8I4#p#J` and `zE-wXIZjLoM#p#J`.
- Filtered out non-fatal blur-kernel assertions (`code == 0xa0020007u`) from Yebis
at call ranges 0xbbc3e0..0xbbc700 and 0xc33000..0xc34200 unless explicitly stopped
with `BB_GAME_ASSERT_STOP=1`.
- Added entry hook at `image + 0xbbc3e0` (`GPUTexUtil_GetRecursiveSampleParameters`)
in `src/probe.c` to clamp sample count `edi >= 3`, preventing black screens and
assertion trips during recursive texture sampling.
Upstream credits:
- deadinside28/bloodborne_pc@8185b88Closes#126
Steam Deck and weak GPUs
- Outputs other than 1080p render at the preset size again (startup patch, as in 0.1);
live resolution changes are now a setting (live_resolution=0|1|auto, off by default).
- Texture cache on integrated GPUs: thresholds follow the driver's current memory budget.
The old budget (~1 GB on the Deck) kept the collector in its aggressive mode, evicting
textures used 2-3 frames ago on every submission.
- Evicted GPU-written images are written back synchronously, while their pages are still
protected (a deferred write could land over memory the game had reused).
- run.sh uses bash builtins only (the AppImage has no sed: the game did not start on NixOS).
Rendering
- Live scaling also reduces the game's half-resolution post-processing (960x540, including
the bloom mip chain, one proxy per level).
- TAA: history of thin surfaces missed by a jitter phase is kept when nothing moves
(railings, window bars: static-camera flicker p99.9 -45%).
- Scene texture LOD bias log2(render/output) in G-buffer passes while upscaling.
- Present on its own thread and at most one frame of GPU run-ahead (even frame pacing).
- Pipeline cache rebuilt instead of disabled when the shader profile changes.
- GPU idle only after the draw pipeline and deferred fences are done (work_retired).
- Recompiler fixes backported from shadPS4; integer interpolation fix for pre-Turing NVIDIA.
- Sharpness up to 2.0 (an extra RCAS pass); native-resolution TAA mode.
Launcher, mods, patches
- English launcher (follows the system language), loose-file mods with load order,
third-party shadPS4 XML patches, 60/90 FPS patches with pointer slots fixed.
- AppImage: host NVIDIA Vulkan driver support, MangoHud, no FSR 4.1.1 models
(BB_PACKAGE_FSR411=1 bundles local ones).
Tools: route recording/replay (F9), consecutive frame dumps, scene scaling diagnostics.
Details: docs/CHANGES_2026-10-02.md, docs/CHANGES_2026-10-03.md.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- Layout: src/ (loader, runtime), scripts/ (image preparation, patch compiler),
tests/, tools/ (developer tools, fetch_fsr4_assets.sh, bridge helper,
diagnostics), docs/history/ (dated reports); build.sh, run.sh, CMake,
packaging, tools and tests follow the new paths. Raw run log removed.
- Submodules: FSR-Vulkan points at upstream c64f093 and build.sh applies
gpu/patches/fsr-vulkan to its working tree; LibAtrac9 registered in
.gitmodules; build.sh initializes missing submodules.
- No absolute home paths in scripts; the desktop entry is a template
installed by launcher/install-desktop.sh.
- Launcher: the save folder is chosen with a folder dialog (default shown,
reset, open in the file manager), status icons that exist in Adwaita,
upscaler asset status for FSR 4 / 4.1.1.
- README.md / README.ru.md: what it is, status, highlights, differences from
shadPS4, build/run, assets, layout, roadmap, credits. LICENSE: GPL-2.0.
- tests/test_probe.py: expectations updated to the loader's current messages.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- Menu, bbport.ini and launcher: "FSR 4.1.1 (INT8)" next to FSR 4 v07; same
placement and settings (BbSettings::IsFsr4). vk_fsr4.cpp records it through
fsr411/ (assets: BB_FSR411_DIR or fsr4_411), guarding its constant ring with
the scheduler's ticks. The device enables VK_VALVE_shader_mixed_float_dot_product.
- postpass_lds.py rewrites the 4.1.1 postpass at the SPIR-V assembly level
(the GLSL round trip is not exact): 32x32 block through workgroup memory,
2.18 -> 0.95 ms at 4K, still bit-exact with the DLL (verify.sh).
- fsr411: BB_FSR4_PROFILE pass timings; DLL-exact inv_scale (1 / scale).
- build_assets.sh: dxil-spirv (pinned, patched), fsr4cap.exe (MinGW), captures
under umu-run, extraction; noise test runs record into noise_capture_*.
4K Balanced in the game: upscaler 4.12 ms (v07 optimized: 4.32 ms).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
tools/fsr4cap: fsr4cap.exe (MinGW) runs AMD's 4.1.1 upscaler DLL through the
FidelityFX API on D3D12 under umu-run/Proton and records every dispatch by
patching the D3D12 vtables (pipelines, root signatures, descriptors, uploads,
constants). capture_all.sh records 1080p..2160p and all quality ratios;
extract.py translates the 29 passes per (tier, model) with dxil-spirv
(+ --class-bindings, patch included; --mixed-float-dot-product as vkd3d-proton)
and checks the replay rules against every capture.
fsr411/fsr411.cpp: plain-Vulkan replay (reflection, push descriptors, roles by
resource name, constants as the DLL computes them). fsr4-bench --fsr411 runs
it; verify.sh compares it with the DLL on the same inputs: bit-exact over 8
frames for 1080p, 1440p, 2560x1080 and 2160p, both models. 1600x900 differs
only where the DLL itself races (right edge).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Model pass 11 lets invocations past its 480-pixel input width (the
dispatch rounds up to 64) write output pixels 960..1023, which are the
first pixels of the next row: a race that made the 1080 tier's output
differ from run to run in a strip at the left edge. fsr4_pass11_guard.pl
returns early for them; fsr4_optimize.sh builds it for every preset into
fsr4_shaders/opt, and every pass is now loaded from opt/ when present.
The signed int8 unpack fix for spirv-cross output is shared
(Fsr4SpirvCrossFixes.pm) and covers all forms. fsr4_verify.sh: bit-exact
at 1440p/2160p, deterministic at 1080p.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The v07 post pass stores each 2x2 block into three images one pixel at a
time; collecting the workgroup's 16x16 block in shared memory and storing
contiguous rows makes it 3.5x faster on RDNA3, bit-exact with the original
(tools/fsr4_verify.sh). tools/fsr4_optimize.sh builds the variants into
fsr4_shaders/opt (spirv-cross -> fsr4_post_lds.pl -> glslang), run.sh and
fetch_fsr4_assets.sh call it, vk_fsr4.cpp prefers them (BB_FSR4_OPT=0 off).
out/gpu/fsr4-bench runs FSR 4 outside the game; the provider (submodule,
local branch, patch in gpu/patches/fsr-vulkan) gains BB_FSR4_PROFILE and
BB_FSR4_STATS. No reactive mask work when FSR 4 is used.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The UI pass was matched against the exact BB_RENDER_RES size, but the game
allocates its targets with an aligned height (1916x1080 for 1916x1078), so
RunScaled never ran: the jittered scene was shown stretched, without any
temporal resolve (flicker and shaking). Accept the alignment and take the
scene size from the scene constants.
RunScaled also created new image views every frame, which filled FSR 4's
eight-entry registry; use the cached views as Run does.
BB_DUMP_TRIGGER dumps the upscaler's input, motion vectors and output of a
few frames for offline checks. tools/restart.sh: line-buffered log.
Co-Authored-By: Claude Opus 5.5 <[email protected]>