gsdx ogl: merge sprite hack take 2

try to detect paving correctly. Avoid to break effect such as Heat effect in Tekken5
This commit is contained in:
Gregory Hainaut 2016-05-14 12:17:59 +02:00
parent 2fc244a3eb
commit 4065730e36
1 changed files with 39 additions and 26 deletions

View File

@ -751,39 +751,52 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
#endif
}
// Post-processing hack
// Upscaling hack to avoid various line/grid issues
if (UserHacks_merge_sprite && tex && tex->m_target && (m_vt.m_primclass == GS_SPRITE_CLASS)) {
if (PRIM->FST && GSLocalMemory::m_psm[tex->m_TEX0.PSM].fmt < 2 && ((m_vt.m_eq.value & 0xCFFFF) == 0xCFFFF)) {
#ifdef ENABLE_OGL_DEBUG
const GSVector4 delta_p = m_vt.m_max.p - m_vt.m_min.p;
const GSVector4 delta_t = m_vt.m_max.t - m_vt.m_min.t;
GL_INS("PP SAMPLER: Dp %f %f Dt %f %f", delta_p.x, delta_p.y, delta_t.x, delta_t.y);
// Ideally the hack ought to be enabled in a true paving mode only. I don't know how to do it accurately
// neither in a fast way. So instead let's just take the hypothesis that all sprites must have the same
// size.
// Tested on Tekken 5.
GSVertex* v = &m_vertex.buff[0];
bool is_paving = true;
// SSE optimization: shuffle m[1] to have (4*32 bits) X, Y, U, V
int first_dpX = v[1].XYZ.X - v[0].XYZ.X;
int first_dpU = v[1].U - v[0].U;
for (int i = 0; i < m_vertex.next; i += 2) {
int dpX = v[i+1].XYZ.X - v[i].XYZ.X;
int dpU = v[i+1].U - v[i].U;
if (dpX != first_dpX || dpU != first_dpU) {
is_paving = false;
break;
}
}
#if 0
GSVector4 delta_p = m_vt.m_max.p - m_vt.m_min.p;
GSVector4 delta_t = m_vt.m_max.t - m_vt.m_min.t;
bool is_blit = PrimitiveOverlap() == PRIM_OVERLAP_NO;
GL_INS("PP SAMPLER: Dp %f %f Dt %f %f. Is blit %d, is paving %d, count %d", delta_p.x, delta_p.y, delta_t.x, delta_t.y, is_blit, is_paving, m_vertex.tail);
#endif
//fprintf(stderr, "SAMPLER: Dp %f %f Dt %f %f\n", delta_p.x, delta_p.y, delta_t.x, delta_t.y);
GSVertex* s = &m_vertex.buff[0];
//fprintf(stderr, "Before %d %d => %d %d \n", s[0].XYZ.X, s[0].XYZ.Y, s[1].XYZ.Y, s[1].XYZ.Y);
//fprintf(stderr, "SAMPLER: p %f %f OFFSET %d\n", m_vt.m_min.p.x, m_vt.m_max.p.x, m_context->XYOFFSET.OFX);
if (is_paving) {
// Replace all sprite with a single fullscreen sprite.
GSVertex* s = &m_vertex.buff[0];
s[0].XYZ.X = (16.0f * m_vt.m_min.p.x) + m_context->XYOFFSET.OFX;
s[1].XYZ.X = (16.0f * m_vt.m_max.p.x) + m_context->XYOFFSET.OFX;
s[0].XYZ.Y = (16.0f * m_vt.m_min.p.y) + m_context->XYOFFSET.OFY;
s[1].XYZ.Y = (16.0f * m_vt.m_max.p.y) + m_context->XYOFFSET.OFY;
s[0].XYZ.X = (16.0f * m_vt.m_min.p.x) + m_context->XYOFFSET.OFX;
s[1].XYZ.X = (16.0f * m_vt.m_max.p.x) + m_context->XYOFFSET.OFX;
s[0].XYZ.Y = (16.0f * m_vt.m_min.p.y) + m_context->XYOFFSET.OFY;
s[1].XYZ.Y = (16.0f * m_vt.m_max.p.y) + m_context->XYOFFSET.OFY;
//fprintf(stderr, "After %d %d => %d %d \n", s[0].XYZ.X, s[0].XYZ.Y, s[1].XYZ.Y, s[1].XYZ.Y);
s[0].U = 16.0f * m_vt.m_min.t.x;
s[0].V = 16.0f * m_vt.m_min.t.y;
s[1].U = 16.0f * m_vt.m_max.t.x;
s[1].V = 16.0f * m_vt.m_max.t.y;
//fprintf(stderr, "Before %d %d => %d %d \n", s[0].U, s[0].V, s[1].U, s[1].V);
s[0].U = 16.0f * m_vt.m_min.t.x;
s[0].V = 16.0f * m_vt.m_min.t.y;
s[1].U = 16.0f * m_vt.m_max.t.x;
s[1].V = 16.0f * m_vt.m_max.t.y;
//fprintf(stderr, "After %d %d => %d %d \n", s[0].U, s[0].V, s[1].U, s[1].V);
m_vertex.head = m_vertex.tail = m_vertex.next = 2;
m_index.tail = 2;
//exit(0);
m_vertex.head = m_vertex.tail = m_vertex.next = 2;
m_index.tail = 2;
}
}
}