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.
This commit is contained in:
riperiperi 2022-09-09 00:30:19 +01:00 committed by GitHub
parent ee1825219b
commit c6d82209ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 1069 additions and 120 deletions

View file

@ -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();