This commit is contained in:
gabest
2007-12-15 11:01:31 +00:00
parent 03d9cc2d34
commit c0debadb6d
10 changed files with 363 additions and 176 deletions

View File

@@ -1725,7 +1725,20 @@ void GSLocalMemory::ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, GIFRe
|| (r.right & (bs.cx-1)) || (r.bottom & (bs.cy-1))
|| (CLAMP.WMS == 3) || (CLAMP.WMT == 3))
{
switch(TEX0.PSM)
DWORD psm = TEX0.PSM;
switch(psm)
{
case PSM_PSMT8:
case PSM_PSMT8H:
case PSM_PSMT4:
case PSM_PSMT4HL:
case PSM_PSMT4HH:
psm = TEX0.CPSM;
break;
}
switch(psm)
{
default:
case PSM_PSMCT32:
@@ -1736,23 +1749,47 @@ void GSLocalMemory::ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, GIFRe
case PSM_PSMCT16S:
ReadTexture<WORD>(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st);
break;
}
}
else
{
(this->*st)(r, dst, dstpitch, TEX0, TEXA);
}
}
void GSLocalMemory::ReadTextureNP2(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP)
{
unSwizzleTexture st = m_psm[TEX0.PSM].ustNP;
readTexel rt = m_psm[TEX0.PSM].rtNP;
CSize bs = m_psm[TEX0.PSM].bs;
if(r.Width() < bs.cx || r.Height() < bs.cy
|| (r.left & (bs.cx-1)) || (r.top & (bs.cy-1))
|| (r.right & (bs.cx-1)) || (r.bottom & (bs.cy-1)))
{
DWORD psm = TEX0.PSM;
switch(psm)
{
case PSM_PSMT8:
case PSM_PSMT8H:
case PSM_PSMT4:
case PSM_PSMT4HL:
case PSM_PSMT4HH:
switch(TEX0.CPSM)
{
default:
ASSERT(0);
case PSM_PSMCT32:
ReadTexture<DWORD>(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st);
break;
case PSM_PSMCT16:
case PSM_PSMCT16S:
ReadTexture<WORD>(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st);
break;
}
psm = TEX0.CPSM;
break;
}
switch(psm)
{
default:
case PSM_PSMCT32:
case PSM_PSMCT24:
ReadTexture2<DWORD>(r, dst, dstpitch, TEX0, TEXA, rt, st);
break;
case PSM_PSMCT16:
case PSM_PSMCT16S:
ReadTexture2<WORD>(r, dst, dstpitch, TEX0, TEXA, rt, st);
break;
}
}
@@ -2005,6 +2042,56 @@ if(!aligned) printf("unaligned memory pointer passed to ReadTexture\n");
}
}
template<typename T>
void GSLocalMemory::ReadTexture2(CRect r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, readTexel rt, unSwizzleTexture st)
{
CSize bs = m_psm[TEX0.PSM].bs;
int bsxm = bs.cx - 1;
int bsym = bs.cy - 1;
CRect cr;
cr.left = (r.left + bsxm) & ~bsxm;
cr.top = (r.top + bsym) & ~bsym;
cr.right = r.right & ~bsxm;
cr.bottom = r.bottom & ~bsym;
bool aligned = ((DWORD_PTR)(dst + (cr.left - r.left) * sizeof(T)) & 0xf) == 0;
if(cr.left >= cr.right && cr.top >= cr.bottom || !aligned)
{
// TODO: expand r to block size, read into temp buffer, copy to r (like above)
if(!aligned) printf("unaligned memory pointer passed to ReadTexture\n");
for(int y = r.top; y < r.bottom; y++, dst += dstpitch)
for(int x = r.left, i = 0; x < r.right; x++, i++)
((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA);
}
else
{
for(int y = r.top; y < cr.top; y++, dst += dstpitch)
for(int x = r.left, i = 0; x < r.right; x++, i++)
((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA);
if(!cr.IsRectEmpty())
(this->*st)(cr, dst + (cr.left - r.left)*sizeof(T), dstpitch, TEX0, TEXA);
for(int y = cr.top; y < cr.bottom; y++, dst += dstpitch)
{
for(int x = r.left, i = 0; x < cr.left; x++, i++)
((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA);
for(int x = cr.right, i = x - r.left; x < r.right; x++, i++)
((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA);
}
for(int y = cr.bottom; y < r.bottom; y++, dst += dstpitch)
for(int x = r.left, i = 0; x < r.right; x++, i++)
((T*)dst)[i] = (T)(this->*rt)(x, y, TEX0, TEXA);
}
}
//
HRESULT GSLocalMemory::SaveBMP(LPCTSTR fn, DWORD bp, DWORD bw, DWORD psm, int w, int h)

View File

@@ -907,12 +907,14 @@ public:
void unSwizzleTexture4HHNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA);
void ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP);
void ReadTextureNP2(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP);
//
static DWORD m_xtbl[1024], m_ytbl[1024];
template<typename T> void ReadTexture(CRect r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP, readTexel rt, unSwizzleTexture st);
template<typename T> void ReadTexture2(CRect r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, readTexel rt, unSwizzleTexture st);
HRESULT SaveBMP(LPCTSTR fn, DWORD bp, DWORD bw, DWORD psm, int w, int h);
};

View File

@@ -25,7 +25,7 @@
int s_n = 0;
bool s_dump = false;
bool s_save = false;
bool s_save = true;
bool s_savez = false;
GSRendererHW::GSRendererHW(BYTE* base, bool mt, void (*irq)(), bool nloophack)
@@ -424,7 +424,8 @@ if(s_dump)
GSTextureFX::PSSelector ps_sel;
ps_sel.fst = PRIM->FST;
ps_sel.clamp = 0;
ps_sel.wms = m_context->CLAMP.WMS;
ps_sel.wmt = m_context->CLAMP.WMT;
ps_sel.bpp = 0;
ps_sel.aem = m_env.TEXA.AEM;
ps_sel.tfx = m_context->TEX0.TFX;
@@ -436,6 +437,9 @@ if(s_dump)
ps_sel.fba = m_context->FBA.FBA;
ps_sel.aout = m_context->FRAME.PSM == PSM_PSMCT16 || m_context->FRAME.PSM == PSM_PSMCT16S || (m_context->FRAME.FBMSK & 0xff000000) == 0x7f000000 ? 1 : 0;
//if(ps_sel.wms == 3) ps_sel.wms = 0;
//if(ps_sel.wmt == 3) ps_sel.wmt = 0;
GSTextureFX::PSSamplerSelector ps_ssel;
ps_ssel.min = m_filter == 2 ? (m_context->TEX1.MMIN & 1) : m_filter;
@@ -445,9 +449,9 @@ if(s_dump)
GSTextureFX::PSConstantBuffer ps_cb;
memset(&ps_cb, 0, sizeof(ps_cb));
ps_cb.FogColor = D3DXVECTOR4((float)(int)m_env.FOGCOL.FCR / 255, (float)(int)m_env.FOGCOL.FCG / 255, (float)(int)m_env.FOGCOL.FCB / 255, 0);
ps_cb.ClampMin = D3DXVECTOR2(-4096, -4096);
ps_cb.ClampMax = D3DXVECTOR2(+4096, +4096);
ps_cb.TA0 = (float)(int)m_env.TEXA.TA0 / 255;
ps_cb.TA1 = (float)(int)m_env.TEXA.TA1 / 255;
ps_cb.AREF = (float)(int)m_context->TEST.AREF / 255;
@@ -470,30 +474,46 @@ if(s_dump)
switch(m_context->CLAMP.WMS)
{
case 0: case 3: ps_ssel.tau = 1; break;
case 1: case 2: ps_ssel.tau = 0; break;
default: __assume(0);
case 0:
ps_ssel.tau = 1;
break;
case 1:
ps_ssel.tau = 0;
break;
case 2:
ps_cb.MINU = (float)(int)m_context->CLAMP.MINU / (1 << m_context->TEX0.TW);
ps_cb.MAXU = (float)(int)m_context->CLAMP.MAXU / (1 << m_context->TEX0.TW);
ps_ssel.tau = 0;
break;
case 3:
ps_cb.UMSK = m_context->CLAMP.MINU;
ps_cb.UFIX = m_context->CLAMP.MAXU;
ps_ssel.tau = 1;
break;
default:
__assume(0);
}
switch(m_context->CLAMP.WMT)
{
case 0: case 3: ps_ssel.tav = 1; break;
case 1: case 2: ps_ssel.tav = 0; break;
default: __assume(0);
}
if(m_context->CLAMP.WMS == 2)
{
ps_cb.ClampMin.x = (float)(int)m_context->CLAMP.MINU / (1 << m_context->TEX0.TW);
ps_cb.ClampMax.x = (float)(int)m_context->CLAMP.MAXU / (1 << m_context->TEX0.TW);
ps_sel.clamp = 1;
}
if(m_context->CLAMP.WMT == 2)
{
ps_cb.ClampMin.y = (float)(int)m_context->CLAMP.MINV / (1 << m_context->TEX0.TH);
ps_cb.ClampMax.y = (float)(int)m_context->CLAMP.MAXV / (1 << m_context->TEX0.TH);
ps_sel.clamp = 1;
case 0:
ps_ssel.tav = 1;
break;
case 1:
ps_ssel.tav = 0;
break;
case 2:
ps_cb.MINV = (float)(int)m_context->CLAMP.MINV / (1 << m_context->TEX0.TH);
ps_cb.MAXV = (float)(int)m_context->CLAMP.MAXV / (1 << m_context->TEX0.TH);
ps_ssel.tav = 0;
break;
case 3:
ps_cb.VMSK = m_context->CLAMP.MINV;
ps_cb.VFIX = m_context->CLAMP.MAXV;
ps_ssel.tav = 1;
break;
default:
__assume(0);
}
float w = (float)(int)tex->m_texture.m_desc.Width;
@@ -657,32 +677,25 @@ void GSRendererHW::MinMaxUV(int w, int h, CRect& r)
{
r.SetRect(0, 0, w, h);
if(m_count > 100)
{
return;
}
uvmm_t uv;
uv.umin = uv.vmin = 0;
uv.umax = uv.vmax = 1;
if(m_context->CLAMP.WMS < 3 || m_context->CLAMP.WMT < 3)
{
uvmm_t uv;
uv.umin = uv.vmin = 0;
uv.umax = uv.vmax = 1;
if(PRIM->FST)
if(m_count < 100)
{
UVMinMax(m_count, (vertex_t*)m_vertices, &uv);
if(PRIM->FST)
{
UVMinMax(m_count, (vertex_t*)m_vertices, &uv);
uv.umin *= 1.0f / (16 << m_context->TEX0.TW);
uv.umax *= 1.0f / (16 << m_context->TEX0.TW);
uv.vmin *= 1.0f / (16 << m_context->TEX0.TH);
uv.vmax *= 1.0f / (16 << m_context->TEX0.TH);
}
else
{
// FIXME
if(m_count > 0)// && m_count < 100)
uv.umin *= 1.0f / (16 << m_context->TEX0.TW);
uv.umax *= 1.0f / (16 << m_context->TEX0.TW);
uv.vmin *= 1.0f / (16 << m_context->TEX0.TH);
uv.vmax *= 1.0f / (16 << m_context->TEX0.TH);
}
else
{
uv.umin = uv.vmin = +1e10;
uv.umax = uv.vmax = -1e10;
@@ -699,86 +712,99 @@ void GSRendererHW::MinMaxUV(int w, int h, CRect& r)
}
}
}
CSize bs = GSLocalMemory::m_psm[m_context->TEX0.PSM].bs;
CSize bsm(bs.cx-1, bs.cy-1);
if(m_context->CLAMP.WMS < 3)
{
if(m_context->CLAMP.WMS == 0)
{
float fmin = floor(uv.umin);
float fmax = floor(uv.umax);
if(fmin != fmax) {uv.umin = 0; uv.umax = 1.0f;}
else {uv.umin -= fmin; uv.umax -= fmax;}
// FIXME:
if(uv.umin == 0 && uv.umax != 1.0f) uv.umax = 1.0f;
}
else if(m_context->CLAMP.WMS == 1)
{
if(uv.umin < 0) uv.umin = 0;
else if(uv.umin > 1.0f) uv.umin = 1.0f;
if(uv.umax < 0) uv.umax = 0;
else if(uv.umax > 1.0f) uv.umax = 1.0f;
if(uv.umin > uv.umax) uv.umin = uv.umax;
}
else if(m_context->CLAMP.WMS == 2)
{
float minu = 1.0f * m_context->CLAMP.MINU / w;
float maxu = 1.0f * m_context->CLAMP.MAXU / w;
if(uv.umin < minu) uv.umin = minu;
else if(uv.umin > maxu) uv.umin = maxu;
if(uv.umax < minu) uv.umax = minu;
else if(uv.umax > maxu) uv.umax = maxu;
if(uv.umin > uv.umax) uv.umin = uv.umax;
}
r.left = max((int)(uv.umin * w) & ~bsm.cx, 0);
r.right = min(((int)(uv.umax * w) + bsm.cx + 1) & ~bsm.cx, w);
}
if(m_context->CLAMP.WMT < 3)
{
if(m_context->CLAMP.WMT == 0)
{
float fmin = floor(uv.vmin);
float fmax = floor(uv.vmax);
if(fmin != fmax) {uv.vmin = 0; uv.vmax = 1.0f;}
else {uv.vmin -= fmin; uv.vmax -= fmax;}
// FIXME:
if(uv.vmin == 0 && uv.vmax != 1.0f) uv.vmax = 1.0f;
}
else if(m_context->CLAMP.WMT == 1)
{
if(uv.vmin < 0) uv.vmin = 0;
else if(uv.vmin > 1.0f) uv.vmin = 1.0f;
if(uv.vmax < 0) uv.vmax = 0;
else if(uv.vmax > 1.0f) uv.vmax = 1.0f;
if(uv.vmin > uv.vmax) uv.vmin = uv.vmax;
}
else if(m_context->CLAMP.WMT == 2)
{
float minv = 1.0f * m_context->CLAMP.MINV / h;
float maxv = 1.0f * m_context->CLAMP.MAXV / h;
if(uv.vmin < minv) uv.vmin = minv;
else if(uv.vmin > maxv) uv.vmin = maxv;
if(uv.vmax < minv) uv.vmax = minv;
else if(uv.vmax > maxv) uv.vmax = maxv;
if(uv.vmin > uv.vmax) uv.vmin = uv.vmax;
}
r.top = max((int)(uv.vmin * h) & ~bsm.cy, 0);
r.bottom = min(((int)(uv.vmax * h) + bsm.cy + 1) & ~bsm.cy, h);
}
}
//ASSERT(r.left <= r.right);
//ASSERT(r.top <= r.bottom);
CSize bs = GSLocalMemory::m_psm[m_context->TEX0.PSM].bs;
CSize bsm(bs.cx - 1, bs.cy - 1);
if(m_context->CLAMP.WMS != 3)
{
if(m_context->CLAMP.WMS == 0)
{
float fmin = floor(uv.umin);
float fmax = floor(uv.umax);
if(fmin != fmax) {uv.umin = 0; uv.umax = 1.0f;}
else {uv.umin -= fmin; uv.umax -= fmax;}
// FIXME:
if(uv.umin == 0 && uv.umax != 1.0f) uv.umax = 1.0f;
}
else if(m_context->CLAMP.WMS == 1)
{
if(uv.umin < 0) uv.umin = 0;
else if(uv.umin > 1.0f) uv.umin = 1.0f;
if(uv.umax < 0) uv.umax = 0;
else if(uv.umax > 1.0f) uv.umax = 1.0f;
if(uv.umin > uv.umax) uv.umin = uv.umax;
}
else if(m_context->CLAMP.WMS == 2)
{
float minu = 1.0f * m_context->CLAMP.MINU / w;
float maxu = 1.0f * m_context->CLAMP.MAXU / w;
if(uv.umin < minu) uv.umin = minu;
else if(uv.umin > maxu) uv.umin = maxu;
if(uv.umax < minu) uv.umax = minu;
else if(uv.umax > maxu) uv.umax = maxu;
if(uv.umin > uv.umax) uv.umin = uv.umax;
}
r.left = (int)(uv.umin * w);
r.right = (int)(uv.umax * w);
}
else
{
r.left = m_context->CLAMP.MAXU;
r.right = r.left + (m_context->CLAMP.MINU + 1);
}
if(m_context->CLAMP.WMT != 3)
{
if(m_context->CLAMP.WMT == 0)
{
float fmin = floor(uv.vmin);
float fmax = floor(uv.vmax);
if(fmin != fmax) {uv.vmin = 0; uv.vmax = 1.0f;}
else {uv.vmin -= fmin; uv.vmax -= fmax;}
// FIXME:
if(uv.vmin == 0 && uv.vmax != 1.0f) uv.vmax = 1.0f;
}
else if(m_context->CLAMP.WMT == 1)
{
if(uv.vmin < 0) uv.vmin = 0;
else if(uv.vmin > 1.0f) uv.vmin = 1.0f;
if(uv.vmax < 0) uv.vmax = 0;
else if(uv.vmax > 1.0f) uv.vmax = 1.0f;
if(uv.vmin > uv.vmax) uv.vmin = uv.vmax;
}
else if(m_context->CLAMP.WMT == 2)
{
float minv = 1.0f * m_context->CLAMP.MINV / h;
float maxv = 1.0f * m_context->CLAMP.MAXV / h;
if(uv.vmin < minv) uv.vmin = minv;
else if(uv.vmin > maxv) uv.vmin = maxv;
if(uv.vmax < minv) uv.vmax = minv;
else if(uv.vmax > maxv) uv.vmax = maxv;
if(uv.vmin > uv.vmax) uv.vmin = uv.vmax;
}
r.top = (int)(uv.vmin * h);
r.bottom = (int)(uv.vmax * h);
}
else
{
r.top = m_context->CLAMP.MAXV;
r.bottom = r.top + (m_context->CLAMP.MINV + 1);
}
r.left = max(r.left & ~bsm.cx, 0);
r.right = min((r.right + bsm.cx + 1) & ~bsm.cx, w);
r.top = max(r.top & ~bsm.cy, 0);
r.bottom = min((r.bottom + bsm.cy + 1) & ~bsm.cy, h);
}
void GSRendererHW::SetupDATE(GSTextureCache::GSRenderTarget* rt, GSTextureCache::GSDepthStencil* ds)

View File

@@ -40,7 +40,6 @@ bool GSTextureCache::GSTexture::Create()
HRESULT hr;
m_TEX0 = m_tc->m_renderer->m_context->TEX0;
m_CLAMP = m_tc->m_renderer->m_context->CLAMP;
DWORD psm = m_TEX0.PSM;
@@ -97,7 +96,6 @@ bool GSTextureCache::GSTexture::Create(GSRenderTarget* rt)
m_scale = rt->m_scale;
m_TEX0 = m_tc->m_renderer->m_context->TEX0;
m_CLAMP = m_tc->m_renderer->m_context->CLAMP;
m_rendered = true;
int tw = 1 << m_TEX0.TW;
@@ -292,7 +290,7 @@ void GSTextureCache::GSTexture::Update()
BYTE* bits = buff + pitch * r.top + (r.left * m_bpp >> 3);
GSLocalMemory::readTexture rt = &GSLocalMemory::ReadTextureNP;
GSLocalMemory::readTexture rt = &GSLocalMemory::ReadTextureNP2;
(m_tc->m_renderer->m_mem.*rt)(r, bits, pitch, m_tc->m_renderer->m_context->TEX0, m_tc->m_renderer->m_env.TEXA, m_tc->m_renderer->m_context->CLAMP);

View File

@@ -201,7 +201,6 @@ GSTextureCache::GSDepthStencil* GSTextureCache::GetDepthStencil(const GIFRegTEX0
GSTextureCache::GSTexture* GSTextureCache::GetTexture()
{
const GIFRegTEX0& TEX0 = m_renderer->m_context->TEX0;
const GIFRegCLAMP& CLAMP = m_renderer->m_context->CLAMP;
DWORD clut[256];
@@ -271,7 +270,6 @@ GSTextureCache::GSTexture* GSTextureCache::GetTexture()
{
if(TEX0.PSM == t->m_TEX0.PSM && TEX0.TBW == t->m_TEX0.TBW
&& TEX0.TW == t->m_TEX0.TW && TEX0.TH == t->m_TEX0.TH
&& (CLAMP.WMS != 3 && t->m_CLAMP.WMS != 3 && CLAMP.WMT != 3 && t->m_CLAMP.WMT != 3 || CLAMP.i64 == t->m_CLAMP.i64)
&& (pal == 0 || TEX0.CPSM == t->m_TEX0.CPSM && !memcmp(t->m_clut, clut, pal * sizeof(clut[0]))))
{
m_tex.MoveToHead(pos);

View File

@@ -75,7 +75,6 @@ public:
bool GetDirtyRect(CRect& r);
public:
GIFRegCLAMP m_CLAMP;
DWORD m_clut[256]; // *
CRect m_valid;
int m_bpp;

View File

@@ -194,35 +194,37 @@ void GSTextureFX::UpdatePS(PSSelector sel, PSSamplerSelector ssel)
if(!(ps = m_ps.Lookup(sel)))
{
CStringA str[12];
CStringA str[13];
str[0].Format("%d", sel.fst);
str[1].Format("%d", sel.clamp);
str[2].Format("%d", sel.bpp);
str[3].Format("%d", sel.aem);
str[4].Format("%d", sel.tfx);
str[5].Format("%d", sel.tcc);
str[6].Format("%d", sel.ate);
str[7].Format("%d", sel.atst);
str[8].Format("%d", sel.fog);
str[9].Format("%d", sel.clr1);
str[10].Format("%d", sel.fba);
str[11].Format("%d", sel.aout);
str[1].Format("%d", sel.wms);
str[2].Format("%d", sel.wmt);
str[3].Format("%d", sel.bpp);
str[4].Format("%d", sel.aem);
str[5].Format("%d", sel.tfx);
str[6].Format("%d", sel.tcc);
str[7].Format("%d", sel.ate);
str[8].Format("%d", sel.atst);
str[9].Format("%d", sel.fog);
str[10].Format("%d", sel.clr1);
str[11].Format("%d", sel.fba);
str[12].Format("%d", sel.aout);
D3D10_SHADER_MACRO macro[] =
{
{"FST", str[0]},
{"CLAMP", str[1]},
{"BPP", str[2]},
{"AEM", str[3]},
{"TFX", str[4]},
{"TCC", str[5]},
{"ATE", str[6]},
{"ATST", str[7]},
{"FOG", str[8]},
{"CLR1", str[9]},
{"FBA", str[10]},
{"AOUT", str[11]},
{"WMS", str[1]},
{"WMT", str[2]},
{"BPP", str[3]},
{"AEM", str[4]},
{"TFX", str[5]},
{"TCC", str[6]},
{"ATE", str[7]},
{"ATST", str[8]},
{"FOG", str[9]},
{"CLR1", str[10]},
{"FBA", str[11]},
{"AOUT", str[12]},
{NULL, NULL},
};

View File

@@ -40,8 +40,14 @@ public:
struct PSConstantBuffer
{
D3DXVECTOR4 FogColor;
D3DXVECTOR2 ClampMin;
D3DXVECTOR2 ClampMax;
float MINU;
float MAXU;
float MINV;
float MAXV;
DWORD UMSK;
DWORD UFIX;
DWORD VMSK;
DWORD VFIX;
float TA0;
float TA1;
float AREF;
@@ -57,7 +63,8 @@ public:
struct
{
DWORD fst:1;
DWORD clamp:1;
DWORD wms:2;
DWORD wmt:2;
DWORD bpp:3;
DWORD aem:1;
DWORD tfx:3;
@@ -72,7 +79,7 @@ public:
DWORD dw;
operator DWORD() {return dw & 0x3ffff;}
operator DWORD() {return dw & 0x1fffff;}
};
union GSSelector

View File

@@ -112,8 +112,14 @@ SamplerState Sampler;
cbuffer cb1
{
float4 FogColor;
float2 ClampMin;
float2 ClampMax;
float MINU;
float MAXU;
float MINV;
float MAXV;
uint UMSK;
uint UFIX;
uint VMSK;
uint VFIX;
float TA0;
float TA1;
float AREF;
@@ -139,7 +145,8 @@ struct PS_OUTPUT
#ifndef FST
#define FST 0
#define CLAMP 0
#define WMS 2
#define WMT 3
#define BPP 0
#define AEM 0
#define TFX 0
@@ -169,6 +176,16 @@ float4 Extract16(uint i)
return f;
}
float RegionRepeat(float tc, float size, float rsize, uint msk, uint fix)
{
tc *= size;
float f = frac(tc);
tc = (float)(((int)tc & msk) | fix);
tc += f;
tc *= rsize;
return tc;
}
PS_OUTPUT ps_main(PS_INPUT input)
{
float2 tc = input.t.xy;
@@ -177,10 +194,25 @@ PS_OUTPUT ps_main(PS_INPUT input)
{
tc /= input.t.w;
}
if(CLAMP == 1)
if(WMS == 2)
{
tc = clamp(tc, ClampMin, ClampMax);
tc.x = clamp(tc.x, MINU, MAXU);
}
if(WMS == 3)
{
tc.x = RegionRepeat(tc.x, WH.x, rWrH.x, UMSK, UFIX);
}
if(WMT == 2)
{
tc.y = clamp(tc.y, MINV, MAXV);
}
if(WMT == 3)
{
tc.y = RegionRepeat(tc.y, WH.y, rWrH.y, VMSK, VFIX);
}
float4 t;

View File

@@ -530,9 +530,45 @@ void GSTextureCache::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const
if(HasSharedBits(BITBLTBUF.SBP, BITBLTBUF.SPSM, rt->m_TEX0.TBP0, rt->m_TEX0.PSM))
{
rt->Read(r);
break;
return;
}
}
GSRenderTarget* rt2 = NULL;
int ymin = INT_MAX;
pos = m_rt.GetHeadPosition();
while(pos)
{
GSRenderTarget* rt = m_rt.GetNext(pos);
if(HasSharedBits(BITBLTBUF.SPSM, rt->m_TEX0.PSM) && BITBLTBUF.SBP > rt->m_TEX0.TBP0)
{
// ffx2 pause screen background
DWORD rowsize = BITBLTBUF.SBW * 8192;
DWORD offset = (BITBLTBUF.SBP - rt->m_TEX0.TBP0) * 256;
if(rowsize > 0 && offset % rowsize == 0)
{
int y = m_renderer->m_mem.m_psm[BITBLTBUF.SPSM].pgs.cy * offset / rowsize;
if(y < ymin && y < 512)
{
rt2 = rt;
ymin = y;
}
}
}
}
if(rt2)
{
rt2->Read(CRect(r.left, r.top + ymin, r.right, r.bottom + ymin));
}
// TODO: ds
}
void GSTextureCache::IncAge()