GSDevice: Improve IsEffective() test

Ensure blending is disabled when colormask is zero.

Intel's (older) DX11 drivers apparently crash the GPU when SRC1_COLOR is
used in blend, when the shader doesn't output it, even though it's not
being written.

It was also missing entirely for OpenGL.
This commit is contained in:
Stenzek 2024-03-29 22:40:51 +10:00 committed by Connor McLaughlin
parent 11ee0a8613
commit 8679755d18
2 changed files with 24 additions and 5 deletions

View File

@ -860,7 +860,8 @@ void GSDevice::CAS(GSTexture*& tex, GSVector4i& src_rect, GSVector4& src_uv, con
bool GSHWDrawConfig::BlendState::IsEffective(ColorMaskSelector colormask) const
{
return enable && ((colormask.key & 7u) || src_factor_alpha != GSDevice::CONST_ZERO || dst_factor_alpha != GSDevice::CONST_ONE);
return enable && (((colormask.key & 7u) && (src_factor != GSDevice::CONST_ONE || dst_factor != GSDevice::CONST_ZERO)) ||
((colormask.key & 8u) && (src_factor_alpha != GSDevice::CONST_ONE || dst_factor_alpha != GSDevice::CONST_ZERO)));
}
// clang-format off

View File

@ -2528,10 +2528,17 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
PSSetShaderResource(3, primid_texture);
}
OMSetBlendState(config.blend.enable, s_gl_blend_factors[config.blend.src_factor],
s_gl_blend_factors[config.blend.dst_factor], s_gl_blend_ops[config.blend.op],
s_gl_blend_factors[config.blend.src_factor_alpha], s_gl_blend_factors[config.blend.dst_factor_alpha],
config.blend.constant_enable, config.blend.constant);
if (config.blend.IsEffective(config.colormask))
{
OMSetBlendState(config.blend.enable, s_gl_blend_factors[config.blend.src_factor],
s_gl_blend_factors[config.blend.dst_factor], s_gl_blend_ops[config.blend.op],
s_gl_blend_factors[config.blend.src_factor_alpha], s_gl_blend_factors[config.blend.dst_factor_alpha],
config.blend.constant_enable, config.blend.constant);
}
else
{
OMSetBlendState();
}
// avoid changing framebuffer just to switch from rt+depth to rt and vice versa
GSTexture* draw_rt = hdr_rt ? hdr_rt : config.rt;
@ -2573,6 +2580,17 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
psel.ps = config.alpha_second_pass.ps;
SetupPipeline(psel);
OMSetColorMaskState(config.alpha_second_pass.colormask);
if (config.blend.IsEffective(config.alpha_second_pass.colormask))
{
OMSetBlendState(config.blend.enable, s_gl_blend_factors[config.blend.src_factor],
s_gl_blend_factors[config.blend.dst_factor], s_gl_blend_ops[config.blend.op],
s_gl_blend_factors[config.blend.src_factor_alpha], s_gl_blend_factors[config.blend.dst_factor_alpha],
config.blend.constant_enable, config.blend.constant);
}
else
{
OMSetBlendState();
}
SetupOM(config.alpha_second_pass.depth);
SendHWDraw(config, psel.ps.IsFeedbackLoop());
}