gsdx-ogl: Some colclip adjustments.

- Always enable sw colclip for BLEND_NO_BAR.
Free blending and it's faster than standard hdr algo when Blending
Accuracy is disabled.

- Enable sw colclip for Safe FBMASK SW emulated.
instead of hdr mode with accumulation blend so we don't use a mix of sw
and hw blending. It is more accurate.
Test case: Superman Shadows of Apokolips, fixes shadows when blending is enabled.

- Use const to get rid of some warnings.
This commit is contained in:
lightningterror 2020-02-23 22:30:15 +01:00
parent 3f467cae67
commit aaaf80f785
1 changed files with 19 additions and 12 deletions

View File

@ -484,17 +484,20 @@ 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 = dev->GetBlendFlags(blend_index);
const uint8 blend_index = uint8(((ALPHA.A * 3 + ALPHA.B) * 3 + ALPHA.C) * 3 + ALPHA.D);
const int blend_flag = m_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
|| (m_prim_overlap == PRIM_OVERLAP_NO) // Blend can be done in a single draw
|| (m_require_full_barrier); // Another effect (for example fbmask) already requires a full barrier
const bool impossible_or_free_blend = (blend_flag & (BLEND_NO_BAR|BLEND_A_MAX|BLEND_ACCU)) // Blend doesn't requires the costly barrier
|| (m_prim_overlap == PRIM_OVERLAP_NO) // Blend can be done in a single draw
|| (m_require_full_barrier); // Another effect (for example fbmask) already requires a full barrier
// Do the multiplication in shader for blending accumulation: Cs*As + Cd or Cs*Af + Cd
bool accumulation_blend = !!(blend_flag & BLEND_ACCU);
// Blending doesn't require barrier
const bool no_barrier_blend = !!(blend_flag & BLEND_NO_BAR);
// Warning no break on purpose
// Note: the "fall through" comments tell gcc not to complain about not having breaks.
switch (m_sw_blending) {
@ -523,11 +526,16 @@ void GSRendererOGL::EmulateBlending(bool DATE_GL42)
// Color clip
if (m_env.COLCLAMP.CLAMP == 0) {
if (m_prim_overlap == PRIM_OVERLAP_NO) {
// Safe FBMASK, avoid hitting accumulation mode on 16bit,
// fixes shadows in Superman shadows of Apokolips.
const bool sw_fbmask_colclip = !m_require_one_barrier && m_ps_sel.fbmask;
const bool free_colclip = m_prim_overlap == PRIM_OVERLAP_NO || no_barrier_blend || sw_fbmask_colclip;
GL_INS("COLCLIP Info (Blending: %d/%d/%d/%d, SW FBMASK: %d, OVERLAP: %d)",
ALPHA.A, ALPHA.B, ALPHA.C, ALPHA.D, sw_fbmask_colclip, m_prim_overlap);
if (free_colclip) {
// The fastest algo that requires a single pass
GL_INS("COLCLIP Free mode ENABLED");
m_ps_sel.colclip = 1;
//ASSERT(sw_blending);
sw_blending = true;
accumulation_blend = false; // disable the HDR algo
} else if (accumulation_blend) {
@ -537,11 +545,10 @@ void GSRendererOGL::EmulateBlending(bool DATE_GL42)
sw_blending = true; // Enable sw blending for the HDR algo
} else if (sw_blending) {
// A slow algo that could requires several passes (barely used)
GL_INS("COLCLIP SW ENABLED (blending is %d/%d/%d/%d)", ALPHA.A, ALPHA.B, ALPHA.C, ALPHA.D);
GL_INS("COLCLIP SW mode ENABLED");
m_ps_sel.colclip = 1;
} else {
// Speed hack skip previous slow algo
GL_INS("COLCLIP HDR Rare case ENABLED");
GL_INS("COLCLIP HDR mode ENABLED");
m_ps_sel.hdr = 1;
}
}
@ -582,7 +589,7 @@ void GSRendererOGL::EmulateBlending(bool DATE_GL42)
// Disable HW blending
dev->OMSetBlendState();
m_require_full_barrier |= !(blend_flag & BLEND_NO_BAR);
m_require_full_barrier |= !no_barrier_blend;
}
// Require the fix alpha vlaue
@ -593,7 +600,7 @@ void GSRendererOGL::EmulateBlending(bool DATE_GL42)
m_ps_sel.clr1 = !!(blend_flag & BLEND_C_CLR);
if (m_ps_sel.dfmt == 1 && ALPHA.C == 1) {
// 24 bits doesn't have an alpha channel so use 1.0f fix factor as equivalent
uint8 hacked_blend_index = blend_index + 3; // +3 <=> +1 on C
const uint8 hacked_blend_index = blend_index + 3; // +3 <=> +1 on C
dev->OMSetBlendState(hacked_blend_index, 128, true);
} else {
dev->OMSetBlendState(blend_index, ALPHA.FIX, (ALPHA.C == 2));