From 597388ecda35b0feaa3b678b7216689a5d84bbac Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 28 May 2023 19:17:07 -0300 Subject: Fix incorrect vertex attribute format change (#5112) * Fix incorrect vertex attribute format change * Only change vertex format if the host supports the new format --- src/Ryujinx.Graphics.Vulkan/PipelineState.cs | 50 ++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 14 deletions(-) (limited to 'src/Ryujinx.Graphics.Vulkan/PipelineState.cs') diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs index aff3f13f..1a396b5c 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs @@ -414,7 +414,7 @@ namespace Ryujinx.Graphics.Vulkan if (isMoltenVk) { - UpdateVertexAttributeDescriptions(); + UpdateVertexAttributeDescriptions(gd); } fixed (VertexInputAttributeDescription* pVertexAttributeDescriptions = &Internal.VertexAttributeDescriptions[0]) @@ -641,7 +641,7 @@ namespace Ryujinx.Graphics.Vulkan } } - private void UpdateVertexAttributeDescriptions() + private void UpdateVertexAttributeDescriptions(VulkanRenderer gd) { // Vertex attributes exceeding the stride are invalid. // In metal, they cause glitches with the vertex shader fetching incorrect values. @@ -651,30 +651,52 @@ namespace Ryujinx.Graphics.Vulkan for (int index = 0; index < VertexAttributeDescriptionsCount; index++) { var attribute = Internal.VertexAttributeDescriptions[index]; - ref var vb = ref Internal.VertexBindingDescriptions[(int)attribute.Binding]; + int vbIndex = GetVertexBufferIndex(attribute.Binding); - Format format = attribute.Format; - - while (vb.Stride != 0 && attribute.Offset + FormatTable.GetAttributeFormatSize(format) > vb.Stride) + if (vbIndex >= 0) { - Format newFormat = FormatTable.DropLastComponent(format); + ref var vb = ref Internal.VertexBindingDescriptions[vbIndex]; + + Format format = attribute.Format; - if (newFormat == format) + while (vb.Stride != 0 && attribute.Offset + FormatTable.GetAttributeFormatSize(format) > vb.Stride) { - // That case means we failed to find a format that fits within the stride, - // so just restore the original format and give up. - format = attribute.Format; - break; + Format newFormat = FormatTable.DropLastComponent(format); + + if (newFormat == format) + { + // That case means we failed to find a format that fits within the stride, + // so just restore the original format and give up. + format = attribute.Format; + break; + } + + format = newFormat; } - format = newFormat; + if (attribute.Format != format && gd.FormatCapabilities.BufferFormatSupports(FormatFeatureFlags.VertexBufferBit, format)) + { + attribute.Format = format; + } } - attribute.Format = format; _vertexAttributeDescriptions2[index] = attribute; } } + private int GetVertexBufferIndex(uint binding) + { + for (int index = 0; index < VertexBindingDescriptionsCount; index++) + { + if (Internal.VertexBindingDescriptions[index].Binding == binding) + { + return index; + } + } + + return -1; + } + public void Dispose() { Stages.Dispose(); -- cgit v1.2.3