aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs')
-rw-r--r--src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs170
1 files changed, 170 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs
new file mode 100644
index 00000000..42ea022a
--- /dev/null
+++ b/src/Ryujinx.Graphics.Vulkan/PipelineDynamicState.cs
@@ -0,0 +1,170 @@
+using Ryujinx.Common.Memory;
+using Silk.NET.Vulkan;
+
+namespace Ryujinx.Graphics.Vulkan
+{
+ struct PipelineDynamicState
+ {
+ private float _depthBiasSlopeFactor;
+ private float _depthBiasConstantFactor;
+ private float _depthBiasClamp;
+
+ public int ScissorsCount;
+ private Array16<Rect2D> _scissors;
+
+ private uint _backCompareMask;
+ private uint _backWriteMask;
+ private uint _backReference;
+ private uint _frontCompareMask;
+ private uint _frontWriteMask;
+ private uint _frontReference;
+
+ private Array4<float> _blendConstants;
+
+ public uint ViewportsCount;
+ public Array16<Viewport> Viewports;
+
+ private enum DirtyFlags
+ {
+ None = 0,
+ 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;
+ _depthBiasConstantFactor = constantFactor;
+ _depthBiasClamp = clamp;
+
+ _dirty |= DirtyFlags.DepthBias;
+ }
+
+ public void SetScissor(int index, Rect2D scissor)
+ {
+ _scissors[index] = scissor;
+
+ _dirty |= DirtyFlags.Scissor;
+ }
+
+ public void SetStencilMasks(
+ uint backCompareMask,
+ uint backWriteMask,
+ uint backReference,
+ uint frontCompareMask,
+ uint frontWriteMask,
+ uint frontReference)
+ {
+ _backCompareMask = backCompareMask;
+ _backWriteMask = backWriteMask;
+ _backReference = backReference;
+ _frontCompareMask = frontCompareMask;
+ _frontWriteMask = frontWriteMask;
+ _frontReference = frontReference;
+
+ _dirty |= DirtyFlags.Stencil;
+ }
+
+ public void SetViewport(int index, Viewport viewport)
+ {
+ Viewports[index] = viewport;
+
+ _dirty |= DirtyFlags.Viewport;
+ }
+
+ public void SetViewports(ref Array16<Viewport> viewports, uint viewportsCount)
+ {
+ Viewports = viewports;
+ ViewportsCount = viewportsCount;
+
+ if (ViewportsCount != 0)
+ {
+ _dirty |= DirtyFlags.Viewport;
+ }
+ }
+
+ public void ForceAllDirty()
+ {
+ _dirty = DirtyFlags.All;
+ }
+
+ public void ReplayIfDirty(Vk api, CommandBuffer commandBuffer)
+ {
+ if (_dirty.HasFlag(DirtyFlags.Blend))
+ {
+ RecordBlend(api, commandBuffer);
+ }
+
+ if (_dirty.HasFlag(DirtyFlags.DepthBias))
+ {
+ RecordDepthBias(api, commandBuffer);
+ }
+
+ if (_dirty.HasFlag(DirtyFlags.Scissor))
+ {
+ RecordScissor(api, commandBuffer);
+ }
+
+ if (_dirty.HasFlag(DirtyFlags.Stencil))
+ {
+ RecordStencilMasks(api, commandBuffer);
+ }
+
+ if (_dirty.HasFlag(DirtyFlags.Viewport))
+ {
+ RecordViewport(api, commandBuffer);
+ }
+
+ _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);
+ }
+
+ private void RecordScissor(Vk api, CommandBuffer commandBuffer)
+ {
+ api.CmdSetScissor(commandBuffer, 0, (uint)ScissorsCount, _scissors.AsSpan());
+ }
+
+ private void RecordStencilMasks(Vk api, CommandBuffer commandBuffer)
+ {
+ api.CmdSetStencilCompareMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backCompareMask);
+ api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backWriteMask);
+ api.CmdSetStencilReference(commandBuffer, StencilFaceFlags.FaceBackBit, _backReference);
+ api.CmdSetStencilCompareMask(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontCompareMask);
+ api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontWriteMask);
+ api.CmdSetStencilReference(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontReference);
+ }
+
+ private void RecordViewport(Vk api, CommandBuffer commandBuffer)
+ {
+ if (ViewportsCount != 0)
+ {
+ api.CmdSetViewport(commandBuffer, 0, ViewportsCount, Viewports.AsSpan());
+ }
+ }
+ }
+}