mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-12-27 13:16:00 +00:00
Implement VK_EXT_extended_dynamic_state3
This commit is contained in:
parent
d5f9ed6a2e
commit
9d8070f20f
7 changed files with 323 additions and 43 deletions
|
@ -39,9 +39,9 @@
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />
|
<PackageVersion Include="Silk.NET.Vulkan" Version="2.21.0" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.16.0" />
|
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.21.0" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.16.0" />
|
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.21.0" />
|
||||||
<PackageVersion Include="SixLabors.ImageSharp" Version="2.1.8" />
|
<PackageVersion Include="SixLabors.ImageSharp" Version="2.1.8" />
|
||||||
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0" />
|
<PackageVersion Include="SixLabors.ImageSharp.Drawing" Version="1.0.0" />
|
||||||
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
||||||
|
@ -49,4 +49,4 @@
|
||||||
<PackageVersion Include="System.Management" Version="8.0.0" />
|
<PackageVersion Include="System.Management" Version="8.0.0" />
|
||||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -32,6 +32,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public readonly bool SupportsConditionalRendering;
|
public readonly bool SupportsConditionalRendering;
|
||||||
public readonly bool SupportsExtendedDynamicState;
|
public readonly bool SupportsExtendedDynamicState;
|
||||||
public readonly bool SupportsExtendedDynamicState2;
|
public readonly bool SupportsExtendedDynamicState2;
|
||||||
|
public readonly bool SupportsExtendedDynamicState3;
|
||||||
public readonly bool SupportsMultiView;
|
public readonly bool SupportsMultiView;
|
||||||
public readonly bool SupportsNullDescriptors;
|
public readonly bool SupportsNullDescriptors;
|
||||||
public readonly bool SupportsPushDescriptors;
|
public readonly bool SupportsPushDescriptors;
|
||||||
|
@ -72,6 +73,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
bool supportsConditionalRendering,
|
bool supportsConditionalRendering,
|
||||||
bool supportsExtendedDynamicState,
|
bool supportsExtendedDynamicState,
|
||||||
bool supportsExtendedDynamicState2,
|
bool supportsExtendedDynamicState2,
|
||||||
|
bool supportsExtendedDynamicState3,
|
||||||
bool supportsMultiView,
|
bool supportsMultiView,
|
||||||
bool supportsNullDescriptors,
|
bool supportsNullDescriptors,
|
||||||
bool supportsPushDescriptors,
|
bool supportsPushDescriptors,
|
||||||
|
@ -111,6 +113,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SupportsConditionalRendering = supportsConditionalRendering;
|
SupportsConditionalRendering = supportsConditionalRendering;
|
||||||
SupportsExtendedDynamicState = supportsExtendedDynamicState;
|
SupportsExtendedDynamicState = supportsExtendedDynamicState;
|
||||||
SupportsExtendedDynamicState2 = supportsExtendedDynamicState2;
|
SupportsExtendedDynamicState2 = supportsExtendedDynamicState2;
|
||||||
|
SupportsExtendedDynamicState3 = supportsExtendedDynamicState3;
|
||||||
SupportsMultiView = supportsMultiView;
|
SupportsMultiView = supportsMultiView;
|
||||||
SupportsNullDescriptors = supportsNullDescriptors;
|
SupportsNullDescriptors = supportsNullDescriptors;
|
||||||
SupportsPushDescriptors = supportsPushDescriptors;
|
SupportsPushDescriptors = supportsPushDescriptors;
|
||||||
|
|
|
@ -886,7 +886,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public void SetDepthClamp(bool clamp)
|
public void SetDepthClamp(bool clamp)
|
||||||
{
|
{
|
||||||
_newState.DepthClampEnable = clamp;
|
if (Gd.ExtendedDynamicState3Features.ExtendedDynamicState3DepthClampEnable)
|
||||||
|
{
|
||||||
|
DynamicState.SetDepthClampEnable(clamp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_newState.DepthClampEnable = clamp;
|
||||||
|
}
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -986,7 +994,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public void SetLogicOpState(bool enable, LogicalOp op)
|
public void SetLogicOpState(bool enable, LogicalOp op)
|
||||||
{
|
{
|
||||||
if (_supportExtDynamic2 && Gd.ExtendedLogicOp)
|
if (Gd.ExtendedDynamicState2Features.ExtendedDynamicState2LogicOp)
|
||||||
{
|
{
|
||||||
DynamicState.SetLogicOp(op.Convert());
|
DynamicState.SetLogicOp(op.Convert());
|
||||||
}
|
}
|
||||||
|
@ -995,21 +1003,53 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_newState.LogicOp = op.Convert();
|
_newState.LogicOp = op.Convert();
|
||||||
}
|
}
|
||||||
|
|
||||||
_newState.LogicOpEnable = enable;
|
if (Gd.ExtendedDynamicState3Features.ExtendedDynamicState3LogicOpEnable)
|
||||||
|
{
|
||||||
|
DynamicState.SetLogicOpEnable(enable);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_newState.LogicOpEnable = enable;
|
||||||
|
}
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMultisampleState(MultisampleDescriptor multisample)
|
public void SetMultisampleState(MultisampleDescriptor multisample)
|
||||||
{
|
{
|
||||||
_newState.AlphaToCoverageEnable = multisample.AlphaToCoverageEnable;
|
if (Gd.ExtendedDynamicState3Features.ExtendedDynamicState3AlphaToCoverageEnable)
|
||||||
_newState.AlphaToOneEnable = multisample.AlphaToOneEnable;
|
{
|
||||||
|
DynamicState.SetAlphaToCoverEnable(multisample.AlphaToCoverageEnable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_newState.AlphaToCoverageEnable = multisample.AlphaToCoverageEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Gd.ExtendedDynamicState3Features.ExtendedDynamicState3AlphaToOneEnable)
|
||||||
|
{
|
||||||
|
DynamicState.SetAlphaToOneEnable(multisample.AlphaToOneEnable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_newState.AlphaToOneEnable = multisample.AlphaToOneEnable;
|
||||||
|
}
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPatchParameters(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
|
public void SetPatchParameters(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
|
||||||
{
|
{
|
||||||
_newState.PatchControlPoints = (uint)vertices;
|
if (Gd.ExtendedDynamicState2Features.ExtendedDynamicState2PatchControlPoints)
|
||||||
|
{
|
||||||
|
DynamicState.SetPatchControlPoints((uint)vertices);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_newState.PatchControlPoints = (uint)vertices;
|
||||||
|
}
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
|
|
||||||
// TODO: Default levels (likely needs emulation on shaders?)
|
// TODO: Default levels (likely needs emulation on shaders?)
|
||||||
|
|
|
@ -52,6 +52,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private LogicOp _logicOp;
|
private LogicOp _logicOp;
|
||||||
|
|
||||||
|
private uint _patchControlPoints;
|
||||||
|
|
||||||
|
private bool _logicOpEnable;
|
||||||
|
|
||||||
|
private bool _depthClampEnable;
|
||||||
|
|
||||||
|
private bool _alphaToCoverEnable;
|
||||||
|
private bool _alphaToOneEnable;
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum DirtyFlags
|
private enum DirtyFlags
|
||||||
{
|
{
|
||||||
|
@ -69,9 +78,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
LineWidth = 1 << 10,
|
LineWidth = 1 << 10,
|
||||||
RasterDiscard = 1 << 11,
|
RasterDiscard = 1 << 11,
|
||||||
LogicOp = 1 << 12,
|
LogicOp = 1 << 12,
|
||||||
|
DepthClampEnable = 1 << 13,
|
||||||
|
LogicOpEnalbe = 1 << 14,
|
||||||
|
AlphaToCover = 1 << 15,
|
||||||
|
AlphaToOne = 1 << 16,
|
||||||
|
PatchControlPoints = 1 << 17,
|
||||||
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,
|
Extended2 = RasterDiscard | LogicOp | PatchControlPoints,
|
||||||
}
|
}
|
||||||
|
|
||||||
private DirtyFlags _dirty;
|
private DirtyFlags _dirty;
|
||||||
|
@ -219,6 +233,41 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_dirty |= DirtyFlags.LogicOp;
|
_dirty |= DirtyFlags.LogicOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetPatchControlPoints(uint points)
|
||||||
|
{
|
||||||
|
_patchControlPoints = points;
|
||||||
|
|
||||||
|
_dirty |= DirtyFlags.PatchControlPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetLogicOpEnable(bool logicOpEnable)
|
||||||
|
{
|
||||||
|
_logicOpEnable = logicOpEnable;
|
||||||
|
|
||||||
|
_dirty |= DirtyFlags.LogicOpEnalbe;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetDepthClampEnable(bool depthClampEnable)
|
||||||
|
{
|
||||||
|
_depthClampEnable = depthClampEnable;
|
||||||
|
|
||||||
|
_dirty |= DirtyFlags.DepthClampEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAlphaToCoverEnable(bool alphaToCoverEnable)
|
||||||
|
{
|
||||||
|
_alphaToCoverEnable = alphaToCoverEnable;
|
||||||
|
|
||||||
|
_dirty |= DirtyFlags.AlphaToCover;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAlphaToOneEnable(bool alphaToOneEnable)
|
||||||
|
{
|
||||||
|
_alphaToOneEnable = alphaToOneEnable;
|
||||||
|
|
||||||
|
_dirty |= DirtyFlags.AlphaToOne;
|
||||||
|
}
|
||||||
|
|
||||||
public void ForceAllDirty(VulkanRenderer gd)
|
public void ForceAllDirty(VulkanRenderer gd)
|
||||||
{
|
{
|
||||||
_dirty = DirtyFlags.Standard;
|
_dirty = DirtyFlags.Standard;
|
||||||
|
@ -238,10 +287,35 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_dirty &= ~DirtyFlags.LineWidth;
|
_dirty &= ~DirtyFlags.LineWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gd.ExtendedLogicOp)
|
if (!gd.ExtendedDynamicState2Features.ExtendedDynamicState2LogicOp)
|
||||||
{
|
{
|
||||||
_dirty &= ~DirtyFlags.LogicOp;
|
_dirty &= ~DirtyFlags.LogicOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gd.ExtendedDynamicState2Features.ExtendedDynamicState2PatchControlPoints)
|
||||||
|
{
|
||||||
|
_dirty &= ~DirtyFlags.LogicOp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3AlphaToCoverageEnable)
|
||||||
|
{
|
||||||
|
_dirty = DirtyFlags.AlphaToCover;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3AlphaToOneEnable)
|
||||||
|
{
|
||||||
|
_dirty = DirtyFlags.AlphaToOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3DepthClampEnable)
|
||||||
|
{
|
||||||
|
_dirty = DirtyFlags.DepthClampEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3LogicOpEnable)
|
||||||
|
{
|
||||||
|
_dirty = DirtyFlags.LogicOpEnalbe;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReplayIfDirty(VulkanRenderer gd, CommandBuffer commandBuffer)
|
public void ReplayIfDirty(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
|
@ -306,11 +380,36 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
RecordRasterizationDiscard(gd, commandBuffer);
|
RecordRasterizationDiscard(gd, commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_dirty.HasFlag(DirtyFlags.RasterDiscard))
|
if (_dirty.HasFlag(DirtyFlags.LogicOp))
|
||||||
{
|
{
|
||||||
RecordLogicOp(gd, commandBuffer);
|
RecordLogicOp(gd, commandBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_dirty.HasFlag(DirtyFlags.PatchControlPoints))
|
||||||
|
{
|
||||||
|
RecordPatchControlPoints(gd, commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_dirty.HasFlag(DirtyFlags.LogicOpEnalbe))
|
||||||
|
{
|
||||||
|
RecordLogicOpEnable(gd, commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_dirty.HasFlag(DirtyFlags.DepthClampEnable))
|
||||||
|
{
|
||||||
|
RecordDepthClampEnable(gd, commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_dirty.HasFlag(DirtyFlags.AlphaToCover))
|
||||||
|
{
|
||||||
|
RecordAlphaToCoverEnable(gd, commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_dirty.HasFlag(DirtyFlags.AlphaToOne))
|
||||||
|
{
|
||||||
|
RecordAlphaToOneEnable(gd, commandBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
_dirty = DirtyFlags.None;
|
_dirty = DirtyFlags.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,6 +520,31 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
gd.ExtendedDynamicState2Api.CmdSetLogicOp(commandBuffer, _logicOp);
|
gd.ExtendedDynamicState2Api.CmdSetLogicOp(commandBuffer, _logicOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly void RecordLogicOpEnable(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
|
{
|
||||||
|
gd.ExtendedDynamicState3Api.CmdSetLogicOpEnable(commandBuffer, _logicOpEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly void RecordDepthClampEnable(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
|
{
|
||||||
|
gd.ExtendedDynamicState3Api.CmdSetDepthClampEnable(commandBuffer, _depthClampEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly void RecordAlphaToCoverEnable(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
|
{
|
||||||
|
gd.ExtendedDynamicState3Api.CmdSetAlphaToCoverageEnable(commandBuffer, _alphaToCoverEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly void RecordAlphaToOneEnable(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
|
{
|
||||||
|
gd.ExtendedDynamicState3Api.CmdSetAlphaToOneEnable(commandBuffer, _alphaToOneEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly void RecordPatchControlPoints(VulkanRenderer gd, CommandBuffer commandBuffer)
|
||||||
|
{
|
||||||
|
gd.ExtendedDynamicState2Api.CmdSetPatchControlPoints(commandBuffer, _patchControlPoints);
|
||||||
|
}
|
||||||
|
|
||||||
private readonly void RecordLineWidth(Vk api, CommandBuffer commandBuffer)
|
private readonly void RecordLineWidth(Vk api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
if (!OperatingSystem.IsMacOS())
|
if (!OperatingSystem.IsMacOS())
|
||||||
|
|
|
@ -407,6 +407,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
|
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
|
||||||
bool supportsExtDynamicState2 = gd.Capabilities.SupportsExtendedDynamicState2;
|
bool supportsExtDynamicState2 = gd.Capabilities.SupportsExtendedDynamicState2;
|
||||||
|
bool supportsExtDynamicState3 = gd.Capabilities.SupportsExtendedDynamicState3;
|
||||||
|
|
||||||
|
|
||||||
fixed (VertexInputAttributeDescription* pVertexAttributeDescriptions = &Internal.VertexAttributeDescriptions[0])
|
fixed (VertexInputAttributeDescription* pVertexAttributeDescriptions = &Internal.VertexAttributeDescriptions[0])
|
||||||
|
@ -468,16 +469,24 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
var tessellationState = new PipelineTessellationStateCreateInfo
|
var tessellationState = new PipelineTessellationStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineTessellationStateCreateInfo,
|
SType = StructureType.PipelineTessellationStateCreateInfo,
|
||||||
PatchControlPoints = PatchControlPoints,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!gd.ExtendedDynamicState2Features.ExtendedDynamicState2PatchControlPoints)
|
||||||
|
{
|
||||||
|
tessellationState.PatchControlPoints = PatchControlPoints;
|
||||||
|
}
|
||||||
|
|
||||||
var rasterizationState = new PipelineRasterizationStateCreateInfo
|
var rasterizationState = new PipelineRasterizationStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineRasterizationStateCreateInfo,
|
SType = StructureType.PipelineRasterizationStateCreateInfo,
|
||||||
DepthClampEnable = DepthClampEnable,
|
|
||||||
PolygonMode = PolygonMode,
|
PolygonMode = PolygonMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!gd.ExtendedDynamicState3Features.ExtendedDynamicState3DepthClampEnable)
|
||||||
|
{
|
||||||
|
rasterizationState.DepthClampEnable = DepthClampEnable;
|
||||||
|
}
|
||||||
|
|
||||||
if (isMoltenVk)
|
if (isMoltenVk)
|
||||||
{
|
{
|
||||||
rasterizationState.LineWidth = 1.0f;
|
rasterizationState.LineWidth = 1.0f;
|
||||||
|
@ -523,10 +532,18 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SampleShadingEnable = false,
|
SampleShadingEnable = false,
|
||||||
RasterizationSamples = TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, SamplesCount),
|
RasterizationSamples = TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, SamplesCount),
|
||||||
MinSampleShading = 1,
|
MinSampleShading = 1,
|
||||||
AlphaToCoverageEnable = AlphaToCoverageEnable,
|
|
||||||
AlphaToOneEnable = AlphaToOneEnable,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!gd.ExtendedDynamicState3Features.ExtendedDynamicState3AlphaToCoverageEnable)
|
||||||
|
{
|
||||||
|
multisampleState.AlphaToCoverageEnable = AlphaToCoverageEnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gd.ExtendedDynamicState3Features.ExtendedDynamicState3AlphaToOneEnable)
|
||||||
|
{
|
||||||
|
multisampleState.AlphaToOneEnable = AlphaToOneEnable;
|
||||||
|
}
|
||||||
|
|
||||||
var depthStencilState = new PipelineDepthStencilStateCreateInfo
|
var depthStencilState = new PipelineDepthStencilStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineDepthStencilStateCreateInfo,
|
SType = StructureType.PipelineDepthStencilStateCreateInfo,
|
||||||
|
@ -541,19 +558,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
StencilFrontFailOp,
|
StencilFrontFailOp,
|
||||||
StencilFrontPassOp,
|
StencilFrontPassOp,
|
||||||
StencilFrontDepthFailOp,
|
StencilFrontDepthFailOp,
|
||||||
StencilFrontCompareOp,
|
StencilFrontCompareOp);
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null);
|
|
||||||
|
|
||||||
var stencilBack = new StencilOpState(
|
var stencilBack = new StencilOpState(
|
||||||
StencilBackFailOp,
|
StencilBackFailOp,
|
||||||
StencilBackPassOp,
|
StencilBackPassOp,
|
||||||
StencilBackDepthFailOp,
|
StencilBackDepthFailOp,
|
||||||
StencilBackCompareOp,
|
StencilBackCompareOp);
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null);
|
|
||||||
|
|
||||||
depthStencilState.Front = stencilFront;
|
depthStencilState.Front = stencilFront;
|
||||||
depthStencilState.Back = stencilBack;
|
depthStencilState.Back = stencilBack;
|
||||||
|
@ -587,16 +598,20 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
var colorBlendState = new PipelineColorBlendStateCreateInfo
|
var colorBlendState = new PipelineColorBlendStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineColorBlendStateCreateInfo,
|
SType = StructureType.PipelineColorBlendStateCreateInfo,
|
||||||
LogicOpEnable = LogicOpEnable,
|
|
||||||
AttachmentCount = ColorBlendAttachmentStateCount,
|
AttachmentCount = ColorBlendAttachmentStateCount,
|
||||||
PAttachments = pColorBlendAttachmentState,
|
PAttachments = pColorBlendAttachmentState,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!(supportsExtDynamicState2 && gd.ExtendedLogicOp))
|
if (!gd.ExtendedDynamicState2Features.ExtendedDynamicState2LogicOp)
|
||||||
{
|
{
|
||||||
colorBlendState.LogicOp = LogicOp;
|
colorBlendState.LogicOp = LogicOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gd.ExtendedDynamicState3Features.ExtendedDynamicState3LogicOpEnable)
|
||||||
|
{
|
||||||
|
colorBlendState.LogicOpEnable = LogicOpEnable;
|
||||||
|
}
|
||||||
|
|
||||||
PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
|
PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
|
||||||
|
|
||||||
if (!AdvancedBlendSrcPreMultiplied ||
|
if (!AdvancedBlendSrcPreMultiplied ||
|
||||||
|
@ -624,13 +639,37 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (supportsExtDynamicState)
|
if (supportsExtDynamicState)
|
||||||
{
|
{
|
||||||
additionalDynamicStatesCount += isMoltenVk ? 11 : 12;
|
additionalDynamicStatesCount += isMoltenVk ? 10 : 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (supportsExtDynamicState2)
|
if (supportsExtDynamicState2)
|
||||||
{
|
{
|
||||||
additionalDynamicStatesCount += 2;
|
additionalDynamicStatesCount += 2;
|
||||||
if (gd.ExtendedLogicOp)
|
if (gd.ExtendedDynamicState2Features.ExtendedDynamicState2LogicOp)
|
||||||
|
{
|
||||||
|
additionalDynamicStatesCount++;
|
||||||
|
}
|
||||||
|
if (gd.ExtendedDynamicState2Features.ExtendedDynamicState2PatchControlPoints)
|
||||||
|
{
|
||||||
|
additionalDynamicStatesCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportsExtDynamicState3)
|
||||||
|
{
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3DepthClampEnable)
|
||||||
|
{
|
||||||
|
additionalDynamicStatesCount++;
|
||||||
|
}
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3LogicOpEnable)
|
||||||
|
{
|
||||||
|
additionalDynamicStatesCount++;
|
||||||
|
}
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3AlphaToCoverageEnable)
|
||||||
|
{
|
||||||
|
additionalDynamicStatesCount++;
|
||||||
|
}
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3AlphaToOneEnable)
|
||||||
{
|
{
|
||||||
additionalDynamicStatesCount++;
|
additionalDynamicStatesCount++;
|
||||||
}
|
}
|
||||||
|
@ -676,10 +715,34 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
dynamicStates[currentIndex++] = DynamicState.DepthBiasEnableExt;
|
dynamicStates[currentIndex++] = DynamicState.DepthBiasEnableExt;
|
||||||
dynamicStates[currentIndex++] = DynamicState.RasterizerDiscardEnableExt;
|
dynamicStates[currentIndex++] = DynamicState.RasterizerDiscardEnableExt;
|
||||||
|
|
||||||
if (gd.ExtendedLogicOp)
|
if (gd.ExtendedDynamicState2Features.ExtendedDynamicState2LogicOp)
|
||||||
{
|
{
|
||||||
dynamicStates[currentIndex++] = DynamicState.LogicOpExt;
|
dynamicStates[currentIndex++] = DynamicState.LogicOpExt;
|
||||||
}
|
}
|
||||||
|
if (gd.ExtendedDynamicState2Features.ExtendedDynamicState2PatchControlPoints)
|
||||||
|
{
|
||||||
|
dynamicStates[currentIndex++] = DynamicState.PatchControlPointsExt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportsExtDynamicState3)
|
||||||
|
{
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3DepthClampEnable)
|
||||||
|
{
|
||||||
|
dynamicStates[currentIndex++] = DynamicState.DepthClampEnableExt;
|
||||||
|
}
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3LogicOpEnable)
|
||||||
|
{
|
||||||
|
dynamicStates[currentIndex++] = DynamicState.LogicOpEnableExt;
|
||||||
|
}
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3AlphaToCoverageEnable)
|
||||||
|
{
|
||||||
|
dynamicStates[currentIndex++] = DynamicState.AlphaToCoverageEnableExt;
|
||||||
|
}
|
||||||
|
if (gd.ExtendedDynamicState3Features.ExtendedDynamicState3AlphaToOneEnable)
|
||||||
|
{
|
||||||
|
dynamicStates[currentIndex++] = DynamicState.AlphaToOneEnableExt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
|
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
|
||||||
|
@ -689,6 +752,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PDynamicStates = dynamicStates,
|
PDynamicStates = dynamicStates,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var pipelineCreateInfo = new GraphicsPipelineCreateInfo
|
var pipelineCreateInfo = new GraphicsPipelineCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.GraphicsPipelineCreateInfo,
|
SType = StructureType.GraphicsPipelineCreateInfo,
|
||||||
|
|
|
@ -263,7 +263,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return InvalidIndex;
|
return InvalidIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static Device CreateDevice(Vk api, VulkanPhysicalDevice physicalDevice, uint queueFamilyIndex, uint queueCount, out bool extendedLogicOp)
|
internal static Device CreateDevice(Vk api, VulkanPhysicalDevice physicalDevice, uint queueFamilyIndex, uint queueCount, out PhysicalDeviceExtendedDynamicState2FeaturesEXT extendedDynamicState2Features, out PhysicalDeviceExtendedDynamicState3FeaturesEXT extendedDynamicState3Features)
|
||||||
{
|
{
|
||||||
if (queueCount > QueuesCount)
|
if (queueCount > QueuesCount)
|
||||||
{
|
{
|
||||||
|
@ -322,6 +322,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
features2.PNext = &supportedFeaturesExtExtendedDynamicState2;
|
features2.PNext = &supportedFeaturesExtExtendedDynamicState2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PhysicalDeviceExtendedDynamicState3FeaturesEXT supportedFeaturesExtExtendedDynamicState3 = new()
|
||||||
|
{
|
||||||
|
SType = StructureType.PhysicalDeviceExtendedDynamicState3FeaturesExt,
|
||||||
|
PNext = features2.PNext,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState3.ExtensionName))
|
||||||
|
{
|
||||||
|
features2.PNext = &supportedFeaturesExtExtendedDynamicState3;
|
||||||
|
}
|
||||||
|
|
||||||
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT supportedFeaturesPrimitiveTopologyListRestart = new()
|
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT supportedFeaturesPrimitiveTopologyListRestart = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt,
|
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt,
|
||||||
|
@ -451,18 +462,45 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
pExtendedFeatures = &featuresExtendedDynamicState;
|
pExtendedFeatures = &featuresExtendedDynamicState;
|
||||||
|
|
||||||
var featuresExtendedDynamicState2 = new PhysicalDeviceExtendedDynamicState2FeaturesEXT()
|
if (physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState2.ExtensionName))
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceExtendedDynamicState2FeaturesExt,
|
var featuresExtendedDynamicState2 = new PhysicalDeviceExtendedDynamicState2FeaturesEXT()
|
||||||
PNext = pExtendedFeatures,
|
{
|
||||||
ExtendedDynamicState2 = physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState2.ExtensionName),
|
SType = StructureType.PhysicalDeviceExtendedDynamicState2FeaturesExt,
|
||||||
ExtendedDynamicState2LogicOp = supportedFeaturesExtExtendedDynamicState2.ExtendedDynamicState2LogicOp,
|
PNext = pExtendedFeatures,
|
||||||
ExtendedDynamicState2PatchControlPoints = supportedFeaturesExtExtendedDynamicState2.ExtendedDynamicState2PatchControlPoints,
|
ExtendedDynamicState2 =
|
||||||
};
|
physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState2.ExtensionName),
|
||||||
|
ExtendedDynamicState2LogicOp =
|
||||||
|
supportedFeaturesExtExtendedDynamicState2.ExtendedDynamicState2LogicOp,
|
||||||
|
ExtendedDynamicState2PatchControlPoints = supportedFeaturesExtExtendedDynamicState2
|
||||||
|
.ExtendedDynamicState2PatchControlPoints,
|
||||||
|
};
|
||||||
|
|
||||||
extendedLogicOp = supportedFeaturesExtExtendedDynamicState2.ExtendedDynamicState2LogicOp;
|
pExtendedFeatures = &featuresExtendedDynamicState2;
|
||||||
|
}
|
||||||
|
|
||||||
pExtendedFeatures = &featuresExtendedDynamicState2;
|
extendedDynamicState2Features = supportedFeaturesExtExtendedDynamicState2;
|
||||||
|
|
||||||
|
|
||||||
|
if (physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState3.ExtensionName))
|
||||||
|
{
|
||||||
|
var featuresExtendedDynamicState3 = new PhysicalDeviceExtendedDynamicState3FeaturesEXT()
|
||||||
|
{
|
||||||
|
SType = StructureType.PhysicalDeviceExtendedDynamicState3FeaturesExt,
|
||||||
|
PNext = pExtendedFeatures,
|
||||||
|
ExtendedDynamicState3LogicOpEnable = supportedFeaturesExtExtendedDynamicState3.ExtendedDynamicState3LogicOpEnable,
|
||||||
|
ExtendedDynamicState3AlphaToCoverageEnable = supportedFeaturesExtExtendedDynamicState3.ExtendedDynamicState3AlphaToCoverageEnable,
|
||||||
|
ExtendedDynamicState3AlphaToOneEnable = supportedFeaturesExtExtendedDynamicState3.ExtendedDynamicState3AlphaToOneEnable,
|
||||||
|
ExtendedDynamicState3DepthClampEnable = supportedFeaturesExtExtendedDynamicState3.ExtendedDynamicState3DepthClampEnable,
|
||||||
|
};
|
||||||
|
|
||||||
|
pExtendedFeatures = &featuresExtendedDynamicState3;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Seems to be a error in Silk.Net bidings investigate further later
|
||||||
|
supportedFeaturesExtExtendedDynamicState3.ExtendedDynamicState3DepthClampEnable = false;
|
||||||
|
|
||||||
|
extendedDynamicState3Features = supportedFeaturesExtExtendedDynamicState3;
|
||||||
|
|
||||||
var featuresVk11 = new PhysicalDeviceVulkan11Features
|
var featuresVk11 = new PhysicalDeviceVulkan11Features
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,6 +36,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
internal ExtConditionalRendering ConditionalRenderingApi { get; private set; }
|
internal ExtConditionalRendering ConditionalRenderingApi { get; private set; }
|
||||||
internal ExtExtendedDynamicState ExtendedDynamicStateApi { get; private set; }
|
internal ExtExtendedDynamicState ExtendedDynamicStateApi { get; private set; }
|
||||||
internal ExtExtendedDynamicState2 ExtendedDynamicState2Api { get; private set; }
|
internal ExtExtendedDynamicState2 ExtendedDynamicState2Api { get; private set; }
|
||||||
|
internal ExtExtendedDynamicState3 ExtendedDynamicState3Api { get; private set; }
|
||||||
|
|
||||||
internal KhrPushDescriptor PushDescriptorApi { get; private set; }
|
internal KhrPushDescriptor PushDescriptorApi { get; private set; }
|
||||||
internal ExtTransformFeedback TransformFeedbackApi { get; private set; }
|
internal ExtTransformFeedback TransformFeedbackApi { get; private set; }
|
||||||
|
@ -99,7 +100,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public bool PreferThreading => true;
|
public bool PreferThreading => true;
|
||||||
|
|
||||||
public bool ExtendedLogicOp;
|
public PhysicalDeviceExtendedDynamicState2FeaturesEXT ExtendedDynamicState2Features;
|
||||||
|
|
||||||
|
public PhysicalDeviceExtendedDynamicState3FeaturesEXT ExtendedDynamicState3Features;
|
||||||
|
|
||||||
|
|
||||||
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
||||||
|
|
||||||
|
@ -141,6 +145,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ExtendedDynamicState2Api = extendedDynamicState2Api;
|
ExtendedDynamicState2Api = extendedDynamicState2Api;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out ExtExtendedDynamicState3 extendedDynamicState3Api))
|
||||||
|
{
|
||||||
|
ExtendedDynamicState3Api = extendedDynamicState3Api;
|
||||||
|
}
|
||||||
|
|
||||||
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out KhrPushDescriptor pushDescriptorApi))
|
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out KhrPushDescriptor pushDescriptorApi))
|
||||||
{
|
{
|
||||||
PushDescriptorApi = pushDescriptorApi;
|
PushDescriptorApi = pushDescriptorApi;
|
||||||
|
@ -392,6 +401,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_physicalDevice.IsDeviceExtensionPresent(ExtConditionalRendering.ExtensionName),
|
_physicalDevice.IsDeviceExtensionPresent(ExtConditionalRendering.ExtensionName),
|
||||||
_physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName),
|
_physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName),
|
||||||
_physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState2.ExtensionName),
|
_physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState2.ExtensionName),
|
||||||
|
_physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState3.ExtensionName),
|
||||||
features2.Features.MultiViewport && !(IsMoltenVk && Vendor == Vendor.Amd), // Workaround for AMD on MoltenVK issue
|
features2.Features.MultiViewport && !(IsMoltenVk && Vendor == Vendor.Amd), // Workaround for AMD on MoltenVK issue
|
||||||
featuresRobustness2.NullDescriptor || IsMoltenVk,
|
featuresRobustness2.NullDescriptor || IsMoltenVk,
|
||||||
supportsPushDescriptors && !IsMoltenVk,
|
supportsPushDescriptors && !IsMoltenVk,
|
||||||
|
@ -456,9 +466,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
var queueFamilyIndex = VulkanInitialization.FindSuitableQueueFamily(Api, _physicalDevice, _surface, out uint maxQueueCount);
|
var queueFamilyIndex = VulkanInitialization.FindSuitableQueueFamily(Api, _physicalDevice, _surface, out uint maxQueueCount);
|
||||||
|
|
||||||
_device = VulkanInitialization.CreateDevice(Api, _physicalDevice, queueFamilyIndex, maxQueueCount, out bool extendedLogicOp);
|
_device = VulkanInitialization.CreateDevice(Api, _physicalDevice, queueFamilyIndex, maxQueueCount, out PhysicalDeviceExtendedDynamicState2FeaturesEXT extendedDynamicState2Features, out PhysicalDeviceExtendedDynamicState3FeaturesEXT extendedDynamicState3Features);
|
||||||
|
|
||||||
ExtendedLogicOp = extendedLogicOp;
|
ExtendedDynamicState2Features = extendedDynamicState2Features;
|
||||||
|
ExtendedDynamicState3Features = extendedDynamicState3Features;
|
||||||
|
|
||||||
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out KhrSwapchain swapchainApi))
|
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out KhrSwapchain swapchainApi))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue