From e8c73cef420d809424f40ea907cb32096b915dfd Mon Sep 17 00:00:00 2001 From: sudonim1 Date: Fri, 12 Mar 2010 19:01:05 +0000 Subject: [PATCH] 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 --- plugins/GSdx/GSDeviceDX.h | 8 ++++++-- plugins/GSdx/GSRendererDX.h | 33 +++++++++++++++++++++++++++++++++ plugins/GSdx/GSTextureFX10.cpp | 14 +++++++++++++- plugins/GSdx/GSTextureFX11.cpp | 14 +++++++++++++- plugins/GSdx/GSTextureFX9.cpp | 14 +++++++++++++- plugins/GSdx/res/tfx.fx | 19 ++++++++++++++++++- 6 files changed, 96 insertions(+), 6 deletions(-) diff --git a/plugins/GSdx/GSDeviceDX.h b/plugins/GSdx/GSDeviceDX.h index a9aedb82b0..ea5200a5a9 100644 --- a/plugins/GSdx/GSDeviceDX.h +++ b/plugins/GSdx/GSDeviceDX.h @@ -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) {} diff --git a/plugins/GSdx/GSRendererDX.h b/plugins/GSdx/GSRendererDX.h index 1546b209e3..38158969ee 100644 --- a/plugins/GSdx/GSRendererDX.h +++ b/plugins/GSdx/GSRendererDX.h @@ -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(); + } } } diff --git a/plugins/GSdx/GSTextureFX10.cpp b/plugins/GSdx/GSTextureFX10.cpp index e6b7721e43..a43b60fde3 100644 --- a/plugins/GSdx/GSTextureFX10.cpp +++ b/plugins/GSdx/GSTextureFX10.cpp @@ -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); diff --git a/plugins/GSdx/GSTextureFX11.cpp b/plugins/GSdx/GSTextureFX11.cpp index 297330ac00..1b621584bf 100644 --- a/plugins/GSdx/GSTextureFX11.cpp +++ b/plugins/GSdx/GSTextureFX11.cpp @@ -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); diff --git a/plugins/GSdx/GSTextureFX9.cpp b/plugins/GSdx/GSTextureFX9.cpp index 1919ef46ff..c5bb0a9923 100644 --- a/plugins/GSdx/GSTextureFX9.cpp +++ b/plugins/GSdx/GSTextureFX9.cpp @@ -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); diff --git a/plugins/GSdx/res/tfx.fx b/plugins/GSdx/res/tfx.fx index 803e853bb9..6ac154f584 100644 --- a/plugins/GSdx/res/tfx.fx +++ b/plugins/GSdx/res/tfx.fx @@ -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;