diff --git a/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs b/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs index b6694bcb3..8c7089aa5 100644 --- a/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs +++ b/src/Ryujinx.Graphics.Vulkan/HardwareCapabilities.cs @@ -46,6 +46,7 @@ namespace Ryujinx.Graphics.Vulkan public readonly bool SupportsViewportArray2; public readonly bool SupportsHostImportedMemory; public readonly bool SupportsDepthClipControl; + public readonly bool SupportsWideLines; public readonly uint SubgroupSize; public readonly SampleCountFlags SupportedSampleCounts; public readonly PortabilitySubsetFlags PortabilitySubset; @@ -84,6 +85,7 @@ namespace Ryujinx.Graphics.Vulkan bool supportsViewportArray2, bool supportsHostImportedMemory, bool supportsDepthClipControl, + bool supportsWideLines, uint subgroupSize, SampleCountFlags supportedSampleCounts, PortabilitySubsetFlags portabilitySubset, @@ -121,6 +123,7 @@ namespace Ryujinx.Graphics.Vulkan SupportsViewportArray2 = supportsViewportArray2; SupportsHostImportedMemory = supportsHostImportedMemory; SupportsDepthClipControl = supportsDepthClipControl; + SupportsWideLines = supportsWideLines; SubgroupSize = subgroupSize; SupportedSampleCounts = supportedSampleCounts; PortabilitySubset = portabilitySubset; diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 61e008290..962f99d99 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -968,7 +968,8 @@ namespace Ryujinx.Graphics.Vulkan public void SetLineParameters(float width, bool smooth) { - _newState.LineWidth = width; + DynamicState.SetLineWidth(Gd.Capabilities.SupportsWideLines ? width : 1.0f); + SignalStateChange(); } diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs index aaa97660a..b5af582da 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs @@ -29,6 +29,8 @@ namespace Ryujinx.Graphics.Vulkan private StencilOp _frontpassop; private StencilOp _frontdepthfailop; private CompareOp _frontcompareop; + + private float _linewidth; public bool _stencilTestEnable; @@ -61,7 +63,8 @@ namespace Ryujinx.Graphics.Vulkan DepthTestCompareOp = 1 << 8, StencilTestEnable = 1 << 9, Toplogy = 1 << 10, - All = Blend | DepthBias | Scissor | Stencil | Viewport | CullMode | FrontFace | DepthTestBool | DepthTestCompareOp | StencilTestEnable | Toplogy, + LineWidth = 1 <<11, + All = Blend | DepthBias | Scissor | Stencil | Viewport | CullMode | FrontFace | DepthTestBool | DepthTestCompareOp | StencilTestEnable | Toplogy | LineWidth, } private DirtyFlags _dirty; @@ -193,6 +196,13 @@ namespace Ryujinx.Graphics.Vulkan _dirty |= DirtyFlags.FrontFace; } + + public void SetLineWidth(float width) + { + _linewidth = width; + + _dirty |= DirtyFlags.LineWidth; + } public void ForceAllDirty() { @@ -255,6 +265,11 @@ namespace Ryujinx.Graphics.Vulkan { RecordPrimitiveTopology(api, commandBuffer); } + + if (_dirty.HasFlag(DirtyFlags.LineWidth)) + { + RecordLineWidth(api, commandBuffer); + } _dirty = DirtyFlags.None; } @@ -333,5 +348,10 @@ namespace Ryujinx.Graphics.Vulkan { api.CmdSetPrimitiveTopology(commandBuffer, Topology); } + + private void RecordLineWidth(Vk api, CommandBuffer commandBuffer) + { + api.CmdSetLineWidth(commandBuffer, _linewidth); + } } } diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs index 4d8348026..a73ae8f1e 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs @@ -479,7 +479,6 @@ namespace Ryujinx.Graphics.Vulkan DepthClampEnable = DepthClampEnable, RasterizerDiscardEnable = RasterizerDiscardEnable, PolygonMode = PolygonMode, - LineWidth = LineWidth, DepthBiasEnable = DepthBiasEnable, }; @@ -600,7 +599,7 @@ namespace Ryujinx.Graphics.Vulkan colorBlendState.PNext = &colorBlendAdvancedState; } - int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 15 : 16) : 7; + int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 16 : 17) : 8; DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount]; @@ -611,21 +610,23 @@ namespace Ryujinx.Graphics.Vulkan dynamicStates[4] = DynamicState.StencilWriteMask; dynamicStates[5] = DynamicState.StencilReference; dynamicStates[6] = DynamicState.BlendConstants; + dynamicStates[7] = DynamicState.LineWidth; + if (supportsExtDynamicState) { - int index = 7; + int index = 8; if (!isMoltenVk) { dynamicStates[index++] = DynamicState.VertexInputBindingStrideExt; } - dynamicStates[index++] = DynamicState.CullMode; - dynamicStates[index++] = DynamicState.FrontFace; - dynamicStates[index++] = DynamicState.DepthTestEnable; - dynamicStates[index++] = DynamicState.DepthWriteEnable; - dynamicStates[index++] = DynamicState.DepthCompareOp; - dynamicStates[index++] = DynamicState.StencilTestEnable; - dynamicStates[index++] = DynamicState.PrimitiveTopology; - dynamicStates[index] = DynamicState.StencilOp; + dynamicStates[index++] = DynamicState.CullModeExt; + dynamicStates[index++] = DynamicState.FrontFaceExt; + dynamicStates[index++] = DynamicState.DepthTestEnableExt; + dynamicStates[index++] = DynamicState.DepthWriteEnableExt; + dynamicStates[index++] = DynamicState.DepthCompareOpExt; + dynamicStates[index++] = DynamicState.StencilTestEnableExt; + dynamicStates[index++] = DynamicState.PrimitiveTopologyExt; + dynamicStates[index] = DynamicState.StencilOpExt; } var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs b/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs index d59ca7e0e..a8de50f6d 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs @@ -382,6 +382,7 @@ namespace Ryujinx.Graphics.Vulkan TessellationShader = supportedFeatures.TessellationShader, VertexPipelineStoresAndAtomics = supportedFeatures.VertexPipelineStoresAndAtomics, RobustBufferAccess = useRobustBufferAccess, + WideLines = supportedFeatures.WideLines, }; void* pExtendedFeatures = null; diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs index 8ef05de36..eedc9ed75 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -397,6 +397,7 @@ namespace Ryujinx.Graphics.Vulkan _physicalDevice.IsDeviceExtensionPresent("VK_NV_viewport_array2"), _physicalDevice.IsDeviceExtensionPresent(ExtExternalMemoryHost.ExtensionName), supportsDepthClipControl && featuresDepthClipControl.DepthClipControl, + _physicalDevice.PhysicalDeviceFeatures.WideLines, propertiesSubgroup.SubgroupSize, supportedSampleCounts, portabilityFlags,