From fa102f7e83eefa58e201d28ceb6dc3915f93180c Mon Sep 17 00:00:00 2001 From: weakboson Date: Mon, 4 Aug 2025 01:50:06 +0800 Subject: [PATCH] [texture_cache] Enforce conservative 3D texture aliasing. Consistently merge/lookup images. Previously, the merging strategy is permissive but the lookup strategy is strict. Together they create a infinite merge loop because lookup always fails and merges are always executed. The last attempt to fix this issue made the lookup strategy more permissive which created unexpected aliased textures. This commit implements an alternative: make the merging strategy strict. --- src/video_core/texture_cache/texture_cache.h | 1 - src/video_core/texture_cache/util.cpp | 25 +++++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 78b6684c49..6c733fe902 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -1426,7 +1426,6 @@ ImageId TextureCache

::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, DA if (solution) { gpu_addr = solution->gpu_addr; cpu_addr = solution->cpu_addr; - // TODO: properly update new_info.size.depth. new_info.resources = solution->resources; join_overlap_ids.push_back(overlap_id); join_copies_to_do.emplace_back(JoinCopy{false, overlap_id}); diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index 83432dfd35..e3faa5bf95 100644 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Ryujinx Team and Contributors // SPDX-License-Identifier: GPL-2.0-or-later AND MIT @@ -343,7 +346,7 @@ template if (!IsBlockLinearSizeCompatible(new_info, info, base.level, 0, strict_size)) { return std::nullopt; } - const u32 mip_depth = std::max(1U, new_info.size.depth << base.level); + const u32 mip_depth = AdjustMipSize(new_info.size.depth, base.level); if (mip_depth < info.size.depth + base.layer) { return std::nullopt; } @@ -428,8 +431,14 @@ template return std::nullopt; } const SubresourceExtent resources = new_info.resources; - s32 layers = 1; - if (info.type != ImageType::e3D) { + s32 layers; + if (info.type == ImageType::e3D) { + const u32 mip_depth = AdjustMipSize(info.size.depth, base->level); + if (mip_depth < new_info.size.depth + base->layer) { + return std::nullopt; + } + layers = 1; + } else { layers = std::max(resources.layers, info.resources.layers + base->layer); } return OverlapResult{ @@ -1216,10 +1225,10 @@ std::optional FindSubresource(const ImageInfo& candidate, const return std::nullopt; } if (existing.type == ImageType::e3D) { - // const u32 mip_depth = std::max(1U, existing.size.depth << base->level); - // if (mip_depth < candidate.size.depth + base->layer) { - // return std::nullopt; - // } + const u32 mip_depth = AdjustMipSize(existing.size.depth, base->level); + if (mip_depth < candidate.size.depth + base->layer) { + return std::nullopt; + } } else if (existing.resources.layers < candidate.resources.layers + base->layer) { return std::nullopt; } @@ -1247,7 +1256,7 @@ bool IsSubCopy(const ImageInfo& candidate, const ImageBase& image, GPUVAddr cand return false; } if (existing.type == ImageType::e3D) { - const u32 mip_depth = std::max(1U, existing.size.depth << base->level); + const u32 mip_depth = AdjustMipSize(existing.size.depth, base->level); if (mip_depth < candidate.size.depth + base->layer) { return false; }