diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 7163c3de8..4a98a456d 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -671,15 +671,15 @@ namespace Ryujinx.Graphics.Vulkan { var oldTopologyClass = GetTopologyClass(oldTopology); - DynamicState.SetCullMode(oldCullMode); - DynamicState.SetStencilTest(oldStencilTestEnable); - DynamicState.SetDepthTestBool(oldDepthTestEnable, oldDepthWriteEnable); - DynamicState.SetPrimitiveTopology(oldTopology); - if (oldTopologyClass != TopologyClass.Triangle) { _newState.TopologyClass = oldTopology; } + + DynamicState.SetCullMode(oldCullMode); + DynamicState.SetStencilTest(oldStencilTestEnable); + DynamicState.SetDepthTestBool(oldDepthTestEnable, oldDepthWriteEnable); + DynamicState.SetPrimitiveTopology(oldTopology); } else { @@ -823,21 +823,35 @@ namespace Ryujinx.Graphics.Vulkan public void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp) { - bool enable = (enables != 0) && (factor > 0.0f || units > 0.0f); + if (factor == 0 && units == 0 && !_newState.DepthBiasEnable && !_supportExtDynamic2) + { + return; + } - if (enable) + bool depthBiasEnable = (enables != 0) && (factor != 0 && units != 0); + bool changed = false; + + if (_supportExtDynamic2) + { + DynamicState.SetDepthBiasEnable(depthBiasEnable); + changed = true; + } + else if (_newState.DepthBiasEnable != depthBiasEnable) + { + _newState.DepthBiasEnable = depthBiasEnable; + changed = true; + } + + if (depthBiasEnable) { DynamicState.SetDepthBias(factor, units, clamp); + changed = true; } - if (Gd.Capabilities.SupportsExtendedDynamicState2) + if (changed) { - DynamicState.SetDepthBiasEnable(enable); + SignalStateChange(); } - - _newState.DepthBiasEnable = enable; - - SignalStateChange(); } public void SetDepthClamp(bool clamp) @@ -849,15 +863,16 @@ namespace Ryujinx.Graphics.Vulkan public void SetDepthMode(DepthMode mode) { - bool oldMode; + bool newMode = mode == DepthMode.MinusOneToOne; - oldMode = _newState.DepthMode; - _newState.DepthMode = mode == DepthMode.MinusOneToOne; - - if (_newState.DepthMode != oldMode) + if (_newState.DepthMode == newMode) { - SignalStateChange(); + return; } + + _newState.DepthMode = newMode; + + SignalStateChange(); } public void SetDepthTest(DepthTestDescriptor depthTest) @@ -865,16 +880,18 @@ namespace Ryujinx.Graphics.Vulkan if (_supportExtDynamic) { DynamicState.SetDepthTestBool(depthTest.TestEnable, depthTest.WriteEnable); - DynamicState.SetDepthTestCompareOp(depthTest.Func.Convert()); + if (depthTest.TestEnable) + { + DynamicState.SetDepthTestCompareOp(depthTest.Func.Convert()); + } } else { - _newState.DepthWriteEnable = depthTest.WriteEnable; - _newState.DepthCompareOp = depthTest.Func.Convert(); + _newState.DepthTestEnable = depthTest.TestEnable; + _newState.DepthWriteEnable = depthTest.WriteEnable && depthTest.TestEnable; + _newState.DepthCompareOp = depthTest.TestEnable ? depthTest.Func.Convert() : default; } - _newState.DepthTestEnable = depthTest.TestEnable; - SignalStateChange(); } @@ -958,7 +975,7 @@ namespace Ryujinx.Graphics.Vulkan _newState.LogicOpEnable = logicOpEnable; - if (Gd.ExtendedDynamicState2Features.ExtendedDynamicState2LogicOp) + if (Gd.ExtendedDynamicState2Features.ExtendedDynamicState2LogicOp && logicOpEnable) { DynamicState.SetLogicOp(op.Convert()); } @@ -1053,17 +1070,18 @@ namespace Ryujinx.Graphics.Vulkan _topology = topology; var vkTopology = Gd.TopologyRemap(topology).Convert(); - var newTopologyClass = GetTopologyClass(vkTopology); - var currentTopologyClass = GetTopologyClass(_newState.TopologyClass); if (_supportExtDynamic) { - DynamicState.SetPrimitiveTopology(vkTopology); - } + var newTopologyClass = GetTopologyClass(vkTopology); + var currentTopologyClass = GetTopologyClass(_newState.TopologyClass); - if ((currentTopologyClass != newTopologyClass)) - { - _newState.TopologyClass = vkTopology; + if ((currentTopologyClass != newTopologyClass)) + { + _newState.TopologyClass = vkTopology; + } + + DynamicState.SetPrimitiveTopology(vkTopology); } _newState.Topology = vkTopology; diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs index 7733ead98..2c473ab79 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs @@ -118,7 +118,7 @@ namespace Ryujinx.Graphics.Vulkan public void SetDepthTestBool(bool testEnable, bool writeEnable) { DepthTestEnable = testEnable; - DepthWriteEnable = writeEnable; + DepthWriteEnable = writeEnable && testEnable; _dirty |= DirtyFlags.DepthTestBool; } @@ -440,10 +440,7 @@ namespace Ryujinx.Graphics.Vulkan { api.CmdSetDepthTestEnable(commandBuffer, DepthTestEnable); - if (DepthTestEnable) - { - api.CmdSetDepthWriteEnable(commandBuffer, DepthWriteEnable); - } + api.CmdSetDepthWriteEnable(commandBuffer, DepthWriteEnable); } private readonly void RecordDepthTestCompareOp(ExtExtendedDynamicState api, CommandBuffer commandBuffer) @@ -478,10 +475,7 @@ namespace Ryujinx.Graphics.Vulkan private readonly void RecordLineWidth(Vk api, CommandBuffer commandBuffer) { - if (!OperatingSystem.IsMacOS()) - { - api.CmdSetLineWidth(commandBuffer, _lineWidth); - } + api.CmdSetLineWidth(commandBuffer, _lineWidth); } } } diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs index 06269eb34..7f0205f11 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs @@ -446,7 +446,7 @@ namespace Ryujinx.Graphics.Vulkan if (isMoltenVk) { - //When widelines feature is not supported it must be 1.0f per spec. + //When widelines feature is not supported it must be 1.0f. rasterizationState.LineWidth = 1.0f; } @@ -514,10 +514,7 @@ namespace Ryujinx.Graphics.Vulkan depthStencilState.Back = stencilBack; depthStencilState.StencilTestEnable = StencilTestEnable; depthStencilState.DepthTestEnable = DepthTestEnable; - if (DepthTestEnable) - { - depthStencilState.DepthWriteEnable = DepthWriteEnable; - } + depthStencilState.DepthWriteEnable = DepthWriteEnable; depthStencilState.DepthCompareOp = DepthCompareOp; } @@ -570,7 +567,7 @@ namespace Ryujinx.Graphics.Vulkan colorBlendState.PNext = &colorBlendAdvancedState; } - int baseDynamicStatesCount = 6; + int baseDynamicStatesCount = 7; int additionalDynamicStatesCount = 0; if (!isMoltenVk) @@ -578,19 +575,9 @@ namespace Ryujinx.Graphics.Vulkan baseDynamicStatesCount++; } - if (DepthBiasEnable) - { - baseDynamicStatesCount++; - } - if (supportsExtDynamicState) { - additionalDynamicStatesCount += isMoltenVk ? 7 : 8; - - if (DepthTestEnable) - { - additionalDynamicStatesCount++; - } + additionalDynamicStatesCount += isMoltenVk ? 8 : 9; } if (supportsExtDynamicState2) @@ -615,16 +602,13 @@ namespace Ryujinx.Graphics.Vulkan dynamicStates[3] = DynamicState.StencilWriteMask; dynamicStates[4] = DynamicState.StencilReference; dynamicStates[5] = DynamicState.BlendConstants; + dynamicStates[6] = DynamicState.DepthBias; - if (DepthBiasEnable) - { - dynamicStates[6] = DynamicState.DepthBias; - } - int currentIndex = DepthBiasEnable ? 7 : 6; + int currentIndex = 7; if (!isMoltenVk) { - //LineWidth is only supported on macOS when using Metal Private API on newer version of MoltenVK + //LineWidth dynamic state is only supported on macOS when using Metal Private API on newer version of MoltenVK dynamicStates[currentIndex++] = DynamicState.LineWidth; } @@ -640,11 +624,7 @@ namespace Ryujinx.Graphics.Vulkan dynamicStates[currentIndex++] = DynamicState.CullModeExt; dynamicStates[currentIndex++] = DynamicState.FrontFaceExt; dynamicStates[currentIndex++] = DynamicState.DepthTestEnableExt; - - if (DepthTestEnable) - { - dynamicStates[currentIndex++] = DynamicState.DepthWriteEnableExt; - } + dynamicStates[currentIndex++] = DynamicState.DepthWriteEnableExt; dynamicStates[currentIndex++] = DynamicState.DepthCompareOpExt; dynamicStates[currentIndex++] = DynamicState.StencilTestEnableExt;