More Dynamic States

This commit is contained in:
sunshineinabox 2024-05-12 23:57:40 -07:00
parent 4933888a9d
commit 5f02e28017
3 changed files with 125 additions and 40 deletions

View file

@ -690,9 +690,9 @@ namespace Ryujinx.Graphics.Vulkan
if (texture is TextureView srcTexture)
{
var oldCullMode = _supportExtDynamic ? DynamicState.CullMode : _newState.CullMode;
var oldStencilTestEnable = _newState.StencilTestEnable;
var oldDepthTestEnable = _newState.DepthTestEnable;
var oldDepthWriteEnable = _newState.DepthWriteEnable;
var oldStencilTestEnable = _supportExtDynamic ? DynamicState._stencilTestEnable : _newState.StencilTestEnable;
var oldDepthTestEnable = _supportExtDynamic ? DynamicState._depthtestEnable : _newState.DepthTestEnable;
var oldDepthWriteEnable = _supportExtDynamic ? DynamicState._depthwriteEnable : _newState.DepthWriteEnable;
var oldTopology = _newState.Topology;
var oldViewports = DynamicState.Viewports;
var oldViewportsCount = _newState.ViewportsCount;
@ -700,15 +700,17 @@ namespace Ryujinx.Graphics.Vulkan
if (_supportExtDynamic)
{
DynamicState.SetCullMode(CullModeFlags.None);
DynamicState.SetDepthTestBool(false, false);
DynamicState.SetStencilTest(false);
}
else
{
_newState.CullMode = CullModeFlags.None;
_newState.StencilTestEnable = false;
_newState.DepthTestEnable = false;
_newState.DepthWriteEnable = false;
}
_newState.StencilTestEnable = false;
_newState.DepthTestEnable = false;
_newState.DepthWriteEnable = false;
SignalStateChange();
Gd.HelperShader.DrawTexture(
@ -722,15 +724,17 @@ namespace Ryujinx.Graphics.Vulkan
if (_supportExtDynamic)
{
DynamicState.SetCullMode(oldCullMode);
DynamicState.SetStencilTest(oldStencilTestEnable);
DynamicState.SetDepthTestBool(oldDepthTestEnable, oldDepthWriteEnable);
}
else
{
_newState.CullMode = oldCullMode;
_newState.StencilTestEnable = oldStencilTestEnable;
_newState.DepthTestEnable = oldDepthTestEnable;
_newState.DepthWriteEnable = oldDepthWriteEnable;
}
_newState.StencilTestEnable = oldStencilTestEnable;
_newState.DepthTestEnable = oldDepthTestEnable;
_newState.DepthWriteEnable = oldDepthWriteEnable;
_newState.Topology = oldTopology;
DynamicState.SetViewports(ref oldViewports, oldViewportsCount);
@ -888,9 +892,18 @@ namespace Ryujinx.Graphics.Vulkan
public void SetDepthTest(DepthTestDescriptor depthTest)
{
_newState.DepthTestEnable = depthTest.TestEnable;
_newState.DepthWriteEnable = depthTest.WriteEnable;
_newState.DepthCompareOp = depthTest.Func.Convert();
if (_supportExtDynamic)
{
DynamicState.SetDepthTestBool(depthTest.TestEnable, depthTest.WriteEnable);
DynamicState.SetDepthTestCompareOp(depthTest.Func.Convert());
}
else
{
_newState.DepthTestEnable = depthTest.TestEnable;
_newState.DepthWriteEnable = depthTest.WriteEnable;
_newState.DepthCompareOp = depthTest.Func.Convert();
}
SignalStateChange();
}
@ -1148,7 +1161,7 @@ namespace Ryujinx.Graphics.Vulkan
public void SetStencilTest(StencilTestDescriptor stencilTest)
{
if (Gd.Capabilities.SupportsExtendedDynamicState)
if (_supportExtDynamic)
{
DynamicState.SetStencilOp(
stencilTest.BackSFail.Convert(),
@ -1159,6 +1172,8 @@ namespace Ryujinx.Graphics.Vulkan
stencilTest.FrontDpPass.Convert(),
stencilTest.FrontDpFail.Convert(),
stencilTest.FrontFunc.Convert());
DynamicState.SetStencilTest(stencilTest.TestEnable);
}
else
{
@ -1170,10 +1185,9 @@ namespace Ryujinx.Graphics.Vulkan
_newState.StencilFrontPassOp = stencilTest.FrontDpPass.Convert();
_newState.StencilFrontDepthFailOp = stencilTest.FrontDpFail.Convert();
_newState.StencilFrontCompareOp = stencilTest.FrontFunc.Convert();
_newState.StencilTestEnable = stencilTest.TestEnable;
}
_newState.StencilTestEnable = stencilTest.TestEnable;
DynamicState.SetStencilMask((uint)stencilTest.BackFuncMask,
(uint)stencilTest.BackMask,
(uint)stencilTest.BackFuncRef,

View file

@ -19,6 +19,7 @@ namespace Ryujinx.Graphics.Vulkan
private uint _frontCompareMask;
private uint _frontWriteMask;
private uint _frontReference;
private bool _opToo;
private StencilOp _backfailop;
private StencilOp _backpassop;
@ -28,6 +29,12 @@ namespace Ryujinx.Graphics.Vulkan
private StencilOp _frontpassop;
private StencilOp _frontdepthfailop;
private CompareOp _frontcompareop;
public bool _stencilTestEnable;
public bool _depthtestEnable;
public bool _depthwriteEnable;
private CompareOp _depthCompareOp;
private Array4<float> _blendConstants;
@ -48,7 +55,10 @@ namespace Ryujinx.Graphics.Vulkan
Viewport = 1 << 4,
CullMode = 1 << 5,
FrontFace = 1 << 6,
All = Blend | DepthBias | Scissor | Stencil | Viewport | CullMode | FrontFace,
DepthTestBool = 1 << 7,
DepthTestCompareOp = 1 << 8,
StencilTestEnable = 1 << 9,
All = Blend | DepthBias | Scissor | Stencil | Viewport | CullMode | FrontFace | DepthTestBool | DepthTestCompareOp | StencilTestEnable,
}
private DirtyFlags _dirty;
@ -79,6 +89,45 @@ namespace Ryujinx.Graphics.Vulkan
_dirty |= DirtyFlags.Scissor;
}
public void SetDepthTestBool(bool testEnable, bool writeEnable)
{
_depthtestEnable = testEnable;
_depthwriteEnable = writeEnable;
_dirty |= DirtyFlags.DepthTestBool;
}
public void SetDepthTestCompareOp(CompareOp depthTestOp)
{
_depthCompareOp = depthTestOp;
_dirty |= DirtyFlags.DepthTestCompareOp;
}
public void SetStencilOp(StencilOp backFailOp,
StencilOp backPassOp,
StencilOp backDepthFailOp,
CompareOp backCompareOp,
StencilOp frontFailOp,
StencilOp frontPassOp,
StencilOp frontDepthFailOp,
CompareOp frontCompareOp)
{
_backfailop = backFailOp;
_backpassop = backPassOp;
_backdepthfailop = backDepthFailOp;
_backcompareop = backCompareOp;
_frontfailop = frontFailOp;
_frontpassop = frontPassOp;
_frontdepthfailop = frontDepthFailOp;
_frontcompareop = frontCompareOp;
_opToo = true;
}
public void SetStencilMask(
uint backCompareMask,
uint backWriteMask,
@ -97,27 +146,14 @@ namespace Ryujinx.Graphics.Vulkan
_dirty |= DirtyFlags.Stencil;
}
public void SetStencilOp(StencilOp backFailOp = default,
StencilOp backPassOp = default,
StencilOp backDepthFailOp = default,
CompareOp backCompareOp = default,
StencilOp frontFailOp = default,
StencilOp frontPassOp = default,
StencilOp frontDepthFailOp = default,
CompareOp frontCompareOp = default)
public void SetStencilTest(bool stencilTestEnable)
{
_backfailop = backFailOp;
_backpassop = backPassOp;
_backdepthfailop = backDepthFailOp;
_backcompareop = backCompareOp;
_frontfailop = frontFailOp;
_frontpassop = frontPassOp;
_frontdepthfailop = frontDepthFailOp;
_frontcompareop = frontCompareOp;
_opToo = true;
_stencilTestEnable = stencilTestEnable;
_dirty |= DirtyFlags.StencilTestEnable;
}
public void SetViewport(int index, Viewport viewport)
{
Viewports[index] = viewport;
@ -191,6 +227,21 @@ namespace Ryujinx.Graphics.Vulkan
{
RecordFrontFace(api, commandBuffer);
}
if (_dirty.HasFlag(DirtyFlags.DepthTestBool))
{
RecordDepthTestBool(api, commandBuffer);
}
if (_dirty.HasFlag(DirtyFlags.DepthTestCompareOp))
{
RecordDepthTestCompareOp(api, commandBuffer);
}
if (_dirty.HasFlag(DirtyFlags.StencilTestEnable))
{
RecordStencilTestEnable(api, commandBuffer);
}
_dirty = DirtyFlags.None;
}
@ -230,7 +281,12 @@ namespace Ryujinx.Graphics.Vulkan
api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontWriteMask);
api.CmdSetStencilReference(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontReference);
}
private readonly void RecordStencilTestEnable(Vk api, CommandBuffer commandBuffer)
{
api.CmdSetStencilTestEnable(commandBuffer, _stencilTestEnable);
}
private void RecordViewport(Vk api, CommandBuffer commandBuffer)
{
if (ViewportsCount != 0)
@ -248,5 +304,16 @@ namespace Ryujinx.Graphics.Vulkan
{
api.CmdSetFrontFace(commandBuffer, FrontFace);
}
private void RecordDepthTestBool(Vk api, CommandBuffer commandBuffer)
{
api.CmdSetDepthTestEnable(commandBuffer, _depthtestEnable);
api.CmdSetDepthWriteEnable(commandBuffer, _depthwriteEnable);
}
private void RecordDepthTestCompareOp(Vk api, CommandBuffer commandBuffer)
{
api.CmdSetDepthCompareOp(commandBuffer, _depthCompareOp);
}
}
}

View file

@ -509,11 +509,7 @@ namespace Ryujinx.Graphics.Vulkan
var depthStencilState = new PipelineDepthStencilStateCreateInfo
{
SType = StructureType.PipelineDepthStencilStateCreateInfo,
DepthTestEnable = DepthTestEnable,
DepthWriteEnable = DepthWriteEnable,
DepthCompareOp = DepthCompareOp,
DepthBoundsTestEnable = DepthBoundsTestEnable,
StencilTestEnable = StencilTestEnable,
MinDepthBounds = MinDepthBounds,
MaxDepthBounds = MaxDepthBounds,
};
@ -540,6 +536,10 @@ namespace Ryujinx.Graphics.Vulkan
depthStencilState.Front = stencilFront;
depthStencilState.Back = stencilBack;
depthStencilState.StencilTestEnable = StencilTestEnable;
depthStencilState.DepthTestEnable = DepthTestEnable;
depthStencilState.DepthWriteEnable = DepthWriteEnable;
depthStencilState.DepthCompareOp = DepthCompareOp;
}
uint blendEnables = 0;
@ -593,7 +593,7 @@ namespace Ryujinx.Graphics.Vulkan
colorBlendState.PNext = &colorBlendAdvancedState;
}
int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 10 : 11) : 7;
int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 14 : 15) : 7;
DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount];
@ -613,6 +613,10 @@ namespace Ryujinx.Graphics.Vulkan
}
dynamicStates[index++] = DynamicState.CullMode;
dynamicStates[index++] = DynamicState.FrontFace;
dynamicStates[index++] = DynamicState.DepthTestEnable;
dynamicStates[index++] = DynamicState.DepthWriteEnable;
dynamicStates[index++] = DynamicState.DepthCompareOp;
dynamicStates[index++] = DynamicState.StencilTestEnable;
dynamicStates[index] = DynamicState.StencilOp;
}