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 int 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 SetViewportsDirty()
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.StencilFaceBackBit, _backCompareMask);
api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.StencilFaceBackBit, _backWriteMask);
api.CmdSetStencilReference(commandBuffer, StencilFaceFlags.StencilFaceBackBit, _backReference);
api.CmdSetStencilCompareMask(commandBuffer, StencilFaceFlags.StencilFaceFrontBit, _frontCompareMask);
api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.StencilFaceFrontBit, _frontWriteMask);
api.CmdSetStencilReference(commandBuffer, StencilFaceFlags.StencilFaceFrontBit, _frontReference);
private void RecordViewport(Vk api, CommandBuffer commandBuffer)
api.CmdSetViewport(commandBuffer, 0, (uint)ViewportsCount, Viewports.AsSpan());