GSdx: there was a bug in unaligned 4/8 bit transfer, small texture glitches may be fixed (simpson game, car logos in gt4).

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1285 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2009-05-29 06:26:46 +00:00
parent 7fef12a4cb
commit 65b90bce83
6 changed files with 68 additions and 18 deletions

View File

@ -130,6 +130,7 @@ CRC::Game CRC::m_games[] =
{0x045D77E9, TalesOfAbyss, US}, // undub
{0xAA5EC3A3, TalesOfAbyss, JP},
{0xFB236A46, SonicUnleashed, US},
{0x4C7BB3C8, SimpsonsGame, Unknown},
};
hash_map<uint32, CRC::Game*> CRC::m_map;

View File

@ -64,6 +64,7 @@ public:
MajokkoALaMode2,
TalesOfAbyss,
SonicUnleashed,
SimpsonsGame,
TitleCount,
};

View File

@ -407,31 +407,55 @@ void GSDevice9::ClearRenderTarget(GSTexture* t, const GSVector4& c)
ClearRenderTarget(t, (c * 255 + 0.5f).zyxw().rgba32());
}
void GSDevice9::ClearRenderTarget(GSTexture* t, uint32 c)
void GSDevice9::ClearRenderTarget(GSTexture* rt, uint32 c)
{
CComPtr<IDirect3DSurface9> surface;
m_dev->GetRenderTarget(0, &surface);
m_dev->SetRenderTarget(0, *(GSTexture9*)t);
m_dev->SetRenderTarget(0, *(GSTexture9*)rt);
m_dev->Clear(0, NULL, D3DCLEAR_TARGET, c, 0, 0);
m_dev->SetRenderTarget(0, surface);
}
void GSDevice9::ClearDepth(GSTexture* t, float c)
{
CComPtr<IDirect3DSurface9> surface;
m_dev->GetDepthStencilSurface(&surface);
GSTexture* rt = CreateRenderTarget(t->GetWidth(), t->GetHeight());
CComPtr<IDirect3DSurface9> rtsurface;
CComPtr<IDirect3DSurface9> dssurface;
m_dev->GetRenderTarget(0, &rtsurface);
m_dev->GetDepthStencilSurface(&dssurface);
m_dev->SetRenderTarget(0, *(GSTexture9*)rt);
m_dev->SetDepthStencilSurface(*(GSTexture9*)t);
m_dev->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, c, 0);
m_dev->SetDepthStencilSurface(surface);
m_dev->SetRenderTarget(0, rtsurface);
m_dev->SetDepthStencilSurface(dssurface);
Recycle(rt);
}
void GSDevice9::ClearStencil(GSTexture* t, uint8 c)
{
CComPtr<IDirect3DSurface9> surface;
m_dev->GetDepthStencilSurface(&surface);
GSTexture* rt = CreateRenderTarget(t->GetWidth(), t->GetHeight());
CComPtr<IDirect3DSurface9> rtsurface;
CComPtr<IDirect3DSurface9> dssurface;
m_dev->GetRenderTarget(0, &rtsurface);
m_dev->GetDepthStencilSurface(&dssurface);
m_dev->SetRenderTarget(0, *(GSTexture9*)rt);
m_dev->SetDepthStencilSurface(*(GSTexture9*)t);
m_dev->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 0, c);
m_dev->SetDepthStencilSurface(surface);
m_dev->SetRenderTarget(0, rtsurface);
m_dev->SetDepthStencilSurface(dssurface);
Recycle(rt);
}
GSTexture* GSDevice9::Create(int type, int w, int h, int format)
@ -492,7 +516,7 @@ GSTexture* GSDevice9::CreateRenderTarget(int w, int h, int format)
GSTexture* GSDevice9::CreateDepthStencil(int w, int h, int format)
{
return __super::CreateDepthStencil(w, h, format ? format : D3DFMT_D24S8);
return __super::CreateDepthStencil(w, h, format ? format : D3DFMT_D24S8); // D3DFMT_D32F_LOCKABLE
}
GSTexture* GSDevice9::CreateTexture(int w, int h, int format)
@ -661,7 +685,7 @@ void GSDevice9::IASetVertexBuffer(const void* vertices, size_t stride, size_t co
{
HRESULT hr;
hr = m_dev->CreateVertexBuffer(m_vertices.limit * stride, D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_vertices.vb, NULL);
hr = m_dev->CreateVertexBuffer(m_vertices.limit * stride, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &m_vertices.vb, NULL);
if(FAILED(hr)) return;
}

View File

@ -813,12 +813,12 @@ void GSLocalMemory::WriteImageTopBottom(int l, int r, int y, int h, uint8* src,
break;
case PSM_PSMT8:
ReadColumn8<true>(y, dst, buff, 16);
memcpy(&buff[y2 * 16], &src[x], h2 * 16);
for(int i = 0, j = y2; i < h2; i++, j++) memcpy(&buff[j * 16], &src[i * srcpitch + x], 16);
WriteColumn8<true>(y, dst, buff, 16);
break;
case PSM_PSMT4:
ReadColumn4<true>(y, dst, buff, 16);
memcpy(&buff[y2 * 16], &src[x >> 1], h2 * 16);
for(int i = 0, j = y2; i < h2; i++, j++) memcpy(&buff[j * 16], &src[i * srcpitch + (x >> 1)], 16);
WriteColumn4<true>(y, dst, buff, 16);
break;
// TODO
@ -894,12 +894,12 @@ void GSLocalMemory::WriteImageTopBottom(int l, int r, int y, int h, uint8* src,
break;
case PSM_PSMT8:
ReadColumn8<true>(y, dst, buff, 16);
memcpy(&buff[0], &src[x], h * 16);
for(int i = 0; i < h; i++) memcpy(&buff[i * 16], &src[i * srcpitch + x], 16);
WriteColumn8<true>(y, dst, buff, 16);
break;
case PSM_PSMT4:
ReadColumn4<true>(y, dst, buff, 16);
memcpy(&buff[0], &src[x >> 1], h * 16);
for(int i = 0; i < h; i++) memcpy(&buff[i * 16], &src[i * srcpitch + (x >> 1)], 16);
WriteColumn4<true>(y, dst, buff, 16);
break;
// TODO
@ -2523,8 +2523,6 @@ HRESULT GSLocalMemory::SaveBMP(const string& fn, uint32 bp, uint32 bw, uint32 ps
TEXA.TA0 = 0;
TEXA.TA1 = 0x80;
// (this->*m_psm[TEX0.PSM].rtx)(GSVector4i(0, 0, w, h), bits, pitch, TEX0, TEXA);
readPixel rp = m_psm[psm].rp;
uint8* p = (uint8*)bits;

View File

@ -572,6 +572,30 @@ protected:
#pragma endregion
#pragma region Simpsons Game z buffer clear
if(m_game.title == CRC::SimpsonsGame)
{
uint32 FBP = m_context->FRAME.Block();
uint32 FBW = m_context->FRAME.FBW;
uint32 FPSM = m_context->FRAME.PSM;
if(FBP == 0x01800 && FPSM == PSM_PSMZ24)
{
// instead of just simply drawing a full height 512x512 sprite to clear the z buffer,
// it uses a 512x256 sprite only, yet it is still able to fill the whole surface with zeros,
// how? by using a render target that overlaps with the lower half of the z buffer...
m_dev->ClearDepth(ds, 0);
return false;
}
return true;
}
#pragma endregion
return true;
}

View File

@ -968,7 +968,7 @@ void GSState::Write(uint8* mem, int len)
int w = m_env.TRXREG.RRW;
int h = m_env.TRXREG.RRH;
// TRACE(_T("Write len=%d DBP=%05x DBW=%d DPSM=%d DSAX=%d DSAY=%d RRW=%d RRH=%d\n"), len, (int)m_env.BITBLTBUF.DBP, (int)m_env.BITBLTBUF.DBW, (int)m_env.BITBLTBUF.DPSM, dx, dy, w, h);
// TRACE(_T("Write len=%d DBP=%05x DBW=%d DPSM=%d DSAX=%d DSAY=%d RRW=%d RRH=%d\n"), len, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM, m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, m_env.TRXREG.RRW, m_env.TRXREG.RRH);
if(!m_tr.Update(w, h, GSLocalMemory::m_psm[m_env.BITBLTBUF.DPSM].trbpp, len))
{
@ -1209,7 +1209,9 @@ template<int index> void GSState::Transfer(uint8* mem, uint32 size)
{
m_q = 1.0f;
if(path.tag.PRE && (path.tag.FLG & 2) == 0)
ASSERT(!(path.tag.PRE && path.tag.FLG == GIF_FLG_REGLIST));
if(path.tag.PRE && path.tag.FLG == GIF_FLG_PACKED)
{
GIFReg r;
r.u64 = path.tag.PRIM;