summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2016-12-18 23:43:37 -0800
committerGravatar Yuri Kunde Schlesner2017-01-29 21:31:38 -0800
commitdcdffabfe69d0cecd2d8c0c1f217b884b20af643 (patch)
tree4d2214f4a878ac16e1df941fb5c763b9869ba6cc /src
parentVideoCore/Shader: Clean up OutputVertex::FromAttributeBuffer (diff)
downloadyuzu-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.cpp24
-rw-r--r--src/video_core/rasterizer.cpp7
-rw-r--r--src/video_core/rasterizer.h40
-rw-r--r--src/video_core/shader/shader.cpp2
-rw-r--r--src/video_core/shader/shader.h49
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
21using Pica::Rasterizer::Vertex;
22
21namespace Pica { 23namespace Pica {
22 24
23namespace Clipper { 25namespace 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
48private: 50private:
@@ -51,7 +53,7 @@ private:
51 Math::Vec4<float24> bias; 53 Math::Vec4<float24> bias;
52}; 54};
53 55
54static void InitScreenCoordinates(OutputVertex& vtx) { 56static 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 */
310static void ProcessTriangleInternal(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, 310static 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
1279void ProcessTriangle(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, 1279void 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
7namespace Pica { 7#include "video_core/shader/shader.h"
8 8
9namespace Shader { 9namespace Pica {
10struct OutputVertex;
11}
12 10
13namespace Rasterizer { 11namespace Rasterizer {
14 12
15void ProcessTriangle(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, 13struct 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
44void 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
30struct OutputVertex { 30struct 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.")
47ASSERT_POS(pos, Regs::VSOutputAttributes::POSITION_X);
48ASSERT_POS(quat, Regs::VSOutputAttributes::QUATERNION_X);
49ASSERT_POS(color, Regs::VSOutputAttributes::COLOR_R);
50ASSERT_POS(tc0, Regs::VSOutputAttributes::TEXCOORD0_U);
51ASSERT_POS(tc1, Regs::VSOutputAttributes::TEXCOORD1_U);
52ASSERT_POS(tc0_w, Regs::VSOutputAttributes::TEXCOORD0_W);
53ASSERT_POS(view, Regs::VSOutputAttributes::VIEW_X);
54ASSERT_POS(tc2, Regs::VSOutputAttributes::TEXCOORD2_U);
55#undef ASSERT_POS
79static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD"); 56static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD");
80static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size"); 57static_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