From 42aee34482d9bf251b4a1f296d5341bab57166db Mon Sep 17 00:00:00 2001 From: iMineLink Date: Tue, 13 Nov 2018 19:22:13 +0100 Subject: [PATCH] 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. --- plugins/GSdx/GSTextureCache.cpp | 52 +++++++++++++++++++-------------- plugins/GSdx/GSTextureCache.h | 16 +++++----- 2 files changed, 38 insertions(+), 30 deletions(-) diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index d036cfb0d2..95734913c0 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -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 // use case. 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); @@ -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)))) { - AttachPaletteToSource(src, psm_s.pal); + AttachPaletteToSource(src, psm_s.pal, true); } 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. if (psm.pal > 0) { 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 // 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_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 { src->m_texture = m_renderer->m_dev->CreateTexture(tw, th); - - if (psm.pal > 0) { - 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); - } + // by default: src->m_should_have_tex_palette = false; + AttachPaletteToSource(src, psm.pal, false); // Attach only Palette object and clut copy } } @@ -1599,8 +1598,8 @@ GSTextureCache::Source::Source(GSRenderer* r, const GIFRegTEX0& TEX0, const GIFR GSTextureCache::Source::~Source() { - if (!m_palette_obj) { - _aligned_free(m_clut); + if (!m_should_have_tex_palette) { + // Eventually valid reference for m_palette is not managed by PaletteMap, so it has to be recycled m_renderer->m_dev->Recycle(m_palette); } @@ -2046,30 +2045,39 @@ void GSTextureCache::SourceMap::RemoveAt(Source* s) delete s; } -// Query the PaletteMap for a valid Palette, then assign both palette texture pointer and clut copy pointer to the Source object -void GSTextureCache::AttachPaletteToSource(Source* s, uint16 pal) +// 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, bool need_gs_texture) { - std::shared_ptr p = m_palette_map.LookupPalette(pal); + std::shared_ptr p = m_palette_map.LookupPalette(pal, need_gs_texture); s->m_palette_obj = p; - s->m_palette = p->GetPaletteGSTexture(); + if (need_gs_texture) { + s->m_palette = p->GetPaletteGSTexture(); + } s->m_clut = p->GetClut(); } // GSTextureCache::Palette -// Creates a new palette texture with current clut content, keeping a reference to its copy -GSTextureCache::Palette::Palette(const GSRenderer* renderer, uint16 pal) { +// Creates a copy of the current clut with eventually a new palette texture with its content +GSTextureCache::Palette::Palette(const GSRenderer* renderer, uint16 pal, bool need_gs_texture) { uint16 palette_size = pal * sizeof(uint32); m_clut = (uint32*)_aligned_malloc(palette_size, 64); m_renderer = renderer; memcpy(m_clut, (const uint32*)m_renderer->m_mem.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); + if (need_gs_texture) { + 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() { - 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 } @@ -2141,7 +2149,7 @@ GSTextureCache::PaletteMap::PaletteMap(const GSRenderer* renderer) { } // Retrieves the palette with the desired clut -std::shared_ptr GSTextureCache::PaletteMap::LookupPalette(uint16 pal) { +std::shared_ptr GSTextureCache::PaletteMap::LookupPalette(uint16 pal, bool need_gs_texture) { // Choose which hash map search into: // pal == 16 : index 0 // pal == 256 : index 1 @@ -2192,7 +2200,7 @@ std::shared_ptr GSTextureCache::PaletteMap::LookupPalet } // Create new Palette using shared pointer - std::shared_ptr palette = std::make_shared(m_renderer, pal); + std::shared_ptr palette = std::make_shared(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) palette_key = { palette->GetClut(), pal }; diff --git a/plugins/GSdx/GSTextureCache.h b/plugins/GSdx/GSTextureCache.h index 5eb0d66e9f..56d32ace05 100644 --- a/plugins/GSdx/GSTextureCache.h +++ b/plugins/GSdx/GSTextureCache.h @@ -55,12 +55,12 @@ public: { private: uint32* m_clut; // Pointer to a copy of relevant clut - GSTexture* m_tex_palette; // Pointer to valid texture with relevant clut as content - const GSRenderer* m_renderer; // Pointer to the current renderer, needed to recycle the referenced GSTexture on destruction + 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 eventually referenced GSTexture on destruction public: - Palette(const GSRenderer* renderer, uint16 pal); // Creates a copy of the current clut and a texture with its content - ~Palette(); // Default destructor, recycles palette texture and frees clut copy + 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, frees clut copy and eventually recycles palette texture // Disable copy constructor and copy operator Palette(const Palette&) = delete; @@ -73,7 +73,7 @@ public: // Getter for clut pointer 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(); }; @@ -162,9 +162,9 @@ public: 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 - std::shared_ptr LookupPalette(uint16 pal); + std::shared_ptr 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 @@ -238,5 +238,5 @@ public: void PrintMemoryUsage(); - void AttachPaletteToSource(Source* s, uint16 pal); + void AttachPaletteToSource(Source* s, uint16 pal, bool need_gs_texture); };