GSDX: Partial COLCLAMP support.

Fixes shadows in Ico and Shadow of the Colossus and hopefully fixes more effects in other games.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2702 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
sudonim1 2010-03-12 19:01:05 +00:00
parent 58c75437d4
commit e8c73cef42
6 changed files with 96 additions and 6 deletions

View File

@ -93,6 +93,7 @@ public:
GSVector4 MinMax;
GSVector4 MinF_TA;
GSVector4i MskFix;
GSVector4 ChannelMask;
struct PSConstantBuffer()
{
@ -102,6 +103,7 @@ public:
MinMax = GSVector4::zero();
MinF_TA = GSVector4::zero();
MskFix = GSVector4i::zero();
ChannelMask = GSVector4(1,1,1,1);
}
__forceinline bool Update(const PSConstantBuffer* cb)
@ -170,12 +172,13 @@ public:
uint32 aout:1;
uint32 rt:1;
uint32 ltf:1;
uint32 colclip:2;
};
uint32 key;
};
operator uint32() {return key & 0x3fffff;}
operator uint32() {return key & 0xffffff;}
PSSelector() : key(0) {}
};
@ -234,6 +237,7 @@ public:
uint32 wg:1;
uint32 wb:1;
uint32 wa:1;
uint32 negative:1;
};
struct
@ -246,7 +250,7 @@ public:
uint32 key;
};
operator uint32() {return key & 0x1fff;}
operator uint32() {return key & 0x3fff;}
OMBlendSelector() : key(0) {}

View File

@ -226,6 +226,11 @@ public:
GSDeviceDX::PSSamplerSelector ps_ssel;
GSDeviceDX::PSConstantBuffer ps_cb;
if (env.COLCLAMP.CLAMP == 0) {
ps_sel.colclip = 1;
ps_cb.ChannelMask = GSVector4((float)om_bsel.wr, (float)om_bsel.wg, (float)om_bsel.wb, (float)om_bsel.wa);
}
ps_sel.clr1 = om_bsel.IsCLR1();
ps_sel.fba = context->FBA.FBA;
ps_sel.aout = context->FRAME.PSM == PSM_PSMCT16 || context->FRAME.PSM == PSM_PSMCT16S || (context->FRAME.FBMSK & 0xff000000) == 0x7f000000 ? 1 : 0;
@ -325,6 +330,20 @@ public:
if(context->TEST.DoFirstPass())
{
dev.DrawPrimitive();
if (env.COLCLAMP.CLAMP == 0)
{
GSDeviceDX::OMBlendSelector om_bselneg(om_bsel);
GSDeviceDX::PSSelector ps_selneg(ps_sel);
om_bselneg.negative = 1;
ps_selneg.colclip = 2;
dev.SetupOM(om_dssel, om_bselneg, afix);
dev.SetupPS(ps_selneg, &ps_cb, ps_ssel);
dev.DrawPrimitive();
}
}
if(context->TEST.DoSecondPass())
@ -376,6 +395,20 @@ public:
dev.SetupOM(om_dssel, om_bsel, afix);
dev.DrawPrimitive();
if (env.COLCLAMP.CLAMP == 0)
{
GSDeviceDX::OMBlendSelector om_bselneg(om_bsel);
GSDeviceDX::PSSelector ps_selneg(ps_sel);
om_bselneg.negative = 1;
ps_selneg.colclip = 2;
dev.SetupOM(om_dssel, om_bselneg, afix);
dev.SetupPS(ps_selneg, &ps_cb, ps_ssel);
dev.DrawPrimitive();
}
}
}

View File

@ -177,7 +177,7 @@ void GSDevice10::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
if(i == m_ps.end())
{
string str[13];
string str[14];
str[0] = format("%d", sel.fst);
str[1] = format("%d", sel.wms);
@ -192,6 +192,7 @@ void GSDevice10::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
str[10] = format("%d", sel.fba);
str[11] = format("%d", sel.aout);
str[12] = format("%d", sel.ltf);
str[13] = format("%d", sel.colclip);
D3D10_SHADER_MACRO macro[] =
{
@ -208,6 +209,7 @@ void GSDevice10::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
{"PS_FBA", str[10].c_str()},
{"PS_AOUT", str[11].c_str()},
{"PS_LTF", str[12].c_str()},
{"PS_COLCLIP", str[13].c_str()},
{NULL, NULL},
};
@ -362,6 +364,16 @@ void GSDevice10::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uin
if (bd.DestBlend >= 3 && bd.DestBlend <= 6)
bd.DestBlend = (D3D10_BLEND)((int)bd.DestBlend + 13);
// Not very good but I don't wanna write another 81 row table
if (bsel.negative) {
if (bd.BlendOp == D3D10_BLEND_OP_ADD)
bd.BlendOp = D3D10_BLEND_OP_REV_SUBTRACT;
else if (bd.BlendOp == D3D10_BLEND_OP_REV_SUBTRACT)
bd.BlendOp = D3D10_BLEND_OP_ADD;
else
; // god knows, best just not to mess with it for now
}
if(blendMapD3D9[i].bogus == 1)
{
ASSERT(0);

View File

@ -181,7 +181,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
if(i == m_ps.end())
{
string str[13];
string str[14];
str[0] = format("%d", sel.fst);
str[1] = format("%d", sel.wms);
@ -196,6 +196,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
str[10] = format("%d", sel.fba);
str[11] = format("%d", sel.aout);
str[12] = format("%d", sel.ltf);
str[13] = format("%d", sel.colclip);
D3D11_SHADER_MACRO macro[] =
{
@ -212,6 +213,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
{"PS_FBA", str[10].c_str()},
{"PS_AOUT", str[11].c_str()},
{"PS_LTF", str[12].c_str()},
{"PS_COLCLIP", str[13].c_str()},
{NULL, NULL},
};
@ -358,6 +360,16 @@ void GSDevice11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uin
if (bd.RenderTarget[0].DestBlend >= 3 && bd.RenderTarget[0].DestBlend <= 6)
bd.RenderTarget[0].DestBlend = (D3D11_BLEND)((int)bd.RenderTarget[0].DestBlend + 13);
// Not very good but I don't wanna write another 81 row table
if (bsel.negative) {
if (bd.RenderTarget[0].BlendOp == D3D11_BLEND_OP_ADD)
bd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_REV_SUBTRACT;
else if (bd.RenderTarget[0].BlendOp == D3D11_BLEND_OP_REV_SUBTRACT)
bd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
else
; // god knows, best just not to mess with it for now
}
if(blendMapD3D9[i].bogus == 1)
{
ASSERT(0);

View File

@ -144,7 +144,7 @@ void GSDevice9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSel
if(i == m_ps.end())
{
string str[12];
string str[13];
str[0] = format("%d", sel.fst);
str[1] = format("%d", sel.wms);
@ -158,6 +158,7 @@ void GSDevice9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSel
str[9] = format("%d", sel.clr1);
str[10] = format("%d", sel.rt);
str[11] = format("%d", sel.ltf);
str[12] = format("%d", sel.colclip);
D3DXMACRO macro[] =
{
@ -173,6 +174,7 @@ void GSDevice9::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSel
{"PS_CLR1", str[9].c_str()},
{"PS_RT", str[10].c_str()},
{"PS_LTF", str[11].c_str()},
{"PS_COLCLIP", str[12].c_str()},
{NULL, NULL},
};
@ -290,6 +292,16 @@ void GSDevice9::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint
bs->SrcBlendAlpha = D3DBLEND_ONE;
bs->DestBlendAlpha = D3DBLEND_ZERO;
// Not very good but I don't wanna write another 81 row table
if (bsel.negative) {
if (bs->BlendOp == D3DBLENDOP_ADD)
bs->BlendOp = D3DBLENDOP_REVSUBTRACT;
else if (bs->BlendOp == D3DBLENDOP_REVSUBTRACT)
bs->BlendOp = D3DBLENDOP_ADD;
else
; // god knows, best just not to mess with it for now
}
if(blendMapD3D9[i].bogus == 1)
{
ASSERT(0);

View File

@ -33,6 +33,7 @@
#define PS_FBA 0
#define PS_AOUT 0
#define PS_LTF 1
#define PS_COLCLIP 0
#endif
struct VS_INPUT
@ -87,6 +88,7 @@ cbuffer cb1
float2 MinF;
float2 TA;
uint4 MskFix;
float4 ChannelMask;
};
float4 sample_c(float2 uv)
@ -121,6 +123,7 @@ float4 sample_p(float u)
#define PS_CLR1 0
#define PS_RT 0
#define PS_LTF 0
#define PS_COLCLIP 0
#endif
struct VS_INPUT
@ -155,7 +158,7 @@ float4 vs_params[3];
#define VertexOffset vs_params[1]
#define TextureScale vs_params[2].xy
float4 ps_params[5];
float4 ps_params[7];
#define FogColor ps_params[0].bgr
#define AREF ps_params[0].a
@ -164,6 +167,7 @@ float4 ps_params[5];
#define MinMax ps_params[3]
#define MinF ps_params[4].xy
#define TA ps_params[4].zw
#define ChannelMask ps_params[6]
float4 sample_c(float2 uv)
{
@ -505,6 +509,19 @@ float4 ps_color(PS_INPUT input)
c = fog(c, input.t.z);
if (PS_COLCLIP == 2)
{
c.rgb = 256./255. - c.rgb;
}
if (PS_COLCLIP > 0)
{
//clip(128./255. - c.rgb * ChannelMask.rgb);
c.rgb *= ChannelMask.rgb;
if (all(c.rgb >= 128./255))
clip(-1);
c.rgb *= c.rgb < 128./255;
}
if(PS_CLR1) // needed for Cd * (As/Ad/F + 1) blending modes
{
c.rgb = 1;