mirror of
https://github.com/stenzek/duckstation.git
synced 2024-11-22 21:39:40 +00:00
GPU/TextureCache: Purge copy-target sources from hash cache
Saves some VRAM/hash cache usage by disacarding hash cache entries that are discarded by a copy, but unfortunately cannot stop the uploads.
This commit is contained in:
parent
6c1b98e46a
commit
9838dd9df2
@ -246,16 +246,18 @@ static void DestroyPipelines();
|
||||
static const Source* ReturnSource(Source* source, const GSVector4i uv_rect, PaletteRecordFlags flags);
|
||||
static Source* CreateSource(SourceKey key);
|
||||
|
||||
static HashCacheKey GetHashCacheKey(SourceKey key, HashType tex_hash, HashType pal_hash);
|
||||
static HashCacheEntry* LookupHashCache(SourceKey key, HashType tex_hash, HashType pal_hash);
|
||||
static void ApplyTextureReplacements(SourceKey key, HashType tex_hash, HashType pal_hash, HashCacheEntry* entry);
|
||||
static void RemoveFromHashCache(HashCacheEntry* entry, SourceKey key, HashType tex_hash, HashType pal_hash);
|
||||
static void RemoveFromHashCache(HashCache::iterator it);
|
||||
static void ClearHashCache();
|
||||
|
||||
static bool IsPageDrawn(u32 page_index, const GSVector4i rect);
|
||||
static void InvalidatePageSources(u32 pn);
|
||||
static void InvalidatePageSources(u32 pn, const GSVector4i rc);
|
||||
static void InvalidatePageSources(u32 pn, const GSVector4i rc, bool remove_from_hash_cache = false);
|
||||
static void InvalidateSources();
|
||||
static void DestroySource(Source* src);
|
||||
static void DestroySource(Source* src, bool remove_from_hash_cache = false);
|
||||
|
||||
static HashType HashPage(u8 page, GPUTextureMode mode);
|
||||
static HashType HashPalette(GPUTexturePaletteReg palette, GPUTextureMode mode);
|
||||
@ -902,7 +904,7 @@ void GPUTextureCache::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 w
|
||||
|
||||
// copy and invalidate
|
||||
GPU_SW_Rasterizer::CopyVRAM(src_x, src_y, dst_x, dst_y, width, height, check_mask, set_mask);
|
||||
AddWrittenRectangle(dst_bounds, convert_copies_to_writes);
|
||||
AddWrittenRectangle(dst_bounds, convert_copies_to_writes, true);
|
||||
}
|
||||
|
||||
void GPUTextureCache::WriteVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask,
|
||||
@ -931,11 +933,11 @@ void GPUTextureCache::WriteVRAM(u32 x, u32 y, u32 width, u32 height, const void*
|
||||
s_last_vram_write = it;
|
||||
}
|
||||
|
||||
void GPUTextureCache::AddWrittenRectangle(const GSVector4i rect, bool update_vram_writes)
|
||||
void GPUTextureCache::AddWrittenRectangle(const GSVector4i rect, bool update_vram_writes, bool remove_from_hash_cache)
|
||||
{
|
||||
LoopRectPages(rect, [&rect, &update_vram_writes](u32 pn) {
|
||||
LoopRectPages(rect, [&rect, &update_vram_writes, &remove_from_hash_cache](u32 pn) {
|
||||
PageEntry& page = s_pages[pn];
|
||||
InvalidatePageSources(pn, rect);
|
||||
InvalidatePageSources(pn, rect, remove_from_hash_cache);
|
||||
|
||||
if (page.num_draw_rects > 0)
|
||||
{
|
||||
@ -1372,7 +1374,7 @@ void GPUTextureCache::InvalidatePageSources(u32 pn)
|
||||
DebugAssert(!ps.head && !ps.tail);
|
||||
}
|
||||
|
||||
void GPUTextureCache::InvalidatePageSources(u32 pn, const GSVector4i rc)
|
||||
void GPUTextureCache::InvalidatePageSources(u32 pn, const GSVector4i rc, bool remove_from_hash_cache)
|
||||
{
|
||||
DebugAssert(pn < NUM_VRAM_PAGES);
|
||||
|
||||
@ -1390,11 +1392,11 @@ void GPUTextureCache::InvalidatePageSources(u32 pn, const GSVector4i rc)
|
||||
}
|
||||
|
||||
GL_INS_FMT("Invalidate source {} in page {} due to overlapping with {}", SourceToString(src), pn, rc);
|
||||
DestroySource(src);
|
||||
DestroySource(src, remove_from_hash_cache);
|
||||
}
|
||||
}
|
||||
|
||||
void GPUTextureCache::DestroySource(Source* src)
|
||||
void GPUTextureCache::DestroySource(Source* src, bool remove_from_hash_cache)
|
||||
{
|
||||
GL_INS_FMT("Invalidate source {}", SourceToString(src));
|
||||
|
||||
@ -1420,9 +1422,13 @@ void GPUTextureCache::DestroySource(Source* src)
|
||||
for (u32 i = 0; i < src->num_page_refs; i++)
|
||||
ListUnlink(src->page_refs[i]);
|
||||
|
||||
DebugAssert(src->from_hash_cache && src->from_hash_cache->ref_count > 0);
|
||||
HashCacheEntry* hcentry = src->from_hash_cache;
|
||||
DebugAssert(hcentry && hcentry->ref_count > 0);
|
||||
ListUnlink(src->hash_cache_ref);
|
||||
src->from_hash_cache->ref_count--;
|
||||
hcentry->ref_count--;
|
||||
if (hcentry->ref_count == 0 && remove_from_hash_cache)
|
||||
RemoveFromHashCache(hcentry, src->key, src->texture_hash, src->palette_hash);
|
||||
|
||||
delete src;
|
||||
}
|
||||
|
||||
@ -2013,9 +2019,14 @@ void GPUTextureCache::InitializeVRAMWritePaletteRecord(VRAMWrite::PaletteRecord*
|
||||
}
|
||||
}
|
||||
|
||||
GPUTextureCache::HashCacheKey GPUTextureCache::GetHashCacheKey(SourceKey key, HashType tex_hash, HashType pal_hash)
|
||||
{
|
||||
return HashCacheKey{tex_hash, pal_hash, static_cast<HashType>(key.mode)};
|
||||
}
|
||||
|
||||
GPUTextureCache::HashCacheEntry* GPUTextureCache::LookupHashCache(SourceKey key, HashType tex_hash, HashType pal_hash)
|
||||
{
|
||||
const HashCacheKey hkey = {tex_hash, pal_hash, static_cast<HashType>(key.mode)};
|
||||
const HashCacheKey hkey = GetHashCacheKey(key, tex_hash, pal_hash);
|
||||
|
||||
const auto it = s_hash_cache.find(hkey);
|
||||
if (it != s_hash_cache.end())
|
||||
@ -2048,6 +2059,14 @@ GPUTextureCache::HashCacheEntry* GPUTextureCache::LookupHashCache(SourceKey key,
|
||||
return &s_hash_cache.emplace(hkey, std::move(entry)).first->second;
|
||||
}
|
||||
|
||||
void GPUTextureCache::RemoveFromHashCache(HashCacheEntry* entry, SourceKey key, HashType tex_hash, HashType pal_hash)
|
||||
{
|
||||
const HashCacheKey hckey = GetHashCacheKey(key, tex_hash, pal_hash);
|
||||
const auto iter = s_hash_cache.find(hckey);
|
||||
Assert(iter != s_hash_cache.end() && &iter->second == entry);
|
||||
RemoveFromHashCache(iter);
|
||||
}
|
||||
|
||||
void GPUTextureCache::RemoveFromHashCache(HashCache::iterator it)
|
||||
{
|
||||
ListIterate(it->second.sources, [](Source* source) { DestroySource(source); });
|
||||
|
@ -109,13 +109,13 @@ void Shutdown();
|
||||
|
||||
void Invalidate();
|
||||
|
||||
void AddWrittenRectangle(const GSVector4i rect, bool update_vram_writes = false);
|
||||
void AddWrittenRectangle(const GSVector4i rect, bool update_vram_writes = false, bool remove_from_hash_cache = false);
|
||||
void AddDrawnRectangle(const GSVector4i rect, const GSVector4i clip_rect);
|
||||
|
||||
void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height, bool set_mask, bool check_mask,
|
||||
const GSVector4i src_bounds, const GSVector4i dst_bounds);
|
||||
void WriteVRAM(u32 x, u32 y, u32 width, u32 height, const void* data, bool set_mask, bool check_mask,
|
||||
const GSVector4i bounds);
|
||||
const GSVector4i bounds);
|
||||
|
||||
const Source* LookupSource(SourceKey key, const GSVector4i uv_rect, PaletteRecordFlags flags);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user