More Dynamic States
This commit is contained in:
parent
4933888a9d
commit
5f02e28017
3 changed files with 125 additions and 40 deletions
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue