void GSRasterizer::DrawLine(const GSVertexSW* v, const GSVector4i& scissor) { GSVertexSW dv = v[1] - v[0]; GSVector4 dp = dv.p.abs(); GSVector4i dpi(dp); if(dpi.y == 0) { if(dpi.x > 0) { // shortcut for horizontal lines GSVector4 mask = (v[0].p > v[1].p).xxxx(); GSVertexSW l, dl; l.p = v[0].p.blend8(v[1].p, mask); l.t = v[0].t.blend8(v[1].t, mask); l.c = v[0].c.blend8(v[1].c, mask); GSVector4 r; r = v[1].p.blend8(v[0].p, mask); GSVector4i p(l.p); if(scissor.y <= p.y && p.y < scissor.w) { GSVertexSW dscan = dv / dv.p.xxxx(); (m_ds->*m_dsf.sp)(v, dscan); l.p = l.p.upl(r).xyzw(l.p); // r.x => l.y DrawTriangleSection(p.y, p.y + 1, l, dl, dscan, scissor); } } return; } int i = dpi.x > dpi.y ? 0 : 1; GSVertexSW edge = v[0]; GSVertexSW dedge = dv / dp.v[i]; // TODO: prestep + clip with the scissor int steps = dpi.v[i]; while(steps-- > 0) { DrawPoint(&edge, scissor); edge += dedge; } }
void GSRasterizer::DrawTriangleBottom(GSVertexSW* v, const GSVector4i& scissor) { GSVertexSW longest; longest.p = v[1].p - v[0].p; int i = longest.p.upl(longest.p == GSVector4::zero()).mask(); if(i & 2) return; i &= 1; GSVertexSW& l = v[i]; GSVector4& r = v[1 - i].p; GSVector4 fscissor(scissor); GSVector4 tb = l.p.upl(v[2].p).ceil(); GSVector4 tbmax = tb.max(fscissor.yyyy()); GSVector4 tbmin = tb.min(fscissor.wwww()); GSVector4i tbi = GSVector4i(tbmax.zzww(tbmin)); int top = tbi.extract32<0>(); int bottom = tbi.extract32<2>(); if(top >= bottom) return; longest.t = v[1].t - v[0].t; longest.c = v[1].c - v[0].c; GSVertexSW dscan = longest * longest.p.xxxx().rcp(); GSVertexSW vl = v[2] - l; GSVector4 vr = v[2].p - r; GSVertexSW dl = vl / vl.p.yyyy(); GSVector4 dr = vr / vr.yyyy(); GSVector4 dy = tbmax.zzzz() - l.p.yyyy(); l.p = l.p.upl(r).xyzw(l.p); // r.x => l.y dl.p = dl.p.upl(dr).xyzw(dl.p); // dr.x => dl.y l += dl * dy; m_dsf.ssp(v, dscan); DrawTriangleSection(top, bottom, l, dl, dscan, fscissor); }
void GSRasterizer::DrawTriangleBottom(GSVertexSW* v, const GSVector4i& scissor) { GSVertexSW longest; longest.p = v[1].p - v[0].p; int i = (longest.p > GSVector4::zero()).upl(longest.p == GSVector4::zero()).mask(); if(i & 2) return; i &= 1; GSVertexSW& l = v[1 - i]; GSVector4& r = v[i].p; GSVector4i tb(l.p.xyxy(v[2].p).ceil()); int top = tb.extract32<1>(); int bottom = tb.extract32<3>(); if(top < scissor.y) top = scissor.y; if(bottom > scissor.w) bottom = scissor.w; if(top >= bottom) return; longest.t = v[1].t - v[0].t; longest.c = v[1].c - v[0].c; GSVertexSW dscan = longest * longest.p.xxxx().rcp(); GSVertexSW vl = v[2] - l; GSVector4 vr = v[2].p - r; GSVertexSW dl = vl / vl.p.yyyy(); GSVector4 dr = vr / vr.yyyy(); float py = (float)top - l.p.y; l.p = l.p.upl(r).xyzw(l.p); // r.x => l.y dl.p = dl.p.upl(dr).xyzw(dl.p); // dr.x => dl.y if(py > 0) l += dl * py; (m_ds->*m_dsf.sp)(v, dscan); // TODO: (m_dsf.ssp)(v, dscan); DrawTriangleSection(top, bottom, l, dl, dscan, scissor); }
void GSRasterizer::DrawTriangleTopBottom(GSVertexSW* v, const GSVector4i& scissor) { GSVertexSW dv[3]; dv[0] = v[1] - v[0]; dv[1] = v[2] - v[0]; GSVertexSW longest = v[0] + dv[1] * (dv[0].p / dv[1].p).yyyy() - v[1]; int i = (longest.p > GSVector4::zero()).upl(longest.p == GSVector4::zero()).mask(); if(i & 2) return; i &= 1; GSVertexSW dscan = longest * longest.p.xxxx().rcp(); (m_ds->*m_dsf.sp)(v, dscan); // TODO: (m_dsf.ssp)(v, dscan); GSVertexSW& l = v[0]; GSVector4 r = v[0].p; GSVertexSW dl; GSVector4 dr; dl = dv[1 - i] / dv[1 - i].p.yyyy(); dr = dv[i].p / dv[i].p.yyyy(); GSVector4i tb(v[0].p.yyyy(v[1].p).xzyy(v[2].p).ceil()); int top = tb.x; int bottom = tb.y; if(top < scissor.y) top = scissor.y; if(bottom > scissor.w) bottom = scissor.w; float py = (float)top - l.p.y; if(py > 0) { GSVector4 dy(py); l += dl * dy; r += dr * dy; } if(top < bottom) { DrawTriangleSection(top, bottom, l, dl, r, dr, dscan, scissor); } if(i) { l = v[1]; dv[2] = v[2] - v[1]; dl = dv[2] / dv[2].p.yyyy(); } else { r = v[1].p; dv[2].p = v[2].p - v[1].p; dr = dv[2].p / dv[2].p.yyyy(); } top = tb.y; bottom = tb.z; if(top < scissor.y) top = scissor.y; if(bottom > scissor.w) bottom = scissor.w; if(top < bottom) { py = (float)top - l.p.y; if(py > 0) l += dl * py; py = (float)top - r.y; if(py > 0) r += dr * py; l.p = l.p.upl(r).xyzw(l.p); // r.x => l.y dl.p = dl.p.upl(dr).xyzw(dl.p); // dr.x => dl.y DrawTriangleSection(top, bottom, l, dl, dscan, scissor); } }
void GSRasterizer::DrawTriangleTopBottom(GSVertexSW* v, const GSVector4i& scissor) { GSVertexSW dv[3]; dv[0] = v[1] - v[0]; dv[1] = v[2] - v[0]; GSVertexSW longest = dv[1] * (dv[0].p / dv[1].p).yyyy() - dv[0]; int i = longest.p.upl(longest.p == GSVector4::zero()).mask(); if(i & 2) return; i &= 1; GSVertexSW dscan = longest * longest.p.xxxx().rcp(); m_dsf.ssp(v, dscan); GSVector4 fscissor(scissor); GSVector4 tb = v[0].p.upl(v[1].p).zwzw(v[1].p.upl(v[2].p)).ceil(); GSVector4 tbmax = tb.max(fscissor.yyyy()); GSVector4 tbmin = tb.min(fscissor.wwww()); GSVector4i tbi = GSVector4i(tbmax.xzyw(tbmin)); int top = tbi.extract32<0>(); int bottom = tbi.extract32<2>(); GSVertexSW& l = v[0]; GSVector4 r = v[0].p; GSVertexSW dl = dv[i] / dv[i].p.yyyy(); GSVector4 dr = dv[1 - i].p / dv[1 - i].p.yyyy(); GSVector4 dy = tbmax.xxxx() - l.p.yyyy(); l += dl * dy; r += dr * dy; if(top < bottom) { DrawTriangleSection(top, bottom, l, dl, r, dr, dscan, fscissor); } top = tbi.y; bottom = tbi.w; if(top < bottom) { if(i == 0) { l = v[1]; dv[2] = v[2] - v[1]; dl = dv[2] / dv[2].p.yyyy(); } else { r = v[1].p; dv[2].p = v[2].p - v[1].p; dr = dv[2].p / dv[2].p.yyyy(); } l += dl * (tbmax.zzzz() - l.p.yyyy()); r += dr * (tbmax.zzzz() - r.yyyy()); l.p = l.p.upl(r).xyzw(l.p); // r.x => l.y dl.p = dl.p.upl(dr).xyzw(dl.p); // dr.x => dl.y DrawTriangleSection(top, bottom, l, dl, dscan, fscissor); } }
void GSRasterizer::DrawLine(const GSVertexSW* v, const GSVector4i& scissor) { GSVertexSW dv = v[1] - v[0]; GSVector4 dp = dv.p.abs(); if(m_dsf.ssle) { int i = (dp < dp.yxwz()).mask() & 1; // |x| <= |y| GSVertexSW dscan; dscan.p = GSVector4::zero(); dscan.t = GSVector4::zero(); dscan.c = GSVector4::zero(); m_dsf.ssp(v, dscan); DrawEdge(v[0], v[1], dv, scissor, i, 0); DrawEdge(v[0], v[1], dv, scissor, i, 1); return; } GSVector4i dpi(dp); if(dpi.y == 0) { if(dpi.x > 0) { // shortcut for horizontal lines GSVector4 mask = (v[0].p > v[1].p).xxxx(); GSVertexSW l, dl; l.p = v[0].p.blend8(v[1].p, mask); l.t = v[0].t.blend8(v[1].t, mask); l.c = v[0].c.blend8(v[1].c, mask); GSVector4 r; r = v[1].p.blend8(v[0].p, mask); GSVector4i p(l.p); if(scissor.top <= p.y && p.y < scissor.bottom) { GSVertexSW dscan = dv / dv.p.xxxx(); m_dsf.ssp(v, dscan); l.p = l.p.upl(r).xyzw(l.p); // r.x => l.y GSVector4 fscissor(scissor); DrawTriangleSection(p.y, p.y + 1, l, dl, dscan, fscissor); } } return; } int i = dpi.x > dpi.y ? 0 : 1; GSVertexSW edge = v[0]; GSVertexSW dedge = dv / dp.v[i]; // TODO: prestep + clip with the scissor int steps = dpi.v[i]; while(steps-- > 0) { DrawPoint(&edge, scissor); edge += dedge; } }