From 9ec2303ad6a399cea9e66fa522f65671046f1879 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Thu, 20 May 2021 21:18:39 -0300
Subject: [PATCH] glasm: Add tessellation shader declarations

---
 .../backend/glasm/emit_glasm.cpp              | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
index b6b8d504e4..476cdda544 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
@@ -347,6 +347,30 @@ std::string_view OutputPrimitive(OutputTopology topology) {
     }
     throw InvalidArgument("Invalid output topology {}", topology);
 }
+
+std::string_view GetTessMode(TessPrimitive primitive) {
+    switch (primitive) {
+    case TessPrimitive::Triangles:
+        return "TRIANGLES";
+    case TessPrimitive::Quads:
+        return "QUADS";
+    case TessPrimitive::Isolines:
+        return "ISOLINES";
+    }
+    throw InvalidArgument("Invalid tessellation primitive {}", primitive);
+}
+
+std::string_view GetTessSpacing(TessSpacing spacing) {
+    switch (spacing) {
+    case TessSpacing::Equal:
+        return "EQUAL";
+    case TessSpacing::FractionalOdd:
+        return "FRACTIONAL_ODD";
+    case TessSpacing::FractionalEven:
+        return "FRACTIONAL_EVEN";
+    }
+    throw InvalidArgument("Invalid tessellation spacing {}", spacing);
+}
 } // Anonymous namespace
 
 std::string EmitGLASM(const Profile& profile, IR::Program& program, Bindings& bindings) {
@@ -356,6 +380,17 @@ std::string EmitGLASM(const Profile& profile, IR::Program& program, Bindings& bi
     std::string header{StageHeader(program.stage)};
     SetupOptions(program, profile, header);
     switch (program.stage) {
+    case Stage::TessellationControl:
+        header += fmt::format("VERTICES_OUT {};", program.invocations);
+        break;
+    case Stage::TessellationEval:
+        header +=
+            fmt::format("TESS_MODE {};"
+                        "TESS_SPACING {};"
+                        "TESS_VERTEX_ORDER {};",
+                        GetTessMode(profile.tess_primitive), GetTessSpacing(profile.tess_spacing),
+                        profile.tess_clockwise ? "CW" : "CCW");
+        break;
     case Stage::Geometry:
         header += fmt::format("PRIMITIVE_IN {};"
                               "PRIMITIVE_OUT {};"