From 8393e2912616ce475619900be8cb29e551ff2997 Mon Sep 17 00:00:00 2001 From: Takoroka <137927095+Takoroka@users.noreply.github.com> Date: Wed, 28 Oct 2026 15:19:44 -0400 Subject: Fix the P6 scratch save in R2UR/MATCH/HFMA2.RELU; GPU memory dump tool The colour cast on title 1 (magenta/cyan, then red/green, changing per course) came from the sky/atmosphere volume shader (a pixel shader drawing a 32^3 RGBA16F table slice by slice), which starts with an unguarded R2UR. R2UR, MATCH and HFMA2.RELU use P6 as scratch and saved/restored it with the uniform-guard mask, 1 << (6 - 7) for an unguarded instruction: undefined, in practice bit 31, which shifted into the opcode bits and turned the save into another instruction. They now always save and restore P6. Debugging aids used to find it: - EDEN_NX2_DUMP=::,...: flush GPU memory ranges at a present (on the GPU thread) and save them next to the frame captures; nx2work/vol3d.py untiles Switch 2 3D textures from such dumps. - GPU::RunOnGpuThread. - Logs of Switch 2 3D images and descriptors. --- src/video_core/texture_cache/image_info.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/video_core/texture_cache/image_info.cpp') diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp index 8b59eb6841..7e86bf00cf 100644 --- a/src/video_core/texture_cache/image_info.cpp +++ b/src/video_core/texture_cache/image_info.cpp @@ -4,9 +4,13 @@ // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include +#include +#include #include #include "common/assert.h" +#include "common/logging.h" #include "common/settings.h" #include "video_core/surface.h" #include "video_core/texture_cache/format_lookup_table.h" @@ -109,14 +113,23 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept { size.height = config.Height(); resources.layers = config.BaseLayer() + config.Depth() * 6; break; - case TextureType::Texture3D: + case TextureType::Texture3D: { ASSERT(config.BaseLayer() == 0); type = ImageType::e3D; size.width = config.Width(); size.height = config.Height(); size.depth = config.Depth(); resources.layers = 1; + // A few distinct 3D descriptors, raw (to check Switch 2 volume fields). + static std::vector> logged; + if (logged.size() < 16 && std::find(logged.begin(), logged.end(), config.raw) == logged.end()) { + logged.push_back(config.raw); + LOG_INFO(HW_GPU, "3D TIC {:016x} {:016x} {:016x} {:016x}: {}x{}x{} block_depth {} levels {}", + config.raw[0], config.raw[1], config.raw[2], config.raw[3], size.width, size.height, + size.depth, config.block_depth.Value(), config.max_mip_level.Value() + 1); + } break; + } case TextureType::Texture1DBuffer: type = ImageType::Buffer; size.width = config.Width(); -- cgit v1.2.3