From 9719b6a1129c017d96532ff026e2bb933c0b2d0b Mon Sep 17 00:00:00 2001 From: riperiperi Date: Wed, 26 Oct 2022 00:49:23 +0100 Subject: [PATCH] Vulkan: Use dynamic state for blend constants (#3793) --- Ryujinx.Graphics.Vulkan/PipelineBase.cs | 9 ++--- Ryujinx.Graphics.Vulkan/PipelineConverter.cs | 5 --- .../PipelineDynamicState.cs | 33 ++++++++++++++++--- Ryujinx.Graphics.Vulkan/PipelineState.cs | 5 +-- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 23abde414d..7c6234b179 100644 --- a/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -535,10 +535,11 @@ namespace Ryujinx.Graphics.Vulkan vkBlend = new PipelineColorBlendAttachmentState(); } - _newState.BlendConstantR = blend.BlendConstant.Red; - _newState.BlendConstantG = blend.BlendConstant.Green; - _newState.BlendConstantB = blend.BlendConstant.Blue; - _newState.BlendConstantA = blend.BlendConstant.Alpha; + DynamicState.SetBlendConstants( + blend.BlendConstant.Red, + blend.BlendConstant.Green, + blend.BlendConstant.Blue, + blend.BlendConstant.Alpha); SignalStateChange(); } diff --git a/Ryujinx.Graphics.Vulkan/PipelineConverter.cs b/Ryujinx.Graphics.Vulkan/PipelineConverter.cs index 477d0cec1b..55d29ffa0c 100644 --- a/Ryujinx.Graphics.Vulkan/PipelineConverter.cs +++ b/Ryujinx.Graphics.Vulkan/PipelineConverter.cs @@ -135,11 +135,6 @@ namespace Ryujinx.Graphics.Vulkan // It is assumed that Dynamic State is enabled when this conversion is used. - pipeline.BlendConstantA = state.BlendDescriptors[0].BlendConstant.Alpha; - pipeline.BlendConstantB = state.BlendDescriptors[0].BlendConstant.Blue; - pipeline.BlendConstantG = state.BlendDescriptors[0].BlendConstant.Green; - pipeline.BlendConstantR = state.BlendDescriptors[0].BlendConstant.Red; - pipeline.CullMode = state.CullEnable ? state.CullMode.Convert() : CullModeFlags.CullModeNone; pipeline.DepthBoundsTestEnable = false; // Not implemented. diff --git a/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs b/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs index 4f73b17b3e..ae29be51cb 100644 --- a/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs +++ b/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs @@ -19,21 +19,34 @@ namespace Ryujinx.Graphics.Vulkan private uint _frontWriteMask; private uint _frontReference; + private Array4 _blendConstants; + public int ViewportsCount; public Array16 Viewports; private enum DirtyFlags { None = 0, - DepthBias = 1 << 0, - Scissor = 1 << 1, - Stencil = 1 << 2, - Viewport = 1 << 3, - All = DepthBias | Scissor | Stencil | Viewport + Blend = 1 << 0, + DepthBias = 1 << 1, + Scissor = 1 << 2, + Stencil = 1 << 3, + Viewport = 1 << 4, + All = Blend | DepthBias | Scissor | Stencil | Viewport } private DirtyFlags _dirty; + public void SetBlendConstants(float r, float g, float b, float a) + { + _blendConstants[0] = r; + _blendConstants[1] = g; + _blendConstants[2] = b; + _blendConstants[3] = a; + + _dirty |= DirtyFlags.Blend; + } + public void SetDepthBias(float slopeFactor, float constantFactor, float clamp) { _depthBiasSlopeFactor = slopeFactor; @@ -87,6 +100,11 @@ namespace Ryujinx.Graphics.Vulkan public void ReplayIfDirty(Vk api, CommandBuffer commandBuffer) { + if (_dirty.HasFlag(DirtyFlags.Blend)) + { + RecordBlend(api, commandBuffer); + } + if (_dirty.HasFlag(DirtyFlags.DepthBias)) { RecordDepthBias(api, commandBuffer); @@ -110,6 +128,11 @@ namespace Ryujinx.Graphics.Vulkan _dirty = DirtyFlags.None; } + private void RecordBlend(Vk api, CommandBuffer commandBuffer) + { + api.CmdSetBlendConstants(commandBuffer, _blendConstants.AsSpan()); + } + private void RecordDepthBias(Vk api, CommandBuffer commandBuffer) { api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor); diff --git a/Ryujinx.Graphics.Vulkan/PipelineState.cs b/Ryujinx.Graphics.Vulkan/PipelineState.cs index 15c4d79e05..d33bc8ce80 100644 --- a/Ryujinx.Graphics.Vulkan/PipelineState.cs +++ b/Ryujinx.Graphics.Vulkan/PipelineState.cs @@ -499,7 +499,7 @@ namespace Ryujinx.Graphics.Vulkan colorBlendState.BlendConstants[3] = BlendConstantA; bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState; - int dynamicStatesCount = supportsExtDynamicState ? 8 : 7; + int dynamicStatesCount = supportsExtDynamicState ? 9 : 8; DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount]; @@ -510,10 +510,11 @@ namespace Ryujinx.Graphics.Vulkan dynamicStates[4] = DynamicState.StencilCompareMask; dynamicStates[5] = DynamicState.StencilWriteMask; dynamicStates[6] = DynamicState.StencilReference; + dynamicStates[7] = DynamicState.BlendConstants; if (supportsExtDynamicState) { - dynamicStates[7] = DynamicState.VertexInputBindingStrideExt; + dynamicStates[8] = DynamicState.VertexInputBindingStrideExt; } var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo()