From ecadc6a4f91a42c98c1d6a9f97791cbae5238780 Mon Sep 17 00:00:00 2001 From: sunshineinabox Date: Sat, 18 May 2024 21:46:22 -0700 Subject: [PATCH] Implement VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT --- src/Ryujinx.Graphics.Vulkan/PipelineBase.cs | 16 ++++++++-- .../PipelineDynamicState.cs | 29 ++++++++++++++++++- src/Ryujinx.Graphics.Vulkan/PipelineState.cs | 6 +++- .../VulkanInitialization.cs | 1 + 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 5024fdd4e..4b9d32ee9 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -898,9 +898,19 @@ namespace Ryujinx.Graphics.Vulkan public void SetDepthMode(DepthMode mode) { - bool oldMode = _newState.DepthMode; - _newState.DepthMode = mode == DepthMode.MinusOneToOne; - if (_newState.DepthMode != oldMode) + bool oldMode; + if (Gd.ExtendedDynamicState3Features.ExtendedDynamicState3DepthClipNegativeOneToOne) + { + oldMode = DynamicState.DepthMode; + DynamicState.SetDepthMode(mode == DepthMode.MinusOneToOne); + } + else + { + oldMode = _newState.DepthMode; + _newState.DepthMode = mode == DepthMode.MinusOneToOne; + } + + if ((Gd.ExtendedDynamicState3Features.ExtendedDynamicState3DepthClipNegativeOneToOne ? DynamicState.DepthMode : _newState.DepthMode) != oldMode) { SignalStateChange(); } diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs index 8f15cc61b..9126771a0 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs @@ -61,6 +61,8 @@ namespace Ryujinx.Graphics.Vulkan private bool _alphaToCoverEnable; private bool _alphaToOneEnable; + public bool DepthMode; + [Flags] private enum DirtyFlags { @@ -83,10 +85,11 @@ namespace Ryujinx.Graphics.Vulkan AlphaToCover = 1 << 15, AlphaToOne = 1 << 16, PatchControlPoints = 1 << 17, + DepthMode = 1 << 18, Standard = Blend | DepthBias | Scissor | Stencil | Viewport | LineWidth, Extended = CullMode | FrontFace | DepthTestBool | DepthTestCompareOp | StencilTestEnable, Extended2 = RasterDiscard | LogicOp | PatchControlPoints, - Extended3 = DepthClampEnable | LogicOpEnable | AlphaToCover | AlphaToOne, + Extended3 = DepthClampEnable | LogicOpEnable | AlphaToCover | AlphaToOne | DepthMode, } private DirtyFlags _dirty; @@ -315,6 +318,15 @@ namespace Ryujinx.Graphics.Vulkan _dirty |= DirtyFlags.AlphaToOne; } } + + public void SetDepthMode(bool mode) + { + if (DepthMode != mode) + { + DepthMode = mode; + _dirty |= DirtyFlags.DepthMode; + } + } public void ForceAllDirty(VulkanRenderer gd) { @@ -369,6 +381,11 @@ namespace Ryujinx.Graphics.Vulkan { _dirty &= ~DirtyFlags.LogicOpEnable; } + + if (!gd.ExtendedDynamicState3Features.ExtendedDynamicState3DepthClipNegativeOneToOne) + { + _dirty &= ~DirtyFlags.DepthMode; + } } public void ReplayIfDirty(VulkanRenderer gd, CommandBuffer commandBuffer) @@ -462,6 +479,11 @@ namespace Ryujinx.Graphics.Vulkan { RecordAlphaToOneEnable(gd, commandBuffer); } + + if (_dirty.HasFlag(DirtyFlags.DepthMode)) + { + RecordDepthMode(gd, commandBuffer); + } _dirty = DirtyFlags.None; } @@ -608,6 +630,11 @@ namespace Ryujinx.Graphics.Vulkan { gd.ExtendedDynamicState2Api.CmdSetPatchControlPoints(commandBuffer, _patchControlPoints); } + + private readonly void RecordDepthMode(VulkanRenderer gd, CommandBuffer commandBuffer) + { + gd.ExtendedDynamicState3Api.CmdSetDepthClipNegativeOneToOne(commandBuffer, DepthMode); + } private readonly void RecordLineWidth(Vk api, CommandBuffer commandBuffer) { diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs index 841512854..01cf1741c 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs @@ -513,9 +513,13 @@ namespace Ryujinx.Graphics.Vulkan var viewportDepthClipControlState = new PipelineViewportDepthClipControlCreateInfoEXT { SType = StructureType.PipelineViewportDepthClipControlCreateInfoExt, - NegativeOneToOne = DepthMode, }; + if (!gd.ExtendedDynamicState3Features.ExtendedDynamicState3DepthClipNegativeOneToOne) + { + viewportDepthClipControlState.NegativeOneToOne = DepthMode; + } + viewportState.PNext = &viewportDepthClipControlState; } diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs b/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs index 1c8b675dc..4b8c15526 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs @@ -493,6 +493,7 @@ namespace Ryujinx.Graphics.Vulkan ExtendedDynamicState3AlphaToCoverageEnable = supportedFeaturesExtExtendedDynamicState3.ExtendedDynamicState3AlphaToCoverageEnable, ExtendedDynamicState3AlphaToOneEnable = supportedFeaturesExtExtendedDynamicState3.ExtendedDynamicState3AlphaToOneEnable, ExtendedDynamicState3DepthClampEnable = supportedFeaturesExtExtendedDynamicState3.ExtendedDynamicState3DepthClampEnable, + ExtendedDynamicState3DepthClipNegativeOneToOne = supportedFeaturesExtExtendedDynamicState3.ExtendedDynamicState3DepthClipNegativeOneToOne, }; pExtendedFeatures = &featuresExtendedDynamicState3;