From 56d153f54865ad22816e01e9353327cc0301f41c Mon Sep 17 00:00:00 2001 From: Markus Wick Date: Sat, 23 Dec 2017 12:44:01 +0100 Subject: [PATCH] VideoCommon: Apply the yscale as upscaling of the XFB. --- Source/Core/VideoCommon/BPStructs.cpp | 14 +++---- Source/Core/VideoCommon/TextureCacheBase.cpp | 39 +++++++++++++------- Source/Core/VideoCommon/TextureCacheBase.h | 6 +-- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index 8909823b7a..609f82903a 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -229,9 +229,9 @@ static void BPWritten(const BPCmd& bp) // bpmem.zcontrol.pixel_format to PEControl::Z24 is when the game wants to copy from ZBuffer // (Zbuffer uses 24-bit Format) bool is_depth_copy = bpmem.zcontrol.pixel_format == PEControl::Z24; - g_texture_cache->CopyRenderTargetToTexture(destAddr, PE_copy.tp_realFormat(), destStride, - is_depth_copy, srcRect, !!PE_copy.intensity_fmt, - !!PE_copy.half_scale, 1.0f, 1.0f); + g_texture_cache->CopyRenderTargetToTexture( + destAddr, PE_copy.tp_realFormat(), srcRect.GetWidth(), srcRect.GetHeight(), destStride, + is_depth_copy, srcRect, !!PE_copy.intensity_fmt, !!PE_copy.half_scale, 1.0f, 1.0f); } else { @@ -250,8 +250,6 @@ static void BPWritten(const BPCmd& bp) float num_xfb_lines = 1.0f + bpmem.copyTexSrcWH.y * yScale; - srcRect.bottom = static_cast(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 | " @@ -260,9 +258,9 @@ static void BPWritten(const BPCmd& bp) 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, - is_depth_copy, srcRect, false, false, yScale, - s_gammaLUT[PE_copy.gamma]); + g_texture_cache->CopyRenderTargetToTexture(destAddr, EFBCopyFormat::XFB, srcRect.GetWidth(), + height, destStride, is_depth_copy, srcRect, false, + false, yScale, s_gammaLUT[PE_copy.gamma]); // This stays in to signal end of a "frame" g_renderer->RenderToXFB(destAddr, srcRect, destStride, height, s_gammaLUT[PE_copy.gamma]); diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 0a8ec009b5..36e1328a92 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -1494,8 +1494,8 @@ void TextureCacheBase::LoadTextureLevelZeroFromMemory(TCacheEntry* entry_to_upda } } -void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstFormat, - u32 dstStride, bool is_depth_copy, +void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstFormat, u32 width, + u32 height, u32 dstStride, bool is_depth_copy, const EFBRectangle& srcRect, bool isIntensity, bool scaleByHalf, float y_scale, float gamma) { @@ -1575,12 +1575,29 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstF return; } - const unsigned int tex_w = scaleByHalf ? srcRect.GetWidth() / 2 : srcRect.GetWidth(); - const unsigned int tex_h = scaleByHalf ? srcRect.GetHeight() / 2 : srcRect.GetHeight(); + // tex_w and tex_h are the native size of the texture in the GC memory. + // The size scaled_* represents the emulated texture. Those differ + // because of upscaling and because of yscaling of XFB copies. + // For the latter, we keep the EFB resolution for the virtual XFB blit. + u32 tex_w = width; + u32 tex_h = height; + u32 scaled_tex_w = g_renderer->EFBToScaledX(srcRect.GetWidth()); + u32 scaled_tex_h = g_renderer->EFBToScaledY(srcRect.GetHeight()); - const bool upscale = is_xfb_copy || g_ActiveConfig.bCopyEFBScaled; - unsigned int scaled_tex_w = upscale ? g_renderer->EFBToScaledX(tex_w) : tex_w; - unsigned int scaled_tex_h = upscale ? g_renderer->EFBToScaledY(tex_h) : tex_h; + if (scaleByHalf) + { + tex_w /= 2; + tex_h /= 2; + scaled_tex_w /= 2; + scaled_tex_h /= 2; + } + + if (!is_xfb_copy && !g_ActiveConfig.bCopyEFBScaled) + { + // No upscaling + scaled_tex_w = tex_w; + scaled_tex_h = tex_h; + } // Get the base (in memory) format of this efb copy. TextureFormat baseFormat = TexDecoder_GetEFBCopyBaseFormat(dstFormat); @@ -1739,13 +1756,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstF entry->may_have_overlapping_textures = false; entry->is_custom_tex = false; - // 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); + CopyEFBToCacheEntry(entry, is_depth_copy, srcRect, scaleByHalf, dstFormat, isIntensity); u64 hash = entry->CalculateHash(); entry->SetHashes(hash, hash); diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index 8b4562227e..6dce346c24 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -246,9 +246,9 @@ public: void LoadTextureLevelZeroFromMemory(TCacheEntry* entry_to_update, const TextureLookupInformation& tex_info, bool decode_on_gpu); virtual void BindTextures(); - void CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstFormat, u32 dstStride, - bool is_depth_copy, const EFBRectangle& srcRect, bool isIntensity, - bool scaleByHalf, float y_scale, float gamma); + void CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstFormat, u32 width, u32 height, + u32 dstStride, bool is_depth_copy, const EFBRectangle& srcRect, + bool isIntensity, bool scaleByHalf, float y_scale, float gamma); virtual void ConvertTexture(TCacheEntry* entry, TCacheEntry* unconverted, const void* palette, TLUTFormat format) = 0;