Make efb2tex behave more like efb2ram.

Instead of having special case code for efb2tex that ignores hashes,
the only diffence between efb2tex and efb2ram now is that efb2tex
writes zeros to the memory instead of actual texture data.

Though keep in mind, all efb2tex copies will have hashes of zero as
their hash.
This commit is contained in:
Scott Mansell 2015-09-06 02:03:49 +12:00
parent c08a83a5aa
commit ee649c6d9f
4 changed files with 32 additions and 25 deletions

View File

@ -237,10 +237,10 @@ void TextureCache::TCacheEntry::FromRenderTarget(u8* dst, unsigned int dstFormat
g_renderer->RestoreAPIState(); g_renderer->RestoreAPIState();
if (!g_ActiveConfig.bSkipEFBCopyToRam) if (g_ActiveConfig.bSkipEFBCopyToRam)
{ this->Zero(dst);
else
g_encoder->Encode(dst, this, srcFormat, srcRect, isIntensity, scaleByHalf); g_encoder->Encode(dst, this, srcFormat, srcRect, isIntensity, scaleByHalf);
}
} }
const char palette_shader[] = const char palette_shader[] =

View File

@ -262,7 +262,11 @@ void TextureCache::TCacheEntry::FromRenderTarget(u8* dstPointer, unsigned int ds
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
if (!g_ActiveConfig.bSkipEFBCopyToRam) if (g_ActiveConfig.bSkipEFBCopyToRam)
{
this->Zero(dstPointer);
}
else
{ {
TextureConverter::EncodeToRamFromTexture( TextureConverter::EncodeToRamFromTexture(
dstPointer, dstPointer,

View File

@ -439,11 +439,9 @@ TextureCache::TCacheEntryBase* TextureCache::Load(const u32 stage)
TCacheEntryBase* entry = iter->second; TCacheEntryBase* entry = iter->second;
if (entry->IsEfbCopy()) if (entry->IsEfbCopy())
{ {
// EFB copies have slightly different rules: the hash doesn't need to match // EFB copies have slightly different rules as EFB copy formats have different
// in EFB2Tex mode, and EFB copy formats have different meanings from texture // meanings from texture formats.
// formats. if (tex_hash == entry->hash && (!isPaletteTexture || g_Config.backend_info.bSupportsPaletteConversion))
if (g_ActiveConfig.bSkipEFBCopyToRam ||
(tex_hash == entry->hash && (!isPaletteTexture || g_Config.backend_info.bSupportsPaletteConversion)))
{ {
// TODO: We should check format/width/height/levels for EFB copies. Checking // TODO: We should check format/width/height/levels for EFB copies. Checking
// format is complicated because EFB copy formats don't exactly match // format is complicated because EFB copy formats don't exactly match
@ -986,12 +984,14 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
unsigned int scaled_tex_h = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledY(tex_h) : tex_h; unsigned int scaled_tex_h = g_ActiveConfig.bCopyEFBScaled ? Renderer::EFBToScaledY(tex_h) : tex_h;
// remove all texture cache entries at dstAddr // remove all texture cache entries at dstAddr
{
std::pair<TexCache::iterator, TexCache::iterator> iter_range = textures_by_address.equal_range((u64)dstAddr); std::pair<TexCache::iterator, TexCache::iterator> iter_range = textures_by_address.equal_range((u64)dstAddr);
TexCache::iterator iter = iter_range.first; TexCache::iterator iter = iter_range.first;
while (iter != iter_range.second) while (iter != iter_range.second)
{ {
iter = FreeTexture(iter); iter = FreeTexture(iter);
} }
}
// create the texture // create the texture
TCacheEntryConfig config; TCacheEntryConfig config;
@ -1012,26 +1012,19 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
entry->FromRenderTarget(dst, dstFormat, dstStride, srcFormat, srcRect, isIntensity, scaleByHalf, cbufid, colmat); entry->FromRenderTarget(dst, dstFormat, dstStride, srcFormat, srcRect, isIntensity, scaleByHalf, cbufid, colmat);
if (!g_ActiveConfig.bSkipEFBCopyToRam)
{
entry->hash = GetHash64(dst, (int)entry->size_in_bytes, g_ActiveConfig.iSafeTextureCache_ColorSamples); entry->hash = GetHash64(dst, (int)entry->size_in_bytes, g_ActiveConfig.iSafeTextureCache_ColorSamples);
// Invalidate all textures that overlap the range of our texture // Invalidate all textures that overlap the range of our texture
TexCache::iterator {
iter = textures_by_address.begin(); TexCache::iterator iter = textures_by_address.begin();
while (iter != textures_by_address.end()) while (iter != textures_by_address.end())
{ {
if (iter->second->OverlapsMemoryRange(dstAddr, entry->size_in_bytes)) if (iter->second->OverlapsMemoryRange(dstAddr, entry->size_in_bytes))
{
iter = FreeTexture(iter); iter = FreeTexture(iter);
}
else else
{
++iter; ++iter;
} }
} }
}
if (g_ActiveConfig.bDumpEFBTarget) if (g_ActiveConfig.bDumpEFBTarget)
{ {
@ -1110,3 +1103,13 @@ void TextureCache::TCacheEntryBase::SetEfbCopy(u32 stride)
size_in_bytes = memory_stride * NumBlocksY(); size_in_bytes = memory_stride * NumBlocksY();
} }
// Fill gamecube memory backing this texture with zeros.
void TextureCache::TCacheEntryBase::Zero(u8* ptr)
{
for (u32 i = 0; i < NumBlocksY(); i++)
{
memset(ptr, 0, CacheLinesPerRow() * 32);
ptr += memory_stride;
}
}

View File

@ -111,7 +111,7 @@ public:
u32 NumBlocksY() const; u32 NumBlocksY() const;
u32 CacheLinesPerRow() const; u32 CacheLinesPerRow() const;
void Memset(u8* ptr, u32 tag); void Zero(u8* ptr);
}; };
virtual ~TextureCache(); // needs virtual for DX11 dtor virtual ~TextureCache(); // needs virtual for DX11 dtor