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