From ff57d2fbbfad4dcfbe00d987c3c3873403053276 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Fri, 21 Oct 2022 22:03:13 +0100 Subject: [PATCH] Enforce stronger format and weaker dimension texture compat checks Rather than using just bpb for format compat, additionally check that the exact component bit layout matches since many games end up reusing RTs for unrelated textures. The texture size requirements have also been weaked to only check the resulting layer size as opposed to width/height - this is somewhat hacky but it gets around the problem of blocklinear alignment. --- app/src/main/cpp/skyline/gpu/texture/texture.cpp | 5 +++-- app/src/main/cpp/skyline/gpu/texture/texture.h | 12 ++++++++++-- app/src/main/cpp/skyline/gpu/texture_manager.cpp | 6 +++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.cpp b/app/src/main/cpp/skyline/gpu/texture/texture.cpp index d7b207ff..0bea16db 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.cpp +++ b/app/src/main/cpp/skyline/gpu/texture/texture.cpp @@ -3,8 +3,9 @@ #include #include -#include #include +#include +#include #include "texture.h" #include "layout.h" #include "adreno_aliasing.h" @@ -20,7 +21,7 @@ namespace skyline::gpu { return layerStride; } - u32 GuestTexture::CalculateLayerSize() { + u32 GuestTexture::CalculateLayerSize() const { switch (tileConfig.mode) { case texture::TileMode::Linear: return static_cast(format->GetSize(dimensions)); diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.h b/app/src/main/cpp/skyline/gpu/texture/texture.h index 835f0223..0eb1d42a 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.h +++ b/app/src/main/cpp/skyline/gpu/texture/texture.h @@ -3,6 +3,8 @@ #pragma once +#include +#include #include #include #include @@ -111,7 +113,13 @@ namespace skyline::gpu { * @return If the supplied format is texel-layout compatible with the current format */ constexpr bool IsCompatible(const FormatBase &other) const { - return bpb == other.bpb && blockHeight == other.blockHeight && blockWidth == other.blockWidth; + return vkFormat == other.vkFormat + || (vkFormat == vk::Format::eD32Sfloat && other.vkFormat == vk::Format::eR32Sfloat) + || (vkFormat == vk::Format::eR32Sfloat && other.vkFormat == vk::Format::eD32Sfloat) + || (componentCount(vkFormat) == componentCount(other.vkFormat) && + ranges::all_of(ranges::views::iota(u8{0}, componentCount(vkFormat)), [this, other](auto i) { + return componentBits(vkFormat, i) == componentBits(other.vkFormat, i); + }) && (vkAspect & other.vkAspect) != vk::ImageAspectFlags{}); } /** @@ -279,7 +287,7 @@ namespace skyline::gpu { /** * @brief Calculates the size of a single layer in bytes, unlike `GetLayerStride` the returned layer size is always calculated and may not be equal to the actual layer stride */ - u32 CalculateLayerSize(); + u32 CalculateLayerSize() const; /** * @return The most appropriate backing image type for this texture diff --git a/app/src/main/cpp/skyline/gpu/texture_manager.cpp b/app/src/main/cpp/skyline/gpu/texture_manager.cpp index 7d36b096..303d5e46 100644 --- a/app/src/main/cpp/skyline/gpu/texture_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/texture_manager.cpp @@ -46,9 +46,9 @@ namespace skyline::gpu { // We've gotten a perfect 1:1 match for *all* mappings from the start to end, we just need to check for compatibility aside from this auto &matchGuestTexture{*hostMapping->texture->guest}; if (matchGuestTexture.format->IsCompatible(*guestTexture.format) && - ((matchGuestTexture.dimensions.width == guestTexture.dimensions.width && - matchGuestTexture.dimensions.height == guestTexture.dimensions.height && - matchGuestTexture.GetViewDepth() == guestTexture.GetViewDepth()) + ((((matchGuestTexture.dimensions.width == guestTexture.dimensions.width && + matchGuestTexture.dimensions.height == guestTexture.dimensions.height) || matchGuestTexture.CalculateLayerSize() == guestTexture.CalculateLayerSize()) && + matchGuestTexture.GetViewDepth() <= guestTexture.GetViewDepth()) || matchGuestTexture.viewMipBase > 0) && matchGuestTexture.tileConfig == guestTexture.tileConfig) { auto &texture{hostMapping->texture};