From 0d7c58065a456335b457950ca2fa74119a1bbc9f Mon Sep 17 00:00:00 2001 From: gabest11 Date: Sat, 3 Dec 2011 21:04:46 +0000 Subject: [PATCH] GSdx: this fixes some of the flickering in THPS, objects in the far distance still have some z-fighting problem, z values used are too large and too close to each other. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4976 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GSRasterizer.cpp | 41 +++++++++++++++++------------------ plugins/GSdx/GSRasterizer.h | 2 +- plugins/GSdx/GSTextureSW.cpp | 11 +++++++++- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/plugins/GSdx/GSRasterizer.cpp b/plugins/GSdx/GSRasterizer.cpp index 5dd257377e..f80fc8196d 100644 --- a/plugins/GSdx/GSRasterizer.cpp +++ b/plugins/GSdx/GSRasterizer.cpp @@ -196,9 +196,12 @@ void GSRasterizer::DrawLine(const GSVertexSW* v) { GSVertexSW dscan = dv / dv.p.xxxx(); + GSVector4 x0 = l.p.xxxx(); + GSVector4 y0 = l.p.yyyy(); + l.p = l.p.upl(r).xyzw(l.p); // r.x => l.y - DrawTriangleSection(p.y, p.y + 1, l, dl, dscan, l.p.xxxx()); + DrawTriangleSection(p.y, p.y + 1, l, dl, dscan, x0, y0); Flush(v, dscan); } @@ -348,14 +351,10 @@ void GSRasterizer::DrawTriangle(const GSVertexSW* vertices) { edge = v[1 - j]; - GSVector4 dy = tbmax.xxxx() - edge.p.yyyy(); - edge.p = edge.p.insert<0, 1>(v[j].p); dedge.p = ddx[2 - (j << 1)].yzzw(dedge.p); - edge += dedge * dy; - - DrawTriangleSection(tb.x, tb.w, edge, dedge, dscan, v[1 - j].p.xxxx()); + DrawTriangleSection(tb.x, tb.w, edge, dedge, dscan, v[1 - j].p.xxxx(), v[1 - j].p.yyyy()); } } else @@ -366,28 +365,20 @@ void GSRasterizer::DrawTriangle(const GSVertexSW* vertices) { edge = v[0]; - GSVector4 dy = tbmax.xxxx() - edge.p.yyyy(); - edge.p = edge.p.xxzw(); dedge.p = ddx[j].xyzw(dedge.p); - edge += dedge * dy; - - DrawTriangleSection(tb.x, tb.z, edge, dedge, dscan, x0); + DrawTriangleSection(tb.x, tb.z, edge, dedge, dscan, x0, v[0].p.yyyy()); } if(tb.y < tb.w) { edge = v[1]; - GSVector4 dy = tbmax.zzzz() - edge.p.yyyy(); - edge.p = (x0 + ddx[j] * dv[0].p.yyyy()).xyzw(edge.p); dedge.p = ddx[2 - (j << 1)].yzzw(dedge.p); - edge += dedge * dy; - - DrawTriangleSection(tb.y, tb.w, edge, dedge, dscan, v[1].p.xxxx()); + DrawTriangleSection(tb.y, tb.w, edge, dedge, dscan, v[1].p.xxxx(), v[1].p.yyyy()); } } @@ -410,7 +401,7 @@ void GSRasterizer::DrawTriangle(const GSVertexSW* vertices) } } -void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW& edge, const GSVertexSW& dedge, const GSVertexSW& dscan, const GSVector4& x0) +void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW& edge, const GSVertexSW& dedge, const GSVertexSW& dscan, const GSVector4& x0, const GSVector4& y0) { ASSERT(top < bottom); ASSERT(edge.p.x <= edge.p.y); @@ -419,11 +410,17 @@ void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW& edge, co GSVector4 scissor = m_fscissor.xzxz(); + GSVector4 prestep = GSVector4(top) - y0; + + GSVertexSW o = dedge * prestep; + while(1) { if(IsOneOfMyScanlines(top)) { - GSVector4 lrf = edge.p.ceil(); + GSVertexSW scan = edge + o; + + GSVector4 lrf = scan.p.ceil(); GSVector4 l = lrf.max(scissor); GSVector4 r = lrf.min(scissor); GSVector4i lr = GSVector4i(l.xxyy(r)); @@ -437,15 +434,17 @@ void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW& edge, co { m_stats.pixels += pixels; - GSVector4 prestep = l.xxxx() - x0; + prestep = l.xxxx() - x0; - AddScanline(e++, pixels, left, top, edge + dscan * prestep); + AddScanline(e++, pixels, left, top, scan + dscan * prestep); } } if(++top >= bottom) break; - edge += dedge; + // NOTE: it is more accurate to accumlate the offset, edge values (especially p.z) may become too large compared to dedge (example: 8000000 + 259.4 == 8000000 + 259.3) + + o += dedge; } m_edge.count += e - &m_edge.buff[m_edge.count]; diff --git a/plugins/GSdx/GSRasterizer.h b/plugins/GSdx/GSRasterizer.h index 10703d9aca..8aa40c6c90 100644 --- a/plugins/GSdx/GSRasterizer.h +++ b/plugins/GSdx/GSRasterizer.h @@ -116,7 +116,7 @@ protected: void DrawTriangle(const GSVertexSW* v); void DrawSprite(const GSVertexSW* v); - __forceinline void DrawTriangleSection(int top, int bottom, GSVertexSW& edge, const GSVertexSW& dedge, const GSVertexSW& dscan, const GSVector4& x0); + __forceinline void DrawTriangleSection(int top, int bottom, GSVertexSW& edge, const GSVertexSW& dedge, const GSVertexSW& dscan, const GSVector4& x0, const GSVector4& y0); void DrawEdge(const GSVertexSW& v0, const GSVertexSW& v1, const GSVertexSW& dv, int orientation, int side); diff --git a/plugins/GSdx/GSTextureSW.cpp b/plugins/GSdx/GSTextureSW.cpp index 7dc1498a22..4011f6ed8c 100644 --- a/plugins/GSdx/GSTextureSW.cpp +++ b/plugins/GSdx/GSTextureSW.cpp @@ -156,7 +156,16 @@ bool GSTextureSW::Save(const string& fn, bool dds) for(int h = m_size.y; h > 0; h--, data -= m_pitch) { - fwrite(data, 1, m_size.x << 2, fp); // TODO: swap red-blue? + for(int i = 0; i < m_size.x; i++) + { + uint32 c = ((uint32*)data)[i]; + + c = (c & 0xff00ff00) | ((c & 0x00ff0000) >> 16) | ((c & 0x000000ff) << 16); + + fwrite(&c, 1, sizeof(c), fp); + } + + // fwrite(data, 1, m_size.x << 2, fp); // TODO: swap red-blue? } fclose(fp);