mirror of https://github.com/PCSX2/pcsx2.git
gsdx ogl: reimplement merge circuit to support feedback write
This commit is contained in:
parent
06055add5c
commit
deb2ed3d09
|
@ -1393,23 +1393,56 @@ void GSDeviceOGL::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
|
||||||
{
|
{
|
||||||
GL_PUSH("DoMerge");
|
GL_PUSH("DoMerge");
|
||||||
|
|
||||||
bool slbg = PMODE.SLBG;
|
GSVector4 full_r(0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
bool mmod = PMODE.MMOD;
|
bool feedback_write_2 = PMODE.EN2 && sTex[2] != nullptr && EXTBUF.FBIN == 1;
|
||||||
|
bool feedback_write_1 = PMODE.EN1 && sTex[2] != nullptr && EXTBUF.FBIN == 0;
|
||||||
|
bool feedback_write_2_but_blend_bg = feedback_write_2 && PMODE.SLBG == 1;
|
||||||
|
|
||||||
|
// Merge the 2 source textures (sTex[0],sTex[1]). Final results go to dTex. Feedback write will go to sTex[2].
|
||||||
|
// If either 2nd output is disabled or SLBG is 1, a background color will be used.
|
||||||
|
// Note: background color is also used when outside of the unit rectangle area
|
||||||
OMSetColorMaskState();
|
OMSetColorMaskState();
|
||||||
ClearRenderTarget(dTex, c);
|
ClearRenderTarget(dTex, c);
|
||||||
|
|
||||||
if(sTex[1] && !slbg)
|
// Upload constant to select YUV algo
|
||||||
{
|
if (feedback_write_2 || feedback_write_1) {
|
||||||
StretchRect(sTex[1], sRect[1], dTex, dRect[1], m_merge_obj.ps[0]);
|
// Write result to feedback loop
|
||||||
|
m_misc_cb_cache.EMOD_AC.x = EXTBUF.EMODA;
|
||||||
|
m_misc_cb_cache.EMOD_AC.y = EXTBUF.EMODC;
|
||||||
|
m_convert.cb->cache_upload(&m_misc_cb_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sTex[0])
|
if (sTex[1] && (PMODE.SLBG == 0 || feedback_write_2_but_blend_bg)) {
|
||||||
{
|
// 2nd output is enabled and selected. Copy it to destination so we can blend it with 1st output
|
||||||
|
// Note: value outside of dRect must contains the background color (c)
|
||||||
|
StretchRect(sTex[1], sRect[1], dTex, dRect[1], ShaderConvert_COPY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save 2nd output
|
||||||
|
if (feedback_write_2) // FIXME I'm not sure dRect[1] is always correct
|
||||||
|
StretchRect(dTex, full_r, sTex[2], dRect[1], ShaderConvert_YUV);
|
||||||
|
|
||||||
|
// Restore background color to process the normal merge
|
||||||
|
if (feedback_write_2_but_blend_bg)
|
||||||
|
ClearRenderTarget(dTex, c);
|
||||||
|
|
||||||
|
if (sTex[0]) {
|
||||||
|
if (PMODE.AMOD == 1) // Keep the alpha from the 2nd output
|
||||||
|
OMSetColorMaskState(OMColorMaskSelector(0x7));
|
||||||
|
|
||||||
|
// 1st output is enabled. It must be blended
|
||||||
|
if (PMODE.MMOD == 1) {
|
||||||
|
// Blend with a constant alpha
|
||||||
m_merge_obj.cb->cache_upload(&c.v);
|
m_merge_obj.cb->cache_upload(&c.v);
|
||||||
|
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[1], m_MERGE_BLEND);
|
||||||
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[mmod ? 1 : 0], m_MERGE_BLEND);
|
} else {
|
||||||
|
// Blend with 2 * input alpha
|
||||||
|
StretchRect(sTex[0], sRect[0], dTex, dRect[0], m_merge_obj.ps[0], m_MERGE_BLEND);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (feedback_write_1) // FIXME I'm not sure dRect[0] is always correct
|
||||||
|
StretchRect(dTex, full_r, sTex[2], dRect[0], ShaderConvert_YUV);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset)
|
void GSDeviceOGL::DoInterlace(GSTexture* sTex, GSTexture* dTex, int shader, bool linear, float yoffset)
|
||||||
|
|
Loading…
Reference in New Issue