GSDX: made the paletted texture handling in the cache a bit more sensible to my eyes and implemented interpolation of palette entries for pixels in paletted textures when using the 8 bit textures option. Regressions in some games I think, such as Virtual On (which is very broken anyway), need to investigate what made them work (to some degree) before. Seems to change some performance characteristics favourably to my surprise, but I might just be bad at remembering framerates.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5287 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
sudonim1@gmail.com 2012-06-11 03:27:16 +00:00
parent 8ab8b4592d
commit e8257df98d
4 changed files with 49 additions and 92 deletions

View File

@ -275,9 +275,17 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
if(tex)
{
const GSLocalMemory::psm_t &psm = GSLocalMemory::m_psm[context->TEX0.PSM];
ps_sel.wms = context->CLAMP.WMS;
ps_sel.wmt = context->CLAMP.WMT;
ps_sel.fmt = tex->m_fmt;
if (tex->m_palette)
{
const GSLocalMemory::psm_t &cpsm = GSLocalMemory::m_psm[context->TEX0.CPSM];
ps_sel.fmt = cpsm.fmt | 4;
}
else
ps_sel.fmt = psm.fmt;
ps_sel.aem = env.TEXA.AEM;
ps_sel.tfx = context->TEX0.TFX;
ps_sel.tcc = context->TEX0.TCC;

View File

@ -585,31 +585,24 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
bool hack = false;
if(dst == NULL)
if(m_spritehack && (TEX0.PSM == PSM_PSMT8 || TEX0.PSM == PSM_PSMT8H))
{
if(m_spritehack && (TEX0.PSM == PSM_PSMT8 || TEX0.PSM == PSM_PSMT8H))
{
src->m_spritehack_t = true;
if(m_spritehack == 2 && TEX0.CPSM != PSM_PSMCT16)
src->m_spritehack_t = false;
}
else
src->m_spritehack_t = false;
src->m_spritehack_t = true;
if(m_paltex && psm.pal > 0)
{
src->m_fmt = FMT_8;
if(m_spritehack == 2 && TEX0.CPSM != PSM_PSMCT16)
src->m_spritehack_t = false;
}
else
src->m_spritehack_t = false;
src->m_texture = m_renderer->m_dev->CreateTexture(tw, th, Get8bitFormat());
src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
}
else
{
src->m_fmt = FMT_32;
src->m_texture = m_renderer->m_dev->CreateTexture(tw, th);
}
if (m_paltex && psm.pal > 0)
{
src->m_texture = m_renderer->m_dev->CreateTexture(tw, th, Get8bitFormat());
src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
}
else if (dst == NULL || dst->m_type != RenderTarget /* TODO */)
{
src->m_texture = m_renderer->m_dev->CreateTexture(tw, th);
}
else
{
@ -617,13 +610,6 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
src->m_target = true;
if(dst->m_type != RenderTarget)
{
// TODO
delete src;
return NULL;
}
dst->Update();
GSTexture* tmp = NULL;
@ -754,34 +740,6 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
else
ASSERT(0);
switch(TEX0.PSM)
{
default:
// Note: this assertion triggers in Xenosaga2 after the first intro scenes, when
// gameplay first begins (in the city).
ASSERT(0);
case PSM_PSMCT32:
src->m_fmt = FMT_32;
break;
case PSM_PSMCT24:
src->m_fmt = FMT_24;
break;
case PSM_PSMCT16:
case PSM_PSMCT16S:
src->m_fmt = FMT_16;
break;
// actually if we end up in that side of the function with a paletted format, we're probably already screwed
case PSM_PSMT8:
case PSM_PSMT8H:
case PSM_PSMT4:
case PSM_PSMT4HL:
case PSM_PSMT4HH:
src->m_fmt = FMT_8;
break;
}
if (psm.pal > 0)
src->m_palette = m_renderer->m_dev->CreateTexture(256, 1);
if(tmp != NULL)
{
m_renderer->m_dev->Recycle(dst->m_texture);
@ -887,7 +845,6 @@ GSTextureCache::Source::Source(GSRenderer* r, const GIFRegTEX0& TEX0, const GIFR
: Surface(r, temp)
, m_palette(NULL)
, m_initpalette(true)
, m_fmt(0)
, m_target(false)
, m_complete(false)
, m_p2t(NULL)
@ -1005,7 +962,7 @@ void GSTextureCache::Source::Update(const GSVector4i& rect)
if(blocks > 0)
{
m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, bs.x * bs.y * blocks << (m_fmt == FMT_32 ? 2 : 0));
m_renderer->m_perfmon.Put(GSPerfMon::Unswizzle, bs.x * bs.y * blocks << (m_palette ? 2 : 0));
Flush(m_write.count);
}
@ -1061,7 +1018,7 @@ void GSTextureCache::Source::Flush(uint32 count)
GSLocalMemory::readTexture rtx = psm.rtx;
if(m_fmt == FMT_8)
if(m_palette)
{
pitch >>= 2;
rtx = psm.rtxP;

View File

@ -29,14 +29,6 @@ class GSTextureCache
public:
enum {RenderTarget, DepthStencil};
enum TextureFormatType
{
FMT_32,
FMT_24,
FMT_16,
FMT_8,
};
class Surface : public GSAlignedClass<32>
{
protected:
@ -68,7 +60,6 @@ public:
bool m_initpalette;
uint32 m_valid[MAX_PAGES]; // each uint32 bits map to the 32 blocks of that page
uint32* m_clut;
int m_fmt;
bool m_target;
bool m_complete;
bool m_repeating;

View File

@ -2,7 +2,7 @@
#define FMT_32 0
#define FMT_24 1
#define FMT_16 2
#define FMT_8 3
#define FMT_PAL 4 /* flag bit */
#if SHADER_MODEL >= 0x400
@ -21,7 +21,7 @@
#define PS_FST 0
#define PS_WMS 0
#define PS_WMT 0
#define PS_FMT FMT_8
#define PS_FMT FMT_32
#define PS_AEM 0
#define PS_TFX 0
#define PS_TCC 1
@ -127,7 +127,7 @@ float4 sample_rt(float2 uv)
#define PS_FST 0
#define PS_WMS 0
#define PS_WMT 0
#define PS_FMT FMT_8
#define PS_FMT FMT_32
#define PS_AEM 0
#define PS_TFX 0
#define PS_TCC 0
@ -387,7 +387,7 @@ float4 sample(float2 st, float q)
float4x4 c;
if(PS_FMT == FMT_8)
if(PS_FMT & FMT_PAL)
{
c = sample_4p(sample_4a(uv));
}
@ -396,6 +396,24 @@ float4 sample(float2 st, float q)
c = sample_4c(uv);
}
for (uint i = 0; i < 4; i++)
{
if((PS_FMT & ~FMT_PAL) == FMT_32)
{
#if SHADER_MODEL <= 0x300
if(PS_RT) c[i].a *= 128.0f / 255;
#endif
}
else if((PS_FMT & ~FMT_PAL) == FMT_24)
{
c[i].a = !PS_AEM || any(c[i].rgb) ? TA.x : 0;
}
else if((PS_FMT & ~FMT_PAL) == FMT_16)
{
c[i].a = c[i].a >= 0.5 ? TA.y : !PS_AEM || any(c[i].rgb) ? TA.x : 0;
}
}
if(PS_LTF)
{
t = lerp(lerp(c[0], c[1], dd.x), lerp(c[2], c[3], dd.x), dd.y);
@ -405,24 +423,7 @@ float4 sample(float2 st, float q)
t = c[0];
}
}
if(PS_FMT == FMT_32)
{
#if SHADER_MODEL <= 0x300
if(PS_RT) t.a *= 128.0f / 255;
#endif
}
else if(PS_FMT == FMT_24)
{
t.a = !PS_AEM || any(t.rgb) ? TA.x : 0;
}
else if(PS_FMT == FMT_16)
{
// a bit incompatible with up-scaling because the 1 bit alpha is interpolated
t.a = t.a >= 0.5 ? TA.y : !PS_AEM || any(t.rgb) ? TA.x : 0;
}
return t;
}