fix(upscaler): UI mask draws write the UI's output-size stencil

Scaleform masks are drawn with color writes off, so they reached the UI
composition without a color target and stayed in the game-size depth. The
next UI draw switched to the output-size UI depth, whose stencil
PrepareUiDepth clears, and the mask was gone: images cut out through a mask
(the loading screen's item picture) vanished at output sizes other than
1080p.

The frame generation HUD-less capture is unaffected: it runs in the
!Scaled() path before ui_phase, and the new branch only applies in ui_phase.

From bmy/bbport-mac e4f7d33

(cherry picked from commit 55b4a0d7247ec05dafc0d40643a2a146869c9531)
This commit is contained in:
0xCydral authored and ayozetr committed 2026-10-11 16:50:59 +01:00
1 parent 1bc4f37504
commit d0318b1ab5
1 file changed
+16
@@ -1471,6 +1471,22 @@ void TemporalUpscaler::OnDraw(u64 vs_hash, VideoCore::ImageId color,
}
return;
}
// bbport: a UI draw without a color target (a Scaleform mask: color writes off) writes the
// stencil that the UI's next draws test. It must go into the UI's output-size depth like
// them: drawn into the guest depth, the mask was lost when the next UI draw switched to the
// UI depth (PrepareUiDepth clears its stencil), and masked images (the loading screen's item
// picture, cut out of a sheet of item pictures) vanished.
if (ui_phase && !color && depth && depth != ui_depth && ui_color) {
const auto& depth_image = texture_cache.GetImage(depth);
const auto& ui_target = texture_cache.GetImage(ui_color);
if (depth_image.info.size.width == ui_target.info.size.width &&
depth_image.info.size.height == ui_target.info.size.height) {
EnsureUiResources(ui_width, ui_height, ui_format, depth_image.info.pixel_format);
PrepareUiDepth(depth);
ui_depth = depth;
}
return;
}
if (!Scaled() || !color) {
return;
}