Avoid unncessary state changes?

This commit is contained in:
sunshineinabox 2024-05-18 14:31:38 -07:00
parent 5f2d924bac
commit 767abfe500

View file

@ -90,77 +90,97 @@ namespace Ryujinx.Graphics.Vulkan
private DirtyFlags _dirty; private DirtyFlags _dirty;
private const float Epsilon = 1e-6f;
private bool FloatCompare(float a, float b)
{
return Math.Abs(a - b) < Epsilon;
}
public void SetBlendConstants(float r, float g, float b, float a) public void SetBlendConstants(float r, float g, float b, float a)
{
if (!FloatCompare(_blendConstants[0], r) ||
!FloatCompare(_blendConstants[1], g) ||
!FloatCompare(_blendConstants[2], b) ||
!FloatCompare(_blendConstants[3], a))
{ {
_blendConstants[0] = r; _blendConstants[0] = r;
_blendConstants[1] = g; _blendConstants[1] = g;
_blendConstants[2] = b; _blendConstants[2] = b;
_blendConstants[3] = a; _blendConstants[3] = a;
_dirty |= DirtyFlags.Blend; _dirty |= DirtyFlags.Blend;
} }
}
public void SetDepthBias(float slopeFactor, float constantFactor, float clamp, bool enable) public void SetDepthBias(float slopeFactor, float constantFactor, float clamp, bool enable)
{
if (!FloatCompare(_depthBiasSlopeFactor, slopeFactor) ||
!FloatCompare(_depthBiasConstantFactor, constantFactor) ||
!FloatCompare(_depthBiasClamp, clamp) ||
_depthBiasEnable != enable)
{ {
_depthBiasSlopeFactor = slopeFactor; _depthBiasSlopeFactor = slopeFactor;
_depthBiasConstantFactor = constantFactor; _depthBiasConstantFactor = constantFactor;
_depthBiasClamp = clamp; _depthBiasClamp = clamp;
_depthBiasEnable = enable; _depthBiasEnable = enable;
_dirty |= DirtyFlags.DepthBias; _dirty |= DirtyFlags.DepthBias;
} }
}
public void SetScissor(int index, Rect2D scissor) public void SetScissor(int index, Rect2D scissor)
{
if (!_scissors[index].Equals(scissor))
{ {
_scissors[index] = scissor; _scissors[index] = scissor;
_dirty |= DirtyFlags.Scissor; _dirty |= DirtyFlags.Scissor;
} }
}
public void SetDepthTestBool(bool testEnable, bool writeEnable) public void SetDepthTestBool(bool testEnable, bool writeEnable)
{
if (_depthtestEnable != testEnable || _depthwriteEnable != writeEnable)
{ {
_depthtestEnable = testEnable; _depthtestEnable = testEnable;
_depthwriteEnable = writeEnable; _depthwriteEnable = writeEnable;
_dirty |= DirtyFlags.DepthTestBool; _dirty |= DirtyFlags.DepthTestBool;
} }
}
public void SetDepthTestCompareOp(CompareOp depthTestOp) public void SetDepthTestCompareOp(CompareOp depthTestOp)
{
if (_depthCompareOp != depthTestOp)
{ {
_depthCompareOp = depthTestOp; _depthCompareOp = depthTestOp;
_dirty |= DirtyFlags.DepthTestCompareOp; _dirty |= DirtyFlags.DepthTestCompareOp;
} }
}
public void SetStencilOp(StencilOp backFailOp, public void SetStencilOp(StencilOp backFailOp, StencilOp backPassOp, StencilOp backDepthFailOp,
StencilOp backPassOp, CompareOp backCompareOp, StencilOp frontFailOp, StencilOp frontPassOp, StencilOp frontDepthFailOp,
StencilOp backDepthFailOp,
CompareOp backCompareOp,
StencilOp frontFailOp,
StencilOp frontPassOp,
StencilOp frontDepthFailOp,
CompareOp frontCompareOp) CompareOp frontCompareOp)
{
if (_backfailop != backFailOp || _backpassop != backPassOp || _backdepthfailop != backDepthFailOp ||
_backcompareop != backCompareOp || _frontfailop != frontFailOp || _frontpassop != frontPassOp ||
_frontdepthfailop != frontDepthFailOp || _frontcompareop != frontCompareOp)
{ {
_backfailop = backFailOp; _backfailop = backFailOp;
_backpassop = backPassOp; _backpassop = backPassOp;
_backdepthfailop = backDepthFailOp; _backdepthfailop = backDepthFailOp;
_backcompareop = backCompareOp; _backcompareop = backCompareOp;
_frontfailop = frontFailOp; _frontfailop = frontFailOp;
_frontpassop = frontPassOp; _frontpassop = frontPassOp;
_frontdepthfailop = frontDepthFailOp; _frontdepthfailop = frontDepthFailOp;
_frontcompareop = frontCompareOp; _frontcompareop = frontCompareOp;
_opToo = true; _opToo = true;
} }
}
public void SetStencilMask( public void SetStencilMask(uint backCompareMask, uint backWriteMask, uint backReference,
uint backCompareMask, uint frontCompareMask, uint frontWriteMask, uint frontReference)
uint backWriteMask, {
uint backReference, if (_backCompareMask != backCompareMask || _backWriteMask != backWriteMask ||
uint frontCompareMask, _backReference != backReference || _frontCompareMask != frontCompareMask ||
uint frontWriteMask, _frontWriteMask != frontWriteMask || _frontReference != frontReference)
uint frontReference)
{ {
_backCompareMask = backCompareMask; _backCompareMask = backCompareMask;
_backWriteMask = backWriteMask; _backWriteMask = backWriteMask;
@ -168,105 +188,132 @@ namespace Ryujinx.Graphics.Vulkan
_frontCompareMask = frontCompareMask; _frontCompareMask = frontCompareMask;
_frontWriteMask = frontWriteMask; _frontWriteMask = frontWriteMask;
_frontReference = frontReference; _frontReference = frontReference;
_dirty |= DirtyFlags.Stencil; _dirty |= DirtyFlags.Stencil;
} }
}
public void SetStencilTest(bool stencilTestEnable) public void SetStencilTest(bool stencilTestEnable)
{
if (_stencilTestEnable != stencilTestEnable)
{ {
_stencilTestEnable = stencilTestEnable; _stencilTestEnable = stencilTestEnable;
_dirty |= DirtyFlags.StencilTestEnable; _dirty |= DirtyFlags.StencilTestEnable;
} }
}
public void SetViewport(int index, Viewport viewport) public void SetViewport(int index, Viewport viewport)
{
if (!Viewports[index].Equals(viewport))
{ {
Viewports[index] = viewport; Viewports[index] = viewport;
_dirty |= DirtyFlags.Viewport; _dirty |= DirtyFlags.Viewport;
} }
}
public void SetViewports(ref Array16<Viewport> viewports, uint viewportsCount) public void SetViewports(ref Array16<Viewport> viewports, uint viewportsCount)
{
if (!Viewports.Equals(viewports) || ViewportsCount != viewportsCount)
{ {
Viewports = viewports; Viewports = viewports;
ViewportsCount = viewportsCount; ViewportsCount = viewportsCount;
if (ViewportsCount != 0) if (ViewportsCount != 0)
{ {
_dirty |= DirtyFlags.Viewport; _dirty |= DirtyFlags.Viewport;
} }
} }
}
public void SetCullMode(CullModeFlags cullMode) public void SetCullMode(CullModeFlags cullMode)
{
if (CullMode != cullMode)
{ {
CullMode = cullMode; CullMode = cullMode;
_dirty |= DirtyFlags.CullMode; _dirty |= DirtyFlags.CullMode;
} }
}
public void SetFrontFace(FrontFace frontFace) public void SetFrontFace(FrontFace frontFace)
{
if (FrontFace != frontFace)
{ {
FrontFace = frontFace; FrontFace = frontFace;
_dirty |= DirtyFlags.FrontFace; _dirty |= DirtyFlags.FrontFace;
} }
}
public void SetLineWidth(float width) public void SetLineWidth(float width)
{
if (!FloatCompare(_linewidth, width))
{ {
_linewidth = width; _linewidth = width;
_dirty |= DirtyFlags.LineWidth; _dirty |= DirtyFlags.LineWidth;
} }
}
public void SetRasterizerDiscard(bool discard) public void SetRasterizerDiscard(bool discard)
{
if (_discard != discard)
{ {
_discard = discard; _discard = discard;
_dirty |= DirtyFlags.RasterDiscard; _dirty |= DirtyFlags.RasterDiscard;
} }
}
public void SetLogicOp(LogicOp op) public void SetLogicOp(LogicOp op)
{
if (_logicOp != op)
{ {
_logicOp = op; _logicOp = op;
_dirty |= DirtyFlags.LogicOp; _dirty |= DirtyFlags.LogicOp;
} }
}
public void SetPatchControlPoints(uint points) public void SetPatchControlPoints(uint points)
{
if (_patchControlPoints != points)
{ {
_patchControlPoints = points; _patchControlPoints = points;
_dirty |= DirtyFlags.PatchControlPoints; _dirty |= DirtyFlags.PatchControlPoints;
} }
}
public void SetLogicOpEnable(bool logicOpEnable) public void SetLogicOpEnable(bool logicOpEnable)
{
if (_logicOpEnable != logicOpEnable)
{ {
_logicOpEnable = logicOpEnable; _logicOpEnable = logicOpEnable;
_dirty |= DirtyFlags.LogicOpEnalbe; _dirty |= DirtyFlags.LogicOpEnalbe;
} }
}
public void SetDepthClampEnable(bool depthClampEnable) public void SetDepthClampEnable(bool depthClampEnable)
{
if (_depthClampEnable != depthClampEnable)
{ {
_depthClampEnable = depthClampEnable; _depthClampEnable = depthClampEnable;
_dirty |= DirtyFlags.DepthClampEnable; _dirty |= DirtyFlags.DepthClampEnable;
} }
}
public void SetAlphaToCoverEnable(bool alphaToCoverEnable) public void SetAlphaToCoverEnable(bool alphaToCoverEnable)
{
if (_alphaToCoverEnable != alphaToCoverEnable)
{ {
_alphaToCoverEnable = alphaToCoverEnable; _alphaToCoverEnable = alphaToCoverEnable;
_dirty |= DirtyFlags.AlphaToCover; _dirty |= DirtyFlags.AlphaToCover;
} }
}
public void SetAlphaToOneEnable(bool alphaToOneEnable) public void SetAlphaToOneEnable(bool alphaToOneEnable)
{
if (_alphaToOneEnable != alphaToOneEnable)
{ {
_alphaToOneEnable = alphaToOneEnable; _alphaToOneEnable = alphaToOneEnable;
_dirty |= DirtyFlags.AlphaToOne; _dirty |= DirtyFlags.AlphaToOne;
} }
}
public void ForceAllDirty(VulkanRenderer gd) public void ForceAllDirty(VulkanRenderer gd)
{ {
@ -418,7 +465,7 @@ namespace Ryujinx.Graphics.Vulkan
api.CmdSetBlendConstants(commandBuffer, _blendConstants.AsSpan()); api.CmdSetBlendConstants(commandBuffer, _blendConstants.AsSpan());
} }
private readonly void RecordDepthBias(VulkanRenderer gd, CommandBuffer commandBuffer) private void RecordDepthBias(VulkanRenderer gd, CommandBuffer commandBuffer)
{ {
gd.Api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor); gd.Api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor);
@ -517,6 +564,11 @@ namespace Ryujinx.Graphics.Vulkan
private readonly void RecordLogicOp(VulkanRenderer gd, CommandBuffer commandBuffer) private readonly void RecordLogicOp(VulkanRenderer gd, CommandBuffer commandBuffer)
{ {
if (!_logicOpEnable)
{
return;
}
gd.ExtendedDynamicState2Api.CmdSetLogicOp(commandBuffer, _logicOp); gd.ExtendedDynamicState2Api.CmdSetLogicOp(commandBuffer, _logicOp);
} }