gsdx-ogl: extend cclip blending level with destination alpha blending

The purpose is to emulate correctly destination alpha factor

An alpha channel of 128 is 1.0 in the GS but only ~0.5 in the GPU

I think few draw call use destination alpha so impact on perf must remains small.
This commit is contained in:
Gregory Hainaut 2015-07-25 18:20:00 +02:00
parent 97b38d9e1b
commit a0edcb58af
4 changed files with 17 additions and 14 deletions

View File

@ -366,7 +366,7 @@ bool GSRendererOGL::EmulateBlending(GSDeviceOGL::PSSelector& ps_sel, GSDeviceOGL
if (accumulation_blend) { if (accumulation_blend) {
ps_sel.hdr = 1; ps_sel.hdr = 1;
GL_INS("COLCLIP Fast HDR mode ENABLED"); GL_INS("COLCLIP Fast HDR mode ENABLED");
} else if (m_sw_blending >= ACC_BLEND_CCLIP || sw_blending_base) { } else if (m_sw_blending >= ACC_BLEND_CCLIP_DALPHA || sw_blending_base) {
ps_sel.colclip = 1; ps_sel.colclip = 1;
sw_blending_base = true; sw_blending_base = true;
GL_INS("COLCLIP SW ENABLED (blending is %d/%d/%d/%d)", ALPHA.A, ALPHA.B, ALPHA.C, ALPHA.D); GL_INS("COLCLIP SW ENABLED (blending is %d/%d/%d/%d)", ALPHA.A, ALPHA.B, ALPHA.C, ALPHA.D);
@ -378,17 +378,18 @@ bool GSRendererOGL::EmulateBlending(GSDeviceOGL::PSSelector& ps_sel, GSDeviceOGL
// Note: Option is duplicated, one impact the blend unit / the other the shader. // Note: Option is duplicated, one impact the blend unit / the other the shader.
sw_blending_base |= accumulation_blend; sw_blending_base |= accumulation_blend;
bool all_blend_sw; // Warning no break on purpose
bool sw_blending_adv = false;
switch (m_sw_blending) { switch (m_sw_blending) {
case ACC_BLEND_ULTRA: all_blend_sw = true; break; case ACC_BLEND_ULTRA: sw_blending_adv |= true;
case ACC_BLEND_FULL: all_blend_sw = !( (ALPHA.A == ALPHA.B) || (ALPHA.C == 2 && afix <= 1.002f) ); break; case ACC_BLEND_FULL: sw_blending_adv |= !( (ALPHA.A == ALPHA.B) || (ALPHA.C == 2 && afix <= 1.002f) );
case ACC_BLEND_CCLIP: case ACC_BLEND_CCLIP_DALPHA: sw_blending_adv |= (ALPHA.C == 1);
case ACC_BLEND_SPRITE: all_blend_sw = m_vt.m_primclass == GS_SPRITE_CLASS; break; case ACC_BLEND_SPRITE: sw_blending_adv |= m_vt.m_primclass == GS_SPRITE_CLASS;
default: all_blend_sw = false; break; default: break;
} }
bool sw_blending = sw_blending_base // Free case or Impossible blend bool sw_blending = sw_blending_base // Free case or Impossible blend
|| all_blend_sw // all blend || sw_blending_adv // complex blending case (for special effect)
|| ps_sel.fbmask; // accurate fbmask || ps_sel.fbmask; // accurate fbmask
@ -399,7 +400,9 @@ bool GSRendererOGL::EmulateBlending(GSDeviceOGL::PSSelector& ps_sel, GSDeviceOGL
sw_blending &= !DATE_GL42; sw_blending &= !DATE_GL42;
// Seriously don't expect me to support this kind of crazyness. // Seriously don't expect me to support this kind of crazyness.
// No mix of COLCLIP + accumulation_blend + DATE GL42 // No mix of COLCLIP + accumulation_blend + DATE GL42
// Neither fbmask and GL42
ASSERT(!(ps_sel.hdr && DATE_GL42)); ASSERT(!(ps_sel.hdr && DATE_GL42));
ASSERT(!(ps_sel.fbmask && DATE_GL42));
// For stat to optimize accurate option // For stat to optimize accurate option
#if 0 #if 0

View File

@ -39,7 +39,7 @@ class GSRendererOGL : public GSRendererHW
ACC_BLEND_NONE = 0, ACC_BLEND_NONE = 0,
ACC_BLEND_FREE = 1, ACC_BLEND_FREE = 1,
ACC_BLEND_SPRITE = 2, ACC_BLEND_SPRITE = 2,
ACC_BLEND_CCLIP = 3, ACC_BLEND_CCLIP_DALPHA = 3,
ACC_BLEND_FULL = 4, ACC_BLEND_FULL = 4,
ACC_BLEND_ULTRA = 5 ACC_BLEND_ULTRA = 5
}; };

View File

@ -123,11 +123,11 @@ const char* dialog_message(int ID, bool* updateText) {
"------------------------------------------------------------------\n" "------------------------------------------------------------------\n"
"Basic\t: Emulate correctly most of the effects with a limited speed penality. It is the recommended setting.\n" "Basic\t: Emulate correctly most of the effects with a limited speed penality. It is the recommended setting.\n"
"------------------------------------------------------------------\n" "------------------------------------------------------------------\n"
"Medium\t: Add emulation of all sprites. Performance impact remains reasonable in 3D game.\n" "Medium\t: Extend it to all sprites. Performance impact remains reasonable in 3D game.\n"
"------------------------------------------------------------------\n" "------------------------------------------------------------------\n"
"High\t: Add full emulation of color wrapping. It helps Castlevania games. Be aware that it will half your FPS.\n" "High\t: Extend it to destination alpha blending and color wrapping. (help shadow and fog effect). A good CPU is required\n"
"------------------------------------------------------------------\n" "------------------------------------------------------------------\n"
"Full\t\t: Except few cases, the blending unit will be fully emulated by the shader. It is very slow! It is intended for debug\n" "Full\t\t: Except few cases, the blending unit will be fully emulated by the shader. It is ultra slow! It is intended for debug\n"
"------------------------------------------------------------------\n" "------------------------------------------------------------------\n"
"Ultra\t: The blending unit will be completely emulated by the shader. It is ultra slow! It is intended for debug\n"; "Ultra\t: The blending unit will be completely emulated by the shader. It is ultra slow! It is intended for debug\n";
#endif #endif

View File

@ -187,9 +187,9 @@ GSdxApp::GSdxApp()
m_gs_crc_level.push_back(GSSetting(4 , "Aggressive", "")); m_gs_crc_level.push_back(GSSetting(4 , "Aggressive", ""));
m_gs_acc_blend_level.push_back(GSSetting(0, "None", "Fastest")); m_gs_acc_blend_level.push_back(GSSetting(0, "None", "Fastest"));
m_gs_acc_blend_level.push_back(GSSetting(1, "Basic", "Recommended")); m_gs_acc_blend_level.push_back(GSSetting(1, "Basic", "Recommended low-end PC"));
m_gs_acc_blend_level.push_back(GSSetting(2, "Medium", "")); m_gs_acc_blend_level.push_back(GSSetting(2, "Medium", ""));
m_gs_acc_blend_level.push_back(GSSetting(3, "High", "Slow")); m_gs_acc_blend_level.push_back(GSSetting(3, "High", "Recommended high-end PC"));
m_gs_acc_blend_level.push_back(GSSetting(4, "Full", "Very Slow")); m_gs_acc_blend_level.push_back(GSSetting(4, "Full", "Very Slow"));
m_gs_acc_blend_level.push_back(GSSetting(5, "Ultra", "Ultra Slow")); m_gs_acc_blend_level.push_back(GSSetting(5, "Ultra", "Ultra Slow"));