More Dynamic States

This commit is contained in:
sunshineinabox 2024-05-12 23:57:40 -07:00
parent 638d74ebe6
commit d12c441e67
3 changed files with 125 additions and 40 deletions

View file

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

View file

@ -19,6 +19,7 @@ namespace Ryujinx.Graphics.Vulkan
private uint _frontCompareMask; private uint _frontCompareMask;
private uint _frontWriteMask; private uint _frontWriteMask;
private uint _frontReference; private uint _frontReference;
private bool _opToo; private bool _opToo;
private StencilOp _backfailop; private StencilOp _backfailop;
private StencilOp _backpassop; private StencilOp _backpassop;
@ -29,6 +30,12 @@ namespace Ryujinx.Graphics.Vulkan
private StencilOp _frontdepthfailop; private StencilOp _frontdepthfailop;
private CompareOp _frontcompareop; private CompareOp _frontcompareop;
public bool _stencilTestEnable;
public bool _depthtestEnable;
public bool _depthwriteEnable;
private CompareOp _depthCompareOp;
private Array4<float> _blendConstants; private Array4<float> _blendConstants;
public uint ViewportsCount; public uint ViewportsCount;
@ -48,7 +55,10 @@ namespace Ryujinx.Graphics.Vulkan
Viewport = 1 << 4, Viewport = 1 << 4,
CullMode = 1 << 5, CullMode = 1 << 5,
FrontFace = 1 << 6, 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; private DirtyFlags _dirty;
@ -79,6 +89,45 @@ namespace Ryujinx.Graphics.Vulkan
_dirty |= DirtyFlags.Scissor; _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( public void SetStencilMask(
uint backCompareMask, uint backCompareMask,
uint backWriteMask, uint backWriteMask,
@ -97,27 +146,14 @@ namespace Ryujinx.Graphics.Vulkan
_dirty |= DirtyFlags.Stencil; _dirty |= DirtyFlags.Stencil;
} }
public void SetStencilOp(StencilOp backFailOp = default, public void SetStencilTest(bool stencilTestEnable)
StencilOp backPassOp = default,
StencilOp backDepthFailOp = default,
CompareOp backCompareOp = default,
StencilOp frontFailOp = default,
StencilOp frontPassOp = default,
StencilOp frontDepthFailOp = default,
CompareOp frontCompareOp = default)
{ {
_backfailop = backFailOp; _stencilTestEnable = stencilTestEnable;
_backpassop = backPassOp;
_backdepthfailop = backDepthFailOp;
_backcompareop = backCompareOp;
_frontfailop = frontFailOp; _dirty |= DirtyFlags.StencilTestEnable;
_frontpassop = frontPassOp;
_frontdepthfailop = frontDepthFailOp;
_frontcompareop = frontCompareOp;
_opToo = true;
} }
public void SetViewport(int index, Viewport viewport) public void SetViewport(int index, Viewport viewport)
{ {
Viewports[index] = viewport; Viewports[index] = viewport;
@ -192,6 +228,21 @@ namespace Ryujinx.Graphics.Vulkan
RecordFrontFace(api, commandBuffer); 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; _dirty = DirtyFlags.None;
} }
@ -231,6 +282,11 @@ namespace Ryujinx.Graphics.Vulkan
api.CmdSetStencilReference(commandBuffer, StencilFaceFlags.FaceFrontBit, _frontReference); 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) private void RecordViewport(Vk api, CommandBuffer commandBuffer)
{ {
if (ViewportsCount != 0) if (ViewportsCount != 0)
@ -248,5 +304,16 @@ namespace Ryujinx.Graphics.Vulkan
{ {
api.CmdSetFrontFace(commandBuffer, FrontFace); 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 var depthStencilState = new PipelineDepthStencilStateCreateInfo
{ {
SType = StructureType.PipelineDepthStencilStateCreateInfo, SType = StructureType.PipelineDepthStencilStateCreateInfo,
DepthTestEnable = DepthTestEnable,
DepthWriteEnable = DepthWriteEnable,
DepthCompareOp = DepthCompareOp,
DepthBoundsTestEnable = DepthBoundsTestEnable, DepthBoundsTestEnable = DepthBoundsTestEnable,
StencilTestEnable = StencilTestEnable,
MinDepthBounds = MinDepthBounds, MinDepthBounds = MinDepthBounds,
MaxDepthBounds = MaxDepthBounds, MaxDepthBounds = MaxDepthBounds,
}; };
@ -540,6 +536,10 @@ namespace Ryujinx.Graphics.Vulkan
depthStencilState.Front = stencilFront; depthStencilState.Front = stencilFront;
depthStencilState.Back = stencilBack; depthStencilState.Back = stencilBack;
depthStencilState.StencilTestEnable = StencilTestEnable;
depthStencilState.DepthTestEnable = DepthTestEnable;
depthStencilState.DepthWriteEnable = DepthWriteEnable;
depthStencilState.DepthCompareOp = DepthCompareOp;
} }
uint blendEnables = 0; uint blendEnables = 0;
@ -589,7 +589,7 @@ namespace Ryujinx.Graphics.Vulkan
colorBlendState.PNext = &colorBlendAdvancedState; colorBlendState.PNext = &colorBlendAdvancedState;
} }
int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 10 : 11) : 7; int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 14 : 15) : 7;
DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount]; DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount];
@ -609,6 +609,10 @@ namespace Ryujinx.Graphics.Vulkan
} }
dynamicStates[index++] = DynamicState.CullMode; dynamicStates[index++] = DynamicState.CullMode;
dynamicStates[index++] = DynamicState.FrontFace; dynamicStates[index++] = DynamicState.FrontFace;
dynamicStates[index++] = DynamicState.DepthTestEnable;
dynamicStates[index++] = DynamicState.DepthWriteEnable;
dynamicStates[index++] = DynamicState.DepthCompareOp;
dynamicStates[index++] = DynamicState.StencilTestEnable;
dynamicStates[index] = DynamicState.StencilOp; dynamicStates[index] = DynamicState.StencilOp;
} }