Merge pull request #4224 from lioncash/tcache

TextureCacheBase: Eliminate static state
This commit is contained in:
Mat M
2016-12-23 04:33:42 -05:00
committed by GitHub
21 changed files with 141 additions and 163 deletions

View File

@ -227,9 +227,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)
TextureCacheBase::CopyRenderTargetToTexture(destAddr, PE_copy.tp_realFormat(), destStride,
bpmem.zcontrol.pixel_format, srcRect,
!!PE_copy.intensity_fmt, !!PE_copy.half_scale);
g_texture_cache->CopyRenderTargetToTexture(destAddr, PE_copy.tp_realFormat(), destStride,
bpmem.zcontrol.pixel_format, srcRect,
!!PE_copy.intensity_fmt, !!PE_copy.half_scale);
}
else
{

View File

@ -243,6 +243,6 @@ void VideoBackendBase::CheckInvalidState()
m_invalid = false;
BPReload();
TextureCacheBase::Invalidate();
g_texture_cache->Invalidate();
}
}

View File

@ -108,7 +108,6 @@ static float AspectToWidescreen(float aspect)
Renderer::Renderer()
{
UpdateActiveConfig();
TextureCacheBase::OnConfigChanged(g_ActiveConfig);
OSDChoice = 0;
OSDTime = 0;

View File

@ -45,16 +45,6 @@ static const u64 MAX_TEXTURE_BINARY_SIZE =
std::unique_ptr<TextureCacheBase> g_texture_cache;
alignas(16) u8* TextureCacheBase::temp = nullptr;
size_t TextureCacheBase::temp_size;
TextureCacheBase::TexCache TextureCacheBase::textures_by_address;
TextureCacheBase::TexCache TextureCacheBase::textures_by_hash;
TextureCacheBase::TexPool TextureCacheBase::texture_pool;
TextureCacheBase::TCacheEntryBase* TextureCacheBase::bound_textures[8];
TextureCacheBase::BackupConfig TextureCacheBase::backup_config;
TextureCacheBase::TCacheEntryBase::~TCacheEntryBase()
{
}
@ -71,12 +61,13 @@ void TextureCacheBase::CheckTempSize(size_t required_size)
TextureCacheBase::TextureCacheBase()
{
temp_size = 2048 * 2048 * 4;
if (!temp)
temp = static_cast<u8*>(Common::AllocateAlignedMemory(temp_size, 16));
SetBackupConfig(g_ActiveConfig);
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable,
g_ActiveConfig.bTexFmtOverlayCenter);
temp_size = 2048 * 2048 * 4;
temp = static_cast<u8*>(Common::AllocateAlignedMemory(temp_size, 16));
TexDecoder_SetTexFmtOverlayOptions(backup_config.texfmt_overlay,
backup_config.texfmt_overlay_center);
HiresTexture::Init();
@ -111,42 +102,33 @@ TextureCacheBase::~TextureCacheBase()
void TextureCacheBase::OnConfigChanged(VideoConfig& config)
{
if (g_texture_cache)
if (config.bHiresTextures != backup_config.hires_textures ||
config.bCacheHiresTextures != backup_config.cache_hires_textures)
{
if (config.bHiresTextures != backup_config.s_hires_textures ||
config.bCacheHiresTextures != backup_config.s_cache_hires_textures)
{
HiresTexture::Update();
}
// TODO: Invalidating texcache is really stupid in some of these cases
if (config.iSafeTextureCache_ColorSamples != backup_config.s_colorsamples ||
config.bTexFmtOverlayEnable != backup_config.s_texfmt_overlay ||
config.bTexFmtOverlayCenter != backup_config.s_texfmt_overlay_center ||
config.bHiresTextures != backup_config.s_hires_textures)
{
g_texture_cache->Invalidate();
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable,
g_ActiveConfig.bTexFmtOverlayCenter);
}
if ((config.iStereoMode > 0) != backup_config.s_stereo_3d ||
config.bStereoEFBMonoDepth != backup_config.s_efb_mono_depth)
{
g_texture_cache->DeleteShaders();
if (!g_texture_cache->CompileShaders())
PanicAlert("Failed to recompile one or more texture conversion shaders.");
}
HiresTexture::Update();
}
backup_config.s_colorsamples = config.iSafeTextureCache_ColorSamples;
backup_config.s_texfmt_overlay = config.bTexFmtOverlayEnable;
backup_config.s_texfmt_overlay_center = config.bTexFmtOverlayCenter;
backup_config.s_hires_textures = config.bHiresTextures;
backup_config.s_cache_hires_textures = config.bCacheHiresTextures;
backup_config.s_stereo_3d = config.iStereoMode > 0;
backup_config.s_efb_mono_depth = config.bStereoEFBMonoDepth;
// TODO: Invalidating texcache is really stupid in some of these cases
if (config.iSafeTextureCache_ColorSamples != backup_config.color_samples ||
config.bTexFmtOverlayEnable != backup_config.texfmt_overlay ||
config.bTexFmtOverlayCenter != backup_config.texfmt_overlay_center ||
config.bHiresTextures != backup_config.hires_textures)
{
Invalidate();
TexDecoder_SetTexFmtOverlayOptions(g_ActiveConfig.bTexFmtOverlayEnable,
g_ActiveConfig.bTexFmtOverlayCenter);
}
if ((config.iStereoMode > 0) != backup_config.stereo_3d ||
config.bStereoEFBMonoDepth != backup_config.efb_mono_depth)
{
g_texture_cache->DeleteShaders();
if (!g_texture_cache->CompileShaders())
PanicAlert("Failed to recompile one or more texture conversion shaders.");
}
SetBackupConfig(config);
}
void TextureCacheBase::Cleanup(int _frameCount)
@ -220,31 +202,38 @@ bool TextureCacheBase::TCacheEntryBase::OverlapsMemoryRange(u32 range_address, u
return true;
}
TextureCacheBase::TCacheEntryBase* TextureCacheBase::TCacheEntryBase::ApplyPalette(u8* palette,
u32 tlutfmt)
void TextureCacheBase::SetBackupConfig(const VideoConfig& config)
{
TCacheEntryConfig newconfig;
newconfig.rendertarget = true;
newconfig.width = config.width;
newconfig.height = config.height;
newconfig.layers = config.layers;
TCacheEntryBase* decoded_entry = AllocateTexture(newconfig);
backup_config.color_samples = config.iSafeTextureCache_ColorSamples;
backup_config.texfmt_overlay = config.bTexFmtOverlayEnable;
backup_config.texfmt_overlay_center = config.bTexFmtOverlayCenter;
backup_config.hires_textures = config.bHiresTextures;
backup_config.cache_hires_textures = config.bCacheHiresTextures;
backup_config.stereo_3d = config.iStereoMode > 0;
backup_config.efb_mono_depth = config.bStereoEFBMonoDepth;
}
if (decoded_entry)
{
decoded_entry->SetGeneralParameters(addr, size_in_bytes, format);
decoded_entry->SetDimensions(native_width, native_height, 1);
decoded_entry->SetHashes(base_hash, hash);
decoded_entry->frameCount = FRAMECOUNT_INVALID;
decoded_entry->is_efb_copy = false;
TextureCacheBase::TCacheEntryBase* TextureCacheBase::ApplyPaletteToEntry(TCacheEntryBase* entry,
u8* palette, u32 tlutfmt)
{
TCacheEntryConfig new_config = entry->config;
new_config.levels = 1;
new_config.rendertarget = true;
g_texture_cache->ConvertTexture(decoded_entry, this, palette, static_cast<TlutFormat>(tlutfmt));
textures_by_address.emplace(addr, decoded_entry);
TCacheEntryBase* decoded_entry = AllocateTexture(new_config);
if (!decoded_entry)
return nullptr;
return decoded_entry;
}
decoded_entry->SetGeneralParameters(entry->addr, entry->size_in_bytes, entry->format);
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;
return nullptr;
ConvertTexture(decoded_entry, entry, palette, static_cast<TlutFormat>(tlutfmt));
textures_by_address.emplace(entry->addr, decoded_entry);
return decoded_entry;
}
void TextureCacheBase::ScaleTextureCacheEntryTo(TextureCacheBase::TCacheEntryBase** entry,
@ -342,7 +331,7 @@ TextureCacheBase::DoPartialTextureUpdates(TexCache::iterator iter_t, u8* palette
{
if (isPaletteTexture)
{
TCacheEntryBase* decoded_entry = entry->ApplyPalette(palette, tlutfmt);
TCacheEntryBase* decoded_entry = ApplyPaletteToEntry(entry, palette, tlutfmt);
if (decoded_entry)
{
// Link the efb copy with the partially updated texture, so we won't apply this partial
@ -701,7 +690,7 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
if (unconverted_copy != textures_by_address.end())
{
TCacheEntryBase* decoded_entry =
unconverted_copy->second->ApplyPalette(&texMem[tlutaddr], tlutfmt);
ApplyPaletteToEntry(unconverted_copy->second, &texMem[tlutaddr], tlutfmt);
if (decoded_entry)
{
@ -810,7 +799,7 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
entry->is_custom_tex = hires_tex != nullptr;
// load texture
entry->Load(width, height, expandedWidth, 0);
entry->Load(temp, width, height, expandedWidth, 0);
std::string basename = "";
if (g_ActiveConfig.bDumpTextures && !hires_tex)
@ -827,7 +816,7 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
const auto& level = hires_tex->m_levels[level_index];
CheckTempSize(level.data_size);
memcpy(temp, level.data.get(), level.data_size);
entry->Load(level.width, level.height, level.width, level_index);
entry->Load(temp, level.width, level.height, level.width, level_index);
}
}
else
@ -858,7 +847,7 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::Load(const u32 stage)
mip_src_data +=
TexDecoder_GetTextureSizeInBytes(expanded_mip_width, expanded_mip_height, texformat);
entry->Load(mip_width, mip_height, expanded_mip_width, level);
entry->Load(temp, mip_width, mip_height, expanded_mip_width, level);
if (g_ActiveConfig.bDumpTextures)
DumpTexture(entry, basename, level);
@ -1253,8 +1242,8 @@ void TextureCacheBase::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFo
if (copy_to_ram)
{
g_texture_cache->CopyEFB(dst, dstFormat, tex_w, bytes_per_row, num_blocks_y, dstStride,
srcFormat, srcRect, isIntensity, scaleByHalf);
CopyEFB(dst, dstFormat, tex_w, bytes_per_row, num_blocks_y, dstStride, srcFormat, srcRect,
isIntensity, scaleByHalf);
}
else
{
@ -1364,7 +1353,7 @@ TextureCacheBase::AllocateTexture(const TCacheEntryConfig& config)
}
else
{
entry = g_texture_cache->CreateTexture(config);
entry = CreateTexture(config);
if (!entry)
return nullptr;

View File

@ -127,16 +127,13 @@ public:
const MathUtil::Rectangle<int>& srcrect,
const MathUtil::Rectangle<int>& dstrect) = 0;
virtual void Load(unsigned int width, unsigned int height, unsigned int expanded_width,
unsigned int level) = 0;
virtual void Load(const u8* buffer, u32 width, u32 height, u32 expanded_width, u32 level) = 0;
virtual void FromRenderTarget(u8* dst, PEControl::PixelFormat srcFormat,
const EFBRectangle& srcRect, bool scaleByHalf,
unsigned int cbufid, const float* colmat) = 0;
bool OverlapsMemoryRange(u32 range_address, u32 range_size) const;
TextureCacheBase::TCacheEntryBase* ApplyPalette(u8* palette, u32 tlutfmt);
bool IsEfbCopy() const { return is_efb_copy; }
u32 NumBlocksY() const;
u32 BytesPerRow() const;
@ -146,13 +143,13 @@ public:
virtual ~TextureCacheBase(); // needs virtual for DX11 dtor
static void OnConfigChanged(VideoConfig& config);
void OnConfigChanged(VideoConfig& config);
// Removes textures which aren't used for more than TEXTURE_KILL_THRESHOLD frames,
// frameCount is the current frame number.
static void Cleanup(int _frameCount);
void Cleanup(int _frameCount);
static void Invalidate();
void Invalidate();
virtual TCacheEntryBase* CreateTexture(const TCacheEntryConfig& config) = 0;
@ -163,13 +160,12 @@ public:
virtual bool CompileShaders() = 0;
virtual void DeleteShaders() = 0;
static TCacheEntryBase* Load(const u32 stage);
static void UnbindTextures();
TCacheEntryBase* Load(const u32 stage);
void UnbindTextures();
virtual void BindTextures();
static void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, u32 dstStride,
PEControl::PixelFormat srcFormat,
const EFBRectangle& srcRect, bool isIntensity,
bool scaleByHalf);
void CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat, u32 dstStride,
PEControl::PixelFormat srcFormat, const EFBRectangle& srcRect,
bool isIntensity, bool scaleByHalf);
virtual void ConvertTexture(TCacheEntryBase* entry, TCacheEntryBase* unconverted, void* palette,
TlutFormat format) = 0;
@ -177,46 +173,52 @@ public:
protected:
TextureCacheBase();
alignas(16) static u8* temp;
static size_t temp_size;
alignas(16) u8* temp = nullptr;
size_t temp_size = 0;
static TCacheEntryBase* bound_textures[8];
TCacheEntryBase* bound_textures[8] = {};
private:
typedef std::multimap<u64, TCacheEntryBase*> TexCache;
typedef std::unordered_multimap<TCacheEntryConfig, TCacheEntryBase*, TCacheEntryConfig::Hasher>
TexPool;
static void ScaleTextureCacheEntryTo(TCacheEntryBase** entry, u32 new_width, u32 new_height);
static TCacheEntryBase* DoPartialTextureUpdates(TexCache::iterator iter, u8* palette,
u32 tlutfmt);
static void DumpTexture(TCacheEntryBase* entry, std::string basename, unsigned int level);
static void CheckTempSize(size_t required_size);
static TCacheEntryBase* AllocateTexture(const TCacheEntryConfig& config);
static TexPool::iterator FindMatchingTextureFromPool(const TCacheEntryConfig& config);
static TexCache::iterator GetTexCacheIter(TCacheEntryBase* entry);
void SetBackupConfig(const VideoConfig& config);
TCacheEntryBase* ApplyPaletteToEntry(TCacheEntryBase* entry, u8* palette, u32 tlutfmt);
void ScaleTextureCacheEntryTo(TCacheEntryBase** entry, u32 new_width, u32 new_height);
TCacheEntryBase* DoPartialTextureUpdates(TexCache::iterator iter, u8* palette, u32 tlutfmt);
void DumpTexture(TCacheEntryBase* entry, std::string basename, unsigned int level);
void CheckTempSize(size_t required_size);
TCacheEntryBase* AllocateTexture(const TCacheEntryConfig& config);
TexPool::iterator FindMatchingTextureFromPool(const TCacheEntryConfig& config);
TexCache::iterator GetTexCacheIter(TCacheEntryBase* entry);
// Removes and unlinks texture from texture cache and returns it to the pool
static TexCache::iterator InvalidateTexture(TexCache::iterator t_iter);
TexCache::iterator InvalidateTexture(TexCache::iterator t_iter);
static TCacheEntryBase* ReturnEntry(unsigned int stage, TCacheEntryBase* entry);
TCacheEntryBase* ReturnEntry(unsigned int stage, TCacheEntryBase* entry);
static TexCache textures_by_address;
static TexCache textures_by_hash;
static TexPool texture_pool;
TexCache textures_by_address;
TexCache textures_by_hash;
TexPool texture_pool;
// Backup configuration values
static struct BackupConfig
struct BackupConfig
{
int s_colorsamples;
bool s_texfmt_overlay;
bool s_texfmt_overlay_center;
bool s_hires_textures;
bool s_cache_hires_textures;
bool s_copy_cache_enable;
bool s_stereo_3d;
bool s_efb_mono_depth;
} backup_config;
int color_samples;
bool texfmt_overlay;
bool texfmt_overlay_center;
bool hires_textures;
bool cache_hires_textures;
bool copy_cache_enable;
bool stereo_3d;
bool efb_mono_depth;
};
BackupConfig backup_config = {};
};
extern std::unique_ptr<TextureCacheBase> g_texture_cache;

View File

@ -214,10 +214,10 @@ void VertexManagerBase::Flush()
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
usedtextures[bpmem.tevindref.getTexMap(bpmem.tevind[i].bt)] = true;
TextureCacheBase::UnbindTextures();
g_texture_cache->UnbindTextures();
for (unsigned int i : usedtextures)
{
const TextureCacheBase::TCacheEntryBase* tentry = TextureCacheBase::Load(i);
const auto* tentry = g_texture_cache->Load(i);
if (tentry)
{