diff --git a/plugins/GSdx/Renderers/Common/GSDevice.cpp b/plugins/GSdx/Renderers/Common/GSDevice.cpp index 77d6575c9e..3c48092295 100644 --- a/plugins/GSdx/Renderers/Common/GSDevice.cpp +++ b/plugins/GSdx/Renderers/Common/GSDevice.cpp @@ -423,3 +423,100 @@ GSAdapter::GSAdapter(const DXGI_ADAPTER_DESC1 &desc_dxgi) #ifdef __linux__ // TODO #endif + +HWBlend GSDevice::GetBlend(size_t index) +{ + HWBlend blend = m_blendMap[index]; + blend.op = ConvertBlendEnum(blend.op); + blend.src = ConvertBlendEnum(blend.src); + blend.dst = ConvertBlendEnum(blend.dst); + return blend; +} + +uint16 GSDevice::GetBlendFlags(size_t index) { return m_blendMap[index].flags; } + +std::array<HWBlend, 3*3*3*3 + 1> GSDevice::m_blendMap = +{{ + { BLEND_NO_BAR , OP_ADD , CONST_ONE , CONST_ZERO} , // 0000: (Cs - Cs)*As + Cs ==> Cs + { 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 0001: (Cs - Cs)*As + Cd ==> Cd + { BLEND_NO_BAR , OP_ADD , CONST_ZERO , CONST_ZERO} , // 0002: (Cs - Cs)*As + 0 ==> 0 + { BLEND_NO_BAR , OP_ADD , CONST_ONE , CONST_ZERO} , // 0010: (Cs - Cs)*Ad + Cs ==> Cs + { 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 0011: (Cs - Cs)*Ad + Cd ==> Cd + { BLEND_NO_BAR , OP_ADD , CONST_ZERO , CONST_ZERO} , // 0012: (Cs - Cs)*Ad + 0 ==> 0 + { BLEND_NO_BAR , OP_ADD , CONST_ONE , CONST_ZERO} , // 0020: (Cs - Cs)*F + Cs ==> Cs + { 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 0021: (Cs - Cs)*F + Cd ==> Cd + { BLEND_NO_BAR , OP_ADD , CONST_ZERO , CONST_ZERO} , // 0022: (Cs - Cs)*F + 0 ==> 0 + { BLEND_A_MAX , OP_SUBTRACT , CONST_ONE , SRC1_ALPHA} , //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As + { 0 , OP_ADD , SRC1_ALPHA , INV_SRC1_ALPHA} , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As) + { 0 , OP_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As + { BLEND_A_MAX , OP_SUBTRACT , CONST_ONE , DST_ALPHA} , //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad + { 0 , OP_ADD , DST_ALPHA , INV_DST_ALPHA} , // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad) + { 0 , OP_SUBTRACT , DST_ALPHA , DST_ALPHA} , // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad + { BLEND_A_MAX , OP_SUBTRACT , CONST_ONE , CONST_COLOR} , //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F + { 0 , OP_ADD , CONST_COLOR , INV_CONST_COLOR} , // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F) + { 0 , OP_SUBTRACT , CONST_COLOR , CONST_COLOR} , // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F + { BLEND_NO_BAR | BLEND_A_MAX , OP_ADD , CONST_ONE , CONST_ZERO} , //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1) + { BLEND_ACCU , OP_ADD , SRC1_ALPHA , CONST_ONE} , //?0201: (Cs - 0)*As + Cd ==> Cs*As + Cd + { BLEND_NO_BAR , OP_ADD , SRC1_ALPHA , CONST_ZERO} , // 0202: (Cs - 0)*As + 0 ==> Cs*As + { BLEND_A_MAX , OP_ADD , CONST_ONE , CONST_ZERO} , //*0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1) + { 0 , OP_ADD , DST_ALPHA , CONST_ONE} , // 0211: (Cs - 0)*Ad + Cd ==> Cs*Ad + Cd + { 0 , OP_ADD , DST_ALPHA , CONST_ZERO} , // 0212: (Cs - 0)*Ad + 0 ==> Cs*Ad + { BLEND_NO_BAR | BLEND_A_MAX , OP_ADD , CONST_ONE , CONST_ZERO} , //*0220: (Cs - 0)*F + Cs ==> Cs*(F + 1) + { BLEND_ACCU , OP_ADD , CONST_COLOR , CONST_ONE} , //?0221: (Cs - 0)*F + Cd ==> Cs*F + Cd + { BLEND_NO_BAR , OP_ADD , CONST_COLOR , CONST_ZERO} , // 0222: (Cs - 0)*F + 0 ==> Cs*F + { 0 , OP_ADD , INV_SRC1_ALPHA , SRC1_ALPHA} , // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As) + { BLEND_A_MAX , OP_REV_SUBTRACT , SRC1_ALPHA , CONST_ONE} , //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As + { 0 , OP_REV_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As + { 0 , OP_ADD , INV_DST_ALPHA , DST_ALPHA} , // 1010: (Cd - Cs)*Ad + Cs ==> Cd*Ad + Cs*(1 - Ad) + { BLEND_A_MAX , OP_REV_SUBTRACT , DST_ALPHA , CONST_ONE} , //*1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad + { 0 , OP_REV_SUBTRACT , DST_ALPHA , DST_ALPHA} , // 1012: (Cd - Cs)*Ad + 0 ==> Cd*Ad - Cs*Ad + { 0 , OP_ADD , INV_CONST_COLOR , CONST_COLOR} , // 1020: (Cd - Cs)*F + Cs ==> Cd*F + Cs*(1 - F) + { BLEND_A_MAX , OP_REV_SUBTRACT , CONST_COLOR , CONST_ONE} , //*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F + { 0 , OP_REV_SUBTRACT , CONST_COLOR , CONST_COLOR} , // 1022: (Cd - Cs)*F + 0 ==> Cd*F - Cs*F + { BLEND_NO_BAR , OP_ADD , CONST_ONE , CONST_ZERO} , // 1100: (Cd - Cd)*As + Cs ==> Cs + { 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 1101: (Cd - Cd)*As + Cd ==> Cd + { BLEND_NO_BAR , OP_ADD , CONST_ZERO , CONST_ZERO} , // 1102: (Cd - Cd)*As + 0 ==> 0 + { BLEND_NO_BAR , OP_ADD , CONST_ONE , CONST_ZERO} , // 1110: (Cd - Cd)*Ad + Cs ==> Cs + { 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 1111: (Cd - Cd)*Ad + Cd ==> Cd + { BLEND_NO_BAR , OP_ADD , CONST_ZERO , CONST_ZERO} , // 1112: (Cd - Cd)*Ad + 0 ==> 0 + { BLEND_NO_BAR , OP_ADD , CONST_ONE , CONST_ZERO} , // 1120: (Cd - Cd)*F + Cs ==> Cs + { 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 1121: (Cd - Cd)*F + Cd ==> Cd + { BLEND_NO_BAR , OP_ADD , CONST_ZERO , CONST_ZERO} , // 1122: (Cd - Cd)*F + 0 ==> 0 + { 0 , OP_ADD , CONST_ONE , SRC1_ALPHA} , // 1200: (Cd - 0)*As + Cs ==> Cs + Cd*As + { BLEND_C_CLR , OP_ADD , DST_COLOR , SRC1_ALPHA} , //#1201: (Cd - 0)*As + Cd ==> Cd*(1 + As) // ffxii main menu background + { 0 , OP_ADD , CONST_ZERO , SRC1_ALPHA} , // 1202: (Cd - 0)*As + 0 ==> Cd*As + { 0 , OP_ADD , CONST_ONE , DST_ALPHA} , // 1210: (Cd - 0)*Ad + Cs ==> Cs + Cd*Ad + { BLEND_C_CLR , OP_ADD , DST_COLOR , DST_ALPHA} , //#1211: (Cd - 0)*Ad + Cd ==> Cd*(1 + Ad) + { 0 , OP_ADD , CONST_ZERO , DST_ALPHA} , // 1212: (Cd - 0)*Ad + 0 ==> Cd*Ad + { 0 , OP_ADD , CONST_ONE , CONST_COLOR} , // 1220: (Cd - 0)*F + Cs ==> Cs + Cd*F + { BLEND_C_CLR , OP_ADD , DST_COLOR , CONST_COLOR} , //#1221: (Cd - 0)*F + Cd ==> Cd*(1 + F) + { 0 , OP_ADD , CONST_ZERO , CONST_COLOR} , // 1222: (Cd - 0)*F + 0 ==> Cd*F + { BLEND_NO_BAR , OP_ADD , INV_SRC1_ALPHA , CONST_ZERO} , // 2000: (0 - Cs)*As + Cs ==> Cs*(1 - As) + { BLEND_ACCU , OP_REV_SUBTRACT , SRC1_ALPHA , CONST_ONE} , //?2001: (0 - Cs)*As + Cd ==> Cd - Cs*As + { BLEND_NO_BAR , OP_REV_SUBTRACT , SRC1_ALPHA , CONST_ZERO} , // 2002: (0 - Cs)*As + 0 ==> 0 - Cs*As + { 0 , OP_ADD , INV_DST_ALPHA , CONST_ZERO} , // 2010: (0 - Cs)*Ad + Cs ==> Cs*(1 - Ad) + { 0 , OP_REV_SUBTRACT , DST_ALPHA , CONST_ONE} , // 2011: (0 - Cs)*Ad + Cd ==> Cd - Cs*Ad + { 0 , OP_REV_SUBTRACT , DST_ALPHA , CONST_ZERO} , // 2012: (0 - Cs)*Ad + 0 ==> 0 - Cs*Ad + { BLEND_NO_BAR , OP_ADD , INV_CONST_COLOR , CONST_ZERO} , // 2020: (0 - Cs)*F + Cs ==> Cs*(1 - F) + { BLEND_ACCU , OP_REV_SUBTRACT , CONST_COLOR , CONST_ONE} , //?2021: (0 - Cs)*F + Cd ==> Cd - Cs*F + { BLEND_NO_BAR , OP_REV_SUBTRACT , CONST_COLOR , CONST_ZERO} , // 2022: (0 - Cs)*F + 0 ==> 0 - Cs*F + { 0 , OP_SUBTRACT , CONST_ONE , SRC1_ALPHA} , // 2100: (0 - Cd)*As + Cs ==> Cs - Cd*As + { 0 , OP_ADD , CONST_ZERO , INV_SRC1_ALPHA} , // 2101: (0 - Cd)*As + Cd ==> Cd*(1 - As) + { 0 , OP_SUBTRACT , CONST_ZERO , SRC1_ALPHA} , // 2102: (0 - Cd)*As + 0 ==> 0 - Cd*As + { 0 , OP_SUBTRACT , CONST_ONE , DST_ALPHA} , // 2110: (0 - Cd)*Ad + Cs ==> Cs - Cd*Ad + { 0 , OP_ADD , CONST_ZERO , INV_DST_ALPHA} , // 2111: (0 - Cd)*Ad + Cd ==> Cd*(1 - Ad) + { 0 , OP_SUBTRACT , CONST_ONE , DST_ALPHA} , // 2112: (0 - Cd)*Ad + 0 ==> 0 - Cd*Ad + { 0 , OP_SUBTRACT , CONST_ONE , CONST_COLOR} , // 2120: (0 - Cd)*F + Cs ==> Cs - Cd*F + { 0 , OP_ADD , CONST_ZERO , INV_CONST_COLOR} , // 2121: (0 - Cd)*F + Cd ==> Cd*(1 - F) + { 0 , OP_SUBTRACT , CONST_ONE , CONST_COLOR} , // 2122: (0 - Cd)*F + 0 ==> 0 - Cd*F + { BLEND_NO_BAR , OP_ADD , CONST_ONE , CONST_ZERO} , // 2200: (0 - 0)*As + Cs ==> Cs + { 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 2201: (0 - 0)*As + Cd ==> Cd + { BLEND_NO_BAR , OP_ADD , CONST_ZERO , CONST_ZERO} , // 2202: (0 - 0)*As + 0 ==> 0 + { BLEND_NO_BAR , OP_ADD , CONST_ONE , CONST_ZERO} , // 2210: (0 - 0)*Ad + Cs ==> Cs + { 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 2211: (0 - 0)*Ad + Cd ==> Cd + { BLEND_NO_BAR , OP_ADD , CONST_ZERO , CONST_ZERO} , // 2212: (0 - 0)*Ad + 0 ==> 0 + { BLEND_NO_BAR , OP_ADD , CONST_ONE , CONST_ZERO} , // 2220: (0 - 0)*F + Cs ==> Cs + { 0 , OP_ADD , CONST_ZERO , CONST_ONE} , // 2221: (0 - 0)*F + Cd ==> Cd + { BLEND_NO_BAR , OP_ADD , CONST_ZERO , CONST_ZERO} , // 2222: (0 - 0)*F + 0 ==> 0 + { 0 , OP_ADD , SRC_ALPHA , INV_SRC_ALPHA} , // extra for merge operation +}}; \ No newline at end of file diff --git a/plugins/GSdx/Renderers/Common/GSDevice.h b/plugins/GSdx/Renderers/Common/GSDevice.h index e9b0c89632..2c217b3dd5 100644 --- a/plugins/GSdx/Renderers/Common/GSDevice.h +++ b/plugins/GSdx/Renderers/Common/GSDevice.h @@ -114,11 +114,40 @@ public: #pragma pack(pop) +enum HWBlendFlags +{ + // A couple of flag to determine the blending behavior + BLEND_A_MAX = 0x100, // Impossible blending uses coeff bigger than 1 + BLEND_C_CLR = 0x200, // Clear color blending (use directly the destination color as blending factor) + BLEND_NO_BAR = 0x400, // Doesn't require sampling of the RT as a texture + BLEND_ACCU = 0x800, // Allow to use a mix of SW and HW blending to keep the best of the 2 worlds +}; + +// Determines the HW blend function for DX11/OGL +struct HWBlend { uint16 flags, op, src, dst; }; + class GSDevice : public GSAlignedClass<32> { +private: FastList<GSTexture*> m_pool; + static std::array<HWBlend, 3*3*3*3 + 1> m_blendMap; protected: + enum : uint16 + { + // HW blend factors + SRC_COLOR, INV_SRC_COLOR, DST_COLOR, INV_DST_COLOR, + SRC1_COLOR, INV_SRC1_COLOR, SRC_ALPHA, INV_SRC_ALPHA, + DST_ALPHA, INV_DST_ALPHA, SRC1_ALPHA, INV_SRC1_ALPHA, + CONST_COLOR, INV_CONST_COLOR, CONST_ONE, CONST_ZERO, + + // HW blend operations + OP_ADD, OP_SUBTRACT, OP_REV_SUBTRACT + }; + + static const int m_NO_BLEND = 0; + static const int m_MERGE_BLEND = m_blendMap.size() - 1; + std::shared_ptr<GSWnd> m_wnd; int m_vsync; bool m_rbswapped; @@ -141,6 +170,7 @@ protected: virtual void DoFXAA(GSTexture* sTex, GSTexture* dTex) {} virtual void DoShadeBoost(GSTexture* sTex, GSTexture* dTex) {} virtual void DoExternalFX(GSTexture* sTex, GSTexture* dTex) {} + virtual uint16 ConvertBlendEnum(uint16 generic) = 0; // Convert blend factors/ops from the generic enum to DX11/OGl specific. public: GSOsdManager m_osd; @@ -213,6 +243,11 @@ public: void PurgePool(); virtual void PrintMemoryUsage(); + + // Convert the GS blend equations to HW specific blend factors/ops + // Index is computed as ((((A * 3 + B) * 3) + C) * 3) + D. A, B, C, D taken from ALPHA register. + HWBlend GetBlend(size_t index); + uint16 GetBlendFlags(size_t index); }; struct GSAdapter diff --git a/plugins/GSdx/Renderers/DX11/GSDevice11.cpp b/plugins/GSdx/Renderers/DX11/GSDevice11.cpp index 88ef16130d..c61888722b 100644 --- a/plugins/GSdx/Renderers/DX11/GSDevice11.cpp +++ b/plugins/GSdx/Renderers/DX11/GSDevice11.cpp @@ -1568,105 +1568,29 @@ void GSDevice11::CompileShader(std::vector<char> source, const char* fn, ID3DInc } } -// (A - B) * C + D -// A: Cs/Cd/0 -// B: Cs/Cd/0 -// C: As/Ad/FIX -// D: Cs/Cd/0 - -// bogus: 0100, 0110, 0120, 0200, 0210, 0220, 1001, 1011, 1021 -// tricky: 1201, 1211, 1221 - -// Source.rgb = float3(1, 1, 1); -// 1201 Cd*(1 + As) => Source * Dest color + Dest * Source alpha -// 1211 Cd*(1 + Ad) => Source * Dest color + Dest * Dest alpha -// 1221 Cd*(1 + F) => Source * Dest color + Dest * Factor - -// Special blending method table: -// # (tricky) => 1 * Cd + Cd * F => Use (Cd, F) as factor of color (1, Cd) -// * (bogus) => C * (1 + F ) + ... => factor is always bigger than 1 (except above case) - -const GSDevice11::D3D11Blend GSDevice11::m_blendMapD3D11[3*3*3*3] = +uint16 GSDevice11::ConvertBlendEnum(uint16 generic) { - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 0000: (Cs - Cs)*As + Cs ==> Cs - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE } , // 0001: (Cs - Cs)*As + Cd ==> Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // 0002: (Cs - Cs)*As + 0 ==> 0 - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 0010: (Cs - Cs)*Ad + Cs ==> Cs - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE } , // 0011: (Cs - Cs)*Ad + Cd ==> Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // 0012: (Cs - Cs)*Ad + 0 ==> 0 - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 0020: (Cs - Cs)*F + Cs ==> Cs - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE } , // 0021: (Cs - Cs)*F + Cd ==> Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // 0022: (Cs - Cs)*F + 0 ==> 0 - { 1, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_SRC1_ALPHA } , //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_INV_SRC1_ALPHA } , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As) - { 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_SRC1_ALPHA } , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As - { 1, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_DEST_ALPHA } , //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_INV_DEST_ALPHA } , // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad) - { 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_DEST_ALPHA } , // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad - { 1, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_BLEND_FACTOR } , //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_INV_BLEND_FACTOR } , // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F) - { 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_BLEND_FACTOR } , // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F - { 1, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1) - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_ONE } , // 0201: (Cs - 0)*As + Cd ==> Cs*As + Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_ZERO } , // 0202: (Cs - 0)*As + 0 ==> Cs*As - { 1, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , //*0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1) - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_ONE } , // 0211: (Cs - 0)*Ad + Cd ==> Cs*Ad + Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_ZERO } , // 0212: (Cs - 0)*Ad + 0 ==> Cs*Ad - { 1, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , //*0220: (Cs - 0)*F + Cs ==> Cs*(F + 1) - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_ONE } , // 0221: (Cs - 0)*F + Cd ==> Cs*F + Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_ZERO } , // 0222: (Cs - 0)*F + 0 ==> Cs*F - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_SRC1_ALPHA , D3D11_BLEND_SRC1_ALPHA } , // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As) - { 1, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_ONE } , //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As - { 0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_SRC1_ALPHA } , // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_DEST_ALPHA , D3D11_BLEND_DEST_ALPHA } , // 1010: (Cd - Cs)*Ad + Cs ==> Cd*Ad + Cs*(1 - Ad) - { 1, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_ONE } , //*1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad - { 0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_DEST_ALPHA } , // 1012: (Cd - Cs)*Ad + 0 ==> Cd*Ad - Cs*Ad - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_BLEND_FACTOR , D3D11_BLEND_BLEND_FACTOR } , // 1020: (Cd - Cs)*F + Cs ==> Cd*F + Cs*(1 - F) - { 1, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_ONE } , //*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F - { 0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_BLEND_FACTOR } , // 1022: (Cd - Cs)*F + 0 ==> Cd*F - Cs*F - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 1100: (Cd - Cd)*As + Cs ==> Cs - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE } , // 1101: (Cd - Cd)*As + Cd ==> Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // 1102: (Cd - Cd)*As + 0 ==> 0 - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 1110: (Cd - Cd)*Ad + Cs ==> Cs - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE } , // 1111: (Cd - Cd)*Ad + Cd ==> Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // 1112: (Cd - Cd)*Ad + 0 ==> 0 - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 1120: (Cd - Cd)*F + Cs ==> Cs - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE } , // 1121: (Cd - Cd)*F + Cd ==> Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // 1122: (Cd - Cd)*F + 0 ==> 0 - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_SRC1_ALPHA } , // 1200: (Cd - 0)*As + Cs ==> Cs + Cd*As - { 2, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_COLOR , D3D11_BLEND_SRC1_ALPHA } , //#1201: (Cd - 0)*As + Cd ==> Cd*(1 + As) // ffxii main menu background glow effect - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_SRC1_ALPHA } , // 1202: (Cd - 0)*As + 0 ==> Cd*As - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_DEST_ALPHA } , // 1210: (Cd - 0)*Ad + Cs ==> Cs + Cd*Ad - { 2, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_COLOR , D3D11_BLEND_DEST_ALPHA } , //#1211: (Cd - 0)*Ad + Cd ==> Cd*(1 + Ad) - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_DEST_ALPHA } , // 1212: (Cd - 0)*Ad + 0 ==> Cd*Ad - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_BLEND_FACTOR } , // 1220: (Cd - 0)*F + Cs ==> Cs + Cd*F - { 2, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_COLOR , D3D11_BLEND_BLEND_FACTOR } , //#1221: (Cd - 0)*F + Cd ==> Cd*(1 + F) - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_BLEND_FACTOR } , // 1222: (Cd - 0)*F + 0 ==> Cd*F - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_SRC1_ALPHA , D3D11_BLEND_ZERO } , // 2000: (0 - Cs)*As + Cs ==> Cs*(1 - As) - { 0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_ONE } , // 2001: (0 - Cs)*As + Cd ==> Cd - Cs*As - { 0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_ZERO } , // 2002: (0 - Cs)*As + 0 ==> 0 - Cs*As - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_DEST_ALPHA , D3D11_BLEND_ZERO } , // 2010: (0 - Cs)*Ad + Cs ==> Cs*(1 - Ad) - { 0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_ONE } , // 2011: (0 - Cs)*Ad + Cd ==> Cd - Cs*Ad - { 0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_ZERO } , // 2012: (0 - Cs)*Ad + 0 ==> 0 - Cs*Ad - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_INV_BLEND_FACTOR , D3D11_BLEND_ZERO } , // 2020: (0 - Cs)*F + Cs ==> Cs*(1 - F) - { 0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_ONE } , // 2021: (0 - Cs)*F + Cd ==> Cd - Cs*F - { 0, D3D11_BLEND_OP_REV_SUBTRACT , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_ZERO } , // 2022: (0 - Cs)*F + 0 ==> 0 - Cs*F - { 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_SRC1_ALPHA } , // 2100: (0 - Cd)*As + Cs ==> Cs - Cd*As - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_INV_SRC1_ALPHA } , // 2101: (0 - Cd)*As + Cd ==> Cd*(1 - As) - { 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ZERO , D3D11_BLEND_SRC1_ALPHA } , // 2102: (0 - Cd)*As + 0 ==> 0 - Cd*As - { 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_DEST_ALPHA } , // 2110: (0 - Cd)*Ad + Cs ==> Cs - Cd*Ad - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_INV_DEST_ALPHA } , // 2111: (0 - Cd)*Ad + Cd ==> Cd*(1 - Ad) - { 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_DEST_ALPHA } , // 2112: (0 - Cd)*Ad + 0 ==> 0 - Cd*Ad - { 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_BLEND_FACTOR } , // 2120: (0 - Cd)*F + Cs ==> Cs - Cd*F - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_INV_BLEND_FACTOR } , // 2121: (0 - Cd)*F + Cd ==> Cd*(1 - F) - { 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_BLEND_FACTOR } , // 2122: (0 - Cd)*F + 0 ==> 0 - Cd*F - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 2200: (0 - 0)*As + Cs ==> Cs - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE } , // 2201: (0 - 0)*As + Cd ==> Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // 2202: (0 - 0)*As + 0 ==> 0 - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 2210: (0 - 0)*Ad + Cs ==> Cs - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE } , // 2211: (0 - 0)*Ad + Cd ==> Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // 2212: (0 - 0)*Ad + 0 ==> 0 - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 2220: (0 - 0)*F + Cs ==> Cs - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE } , // 2221: (0 - 0)*F + Cd ==> Cd - { 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // 2222: (0 - 0)*F + 0 ==> 0 -}; \ No newline at end of file + switch (generic) + { + case SRC_COLOR : return D3D11_BLEND_SRC_COLOR; + case INV_SRC_COLOR : return D3D11_BLEND_INV_SRC_COLOR; + case DST_COLOR : return D3D11_BLEND_DEST_COLOR; + case INV_DST_COLOR : return D3D11_BLEND_INV_DEST_COLOR; + case SRC1_COLOR : return D3D11_BLEND_SRC1_COLOR; + case INV_SRC1_COLOR : return D3D11_BLEND_INV_SRC1_COLOR; + case SRC_ALPHA : return D3D11_BLEND_SRC_ALPHA; + case INV_SRC_ALPHA : return D3D11_BLEND_INV_SRC_ALPHA; + case DST_ALPHA : return D3D11_BLEND_DEST_ALPHA; + case INV_DST_ALPHA : return D3D11_BLEND_INV_DEST_ALPHA; + case SRC1_ALPHA : return D3D11_BLEND_SRC1_ALPHA; + case INV_SRC1_ALPHA : return D3D11_BLEND_INV_SRC1_ALPHA; + case CONST_COLOR : return D3D11_BLEND_BLEND_FACTOR; + case INV_CONST_COLOR : return D3D11_BLEND_INV_BLEND_FACTOR; + case CONST_ONE : return D3D11_BLEND_ONE; + case CONST_ZERO : return D3D11_BLEND_ZERO; + case OP_ADD : return D3D11_BLEND_OP_ADD; + case OP_SUBTRACT : return D3D11_BLEND_OP_SUBTRACT; + case OP_REV_SUBTRACT : return D3D11_BLEND_OP_REV_SUBTRACT; + default : ASSERT(0); return 0; + } +} \ No newline at end of file diff --git a/plugins/GSdx/Renderers/DX11/GSDevice11.h b/plugins/GSdx/Renderers/DX11/GSDevice11.h index dee3e6f32d..b59daec06f 100644 --- a/plugins/GSdx/Renderers/DX11/GSDevice11.h +++ b/plugins/GSdx/Renderers/DX11/GSDevice11.h @@ -206,7 +206,6 @@ public: uint32 read_ba:1; uint32 fbmask:1; - // *** Word 2 // Blend and Colclip uint32 clr1:1; @@ -309,14 +308,6 @@ public: } }; - struct D3D11Blend - { - int bogus; - D3D11_BLEND_OP op; - D3D11_BLEND src, dst; - }; - static const D3D11Blend m_blendMapD3D11[3*3*3*3]; - #pragma pack(pop) private: @@ -338,7 +329,7 @@ private: void BeforeDraw(); void AfterDraw(); - // + uint16 ConvertBlendEnum(uint16 generic) final; CComPtr<ID3D11Device> m_dev; CComPtr<ID3D11DeviceContext> m_ctx; diff --git a/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp b/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp index 43628152b8..3eb089ad5f 100644 --- a/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp +++ b/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp @@ -398,9 +398,10 @@ void GSDevice11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uin { int i = ((bsel.a * 3 + bsel.b) * 3 + bsel.c) * 3 + bsel.d; - bd.RenderTarget[0].BlendOp = m_blendMapD3D11[i].op; - bd.RenderTarget[0].SrcBlend = m_blendMapD3D11[i].src; - bd.RenderTarget[0].DestBlend = m_blendMapD3D11[i].dst; + HWBlend blend = GetBlend(i); + bd.RenderTarget[0].BlendOp = (D3D11_BLEND_OP)blend.op; + bd.RenderTarget[0].SrcBlend = (D3D11_BLEND)blend.src; + bd.RenderTarget[0].DestBlend = (D3D11_BLEND)blend.dst; bd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; diff --git a/plugins/GSdx/Renderers/Null/GSDeviceNull.h b/plugins/GSdx/Renderers/Null/GSDeviceNull.h index cddf135d46..2595ed1906 100644 --- a/plugins/GSdx/Renderers/Null/GSDeviceNull.h +++ b/plugins/GSdx/Renderers/Null/GSDeviceNull.h @@ -31,6 +31,7 @@ private: void DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex, GSVector4* dRect, const GSRegPMODE& PMODE, const GSRegEXTBUF& EXTBUF, const GSVector4& c) {} void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0) {} + uint16 ConvertBlendEnum(uint16 generic) { return 0xFFFF; } public: GSDeviceNull() {} diff --git a/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.cpp b/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.cpp index f89fca0ed5..67ba6b8816 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.cpp +++ b/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.cpp @@ -1733,7 +1733,7 @@ void GSDeviceOGL::OMSetBlendState(uint8 blend_index, uint8 blend_factor, bool is glBlendColor(bf, bf, bf, bf); } - OGLBlend b = m_blendMapOGL[blend_index]; + HWBlend b = GetBlend(blend_index); if (accumulation_blend) { b.src = GL_ONE; b.dst = GL_ONE; @@ -1975,110 +1975,29 @@ void GSDeviceOGL::DebugOutputToFile(GLenum gl_source, GLenum gl_type, GLuint id, #endif } -// (A - B) * C + D -// A: Cs/Cd/0 -// B: Cs/Cd/0 -// C: As/Ad/FIX -// D: Cs/Cd/0 - -// bogus: 0100, 0110, 0120, 0200, 0210, 0220, 1001, 1011, 1021 -// tricky: 1201, 1211, 1221 - -// Source.rgb = float3(1, 1, 1); -// 1201 Cd*(1 + As) => Source * Dest color + Dest * Source alpha -// 1211 Cd*(1 + Ad) => Source * Dest color + Dest * Dest alpha -// 1221 Cd*(1 + F) => Source * Dest color + Dest * Factor - -// Special blending method table: -// # (tricky) => 1 * Cd + Cd * F => Use (Cd, F) as factor of color (1, Cd) -// * (bogus) => C * (1 + F ) + ... => factor is always bigger than 1 (except above case) -// ? => Cs * F + Cd => do the multiplication in shader and addition in blending unit. It is an optimization - -const int GSDeviceOGL::m_NO_BLEND = 0; -const int GSDeviceOGL::m_MERGE_BLEND = 3*3*3*3; - -const GSDeviceOGL::OGLBlend GSDeviceOGL::m_blendMapOGL[3*3*3*3 + 1] = +uint16 GSDeviceOGL::ConvertBlendEnum(uint16 generic) { - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 0000: (Cs - Cs)*As + Cs ==> Cs - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE} , // 0001: (Cs - Cs)*As + Cd ==> Cd - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ZERO , GL_ZERO} , // 0002: (Cs - Cs)*As + 0 ==> 0 - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 0010: (Cs - Cs)*Ad + Cs ==> Cs - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE} , // 0011: (Cs - Cs)*Ad + Cd ==> Cd - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ZERO , GL_ZERO} , // 0012: (Cs - Cs)*Ad + 0 ==> 0 - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 0020: (Cs - Cs)*F + Cs ==> Cs - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE} , // 0021: (Cs - Cs)*F + Cd ==> Cd - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ZERO , GL_ZERO} , // 0022: (Cs - Cs)*F + 0 ==> 0 - { BLEND_A_MAX , GL_FUNC_SUBTRACT , GL_ONE , GL_SRC1_ALPHA} , //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As - { 0 , GL_FUNC_ADD , GL_SRC1_ALPHA , GL_ONE_MINUS_SRC1_ALPHA} , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As) - { 0 , GL_FUNC_SUBTRACT , GL_SRC1_ALPHA , GL_SRC1_ALPHA} , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As - { BLEND_A_MAX , GL_FUNC_SUBTRACT , GL_ONE , GL_DST_ALPHA} , //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad - { 0 , GL_FUNC_ADD , GL_DST_ALPHA , GL_ONE_MINUS_DST_ALPHA} , // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad) - { 0 , GL_FUNC_SUBTRACT , GL_DST_ALPHA , GL_DST_ALPHA} , // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad - { BLEND_A_MAX , GL_FUNC_SUBTRACT , GL_ONE , GL_CONSTANT_COLOR} , //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F - { 0 , GL_FUNC_ADD , GL_CONSTANT_COLOR , GL_ONE_MINUS_CONSTANT_COLOR} , // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F) - { 0 , GL_FUNC_SUBTRACT , GL_CONSTANT_COLOR , GL_CONSTANT_COLOR} , // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F - { BLEND_NO_BAR | BLEND_A_MAX , GL_FUNC_ADD , GL_ONE , GL_ZERO} , //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1) - { BLEND_ACCU , GL_FUNC_ADD , GL_SRC1_ALPHA , GL_ONE} , //?0201: (Cs - 0)*As + Cd ==> Cs*As + Cd - { BLEND_NO_BAR , GL_FUNC_ADD , GL_SRC1_ALPHA , GL_ZERO} , // 0202: (Cs - 0)*As + 0 ==> Cs*As - { BLEND_A_MAX , GL_FUNC_ADD , GL_ONE , GL_ZERO} , //*0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1) - { 0 , GL_FUNC_ADD , GL_DST_ALPHA , GL_ONE} , // 0211: (Cs - 0)*Ad + Cd ==> Cs*Ad + Cd - { 0 , GL_FUNC_ADD , GL_DST_ALPHA , GL_ZERO} , // 0212: (Cs - 0)*Ad + 0 ==> Cs*Ad - { BLEND_NO_BAR | BLEND_A_MAX , GL_FUNC_ADD , GL_ONE , GL_ZERO} , //*0220: (Cs - 0)*F + Cs ==> Cs*(F + 1) - { BLEND_ACCU , GL_FUNC_ADD , GL_CONSTANT_COLOR , GL_ONE} , //?0221: (Cs - 0)*F + Cd ==> Cs*F + Cd - { BLEND_NO_BAR , GL_FUNC_ADD , GL_CONSTANT_COLOR , GL_ZERO} , // 0222: (Cs - 0)*F + 0 ==> Cs*F - { 0 , GL_FUNC_ADD , GL_ONE_MINUS_SRC1_ALPHA , GL_SRC1_ALPHA} , // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As) - { BLEND_A_MAX , GL_FUNC_REVERSE_SUBTRACT , GL_SRC1_ALPHA , GL_ONE} , //*1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As - { 0 , GL_FUNC_REVERSE_SUBTRACT , GL_SRC1_ALPHA , GL_SRC1_ALPHA} , // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As - { 0 , GL_FUNC_ADD , GL_ONE_MINUS_DST_ALPHA , GL_DST_ALPHA} , // 1010: (Cd - Cs)*Ad + Cs ==> Cd*Ad + Cs*(1 - Ad) - { BLEND_A_MAX , GL_FUNC_REVERSE_SUBTRACT , GL_DST_ALPHA , GL_ONE} , //*1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad - { 0 , GL_FUNC_REVERSE_SUBTRACT , GL_DST_ALPHA , GL_DST_ALPHA} , // 1012: (Cd - Cs)*Ad + 0 ==> Cd*Ad - Cs*Ad - { 0 , GL_FUNC_ADD , GL_ONE_MINUS_CONSTANT_COLOR , GL_CONSTANT_COLOR} , // 1020: (Cd - Cs)*F + Cs ==> Cd*F + Cs*(1 - F) - { BLEND_A_MAX , GL_FUNC_REVERSE_SUBTRACT , GL_CONSTANT_COLOR , GL_ONE} , //*1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F - { 0 , GL_FUNC_REVERSE_SUBTRACT , GL_CONSTANT_COLOR , GL_CONSTANT_COLOR} , // 1022: (Cd - Cs)*F + 0 ==> Cd*F - Cs*F - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 1100: (Cd - Cd)*As + Cs ==> Cs - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE} , // 1101: (Cd - Cd)*As + Cd ==> Cd - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ZERO , GL_ZERO} , // 1102: (Cd - Cd)*As + 0 ==> 0 - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 1110: (Cd - Cd)*Ad + Cs ==> Cs - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE} , // 1111: (Cd - Cd)*Ad + Cd ==> Cd - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ZERO , GL_ZERO} , // 1112: (Cd - Cd)*Ad + 0 ==> 0 - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 1120: (Cd - Cd)*F + Cs ==> Cs - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE} , // 1121: (Cd - Cd)*F + Cd ==> Cd - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ZERO , GL_ZERO} , // 1122: (Cd - Cd)*F + 0 ==> 0 - { 0 , GL_FUNC_ADD , GL_ONE , GL_SRC1_ALPHA} , // 1200: (Cd - 0)*As + Cs ==> Cs + Cd*As - { BLEND_C_CLR , GL_FUNC_ADD , GL_DST_COLOR , GL_SRC1_ALPHA} , //#1201: (Cd - 0)*As + Cd ==> Cd*(1 + As) // ffxii main menu background - { 0 , GL_FUNC_ADD , GL_ZERO , GL_SRC1_ALPHA} , // 1202: (Cd - 0)*As + 0 ==> Cd*As - { 0 , GL_FUNC_ADD , GL_ONE , GL_DST_ALPHA} , // 1210: (Cd - 0)*Ad + Cs ==> Cs + Cd*Ad - { BLEND_C_CLR , GL_FUNC_ADD , GL_DST_COLOR , GL_DST_ALPHA} , //#1211: (Cd - 0)*Ad + Cd ==> Cd*(1 + Ad) - { 0 , GL_FUNC_ADD , GL_ZERO , GL_DST_ALPHA} , // 1212: (Cd - 0)*Ad + 0 ==> Cd*Ad - { 0 , GL_FUNC_ADD , GL_ONE , GL_CONSTANT_COLOR} , // 1220: (Cd - 0)*F + Cs ==> Cs + Cd*F - { BLEND_C_CLR , GL_FUNC_ADD , GL_DST_COLOR , GL_CONSTANT_COLOR} , //#1221: (Cd - 0)*F + Cd ==> Cd*(1 + F) - { 0 , GL_FUNC_ADD , GL_ZERO , GL_CONSTANT_COLOR} , // 1222: (Cd - 0)*F + 0 ==> Cd*F - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE_MINUS_SRC1_ALPHA , GL_ZERO} , // 2000: (0 - Cs)*As + Cs ==> Cs*(1 - As) - { BLEND_ACCU , GL_FUNC_REVERSE_SUBTRACT , GL_SRC1_ALPHA , GL_ONE} , // 2001: (0 - Cs)*As + Cd ==> Cd - Cs*As - { BLEND_NO_BAR , GL_FUNC_REVERSE_SUBTRACT , GL_SRC1_ALPHA , GL_ZERO} , // 2002: (0 - Cs)*As + 0 ==> 0 - Cs*As - { 0 , GL_FUNC_ADD , GL_ONE_MINUS_DST_ALPHA , GL_ZERO} , // 2010: (0 - Cs)*Ad + Cs ==> Cs*(1 - Ad) - { 0 , GL_FUNC_REVERSE_SUBTRACT , GL_DST_ALPHA , GL_ONE} , // 2011: (0 - Cs)*Ad + Cd ==> Cd - Cs*Ad - { 0 , GL_FUNC_REVERSE_SUBTRACT , GL_DST_ALPHA , GL_ZERO} , // 2012: (0 - Cs)*Ad + 0 ==> 0 - Cs*Ad - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE_MINUS_CONSTANT_COLOR , GL_ZERO} , // 2020: (0 - Cs)*F + Cs ==> Cs*(1 - F) - { BLEND_ACCU , GL_FUNC_REVERSE_SUBTRACT , GL_CONSTANT_COLOR , GL_ONE} , // 2021: (0 - Cs)*F + Cd ==> Cd - Cs*F - { BLEND_NO_BAR , GL_FUNC_REVERSE_SUBTRACT , GL_CONSTANT_COLOR , GL_ZERO} , // 2022: (0 - Cs)*F + 0 ==> 0 - Cs*F - { 0 , GL_FUNC_SUBTRACT , GL_ONE , GL_SRC1_ALPHA} , // 2100: (0 - Cd)*As + Cs ==> Cs - Cd*As - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE_MINUS_SRC1_ALPHA} , // 2101: (0 - Cd)*As + Cd ==> Cd*(1 - As) - { 0 , GL_FUNC_SUBTRACT , GL_ZERO , GL_SRC1_ALPHA} , // 2102: (0 - Cd)*As + 0 ==> 0 - Cd*As - { 0 , GL_FUNC_SUBTRACT , GL_ONE , GL_DST_ALPHA} , // 2110: (0 - Cd)*Ad + Cs ==> Cs - Cd*Ad - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE_MINUS_DST_ALPHA} , // 2111: (0 - Cd)*Ad + Cd ==> Cd*(1 - Ad) - { 0 , GL_FUNC_SUBTRACT , GL_ONE , GL_DST_ALPHA} , // 2112: (0 - Cd)*Ad + 0 ==> 0 - Cd*Ad - { 0 , GL_FUNC_SUBTRACT , GL_ONE , GL_CONSTANT_COLOR} , // 2120: (0 - Cd)*F + Cs ==> Cs - Cd*F - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE_MINUS_CONSTANT_COLOR} , // 2121: (0 - Cd)*F + Cd ==> Cd*(1 - F) - { 0 , GL_FUNC_SUBTRACT , GL_ONE , GL_CONSTANT_COLOR} , // 2122: (0 - Cd)*F + 0 ==> 0 - Cd*F - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 2200: (0 - 0)*As + Cs ==> Cs - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE} , // 2201: (0 - 0)*As + Cd ==> Cd - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ZERO , GL_ZERO} , // 2202: (0 - 0)*As + 0 ==> 0 - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 2210: (0 - 0)*Ad + Cs ==> Cs - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE} , // 2211: (0 - 0)*Ad + Cd ==> Cd - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ZERO , GL_ZERO} , // 2212: (0 - 0)*Ad + 0 ==> 0 - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 2220: (0 - 0)*F + Cs ==> Cs - { 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE} , // 2221: (0 - 0)*F + Cd ==> Cd - { BLEND_NO_BAR , GL_FUNC_ADD , GL_ZERO , GL_ZERO} , // 2222: (0 - 0)*F + 0 ==> 0 - { 0 , GL_FUNC_ADD , GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA} , // extra for merge operation -}; + switch (generic) + { + case SRC_COLOR : return GL_SRC_COLOR; + case INV_SRC_COLOR : return GL_ONE_MINUS_SRC_COLOR; + case DST_COLOR : return GL_DST_COLOR; + case INV_DST_COLOR : return GL_ONE_MINUS_DST_COLOR; + case SRC1_COLOR : return GL_SRC1_COLOR; + case INV_SRC1_COLOR : return GL_ONE_MINUS_SRC1_COLOR; + case SRC_ALPHA : return GL_SRC_ALPHA; + case INV_SRC_ALPHA : return GL_ONE_MINUS_SRC_ALPHA; + case DST_ALPHA : return GL_DST_ALPHA; + case INV_DST_ALPHA : return GL_ONE_MINUS_DST_ALPHA; + case SRC1_ALPHA : return GL_SRC1_ALPHA; + case INV_SRC1_ALPHA : return GL_ONE_MINUS_SRC1_ALPHA; + case CONST_COLOR : return GL_CONSTANT_COLOR; + case INV_CONST_COLOR : return GL_ONE_MINUS_CONSTANT_COLOR; + case CONST_ONE : return GL_ONE; + case CONST_ZERO : return GL_ZERO; + case OP_ADD : return GL_FUNC_ADD; + case OP_SUBTRACT : return GL_FUNC_SUBTRACT; + case OP_REV_SUBTRACT : return GL_FUNC_REVERSE_SUBTRACT; + default : ASSERT(0); return 0; + } +} \ No newline at end of file diff --git a/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.h b/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.h index a7817f5ff6..333a1c3bd9 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.h +++ b/plugins/GSdx/Renderers/OpenGL/GSDeviceOGL.h @@ -29,12 +29,6 @@ #include "GSShaderOGL.h" #include "GLState.h" -// A couple of flag to determine the blending behavior -#define BLEND_A_MAX (0x100) // Impossible blending uses coeff bigger than 1 -#define BLEND_C_CLR (0x200) // Clear color blending (use directly the destination color as blending factor) -#define BLEND_NO_BAR (0x400) // don't require texture barrier for the blending (because the RT is not used) -#define BLEND_ACCU (0x800) // Allow to use a mix of SW and HW blending to keep the best of the 2 worlds - #ifdef ENABLE_OGL_DEBUG_MEM_BW extern uint64 g_real_texture_upload_byte; extern uint64 g_vertex_upload_byte; @@ -401,15 +395,10 @@ public: MiscConstantBuffer() {memset(this, 0, sizeof(*this));} }; - struct OGLBlend {uint16 bogus, op, src, dst;}; - static const OGLBlend m_blendMapOGL[3*3*3*3 + 1]; - static const int m_NO_BLEND; - static const int m_MERGE_BLEND; - static int m_shader_inst; static int m_shader_reg; - private: +private: int m_force_texture_clear; int m_mipmap; TriFiltering m_filter; @@ -506,7 +495,9 @@ public: void OMAttachDs(GSTextureOGL* ds = NULL); void OMSetFBO(GLuint fbo); - public: + uint16 ConvertBlendEnum(uint16 generic) final; + +public: GSShaderOGL* m_shader; GSDeviceOGL(); diff --git a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp index 7d06d6bf8d..50a5eadc86 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp +++ b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp @@ -482,7 +482,7 @@ void GSRendererOGL::EmulateBlending(bool DATE_GL42) // Compute the blending equation to detect special case uint8 blend_index = uint8(((ALPHA.A * 3 + ALPHA.B) * 3 + ALPHA.C) * 3 + ALPHA.D); - int blend_flag = GSDeviceOGL::m_blendMapOGL[blend_index].bogus; + int blend_flag = dev->GetBlendFlags(blend_index); // SW Blend is (nearly) free. Let's use it. bool impossible_or_free_blend = (blend_flag & (BLEND_NO_BAR|BLEND_A_MAX|BLEND_ACCU)) // Blend doesn't requires the costly barrier