From c53f58a4a9d0216762544637c2cebb53f7b9d3ea Mon Sep 17 00:00:00 2001 From: sunshineinabox Date: Sat, 3 Aug 2024 19:47:08 -0700 Subject: [PATCH] Resolve issue with primitive toplogy Primitive Restart Enable should depend on Extended dynamic state 2 extension not 1 Resolve Primitive restart enable Fix MoltenVK crash --- src/Ryujinx.Graphics.Vulkan/PipelineBase.cs | 17 ++++----- .../PipelineDynamicState.cs | 8 ++--- src/Ryujinx.Graphics.Vulkan/PipelineState.cs | 35 ++++++++----------- 3 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 3ccd82a10e..1592297523 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -669,9 +669,9 @@ namespace Ryujinx.Graphics.Vulkan if (_supportExtDynamic) { - if (oldTopology.ConvertToClass() != _newState.TopologyClass.ConvertToClass()) + if (oldTopology.ConvertToClass() != _newState.Topology.ConvertToClass()) { - _newState.TopologyClass = _newState.TopologyClass.ConvertToClass(); + _newState.Topology = oldTopology; } DynamicState.SetCullMode(oldCullMode); @@ -686,10 +686,9 @@ namespace Ryujinx.Graphics.Vulkan _newState.DepthTestEnable = oldDepthTestEnable; _newState.DepthWriteEnable = oldDepthWriteEnable; _newState.ViewportsCount = oldViewportsCount; + _newState.Topology = oldTopology; } - _newState.Topology = oldTopology; - DynamicState.SetViewports(ref oldViewports, oldViewportsCount); SignalStateChange(); @@ -1072,15 +1071,17 @@ namespace Ryujinx.Graphics.Vulkan { var newTopologyClass = vkTopology.ConvertToClass(); - if ((_newState.TopologyClass != newTopologyClass)) + if ((_newState.Topology.ConvertToClass() != newTopologyClass)) { - _newState.TopologyClass = newTopologyClass; + _newState.Topology = vkTopology; } DynamicState.SetPrimitiveTopology(vkTopology); } - - _newState.Topology = vkTopology; + else + { + _newState.Topology = vkTopology; + } SignalStateChange(); } diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs index 623c47fac9..5194652d68 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs @@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Vulkan private uint _patchControlPoints; - public PrimitiveTopology Topology; + private PrimitiveTopology _topology; private bool _primitiveRestartEnable; @@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.Vulkan PrimitiveRestart = 1 << 14, PrimitiveTopology = 1 << 15, DepthBiasEnable = 1 << 16, - Standard = Blend | DepthBias | Scissor | Stencil | Viewport | LineWidth, + Standard = Blend | DepthBias | Scissor | Stencil | Viewport, Extended = CullMode | FrontFace | DepthTestBool | DepthTestCompareOp | StencilTestEnableandStencilOp | PrimitiveTopology, Extended2 = RasterDiscard | PrimitiveRestart | DepthBiasEnable, } @@ -217,7 +217,7 @@ namespace Ryujinx.Graphics.Vulkan public void SetPrimitiveTopology(PrimitiveTopology primitiveTopology) { - Topology = primitiveTopology; + _topology = primitiveTopology; _dirty |= DirtyFlags.PrimitiveTopology; } @@ -460,7 +460,7 @@ namespace Ryujinx.Graphics.Vulkan private readonly void RecordPrimitiveTopology(VulkanRenderer gd, CommandBuffer commandBuffer) { - gd.ExtendedDynamicStateApi.CmdSetPrimitiveTopology(commandBuffer, Topology); + gd.ExtendedDynamicStateApi.CmdSetPrimitiveTopology(commandBuffer, _topology); } private readonly void RecordLogicOp(VulkanRenderer gd, CommandBuffer commandBuffer) diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs index 1dfca2bfff..fb8a65bc6b 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs @@ -239,12 +239,6 @@ namespace Ryujinx.Graphics.Vulkan set => Internal.Id3 = (Internal.Id3 & 0xFFFFFFFFFFFFFFBF) | ((value ? 1UL : 0UL) << 6); } - public PrimitiveTopology TopologyClass - { - readonly get => (PrimitiveTopology)((Internal.Id3 >> 7) & 0xF); - set => Internal.Id3 = (Internal.Id3 & 0xFFFFFFFFFFFFFF8F) | ((ulong)value << 7); - } - public bool HasTessellationControlShader; public NativeArray Stages; public PipelineLayout PipelineLayout; @@ -366,17 +360,11 @@ namespace Ryujinx.Graphics.Vulkan var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo { SType = StructureType.PipelineInputAssemblyStateCreateInfo, - Topology = supportsExtDynamicState ? TopologyClass : Topology, + Topology = Topology, }; PipelineTessellationStateCreateInfo tessellationState; - if (!gd.Capabilities.SupportsExtendedDynamicState2.ExtendedDynamicState2PatchControlPoints && HasTessellationControlShader) - { - tessellationState.SType = StructureType.PipelineTessellationStateCreateInfo; - tessellationState.PatchControlPoints = PatchControlPoints; - } - var rasterizationState = new PipelineRasterizationStateCreateInfo { SType = StructureType.PipelineRasterizationStateCreateInfo, @@ -390,12 +378,6 @@ namespace Ryujinx.Graphics.Vulkan rasterizationState.LineWidth = 1.0f; } - if (!supportsExtDynamicState2) - { - rasterizationState.DepthBiasEnable = DepthBiasEnable; - rasterizationState.RasterizerDiscardEnable = RasterizerDiscardEnable; - } - var viewportState = new PipelineViewportStateCreateInfo { SType = StructureType.PipelineViewportStateCreateInfo, @@ -430,8 +412,6 @@ namespace Ryujinx.Graphics.Vulkan if (!supportsExtDynamicState) { - inputAssemblyState.PrimitiveRestartEnable = PrimitiveRestartEnable; - rasterizationState.CullMode = CullMode; rasterizationState.FrontFace = FrontFace; @@ -458,6 +438,19 @@ namespace Ryujinx.Graphics.Vulkan depthStencilState.DepthCompareOp = DepthCompareOp; } + if (!supportsExtDynamicState2) + { + inputAssemblyState.PrimitiveRestartEnable = PrimitiveRestartEnable; + rasterizationState.DepthBiasEnable = DepthBiasEnable; + rasterizationState.RasterizerDiscardEnable = RasterizerDiscardEnable; + } + + if (!gd.Capabilities.SupportsExtendedDynamicState2.ExtendedDynamicState2PatchControlPoints && HasTessellationControlShader) + { + tessellationState.SType = StructureType.PipelineTessellationStateCreateInfo; + tessellationState.PatchControlPoints = PatchControlPoints; + } + uint blendEnables = 0; if (isMoltenVk && Internal.AttachmentIntegerFormatMask != 0)