GSdx: Made a DX11/OGL-independent blend map in GSDevice.cpp. Convert to OGL/DX11 specific constants at run time.

This commit is contained in:
hibye8313 2019-06-06 10:21:32 -04:00 committed by lightningterror
parent a3bf46ecd9
commit 718042e6a6
9 changed files with 194 additions and 235 deletions

View File

@ -423,3 +423,100 @@ GSAdapter::GSAdapter(const DXGI_ADAPTER_DESC1 &desc_dxgi)
#ifdef __linux__ #ifdef __linux__
// TODO // TODO
#endif #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
}};

View File

@ -114,11 +114,40 @@ public:
#pragma pack(pop) #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> class GSDevice : public GSAlignedClass<32>
{ {
private:
FastList<GSTexture*> m_pool; FastList<GSTexture*> m_pool;
static std::array<HWBlend, 3*3*3*3 + 1> m_blendMap;
protected: 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; std::shared_ptr<GSWnd> m_wnd;
int m_vsync; int m_vsync;
bool m_rbswapped; bool m_rbswapped;
@ -141,6 +170,7 @@ protected:
virtual void DoFXAA(GSTexture* sTex, GSTexture* dTex) {} virtual void DoFXAA(GSTexture* sTex, GSTexture* dTex) {}
virtual void DoShadeBoost(GSTexture* sTex, GSTexture* dTex) {} virtual void DoShadeBoost(GSTexture* sTex, GSTexture* dTex) {}
virtual void DoExternalFX(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: public:
GSOsdManager m_osd; GSOsdManager m_osd;
@ -213,6 +243,11 @@ public:
void PurgePool(); void PurgePool();
virtual void PrintMemoryUsage(); 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 struct GSAdapter

View File

@ -1568,105 +1568,29 @@ void GSDevice11::CompileShader(std::vector<char> source, const char* fn, ID3DInc
} }
} }
// (A - B) * C + D uint16 GSDevice11::ConvertBlendEnum(uint16 generic)
// 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] =
{ {
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 0000: (Cs - Cs)*As + Cs ==> Cs switch (generic)
{ 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 case SRC_COLOR : return D3D11_BLEND_SRC_COLOR;
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 0010: (Cs - Cs)*Ad + Cs ==> Cs case INV_SRC_COLOR : return D3D11_BLEND_INV_SRC_COLOR;
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE } , // 0011: (Cs - Cs)*Ad + Cd ==> Cd case DST_COLOR : return D3D11_BLEND_DEST_COLOR;
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // 0012: (Cs - Cs)*Ad + 0 ==> 0 case INV_DST_COLOR : return D3D11_BLEND_INV_DEST_COLOR;
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , // 0020: (Cs - Cs)*F + Cs ==> Cs case SRC1_COLOR : return D3D11_BLEND_SRC1_COLOR;
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ONE } , // 0021: (Cs - Cs)*F + Cd ==> Cd case INV_SRC1_COLOR : return D3D11_BLEND_INV_SRC1_COLOR;
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // 0022: (Cs - Cs)*F + 0 ==> 0 case SRC_ALPHA : return D3D11_BLEND_SRC_ALPHA;
{ 1, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_SRC1_ALPHA } , //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As case INV_SRC_ALPHA : return D3D11_BLEND_INV_SRC_ALPHA;
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_INV_SRC1_ALPHA } , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As) case DST_ALPHA : return D3D11_BLEND_DEST_ALPHA;
{ 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_SRC1_ALPHA } , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As case INV_DST_ALPHA : return D3D11_BLEND_INV_DEST_ALPHA;
{ 1, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_DEST_ALPHA } , //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad case SRC1_ALPHA : return D3D11_BLEND_SRC1_ALPHA;
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_INV_DEST_ALPHA } , // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad) case INV_SRC1_ALPHA : return D3D11_BLEND_INV_SRC1_ALPHA;
{ 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_DEST_ALPHA } , // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad case CONST_COLOR : return D3D11_BLEND_BLEND_FACTOR;
{ 1, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_ONE , D3D11_BLEND_BLEND_FACTOR } , //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F case INV_CONST_COLOR : return D3D11_BLEND_INV_BLEND_FACTOR;
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_INV_BLEND_FACTOR } , // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F) case CONST_ONE : return D3D11_BLEND_ONE;
{ 0, D3D11_BLEND_OP_SUBTRACT , D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_BLEND_FACTOR } , // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F case CONST_ZERO : return D3D11_BLEND_ZERO;
{ 1, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1) case OP_ADD : return D3D11_BLEND_OP_ADD;
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_ONE } , // 0201: (Cs - 0)*As + Cd ==> Cs*As + Cd case OP_SUBTRACT : return D3D11_BLEND_OP_SUBTRACT;
{ 0, D3D11_BLEND_OP_ADD , D3D11_BLEND_SRC1_ALPHA , D3D11_BLEND_ZERO } , // 0202: (Cs - 0)*As + 0 ==> Cs*As case OP_REV_SUBTRACT : return D3D11_BLEND_OP_REV_SUBTRACT;
{ 1, D3D11_BLEND_OP_ADD , D3D11_BLEND_ONE , D3D11_BLEND_ZERO } , //*0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1) default : ASSERT(0); return 0;
{ 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
};

View File

@ -206,7 +206,6 @@ public:
uint32 read_ba:1; uint32 read_ba:1;
uint32 fbmask:1; uint32 fbmask:1;
// *** Word 2
// Blend and Colclip // Blend and Colclip
uint32 clr1:1; 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) #pragma pack(pop)
private: private:
@ -338,7 +329,7 @@ private:
void BeforeDraw(); void BeforeDraw();
void AfterDraw(); void AfterDraw();
// uint16 ConvertBlendEnum(uint16 generic) final;
CComPtr<ID3D11Device> m_dev; CComPtr<ID3D11Device> m_dev;
CComPtr<ID3D11DeviceContext> m_ctx; CComPtr<ID3D11DeviceContext> m_ctx;

View File

@ -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; int i = ((bsel.a * 3 + bsel.b) * 3 + bsel.c) * 3 + bsel.d;
bd.RenderTarget[0].BlendOp = m_blendMapD3D11[i].op; HWBlend blend = GetBlend(i);
bd.RenderTarget[0].SrcBlend = m_blendMapD3D11[i].src; bd.RenderTarget[0].BlendOp = (D3D11_BLEND_OP)blend.op;
bd.RenderTarget[0].DestBlend = m_blendMapD3D11[i].dst; 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].BlendOpAlpha = D3D11_BLEND_OP_ADD;
bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;

View File

@ -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 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) {} void DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset = 0) {}
uint16 ConvertBlendEnum(uint16 generic) { return 0xFFFF; }
public: public:
GSDeviceNull() {} GSDeviceNull() {}

View File

@ -1733,7 +1733,7 @@ void GSDeviceOGL::OMSetBlendState(uint8 blend_index, uint8 blend_factor, bool is
glBlendColor(bf, bf, bf, bf); glBlendColor(bf, bf, bf, bf);
} }
OGLBlend b = m_blendMapOGL[blend_index]; HWBlend b = GetBlend(blend_index);
if (accumulation_blend) { if (accumulation_blend) {
b.src = GL_ONE; b.src = GL_ONE;
b.dst = GL_ONE; b.dst = GL_ONE;
@ -1975,110 +1975,29 @@ void GSDeviceOGL::DebugOutputToFile(GLenum gl_source, GLenum gl_type, GLuint id,
#endif #endif
} }
// (A - B) * C + D uint16 GSDeviceOGL::ConvertBlendEnum(uint16 generic)
// 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] =
{ {
{ BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 0000: (Cs - Cs)*As + Cs ==> Cs switch (generic)
{ 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 case SRC_COLOR : return GL_SRC_COLOR;
{ BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 0010: (Cs - Cs)*Ad + Cs ==> Cs case INV_SRC_COLOR : return GL_ONE_MINUS_SRC_COLOR;
{ 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE} , // 0011: (Cs - Cs)*Ad + Cd ==> Cd case DST_COLOR : return GL_DST_COLOR;
{ BLEND_NO_BAR , GL_FUNC_ADD , GL_ZERO , GL_ZERO} , // 0012: (Cs - Cs)*Ad + 0 ==> 0 case INV_DST_COLOR : return GL_ONE_MINUS_DST_COLOR;
{ BLEND_NO_BAR , GL_FUNC_ADD , GL_ONE , GL_ZERO} , // 0020: (Cs - Cs)*F + Cs ==> Cs case SRC1_COLOR : return GL_SRC1_COLOR;
{ 0 , GL_FUNC_ADD , GL_ZERO , GL_ONE} , // 0021: (Cs - Cs)*F + Cd ==> Cd case INV_SRC1_COLOR : return GL_ONE_MINUS_SRC1_COLOR;
{ BLEND_NO_BAR , GL_FUNC_ADD , GL_ZERO , GL_ZERO} , // 0022: (Cs - Cs)*F + 0 ==> 0 case SRC_ALPHA : return GL_SRC_ALPHA;
{ BLEND_A_MAX , GL_FUNC_SUBTRACT , GL_ONE , GL_SRC1_ALPHA} , //*0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As case INV_SRC_ALPHA : return GL_ONE_MINUS_SRC_ALPHA;
{ 0 , GL_FUNC_ADD , GL_SRC1_ALPHA , GL_ONE_MINUS_SRC1_ALPHA} , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As) case DST_ALPHA : return GL_DST_ALPHA;
{ 0 , GL_FUNC_SUBTRACT , GL_SRC1_ALPHA , GL_SRC1_ALPHA} , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As case INV_DST_ALPHA : return GL_ONE_MINUS_DST_ALPHA;
{ BLEND_A_MAX , GL_FUNC_SUBTRACT , GL_ONE , GL_DST_ALPHA} , //*0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad case SRC1_ALPHA : return GL_SRC1_ALPHA;
{ 0 , GL_FUNC_ADD , GL_DST_ALPHA , GL_ONE_MINUS_DST_ALPHA} , // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad) case INV_SRC1_ALPHA : return GL_ONE_MINUS_SRC1_ALPHA;
{ 0 , GL_FUNC_SUBTRACT , GL_DST_ALPHA , GL_DST_ALPHA} , // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad case CONST_COLOR : return GL_CONSTANT_COLOR;
{ BLEND_A_MAX , GL_FUNC_SUBTRACT , GL_ONE , GL_CONSTANT_COLOR} , //*0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F case INV_CONST_COLOR : return GL_ONE_MINUS_CONSTANT_COLOR;
{ 0 , GL_FUNC_ADD , GL_CONSTANT_COLOR , GL_ONE_MINUS_CONSTANT_COLOR} , // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F) case CONST_ONE : return GL_ONE;
{ 0 , GL_FUNC_SUBTRACT , GL_CONSTANT_COLOR , GL_CONSTANT_COLOR} , // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F case CONST_ZERO : return GL_ZERO;
{ BLEND_NO_BAR | BLEND_A_MAX , GL_FUNC_ADD , GL_ONE , GL_ZERO} , //*0200: (Cs - 0)*As + Cs ==> Cs*(As + 1) case OP_ADD : return GL_FUNC_ADD;
{ BLEND_ACCU , GL_FUNC_ADD , GL_SRC1_ALPHA , GL_ONE} , //?0201: (Cs - 0)*As + Cd ==> Cs*As + Cd case OP_SUBTRACT : return GL_FUNC_SUBTRACT;
{ BLEND_NO_BAR , GL_FUNC_ADD , GL_SRC1_ALPHA , GL_ZERO} , // 0202: (Cs - 0)*As + 0 ==> Cs*As case OP_REV_SUBTRACT : return GL_FUNC_REVERSE_SUBTRACT;
{ BLEND_A_MAX , GL_FUNC_ADD , GL_ONE , GL_ZERO} , //*0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1) default : ASSERT(0); return 0;
{ 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
};

View File

@ -29,12 +29,6 @@
#include "GSShaderOGL.h" #include "GSShaderOGL.h"
#include "GLState.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 #ifdef ENABLE_OGL_DEBUG_MEM_BW
extern uint64 g_real_texture_upload_byte; extern uint64 g_real_texture_upload_byte;
extern uint64 g_vertex_upload_byte; extern uint64 g_vertex_upload_byte;
@ -401,15 +395,10 @@ public:
MiscConstantBuffer() {memset(this, 0, sizeof(*this));} 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_inst;
static int m_shader_reg; static int m_shader_reg;
private: private:
int m_force_texture_clear; int m_force_texture_clear;
int m_mipmap; int m_mipmap;
TriFiltering m_filter; TriFiltering m_filter;
@ -506,7 +495,9 @@ public:
void OMAttachDs(GSTextureOGL* ds = NULL); void OMAttachDs(GSTextureOGL* ds = NULL);
void OMSetFBO(GLuint fbo); void OMSetFBO(GLuint fbo);
public: uint16 ConvertBlendEnum(uint16 generic) final;
public:
GSShaderOGL* m_shader; GSShaderOGL* m_shader;
GSDeviceOGL(); GSDeviceOGL();

View File

@ -482,7 +482,7 @@ void GSRendererOGL::EmulateBlending(bool DATE_GL42)
// Compute the blending equation to detect special case // Compute the blending equation to detect special case
uint8 blend_index = uint8(((ALPHA.A * 3 + ALPHA.B) * 3 + ALPHA.C) * 3 + ALPHA.D); 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. // 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 bool impossible_or_free_blend = (blend_flag & (BLEND_NO_BAR|BLEND_A_MAX|BLEND_ACCU)) // Blend doesn't requires the costly barrier