diff options
| author | 2016-12-18 23:43:37 -0800 | |
|---|---|---|
| committer | 2017-01-29 21:31:38 -0800 | |
| commit | dcdffabfe69d0cecd2d8c0c1f217b884b20af643 (patch) | |
| tree | 4d2214f4a878ac16e1df941fb5c763b9869ba6cc /src | |
| parent | VideoCore/Shader: Clean up OutputVertex::FromAttributeBuffer (diff) | |
| download | yuzu-dcdffabfe69d0cecd2d8c0c1f217b884b20af643.tar.gz yuzu-dcdffabfe69d0cecd2d8c0c1f217b884b20af643.tar.xz yuzu-dcdffabfe69d0cecd2d8c0c1f217b884b20af643.zip | |
VideoCore: Extract swrast-specific data from OutputVertex
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/clipper.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/rasterizer.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/rasterizer.h | 40 | ||||
| -rw-r--r-- | src/video_core/shader/shader.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/shader/shader.h | 49 |
5 files changed, 64 insertions, 58 deletions
diff --git a/src/video_core/clipper.cpp b/src/video_core/clipper.cpp index 05b5cea73..0774ffc53 100644 --- a/src/video_core/clipper.cpp +++ b/src/video_core/clipper.cpp | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | #include "video_core/rasterizer.h" | 18 | #include "video_core/rasterizer.h" |
| 19 | #include "video_core/shader/shader.h" | 19 | #include "video_core/shader/shader.h" |
| 20 | 20 | ||
| 21 | using Pica::Rasterizer::Vertex; | ||
| 22 | |||
| 21 | namespace Pica { | 23 | namespace Pica { |
| 22 | 24 | ||
| 23 | namespace Clipper { | 25 | namespace Clipper { |
| @@ -29,20 +31,20 @@ public: | |||
| 29 | float24::FromFloat32(0), float24::FromFloat32(0))) | 31 | float24::FromFloat32(0), float24::FromFloat32(0))) |
| 30 | : coeffs(coeffs), bias(bias) {} | 32 | : coeffs(coeffs), bias(bias) {} |
| 31 | 33 | ||
| 32 | bool IsInside(const OutputVertex& vertex) const { | 34 | bool IsInside(const Vertex& vertex) const { |
| 33 | return Math::Dot(vertex.pos + bias, coeffs) <= float24::FromFloat32(0); | 35 | return Math::Dot(vertex.pos + bias, coeffs) <= float24::FromFloat32(0); |
| 34 | } | 36 | } |
| 35 | 37 | ||
| 36 | bool IsOutSide(const OutputVertex& vertex) const { | 38 | bool IsOutSide(const Vertex& vertex) const { |
| 37 | return !IsInside(vertex); | 39 | return !IsInside(vertex); |
| 38 | } | 40 | } |
| 39 | 41 | ||
| 40 | OutputVertex GetIntersection(const OutputVertex& v0, const OutputVertex& v1) const { | 42 | Vertex GetIntersection(const Vertex& v0, const Vertex& v1) const { |
| 41 | float24 dp = Math::Dot(v0.pos + bias, coeffs); | 43 | float24 dp = Math::Dot(v0.pos + bias, coeffs); |
| 42 | float24 dp_prev = Math::Dot(v1.pos + bias, coeffs); | 44 | float24 dp_prev = Math::Dot(v1.pos + bias, coeffs); |
| 43 | float24 factor = dp_prev / (dp_prev - dp); | 45 | float24 factor = dp_prev / (dp_prev - dp); |
| 44 | 46 | ||
| 45 | return OutputVertex::Lerp(factor, v0, v1); | 47 | return Vertex::Lerp(factor, v0, v1); |
| 46 | } | 48 | } |
| 47 | 49 | ||
| 48 | private: | 50 | private: |
| @@ -51,7 +53,7 @@ private: | |||
| 51 | Math::Vec4<float24> bias; | 53 | Math::Vec4<float24> bias; |
| 52 | }; | 54 | }; |
| 53 | 55 | ||
| 54 | static void InitScreenCoordinates(OutputVertex& vtx) { | 56 | static void InitScreenCoordinates(Vertex& vtx) { |
| 55 | struct { | 57 | struct { |
| 56 | float24 halfsize_x; | 58 | float24 halfsize_x; |
| 57 | float24 offset_x; | 59 | float24 offset_x; |
| @@ -91,8 +93,8 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu | |||
| 91 | // introduces at most 1 new vertex to the polygon. Since we start with a triangle and have a | 93 | // introduces at most 1 new vertex to the polygon. Since we start with a triangle and have a |
| 92 | // fixed 6 clipping planes, the maximum number of vertices of the clipped polygon is 3 + 6 = 9. | 94 | // fixed 6 clipping planes, the maximum number of vertices of the clipped polygon is 3 + 6 = 9. |
| 93 | static const size_t MAX_VERTICES = 9; | 95 | static const size_t MAX_VERTICES = 9; |
| 94 | static_vector<OutputVertex, MAX_VERTICES> buffer_a = {v0, v1, v2}; | 96 | static_vector<Vertex, MAX_VERTICES> buffer_a = {v0, v1, v2}; |
| 95 | static_vector<OutputVertex, MAX_VERTICES> buffer_b; | 97 | static_vector<Vertex, MAX_VERTICES> buffer_b; |
| 96 | auto* output_list = &buffer_a; | 98 | auto* output_list = &buffer_a; |
| 97 | auto* input_list = &buffer_b; | 99 | auto* input_list = &buffer_b; |
| 98 | 100 | ||
| @@ -123,7 +125,7 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu | |||
| 123 | std::swap(input_list, output_list); | 125 | std::swap(input_list, output_list); |
| 124 | output_list->clear(); | 126 | output_list->clear(); |
| 125 | 127 | ||
| 126 | const OutputVertex* reference_vertex = &input_list->back(); | 128 | const Vertex* reference_vertex = &input_list->back(); |
| 127 | 129 | ||
| 128 | for (const auto& vertex : *input_list) { | 130 | for (const auto& vertex : *input_list) { |
| 129 | // NOTE: This algorithm changes vertex order in some cases! | 131 | // NOTE: This algorithm changes vertex order in some cases! |
| @@ -148,9 +150,9 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu | |||
| 148 | InitScreenCoordinates((*output_list)[1]); | 150 | InitScreenCoordinates((*output_list)[1]); |
| 149 | 151 | ||
| 150 | for (size_t i = 0; i < output_list->size() - 2; i++) { | 152 | for (size_t i = 0; i < output_list->size() - 2; i++) { |
| 151 | OutputVertex& vtx0 = (*output_list)[0]; | 153 | Vertex& vtx0 = (*output_list)[0]; |
| 152 | OutputVertex& vtx1 = (*output_list)[i + 1]; | 154 | Vertex& vtx1 = (*output_list)[i + 1]; |
| 153 | OutputVertex& vtx2 = (*output_list)[i + 2]; | 155 | Vertex& vtx2 = (*output_list)[i + 2]; |
| 154 | 156 | ||
| 155 | InitScreenCoordinates(vtx2); | 157 | InitScreenCoordinates(vtx2); |
| 156 | 158 | ||
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index b9f5d4533..0674eb85e 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp | |||
| @@ -307,8 +307,8 @@ MICROPROFILE_DEFINE(GPU_Rasterization, "GPU", "Rasterization", MP_RGB(50, 50, 24 | |||
| 307 | * Helper function for ProcessTriangle with the "reversed" flag to allow for implementing | 307 | * Helper function for ProcessTriangle with the "reversed" flag to allow for implementing |
| 308 | * culling via recursion. | 308 | * culling via recursion. |
| 309 | */ | 309 | */ |
| 310 | static void ProcessTriangleInternal(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, | 310 | static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Vertex& v2, |
| 311 | const Shader::OutputVertex& v2, bool reversed = false) { | 311 | bool reversed = false) { |
| 312 | const auto& regs = g_state.regs; | 312 | const auto& regs = g_state.regs; |
| 313 | MICROPROFILE_SCOPE(GPU_Rasterization); | 313 | MICROPROFILE_SCOPE(GPU_Rasterization); |
| 314 | 314 | ||
| @@ -1276,8 +1276,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, const Shader | |||
| 1276 | } | 1276 | } |
| 1277 | } | 1277 | } |
| 1278 | 1278 | ||
| 1279 | void ProcessTriangle(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, | 1279 | void ProcessTriangle(const Vertex& v0, const Vertex& v1, const Vertex& v2) { |
| 1280 | const Shader::OutputVertex& v2) { | ||
| 1281 | ProcessTriangleInternal(v0, v1, v2); | 1280 | ProcessTriangleInternal(v0, v1, v2); |
| 1282 | } | 1281 | } |
| 1283 | 1282 | ||
diff --git a/src/video_core/rasterizer.h b/src/video_core/rasterizer.h index 6cbda3067..3a72ac343 100644 --- a/src/video_core/rasterizer.h +++ b/src/video_core/rasterizer.h | |||
| @@ -4,16 +4,44 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | namespace Pica { | 7 | #include "video_core/shader/shader.h" |
| 8 | 8 | ||
| 9 | namespace Shader { | 9 | namespace Pica { |
| 10 | struct OutputVertex; | ||
| 11 | } | ||
| 12 | 10 | ||
| 13 | namespace Rasterizer { | 11 | namespace Rasterizer { |
| 14 | 12 | ||
| 15 | void ProcessTriangle(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, | 13 | struct Vertex : Shader::OutputVertex { |
| 16 | const Shader::OutputVertex& v2); | 14 | Vertex(const OutputVertex& v) : OutputVertex(v) {} |
| 15 | |||
| 16 | // Attributes used to store intermediate results | ||
| 17 | // position after perspective divide | ||
| 18 | Math::Vec3<float24> screenpos; | ||
| 19 | |||
| 20 | // Linear interpolation | ||
| 21 | // factor: 0=this, 1=vtx | ||
| 22 | void Lerp(float24 factor, const Vertex& vtx) { | ||
| 23 | pos = pos * factor + vtx.pos * (float24::FromFloat32(1) - factor); | ||
| 24 | |||
| 25 | // TODO: Should perform perspective correct interpolation here... | ||
| 26 | tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor); | ||
| 27 | tc1 = tc1 * factor + vtx.tc1 * (float24::FromFloat32(1) - factor); | ||
| 28 | tc2 = tc2 * factor + vtx.tc2 * (float24::FromFloat32(1) - factor); | ||
| 29 | |||
| 30 | screenpos = screenpos * factor + vtx.screenpos * (float24::FromFloat32(1) - factor); | ||
| 31 | |||
| 32 | color = color * factor + vtx.color * (float24::FromFloat32(1) - factor); | ||
| 33 | } | ||
| 34 | |||
| 35 | // Linear interpolation | ||
| 36 | // factor: 0=v0, 1=v1 | ||
| 37 | static Vertex Lerp(float24 factor, const Vertex& v0, const Vertex& v1) { | ||
| 38 | Vertex ret = v0; | ||
| 39 | ret.Lerp(factor, v1); | ||
| 40 | return ret; | ||
| 41 | } | ||
| 42 | }; | ||
| 43 | |||
| 44 | void ProcessTriangle(const Vertex& v0, const Vertex& v1, const Vertex& v2); | ||
| 17 | 45 | ||
| 18 | } // namespace Rasterizer | 46 | } // namespace Rasterizer |
| 19 | 47 | ||
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp index 2c6e45ac4..f5f7ea61d 100644 --- a/src/video_core/shader/shader.cpp +++ b/src/video_core/shader/shader.cpp | |||
| @@ -26,7 +26,7 @@ OutputVertex OutputVertex::FromAttributeBuffer(const Regs& regs, AttributeBuffer | |||
| 26 | OutputVertex ret{}; | 26 | OutputVertex ret{}; |
| 27 | std::array<float24, 24> vertex_slots; | 27 | std::array<float24, 24> vertex_slots; |
| 28 | }; | 28 | }; |
| 29 | static_assert(sizeof(vertex_slots) <= sizeof(ret), "Struct and array have different sizes."); | 29 | static_assert(sizeof(vertex_slots) == sizeof(ret), "Struct and array have different sizes."); |
| 30 | 30 | ||
| 31 | unsigned int num_attributes = regs.vs_output_total; | 31 | unsigned int num_attributes = regs.vs_output_total; |
| 32 | ASSERT(num_attributes <= 7); | 32 | ASSERT(num_attributes <= 7); |
diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index 00bd723cf..b188d3edf 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h | |||
| @@ -28,9 +28,6 @@ struct AttributeBuffer { | |||
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | struct OutputVertex { | 30 | struct OutputVertex { |
| 31 | OutputVertex() = default; | ||
| 32 | |||
| 33 | // VS output attributes | ||
| 34 | Math::Vec4<float24> pos; | 31 | Math::Vec4<float24> pos; |
| 35 | Math::Vec4<float24> quat; | 32 | Math::Vec4<float24> quat; |
| 36 | Math::Vec4<float24> color; | 33 | Math::Vec4<float24> color; |
| @@ -42,42 +39,22 @@ struct OutputVertex { | |||
| 42 | INSERT_PADDING_WORDS(1); | 39 | INSERT_PADDING_WORDS(1); |
| 43 | Math::Vec2<float24> tc2; | 40 | Math::Vec2<float24> tc2; |
| 44 | 41 | ||
| 45 | // Padding for optimal alignment | ||
| 46 | INSERT_PADDING_WORDS(4); | ||
| 47 | |||
| 48 | // Attributes used to store intermediate results | ||
| 49 | |||
| 50 | // position after perspective divide | ||
| 51 | Math::Vec3<float24> screenpos; | ||
| 52 | INSERT_PADDING_WORDS(1); | ||
| 53 | |||
| 54 | // Linear interpolation | ||
| 55 | // factor: 0=this, 1=vtx | ||
| 56 | void Lerp(float24 factor, const OutputVertex& vtx) { | ||
| 57 | pos = pos * factor + vtx.pos * (float24::FromFloat32(1) - factor); | ||
| 58 | |||
| 59 | // TODO: Should perform perspective correct interpolation here... | ||
| 60 | tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor); | ||
| 61 | tc1 = tc1 * factor + vtx.tc1 * (float24::FromFloat32(1) - factor); | ||
| 62 | tc2 = tc2 * factor + vtx.tc2 * (float24::FromFloat32(1) - factor); | ||
| 63 | |||
| 64 | screenpos = screenpos * factor + vtx.screenpos * (float24::FromFloat32(1) - factor); | ||
| 65 | |||
| 66 | color = color * factor + vtx.color * (float24::FromFloat32(1) - factor); | ||
| 67 | } | ||
| 68 | |||
| 69 | // Linear interpolation | ||
| 70 | // factor: 0=v0, 1=v1 | ||
| 71 | static OutputVertex Lerp(float24 factor, const OutputVertex& v0, const OutputVertex& v1) { | ||
| 72 | OutputVertex ret = v0; | ||
| 73 | ret.Lerp(factor, v1); | ||
| 74 | return ret; | ||
| 75 | } | ||
| 76 | |||
| 77 | static OutputVertex FromAttributeBuffer(const Regs& regs, AttributeBuffer& output); | 42 | static OutputVertex FromAttributeBuffer(const Regs& regs, AttributeBuffer& output); |
| 78 | }; | 43 | }; |
| 44 | #define ASSERT_POS(var, pos) \ | ||
| 45 | static_assert(offsetof(OutputVertex, var) == pos * sizeof(float24), "Semantic at wrong " \ | ||
| 46 | "offset.") | ||
| 47 | ASSERT_POS(pos, Regs::VSOutputAttributes::POSITION_X); | ||
| 48 | ASSERT_POS(quat, Regs::VSOutputAttributes::QUATERNION_X); | ||
| 49 | ASSERT_POS(color, Regs::VSOutputAttributes::COLOR_R); | ||
| 50 | ASSERT_POS(tc0, Regs::VSOutputAttributes::TEXCOORD0_U); | ||
| 51 | ASSERT_POS(tc1, Regs::VSOutputAttributes::TEXCOORD1_U); | ||
| 52 | ASSERT_POS(tc0_w, Regs::VSOutputAttributes::TEXCOORD0_W); | ||
| 53 | ASSERT_POS(view, Regs::VSOutputAttributes::VIEW_X); | ||
| 54 | ASSERT_POS(tc2, Regs::VSOutputAttributes::TEXCOORD2_U); | ||
| 55 | #undef ASSERT_POS | ||
| 79 | static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD"); | 56 | static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD"); |
| 80 | static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size"); | 57 | static_assert(sizeof(OutputVertex) == 24 * sizeof(float), "OutputVertex has invalid size"); |
| 81 | 58 | ||
| 82 | /** | 59 | /** |
| 83 | * This structure contains the state information that needs to be unique for a shader unit. The 3DS | 60 | * This structure contains the state information that needs to be unique for a shader unit. The 3DS |