Add an additional flag fo 'XFB Copy'
This commit is contained in:
parent
65cd085f9b
commit
2cd9565b18
|
@ -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
|
// 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),
|
// 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.
|
// 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()->EndRenderPass();
|
||||||
StateTracker::GetInstance()->SetPendingRebind();
|
StateTracker::GetInstance()->SetPendingRebind();
|
||||||
|
|
|
@ -158,7 +158,7 @@ void TextureCacheBase::Cleanup(int _frameCount)
|
||||||
}
|
}
|
||||||
else if (_frameCount > TEXTURE_KILL_THRESHOLD + iter->second->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
|
// Only remove EFB copies when they wouldn't be used anymore(changed hash), because EFB
|
||||||
// copies living on the
|
// 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->SetDimensions(entry->native_width, entry->native_height, 1);
|
||||||
decoded_entry->SetHashes(entry->base_hash, entry->hash);
|
decoded_entry->SetHashes(entry->base_hash, entry->hash);
|
||||||
decoded_entry->frameCount = FRAMECOUNT_INVALID;
|
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;
|
decoded_entry->may_have_overlapping_textures = entry->may_have_overlapping_textures;
|
||||||
|
|
||||||
ConvertTexture(decoded_entry, entry, palette, tlutfmt);
|
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
|
// 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.
|
// 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;
|
return entry_to_update;
|
||||||
|
|
||||||
u32 block_width = TexDecoder_GetBlockWidthInTexels(entry_to_update->format.texfmt);
|
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)
|
while (iter.first != iter.second)
|
||||||
{
|
{
|
||||||
TCacheEntry* entry = iter.first->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->references.count(entry_to_update) == 0 &&
|
||||||
entry->OverlapsMemoryRange(entry_to_update->addr, entry_to_update->size_in_bytes) &&
|
entry->OverlapsMemoryRange(entry_to_update->addr, entry_to_update->size_in_bytes) &&
|
||||||
entry->memory_stride == numBlocksX * block_size)
|
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.
|
// 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.
|
// 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)
|
entry->memory_stride == entry->BytesPerRow() && !entry->may_have_overlapping_textures)
|
||||||
{
|
{
|
||||||
// EFB copies have slightly different rules as EFB copy formats have different
|
// 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
|
else
|
||||||
{
|
{
|
||||||
// For normal textures, all texture parameters need to match
|
// 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_levels >= tex_levels && entry->native_width == nativeW &&
|
||||||
entry->native_height == nativeH)
|
entry->native_height == nativeH)
|
||||||
{
|
{
|
||||||
|
@ -844,7 +845,7 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::GetTexture(u32 address, u32 wid
|
||||||
// Example: Sonic the Fighters (inside Sonic Gems Collection)
|
// Example: Sonic the Fighters (inside Sonic Gems Collection)
|
||||||
// Skip EFB copies here, so they can be used for partial texture updates
|
// Skip EFB copies here, so they can be used for partial texture updates
|
||||||
if (entry->frameCount != FRAMECOUNT_INVALID && entry->frameCount < temp_frameCount &&
|
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;
|
temp_frameCount = entry->frameCount;
|
||||||
oldest_entry = iter;
|
oldest_entry = iter;
|
||||||
|
@ -1016,9 +1017,9 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::GetTexture(u32 address, u32 wid
|
||||||
entry->SetGeneralParameters(address, texture_size, full_format, false);
|
entry->SetGeneralParameters(address, texture_size, full_format, false);
|
||||||
entry->SetDimensions(nativeW, nativeH, tex_levels);
|
entry->SetDimensions(nativeW, nativeH, tex_levels);
|
||||||
entry->SetHashes(base_hash, full_hash);
|
entry->SetHashes(base_hash, full_hash);
|
||||||
entry->is_efb_copy = false;
|
|
||||||
entry->is_custom_tex = hires_tex != nullptr;
|
entry->is_custom_tex = hires_tex != nullptr;
|
||||||
entry->memory_stride = entry->BytesPerRow();
|
entry->memory_stride = entry->BytesPerRow();
|
||||||
|
entry->SetNotCopy();
|
||||||
|
|
||||||
std::string basename = "";
|
std::string basename = "";
|
||||||
if (g_ActiveConfig.bDumpTextures && !hires_tex)
|
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->SetDimensions(tex_w, tex_h, 1);
|
||||||
|
|
||||||
entry->frameCount = FRAMECOUNT_INVALID;
|
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->may_have_overlapping_textures = false;
|
||||||
entry->is_custom_tex = false;
|
entry->is_custom_tex = false;
|
||||||
|
|
||||||
|
@ -1727,9 +1736,10 @@ u32 TextureCacheBase::TCacheEntry::NumBlocksY() const
|
||||||
return actualHeight / blockH;
|
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;
|
memory_stride = stride;
|
||||||
|
|
||||||
_assert_msg_(VIDEO, memory_stride >= BytesPerRow(), "Memory stride is too small");
|
_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();
|
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
|
int TextureCacheBase::TCacheEntry::HashSampleSize() const
|
||||||
{
|
{
|
||||||
if (should_force_safe_hashing)
|
if (should_force_safe_hashing)
|
||||||
|
|
|
@ -85,6 +85,7 @@ public:
|
||||||
bool has_arbitrary_mips = false; // indicates that the mips in this texture are arbitrary
|
bool has_arbitrary_mips = false; // indicates that the mips in this texture are arbitrary
|
||||||
// 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;
|
||||||
|
|
||||||
unsigned int native_width,
|
unsigned int native_width,
|
||||||
native_height; // Texture dimensions from the GameCube's point of view
|
native_height; // Texture dimensions from the GameCube's point of view
|
||||||
|
@ -137,11 +138,15 @@ public:
|
||||||
other_entry->references.emplace(this);
|
other_entry->references.emplace(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetXfbCopy(u32 stride);
|
||||||
void SetEfbCopy(u32 stride);
|
void SetEfbCopy(u32 stride);
|
||||||
|
void SetNotCopy();
|
||||||
|
|
||||||
bool OverlapsMemoryRange(u32 range_address, u32 range_size) const;
|
bool OverlapsMemoryRange(u32 range_address, u32 range_size) const;
|
||||||
|
|
||||||
bool IsEfbCopy() const { return is_efb_copy; }
|
bool IsEfbCopy() const { return is_efb_copy; }
|
||||||
|
bool IsCopy() const { return is_xfb_copy || is_efb_copy; }
|
||||||
|
|
||||||
u32 NumBlocksY() const;
|
u32 NumBlocksY() const;
|
||||||
u32 BytesPerRow() const;
|
u32 BytesPerRow() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue