Attempt proper VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY implementation

This commit is contained in:
sunshineinabox 2024-05-26 22:08:14 -07:00
parent 4b504243d8
commit 7ac2cd44d0
3 changed files with 64 additions and 8 deletions

View file

@ -696,7 +696,7 @@ namespace Ryujinx.Graphics.Vulkan
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 = _supportExtDynamic ? DynamicState.Topology : _newState.Topology;
var oldViewports = DynamicState.Viewports; var oldViewports = DynamicState.Viewports;
var oldViewportsCount = _supportExtDynamic ? DynamicState.ViewportsCount : _newState.ViewportsCount; var oldViewportsCount = _supportExtDynamic ? DynamicState.ViewportsCount : _newState.ViewportsCount;
@ -729,6 +729,7 @@ namespace Ryujinx.Graphics.Vulkan
DynamicState.SetCullMode(oldCullMode); DynamicState.SetCullMode(oldCullMode);
DynamicState.SetStencilTest(oldStencilTestEnable); DynamicState.SetStencilTest(oldStencilTestEnable);
DynamicState.SetDepthTestBool(oldDepthTestEnable, oldDepthWriteEnable); DynamicState.SetDepthTestBool(oldDepthTestEnable, oldDepthWriteEnable);
DynamicState.SetPrimitiveTopology(oldTopology);
} }
else else
{ {
@ -737,10 +738,9 @@ namespace Ryujinx.Graphics.Vulkan
_newState.DepthTestEnable = oldDepthTestEnable; _newState.DepthTestEnable = oldDepthTestEnable;
_newState.DepthWriteEnable = oldDepthWriteEnable; _newState.DepthWriteEnable = oldDepthWriteEnable;
_newState.ViewportsCount = oldViewportsCount; _newState.ViewportsCount = oldViewportsCount;
_newState.Topology = oldTopology;
} }
_newState.Topology = oldTopology;
DynamicState.SetViewports(ref oldViewports, oldViewportsCount); DynamicState.SetViewports(ref oldViewports, oldViewportsCount);
SignalStateChange(); SignalStateChange();
@ -1094,11 +1094,52 @@ namespace Ryujinx.Graphics.Vulkan
var vkTopology = Gd.TopologyRemap(topology).Convert(); var vkTopology = Gd.TopologyRemap(topology).Convert();
_newState.Topology = vkTopology; var currentTopologyClass = GetTopologyClass(_newState.Topology);
var newTopologyClass = GetTopologyClass(vkTopology);
if (_supportExtDynamic)
{
DynamicState.SetPrimitiveTopology(vkTopology);
if (currentTopologyClass != newTopologyClass)
{
_newState.Topology = vkTopology;
}
}
else
{
_newState.Topology = vkTopology;
}
SignalStateChange(); SignalStateChange();
} }
private TopologyClass GetTopologyClass(Silk.NET.Vulkan.PrimitiveTopology topology)
{
return topology switch
{
Silk.NET.Vulkan.PrimitiveTopology.PointList => TopologyClass.Point,
Silk.NET.Vulkan.PrimitiveTopology.LineList => TopologyClass.Line,
Silk.NET.Vulkan.PrimitiveTopology.LineStrip => TopologyClass.Line,
Silk.NET.Vulkan.PrimitiveTopology.LineListWithAdjacency => TopologyClass.Line,
Silk.NET.Vulkan.PrimitiveTopology.LineStripWithAdjacency => TopologyClass.Line,
Silk.NET.Vulkan.PrimitiveTopology.TriangleList => TopologyClass.Triangle,
Silk.NET.Vulkan.PrimitiveTopology.TriangleStrip => TopologyClass.Triangle,
Silk.NET.Vulkan.PrimitiveTopology.TriangleFan => TopologyClass.Triangle,
Silk.NET.Vulkan.PrimitiveTopology.TriangleListWithAdjacency => TopologyClass.Triangle,
Silk.NET.Vulkan.PrimitiveTopology.TriangleStripWithAdjacency => TopologyClass.Triangle,
Silk.NET.Vulkan.PrimitiveTopology.PatchList => TopologyClass.Patch,
_ => throw new ArgumentOutOfRangeException(nameof(topology), topology, null)
};
}
private enum TopologyClass
{
Point,
Line,
Triangle,
Patch
}
public void SetProgram(IProgram program) public void SetProgram(IProgram program)
{ {
var internalProgram = (ShaderCollection)program; var internalProgram = (ShaderCollection)program;

View file

@ -54,6 +54,8 @@ namespace Ryujinx.Graphics.Vulkan
private uint _patchControlPoints; private uint _patchControlPoints;
public PrimitiveTopology Topology;
private bool _primitiveRestartEnable; private bool _primitiveRestartEnable;
[Flags] [Flags]
@ -75,8 +77,9 @@ namespace Ryujinx.Graphics.Vulkan
LogicOp = 1 << 12, LogicOp = 1 << 12,
PatchControlPoints = 1 << 13, PatchControlPoints = 1 << 13,
PrimitiveRestart = 1 << 14, PrimitiveRestart = 1 << 14,
PrimitiveTopology = 1 << 15,
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 | PrimitiveTopology,
Extended2 = RasterDiscard | LogicOp | PatchControlPoints | PrimitiveRestart, Extended2 = RasterDiscard | LogicOp | PatchControlPoints | PrimitiveRestart,
} }
@ -203,6 +206,12 @@ namespace Ryujinx.Graphics.Vulkan
_dirty |= DirtyFlags.PrimitiveRestart; _dirty |= DirtyFlags.PrimitiveRestart;
} }
public void SetPrimitiveTopology(PrimitiveTopology primitiveTopology)
{
Topology = primitiveTopology;
_dirty |= DirtyFlags.PrimitiveTopology;
}
public void SetLogicOp(LogicOp op) public void SetLogicOp(LogicOp op)
{ {
_logicOp = op; _logicOp = op;
@ -312,9 +321,9 @@ namespace Ryujinx.Graphics.Vulkan
RecordPrimitiveRestartEnable(gd, commandBuffer); RecordPrimitiveRestartEnable(gd, commandBuffer);
} }
if (_dirty.HasFlag(DirtyFlags.PrimitiveRestart)) if (_dirty.HasFlag(DirtyFlags.PrimitiveTopology))
{ {
RecordPrimitiveRestartEnable(gd, commandBuffer); RecordPrimitiveTopology(gd, commandBuffer);
} }
if (_dirty.HasFlag(DirtyFlags.LogicOp)) if (_dirty.HasFlag(DirtyFlags.LogicOp))
@ -443,6 +452,11 @@ namespace Ryujinx.Graphics.Vulkan
gd.ExtendedDynamicState2Api.CmdSetPrimitiveRestartEnable(commandBuffer, _primitiveRestartEnable); gd.ExtendedDynamicState2Api.CmdSetPrimitiveRestartEnable(commandBuffer, _primitiveRestartEnable);
} }
private readonly void RecordPrimitiveTopology(VulkanRenderer gd, CommandBuffer commandBuffer)
{
gd.ExtendedDynamicStateApi.CmdSetPrimitiveTopology(commandBuffer, Topology);
}
private readonly void RecordLogicOp(VulkanRenderer gd, CommandBuffer commandBuffer) private readonly void RecordLogicOp(VulkanRenderer gd, CommandBuffer commandBuffer)
{ {
gd.ExtendedDynamicState2Api.CmdSetLogicOp(commandBuffer, _logicOp); gd.ExtendedDynamicState2Api.CmdSetLogicOp(commandBuffer, _logicOp);

View file

@ -592,7 +592,7 @@ namespace Ryujinx.Graphics.Vulkan
if (supportsExtDynamicState) if (supportsExtDynamicState)
{ {
additionalDynamicStatesCount += isMoltenVk ? 7 : 8; additionalDynamicStatesCount += isMoltenVk ? 8 : 9;
} }
if (supportsExtDynamicState2) if (supportsExtDynamicState2)
@ -643,6 +643,7 @@ namespace Ryujinx.Graphics.Vulkan
dynamicStates[currentIndex++] = DynamicState.DepthCompareOpExt; dynamicStates[currentIndex++] = DynamicState.DepthCompareOpExt;
dynamicStates[currentIndex++] = DynamicState.StencilTestEnableExt; dynamicStates[currentIndex++] = DynamicState.StencilTestEnableExt;
dynamicStates[currentIndex++] = DynamicState.StencilOpExt; dynamicStates[currentIndex++] = DynamicState.StencilOpExt;
dynamicStates[currentIndex++] = DynamicState.PrimitiveTopologyExt;
} }
if (supportsExtDynamicState2) if (supportsExtDynamicState2)