Enable VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT

This commit is contained in:
sunshineinabox 2024-05-19 00:24:07 -07:00
parent 863674768d
commit 5d5f482d57
3 changed files with 90 additions and 55 deletions

View file

@ -694,9 +694,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 = _supportExtDynamic ? DynamicState._stencilTestEnable : _newState.StencilTestEnable; var oldStencilTestEnable = _supportExtDynamic ? DynamicState.StencilTestEnable : _newState.StencilTestEnable;
var oldDepthTestEnable = _supportExtDynamic ? DynamicState._depthtestEnable : _newState.DepthTestEnable; var oldDepthTestEnable = _supportExtDynamic ? DynamicState.DepthTestEnable : _newState.DepthTestEnable;
var oldDepthWriteEnable = _supportExtDynamic ? DynamicState._depthwriteEnable : _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 = _supportExtDynamic ? DynamicState.ViewportsCount : _newState.ViewportsCount; var oldViewportsCount = _supportExtDynamic ? DynamicState.ViewportsCount : _newState.ViewportsCount;
@ -1082,7 +1082,43 @@ namespace Ryujinx.Graphics.Vulkan
public void SetPrimitiveRestart(bool enable, int index) public void SetPrimitiveRestart(bool enable, int index)
{ {
_newState.PrimitiveRestartEnable = enable; bool primitiveRestartEnable = enable;
bool topologySupportsRestart;
if (Gd.Capabilities.SupportsPrimitiveTopologyListRestart)
{
topologySupportsRestart = Gd.Capabilities.SupportsPrimitiveTopologyPatchListRestart ||
_newState.Topology != Silk.NET.Vulkan.PrimitiveTopology.PatchList;
}
else
{
topologySupportsRestart = _newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.LineStrip ||
_newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.TriangleStrip ||
_newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.TriangleFan ||
_newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.LineStripWithAdjacency ||
_newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.TriangleStripWithAdjacency;
}
primitiveRestartEnable &= topologySupportsRestart;
//Cannot disable primitveRestartEnable for these Topoligies on MacOS
if ((_newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.LineStrip || _newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.TriangleStrip ||
_newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.LineStripWithAdjacency ||
_newState.Topology == Silk.NET.Vulkan.PrimitiveTopology.TriangleStripWithAdjacency) && Gd.IsMoltenVk)
{
primitiveRestartEnable = true;
}
if (_supportExtDynamic2)
{
DynamicState.SetPrimitiveRestartEnable(primitiveRestartEnable);
}
else
{
_newState.PrimitiveRestartEnable = primitiveRestartEnable;
}
// TODO: What to do about the index? // TODO: What to do about the index?
SignalStateChange(); SignalStateChange();
} }

View file

@ -32,12 +32,12 @@ namespace Ryujinx.Graphics.Vulkan
private StencilOp _frontdepthfailop; private StencilOp _frontdepthfailop;
private CompareOp _frontcompareop; private CompareOp _frontcompareop;
private float _linewidth; private float _lineWidth;
public bool _stencilTestEnable; public bool StencilTestEnable;
public bool _depthtestEnable; public bool DepthTestEnable;
public bool _depthwriteEnable; public bool DepthWriteEnable;
private CompareOp _depthCompareOp; private CompareOp _depthCompareOp;
private Array4<float> _blendConstants; private Array4<float> _blendConstants;
@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Vulkan
public Array16<Viewport> Viewports; public Array16<Viewport> Viewports;
public CullModeFlags CullMode; public CullModeFlags CullMode;
public FrontFace FrontFace; private FrontFace _frontFace;
private bool _discard; private bool _discard;
@ -63,6 +63,8 @@ namespace Ryujinx.Graphics.Vulkan
public bool DepthMode; public bool DepthMode;
private bool _primitiveRestartEnable;
[Flags] [Flags]
private enum DirtyFlags private enum DirtyFlags
{ {
@ -86,9 +88,10 @@ namespace Ryujinx.Graphics.Vulkan
AlphaToOne = 1 << 16, AlphaToOne = 1 << 16,
PatchControlPoints = 1 << 17, PatchControlPoints = 1 << 17,
DepthMode = 1 << 18, DepthMode = 1 << 18,
PrimitiveRestart = 1 << 19,
Standard = Blend | DepthBias | Scissor | Stencil | Viewport | LineWidth, Standard = Blend | DepthBias | Scissor | Stencil | Viewport | LineWidth,
Extended = CullMode | FrontFace | DepthTestBool | DepthTestCompareOp | StencilTestEnable, Extended = CullMode | FrontFace | DepthTestBool | DepthTestCompareOp | StencilTestEnable,
Extended2 = RasterDiscard | LogicOp | PatchControlPoints, Extended2 = RasterDiscard | LogicOp | PatchControlPoints | PrimitiveRestart,
Extended3 = DepthClampEnable | LogicOpEnable | AlphaToCover | AlphaToOne | DepthMode, Extended3 = DepthClampEnable | LogicOpEnable | AlphaToCover | AlphaToOne | DepthMode,
} }
@ -142,10 +145,10 @@ namespace Ryujinx.Graphics.Vulkan
public void SetDepthTestBool(bool testEnable, bool writeEnable) public void SetDepthTestBool(bool testEnable, bool writeEnable)
{ {
if (_depthtestEnable != testEnable || _depthwriteEnable != writeEnable) if (DepthTestEnable != testEnable || DepthWriteEnable != writeEnable)
{ {
_depthtestEnable = testEnable; DepthTestEnable = testEnable;
_depthwriteEnable = writeEnable; DepthWriteEnable = writeEnable;
_dirty |= DirtyFlags.DepthTestBool; _dirty |= DirtyFlags.DepthTestBool;
} }
} }
@ -198,14 +201,13 @@ namespace Ryujinx.Graphics.Vulkan
public void SetStencilTest(bool stencilTestEnable) public void SetStencilTest(bool stencilTestEnable)
{ {
if (_stencilTestEnable != 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)) if (!Viewports[index].Equals(viewport))
@ -239,18 +241,18 @@ namespace Ryujinx.Graphics.Vulkan
public void SetFrontFace(FrontFace frontFace) public void SetFrontFace(FrontFace frontFace)
{ {
if (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)) if (!FloatCompare(_lineWidth, width))
{ {
_linewidth = width; _lineWidth = width;
_dirty |= DirtyFlags.LineWidth; _dirty |= DirtyFlags.LineWidth;
} }
@ -265,6 +267,15 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
public void SetPrimitiveRestartEnable(bool primitiveRestart)
{
if (_primitiveRestartEnable != primitiveRestart)
{
_primitiveRestartEnable = primitiveRestart;
_dirty |= DirtyFlags.PrimitiveRestart;
}
}
public void SetLogicOp(LogicOp op) public void SetLogicOp(LogicOp op)
{ {
if (_logicOp != op) if (_logicOp != op)
@ -450,6 +461,11 @@ namespace Ryujinx.Graphics.Vulkan
RecordRasterizationDiscard(gd, commandBuffer); RecordRasterizationDiscard(gd, commandBuffer);
} }
if (_dirty.HasFlag(DirtyFlags.PrimitiveRestart))
{
RecordPrimitiveRestartEnable(gd, commandBuffer);
}
if (_dirty.HasFlag(DirtyFlags.LogicOp)) if (_dirty.HasFlag(DirtyFlags.LogicOp))
{ {
RecordLogicOp(gd, commandBuffer); RecordLogicOp(gd, commandBuffer);
@ -528,7 +544,7 @@ namespace Ryujinx.Graphics.Vulkan
private readonly void RecordStencil(VulkanRenderer gd, CommandBuffer commandBuffer) private readonly void RecordStencil(VulkanRenderer gd, CommandBuffer commandBuffer)
{ {
if (_opToo && _stencilTestEnable) if (_opToo && StencilTestEnable)
{ {
gd.ExtendedDynamicStateApi.CmdSetStencilOp(commandBuffer, StencilFaceFlags.FaceBackBit, _backfailop, _backpassop, gd.ExtendedDynamicStateApi.CmdSetStencilOp(commandBuffer, StencilFaceFlags.FaceBackBit, _backfailop, _backpassop,
_backdepthfailop, _backcompareop); _backdepthfailop, _backcompareop);
@ -546,7 +562,7 @@ namespace Ryujinx.Graphics.Vulkan
private readonly void RecordStencilTestEnable(ExtExtendedDynamicState api, CommandBuffer commandBuffer) private readonly void RecordStencilTestEnable(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
{ {
api.CmdSetStencilTestEnable(commandBuffer, _stencilTestEnable); api.CmdSetStencilTestEnable(commandBuffer, StencilTestEnable);
} }
private void RecordViewport(VulkanRenderer gd, CommandBuffer commandBuffer) private void RecordViewport(VulkanRenderer gd, CommandBuffer commandBuffer)
@ -576,14 +592,14 @@ namespace Ryujinx.Graphics.Vulkan
private readonly void RecordFrontFace(ExtExtendedDynamicState api, CommandBuffer commandBuffer) private readonly void RecordFrontFace(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
{ {
api.CmdSetFrontFace(commandBuffer, FrontFace); api.CmdSetFrontFace(commandBuffer, _frontFace);
} }
private readonly void RecordDepthTestBool(ExtExtendedDynamicState api, CommandBuffer commandBuffer) private readonly void RecordDepthTestBool(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
{ {
api.CmdSetDepthTestEnable(commandBuffer, _depthtestEnable); api.CmdSetDepthTestEnable(commandBuffer, DepthTestEnable);
api.CmdSetDepthWriteEnable(commandBuffer, _depthwriteEnable); api.CmdSetDepthWriteEnable(commandBuffer, DepthWriteEnable);
} }
private readonly void RecordDepthTestCompareOp(ExtExtendedDynamicState api, CommandBuffer commandBuffer) private readonly void RecordDepthTestCompareOp(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
@ -596,6 +612,11 @@ namespace Ryujinx.Graphics.Vulkan
gd.ExtendedDynamicState2Api.CmdSetRasterizerDiscardEnable(commandBuffer, _discard); gd.ExtendedDynamicState2Api.CmdSetRasterizerDiscardEnable(commandBuffer, _discard);
} }
private readonly void RecordPrimitiveRestartEnable(VulkanRenderer gd, CommandBuffer commandBuffer)
{
gd.ExtendedDynamicState2Api.CmdSetPrimitiveRestartEnable(commandBuffer, _primitiveRestartEnable);
}
private readonly void RecordLogicOp(VulkanRenderer gd, CommandBuffer commandBuffer) private readonly void RecordLogicOp(VulkanRenderer gd, CommandBuffer commandBuffer)
{ {
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3LogicOpEnable && !_logicOpEnable) if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3LogicOpEnable && !_logicOpEnable)
@ -640,7 +661,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
if (!OperatingSystem.IsMacOS()) if (!OperatingSystem.IsMacOS())
{ {
api.CmdSetLineWidth(commandBuffer, _linewidth); api.CmdSetLineWidth(commandBuffer, _lineWidth);
} }
} }
} }

View file

@ -432,40 +432,17 @@ namespace Ryujinx.Graphics.Vulkan
return null; return null;
} }
bool primitiveRestartEnable = PrimitiveRestartEnable;
bool topologySupportsRestart;
if (gd.Capabilities.SupportsPrimitiveTopologyListRestart)
{
topologySupportsRestart = gd.Capabilities.SupportsPrimitiveTopologyPatchListRestart || Topology != PrimitiveTopology.PatchList;
}
else
{
topologySupportsRestart = Topology == PrimitiveTopology.LineStrip ||
Topology == PrimitiveTopology.TriangleStrip ||
Topology == PrimitiveTopology.TriangleFan ||
Topology == PrimitiveTopology.LineStripWithAdjacency ||
Topology == PrimitiveTopology.TriangleStripWithAdjacency;
}
primitiveRestartEnable &= topologySupportsRestart;
//Cannot disable primitveRestartEnable for these Topoligies on MacOS
if ((Topology == PrimitiveTopology.LineStrip || Topology == PrimitiveTopology.TriangleStrip ||
Topology == PrimitiveTopology.LineStripWithAdjacency ||
Topology == PrimitiveTopology.TriangleStripWithAdjacency) && isMoltenVk)
{
primitiveRestartEnable = true;
}
var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo
{ {
SType = StructureType.PipelineInputAssemblyStateCreateInfo, SType = StructureType.PipelineInputAssemblyStateCreateInfo,
PrimitiveRestartEnable = primitiveRestartEnable,
Topology = Topology, Topology = Topology,
}; };
if (!supportsExtDynamicState)
{
inputAssemblyState.PrimitiveRestartEnable = PrimitiveRestartEnable;
}
var tessellationState = new PipelineTessellationStateCreateInfo var tessellationState = new PipelineTessellationStateCreateInfo
{ {
SType = StructureType.PipelineTessellationStateCreateInfo, SType = StructureType.PipelineTessellationStateCreateInfo,
@ -631,7 +608,7 @@ namespace Ryujinx.Graphics.Vulkan
if (supportsExtDynamicState2) if (supportsExtDynamicState2)
{ {
additionalDynamicStatesCount += 2; additionalDynamicStatesCount += 3;
if (gd.ExtendedDynamicState2Features.ExtendedDynamicState2LogicOp) if (gd.ExtendedDynamicState2Features.ExtendedDynamicState2LogicOp)
{ {
additionalDynamicStatesCount++; additionalDynamicStatesCount++;
@ -703,6 +680,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
dynamicStates[currentIndex++] = DynamicState.DepthBiasEnableExt; dynamicStates[currentIndex++] = DynamicState.DepthBiasEnableExt;
dynamicStates[currentIndex++] = DynamicState.RasterizerDiscardEnableExt; dynamicStates[currentIndex++] = DynamicState.RasterizerDiscardEnableExt;
dynamicStates[currentIndex++] = DynamicState.PrimitiveRestartEnableExt;
if (gd.ExtendedDynamicState2Features.ExtendedDynamicState2LogicOp) if (gd.ExtendedDynamicState2Features.ExtendedDynamicState2LogicOp)
{ {