Add an additional flag fo 'XFB Copy'

This commit is contained in:
iwubcode 2017-06-26 12:06:50 -05:00
parent 65cd085f9b
commit 2cd9565b18
3 changed files with 44 additions and 12 deletions

View file

@ -150,7 +150,7 @@ TextureConverter::GetCommandBufferForTextureConversion(const TextureCache::TCach
// EFB copies can be used as paletted textures as well. For these, we can't assume them to be
// contain the correct data before the frame begins (when the init command buffer is executed),
// so we must convert them at the appropriate time, during the drawing command buffer.
if (src_entry->IsEfbCopy())
if (src_entry->IsCopy())
{
StateTracker::GetInstance()->EndRenderPass();
StateTracker::GetInstance()->SetPendingRebind();

View file

@ -158,7 +158,7 @@ void TextureCacheBase::Cleanup(int _frameCount)
}
else if (_frameCount > TEXTURE_KILL_THRESHOLD + iter->second->frameCount)
{
if (iter->second->IsEfbCopy())
if (iter->second->IsCopy())
{
// Only remove EFB copies when they wouldn't be used anymore(changed hash), because EFB
// copies living on the
@ -243,7 +243,8 @@ TextureCacheBase::ApplyPaletteToEntry(TCacheEntry* entry, u8* palette, TLUTForma
decoded_entry->SetDimensions(entry->native_width, entry->native_height, 1);
decoded_entry->SetHashes(entry->base_hash, entry->hash);
decoded_entry->frameCount = FRAMECOUNT_INVALID;
decoded_entry->is_efb_copy = false;
decoded_entry->should_force_safe_hashing = false;
decoded_entry->SetNotCopy();
decoded_entry->may_have_overlapping_textures = entry->may_have_overlapping_textures;
ConvertTexture(decoded_entry, entry, palette, tlutfmt);
@ -307,7 +308,7 @@ TextureCacheBase::DoPartialTextureUpdates(TCacheEntry* entry_to_update, u8* pale
// EFB copies are excluded from these updates, until there's an example where a game would
// benefit from updating. This would require more work to be done.
if (entry_to_update->IsEfbCopy())
if (entry_to_update->IsCopy())
return entry_to_update;
u32 block_width = TexDecoder_GetBlockWidthInTexels(entry_to_update->format.texfmt);
@ -321,7 +322,7 @@ TextureCacheBase::DoPartialTextureUpdates(TCacheEntry* entry_to_update, u8* pale
while (iter.first != iter.second)
{
TCacheEntry* entry = iter.first->second;
if (entry != entry_to_update && entry->IsEfbCopy() && !entry->tmem_only &&
if (entry != entry_to_update && entry->IsCopy() && !entry->tmem_only &&
entry->references.count(entry_to_update) == 0 &&
entry->OverlapsMemoryRange(entry_to_update->addr, entry_to_update->size_in_bytes) &&
entry->memory_stride == numBlocksX * block_size)
@ -793,7 +794,7 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::GetTexture(u32 address, u32 wid
// Do not load strided EFB copies, they are not meant to be used directly.
// Also do not directly load EFB copies, which were partly overwritten.
if (entry->IsEfbCopy() && entry->native_width == nativeW && entry->native_height == nativeH &&
if (entry->IsCopy() && entry->native_width == nativeW && entry->native_height == nativeH &&
entry->memory_stride == entry->BytesPerRow() && !entry->may_have_overlapping_textures)
{
// EFB copies have slightly different rules as EFB copy formats have different
@ -828,7 +829,7 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::GetTexture(u32 address, u32 wid
else
{
// For normal textures, all texture parameters need to match
if (!entry->IsEfbCopy() && entry->hash == full_hash && entry->format == full_format &&
if (!entry->IsCopy() && entry->hash == full_hash && entry->format == full_format &&
entry->native_levels >= tex_levels && entry->native_width == nativeW &&
entry->native_height == nativeH)
{
@ -844,7 +845,7 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::GetTexture(u32 address, u32 wid
// Example: Sonic the Fighters (inside Sonic Gems Collection)
// Skip EFB copies here, so they can be used for partial texture updates
if (entry->frameCount != FRAMECOUNT_INVALID && entry->frameCount < temp_frameCount &&
!entry->IsEfbCopy() && !(isPaletteTexture && entry->base_hash == base_hash))
!entry->IsCopy() && !(isPaletteTexture && entry->base_hash == base_hash))
{
temp_frameCount = entry->frameCount;
oldest_entry = iter;
@ -1016,9 +1017,9 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::GetTexture(u32 address, u32 wid
entry->SetGeneralParameters(address, texture_size, full_format, false);
entry->SetDimensions(nativeW, nativeH, tex_levels);
entry->SetHashes(base_hash, full_hash);
entry->is_efb_copy = false;
entry->is_custom_tex = hires_tex != nullptr;
entry->memory_stride = entry->BytesPerRow();
entry->SetNotCopy();
std::string basename = "";
if (g_ActiveConfig.bDumpTextures && !hires_tex)
@ -1557,7 +1558,15 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, EFBCopyFormat dstF
entry->SetDimensions(tex_w, tex_h, 1);
entry->frameCount = FRAMECOUNT_INVALID;
entry->SetEfbCopy(dstStride);
if (is_xfb_copy)
{
entry->should_force_safe_hashing = is_xfb_copy;
entry->SetXfbCopy(dstStride);
}
else
{
entry->SetEfbCopy(dstStride);
}
entry->may_have_overlapping_textures = false;
entry->is_custom_tex = false;
@ -1727,9 +1736,10 @@ u32 TextureCacheBase::TCacheEntry::NumBlocksY() const
return actualHeight / blockH;
}
void TextureCacheBase::TCacheEntry::SetEfbCopy(u32 stride)
void TextureCacheBase::TCacheEntry::SetXfbCopy(u32 stride)
{
is_efb_copy = true;
is_efb_copy = false;
is_xfb_copy = true;
memory_stride = stride;
_assert_msg_(VIDEO, memory_stride >= BytesPerRow(), "Memory stride is too small");
@ -1737,6 +1747,23 @@ void TextureCacheBase::TCacheEntry::SetEfbCopy(u32 stride)
size_in_bytes = memory_stride * NumBlocksY();
}
void TextureCacheBase::TCacheEntry::SetEfbCopy(u32 stride)
{
is_efb_copy = true;
is_xfb_copy = false;
memory_stride = stride;
_assert_msg_(VIDEO, memory_stride >= BytesPerRow(), "Memory stride is too small");
size_in_bytes = memory_stride * NumBlocksY();
}
void TextureCacheBase::TCacheEntry::SetNotCopy()
{
is_xfb_copy = false;
is_efb_copy = false;
}
int TextureCacheBase::TCacheEntry::HashSampleSize() const
{
if (should_force_safe_hashing)

View file

@ -85,6 +85,7 @@ public:
bool has_arbitrary_mips = false; // indicates that the mips in this texture are arbitrary
// content, aren't just downscaled
bool should_force_safe_hashing = false; // for XFB
bool is_xfb_copy = false;
unsigned int native_width,
native_height; // Texture dimensions from the GameCube's point of view
@ -137,11 +138,15 @@ public:
other_entry->references.emplace(this);
}
void SetXfbCopy(u32 stride);
void SetEfbCopy(u32 stride);
void SetNotCopy();
bool OverlapsMemoryRange(u32 range_address, u32 range_size) const;
bool IsEfbCopy() const { return is_efb_copy; }
bool IsCopy() const { return is_xfb_copy || is_efb_copy; }
u32 NumBlocksY() const;
u32 BytesPerRow() const;