GS/HW: Only update GPU CLUT on target change or draw update

This commit is contained in:
refractionpcsx2 2025-12-15 23:28:09 +00:00
parent cf4412ecbe
commit e42759afb4
6 changed files with 29 additions and 1 deletions

View File

@ -450,7 +450,10 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
{
GL_PUSH("Update GPU CLUT [CBP=%04X, CPSM=%s, CBW=%u, CSA=%u, Offset=(%d,%d)]",
TEX0.CBP, GSUtil::GetPSMName(TEX0.CPSM), CBW, TEX0.CSA, offset.x, offset.y);
g_gs_device->UpdateCLUTTexture(src, scale, offset.x, offset.y, dst, dOffset, dst_size);
if(g_gs_renderer->GetLastGPUCLUTDraw() == GSState::s_n)
g_gs_device->UpdateCLUTTexture(src, scale, offset.x, offset.y, dst, dOffset, dst_size);
m_current_gpu_clut = dst;
}
}

View File

@ -51,6 +51,7 @@ public:
virtual float GetTextureScaleFactor() { return 1.0f; }
GSVector2i GetInternalResolution();
float GetModXYOffset();
virtual int GetLastGPUCLUTDraw() { return GSState::s_n; }
virtual GSTexture* LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVector2i& offset, float* scale, const GSVector2i& size);

View File

@ -59,6 +59,11 @@ void GSRendererHW::ReadbackTextureCache()
g_texture_cache->ReadbackAll();
}
int GSRendererHW::GetLastGPUCLUTDraw()
{
return g_texture_cache->GetLastGPUCLUTDraw();
}
GSTexture* GSRendererHW::LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVector2i& offset, float* scale, const GSVector2i& size)
{
return g_texture_cache->LookupPaletteSource(CBP, CPSM, CBW, offset, scale, size);

View File

@ -242,6 +242,8 @@ public:
void PurgeTextureCache(bool sources, bool targets, bool hash_cache) override;
void ReadbackTextureCache() override;
int GetLastGPUCLUTDraw() override;
GSTexture* LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVector2i& offset, float* scale, const GSVector2i& size) override;
/// Called by the texture cache to know for certain whether there is a channel shuffle.

View File

@ -6987,6 +6987,19 @@ GSTexture* GSTextureCache::LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVec
continue;
}
if (m_last_clut_target != nullptr && m_last_clut_target == t)
{
if (t->m_last_draw > m_last_gpu_clut_draw)
{
m_last_gpu_clut_draw = GSState::s_n;
}
}
else
{
m_last_clut_target = t;
m_last_gpu_clut_draw = GSState::s_n;
}
offset = this_offset;
*scale = t->m_scale;

View File

@ -441,6 +441,9 @@ protected:
GSTexture* m_temporary_z = nullptr; // invalidated after the draw
TempZAddress m_temporary_z_info;
Target* m_last_clut_target = nullptr;
int m_last_gpu_clut_draw = 0;
std::unique_ptr<GSDownloadTexture> m_color_download_texture;
std::unique_ptr<GSDownloadTexture> m_uint16_download_texture;
std::unique_ptr<GSDownloadTexture> m_uint32_download_texture;
@ -481,6 +484,7 @@ public:
__fi u64 GetTotalHashCacheMemoryUsage() const { return (m_hash_cache_memory_usage + m_hash_cache_replacement_memory_usage); }
__fi u64 GetSourceMemoryUsage() const { return m_source_memory_usage; }
__fi u64 GetTargetMemoryUsage() const { return m_target_memory_usage; }
__fi int GetLastGPUCLUTDraw() { return m_last_gpu_clut_draw; };
void Read(Target* t, const GSVector4i& r);
void Read(Source* t, const GSVector4i& r);