diff options
| author | Duck912 <350528965+Duck912@users.noreply.github.com> | 2026-11-01 21:42:54 -0500 |
|---|---|---|
| committer | Duck912 <350528965+Duck912@users.noreply.github.com> | 2026-11-01 21:54:48 -0500 |
| commit | d125cfb41c0b78b0f4880fac20fab65c913d97e3 (patch) | |
| tree | 3080f9c07e3ef13e8002010e6bb9478becfda0fa /src/video_core | |
| parent | c08b5efbaa4a7a2da78ca4509bec823ad38d5223 (diff) | |
kepler_compute: stand in for Fortune's Weave's DLSS with an upscale
Every 3D frame of Fire Emblem: Fortune's Weave goes through its DLSS
network, which the HMMA lowering cannot run, so its 3D scenes stayed
black. The stand-in written for title 4 (handles at cbuf0+0x90/0xa0)
never matched it. The network's last pass reads the input colour through
cbuf0+0x328 and writes the output through cbuf0+0x348; when title 4's
pair does not fit, blit those instead.
Assisted-by: Claude Opus 5.5 (debugging, implementation and drafting)
Signed-off-by: Duck912 <350528965+Duck912@users.noreply.github.com>
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/engines/kepler_compute.cpp | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index ab2ba10162..233304d273 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.cpp @@ -590,7 +590,9 @@ std::atomic<u32> g_nx2_trace_draws_after_upscale{}; // Title 4's upscaler reads the tonemapped frame through the texture handle at cbuf0+0x90 and // writes the output resolution image through the surface handle at cbuf0+0xa0 (from its -// TLD/SUST operands). Blit one to the other with bilinear filtering when both are plain 2D images +// TLD/SUST operands). Fire Emblem: Fortune's Weave's DLSS network ends with a pass that reads the +// input colour through cbuf0+0x328 and writes the DLSS output through cbuf0+0x348 (B10G11R11; 720p +// to 1440p docked). Blit one to the other with bilinear filtering when both are plain 2D images // of the same format and the output is larger. bool KeplerCompute::UpscaleInsteadOfNativeProgram() { const auto& cbuf = launch_description.const_buffer_config[0]; @@ -600,11 +602,18 @@ bool KeplerCompute::UpscaleInsteadOfNativeProgram() { if (tic_index > regs.tic.limit) return std::nullopt; return GetTICEntry(tic_index); }; - const auto input = image(0x90), output = image(0xa0); - if (!input || !output || input->format != output->format || input->Address() == 0 || - output->Address() == 0 || output->Width() <= input->Width() || !input->IsBlockLinear() || - !output->IsBlockLinear()) - return false; + const auto usable = [](const std::optional<Texture::TICEntry>& input, + const std::optional<Texture::TICEntry>& output) { + return input && output && input->format == output->format && input->Address() != 0 && + output->Address() != 0 && output->Width() > input->Width() && input->IsBlockLinear() && + output->IsBlockLinear(); + }; + auto input = image(0x90), output = image(0xa0); + if (!usable(input, output)) { + input = image(0x328); + output = image(0x348); + if (!usable(input, output)) return false; + } using RTFormat = Tegra::RenderTargetFormat; RTFormat format{}; switch (input->format) { |
