فهرست منبع

VideoCore: Extract swrast-specific data from OutputVertex

Yuri Kunde Schlesner 9 سال پیش
والد
کامیت
dcdffabfe6
5فایلهای تغییر یافته به همراه64 افزوده شده و 58 حذف شده
  1. 13 11
      src/video_core/clipper.cpp
  2. 3 4
      src/video_core/rasterizer.cpp
  3. 34 6
      src/video_core/rasterizer.h
  4. 1 1
      src/video_core/shader/shader.cpp
  5. 13 36
      src/video_core/shader/shader.h

+ 13 - 11
src/video_core/clipper.cpp

@@ -18,6 +18,8 @@
 #include "video_core/rasterizer.h"
 #include "video_core/shader/shader.h"
 
+using Pica::Rasterizer::Vertex;
+
 namespace Pica {
 
 namespace Clipper {
@@ -29,20 +31,20 @@ public:
                                                  float24::FromFloat32(0), float24::FromFloat32(0)))
         : coeffs(coeffs), bias(bias) {}
 
-    bool IsInside(const OutputVertex& vertex) const {
+    bool IsInside(const Vertex& vertex) const {
         return Math::Dot(vertex.pos + bias, coeffs) <= float24::FromFloat32(0);
     }
 
-    bool IsOutSide(const OutputVertex& vertex) const {
+    bool IsOutSide(const Vertex& vertex) const {
         return !IsInside(vertex);
     }
 
-    OutputVertex GetIntersection(const OutputVertex& v0, const OutputVertex& v1) const {
+    Vertex GetIntersection(const Vertex& v0, const Vertex& v1) const {
         float24 dp = Math::Dot(v0.pos + bias, coeffs);
         float24 dp_prev = Math::Dot(v1.pos + bias, coeffs);
         float24 factor = dp_prev / (dp_prev - dp);
 
-        return OutputVertex::Lerp(factor, v0, v1);
+        return Vertex::Lerp(factor, v0, v1);
     }
 
 private:
@@ -51,7 +53,7 @@ private:
     Math::Vec4<float24> bias;
 };
 
-static void InitScreenCoordinates(OutputVertex& vtx) {
+static void InitScreenCoordinates(Vertex& vtx) {
     struct {
         float24 halfsize_x;
         float24 offset_x;
@@ -91,8 +93,8 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
     // introduces at most 1 new vertex to the polygon. Since we start with a triangle and have a
     // fixed 6 clipping planes, the maximum number of vertices of the clipped polygon is 3 + 6 = 9.
     static const size_t MAX_VERTICES = 9;
-    static_vector<OutputVertex, MAX_VERTICES> buffer_a = {v0, v1, v2};
-    static_vector<OutputVertex, MAX_VERTICES> buffer_b;
+    static_vector<Vertex, MAX_VERTICES> buffer_a = {v0, v1, v2};
+    static_vector<Vertex, MAX_VERTICES> buffer_b;
     auto* output_list = &buffer_a;
     auto* input_list = &buffer_b;
 
@@ -123,7 +125,7 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
         std::swap(input_list, output_list);
         output_list->clear();
 
-        const OutputVertex* reference_vertex = &input_list->back();
+        const Vertex* reference_vertex = &input_list->back();
 
         for (const auto& vertex : *input_list) {
             // NOTE: This algorithm changes vertex order in some cases!
@@ -148,9 +150,9 @@ void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const Outpu
     InitScreenCoordinates((*output_list)[1]);
 
     for (size_t i = 0; i < output_list->size() - 2; i++) {
-        OutputVertex& vtx0 = (*output_list)[0];
-        OutputVertex& vtx1 = (*output_list)[i + 1];
-        OutputVertex& vtx2 = (*output_list)[i + 2];
+        Vertex& vtx0 = (*output_list)[0];
+        Vertex& vtx1 = (*output_list)[i + 1];
+        Vertex& vtx2 = (*output_list)[i + 2];
 
         InitScreenCoordinates(vtx2);
 

+ 3 - 4
src/video_core/rasterizer.cpp

@@ -307,8 +307,8 @@ MICROPROFILE_DEFINE(GPU_Rasterization, "GPU", "Rasterization", MP_RGB(50, 50, 24
  * Helper function for ProcessTriangle with the "reversed" flag to allow for implementing
  * culling via recursion.
  */
-static void ProcessTriangleInternal(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1,
-                                    const Shader::OutputVertex& v2, bool reversed = false) {
+static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Vertex& v2,
+                                    bool reversed = false) {
     const auto& regs = g_state.regs;
     MICROPROFILE_SCOPE(GPU_Rasterization);
 
@@ -1276,8 +1276,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, const Shader
     }
 }
 
-void ProcessTriangle(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1,
-                     const Shader::OutputVertex& v2) {
+void ProcessTriangle(const Vertex& v0, const Vertex& v1, const Vertex& v2) {
     ProcessTriangleInternal(v0, v1, v2);
 }
 

+ 34 - 6
src/video_core/rasterizer.h

@@ -4,16 +4,44 @@
 
 #pragma once
 
-namespace Pica {
+#include "video_core/shader/shader.h"
 
-namespace Shader {
-struct OutputVertex;
-}
+namespace Pica {
 
 namespace Rasterizer {
 
-void ProcessTriangle(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1,
-                     const Shader::OutputVertex& v2);
+struct Vertex : Shader::OutputVertex {
+    Vertex(const OutputVertex& v) : OutputVertex(v) {}
+
+    // Attributes used to store intermediate results
+    // position after perspective divide
+    Math::Vec3<float24> screenpos;
+
+    // Linear interpolation
+    // factor: 0=this, 1=vtx
+    void Lerp(float24 factor, const Vertex& vtx) {
+        pos = pos * factor + vtx.pos * (float24::FromFloat32(1) - factor);
+
+        // TODO: Should perform perspective correct interpolation here...
+        tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor);
+        tc1 = tc1 * factor + vtx.tc1 * (float24::FromFloat32(1) - factor);
+        tc2 = tc2 * factor + vtx.tc2 * (float24::FromFloat32(1) - factor);
+
+        screenpos = screenpos * factor + vtx.screenpos * (float24::FromFloat32(1) - factor);
+
+        color = color * factor + vtx.color * (float24::FromFloat32(1) - factor);
+    }
+
+    // Linear interpolation
+    // factor: 0=v0, 1=v1
+    static Vertex Lerp(float24 factor, const Vertex& v0, const Vertex& v1) {
+        Vertex ret = v0;
+        ret.Lerp(factor, v1);
+        return ret;
+    }
+};
+
+void ProcessTriangle(const Vertex& v0, const Vertex& v1, const Vertex& v2);
 
 } // namespace Rasterizer
 

+ 1 - 1
src/video_core/shader/shader.cpp

@@ -26,7 +26,7 @@ OutputVertex OutputVertex::FromAttributeBuffer(const Regs& regs, AttributeBuffer
         OutputVertex ret{};
         std::array<float24, 24> vertex_slots;
     };
-    static_assert(sizeof(vertex_slots) <= sizeof(ret), "Struct and array have different sizes.");
+    static_assert(sizeof(vertex_slots) == sizeof(ret), "Struct and array have different sizes.");
 
     unsigned int num_attributes = regs.vs_output_total;
     ASSERT(num_attributes <= 7);

+ 13 - 36
src/video_core/shader/shader.h

@@ -28,9 +28,6 @@ struct AttributeBuffer {
 };
 
 struct OutputVertex {
-    OutputVertex() = default;
-
-    // VS output attributes
     Math::Vec4<float24> pos;
     Math::Vec4<float24> quat;
     Math::Vec4<float24> color;
@@ -42,42 +39,22 @@ struct OutputVertex {
     INSERT_PADDING_WORDS(1);
     Math::Vec2<float24> tc2;
 
-    // Padding for optimal alignment
-    INSERT_PADDING_WORDS(4);
-
-    // Attributes used to store intermediate results
-
-    // position after perspective divide
-    Math::Vec3<float24> screenpos;
-    INSERT_PADDING_WORDS(1);
-
-    // Linear interpolation
-    // factor: 0=this, 1=vtx
-    void Lerp(float24 factor, const OutputVertex& vtx) {
-        pos = pos * factor + vtx.pos * (float24::FromFloat32(1) - factor);
-
-        // TODO: Should perform perspective correct interpolation here...
-        tc0 = tc0 * factor + vtx.tc0 * (float24::FromFloat32(1) - factor);
-        tc1 = tc1 * factor + vtx.tc1 * (float24::FromFloat32(1) - factor);
-        tc2 = tc2 * factor + vtx.tc2 * (float24::FromFloat32(1) - factor);
-
-        screenpos = screenpos * factor + vtx.screenpos * (float24::FromFloat32(1) - factor);
-
-        color = color * factor + vtx.color * (float24::FromFloat32(1) - factor);
-    }
-
-    // Linear interpolation
-    // factor: 0=v0, 1=v1
-    static OutputVertex Lerp(float24 factor, const OutputVertex& v0, const OutputVertex& v1) {
-        OutputVertex ret = v0;
-        ret.Lerp(factor, v1);
-        return ret;
-    }
-
     static OutputVertex FromAttributeBuffer(const Regs& regs, AttributeBuffer& output);
 };
+#define ASSERT_POS(var, pos)                                                                       \
+    static_assert(offsetof(OutputVertex, var) == pos * sizeof(float24), "Semantic at wrong "       \
+                                                                        "offset.")
+ASSERT_POS(pos, Regs::VSOutputAttributes::POSITION_X);
+ASSERT_POS(quat, Regs::VSOutputAttributes::QUATERNION_X);
+ASSERT_POS(color, Regs::VSOutputAttributes::COLOR_R);
+ASSERT_POS(tc0, Regs::VSOutputAttributes::TEXCOORD0_U);
+ASSERT_POS(tc1, Regs::VSOutputAttributes::TEXCOORD1_U);
+ASSERT_POS(tc0_w, Regs::VSOutputAttributes::TEXCOORD0_W);
+ASSERT_POS(view, Regs::VSOutputAttributes::VIEW_X);
+ASSERT_POS(tc2, Regs::VSOutputAttributes::TEXCOORD2_U);
+#undef ASSERT_POS
 static_assert(std::is_pod<OutputVertex>::value, "Structure is not POD");
-static_assert(sizeof(OutputVertex) == 32 * sizeof(float), "OutputVertex has invalid size");
+static_assert(sizeof(OutputVertex) == 24 * sizeof(float), "OutputVertex has invalid size");
 
 /**
  * This structure contains the state information that needs to be unique for a shader unit. The 3DS