mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
GS/HW: Modify the conditions for updating GPU CLUT to be as optimal as possible
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include "GS/Renderers/Common/GSDevice.h"
|
||||
#include "GS/Renderers/Common/GSRenderer.h"
|
||||
#include "common/AlignedMalloc.h"
|
||||
#include "common/Console.h"
|
||||
|
||||
GSClut::GSClut(GSLocalMemory* mem)
|
||||
: m_mem(mem)
|
||||
@@ -409,7 +410,6 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
}
|
||||
}
|
||||
|
||||
m_current_gpu_clut = nullptr;
|
||||
if (GSConfig.UserHacks_GPUTargetCLUTMode != GSGPUTargetCLUTMode::Disabled)
|
||||
{
|
||||
const bool is_4bit = (TEX0.PSM == PSMT4 || TEX0.PSM == PSMT4HL || TEX0.PSM == PSMT4HH);
|
||||
@@ -440,27 +440,36 @@ void GSClut::Read32(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
GSTexture* dst = is_4bit ? m_gpu_clut4 : m_gpu_clut8;
|
||||
const u32 dst_size = is_4bit ? 16 : 256;
|
||||
const u32 dOffset = (TEX0.CSA & ((TEX0.CPSM == PSMCT16 || TEX0.CPSM == PSMCT16S) ? 15u : 31u)) << 4;
|
||||
bool new_clut = false;
|
||||
|
||||
if (src != m_current_gpu_clut && (src != m_last_gpu_clut || m_gpu_clut_last_offset != offset))
|
||||
m_gpu_clut_dirty = true;
|
||||
|
||||
if (!dst)
|
||||
{
|
||||
// allocate texture lazily
|
||||
dst = g_gs_device->CreateRenderTarget(dst_size, 1, GSTexture::Format::Color, false);
|
||||
is_4bit ? (m_gpu_clut4 = dst) : (m_gpu_clut8 = dst);
|
||||
new_clut = true;
|
||||
m_gpu_clut_dirty = true;
|
||||
}
|
||||
if (dst)
|
||||
{
|
||||
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);
|
||||
|
||||
if (new_clut || g_gs_renderer->GetLastGPUCLUTDraw() == GSState::s_n)
|
||||
if (m_gpu_clut_dirty)
|
||||
{
|
||||
m_last_gpu_clut = src;
|
||||
g_gs_device->UpdateCLUTTexture(src, scale, offset.x, offset.y, dst, dOffset, dst_size);
|
||||
}
|
||||
|
||||
m_gpu_clut_dirty = false;
|
||||
m_current_gpu_clut = dst;
|
||||
m_gpu_clut_last_offset = offset;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_current_gpu_clut = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,10 @@ class alignas(32) GSClut final : public GSAlignedClass<32>
|
||||
GSTexture* m_gpu_clut4 = nullptr;
|
||||
GSTexture* m_gpu_clut8 = nullptr;
|
||||
GSTexture* m_current_gpu_clut = nullptr;
|
||||
GSTexture* m_last_gpu_clut = nullptr;
|
||||
GSVector2i m_gpu_clut_last_offset = 0;
|
||||
u64 m_gpu_clut_draw = 0;
|
||||
bool m_gpu_clut_dirty = true;
|
||||
|
||||
typedef void (GSClut::*writeCLUT)(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT);
|
||||
|
||||
@@ -97,7 +101,14 @@ public:
|
||||
~GSClut();
|
||||
|
||||
__fi GSTexture* GetGPUTexture() const { return m_current_gpu_clut; }
|
||||
|
||||
__fi void SetGPUTextureDirty(u64 draw, GSTexture* texture)
|
||||
{
|
||||
if (texture == m_last_gpu_clut && draw > m_gpu_clut_draw)
|
||||
{
|
||||
m_gpu_clut_draw = draw;
|
||||
m_gpu_clut_dirty = true;
|
||||
}
|
||||
}
|
||||
void Reset();
|
||||
bool InvalidateRange(u32 start_block, u32 end_block, bool is_draw = false);
|
||||
u8 IsInvalid();
|
||||
|
||||
@@ -51,7 +51,6 @@ public:
|
||||
virtual float GetTextureScaleFactor() { return 1.0f; }
|
||||
GSVector2i GetInternalResolution();
|
||||
float GetModXYOffset();
|
||||
virtual u64 GetLastGPUCLUTDraw() { return GSState::s_n; }
|
||||
|
||||
virtual GSTexture* LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVector2i& offset, float* scale, const GSVector2i& size);
|
||||
|
||||
|
||||
@@ -59,11 +59,6 @@ void GSRendererHW::ReadbackTextureCache()
|
||||
g_texture_cache->ReadbackAll();
|
||||
}
|
||||
|
||||
u64 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);
|
||||
@@ -4884,6 +4879,9 @@ void GSRendererHW::Draw()
|
||||
|
||||
if ((fm & fm_mask) != fm_mask && !no_rt)
|
||||
{
|
||||
if (m_mem.m_clut.GetGPUTexture() && m_mem.m_clut.GetGPUTexture() == rt->m_texture)
|
||||
m_mem.m_clut.SetGPUTextureDirty(rt->m_last_draw, rt->m_texture);
|
||||
|
||||
g_texture_cache->InvalidateVideoMem(context->offset.fb, real_rect, false);
|
||||
|
||||
// Remove overwritten Zs at the FBP.
|
||||
|
||||
@@ -242,7 +242,6 @@ public:
|
||||
|
||||
void PurgeTextureCache(bool sources, bool targets, bool hash_cache) override;
|
||||
void ReadbackTextureCache() override;
|
||||
u64 GetLastGPUCLUTDraw() override;
|
||||
|
||||
GSTexture* LookupPaletteSource(u32 CBP, u32 CPSM, u32 CBW, GSVector2i& offset, float* scale, const GSVector2i& size) override;
|
||||
|
||||
|
||||
@@ -7064,18 +7064,7 @@ 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;
|
||||
}
|
||||
GSRendererHW::GetInstance()->m_mem.m_clut.SetGPUTextureDirty(t->m_last_draw, t->m_texture);
|
||||
|
||||
offset = this_offset;
|
||||
*scale = t->m_scale;
|
||||
|
||||
@@ -441,9 +441,6 @@ protected:
|
||||
GSTexture* m_temporary_z = nullptr; // invalidated after the draw
|
||||
TempZAddress m_temporary_z_info;
|
||||
|
||||
Target* m_last_clut_target = nullptr;
|
||||
u64 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;
|
||||
@@ -484,7 +481,6 @@ 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 u64 GetLastGPUCLUTDraw() { return m_last_gpu_clut_draw; };
|
||||
|
||||
void Read(Target* t, const GSVector4i& r);
|
||||
void Read(Source* t, const GSVector4i& r);
|
||||
|
||||
Reference in New Issue
Block a user