From 549fdd07367c03458f7d6aab26819cb0f55e54cd Mon Sep 17 00:00:00 2001
From: GPUCode <47210458+GPUCode@users.noreply.github.com>
Date: Wed, 24 Jan 2024 04:47:08 +0200
Subject: [PATCH] pica_core: Propogate vertex uniforms to geometry setup when
 not in exclusive mode (#7367)

---
 src/video_core/pica/pica_core.cpp    | 14 +++++++++++++-
 src/video_core/pica/shader_setup.cpp | 12 +++++++-----
 src/video_core/pica/shader_setup.h   |  3 ++-
 3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/src/video_core/pica/pica_core.cpp b/src/video_core/pica/pica_core.cpp
index 53e273833..1c9304090 100644
--- a/src/video_core/pica/pica_core.cpp
+++ b/src/video_core/pica/pica_core.cpp
@@ -256,6 +256,10 @@ void PicaCore::WriteInternalReg(u32 id, u32 value, u32 mask) {
 
     case PICA_REG_INDEX(vs.bool_uniforms):
         vs_setup.WriteUniformBoolReg(regs.internal.vs.bool_uniforms.Value());
+        if (!regs.internal.pipeline.gs_unit_exclusive_configuration &&
+            regs.internal.pipeline.use_gs == PipelineRegs::UseGS::No) {
+            gs_setup.WriteUniformBoolReg(regs.internal.vs.bool_uniforms.Value());
+        }
         break;
 
     case PICA_REG_INDEX(vs.int_uniforms[0]):
@@ -264,6 +268,10 @@ void PicaCore::WriteInternalReg(u32 id, u32 value, u32 mask) {
     case PICA_REG_INDEX(vs.int_uniforms[3]): {
         const u32 index = (id - PICA_REG_INDEX(vs.int_uniforms[0]));
         vs_setup.WriteUniformIntReg(index, regs.internal.vs.GetIntUniform(index));
+        if (!regs.internal.pipeline.gs_unit_exclusive_configuration &&
+            regs.internal.pipeline.use_gs == PipelineRegs::UseGS::No) {
+            gs_setup.WriteUniformIntReg(index, regs.internal.vs.GetIntUniform(index));
+        }
         break;
     }
 
@@ -275,7 +283,11 @@ void PicaCore::WriteInternalReg(u32 id, u32 value, u32 mask) {
     case PICA_REG_INDEX(vs.uniform_setup.set_value[5]):
     case PICA_REG_INDEX(vs.uniform_setup.set_value[6]):
     case PICA_REG_INDEX(vs.uniform_setup.set_value[7]): {
-        vs_setup.WriteUniformFloatReg(regs.internal.vs, value);
+        const auto index = vs_setup.WriteUniformFloatReg(regs.internal.vs, value);
+        if (!regs.internal.pipeline.gs_unit_exclusive_configuration &&
+            regs.internal.pipeline.use_gs == PipelineRegs::UseGS::No && index) {
+            gs_setup.uniforms.f[index.value()] = vs_setup.uniforms.f[index.value()];
+        }
         break;
     }
 
diff --git a/src/video_core/pica/shader_setup.cpp b/src/video_core/pica/shader_setup.cpp
index 2b4b62002..9eca8f372 100644
--- a/src/video_core/pica/shader_setup.cpp
+++ b/src/video_core/pica/shader_setup.cpp
@@ -27,21 +27,23 @@ void ShaderSetup::WriteUniformIntReg(u32 index, const Common::Vec4<u8> values) {
     uniforms.i[index] = values;
 }
 
-void ShaderSetup::WriteUniformFloatReg(ShaderRegs& config, u32 value) {
+std::optional<u32> ShaderSetup::WriteUniformFloatReg(ShaderRegs& config, u32 value) {
     auto& uniform_setup = config.uniform_setup;
     const bool is_float32 = uniform_setup.IsFloat32();
     if (!uniform_queue.Push(value, is_float32)) {
-        return;
+        return std::nullopt;
     }
 
     const auto uniform = uniform_queue.Get(is_float32);
     if (uniform_setup.index >= uniforms.f.size()) {
         LOG_ERROR(HW_GPU, "Invalid float uniform index {}", uniform_setup.index.Value());
-        return;
+        return std::nullopt;
     }
 
-    uniforms.f[uniform_setup.index] = uniform;
-    uniform_setup.index.Assign(uniform_setup.index + 1);
+    const u32 index = uniform_setup.index.Value();
+    uniforms.f[index] = uniform;
+    uniform_setup.index.Assign(index + 1);
+    return index;
 }
 
 u64 ShaderSetup::GetProgramCodeHash() {
diff --git a/src/video_core/pica/shader_setup.h b/src/video_core/pica/shader_setup.h
index 1a240000a..7011559c4 100644
--- a/src/video_core/pica/shader_setup.h
+++ b/src/video_core/pica/shader_setup.h
@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <optional>
 #include "common/vector_math.h"
 #include "video_core/pica/packed_attribute.h"
 #include "video_core/pica_types.h"
@@ -58,7 +59,7 @@ public:
 
     void WriteUniformIntReg(u32 index, const Common::Vec4<u8> values);
 
-    void WriteUniformFloatReg(ShaderRegs& config, u32 value);
+    std::optional<u32> WriteUniformFloatReg(ShaderRegs& config, u32 value);
 
     u64 GetProgramCodeHash();