diff options
| author | 2014-12-23 13:05:51 -0200 | |
|---|---|---|
| committer | 2014-12-29 02:08:11 -0200 | |
| commit | 8369ee58035ca98f776428f6cccbcf987fee3bc9 (patch) | |
| tree | 3c1800823ffe55529ba6dbcba0c4407d2da625f2 /src | |
| parent | GPU: Bitwise texture swizzling (diff) | |
| download | yuzu-8369ee58035ca98f776428f6cccbcf987fee3bc9.tar.gz yuzu-8369ee58035ca98f776428f6cccbcf987fee3bc9.tar.xz yuzu-8369ee58035ca98f776428f6cccbcf987fee3bc9.zip | |
Rasterizer: Pre-divide vertex attributes by W
Execute the division-by-W for perspective-correct interpolation of
values in the clipper, moving them out of the rasterization inner loop.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/clipper.cpp | 13 | ||||
| -rw-r--r-- | src/video_core/pica.h | 20 | ||||
| -rw-r--r-- | src/video_core/rasterizer.cpp | 7 |
3 files changed, 32 insertions, 8 deletions
diff --git a/src/video_core/clipper.cpp b/src/video_core/clipper.cpp index 0521ef866..1744066ba 100644 --- a/src/video_core/clipper.cpp +++ b/src/video_core/clipper.cpp | |||
| @@ -91,10 +91,17 @@ static void InitScreenCoordinates(OutputVertex& vtx) | |||
| 91 | viewport.zscale = float24::FromRawFloat24(registers.viewport_depth_range); | 91 | viewport.zscale = float24::FromRawFloat24(registers.viewport_depth_range); |
| 92 | viewport.offset_z = float24::FromRawFloat24(registers.viewport_depth_far_plane); | 92 | viewport.offset_z = float24::FromRawFloat24(registers.viewport_depth_far_plane); |
| 93 | 93 | ||
| 94 | float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w; | ||
| 95 | vtx.color *= inv_w; | ||
| 96 | vtx.tc0 *= inv_w; | ||
| 97 | vtx.tc1 *= inv_w; | ||
| 98 | vtx.tc2 *= inv_w; | ||
| 99 | vtx.pos.w = inv_w; | ||
| 100 | |||
| 94 | // TODO: Not sure why the viewport width needs to be divided by 2 but the viewport height does not | 101 | // TODO: Not sure why the viewport width needs to be divided by 2 but the viewport height does not |
| 95 | vtx.screenpos[0] = (vtx.pos.x / vtx.pos.w + float24::FromFloat32(1.0)) * viewport.halfsize_x + viewport.offset_x; | 102 | vtx.screenpos[0] = (vtx.pos.x * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_x + viewport.offset_x; |
| 96 | vtx.screenpos[1] = (vtx.pos.y / vtx.pos.w + float24::FromFloat32(1.0)) * viewport.halfsize_y + viewport.offset_y; | 103 | vtx.screenpos[1] = (vtx.pos.y * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_y + viewport.offset_y; |
| 97 | vtx.screenpos[2] = viewport.offset_z - vtx.pos.z / vtx.pos.w * viewport.zscale; | 104 | vtx.screenpos[2] = viewport.offset_z - vtx.pos.z * inv_w * viewport.zscale; |
| 98 | } | 105 | } |
| 99 | 106 | ||
| 100 | void ProcessTriangle(OutputVertex &v0, OutputVertex &v1, OutputVertex &v2) { | 107 | void ProcessTriangle(OutputVertex &v0, OutputVertex &v1, OutputVertex &v2) { |
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 89d97e4e9..38bac748c 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -757,6 +757,26 @@ struct float24 { | |||
| 757 | return float24::FromFloat32(ToFloat32() - flt.ToFloat32()); | 757 | return float24::FromFloat32(ToFloat32() - flt.ToFloat32()); |
| 758 | } | 758 | } |
| 759 | 759 | ||
| 760 | float24& operator *= (const float24& flt) { | ||
| 761 | value *= flt.ToFloat32(); | ||
| 762 | return *this; | ||
| 763 | } | ||
| 764 | |||
| 765 | float24& operator /= (const float24& flt) { | ||
| 766 | value /= flt.ToFloat32(); | ||
| 767 | return *this; | ||
| 768 | } | ||
| 769 | |||
| 770 | float24& operator += (const float24& flt) { | ||
| 771 | value += flt.ToFloat32(); | ||
| 772 | return *this; | ||
| 773 | } | ||
| 774 | |||
| 775 | float24& operator -= (const float24& flt) { | ||
| 776 | value -= flt.ToFloat32(); | ||
| 777 | return *this; | ||
| 778 | } | ||
| 779 | |||
| 760 | float24 operator - () const { | 780 | float24 operator - () const { |
| 761 | return float24::FromFloat32(-ToFloat32()); | 781 | return float24::FromFloat32(-ToFloat32()); |
| 762 | } | 782 | } |
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 63da7104d..a80148872 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -106,10 +106,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 106 | int bias1 = IsRightSideOrFlatBottomEdge(vtxpos[1].xy(), vtxpos[2].xy(), vtxpos[0].xy()) ? -1 : 0; | 106 | int bias1 = IsRightSideOrFlatBottomEdge(vtxpos[1].xy(), vtxpos[2].xy(), vtxpos[0].xy()) ? -1 : 0; |
| 107 | int bias2 = IsRightSideOrFlatBottomEdge(vtxpos[2].xy(), vtxpos[0].xy(), vtxpos[1].xy()) ? -1 : 0; | 107 | int bias2 = IsRightSideOrFlatBottomEdge(vtxpos[2].xy(), vtxpos[0].xy(), vtxpos[1].xy()) ? -1 : 0; |
| 108 | 108 | ||
| 109 | const Math::Vec3<float24> w_inverse = Math::MakeVec( | 109 | auto w_inverse = Math::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w); |
| 110 | float24::FromFloat32(1.0f) / v0.pos.w, | ||
| 111 | float24::FromFloat32(1.0f) / v1.pos.w, | ||
| 112 | float24::FromFloat32(1.0f) / v2.pos.w); | ||
| 113 | 110 | ||
| 114 | auto textures = registers.GetTextures(); | 111 | auto textures = registers.GetTextures(); |
| 115 | auto tev_stages = registers.GetTevStages(); | 112 | auto tev_stages = registers.GetTevStages(); |
| @@ -158,7 +155,7 @@ void ProcessTriangle(const VertexShader::OutputVertex& v0, | |||
| 158 | // | 155 | // |
| 159 | // The generalization to three vertices is straightforward in baricentric coordinates. | 156 | // The generalization to three vertices is straightforward in baricentric coordinates. |
| 160 | auto GetInterpolatedAttribute = [&](float24 attr0, float24 attr1, float24 attr2) { | 157 | auto GetInterpolatedAttribute = [&](float24 attr0, float24 attr1, float24 attr2) { |
| 161 | auto attr_over_w = Math::MakeVec(attr0, attr1, attr2) * w_inverse; | 158 | auto attr_over_w = Math::MakeVec(attr0, attr1, attr2); |
| 162 | float24 interpolated_attr_over_w = Math::Dot(attr_over_w, baricentric_coordinates); | 159 | float24 interpolated_attr_over_w = Math::Dot(attr_over_w, baricentric_coordinates); |
| 163 | return interpolated_attr_over_w * interpolated_w_inverse; | 160 | return interpolated_attr_over_w * interpolated_w_inverse; |
| 164 | }; | 161 | }; |