From 49edf14a3ea3139e3f5307007819b373425a3843 Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Wed, 23 Jun 2021 18:04:59 -0300
Subject: [PATCH] Pass all inputs when geometry shader passthrough is enabled
 (#2362)

* Pass all inputs when geometry shader passthrough is enabled

* Shader cache version bump
---
 Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs    |  2 +-
 .../CodeGen/Glsl/Declarations.cs              | 75 ++++++++++++-------
 2 files changed, 48 insertions(+), 29 deletions(-)

diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index b080a8bb4..a44081920 100644
--- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
         /// <summary>
         /// Version of the codegen (to be changed when codegen or guest format change).
         /// </summary>
-        private const ulong ShaderCodeGenVersion = 2367;
+        private const ulong ShaderCodeGenVersion = 2362;
 
         // Progress reporting helpers
         private volatile int _shaderCount;
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
index cb17f18de..2e993ef0b 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
@@ -131,7 +131,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
                     context.AppendLine();
                 }
 
-                if (info.IAttributes.Count != 0)
+                if (info.IAttributes.Count != 0 || context.Config.GpPassthrough)
                 {
                     DeclareInputAttributes(context, info);
 
@@ -371,45 +371,64 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
 
         private static void DeclareInputAttributes(CodeGenContext context, StructuredProgramInfo info)
         {
-            string suffix = context.Config.Stage == ShaderStage.Geometry ? "[]" : string.Empty;
-
-            foreach (int attr in info.IAttributes.OrderBy(x => x))
+            if (context.Config.GpPassthrough)
             {
-                string iq = string.Empty;
-
-                if (context.Config.Stage == ShaderStage.Fragment)
+                for (int attr = 0; attr < MaxAttributes; attr++)
                 {
-                    iq = context.Config.ImapTypes[attr].GetFirstUsedType() switch
-                    {
-                        PixelImap.Constant => "flat ",
-                        PixelImap.ScreenLinear => "noperspective ",
-                        _ => string.Empty
-                    };
+                    DeclareInputAttribute(context, info, attr);
                 }
 
-                string pass = context.Config.GpPassthrough ? "passthrough, " : string.Empty;
-
-                string name = $"{DefaultNames.IAttributePrefix}{attr}";
-
-                if ((context.Config.Flags & TranslationFlags.Feedback) != 0)
+                foreach (int attr in info.IAttributes.OrderBy(x => x).Where(x => x >= MaxAttributes))
                 {
-                    for (int c = 0; c < 4; c++)
-                    {
-                        char swzMask = "xyzw"[c];
-
-                        context.AppendLine($"layout ({pass}location = {attr}, component = {c}) {iq}in float {name}_{swzMask}{suffix};");
-                    }
+                    DeclareInputAttribute(context, info, attr);
                 }
-                else
+            }
+            else
+            {
+                foreach (int attr in info.IAttributes.OrderBy(x => x))
                 {
-                    context.AppendLine($"layout ({pass}location = {attr}) {iq}in vec4 {name}{suffix};");
+                    DeclareInputAttribute(context, info, attr);
                 }
             }
         }
 
+        private static void DeclareInputAttribute(CodeGenContext context, StructuredProgramInfo info, int attr)
+        {
+            string suffix = context.Config.Stage == ShaderStage.Geometry ? "[]" : string.Empty;
+            string iq = string.Empty;
+
+            if (context.Config.Stage == ShaderStage.Fragment)
+            {
+                iq = context.Config.ImapTypes[attr].GetFirstUsedType() switch
+                {
+                    PixelImap.Constant => "flat ",
+                    PixelImap.ScreenLinear => "noperspective ",
+                    _ => string.Empty
+                };
+            }
+
+            string pass = context.Config.GpPassthrough && !info.OAttributes.Contains(attr) ? "passthrough, " : string.Empty;
+
+            string name = $"{DefaultNames.IAttributePrefix}{attr}";
+
+            if ((context.Config.Flags & TranslationFlags.Feedback) != 0)
+            {
+                for (int c = 0; c < 4; c++)
+                {
+                    char swzMask = "xyzw"[c];
+
+                    context.AppendLine($"layout ({pass}location = {attr}, component = {c}) {iq}in float {name}_{swzMask}{suffix};");
+                }
+            }
+            else
+            {
+                context.AppendLine($"layout ({pass}location = {attr}) {iq}in vec4 {name}{suffix};");
+            }
+        }
+
         private static void DeclareOutputAttributes(CodeGenContext context, StructuredProgramInfo info)
         {
-            if (context.Config.Stage == ShaderStage.Fragment)
+            if (context.Config.Stage == ShaderStage.Fragment || context.Config.GpPassthrough)
             {
                 DeclareUsedOutputAttributes(context, info);
             }
@@ -423,7 +442,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
         {
             foreach (int attr in info.OAttributes.OrderBy(x => x))
             {
-                context.AppendLine($"layout (location = {attr}) out vec4 {DefaultNames.OAttributePrefix}{attr};");
+                DeclareOutputAttribute(context, attr);
             }
         }