Merge pull request #6266 from iwubcode/fix_pal_vertical_scaling
Fix PAL vertical scaling
This commit is contained in:
commit
3daeb6b970
|
@ -214,14 +214,14 @@ static void BPWritten(const BPCmd& bp)
|
||||||
u32 destStride = bpmem.copyMipMapStrideChannels << 5;
|
u32 destStride = bpmem.copyMipMapStrideChannels << 5;
|
||||||
|
|
||||||
EFBRectangle srcRect;
|
EFBRectangle srcRect;
|
||||||
srcRect.left = (int)bpmem.copyTexSrcXY.x;
|
srcRect.left = static_cast<int>(bpmem.copyTexSrcXY.x);
|
||||||
srcRect.top = (int)bpmem.copyTexSrcXY.y;
|
srcRect.top = static_cast<int>(bpmem.copyTexSrcXY.y);
|
||||||
|
|
||||||
// Here Width+1 like Height, otherwise some textures are corrupted already since the native
|
// Here Width+1 like Height, otherwise some textures are corrupted already since the native
|
||||||
// resolution.
|
// resolution.
|
||||||
// TODO: What's the behavior of out of bound access?
|
// TODO: What's the behavior of out of bound access?
|
||||||
srcRect.right = (int)(bpmem.copyTexSrcXY.x + bpmem.copyTexSrcWH.x + 1);
|
srcRect.right = static_cast<int>(bpmem.copyTexSrcXY.x + bpmem.copyTexSrcWH.x + 1);
|
||||||
srcRect.bottom = (int)(bpmem.copyTexSrcXY.y + bpmem.copyTexSrcWH.y + 1);
|
srcRect.bottom = static_cast<int>(bpmem.copyTexSrcXY.y + bpmem.copyTexSrcWH.y + 1);
|
||||||
|
|
||||||
UPE_Copy PE_copy = bpmem.triggerEFBCopy;
|
UPE_Copy PE_copy = bpmem.triggerEFBCopy;
|
||||||
|
|
||||||
|
@ -246,18 +246,20 @@ static void BPWritten(const BPCmd& bp)
|
||||||
|
|
||||||
float yScale;
|
float yScale;
|
||||||
if (PE_copy.scale_invert)
|
if (PE_copy.scale_invert)
|
||||||
yScale = 256.0f / (float)bpmem.dispcopyyscale;
|
yScale = 256.0f / static_cast<float>(bpmem.dispcopyyscale);
|
||||||
else
|
else
|
||||||
yScale = (float)bpmem.dispcopyyscale / 256.0f;
|
yScale = static_cast<float>(bpmem.dispcopyyscale) / 256.0f;
|
||||||
|
|
||||||
float num_xfb_lines = 1.0f + bpmem.copyTexSrcWH.y * yScale;
|
float num_xfb_lines = 1.0f + bpmem.copyTexSrcWH.y * yScale;
|
||||||
|
|
||||||
|
srcRect.bottom = static_cast<int>(bpmem.copyTexSrcXY.y + num_xfb_lines);
|
||||||
|
|
||||||
u32 height = static_cast<u32>(num_xfb_lines);
|
u32 height = static_cast<u32>(num_xfb_lines);
|
||||||
|
|
||||||
DEBUG_LOG(VIDEO, "RenderToXFB: destAddr: %08x | srcRect {%d %d %d %d} | fbWidth: %u | "
|
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,
|
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;
|
bool is_depth_copy = bpmem.zcontrol.pixel_format == PEControl::Z24;
|
||||||
g_texture_cache->CopyRenderTargetToTexture(destAddr, EFBCopyFormat::XFB, destStride,
|
g_texture_cache->CopyRenderTargetToTexture(destAddr, EFBCopyFormat::XFB, destStride,
|
||||||
|
|
|
@ -1250,8 +1250,7 @@ TextureCacheBase::GetXFBFromCache(const TextureLookupInformation& tex_info)
|
||||||
|
|
||||||
if ((entry->is_xfb_copy || entry->format.texfmt == TextureFormat::XFB) &&
|
if ((entry->is_xfb_copy || entry->format.texfmt == TextureFormat::XFB) &&
|
||||||
entry->native_width == tex_info.native_width &&
|
entry->native_width == tex_info.native_width &&
|
||||||
static_cast<unsigned int>(entry->native_height * entry->y_scale) ==
|
entry->native_height == tex_info.native_height &&
|
||||||
tex_info.native_height &&
|
|
||||||
entry->memory_stride == entry->BytesPerRow() && !entry->may_have_overlapping_textures)
|
entry->memory_stride == entry->BytesPerRow() && !entry->may_have_overlapping_textures)
|
||||||
{
|
{
|
||||||
if (tex_info.base_hash == entry->hash && !entry->reference_changed)
|
if (tex_info.base_hash == entry->hash && !entry->reference_changed)
|
||||||
|
@ -1340,21 +1339,18 @@ bool TextureCacheBase::LoadTextureFromOverlappingTextures(TCacheEntry* entry_to_
|
||||||
u32 copy_width =
|
u32 copy_width =
|
||||||
std::min(entry->native_width - src_x, entry_to_update->native_width - dst_x);
|
std::min(entry->native_width - src_x, entry_to_update->native_width - dst_x);
|
||||||
u32 copy_height =
|
u32 copy_height =
|
||||||
std::min((entry->native_height * entry->y_scale) - src_y,
|
std::min(entry->native_height - src_y, entry_to_update->native_height - dst_y);
|
||||||
(entry_to_update->native_height * entry_to_update->y_scale) - dst_y);
|
|
||||||
|
|
||||||
// If one of the textures is scaled, scale both with the current efb scaling factor
|
// 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() ||
|
if (entry_to_update->native_width != entry_to_update->GetWidth() ||
|
||||||
(entry_to_update->native_height * entry_to_update->y_scale) !=
|
entry_to_update->native_height != entry_to_update->GetHeight() ||
|
||||||
entry_to_update->GetHeight() ||
|
entry->native_width != entry->GetWidth() || entry->native_height != entry->GetHeight())
|
||||||
entry->native_width != entry->GetWidth() ||
|
|
||||||
(entry->native_height * entry->y_scale) != entry->GetHeight())
|
|
||||||
{
|
{
|
||||||
ScaleTextureCacheEntryTo(
|
ScaleTextureCacheEntryTo(entry_to_update,
|
||||||
entry_to_update, g_renderer->EFBToScaledX(entry_to_update->native_width),
|
g_renderer->EFBToScaledX(entry_to_update->native_width),
|
||||||
g_renderer->EFBToScaledY(entry_to_update->native_height * entry_to_update->y_scale));
|
g_renderer->EFBToScaledY(entry_to_update->native_height));
|
||||||
ScaleTextureCacheEntryTo(entry, g_renderer->EFBToScaledX(entry->native_width),
|
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_x = g_renderer->EFBToScaledX(src_x);
|
||||||
src_y = g_renderer->EFBToScaledY(src_y);
|
src_y = g_renderer->EFBToScaledY(src_y);
|
||||||
|
@ -1593,7 +1589,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstF
|
||||||
const u32 blockW = TexDecoder_GetBlockWidthInTexels(baseFormat);
|
const u32 blockW = TexDecoder_GetBlockWidthInTexels(baseFormat);
|
||||||
|
|
||||||
// Round up source height to multiple of block size
|
// Round up source height to multiple of block size
|
||||||
u32 actualHeight = Common::AlignUp(static_cast<unsigned int>(tex_h * y_scale), blockH);
|
u32 actualHeight = Common::AlignUp(tex_h, blockH);
|
||||||
const u32 actualWidth = Common::AlignUp(tex_w, blockW);
|
const u32 actualWidth = Common::AlignUp(tex_w, blockW);
|
||||||
|
|
||||||
u32 num_blocks_y = actualHeight / blockH;
|
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->SetGeneralParameters(dstAddr, 0, baseFormat, is_xfb_copy);
|
||||||
entry->SetDimensions(tex_w, tex_h, 1);
|
entry->SetDimensions(tex_w, tex_h, 1);
|
||||||
entry->y_scale = y_scale;
|
|
||||||
entry->gamma = gamma;
|
entry->gamma = gamma;
|
||||||
|
|
||||||
entry->frameCount = FRAMECOUNT_INVALID;
|
entry->frameCount = FRAMECOUNT_INVALID;
|
||||||
|
@ -1744,7 +1739,13 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstF
|
||||||
entry->may_have_overlapping_textures = false;
|
entry->may_have_overlapping_textures = false;
|
||||||
entry->is_custom_tex = 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();
|
u64 hash = entry->CalculateHash();
|
||||||
entry->SetHashes(hash, hash);
|
entry->SetHashes(hash, hash);
|
||||||
|
@ -1933,7 +1934,7 @@ u32 TextureCacheBase::TCacheEntry::NumBlocksY() const
|
||||||
{
|
{
|
||||||
u32 blockH = TexDecoder_GetBlockHeightInTexels(format.texfmt);
|
u32 blockH = TexDecoder_GetBlockHeightInTexels(format.texfmt);
|
||||||
// Round up source height to multiple of block size
|
// Round up source height to multiple of block size
|
||||||
u32 actualHeight = Common::AlignUp(static_cast<unsigned int>(native_height * y_scale), blockH);
|
u32 actualHeight = Common::AlignUp(native_height, blockH);
|
||||||
|
|
||||||
return actualHeight / blockH;
|
return actualHeight / blockH;
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,6 @@ public:
|
||||||
// content, aren't just downscaled
|
// content, aren't just downscaled
|
||||||
bool should_force_safe_hashing = false; // for XFB
|
bool should_force_safe_hashing = false; // for XFB
|
||||||
bool is_xfb_copy = false;
|
bool is_xfb_copy = false;
|
||||||
float y_scale = 1.0f;
|
|
||||||
float gamma = 1.0f;
|
float gamma = 1.0f;
|
||||||
u64 id;
|
u64 id;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue