diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index e202a4ada..ff4293d00 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -693,7 +693,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 = _newState.ViewportsCount; @@ -726,6 +726,7 @@ namespace Ryujinx.Graphics.Vulkan DynamicState.SetCullMode(oldCullMode); DynamicState.SetStencilTest(oldStencilTestEnable); DynamicState.SetDepthTestBool(oldDepthTestEnable, oldDepthWriteEnable); + DynamicState.SetPrimitiveTopology(ref oldTopology); } else { @@ -733,9 +734,8 @@ namespace Ryujinx.Graphics.Vulkan _newState.StencilTestEnable = oldStencilTestEnable; _newState.DepthTestEnable = oldDepthTestEnable; _newState.DepthWriteEnable = oldDepthWriteEnable; + _newState.Topology = oldTopology; } - - _newState.Topology = oldTopology; DynamicState.SetViewports(ref oldViewports, oldViewportsCount); @@ -1018,9 +1018,15 @@ namespace Ryujinx.Graphics.Vulkan _topology = topology; var vkTopology = Gd.TopologyRemap(topology).Convert(); - - _newState.Topology = vkTopology; - + if (_supportExtDynamic) + { + DynamicState.SetPrimitiveTopology(ref vkTopology); + } + else + { + _newState.Topology = vkTopology; + } + SignalStateChange(); } diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs b/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs index bd91bfae8..c3a7d4a8b 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineConverter.cs @@ -164,10 +164,7 @@ namespace Ryujinx.Graphics.Vulkan pipeline.DepthBoundsTestEnable = false; // Not implemented. pipeline.DepthClampEnable = state.DepthClampEnable; - - pipeline.DepthTestEnable = state.DepthTest.TestEnable; - pipeline.DepthWriteEnable = state.DepthTest.WriteEnable; - pipeline.DepthCompareOp = state.DepthTest.Func.Convert(); + pipeline.DepthMode = state.DepthMode == DepthMode.MinusOneToOne; pipeline.HasDepthStencil = state.DepthStencilEnable; @@ -200,6 +197,10 @@ namespace Ryujinx.Graphics.Vulkan // Stencil masks and ref are dynamic, so are 0 in the Vulkan pipeline. if (!gd.Capabilities.SupportsExtendedDynamicState) { + pipeline.DepthTestEnable = state.DepthTest.TestEnable; + pipeline.DepthWriteEnable = state.DepthTest.WriteEnable; + pipeline.DepthCompareOp = state.DepthTest.Func.Convert(); + pipeline.CullMode = state.CullEnable ? state.CullMode.Convert() : CullModeFlags.None; pipeline.FrontFace = state.FrontFace.Convert(); @@ -213,12 +214,12 @@ namespace Ryujinx.Graphics.Vulkan pipeline.StencilBackPassOp = state.StencilTest.BackDpPass.Convert(); pipeline.StencilBackDepthFailOp = state.StencilTest.BackDpFail.Convert(); pipeline.StencilBackCompareOp = state.StencilTest.BackFunc.Convert(); + + pipeline.StencilTestEnable = state.StencilTest.TestEnable; + + pipeline.Topology = gd.TopologyRemap(state.Topology).Convert(); } - - pipeline.StencilTestEnable = state.StencilTest.TestEnable; - - pipeline.Topology = gd.TopologyRemap(state.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 7a1c39b04..916b065bd 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs @@ -36,6 +36,8 @@ namespace Ryujinx.Graphics.Vulkan public bool _depthwriteEnable; private CompareOp _depthCompareOp; + public PrimitiveTopology Topology; + private Array4 _blendConstants; public uint ViewportsCount; @@ -58,7 +60,8 @@ namespace Ryujinx.Graphics.Vulkan DepthTestBool = 1 << 7, DepthTestCompareOp = 1 << 8, StencilTestEnable = 1 << 9, - All = Blend | DepthBias | Scissor | Stencil | Viewport | CullMode | FrontFace | DepthTestBool | DepthTestCompareOp | StencilTestEnable, + Toplogy = 1 << 10, + All = Blend | DepthBias | Scissor | Stencil | Viewport | CullMode | FrontFace | DepthTestBool | DepthTestCompareOp | StencilTestEnable | Toplogy, } private DirtyFlags _dirty; @@ -103,8 +106,13 @@ namespace Ryujinx.Graphics.Vulkan _dirty |= DirtyFlags.DepthTestCompareOp; } + + public void SetPrimitiveTopology(ref PrimitiveTopology topology) + { + Topology = topology; - + _dirty |= DirtyFlags.Toplogy; + } public void SetStencilOp(StencilOp backFailOp, StencilOp backPassOp, @@ -242,6 +250,11 @@ namespace Ryujinx.Graphics.Vulkan { RecordStencilTestEnable(api, commandBuffer); } + + if (_dirty.HasFlag(DirtyFlags.Toplogy)) + { + RecordPrimitiveTopology(api, commandBuffer); + } _dirty = DirtyFlags.None; } @@ -315,5 +328,10 @@ namespace Ryujinx.Graphics.Vulkan { api.CmdSetDepthCompareOp(commandBuffer, _depthCompareOp); } + + private void RecordPrimitiveTopology(Vk api, CommandBuffer commandBuffer) + { + api.CmdSetPrimitiveTopology(commandBuffer, Topology); + } } } diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs index 7171b61c9..251cd61ed 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs @@ -453,9 +453,13 @@ namespace Ryujinx.Graphics.Vulkan { SType = StructureType.PipelineInputAssemblyStateCreateInfo, PrimitiveRestartEnable = primitiveRestartEnable, - Topology = Topology, }; + if (!supportsExtDynamicState) + { + inputAssemblyState.Topology = Topology; + } + var tessellationState = new PipelineTessellationStateCreateInfo { SType = StructureType.PipelineTessellationStateCreateInfo, @@ -589,7 +593,7 @@ namespace Ryujinx.Graphics.Vulkan colorBlendState.PNext = &colorBlendAdvancedState; } - int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 14 : 15) : 7; + int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 15 : 16) : 7; DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount]; @@ -613,6 +617,7 @@ namespace Ryujinx.Graphics.Vulkan dynamicStates[index++] = DynamicState.DepthWriteEnable; dynamicStates[index++] = DynamicState.DepthCompareOp; dynamicStates[index++] = DynamicState.StencilTestEnable; + dynamicStates[index++] = DynamicState.PrimitiveTopology; dynamicStates[index] = DynamicState.StencilOp; }