ExtDynamicState2

This commit is contained in:
sunshineinabox 2024-05-16 23:50:45 -07:00
parent cee5ae5551
commit c728a3b6a4
6 changed files with 95 additions and 13 deletions

View file

@ -31,6 +31,7 @@ namespace Ryujinx.Graphics.Vulkan
public readonly bool SupportsShaderStorageImageMultisample; public readonly bool SupportsShaderStorageImageMultisample;
public readonly bool SupportsConditionalRendering; public readonly bool SupportsConditionalRendering;
public readonly bool SupportsExtendedDynamicState; public readonly bool SupportsExtendedDynamicState;
public readonly bool SupportsExtendedDynamicState2;
public readonly bool SupportsMultiView; public readonly bool SupportsMultiView;
public readonly bool SupportsNullDescriptors; public readonly bool SupportsNullDescriptors;
public readonly bool SupportsPushDescriptors; public readonly bool SupportsPushDescriptors;
@ -70,6 +71,7 @@ namespace Ryujinx.Graphics.Vulkan
bool supportsShaderStorageImageMultisample, bool supportsShaderStorageImageMultisample,
bool supportsConditionalRendering, bool supportsConditionalRendering,
bool supportsExtendedDynamicState, bool supportsExtendedDynamicState,
bool supportsExtendedDynamicState2,
bool supportsMultiView, bool supportsMultiView,
bool supportsNullDescriptors, bool supportsNullDescriptors,
bool supportsPushDescriptors, bool supportsPushDescriptors,
@ -108,6 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
SupportsShaderStorageImageMultisample = supportsShaderStorageImageMultisample; SupportsShaderStorageImageMultisample = supportsShaderStorageImageMultisample;
SupportsConditionalRendering = supportsConditionalRendering; SupportsConditionalRendering = supportsConditionalRendering;
SupportsExtendedDynamicState = supportsExtendedDynamicState; SupportsExtendedDynamicState = supportsExtendedDynamicState;
SupportsExtendedDynamicState2 = supportsExtendedDynamicState2;
SupportsMultiView = supportsMultiView; SupportsMultiView = supportsMultiView;
SupportsNullDescriptors = supportsNullDescriptors; SupportsNullDescriptors = supportsNullDescriptors;
SupportsPushDescriptors = supportsPushDescriptors; SupportsPushDescriptors = supportsPushDescriptors;

View file

@ -85,6 +85,7 @@ namespace Ryujinx.Graphics.Vulkan
private bool _tfActive; private bool _tfActive;
private bool _supportExtDynamic; private bool _supportExtDynamic;
private bool _supportExtDynamic2;
private readonly PipelineColorBlendAttachmentState[] _storedBlend; private readonly PipelineColorBlendAttachmentState[] _storedBlend;
@ -125,6 +126,9 @@ namespace Ryujinx.Graphics.Vulkan
_storedBlend = new PipelineColorBlendAttachmentState[Constants.MaxRenderTargets]; _storedBlend = new PipelineColorBlendAttachmentState[Constants.MaxRenderTargets];
_supportExtDynamic = gd.Capabilities.SupportsExtendedDynamicState; _supportExtDynamic = gd.Capabilities.SupportsExtendedDynamicState;
_supportExtDynamic2 = gd.Capabilities.SupportsExtendedDynamicState2;
_newState.Initialize(); _newState.Initialize();
} }
@ -868,9 +872,13 @@ namespace Ryujinx.Graphics.Vulkan
public void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp) public void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp)
{ {
DynamicState.SetDepthBias(factor, units, clamp); DynamicState.SetDepthBias(factor, units, clamp, (enables != 0));
_newState.DepthBiasEnable = enables != 0; if (!_supportExtDynamic2)
{
_newState.DepthBiasEnable = enables != 0;
}
SignalStateChange(); SignalStateChange();
} }
@ -983,6 +991,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
_newState.LogicOpEnable = enable; _newState.LogicOpEnable = enable;
_newState.LogicOp = op.Convert(); _newState.LogicOp = op.Convert();
SignalStateChange(); SignalStateChange();
} }
@ -1071,7 +1080,14 @@ namespace Ryujinx.Graphics.Vulkan
public void SetRasterizerDiscard(bool discard) public void SetRasterizerDiscard(bool discard)
{ {
_newState.RasterizerDiscardEnable = discard; if (!_supportExtDynamic2)
{
_newState.RasterizerDiscardEnable = discard;
}
else
{
DynamicState.SetRasterizerDiscard(discard);
}
SignalStateChange(); SignalStateChange();
} }

View file

@ -10,6 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
private float _depthBiasSlopeFactor; private float _depthBiasSlopeFactor;
private float _depthBiasConstantFactor; private float _depthBiasConstantFactor;
private float _depthBiasClamp; private float _depthBiasClamp;
private bool _depthBiasEnable;
public int ScissorsCount; public int ScissorsCount;
private Array16<Rect2D> _scissors; private Array16<Rect2D> _scissors;
@ -47,6 +48,8 @@ namespace Ryujinx.Graphics.Vulkan
public CullModeFlags CullMode; public CullModeFlags CullMode;
public FrontFace FrontFace; public FrontFace FrontFace;
private bool _discard;
[Flags] [Flags]
private enum DirtyFlags private enum DirtyFlags
{ {
@ -62,8 +65,10 @@ namespace Ryujinx.Graphics.Vulkan
DepthTestCompareOp = 1 << 8, DepthTestCompareOp = 1 << 8,
StencilTestEnable = 1 << 9, StencilTestEnable = 1 << 9,
LineWidth = 1 << 10, LineWidth = 1 << 10,
RasterDiscard = 1 << 11,
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,
} }
private DirtyFlags _dirty; private DirtyFlags _dirty;
@ -78,11 +83,12 @@ namespace Ryujinx.Graphics.Vulkan
_dirty |= DirtyFlags.Blend; _dirty |= DirtyFlags.Blend;
} }
public void SetDepthBias(float slopeFactor, float constantFactor, float clamp) public void SetDepthBias(float slopeFactor, float constantFactor, float clamp, bool enable)
{ {
_depthBiasSlopeFactor = slopeFactor; _depthBiasSlopeFactor = slopeFactor;
_depthBiasConstantFactor = constantFactor; _depthBiasConstantFactor = constantFactor;
_depthBiasClamp = clamp; _depthBiasClamp = clamp;
_depthBiasEnable = enable;
_dirty |= DirtyFlags.DepthBias; _dirty |= DirtyFlags.DepthBias;
} }
@ -195,6 +201,13 @@ namespace Ryujinx.Graphics.Vulkan
_dirty |= DirtyFlags.LineWidth; _dirty |= DirtyFlags.LineWidth;
} }
public void SetRasterizerDiscard(bool discard)
{
_discard = discard;
_dirty |= DirtyFlags.RasterDiscard;
}
public void ForceAllDirty(VulkanRenderer gd) public void ForceAllDirty(VulkanRenderer gd)
{ {
@ -205,6 +218,11 @@ namespace Ryujinx.Graphics.Vulkan
_dirty = DirtyFlags.Standard | DirtyFlags.Extended; _dirty = DirtyFlags.Standard | DirtyFlags.Extended;
} }
if (gd.Capabilities.SupportsExtendedDynamicState2)
{
_dirty = DirtyFlags.Standard | DirtyFlags.Extended | DirtyFlags.Extended2;
}
if (gd.IsMoltenVk) if (gd.IsMoltenVk)
{ {
_dirty &= ~DirtyFlags.LineWidth; _dirty &= ~DirtyFlags.LineWidth;
@ -220,7 +238,7 @@ namespace Ryujinx.Graphics.Vulkan
if (_dirty.HasFlag(DirtyFlags.DepthBias)) if (_dirty.HasFlag(DirtyFlags.DepthBias))
{ {
RecordDepthBias(gd.Api, commandBuffer); RecordDepthBias(gd, commandBuffer);
} }
if (_dirty.HasFlag(DirtyFlags.Scissor)) if (_dirty.HasFlag(DirtyFlags.Scissor))
@ -267,7 +285,12 @@ namespace Ryujinx.Graphics.Vulkan
{ {
RecordLineWidth(gd.Api, commandBuffer); RecordLineWidth(gd.Api, commandBuffer);
} }
if (_dirty.HasFlag(DirtyFlags.RasterDiscard))
{
RecordRasterizationDiscard(gd, commandBuffer);
}
_dirty = DirtyFlags.None; _dirty = DirtyFlags.None;
} }
@ -276,9 +299,14 @@ namespace Ryujinx.Graphics.Vulkan
api.CmdSetBlendConstants(commandBuffer, _blendConstants.AsSpan()); api.CmdSetBlendConstants(commandBuffer, _blendConstants.AsSpan());
} }
private readonly void RecordDepthBias(Vk api, CommandBuffer commandBuffer) private readonly void RecordDepthBias(VulkanRenderer gd, CommandBuffer commandBuffer)
{ {
api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor); gd.Api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor);
if (gd.Capabilities.SupportsExtendedDynamicState2)
{
gd.ExtendedDynamicState2Api.CmdSetDepthBiasEnable(commandBuffer, _depthBiasEnable);
}
} }
private void RecordScissor(VulkanRenderer gd, CommandBuffer commandBuffer) private void RecordScissor(VulkanRenderer gd, CommandBuffer commandBuffer)
@ -363,6 +391,11 @@ namespace Ryujinx.Graphics.Vulkan
api.CmdSetDepthCompareOp(commandBuffer, _depthCompareOp); api.CmdSetDepthCompareOp(commandBuffer, _depthCompareOp);
} }
private void RecordRasterizationDiscard(VulkanRenderer gd, CommandBuffer commandBuffer)
{
gd.ExtendedDynamicState2Api.CmdSetRasterizerDiscardEnable(commandBuffer, _discard);
}
private void RecordLineWidth(Vk api, CommandBuffer commandBuffer) private void RecordLineWidth(Vk api, CommandBuffer commandBuffer)
{ {
if (!OperatingSystem.IsMacOS()) if (!OperatingSystem.IsMacOS())

View file

@ -406,6 +406,8 @@ namespace Ryujinx.Graphics.Vulkan
} }
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState; bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
bool supportsExtDynamicState2 = gd.Capabilities.SupportsExtendedDynamicState2;
fixed (VertexInputAttributeDescription* pVertexAttributeDescriptions = &Internal.VertexAttributeDescriptions[0]) fixed (VertexInputAttributeDescription* pVertexAttributeDescriptions = &Internal.VertexAttributeDescriptions[0])
fixed (VertexInputAttributeDescription* pVertexAttributeDescriptions2 = &_vertexAttributeDescriptions2[0]) fixed (VertexInputAttributeDescription* pVertexAttributeDescriptions2 = &_vertexAttributeDescriptions2[0])
@ -473,9 +475,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
SType = StructureType.PipelineRasterizationStateCreateInfo, SType = StructureType.PipelineRasterizationStateCreateInfo,
DepthClampEnable = DepthClampEnable, DepthClampEnable = DepthClampEnable,
RasterizerDiscardEnable = RasterizerDiscardEnable,
PolygonMode = PolygonMode, PolygonMode = PolygonMode,
DepthBiasEnable = DepthBiasEnable,
}; };
if (isMoltenVk) if (isMoltenVk)
@ -488,6 +488,12 @@ namespace Ryujinx.Graphics.Vulkan
rasterizationState.CullMode = CullMode; rasterizationState.CullMode = CullMode;
rasterizationState.FrontFace = FrontFace; rasterizationState.FrontFace = FrontFace;
} }
if (!supportsExtDynamicState2)
{
rasterizationState.DepthBiasEnable = DepthBiasEnable;
rasterizationState.RasterizerDiscardEnable = RasterizerDiscardEnable;
}
var viewportState = new PipelineViewportStateCreateInfo var viewportState = new PipelineViewportStateCreateInfo
{ {
@ -590,7 +596,7 @@ namespace Ryujinx.Graphics.Vulkan
AttachmentCount = ColorBlendAttachmentStateCount, AttachmentCount = ColorBlendAttachmentStateCount,
PAttachments = pColorBlendAttachmentState, PAttachments = pColorBlendAttachmentState,
}; };
PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState; PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
if (!AdvancedBlendSrcPreMultiplied || if (!AdvancedBlendSrcPreMultiplied ||
@ -608,7 +614,7 @@ namespace Ryujinx.Graphics.Vulkan
colorBlendState.PNext = &colorBlendAdvancedState; colorBlendState.PNext = &colorBlendAdvancedState;
} }
int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 17 : 18) : (isMoltenVk ? 7 : 8); int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 18 : 19) : (isMoltenVk ? 7 : 8);
DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount]; DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount];
@ -642,6 +648,12 @@ namespace Ryujinx.Graphics.Vulkan
dynamicStates[index] = DynamicState.StencilOpExt; dynamicStates[index] = DynamicState.StencilOpExt;
} }
if (supportsExtDynamicState2)
{
dynamicStates[16] = DynamicState.DepthBiasEnableExt;
dynamicStates[17] = DynamicState.RasterizerDiscardEnableExt;
}
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
{ {
SType = StructureType.PipelineDynamicStateCreateInfo, SType = StructureType.PipelineDynamicStateCreateInfo,

View file

@ -23,6 +23,7 @@ namespace Ryujinx.Graphics.Vulkan
private static readonly string[] _desirableExtensions = { private static readonly string[] _desirableExtensions = {
ExtConditionalRendering.ExtensionName, ExtConditionalRendering.ExtensionName,
ExtExtendedDynamicState.ExtensionName, ExtExtendedDynamicState.ExtensionName,
ExtExtendedDynamicState2.ExtensionName,
ExtTransformFeedback.ExtensionName, ExtTransformFeedback.ExtensionName,
KhrDrawIndirectCount.ExtensionName, KhrDrawIndirectCount.ExtensionName,
KhrPushDescriptor.ExtensionName, KhrPushDescriptor.ExtensionName,
@ -290,7 +291,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
SType = StructureType.PhysicalDeviceFeatures2, SType = StructureType.PhysicalDeviceFeatures2,
}; };
PhysicalDeviceVulkan11Features supportedFeaturesVk11 = new() PhysicalDeviceVulkan11Features supportedFeaturesVk11 = new()
{ {
SType = StructureType.PhysicalDeviceVulkan11Features, SType = StructureType.PhysicalDeviceVulkan11Features,
@ -438,6 +439,15 @@ namespace Ryujinx.Graphics.Vulkan
}; };
pExtendedFeatures = &featuresExtendedDynamicState; pExtendedFeatures = &featuresExtendedDynamicState;
var featuresExtendedDynamicState2 = new PhysicalDeviceExtendedDynamicState2FeaturesEXT()
{
SType = StructureType.PhysicalDeviceExtendedDynamicState2FeaturesExt,
PNext = pExtendedFeatures,
ExtendedDynamicState2 = physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState2.ExtensionName),
};
pExtendedFeatures = &featuresExtendedDynamicState2;
var featuresVk11 = new PhysicalDeviceVulkan11Features var featuresVk11 = new PhysicalDeviceVulkan11Features
{ {

View file

@ -35,6 +35,8 @@ namespace Ryujinx.Graphics.Vulkan
internal KhrSwapchain SwapchainApi { get; private set; } internal KhrSwapchain SwapchainApi { get; private set; }
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 KhrPushDescriptor PushDescriptorApi { get; private set; } internal KhrPushDescriptor PushDescriptorApi { get; private set; }
internal ExtTransformFeedback TransformFeedbackApi { get; private set; } internal ExtTransformFeedback TransformFeedbackApi { get; private set; }
internal KhrDrawIndirectCount DrawIndirectCountApi { get; private set; } internal KhrDrawIndirectCount DrawIndirectCountApi { get; private set; }
@ -131,6 +133,11 @@ namespace Ryujinx.Graphics.Vulkan
{ {
ExtendedDynamicStateApi = extendedDynamicStateApi; ExtendedDynamicStateApi = extendedDynamicStateApi;
} }
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out ExtExtendedDynamicState2 extendedDynamicState2Api))
{
ExtendedDynamicState2Api = extendedDynamicState2Api;
}
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out KhrPushDescriptor pushDescriptorApi)) if (Api.TryGetDeviceExtension(_instance.Instance, _device, out KhrPushDescriptor pushDescriptorApi))
{ {
@ -382,6 +389,7 @@ namespace Ryujinx.Graphics.Vulkan
features2.Features.ShaderStorageImageMultisample, features2.Features.ShaderStorageImageMultisample,
_physicalDevice.IsDeviceExtensionPresent(ExtConditionalRendering.ExtensionName), _physicalDevice.IsDeviceExtensionPresent(ExtConditionalRendering.ExtensionName),
_physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName), _physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName),
_physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState2.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,