diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-28 02:45:00 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-28 02:45:00 -0400 |
| commit | 3e48eedecf91f8f8d0917f8f78ce26a3d0482e5c (patch) | |
| tree | 5a5b4bf2932b7ea0d7467aa8916a37d73600aceb /src/video_core/engines | |
| parent | 585e457172693730fe82f34a2ce513ac7cdc948d (diff) | |
nx2: title 4's cutscene scene renders; blit constants for fragment shaders
- Render area falls back to colour target 0 when the surface clip is unset
(Switch 2 titles may never program it); it feeds the synthesized blit block.
- BlitConstantsPass also covers fragment shaders: UV clamp rectangle 0..1
(0x30-0x3c) and zero dither bias.
- Debug: EDEN_NX2_SKIP_VS=<addr,...>, EDEN_NX2_TRACE_VS=<addr>,
EDEN_NX2_UPSCALE_SOURCE[_FORMAT], EDEN_NX2_TRACE_AFTER_UPSCALE,
EDEN_NX2_SAMPLE_AT, skipped-draw reasons, clear tracing.
Showing the raw HDR scene colour through the upscale fallback gives the
correct lit cockpit scene; the game's tonemap pass still outputs black.
Diffstat (limited to 'src/video_core/engines')
| -rw-r--r-- | src/video_core/engines/kepler_compute.cpp | 55 | ||||
| -rw-r--r-- | src/video_core/engines/kepler_compute.h | 4 |
2 files changed, 54 insertions, 5 deletions
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index 136fcb9dda..85b1f971f7 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.cpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include <algorithm> +#include <atomic> #include <bitset> #include <cstdlib> #include <fstream> @@ -432,6 +433,8 @@ void KeplerCompute::DescribeNativeResources(const NativeQmdScheduler::Descriptor } } +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 @@ -486,7 +489,11 @@ bool KeplerCompute::UpscaleInsteadOfNativeProgram() { .src_y1 = static_cast<s32>(input->Height()), }; // Debug: does the input hold anything? Download it once and count non-zero words. - if (static u32 sampled{}; sampled++ == 20) { + static const u32 sample_at = [] { + const char* value = std::getenv("EDEN_NX2_SAMPLE_AT"); + return value ? static_cast<u32>(std::strtoul(value, nullptr, 10)) : 20U; + }(); + if (static u32 sampled{}; sampled++ == sample_at) { const auto sample = [&](const Texture::TICEntry& tic) { const u64 size = u64{tic.Width()} * tic.Height() * 4; if (const auto device = memory_manager.GpuToCpuAddress(tic.Address())) { @@ -527,12 +534,50 @@ bool KeplerCompute::UpscaleInsteadOfNativeProgram() { (void)fake; } } - const bool done = rasterizer->AccelerateSurfaceCopy(surface(*input), surface(*output), config); + auto source = surface(*input); + // EDEN_NX2_UPSCALE_SOURCE=<gpu address>: blit from another same-sized image (debug aid). + if (static const u64 override_source = [] { + const char* value = std::getenv("EDEN_NX2_UPSCALE_SOURCE"); + return value ? std::strtoull(value, nullptr, 16) : 0ULL; + }(); + override_source != 0) { + source.addr_upper = static_cast<u32>(override_source >> 32); + source.addr_lower = static_cast<u32>(override_source); + if (const char* value = std::getenv("EDEN_NX2_UPSCALE_SOURCE_FORMAT")) { + source.format = static_cast<RTFormat>(std::strtoul(value, nullptr, 16)); + } + } + const bool done = rasterizer->AccelerateSurfaceCopy(source, surface(*output), config); + if (static u32 checked{}; checked++ == sample_at) { + const u64 size = u64{output->Width()} * output->Height() * 4; + if (const auto device = memory_manager.GpuToCpuAddress(output->Address())) { + rasterizer->FlushRegion(*device, size, VideoCommon::CacheType::All); + } + u32 nonzero{}, samples{}, changes{}, last{}; + for (u64 offset = 0; offset < size; offset += 4096 + 4) { + const u32 word = memory_manager.Read<u32>(output->Address() + offset); + ++samples; + nonzero += word != 0; + changes += word != last; + last = word; + } + LOG_INFO(HW_GPU, "Upscale fallback output after blit: {}/{} non-zero, {} changes", nonzero, samples, + changes); + } + // Debug: trace the draws that follow one upscale (EDEN_NX2_RT_TRACE_AFTER_UPSCALE). + static const u32 trace_at = [] { + const char* value = std::getenv("EDEN_NX2_TRACE_AFTER_UPSCALE"); + return value ? static_cast<u32>(std::strtoul(value, nullptr, 10)) : 30U; + }(); + if (static u32 count{}; ++count == trace_at) g_nx2_trace_draws_after_upscale = 40; static u32 logged{}; if (logged++ < 4) { - LOG_INFO(HW_GPU, "Upscale fallback {:#x} {}x{} -> {:#x} {}x{}: {}", input->Address(), - input->Width(), input->Height(), output->Address(), output->Width(), - output->Height(), done ? "blitted" : "not accelerated"); + LOG_INFO(HW_GPU, "Upscale fallback {:#x} {}x{} block {}/{}/{} -> {:#x} {}x{} block {}/{}/{} levels {}: {}", + input->Address(), input->Width(), input->Height(), input->block_width.Value(), + input->block_height.Value(), input->block_depth.Value(), output->Address(), + output->Width(), output->Height(), output->block_width.Value(), + output->block_height.Value(), output->block_depth.Value(), output->max_mip_level.Value(), + done ? "blitted" : "not accelerated"); } return done; } diff --git a/src/video_core/engines/kepler_compute.h b/src/video_core/engines/kepler_compute.h index 3bd41a2dfa..dd69211f7b 100644 --- a/src/video_core/engines/kepler_compute.h +++ b/src/video_core/engines/kepler_compute.h @@ -7,6 +7,7 @@ #pragma once #include <array> +#include <atomic> #include <cstddef> #include <optional> #include <vector> @@ -33,6 +34,9 @@ class RasterizerInterface; namespace Tegra::Engines { +/// Draws left to trace after an upscale fallback (debug aid). +extern std::atomic<u32> g_nx2_trace_draws_after_upscale; + /** * This Engine is known as GK104_Compute. Documentation can be found in: * https://github.com/envytools/envytools/blob/master/rnndb/graph/gk104_compute.xml |
