TexCache: use an unordered_multimap for the tex pool

This commit is contained in:
degasus
2015-01-17 10:57:19 +01:00
parent 4639d3b1bc
commit 8565f02699
2 changed files with 34 additions and 23 deletions

View File

@ -31,7 +31,7 @@ GC_ALIGNED16(u8 *TextureCache::temp) = nullptr;
size_t TextureCache::temp_size; size_t TextureCache::temp_size;
TextureCache::TexCache TextureCache::textures; TextureCache::TexCache TextureCache::textures;
TextureCache::TexturePool TextureCache::texture_pool; TextureCache::TexPool TextureCache::texture_pool;
TextureCache::BackupConfig TextureCache::backup_config; TextureCache::BackupConfig TextureCache::backup_config;
@ -82,7 +82,7 @@ void TextureCache::Invalidate()
for (auto& rt : texture_pool) for (auto& rt : texture_pool)
{ {
delete rt; delete rt.second;
} }
texture_pool.clear(); texture_pool.clear();
} }
@ -161,19 +161,22 @@ void TextureCache::Cleanup(int _frameCount)
} }
} }
for (size_t i = 0; i < texture_pool.size();) TexPool::iterator iter2 = texture_pool.begin();
TexPool::iterator tcend2 = texture_pool.end();
while (iter2 != tcend2)
{ {
auto rt = texture_pool[i]; if(iter2->second->frameCount == FRAMECOUNT_INVALID)
if (_frameCount > TEXTURE_POOL_KILL_THRESHOLD + rt->frameCount)
{ {
delete rt; iter2->second->frameCount = _frameCount;
texture_pool[i] = texture_pool.back(); }
texture_pool.pop_back(); if (_frameCount > TEXTURE_POOL_KILL_THRESHOLD + iter2->second->frameCount)
{
delete iter2->second;
iter2 = texture_pool.erase(iter2);
} }
else else
{ {
++i; ++iter2;
} }
} }
} }
@ -888,17 +891,12 @@ void TextureCache::CopyRenderTargetToTexture(u32 dstAddr, unsigned int dstFormat
TextureCache::TCacheEntryBase* TextureCache::AllocateTexture(const TCacheEntryConfig& config) TextureCache::TCacheEntryBase* TextureCache::AllocateTexture(const TCacheEntryConfig& config)
{ {
for (size_t i = 0; i < texture_pool.size(); ++i) TexPool::iterator iter = texture_pool.find(config);
if (iter != texture_pool.end())
{ {
auto rt = texture_pool[i]; TextureCache::TCacheEntryBase* entry = iter->second;
texture_pool.erase(iter);
if (rt->config == config) return entry;
{
texture_pool[i] = texture_pool.back();
texture_pool.pop_back();
return rt;
}
} }
INCSTAT(stats.numTexturesCreated); INCSTAT(stats.numTexturesCreated);
@ -907,5 +905,6 @@ TextureCache::TCacheEntryBase* TextureCache::AllocateTexture(const TCacheEntryCo
void TextureCache::FreeTexture(TCacheEntryBase* entry) void TextureCache::FreeTexture(TCacheEntryBase* entry)
{ {
texture_pool.push_back(entry); entry->frameCount = FRAMECOUNT_INVALID;
texture_pool.insert(TexPool::value_type(entry->config, entry));
} }

View File

@ -4,7 +4,9 @@
#pragma once #pragma once
#include <functional>
#include <map> #include <map>
#include <unordered_map>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/Thread.h" #include "Common/Thread.h"
@ -37,6 +39,16 @@ public:
{ {
return width == b.width && height == b.height && levels == b.levels && layers == b.layers && rendertarget == b.rendertarget; return width == b.width && height == b.height && levels == b.levels && layers == b.layers && rendertarget == b.rendertarget;
} }
struct Hasher : std::hash<u64>
{
size_t operator()(const TextureCache::TCacheEntryConfig& c) const
{
u64 id = (u64)c.rendertarget << 63 | (u64)c.layers << 48 | (u64)c.levels << 32 | (u64)c.height << 16 | (u64)c.width;
return std::hash<u64>::operator()(id);
}
};
}; };
struct TCacheEntryBase struct TCacheEntryBase
@ -134,10 +146,10 @@ private:
static void FreeTexture(TCacheEntryBase* entry); static void FreeTexture(TCacheEntryBase* entry);
typedef std::map<u32, TCacheEntryBase*> TexCache; typedef std::map<u32, TCacheEntryBase*> TexCache;
typedef std::vector<TCacheEntryBase*> TexturePool; typedef std::unordered_multimap<TCacheEntryConfig, TCacheEntryBase*, TCacheEntryConfig::Hasher> TexPool;
static TexCache textures; static TexCache textures;
static TexturePool texture_pool; static TexPool texture_pool;
// Backup configuration values // Backup configuration values
static struct BackupConfig static struct BackupConfig