GSdx: sse2 code path still had a little mipmapping bug, tales of legendia does not crash anymore, added a hack for suikoden tactics (http://code.google.com/p/pcsx2/issues/detail?id=972)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4457 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2011-03-19 19:29:30 +00:00
parent 13e2213f95
commit de3333df6c
7 changed files with 45 additions and 20 deletions

View File

@ -176,6 +176,7 @@ CRC::Game CRC::m_games[] =
{0xD568B684, SMTDDS2, EU, ZWriteMustNotClear}, // SMT Digital Devil Saga 2 {0xD568B684, SMTDDS2, EU, ZWriteMustNotClear}, // SMT Digital Devil Saga 2
{0xE47C1A9C, SMTDDS2, JP, ZWriteMustNotClear}, // SMT Digital Devil Saga 2 {0xE47C1A9C, SMTDDS2, JP, ZWriteMustNotClear}, // SMT Digital Devil Saga 2
{0x0B8AB37B, RozenMaidenGebetGarden, JP, 0}, {0x0B8AB37B, RozenMaidenGebetGarden, JP, 0},
{0x1CC39DBD, SuikodenTactics, US, 0},
}; };
hash_map<uint32, CRC::Game*> CRC::m_map; hash_map<uint32, CRC::Game*> CRC::m_map;

View File

@ -81,6 +81,7 @@ public:
SMTDDS1, SMTDDS1,
SMTDDS2, SMTDDS2,
RozenMaidenGebetGarden, RozenMaidenGebetGarden,
SuikodenTactics,
TitleCount, TitleCount,
}; };

View File

@ -2958,7 +2958,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset)
{ {
movdqa(ptr[&m_local.temp.test], xmm7); movdqa(ptr[&m_local.temp.test], xmm7);
mov(ebx, ptr[&m_local.temp.lod.i.u32[0]]); mov(ebx, ptr[&lod_i->u32[0]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm6, xmm5, 0); ReadTexel(xmm6, xmm5, 0);
@ -2966,7 +2966,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset)
ReadTexel(xmm4, xmm2, 0); ReadTexel(xmm4, xmm2, 0);
psrldq(xmm2, 4); psrldq(xmm2, 4);
mov(ebx, ptr[&m_local.temp.lod.i.u32[1]]); mov(ebx, ptr[&lod_i->u32[1]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm1, xmm5, 0); ReadTexel(xmm1, xmm5, 0);
@ -2977,7 +2977,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset)
punpckldq(xmm6, xmm1); punpckldq(xmm6, xmm1);
punpckldq(xmm4, xmm7); punpckldq(xmm4, xmm7);
mov(ebx, ptr[&m_local.temp.lod.i.u32[2]]); mov(ebx, ptr[&lod_i->u32[2]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm1, xmm5, 0); ReadTexel(xmm1, xmm5, 0);
@ -2985,7 +2985,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset)
ReadTexel(xmm7, xmm2, 0); ReadTexel(xmm7, xmm2, 0);
psrldq(xmm2, 4); psrldq(xmm2, 4);
mov(ebx, ptr[&m_local.temp.lod.i.u32[3]]); mov(ebx, ptr[&lod_i->u32[3]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm5, xmm5, 0); ReadTexel(xmm5, xmm5, 0);
@ -2997,7 +2997,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset)
punpcklqdq(xmm6, xmm1); punpcklqdq(xmm6, xmm1);
punpcklqdq(xmm4, xmm7); punpcklqdq(xmm4, xmm7);
mov(ebx, ptr[&m_local.temp.lod.i.u32[0]]); mov(ebx, ptr[&lod_i->u32[0]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm1, xmm0, 0); ReadTexel(xmm1, xmm0, 0);
@ -3005,7 +3005,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset)
ReadTexel(xmm5, xmm3, 0); ReadTexel(xmm5, xmm3, 0);
psrldq(xmm3, 4); psrldq(xmm3, 4);
mov(ebx, ptr[&m_local.temp.lod.i.u32[1]]); mov(ebx, ptr[&lod_i->u32[1]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm2, xmm0, 0); ReadTexel(xmm2, xmm0, 0);
@ -3016,7 +3016,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset)
punpckldq(xmm1, xmm2); punpckldq(xmm1, xmm2);
punpckldq(xmm5, xmm7); punpckldq(xmm5, xmm7);
mov(ebx, ptr[&m_local.temp.lod.i.u32[2]]); mov(ebx, ptr[&lod_i->u32[2]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm2, xmm0, 0); ReadTexel(xmm2, xmm0, 0);
@ -3024,7 +3024,7 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset)
ReadTexel(xmm7, xmm3, 0); ReadTexel(xmm7, xmm3, 0);
psrldq(xmm3, 4); psrldq(xmm3, 4);
mov(ebx, ptr[&m_local.temp.lod.i.u32[3]]); mov(ebx, ptr[&lod_i->u32[3]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm0, xmm0, 0); ReadTexel(xmm0, xmm0, 0);
@ -3040,13 +3040,13 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset)
} }
else else
{ {
mov(ebx, ptr[&m_local.temp.lod.i.u32[0]]); mov(ebx, ptr[&lod_i->u32[0]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm6, xmm5, 0); ReadTexel(xmm6, xmm5, 0);
psrldq(xmm5, 4); // shuffle instead? (1 2 3 0 ~ rotation) psrldq(xmm5, 4); // shuffle instead? (1 2 3 0 ~ rotation)
mov(ebx, ptr[&m_local.temp.lod.i.u32[1]]); mov(ebx, ptr[&lod_i->u32[1]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm1, xmm5, 0); ReadTexel(xmm1, xmm5, 0);
@ -3054,13 +3054,13 @@ void GSDrawScanlineCodeGenerator::ReadTexel(int pixels, int mip_offset)
punpckldq(xmm6, xmm1); punpckldq(xmm6, xmm1);
mov(ebx, ptr[&m_local.temp.lod.i.u32[2]]); mov(ebx, ptr[&lod_i->u32[2]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm1, xmm5, 0); ReadTexel(xmm1, xmm5, 0);
psrldq(xmm5, 4); psrldq(xmm5, 4);
mov(ebx, ptr[&m_local.temp.lod.i.u32[3]]); mov(ebx, ptr[&lod_i->u32[3]]);
mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]); mov(ebx, ptr[edx + ebx * sizeof(void*) + mip_offset]);
ReadTexel(xmm4, xmm5, 0); ReadTexel(xmm4, xmm5, 0);

View File

@ -129,7 +129,10 @@ void GSRendererSW::Draw()
GSScanlineGlobalData gd; GSScanlineGlobalData gd;
GetScanlineGlobalData(gd); if(!GetScanlineGlobalData(gd))
{
return;
}
if(!gd.sel.fwrite && !gd.sel.zwrite) if(!gd.sel.fwrite && !gd.sel.zwrite)
{ {
@ -244,7 +247,7 @@ void GSRendererSW::InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GS
#include "GSTextureSW.h" #include "GSTextureSW.h"
void GSRendererSW::GetScanlineGlobalData(GSScanlineGlobalData& gd) bool GSRendererSW::GetScanlineGlobalData(GSScanlineGlobalData& gd)
{ {
const GSDrawingEnvironment& env = m_env; const GSDrawingEnvironment& env = m_env;
const GSDrawingContext* context = m_context; const GSDrawingContext* context = m_context;
@ -346,7 +349,7 @@ void GSRendererSW::GetScanlineGlobalData(GSScanlineGlobalData& gd)
const GSTextureCacheSW::Texture* t = m_tc->Lookup(context->TEX0, env.TEXA, r); const GSTextureCacheSW::Texture* t = m_tc->Lookup(context->TEX0, env.TEXA, r);
if(t == NULL) {ASSERT(0); return;} if(t == NULL) {ASSERT(0); return false;}
gd.tex[0] = t->m_buff; gd.tex[0] = t->m_buff;
gd.sel.tw = t->m_tw - 3; gd.sel.tw = t->m_tw - 3;
@ -469,7 +472,7 @@ void GSRendererSW::GetScanlineGlobalData(GSScanlineGlobalData& gd)
const GSTextureCacheSW::Texture* t = m_tc->Lookup(MIP_TEX0, env.TEXA, r, gd.sel.tw + 3); const GSTextureCacheSW::Texture* t = m_tc->Lookup(MIP_TEX0, env.TEXA, r, gd.sel.tw + 3);
if(t == NULL) {ASSERT(0); return;} if(t == NULL) {ASSERT(0); return false;}
gd.tex[i] = t->m_buff; gd.tex[i] = t->m_buff;
@ -684,6 +687,8 @@ void GSRendererSW::GetScanlineGlobalData(GSScanlineGlobalData& gd)
{ {
gd.zm |= GSVector4i::xffff0000(); gd.zm |= GSVector4i::xffff0000();
} }
return true;
} }
template<uint32 prim, uint32 tme, uint32 fst> template<uint32 prim, uint32 tme, uint32 fst>
@ -848,5 +853,7 @@ if(!m_dump)
} }
m_count += count; m_count += count;
// Flush();
} }
} }

View File

@ -42,7 +42,7 @@ protected:
void Draw(); void Draw();
void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r); void InvalidateVideoMem(const GIFRegBITBLTBUF& BITBLTBUF, const GSVector4i& r);
void GetScanlineGlobalData(GSScanlineGlobalData& gd); bool GetScanlineGlobalData(GSScanlineGlobalData& gd);
public: public:
GSRendererSW(int threads); GSRendererSW(int threads);

View File

@ -2482,6 +2482,19 @@ bool GSC_HauntingGround(const GSFrameInfo& fi, int& skip)
return true; return true;
} }
bool GSC_SuikodenTactics(const GSFrameInfo& fi, int& skip)
{
if(skip == 0)
{
if(!fi.TME && fi.TPSM == PSM_PSMT8H && fi.FPSM == 0 && fi.FBMSK == 0x0FF000000 && fi.TBP0 == 0 && GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM))
{
skip = 4;
}
}
return true;
}
bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw) bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
{ {
GSFrameInfo fi; GSFrameInfo fi;
@ -2536,6 +2549,7 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
map[CRC::ValkyrieProfile2] = GSC_ValkyrieProfile2; map[CRC::ValkyrieProfile2] = GSC_ValkyrieProfile2;
map[CRC::RadiataStories] = GSC_RadiataStories; map[CRC::RadiataStories] = GSC_RadiataStories;
map[CRC::HauntingGround] = GSC_HauntingGround; map[CRC::HauntingGround] = GSC_HauntingGround;
map[CRC::SuikodenTactics] = GSC_SuikodenTactics;
} }
// TODO: just set gsc in SetGameCRC once // TODO: just set gsc in SetGameCRC once

View File

@ -119,7 +119,7 @@ const GSTextureCacheSW::Texture* GSTextureCacheSW::Lookup(const GIFRegTEX0& TEX0
if(!t->Update(TEX0, TEXA, r)) if(!t->Update(TEX0, TEXA, r))
{ {
printf("!@#$\n"); // memory allocation may fail if the game is too hungry printf("!@#$\n"); // memory allocation may fail if the game is too hungry (tales of legendia fight transition/scene)
RemoveAt(t); RemoveAt(t);
@ -256,13 +256,15 @@ bool GSTextureCacheSW::Texture::Update(const GIFRegTEX0& TEX0, const GIFRegTEXA&
bool repeating = m_TEX0.IsRepeating(); bool repeating = m_TEX0.IsRepeating();
if(m_TEX0.TBW == 1) // repeating) if(m_TEX0.TBW == 1 && m_tw != 0) // repeating)
{ {
// FIXME: // FIXME:
// - marking a block prevents fetching it again to a different part of the texture // - marking a block prevents fetching it again to a different part of the texture
// - only a real issue for TBW = 1 mipmap levels, where the repeating part is below and often exploited (onimusha 3 intro / sidewalk) // - only a real issue for TBW = 1 mipmap levels, where the repeating part is below and often exploited (onimusha 3 intro / sidewalk)
r = GSVector4i(0, 0, tw, th); // r = GSVector4i(0, 0, tw, th);
r.top = 0;
r.bottom = th;
} }
r = r.ralign<Align_Outside>(bs); r = r.ralign<Align_Outside>(bs);