diff options
| author | 2017-06-11 11:55:35 -0500 | |
|---|---|---|
| committer | 2017-07-11 19:39:15 +0300 | |
| commit | 73566ff7a990cdfe8d8f023997b57942dc785fc4 (patch) | |
| tree | ba42cbed66eeb4cd08012181f774a8633b9c2120 /src | |
| parent | SwRasterizer: Corrected the light LUT lookups. (diff) | |
| download | yuzu-73566ff7a990cdfe8d8f023997b57942dc785fc4.tar.gz yuzu-73566ff7a990cdfe8d8f023997b57942dc785fc4.tar.xz yuzu-73566ff7a990cdfe8d8f023997b57942dc785fc4.zip | |
SwRasterizer: Flip the vertex quaternions before clipping (if necessary).
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/vector_math.h | 2 | ||||
| -rw-r--r-- | src/video_core/swrasterizer/clipper.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/swrasterizer/rasterizer.cpp | 24 |
3 files changed, 16 insertions, 21 deletions
diff --git a/src/common/vector_math.h b/src/common/vector_math.h index c7a461a1e..d0fe0e405 100644 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h | |||
| @@ -462,7 +462,7 @@ public: | |||
| 462 | z -= other.z; | 462 | z -= other.z; |
| 463 | w -= other.w; | 463 | w -= other.w; |
| 464 | } | 464 | } |
| 465 | template <typename Q = T, class = typename std::enable_if<std::is_signed<Q>::value>::type> | 465 | template <typename Q = T> |
| 466 | Vec4<decltype(-T{})> operator-() const { | 466 | Vec4<decltype(-T{})> operator-() const { |
| 467 | return MakeVec(-x, -y, -z, -w); | 467 | return MakeVec(-x, -y, -z, -w); |
| 468 | } | 468 | } |
diff --git a/src/video_core/swrasterizer/clipper.cpp b/src/video_core/swrasterizer/clipper.cpp index 6fb923756..7537689b7 100644 --- a/src/video_core/swrasterizer/clipper.cpp +++ b/src/video_core/swrasterizer/clipper.cpp | |||
| @@ -95,6 +95,17 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu | |||
| 95 | static const size_t MAX_VERTICES = 9; | 95 | static const size_t MAX_VERTICES = 9; |
| 96 | static_vector<Vertex, MAX_VERTICES> buffer_a = {v0, v1, v2}; | 96 | static_vector<Vertex, MAX_VERTICES> buffer_a = {v0, v1, v2}; |
| 97 | static_vector<Vertex, MAX_VERTICES> buffer_b; | 97 | static_vector<Vertex, MAX_VERTICES> buffer_b; |
| 98 | |||
| 99 | auto FlipQuaternionIfOpposite = [](auto& a, const auto& b) { | ||
| 100 | if (Math::Dot(a, b) < float24::Zero()) | ||
| 101 | a = -a; | ||
| 102 | }; | ||
| 103 | |||
| 104 | // Flip the quaternions if they are opposite to prevent interpolating them over the wrong | ||
| 105 | // direction. | ||
| 106 | FlipQuaternionIfOpposite(buffer_a[1].quat, buffer_a[0].quat); | ||
| 107 | FlipQuaternionIfOpposite(buffer_a[2].quat, buffer_a[0].quat); | ||
| 108 | |||
| 98 | auto* output_list = &buffer_a; | 109 | auto* output_list = &buffer_a; |
| 99 | auto* input_list = &buffer_b; | 110 | auto* input_list = &buffer_b; |
| 100 | 111 | ||
diff --git a/src/video_core/swrasterizer/rasterizer.cpp b/src/video_core/swrasterizer/rasterizer.cpp index 2c804b6e7..76f793c86 100644 --- a/src/video_core/swrasterizer/rasterizer.cpp +++ b/src/video_core/swrasterizer/rasterizer.cpp | |||
| @@ -362,13 +362,6 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Qu | |||
| 362 | }; | 362 | }; |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | static bool AreQuaternionsOpposite(Math::Vec4<Pica::float24> qa, Math::Vec4<Pica::float24> qb) { | ||
| 366 | Math::Vec4f a{ qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32() }; | ||
| 367 | Math::Vec4f b{ qb.x.ToFloat32(), qb.y.ToFloat32(), qb.z.ToFloat32(), qb.w.ToFloat32() }; | ||
| 368 | |||
| 369 | return (Math::Dot(a, b) < 0.f); | ||
| 370 | } | ||
| 371 | |||
| 372 | MICROPROFILE_DEFINE(GPU_Rasterization, "GPU", "Rasterization", MP_RGB(50, 50, 240)); | 365 | MICROPROFILE_DEFINE(GPU_Rasterization, "GPU", "Rasterization", MP_RGB(50, 50, 240)); |
| 373 | 366 | ||
| 374 | /** | 367 | /** |
| @@ -462,15 +455,6 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 462 | int bias2 = | 455 | int bias2 = |
| 463 | IsRightSideOrFlatBottomEdge(vtxpos[2].xy(), vtxpos[0].xy(), vtxpos[1].xy()) ? -1 : 0; | 456 | IsRightSideOrFlatBottomEdge(vtxpos[2].xy(), vtxpos[0].xy(), vtxpos[1].xy()) ? -1 : 0; |
| 464 | 457 | ||
| 465 | // Flip the quaternions if they are opposite to prevent interpolating them over the wrong direction. | ||
| 466 | auto v1_quat = v1.quat; | ||
| 467 | auto v2_quat = v2.quat; | ||
| 468 | |||
| 469 | if (AreQuaternionsOpposite(v0.quat, v1.quat)) | ||
| 470 | v1_quat = v1_quat * float24::FromFloat32(-1.0f); | ||
| 471 | if (AreQuaternionsOpposite(v0.quat, v2.quat)) | ||
| 472 | v2_quat = v2_quat * float24::FromFloat32(-1.0f); | ||
| 473 | |||
| 474 | auto w_inverse = Math::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w); | 458 | auto w_inverse = Math::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w); |
| 475 | 459 | ||
| 476 | auto textures = regs.texturing.GetTextures(); | 460 | auto textures = regs.texturing.GetTextures(); |
| @@ -571,11 +555,11 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve | |||
| 571 | 555 | ||
| 572 | Math::Quaternion<float> normquat{ | 556 | Math::Quaternion<float> normquat{ |
| 573 | { | 557 | { |
| 574 | GetInterpolatedAttribute(v0.quat.x, v1_quat.x, v2_quat.x).ToFloat32(), | 558 | GetInterpolatedAttribute(v0.quat.x, v1.quat.x, v2.quat.x).ToFloat32(), |
| 575 | GetInterpolatedAttribute(v0.quat.y, v1_quat.y, v2_quat.y).ToFloat32(), | 559 | GetInterpolatedAttribute(v0.quat.y, v1.quat.y, v2.quat.y).ToFloat32(), |
| 576 | GetInterpolatedAttribute(v0.quat.z, v1_quat.z, v2_quat.z).ToFloat32() | 560 | GetInterpolatedAttribute(v0.quat.z, v1.quat.z, v2.quat.z).ToFloat32() |
| 577 | }, | 561 | }, |
| 578 | GetInterpolatedAttribute(v0.quat.w, v1_quat.w, v2_quat.w).ToFloat32(), | 562 | GetInterpolatedAttribute(v0.quat.w, v1.quat.w, v2.quat.w).ToFloat32(), |
| 579 | }; | 563 | }; |
| 580 | 564 | ||
| 581 | Math::Vec3<float> fragment_position{ | 565 | Math::Vec3<float> fragment_position{ |