Avoid unncessary state changes?
This commit is contained in:
parent
cf1c9ed9ec
commit
116dd738d4
1 changed files with 148 additions and 96 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue