vulkan: preserve the game aspect when presenting #205

Merged
monsterlag merged 8 commits from fix/preserve-game-aspect into main 2026-11-08 02:44:09 +00:00
monsterlag commented 2026-11-07 15:43:45 +00:00 (Migrated from github.com)

Fixes #119. Refs #297.

Fit the game's source crop into a centered presentation rectangle and clear uncovered areas to black, including frame-generated presents. Preserve the existing camera-aspect override when Ultrawide or HOS_ASPECT is enabled.

This branch retains upstream controller callbacks and appends the aspect callback after them, requiring renderer API4. Deploy the executable and DLL together; the actual renderer rejects null/API3 hosts before loading Vulkan.

Validation:

  • Eleven rectangle/crop/odd-size/override cases pass, including with the new official GNU Clang23.1.5 toolchain. Matching C/C++ API layout and the real DLL's null/API3 rejection pass.
  • A fresh normal lift and complete matching host/API4 renderer build with the no-visual-studio release toolkit passed in 992 seconds, zero failures. This live candidate combines this aspect change and independent-upscaling #417 on release commit e40306e.
  • RTX5090/Windows, isolated checkpoint, 100% game resolution: actual 3840x1080 and 5120x1440 windows each show the Kokiri scene, HUD and centered sidebars with Catmull-Rom/FG off and Lanczos/FG off. Lanczos cases explicitly set RX_VK_FRAMEGEN=0. Successful-dispatch logs confirm requested filters and centered 1920x1080/2560x1440 destinations, with no interpolation initialization.
  • Sharpness-only/FG off and Catmull/FG2 also display correctly. Actual 5120x2160 fullscreen and restoration to3840x1080 preserve the scene/HUD. All six current sessions close normally.
  • Earlier integration checks also cover 16:10 letterboxing, explicit camera-aspect overrides and both filters/FG2 at both32:9 window sizes.

FG-off active-filter testing above includes #417, which fixes an existing independent upscaler bypass; this PR's aspect change does not include that fix or claim to solve the reported RTX4070 black screen.

These are compatibility checks, not native60+FPS evidence. Warm gameplay was roughly48-52FPS at100% resolution. The first cold run sustained11.6-11.8FPS after shader jobs finished and recovered to46-50FPS after F11; the cause remains unexplained and the initial failure is preserved.

The panel is5120x2160, so physical32:9 fullscreen and the reporter's RTX4070 remain unverified. AMD/Intel/Linux runtime, physical audio/controller behavior, wider progression and arbitrary drag/minimize transitions are also untested. No speculative black-screen workaround is included.

Fixes #119. Refs #297. Fit the game's source crop into a centered presentation rectangle and clear uncovered areas to black, including frame-generated presents. Preserve the existing camera-aspect override when Ultrawide or HOS_ASPECT is enabled. This branch retains upstream controller callbacks and appends the aspect callback after them, requiring renderer API4. Deploy the executable and DLL together; the actual renderer rejects null/API3 hosts before loading Vulkan. Validation: - Eleven rectangle/crop/odd-size/override cases pass, including with the new official GNU Clang23.1.5 toolchain. Matching C/C++ API layout and the real DLL's null/API3 rejection pass. - A fresh normal lift and complete matching host/API4 renderer build with the no-visual-studio release toolkit passed in 992 seconds, zero failures. This live candidate combines this aspect change and independent-upscaling #417 on release commit e40306e. - RTX5090/Windows, isolated checkpoint, 100% game resolution: actual 3840x1080 and 5120x1440 windows each show the Kokiri scene, HUD and centered sidebars with Catmull-Rom/FG off and Lanczos/FG off. Lanczos cases explicitly set RX_VK_FRAMEGEN=0. Successful-dispatch logs confirm requested filters and centered 1920x1080/2560x1440 destinations, with no interpolation initialization. - Sharpness-only/FG off and Catmull/FG2 also display correctly. Actual 5120x2160 fullscreen and restoration to3840x1080 preserve the scene/HUD. All six current sessions close normally. - Earlier integration checks also cover 16:10 letterboxing, explicit camera-aspect overrides and both filters/FG2 at both32:9 window sizes. FG-off active-filter testing above includes #417, which fixes an existing independent upscaler bypass; this PR's aspect change does not include that fix or claim to solve the reported RTX4070 black screen. These are compatibility checks, not native60+FPS evidence. Warm gameplay was roughly48-52FPS at100% resolution. The first cold run sustained11.6-11.8FPS after shader jobs finished and recovered to46-50FPS after F11; the cause remains unexplained and the initial failure is preserved. The panel is5120x2160, so physical32:9 fullscreen and the reporter's RTX4070 remain unverified. AMD/Intel/Linux runtime, physical audio/controller behavior, wider progression and arbitrary drag/minimize transitions are also untested. No speculative black-screen workaround is included.
turpcorp commented 2026-11-07 18:19:38 +00:00 (Migrated from github.com)

Tested the same approach on another setup, and found one case where it goes black.

Setup: RTX 4070, 5120x1440 (32:9), Windows 11, fullscreen, the movie-sync build (44abdcd). Frame generation Off, Ultrawide 16:9, Resolution 100%.

I patched only hookshot_vk.dll with essentially the same change as this PR: a centered fit rectangle, a black clear, then the blit into the rectangle.

Upscaling Upscale target Result
Off n/a (blit into the rect) ✅ Correct: 2560x1440 centered, bars both sides
Catmull-Rom framegen_scale(..., rect.w, rect.h), as in this PR ❌ Title screen fine; gameplay all black (sound plays, the save icon shows, ~878 draws/frame in the log)
Catmull-Rom framegen_scale(..., swap_extent.w, swap_extent.h), then blit that into the rect ✅ Correct

Switching Upscaling to Off live in the Insert menu brought the picture back right away, so the black screen comes from upscaling straight to the rectangle's size. I didn't find the root cause. Your 5090 test had frame generation at 2x, and mine had it off, so that may be the difference.

The workaround I'm running upscales at the window's size (as before this PR) and then blits that into the rectangle:

if (const VkImage scaled = src && view ? framegen_scale(f.cmd, view, src, sw, sh, crop, dev.swap_extent.width, dev.swap_extent.height) : VK_NULL_HANDLE) {
    blit_crop_to_rect(f.cmd, scaled, dev.swap_extent.width, dev.swap_extent.height, nullptr, dst,
                      VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, rect);
}

It does extra upscaling work on wide screens, so it's a workaround, not a fix. Happy to test a build or send logs.

Also relevant to #119 (16:10 laptop, stretched in fullscreen).

Tested the same approach on another setup, and found one case where it goes black. **Setup:** RTX 4070, 5120x1440 (32:9), Windows 11, fullscreen, the `movie-sync` build (44abdcd). Frame generation **Off**, Ultrawide 16:9, Resolution 100%. I patched only `hookshot_vk.dll` with essentially the same change as this PR: a centered fit rectangle, a black clear, then the blit into the rectangle. | Upscaling | Upscale target | Result | |---|---|---| | Off | n/a (blit into the rect) | ✅ Correct: 2560x1440 centered, bars both sides | | Catmull-Rom | `framegen_scale(..., rect.w, rect.h)`, as in this PR | ❌ Title screen fine; **gameplay all black** (sound plays, the save icon shows, ~878 draws/frame in the log) | | Catmull-Rom | `framegen_scale(..., swap_extent.w, swap_extent.h)`, then blit that into the rect | ✅ Correct | Switching Upscaling to Off live in the Insert menu brought the picture back right away, so the black screen comes from upscaling straight to the rectangle's size. I didn't find the root cause. Your 5090 test had frame generation at 2x, and mine had it off, so that may be the difference. The workaround I'm running upscales at the window's size (as before this PR) and then blits that into the rectangle: ```cpp if (const VkImage scaled = src && view ? framegen_scale(f.cmd, view, src, sw, sh, crop, dev.swap_extent.width, dev.swap_extent.height) : VK_NULL_HANDLE) { blit_crop_to_rect(f.cmd, scaled, dev.swap_extent.width, dev.swap_extent.height, nullptr, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, rect); } ``` It does extra upscaling work on wide screens, so it's a workaround, not a fix. Happy to test a build or send logs. Also relevant to #119 (16:10 laptop, stretched in fullscreen).
NotRexed commented 2026-11-07 23:08:24 +00:00 (Migrated from github.com)

Thanks, this is a good fix for #119/#297. Before merging: a 32:9 user reported a black picture with upscaling on (see #297). Could you check that case (3840x1080 or 5120x1440 fullscreen with Upscaling Catmull-Rom/Lanczos) and the frame generation path at those sizes? Also, it bumps the renderer API to v2, which #324 also did; that one is closing, so v2 is yours.

Thanks, this is a good fix for #119/#297. Before merging: a 32:9 user reported a black picture with upscaling on (see #297). Could you check that case (3840x1080 or 5120x1440 fullscreen with Upscaling Catmull-Rom/Lanczos) and the frame generation path at those sizes? Also, it bumps the renderer API to v2, which #324 also did; that one is closing, so v2 is yours.
NotRexed commented 2026-11-08 02:44:15 +00:00 (Migrated from github.com)

Merged, thanks! Tested here on a 3440x1440 monitor with a 2580x1080 window: the picture keeps its 16:9 shape with bars at the sides, with Upscaling off and with Lanczos, no black picture. If the 32:9 black case comes back with this, please open an issue with the window size and the Insert menu settings.

Merged, thanks! Tested here on a 3440x1440 monitor with a 2580x1080 window: the picture keeps its 16:9 shape with bars at the sides, with Upscaling off and with Lanczos, no black picture. If the 32:9 black case comes back with this, please open an issue with the window size and the Insert menu settings.
Commenting is not possible because the repository is archived.
No description provided.