gsdx-tc: trace the texture format to detect texture shuffling

It fixes games that uses 16 bits RT (like snow engine games)
This commit is contained in:
Gregory Hainaut 2015-06-17 20:02:03 +02:00
parent 33c9e9da0a
commit 3b127f663b
7 changed files with 19 additions and 10 deletions

View File

@ -50,6 +50,7 @@ protected:
bool m_shaderfx;
bool m_fxaa;
bool m_shadeboost;
bool m_texture_shuffle;
virtual GSTexture* GetOutput(int i) = 0;

View File

@ -225,7 +225,7 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
GSDeviceDX::PSSamplerSelector ps_ssel;
GSDeviceDX::PSConstantBuffer ps_cb;
if ((context->FRAME.PSM == 0x2) && ((context->TEX0.PSM & 3) == 2) && (m_vt.m_primclass == GS_SPRITE_CLASS)) {
if (m_texture_shuffle) {
ps_sel.shuffle = 1;
ps_sel.fmt = 0;

View File

@ -361,6 +361,7 @@ void GSRendererHW::Draw()
}
GSTextureCache::Source* tex = NULL;
m_texture_shuffle = false;
if(PRIM->TME)
{
@ -395,6 +396,12 @@ void GSRendererHW::Draw()
{
m_mem.m_clut.Read32(context->TEX0, env.TEXA);
}
if (rt) {
rt->m_32_bits_fmt |= tex->m_32_bits_fmt;
}
// Both input and output are 16 bits but texture was initially 32 bits!
m_texture_shuffle = ((context->FRAME.PSM & 0x2) && ((context->TEX0.PSM & 3) == 2) && (m_vt.m_primclass == GS_SPRITE_CLASS) && tex->m_32_bits_fmt);
}
if(s_dump)

View File

@ -247,7 +247,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
GSDeviceOGL::OMColorMaskSelector om_csel;
GSDeviceOGL::OMDepthStencilSelector om_dssel;
if ((context->FRAME.PSM & 0x2) && ((context->TEX0.PSM & 3) == 2) && (m_vt.m_primclass == GS_SPRITE_CLASS)) {
if (m_texture_shuffle) {
ps_sel.shuffle = 1;
ps_sel.dfmt = 0;

View File

@ -516,6 +516,8 @@ void GSRendererSW::Draw()
Sync(2);
uint64 frame = m_perfmon.GetFrame();
// Dump the texture in 32 bits format. It helps to debug texture shuffle effect
// It will breaks the few games that really uses 16 bits RT
bool texture_shuffle = ((context->FRAME.PSM & 0x2) && ((context->TEX0.PSM & 3) == 2) && (m_vt.m_primclass == GS_SPRITE_CLASS));
string s;
@ -531,7 +533,7 @@ void GSRendererSW::Draw()
if(s_savet && s_n >= s_saven && PRIM->TME)
{
if (texture_shuffle) {
// Dump the texture in 32 bits format. It helps to debug texture shuffle effect
// Dump the RT in 32 bits format. It helps to debug texture shuffle effect
s = format("%05d_f%lld_tex_%05x_32bits.bmp", s_n, frame, (int)m_context->TEX0.TBP0);
m_mem.SaveBMP(root_sw+s, m_context->TEX0.TBP0, m_context->TEX0.TBW, 0, 1 << m_context->TEX0.TW, 1 << m_context->TEX0.TH);

View File

@ -223,13 +223,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int
dst = t;
#if 0
// Likely the root cause of tons and tons of bug
if (dst->m_TEX0.PSM != TEX0.PSM) {
GL_INS("TC: ERROR: use a target with format 0x%x as 0x%x without any conversion", dst->m_TEX0.PSM, TEX0.PSM);
}
#endif
dst->m_32_bits_fmt |= !(TEX0.PSM & 2);
dst->m_TEX0 = TEX0;
break;
@ -256,6 +250,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int
if(!t->m_age && bp == t->m_TEX0.TBP0)
{
dst = CreateTarget(TEX0, w, h, type);
if (type == DepthStencil) {
GL_CACHE("TC: Lookup Target(Depth) %dx%d, hit Color (0x%x, F:0x%x)", w, h, bp, TEX0.PSM);
int shader = (TEX0.PSM & 1) ? 13 : 12;
@ -753,6 +748,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
if (dst)
{
// TODO: clean up this mess
src->m_32_bits_fmt = dst->m_32_bits_fmt;
src->m_target = true;
@ -1011,6 +1007,7 @@ GSTextureCache::Surface::Surface(GSRenderer* r, uint8* temp)
, m_texture(NULL)
, m_age(0)
, m_temp(temp)
, m_32_bits_fmt(false)
{
m_TEX0.TBP0 = 0x3fff;
}
@ -1270,6 +1267,7 @@ GSTextureCache::Target::Target(GSRenderer* r, const GIFRegTEX0& TEX0, uint8* tem
, m_depth_supported(depth_supported)
{
m_TEX0 = TEX0;
m_32_bits_fmt |= !(TEX0.PSM & 2);
m_valid = GSVector4i::zero();
}

View File

@ -40,6 +40,7 @@ public:
GIFRegTEXA m_TEXA;
int m_age;
uint8* m_temp;
bool m_32_bits_fmt; // Allow to detect the casting of 32 bits as 16 bits texture
public:
Surface(GSRenderer* r, uint8* temp);