diff options
author | gdkchan <gab.dark.100@gmail.com> | 2023-05-28 19:17:07 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-29 00:17:07 +0200 |
commit | 597388ecda35b0feaa3b678b7216689a5d84bbac (patch) | |
tree | dbe27966650ca1e323aeacf71be84fe33c7648e8 /src | |
parent | 1cf6d7b7bbcb4f10025e8230339873a15dea2752 (diff) |
Fix incorrect vertex attribute format change (#5112)1.1.838
* Fix incorrect vertex attribute format change
* Only change vertex format if the host supports the new format
Diffstat (limited to 'src')
-rw-r--r-- | src/Ryujinx.Graphics.Vulkan/FormatCapabilities.cs | 7 | ||||
-rw-r--r-- | src/Ryujinx.Graphics.Vulkan/PipelineBase.cs | 1 | ||||
-rw-r--r-- | src/Ryujinx.Graphics.Vulkan/PipelineState.cs | 50 |
3 files changed, 43 insertions, 15 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/FormatCapabilities.cs b/src/Ryujinx.Graphics.Vulkan/FormatCapabilities.cs index 7019dfd9..a2ebc518 100644 --- a/src/Ryujinx.Graphics.Vulkan/FormatCapabilities.cs +++ b/src/Ryujinx.Graphics.Vulkan/FormatCapabilities.cs @@ -65,6 +65,13 @@ namespace Ryujinx.Graphics.Vulkan return (formatFeatureFlags & flags) == flags; } + public bool BufferFormatSupports(FormatFeatureFlags flags, VkFormat format) + { + _api.GetPhysicalDeviceFormatProperties(_physicalDevice, format, out var fp); + + return (fp.BufferFeatures & flags) == flags; + } + public bool OptimalFormatSupports(FormatFeatureFlags flags, GAL.Format format) { var formatFeatureFlags = _optimalTable[(int)format]; diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index b4eccfbb..c254d378 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -551,7 +551,6 @@ namespace Ryujinx.Graphics.Vulkan (uint)maxDrawCount, (uint)stride); } - } else { 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(); |