From 052b23c83c3a58afdd63c3d5a7655be482f1c739 Mon Sep 17 00:00:00 2001
From: Mary <mary@mary.zone>
Date: Mon, 13 Feb 2023 21:32:20 +0100
Subject: [PATCH] vulkan: Do not call vkCmdSetViewport when viewportCount is 0
 (#4406)

This fix validation error "VUID-vkCmdSetViewport-viewportCount-arraylength".
---
 Ryujinx.Graphics.Vulkan/PipelineBase.cs         |  8 +++-----
 Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs | 17 +++++++++++++----
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
index 43dccf86ef..02b1c38961 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineBase.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
@@ -650,9 +650,7 @@ namespace Ryujinx.Graphics.Vulkan
                 _newState.DepthWriteEnable = oldDepthWriteEnable;
                 _newState.Topology = oldTopology;
 
-                DynamicState.Viewports = oldViewports;
-                DynamicState.ViewportsCount = (int)oldViewportsCount;
-                DynamicState.SetViewportsDirty();
+                DynamicState.SetViewports(ref oldViewports, oldViewportsCount);
 
                 _newState.ViewportsCount = oldViewportsCount;
                 SignalStateChange();
@@ -1183,6 +1181,8 @@ namespace Ryujinx.Graphics.Vulkan
                 return Math.Clamp(value, 0f, 1f);
             }
 
+            DynamicState.ViewportsCount = (uint)count;
+
             for (int i = 0; i < count; i++)
             {
                 var viewport = viewports[i];
@@ -1196,8 +1196,6 @@ namespace Ryujinx.Graphics.Vulkan
                     Clamp(viewport.DepthFar)));
             }
 
-            DynamicState.ViewportsCount = count;
-
             float disableTransformF = disableTransform ? 1.0f : 0.0f;
             if (SupportBufferUpdater.Data.ViewportInverse.W != disableTransformF || disableTransform)
             {
diff --git a/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs b/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs
index b4d6e95c7c..42ea022a44 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs
@@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Vulkan
 
         private Array4<float> _blendConstants;
 
-        public int ViewportsCount;
+        public uint ViewportsCount;
         public Array16<Viewport> Viewports;
 
         private enum DirtyFlags
@@ -88,9 +88,15 @@ namespace Ryujinx.Graphics.Vulkan
             _dirty |= DirtyFlags.Viewport;
         }
 
-        public void SetViewportsDirty()
+        public void SetViewports(ref Array16<Viewport> viewports, uint viewportsCount)
         {
-            _dirty |= DirtyFlags.Viewport;
+            Viewports = viewports;
+            ViewportsCount = viewportsCount;
+
+            if (ViewportsCount != 0)
+            {
+                _dirty |= DirtyFlags.Viewport;
+            }
         }
 
         public void ForceAllDirty()
@@ -155,7 +161,10 @@ namespace Ryujinx.Graphics.Vulkan
 
         private void RecordViewport(Vk api, CommandBuffer commandBuffer)
         {
-            api.CmdSetViewport(commandBuffer, 0, (uint)ViewportsCount, Viewports.AsSpan());
+            if (ViewportsCount != 0)
+            {
+                api.CmdSetViewport(commandBuffer, 0, ViewportsCount, Viewports.AsSpan());
+            }
         }
     }
 }