diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 7553801881..6bc15743cb 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -639,7 +639,7 @@ namespace Ryujinx.Graphics.Vulkan var oldStencilTestEnable = _supportExtDynamic ? DynamicState.StencilTestEnable : _newState.StencilTestEnable; var oldDepthTestEnable = _supportExtDynamic ? DynamicState.DepthTestEnable : _newState.DepthTestEnable; var oldDepthWriteEnable = _supportExtDynamic ? DynamicState.DepthWriteEnable : _newState.DepthWriteEnable; - var oldTopology = _newState.Topology; + var oldTopology = _supportExtDynamic ? DynamicState._topology : _newState.Topology; var oldViewports = DynamicState.Viewports; var oldViewportsCount = _supportExtDynamic ? DynamicState.ViewportsCount : _newState.ViewportsCount; @@ -1023,41 +1023,13 @@ namespace Ryujinx.Graphics.Vulkan public void SetPrimitiveRestart(bool enable, int index) { - bool primitiveRestartEnable = enable; - - bool topologySupportsRestart; - - if (Gd.Capabilities.SupportsPrimitiveTopologyListRestart) - { - topologySupportsRestart = Gd.Capabilities.SupportsPrimitiveTopologyPatchListRestart || - _newState.Topology != Silk.NET.Vulkan.PrimitiveTopology.PatchList; - } - else - { - topologySupportsRestart = _newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.LineStrip || - _newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.TriangleStrip || - _newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.TriangleFan || - _newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.LineStripWithAdjacency || - _newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.TriangleStripWithAdjacency; - } - - primitiveRestartEnable &= topologySupportsRestart; - - //Cannot disable primitiveRestartEnable for these Topologies on MacOS - if ((_newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.LineStrip || _newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.TriangleStrip || - _newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.LineStripWithAdjacency || - _newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.TriangleStripWithAdjacency) && Gd.IsMoltenVk) - { - primitiveRestartEnable = true; - } - if (_supportExtDynamic2) { - DynamicState.SetPrimitiveRestartEnable(primitiveRestartEnable); + DynamicState.SetPrimitiveRestartEnable(enable); } else { - _newState.PrimitiveRestartEnable = primitiveRestartEnable; + _newState.PrimitiveRestartEnable = enable; } // TODO: What to do about the index? diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs b/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs index aa5dff3b1e..822838f005 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs @@ -4,6 +4,7 @@ using Silk.NET.Vulkan; using System; using Format = Silk.NET.Vulkan.Format; using PolygonMode = Silk.NET.Vulkan.PolygonMode; +using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology; namespace Ryujinx.Graphics.Vulkan { @@ -152,7 +153,7 @@ namespace Ryujinx.Graphics.Vulkan 0); } - public static PipelineState ToVulkanPipelineState(this ProgramPipelineState state, VulkanRenderer gd) + public static PipelineState ToVulkanPipelineState(this ProgramPipelineState state, VulkanRenderer gd, bool hasTCS) { var extendedDynamicState2 = gd.Capabilities.SupportsExtendedDynamicState2; var extendedDynamicState = gd.Capabilities.SupportsExtendedDynamicState; @@ -219,7 +220,8 @@ namespace Ryujinx.Graphics.Vulkan pipeline.StencilBackDepthFailOp = extendedDynamicState ? 0 : state.StencilTest.BackDpFail.Convert(); pipeline.StencilBackCompareOp = extendedDynamicState ? 0 : state.StencilTest.BackFunc.Convert(); - pipeline.Topology = extendedDynamicState ? gd.TopologyRemap(state.Topology).Convert().ConvertToClass() : gd.TopologyRemap(state.Topology).Convert(); + var topology = hasTCS ? PrimitiveTopology.Patches : state.Topology; + pipeline.Topology = extendedDynamicState ? gd.TopologyRemap(topology).Convert().ConvertToClass() : gd.TopologyRemap(topology).Convert(); int vaCount = Math.Min(Constants.MaxVertexAttributes, state.VertexAttribCount); int vbCount = Math.Min(Constants.MaxVertexBuffers, state.VertexBufferCount); diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs index 5194652d68..8fa274f3a1 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; - private PrimitiveTopology _topology; + public PrimitiveTopology _topology; private bool _primitiveRestartEnable; @@ -455,7 +455,33 @@ namespace Ryujinx.Graphics.Vulkan private readonly void RecordPrimitiveRestartEnable(VulkanRenderer gd, CommandBuffer commandBuffer) { - gd.ExtendedDynamicState2Api.CmdSetPrimitiveRestartEnable(commandBuffer, _primitiveRestartEnable); + bool primitiveRestartEnable = _primitiveRestartEnable; + + bool topologySupportsRestart; + + if (gd.Capabilities.SupportsPrimitiveTopologyListRestart) + { + topologySupportsRestart = gd.Capabilities.SupportsPrimitiveTopologyPatchListRestart || + _topology != PrimitiveTopology.PatchList; + } + else + { + topologySupportsRestart = _topology == PrimitiveTopology.LineStrip || + _topology == PrimitiveTopology.TriangleStrip || + _topology == PrimitiveTopology.TriangleFan || + _topology == PrimitiveTopology.LineStripWithAdjacency || + _topology == PrimitiveTopology.TriangleStripWithAdjacency; + } + + primitiveRestartEnable &= topologySupportsRestart; + + //Cannot disable primitiveRestartEnable for these Topologies on MacOS + if (gd.IsMoltenVk) + { + primitiveRestartEnable = true; + } + + gd.ExtendedDynamicState2Api.CmdSetPrimitiveRestartEnable(commandBuffer, primitiveRestartEnable); } private readonly void RecordPrimitiveTopology(VulkanRenderer gd, CommandBuffer commandBuffer) diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs index f6de4c5e7c..d1383fc243 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs @@ -488,7 +488,27 @@ namespace Ryujinx.Graphics.Vulkan if (!_supportsExtDynamicState2.ExtendedDynamicState2) { - inputAssemblyState.PrimitiveRestartEnable = PrimitiveRestartEnable; + bool primitiveRestartEnable = PrimitiveRestartEnable; + + bool topologySupportsRestart; + + if (gd.Capabilities.SupportsPrimitiveTopologyListRestart) + { + topologySupportsRestart = gd.Capabilities.SupportsPrimitiveTopologyPatchListRestart || + Topology != PrimitiveTopology.PatchList; + } + else + { + topologySupportsRestart = Topology == PrimitiveTopology.LineStrip || + Topology == PrimitiveTopology.TriangleStrip || + Topology == PrimitiveTopology.TriangleFan || + Topology == PrimitiveTopology.LineStripWithAdjacency || + Topology == PrimitiveTopology.TriangleStripWithAdjacency; + } + + primitiveRestartEnable &= topologySupportsRestart; + + inputAssemblyState.PrimitiveRestartEnable = primitiveRestartEnable; rasterizationState.DepthBiasEnable = DepthBiasEnable; rasterizationState.RasterizerDiscardEnable = RasterizerDiscardEnable; } diff --git a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs index 821a3cbceb..232a093b89 100644 --- a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs +++ b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs @@ -552,7 +552,7 @@ namespace Ryujinx.Graphics.Vulkan // The active attachment formats have been provided by the abstraction layer. var renderPass = CreateDummyRenderPass(); - PipelineState pipeline = _state.ToVulkanPipelineState(_gd); + PipelineState pipeline = _state.ToVulkanPipelineState(_gd, HasTessellationControlShader); ShaderTopology = pipeline.Topology;