Merge pull request #533 from PCSX2/gsdx-impossible-blend

Gsdx impossible blend support on openGL
This commit is contained in:
Gregory Hainaut 2015-05-09 19:49:18 +02:00
commit b89f0cfa4c
9 changed files with 186 additions and 37 deletions

View File

@ -493,12 +493,25 @@ namespace GLLoader {
if (!found_GL_ARB_direct_state_access) {
Emulate_DSA::Init();
}
if (gl_BindTextureUnit == NULL) {
fprintf(stderr, "FATAL ERROR !!!! Failed to setup DSA function pointer!!!\n");
status = false;
}
if (!found_GL_ARB_texture_barrier) {
if (theApp.GetConfig("accurate_blend", 0)) {
fprintf(stderr, "Error GL_ARB_texture_barrier is not supported by your driver so you can't enable accurate_blend! Sorry.\n");
theApp.SetConfig("accurate_blend", 0);
}
}
if (!found_GL_ARB_shader_image_load_store) {
if (theApp.GetConfig("accurate_date", 0)) {
fprintf(stderr, "Error GL_ARB_shader_image_load_store is not supported by your driver so you can't enable accurate_date! Sorry.\n");
theApp.SetConfig("accurate_date", 0);
}
}
fprintf(stderr, "\n");
return status;

View File

@ -632,6 +632,7 @@ GLuint GSDeviceOGL::CompilePS(PSSelector sel)
+ format("#define PS_DATE %d\n", sel.date)
+ format("#define PS_TCOFFSETHACK %d\n", sel.tcoffsethack)
//+ format("#define PS_POINT_SAMPLER %d\n", sel.point_sampler)
+ format("#define PS_BLEND %d\n", sel.blend)
+ format("#define PS_IIP %d\n", sel.iip)
;
@ -1264,32 +1265,32 @@ const GSDeviceOGL::D3D9Blend GSDeviceOGL::m_blendMapD3D9[3*3*3*3] =
{0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO}, // 0020: (Cs - Cs)*F + Cs ==> Cs
{0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ONE}, // 0021: (Cs - Cs)*F + Cd ==> Cd
{0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ZERO}, // 0022: (Cs - Cs)*F + 0 ==> 0
{1, D3DBLENDOP_SUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As
{4, D3DBLENDOP_SUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As
{0, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA}, // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As)
{0, D3DBLENDOP_SUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As
{1, D3DBLENDOP_SUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad
{5, D3DBLENDOP_SUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad
{0, D3DBLENDOP_ADD, D3DBLEND_DESTALPHA, D3DBLEND_INVDESTALPHA}, // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad)
{0, D3DBLENDOP_SUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad
{1, D3DBLENDOP_SUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR}, //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F
{6, D3DBLENDOP_SUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR}, //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F
{0, D3DBLENDOP_ADD, D3DBLEND_BLENDFACTOR, D3DBLEND_INVBLENDFACTOR}, // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F)
{0, D3DBLENDOP_SUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR}, // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F
{1, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_ZERO}, //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1)
{7, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_ZERO}, //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1)
{0, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_ONE}, // 0201: (Cs - 0)*As + Cd ==> Cs*As + Cd
{0, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_ZERO}, // 0202: (Cs - 0)*As + 0 ==> Cs*As
{1, D3DBLENDOP_ADD, D3DBLEND_DESTALPHA, D3DBLEND_ZERO}, //*0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1)
{8, D3DBLENDOP_ADD, D3DBLEND_DESTALPHA, D3DBLEND_ZERO}, //*0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1)
{0, D3DBLENDOP_ADD, D3DBLEND_DESTALPHA, D3DBLEND_ONE}, // 0211: (Cs - 0)*Ad + Cd ==> Cs*Ad + Cd
{0, D3DBLENDOP_ADD, D3DBLEND_DESTALPHA, D3DBLEND_ZERO}, // 0212: (Cs - 0)*Ad + 0 ==> Cs*Ad
{1, D3DBLENDOP_ADD, D3DBLEND_BLENDFACTOR, D3DBLEND_ZERO}, //*0220: (Cs - 0)*F + Cs ==> Cs*(F + 1)
{9, D3DBLENDOP_ADD, D3DBLEND_BLENDFACTOR, D3DBLEND_ZERO}, //*0220: (Cs - 0)*F + Cs ==> Cs*(F + 1)
{0, D3DBLENDOP_ADD, D3DBLEND_BLENDFACTOR, D3DBLEND_ONE}, // 0221: (Cs - 0)*F + Cd ==> Cs*F + Cd
{0, D3DBLENDOP_ADD, D3DBLEND_BLENDFACTOR, D3DBLEND_ZERO}, // 0222: (Cs - 0)*F + 0 ==> Cs*F
{0, D3DBLENDOP_ADD, D3DBLEND_INVSRCALPHA, D3DBLEND_SRCALPHA}, // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As)
{1, D3DBLENDOP_REVSUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As
{10,D3DBLENDOP_REVSUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As
{0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As
{0, D3DBLENDOP_ADD, D3DBLEND_INVDESTALPHA, D3DBLEND_DESTALPHA}, // 1010: (Cd - Cs)*Ad + Cs ==> Cd*Ad + Cs*(1 - Ad)
{1, D3DBLENDOP_REVSUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, //*1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad
{11,D3DBLENDOP_REVSUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, //*1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad
{0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, // 1012: (Cd - Cs)*Ad + 0 ==> Cd*Ad - Cs*Ad
{0, D3DBLENDOP_ADD, D3DBLEND_INVBLENDFACTOR, D3DBLEND_BLENDFACTOR}, // 1020: (Cd - Cs)*F + Cs ==> Cd*F + Cs*(1 - F)
{1, D3DBLENDOP_REVSUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR},//*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F
{12,D3DBLENDOP_REVSUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR},//*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F
{0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR},// 1022: (Cd - Cs)*F + 0 ==> Cd*F - Cs*F
{0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO}, // 1100: (Cd - Cd)*As + Cs ==> Cs
{0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ONE}, // 1101: (Cd - Cd)*As + Cd ==> Cd

View File

@ -65,6 +65,8 @@ public:
void SetBogus(char bogus) { m_bogus = bogus; }
int GetBogus() { return m_bogus; }
void RevertOp()
{
if(m_equation_RGB == GL_FUNC_ADD)
@ -92,7 +94,7 @@ public:
#ifdef ENABLE_OGL_DEBUG
if (m_bogus) {
GL_INS("!!! Bogus blending effect !!!");
fprintf(stderr, "Bogus blending effect used : %s\n", (m_bogus == 1) ? "impossible effect" : "clear effect");
fprintf(stderr, "Bogus blending effect used : %s (%d)\n", (m_bogus > 2) ? "impossible effect" : "clear effect", m_bogus);
}
#endif
if (m_enable) {
@ -254,6 +256,7 @@ class GSDeviceOGL : public GSDevice
GSVector4 WH;
GSVector4 MinF_TA;
GSVector4i MskFix;
GSVector4 AlphaCoeff;
GSVector4 HalfTexel;
GSVector4 MinMax;
@ -267,6 +270,7 @@ class GSDeviceOGL : public GSDevice
MinMax = GSVector4::zero();
MinF_TA = GSVector4::zero();
MskFix = GSVector4i::zero();
AlphaCoeff = GSVector4::zero();
}
__forceinline bool Update(const PSConstantBuffer* cb)
@ -276,13 +280,14 @@ class GSDeviceOGL : public GSDevice
// if WH matches both HalfTexel and TC_OffsetHack do too
// MinMax depends on WH and MskFix so no need to check it too
if(!((a[0] == b[0]) & (a[1] == b[1]) & (a[2] == b[2]) & (a[3] == b[3])).alltrue())
if(!((a[0] == b[0]) & (a[1] == b[1]) & (a[2] == b[2]) & (a[3] == b[3]) & (a[4] == b[4])).alltrue())
{
// Note previous check uses SSE already, a plain copy will be faster than any memcpy
a[0] = b[0];
a[1] = b[1];
a[2] = b[2];
a[3] = b[3];
a[4] = b[4];
return true;
}
@ -318,14 +323,14 @@ class GSDeviceOGL : public GSDevice
uint32 wmt:2;
uint32 ltf:1;
uint32 _free:4;
uint32 blend:4;
};
uint32 key;
};
// FIXME is the & useful ?
operator uint32() {return key & 0x0fffffff;}
operator uint32() {return key & 0xffffffff;}
PSSelector() : key(0) {}
};
@ -623,7 +628,7 @@ class GSDeviceOGL : public GSDevice
void SetupPS(PSSelector sel);
void SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer* ps_cb);
void SetupSampler(PSSamplerSelector ssel);
void SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
int SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix);
GLuint GetSamplerID(PSSamplerSelector ssel);
GLuint GetPaletteSamplerID();

View File

@ -187,6 +187,26 @@ bool GSRendererOGL::PrimitiveOverlap()
return false;
}
void GSRendererOGL::SendDraw(bool require_barrier)
{
GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
if (!require_barrier || !PrimitiveOverlap()) {
dev->DrawIndexedPrimitive();
} else {
ASSERT(m_vt.m_primclass != GS_POINT_CLASS);
ASSERT(m_vt.m_primclass != GS_LINE_CLASS);
ASSERT(GLLoader::found_geometry_shader);
size_t nb_vertex = (m_vt.m_primclass == GS_TRIANGLE_CLASS) ? 3 : 2;
for (size_t p = 0; p < m_index.tail; p += nb_vertex) {
gl_TextureBarrier();
dev->DrawIndexedPrimitive(p, nb_vertex);
}
}
}
void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex)
{
#ifdef ENABLE_OGL_DEBUG
@ -203,6 +223,8 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
bool DATE_GL42 = false;
bool DATE_GL45 = false;
bool require_barrier = false; // For blend (and maybe in date in the future)
ASSERT(m_dev != NULL);
GSDeviceOGL* dev = (GSDeviceOGL*)m_dev;
@ -543,11 +565,25 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
GL_POP();
dev->OMSetColorMaskState(om_csel);
dev->SetupOM(om_dssel, om_bsel, afix);
// Handle blending with care
int bogus_blend = dev->SetupOM(om_dssel, om_bsel, afix);
if (m_accurate_blend && bogus_blend > 2) {
ps_sel.blend = bogus_blend - 3;
dev->SetupPS(ps_sel);
dev->PSSetShaderResource(3, rt);
if (bogus_blend == 6 || bogus_blend == 9 || bogus_blend == 12) {
ps_cb.AlphaCoeff = GSVector4((float)(int)afix / 0x80);
}
require_barrier = ((bogus_blend != 7) && (bogus_blend != 9));
}
dev->SetupCB(&vs_cb, &ps_cb);
if (DATE_GL42) {
GL_PUSH("Date GL42");
ASSERT(bogus_blend <= 2);
// It could be good idea to use stencil in the same time.
// Early stencil test will reduce the number of atomic-load operation
@ -562,7 +598,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
// Don't write anything on the color buffer
dev->OMSetWriteBuffer(GL_NONE);
// Compute primitiveID max that pass the date test
dev->DrawIndexedPrimitive();
SendDraw(false);
// Ask PS to discard shader above the primitiveID max
dev->OMSetWriteBuffer();
@ -581,10 +617,11 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
if(context->TEST.DoFirstPass())
{
dev->DrawIndexedPrimitive();
SendDraw(require_barrier);
if (env.COLCLAMP.CLAMP == 0 && !tex && PRIM->PRIM != GS_POINTLIST)
{
ASSERT(bogus_blend <= 2);
GL_PUSH("COLCLIP");
GSDeviceOGL::OMBlendSelector om_bselneg(om_bsel);
GSDeviceOGL::PSSelector ps_selneg(ps_sel);
@ -595,7 +632,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
dev->SetupOM(om_dssel, om_bselneg, afix);
dev->SetupPS(ps_selneg);
dev->DrawIndexedPrimitive();
SendDraw(false);
dev->SetupOM(om_dssel, om_bsel, afix);
GL_POP();
}
@ -640,10 +677,11 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
dev->OMSetColorMaskState(om_csel);
dev->SetupOM(om_dssel, om_bsel, afix);
dev->DrawIndexedPrimitive();
SendDraw(require_barrier);
if (env.COLCLAMP.CLAMP == 0 && !tex && PRIM->PRIM != GS_POINTLIST)
{
ASSERT(bogus_blend <= 2);
GL_PUSH("COLCLIP");
GSDeviceOGL::OMBlendSelector om_bselneg(om_bsel);
GSDeviceOGL::PSSelector ps_selneg(ps_sel);
@ -654,7 +692,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
dev->SetupOM(om_dssel, om_bselneg, afix);
dev->SetupPS(ps_selneg);
dev->DrawIndexedPrimitive();
SendDraw(false);
GL_POP();
}
}

View File

@ -56,4 +56,6 @@ class GSRendererOGL : public GSRendererHW
void DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex);
bool PrimitiveOverlap();
void SendDraw(bool require_barrier);
};

View File

@ -103,23 +103,24 @@ GSBlendStateOGL* GSDeviceOGL::CreateBlend(OMBlendSelector bsel, uint8 afix)
{
int i = ((bsel.a * 3 + bsel.b) * 3 + bsel.c) * 3 + bsel.d;
bs->EnableBlend();
bs->SetRGB(m_blendMapD3D9[i].op, m_blendMapD3D9[i].src, m_blendMapD3D9[i].dst);
bs->SetBogus(m_blendMapD3D9[i].bogus);
if(m_blendMapD3D9[i].bogus == 1)
{
if (m_blendMapD3D9[i].bogus > 2) {
if (!theApp.GetConfig("accurate_blend", 0)) {
bs->EnableBlend();
if (bsel.a == 0)
bs->SetRGB(m_blendMapD3D9[i].op, GL_ONE, m_blendMapD3D9[i].dst);
else
bs->SetRGB(m_blendMapD3D9[i].op, m_blendMapD3D9[i].src, GL_ONE);
}
const string afixstr = format("%d >> 7", afix);
const char *col[3] = {"Cs", "Cd", "0"};
const char *alpha[3] = {"As", "Ad", afixstr.c_str()};
// FIXME, need to investigate OGL capabilities. Maybe for OGL5 ;)
fprintf(stderr, "Impossible blend for D3D: (%s - %s) * %s + %s\n", col[bsel.a], col[bsel.b], alpha[bsel.c], col[bsel.d]);
} else {
bs->EnableBlend();
}
// Not very good but I don't wanna write another 81 row table
@ -230,7 +231,7 @@ GLuint GSDeviceOGL::GetPaletteSamplerID()
return m_palette_ss;
}
void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix)
int GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix)
{
GSDepthStencilOGL* dss = m_om_dss[dssel];
@ -254,4 +255,6 @@ void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, ui
// Dynamic
// *************************************************************
OMSetBlendState(bs, (float)(int)afix / 0x80);
return bs->GetBogus();
}

View File

@ -38,12 +38,6 @@
//#define DISABLE_DATE
// Allow to dump texture as PNG (require libpng++). It reduces the size of the dump
// and alpha is well supported (on linux)
//#define ENABLE_OGL_PNG
// The next two define allows to dump texture without alpha or only the alpha channel.
//#define ENABLE_OGL_PNG_OPAQUE
//#define ENABLE_OGL_PNG_ALPHA
#if defined(_DEBUG) || defined(_DEVEL)
#define ENABLE_OGL_DEBUG // Create a debug context and check opengl command status. Allow also to dump various textures/states.
@ -54,3 +48,12 @@
#ifdef _WINDOWS
//#define ENABLE_OPENCL
#endif
#if defined(ENABLE_OGL_DEBUG) && defined(__linux__)
// Allow to dump texture as PNG (require libpng++). It reduces the size of the dump
// and alpha is well supported (on linux)
#define ENABLE_OGL_PNG
// The next two define allows to dump texture without alpha or only the alpha channel.
#define ENABLE_OGL_PNG_OPAQUE
#define ENABLE_OGL_PNG_ALPHA
#endif

View File

@ -65,6 +65,7 @@ layout(std140, binding = 21) uniform cb21
vec2 MinF;
vec2 TA;
uvec4 MskFix;
vec4 Af;
vec4 HalfTexel;
vec4 MinMax;
vec4 TC_OffsetHack;
@ -374,6 +375,43 @@ vec4 ps_color()
return c;
}
void ps_blend(inout vec4 c, in float As)
{
vec4 rt = texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0);
// FIXME Ad or Ad * 2?
float Ad = rt.a;
#if PS_BLEND == 1
// {4, D3DBLENDOP_SUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As
c.rgb = c.rgb * (As + 1.0f) - rt.rgb * As;
#elif PS_BLEND == 2
// {5, D3DBLENDOP_SUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad
c.rgb = c.rgb * (Ad + 1.0f) - rt.rgb * Ad;
#elif PS_BLEND == 3
// {6, D3DBLENDOP_SUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR}, //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F
c.rgb = c.rgb * (Af.x + 1.0f) - rt.rgb * Af.x;
#elif PS_BLEND == 4
// {7, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_ZERO}, //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1)
c.rgb = c.rgb * (As + 1.0f); // FIXME Not bogus
#elif PS_BLEND == 5
// {8, D3DBLENDOP_ADD, D3DBLEND_DESTALPHA, D3DBLEND_ZERO}, //*0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1)
c.rgb = c.rgb * (Ad + 1.0f);
#elif PS_BLEND == 6
// {9, D3DBLENDOP_ADD, D3DBLEND_BLENDFACTOR, D3DBLEND_ZERO}, //*0220: (Cs - 0)*F + Cs ==> Cs*(F + 1)
besoin du fix
c.rgb = c.rgb * (Af.x + 1.0f); // FIXME Not bogus
#elif PS_BLEND == 7
// {10,D3DBLENDOP_REVSUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As
c.rgb = rt.rgb * (As + 1.0f) - c.rgb * As;
#elif PS_BLEND == 8
// {11,D3DBLENDOP_REVSUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, //*1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad
c.rgb = rt.rgb * (Ad + 1.0f) - c.rgb * Ad;
#elif PS_BLEND == 9
// {12,D3DBLENDOP_REVSUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR},//*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F
c.rgb = rt.rgb * (Af.x + 1.0f) - c.rgb * Af.x;
#endif
}
void ps_main()
{
#if (PS_DATE & 3) == 1 && !defined(DISABLE_GL42_image)
@ -445,6 +483,10 @@ void ps_main()
}
#endif
#if PS_BLEND > 0
ps_blend(c, alpha);
#endif
SV_Target0 = c;
SV_Target1 = vec4(alpha, alpha, alpha, alpha);
}

View File

@ -779,6 +779,7 @@ static const char* tfx_fs_all_glsl =
" vec2 MinF;\n"
" vec2 TA;\n"
" uvec4 MskFix;\n"
" vec4 Af;\n"
" vec4 HalfTexel;\n"
" vec4 MinMax;\n"
" vec4 TC_OffsetHack;\n"
@ -1088,6 +1089,43 @@ static const char* tfx_fs_all_glsl =
" return c;\n"
"}\n"
"\n"
"void ps_blend(inout vec4 c, in float As)\n"
"{\n"
" vec4 rt = texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0);\n"
" // FIXME Ad or Ad * 2?\n"
" float Ad = rt.a;\n"
"\n"
"#if PS_BLEND == 1\n"
" // {4, D3DBLENDOP_SUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As\n"
" c.rgb = c.rgb * (As + 1.0f) - rt.rgb * As;\n"
"#elif PS_BLEND == 2\n"
" // {5, D3DBLENDOP_SUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad\n"
" c.rgb = c.rgb * (Ad + 1.0f) - rt.rgb * Ad;\n"
"#elif PS_BLEND == 3\n"
" // {6, D3DBLENDOP_SUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR}, //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F\n"
" c.rgb = c.rgb * (Af.x + 1.0f) - rt.rgb * Af.x;\n"
"#elif PS_BLEND == 4\n"
" // {7, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_ZERO}, //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1)\n"
" c.rgb = c.rgb * (As + 1.0f); // FIXME Not bogus\n"
"#elif PS_BLEND == 5\n"
" // {8, D3DBLENDOP_ADD, D3DBLEND_DESTALPHA, D3DBLEND_ZERO}, //*0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1)\n"
" c.rgb = c.rgb * (Ad + 1.0f);\n"
"#elif PS_BLEND == 6\n"
" // {9, D3DBLENDOP_ADD, D3DBLEND_BLENDFACTOR, D3DBLEND_ZERO}, //*0220: (Cs - 0)*F + Cs ==> Cs*(F + 1)\n"
" besoin du fix\n"
" c.rgb = c.rgb * (Af.x + 1.0f); // FIXME Not bogus\n"
"#elif PS_BLEND == 7\n"
" // {10,D3DBLENDOP_REVSUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As\n"
" c.rgb = rt.rgb * (As + 1.0f) - c.rgb * As;\n"
"#elif PS_BLEND == 8\n"
" // {11,D3DBLENDOP_REVSUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, //*1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad\n"
" c.rgb = rt.rgb * (Ad + 1.0f) - c.rgb * Ad;\n"
"#elif PS_BLEND == 9\n"
" // {12,D3DBLENDOP_REVSUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR},//*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F\n"
" c.rgb = rt.rgb * (Af.x + 1.0f) - c.rgb * Af.x;\n"
"#endif\n"
"}\n"
"\n"
"void ps_main()\n"
"{\n"
"#if (PS_DATE & 3) == 1 && !defined(DISABLE_GL42_image)\n"
@ -1159,6 +1197,10 @@ static const char* tfx_fs_all_glsl =
" }\n"
"#endif\n"
"\n"
"#if PS_BLEND > 0\n"
" ps_blend(c, alpha);\n"
"#endif\n"
"\n"
" SV_Target0 = c;\n"
" SV_Target1 = vec4(alpha, alpha, alpha, alpha);\n"
"}\n"