GSdx-TC: Use PaletteMap also when 8-bit texture is disabled by caching only clut copies. (#2681)

Enabled caching of clut copies with PaletteMap also in the case 8-bit texture is disabled, which is the default (on #2344 the caching of clut copies and palette textures was done only when 8-bit texture was enabled).
Brings moderate speedups ~10% in the most concitated parts of the ZoE2 Anubis benchmark, but may improve performance in all the cases when there are many Source objects created with clut copies to be stored.
The quality of the comments has been improved to better highlight the mechanics of the caching system.
This commit is contained in:
iMineLink 2018-11-13 19:22:13 +01:00 committed by lightningterror
parent ef3802b67a
commit 42aee34482
2 changed files with 38 additions and 30 deletions

View File

@ -168,7 +168,8 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0
// If it is too expensive, one could cut memory allocation in Source constructor for this // If it is too expensive, one could cut memory allocation in Source constructor for this
// use case. // use case.
if (palette) { if (palette) {
AttachPaletteToSource(src, psm_s.pal); // Palette is attached (Palette object, clut copy and palette texture) directly because the texture is not going in the texture cache list
AttachPaletteToSource(src, psm_s.pal, true);
} }
m_src.m_surfaces.insert(src); m_src.m_surfaces.insert(src);
@ -402,7 +403,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
} }
if (src->m_should_have_tex_palette && (!src->m_clut || !GSVector4i::compare64(src->m_clut, clut, psm_s.pal * sizeof(uint32)))) { if (src->m_should_have_tex_palette && (!src->m_clut || !GSVector4i::compare64(src->m_clut, clut, psm_s.pal * sizeof(uint32)))) {
AttachPaletteToSource(src, psm_s.pal); AttachPaletteToSource(src, psm_s.pal, true);
} }
src->Update(r); src->Update(r);
@ -1339,6 +1340,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
// Because the texture is already on the GPU, CPU can't convert it. // Because the texture is already on the GPU, CPU can't convert it.
if (psm.pal > 0) { if (psm.pal > 0) {
src->m_should_have_tex_palette = true; src->m_should_have_tex_palette = true;
// Palette (Palette object, clut copy and palette texture) is going to be attached in Source lookup code exploiting initial condition !src->m_clut
} }
// Disable linear filtering for various GS post-processing effect // Disable linear filtering for various GS post-processing effect
// 1/ Palette is used to interpret the alpha channel of the RT as an index. // 1/ Palette is used to interpret the alpha channel of the RT as an index.
@ -1453,15 +1455,12 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
{ {
src->m_texture = m_renderer->m_dev->CreateTexture(tw, th, Get8bitFormat()); src->m_texture = m_renderer->m_dev->CreateTexture(tw, th, Get8bitFormat());
src->m_should_have_tex_palette = true; src->m_should_have_tex_palette = true;
// Palette (Palette object, clut copy and palette texture) is going to be attached in Source lookup code exploiting initial condition !src->m_clut
} }
else { else {
src->m_texture = m_renderer->m_dev->CreateTexture(tw, th); src->m_texture = m_renderer->m_dev->CreateTexture(tw, th);
// by default: src->m_should_have_tex_palette = false;
if (psm.pal > 0) { AttachPaletteToSource(src, psm.pal, false); // Attach only Palette object and clut copy
uint16 palette_size = psm.pal * sizeof(uint32);
src->m_clut = (uint32*)_aligned_malloc(palette_size * sizeof(uint32), 64);
memcpy(src->m_clut, (const uint32*)m_renderer->m_mem.m_clut, palette_size);
}
} }
} }
@ -1599,8 +1598,8 @@ GSTextureCache::Source::Source(GSRenderer* r, const GIFRegTEX0& TEX0, const GIFR
GSTextureCache::Source::~Source() GSTextureCache::Source::~Source()
{ {
if (!m_palette_obj) { if (!m_should_have_tex_palette) {
_aligned_free(m_clut); // Eventually valid reference for m_palette is not managed by PaletteMap, so it has to be recycled
m_renderer->m_dev->Recycle(m_palette); m_renderer->m_dev->Recycle(m_palette);
} }
@ -2046,30 +2045,39 @@ void GSTextureCache::SourceMap::RemoveAt(Source* s)
delete s; delete s;
} }
// Query the PaletteMap for a valid Palette, then assign both palette texture pointer and clut copy pointer to the Source object // Query the PaletteMap for a valid Palette, then both its reference, clut copy pointer and eventually palette texture pointer to the Source object
void GSTextureCache::AttachPaletteToSource(Source* s, uint16 pal) void GSTextureCache::AttachPaletteToSource(Source* s, uint16 pal, bool need_gs_texture)
{ {
std::shared_ptr<Palette> p = m_palette_map.LookupPalette(pal); std::shared_ptr<Palette> p = m_palette_map.LookupPalette(pal, need_gs_texture);
s->m_palette_obj = p; s->m_palette_obj = p;
s->m_palette = p->GetPaletteGSTexture(); if (need_gs_texture) {
s->m_palette = p->GetPaletteGSTexture();
}
s->m_clut = p->GetClut(); s->m_clut = p->GetClut();
} }
// GSTextureCache::Palette // GSTextureCache::Palette
// Creates a new palette texture with current clut content, keeping a reference to its copy // Creates a copy of the current clut with eventually a new palette texture with its content
GSTextureCache::Palette::Palette(const GSRenderer* renderer, uint16 pal) { GSTextureCache::Palette::Palette(const GSRenderer* renderer, uint16 pal, bool need_gs_texture) {
uint16 palette_size = pal * sizeof(uint32); uint16 palette_size = pal * sizeof(uint32);
m_clut = (uint32*)_aligned_malloc(palette_size, 64); m_clut = (uint32*)_aligned_malloc(palette_size, 64);
m_renderer = renderer; m_renderer = renderer;
memcpy(m_clut, (const uint32*)m_renderer->m_mem.m_clut, palette_size); memcpy(m_clut, (const uint32*)m_renderer->m_mem.m_clut, palette_size);
m_tex_palette = m_renderer->m_dev->CreateTexture(256, 1); if (need_gs_texture) {
m_tex_palette->Update(GSVector4i(0, 0, pal, 1), m_clut, palette_size); m_tex_palette = m_renderer->m_dev->CreateTexture(256, 1);
m_tex_palette->Update(GSVector4i(0, 0, pal, 1), m_clut, palette_size);
}
else {
m_tex_palette = nullptr;
}
} }
// Default destructor, recycles palette texture and frees clut copy // Default destructor, frees clut copy and recycles eventual palette texture
GSTextureCache::Palette::~Palette() { GSTextureCache::Palette::~Palette() {
m_renderer->m_dev->Recycle(GetPaletteGSTexture()); // Recycle palette texture if (GetPaletteGSTexture()) {
m_renderer->m_dev->Recycle(GetPaletteGSTexture()); // Recycle palette texture, if any
}
_aligned_free(GetClut()); // Free clut copy _aligned_free(GetClut()); // Free clut copy
} }
@ -2141,7 +2149,7 @@ GSTextureCache::PaletteMap::PaletteMap(const GSRenderer* renderer) {
} }
// Retrieves the palette with the desired clut // Retrieves the palette with the desired clut
std::shared_ptr<GSTextureCache::Palette> GSTextureCache::PaletteMap::LookupPalette(uint16 pal) { std::shared_ptr<GSTextureCache::Palette> GSTextureCache::PaletteMap::LookupPalette(uint16 pal, bool need_gs_texture) {
// Choose which hash map search into: // Choose which hash map search into:
// pal == 16 : index 0 // pal == 16 : index 0
// pal == 256 : index 1 // pal == 256 : index 1
@ -2192,7 +2200,7 @@ std::shared_ptr<GSTextureCache::Palette> GSTextureCache::PaletteMap::LookupPalet
} }
// Create new Palette using shared pointer // Create new Palette using shared pointer
std::shared_ptr<Palette> palette = std::make_shared<Palette>(m_renderer, pal); std::shared_ptr<Palette> palette = std::make_shared<Palette>(m_renderer, pal, need_gs_texture);
// Create key for storing the Palette into the map (use copy of the clut stored into Palette itself as key attribute) // Create key for storing the Palette into the map (use copy of the clut stored into Palette itself as key attribute)
palette_key = { palette->GetClut(), pal }; palette_key = { palette->GetClut(), pal };

View File

@ -55,12 +55,12 @@ public:
{ {
private: private:
uint32* m_clut; // Pointer to a copy of relevant clut uint32* m_clut; // Pointer to a copy of relevant clut
GSTexture* m_tex_palette; // Pointer to valid texture with relevant clut as content GSTexture* m_tex_palette; // Pointer to valid texture with relevant clut as content, if instantiated by the constructor
const GSRenderer* m_renderer; // Pointer to the current renderer, needed to recycle the referenced GSTexture on destruction const GSRenderer* m_renderer; // Pointer to the current renderer, needed to recycle the eventually referenced GSTexture on destruction
public: public:
Palette(const GSRenderer* renderer, uint16 pal); // Creates a copy of the current clut and a texture with its content Palette(const GSRenderer* renderer, uint16 pal, bool need_gs_texture); // Creates a copy of the current clut and, if needed (need_gs_texture == true), a texture with its content
~Palette(); // Default destructor, recycles palette texture and frees clut copy ~Palette(); // Default destructor, frees clut copy and eventually recycles palette texture
// Disable copy constructor and copy operator // Disable copy constructor and copy operator
Palette(const Palette&) = delete; Palette(const Palette&) = delete;
@ -73,7 +73,7 @@ public:
// Getter for clut pointer // Getter for clut pointer
uint32* GetClut(); uint32* GetClut();
// Getter for palette texture pointer // Getter for palette texture pointer, may be nullptr if object has been instantiated with need_gs_texture == false
GSTexture* GetPaletteGSTexture(); GSTexture* GetPaletteGSTexture();
}; };
@ -162,9 +162,9 @@ public:
PaletteMap(const GSRenderer* renderer); // Default constructor PaletteMap(const GSRenderer* renderer); // Default constructor
// Retrieves a shared pointer to a valid Palette from m_maps or creates a new one adding it to the data structure // Retrieves a shared pointer to a valid Palette from m_maps or creates a new one adding it to the data structure
std::shared_ptr<Palette> LookupPalette(uint16 pal); std::shared_ptr<Palette> LookupPalette(uint16 pal, bool need_gs_texture);
void Clear(); // Clears m_maps, deleting clut(s) arrays and recycling palette textures void Clear(); // Clears m_maps, thus deletes Palette objects
}; };
class SourceMap class SourceMap
@ -238,5 +238,5 @@ public:
void PrintMemoryUsage(); void PrintMemoryUsage();
void AttachPaletteToSource(Source* s, uint16 pal); void AttachPaletteToSource(Source* s, uint16 pal, bool need_gs_texture);
}; };