From e1332b1d7ed4696a4a727906bce62689b8eb329c Mon Sep 17 00:00:00 2001 From: iwubcode Date: Thu, 21 Dec 2017 11:22:46 -0600 Subject: [PATCH] Texture Cache Base: Move PAL vertical scaling to be baked into the texture size. This saves on a number of multiplications and fixes an issue where we were multiplying the y-scaling factor by the srcRectangle's height + 1 which was causing a crash in some GC titles --- Source/Core/VideoCommon/BPStructs.cpp | 6 ++-- Source/Core/VideoCommon/TextureCacheBase.cpp | 33 ++++++++++---------- Source/Core/VideoCommon/TextureCacheBase.h | 1 - 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index 108a478035..2e79db8477 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -252,12 +252,14 @@ static void BPWritten(const BPCmd& bp) float num_xfb_lines = 1.0f + bpmem.copyTexSrcWH.y * yScale; + srcRect.bottom = (int)(bpmem.copyTexSrcXY.y + num_xfb_lines); + u32 height = static_cast(num_xfb_lines); DEBUG_LOG(VIDEO, "RenderToXFB: destAddr: %08x | srcRect {%d %d %d %d} | fbWidth: %u | " - "fbStride: %u | fbHeight: %u", + "fbStride: %u | fbHeight: %u | yScale: %f", destAddr, srcRect.left, srcRect.top, srcRect.right, srcRect.bottom, - bpmem.copyTexSrcWH.x + 1, destStride, height); + bpmem.copyTexSrcWH.x + 1, destStride, height, yScale); bool is_depth_copy = bpmem.zcontrol.pixel_format == PEControl::Z24; g_texture_cache->CopyRenderTargetToTexture(destAddr, EFBCopyFormat::XFB, destStride, diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 1e63aa36e9..0a8ec009b5 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -1250,8 +1250,7 @@ TextureCacheBase::GetXFBFromCache(const TextureLookupInformation& tex_info) if ((entry->is_xfb_copy || entry->format.texfmt == TextureFormat::XFB) && entry->native_width == tex_info.native_width && - static_cast(entry->native_height * entry->y_scale) == - tex_info.native_height && + entry->native_height == tex_info.native_height && entry->memory_stride == entry->BytesPerRow() && !entry->may_have_overlapping_textures) { if (tex_info.base_hash == entry->hash && !entry->reference_changed) @@ -1340,21 +1339,18 @@ bool TextureCacheBase::LoadTextureFromOverlappingTextures(TCacheEntry* entry_to_ u32 copy_width = std::min(entry->native_width - src_x, entry_to_update->native_width - dst_x); u32 copy_height = - std::min((entry->native_height * entry->y_scale) - src_y, - (entry_to_update->native_height * entry_to_update->y_scale) - dst_y); + std::min(entry->native_height - src_y, entry_to_update->native_height - dst_y); // If one of the textures is scaled, scale both with the current efb scaling factor if (entry_to_update->native_width != entry_to_update->GetWidth() || - (entry_to_update->native_height * entry_to_update->y_scale) != - entry_to_update->GetHeight() || - entry->native_width != entry->GetWidth() || - (entry->native_height * entry->y_scale) != entry->GetHeight()) + entry_to_update->native_height != entry_to_update->GetHeight() || + entry->native_width != entry->GetWidth() || entry->native_height != entry->GetHeight()) { - ScaleTextureCacheEntryTo( - entry_to_update, g_renderer->EFBToScaledX(entry_to_update->native_width), - g_renderer->EFBToScaledY(entry_to_update->native_height * entry_to_update->y_scale)); + ScaleTextureCacheEntryTo(entry_to_update, + g_renderer->EFBToScaledX(entry_to_update->native_width), + g_renderer->EFBToScaledY(entry_to_update->native_height)); ScaleTextureCacheEntryTo(entry, g_renderer->EFBToScaledX(entry->native_width), - g_renderer->EFBToScaledY(entry->native_height * entry->y_scale)); + g_renderer->EFBToScaledY(entry->native_height)); src_x = g_renderer->EFBToScaledX(src_x); src_y = g_renderer->EFBToScaledY(src_y); @@ -1593,7 +1589,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstF const u32 blockW = TexDecoder_GetBlockWidthInTexels(baseFormat); // Round up source height to multiple of block size - u32 actualHeight = Common::AlignUp(static_cast(tex_h * y_scale), blockH); + u32 actualHeight = Common::AlignUp(tex_h, blockH); const u32 actualWidth = Common::AlignUp(tex_w, blockW); u32 num_blocks_y = actualHeight / blockH; @@ -1728,7 +1724,6 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstF { entry->SetGeneralParameters(dstAddr, 0, baseFormat, is_xfb_copy); entry->SetDimensions(tex_w, tex_h, 1); - entry->y_scale = y_scale; entry->gamma = gamma; entry->frameCount = FRAMECOUNT_INVALID; @@ -1744,7 +1739,13 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstF entry->may_have_overlapping_textures = false; entry->is_custom_tex = false; - CopyEFBToCacheEntry(entry, is_depth_copy, srcRect, scaleByHalf, dstFormat, isIntensity); + // For XFB, the resulting XFB copy texture is the height of the actual texture + the y-scaling + // however, the actual Wii/GC texture that we want to "stretch" to this copy is without the + // y-scaling so we need to remove it here + // The best use-case for this is PAL games which have a different aspect ratio + EFBRectangle unscaled_rect = srcRect; + unscaled_rect.bottom /= y_scale; + CopyEFBToCacheEntry(entry, is_depth_copy, unscaled_rect, scaleByHalf, dstFormat, isIntensity); u64 hash = entry->CalculateHash(); entry->SetHashes(hash, hash); @@ -1933,7 +1934,7 @@ u32 TextureCacheBase::TCacheEntry::NumBlocksY() const { u32 blockH = TexDecoder_GetBlockHeightInTexels(format.texfmt); // Round up source height to multiple of block size - u32 actualHeight = Common::AlignUp(static_cast(native_height * y_scale), blockH); + u32 actualHeight = Common::AlignUp(native_height, blockH); return actualHeight / blockH; } diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index 65ccd4196d..8b4562227e 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -126,7 +126,6 @@ public: // content, aren't just downscaled bool should_force_safe_hashing = false; // for XFB bool is_xfb_copy = false; - float y_scale = 1.0f; float gamma = 1.0f; u64 id;