From c6d82209abeacd2336cde99e5a02b4596e70da83 Mon Sep 17 00:00:00 2001
From: riperiperi <rhy3756547@hotmail.com>
Date: Fri, 9 Sep 2022 00:30:19 +0100
Subject: Restride vertex buffer when stride causes attributes to misalign in
 Vulkan. (#3679)

* Vertex Buffer Alignment part 1

* Update CacheByRange

* Add Stride Change compute shader, fix storage buffers in helpers

* An AMD exclusive

* Reword

* Change rules - stride conversion when attrs misalign

* Fix stupid mistake

* Fix background pipeline compile

* Improve a few things.

* Fix some feedback

* Address Feedback

(the shader binary didn't change when i changed the source to use the subgroup size)

* Fix bug where rewritten buffer would be disposed instantly.
---
 Ryujinx.Graphics.Vulkan/VulkanRenderer.cs | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

(limited to 'Ryujinx.Graphics.Vulkan/VulkanRenderer.cs')

diff --git a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index b2f69636..bacb74cc 100644
--- a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -188,11 +188,22 @@ namespace Ryujinx.Graphics.Vulkan
                 SType = StructureType.PhysicalDeviceRobustness2FeaturesExt
             };
 
+            PhysicalDeviceShaderFloat16Int8FeaturesKHR featuresShaderInt8 = new PhysicalDeviceShaderFloat16Int8FeaturesKHR()
+            {
+                SType = StructureType.PhysicalDeviceShaderFloat16Int8Features
+            };
+
             if (supportedExtensions.Contains("VK_EXT_robustness2"))
             {
                 features2.PNext = &featuresRobustness2;
             }
 
+            if (supportedExtensions.Contains("VK_KHR_shader_float16_int8"))
+            {
+                featuresShaderInt8.PNext = features2.PNext;
+                features2.PNext = &featuresShaderInt8;
+            }
+
             Api.GetPhysicalDeviceFeatures2(_physicalDevice, &features2);
 
             Capabilities = new HardwareCapabilities(
@@ -202,6 +213,7 @@ namespace Ryujinx.Graphics.Vulkan
                 supportedExtensions.Contains("VK_EXT_fragment_shader_interlock"),
                 supportedExtensions.Contains("VK_NV_geometry_shader_passthrough"),
                 supportedExtensions.Contains("VK_EXT_subgroup_size_control"),
+                featuresShaderInt8.ShaderInt8,
                 supportedExtensions.Contains(ExtConditionalRendering.ExtensionName),
                 supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName),
                 features2.Features.MultiViewport,
@@ -506,6 +518,24 @@ namespace Ryujinx.Graphics.Vulkan
             PrintGpuInformation();
         }
 
+        public bool NeedsVertexBufferAlignment(int attrScalarAlignment, out int alignment)
+        {
+            if (Vendor != Vendor.Nvidia)
+            {
+                // Vulkan requires that vertex attributes are globally aligned by their component size,
+                // so buffer strides that don't divide by the largest scalar element are invalid.
+                // Guest applications do this, NVIDIA GPUs are OK with it, others are not.
+
+                alignment = attrScalarAlignment;
+
+                return true;
+            }
+
+            alignment = 1;
+
+            return false;
+        }
+
         public void PreFrame()
         {
             _syncManager.Cleanup();
-- 
cgit v1.2.3-70-g09d2