Use device features to enable to disable LogicOp Extended Dynamic State

Improve index counting
This commit is contained in:
sunshineinabox 2024-05-17 15:02:56 -07:00
parent b5574ac65f
commit d5f9ed6a2e
6 changed files with 173 additions and 102 deletions

View file

@ -84,8 +84,8 @@ namespace Ryujinx.Graphics.Vulkan
private bool _tfEnabled; private bool _tfEnabled;
private bool _tfActive; private bool _tfActive;
private bool _supportExtDynamic; private readonly bool _supportExtDynamic;
private bool _supportExtDynamic2; private readonly bool _supportExtDynamic2;
private readonly PipelineColorBlendAttachmentState[] _storedBlend; private readonly PipelineColorBlendAttachmentState[] _storedBlend;
@ -986,8 +986,16 @@ namespace Ryujinx.Graphics.Vulkan
public void SetLogicOpState(bool enable, LogicalOp op) public void SetLogicOpState(bool enable, LogicalOp op)
{ {
if (_supportExtDynamic2 && Gd.ExtendedLogicOp)
{
DynamicState.SetLogicOp(op.Convert());
}
else
{
_newState.LogicOp = op.Convert();
}
_newState.LogicOpEnable = enable; _newState.LogicOpEnable = enable;
_newState.LogicOp = op.Convert();
SignalStateChange(); SignalStateChange();
} }

View file

@ -50,6 +50,8 @@ namespace Ryujinx.Graphics.Vulkan
private bool _discard; private bool _discard;
private LogicOp _logicOp;
[Flags] [Flags]
private enum DirtyFlags private enum DirtyFlags
{ {
@ -66,9 +68,10 @@ namespace Ryujinx.Graphics.Vulkan
StencilTestEnable = 1 << 9, StencilTestEnable = 1 << 9,
LineWidth = 1 << 10, LineWidth = 1 << 10,
RasterDiscard = 1 << 11, RasterDiscard = 1 << 11,
LogicOp = 1 << 12,
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, Extended2 = RasterDiscard | LogicOp,
} }
private DirtyFlags _dirty; private DirtyFlags _dirty;
@ -209,6 +212,13 @@ namespace Ryujinx.Graphics.Vulkan
_dirty |= DirtyFlags.RasterDiscard; _dirty |= DirtyFlags.RasterDiscard;
} }
public void SetLogicOp(LogicOp op)
{
_logicOp = op;
_dirty |= DirtyFlags.LogicOp;
}
public void ForceAllDirty(VulkanRenderer gd) public void ForceAllDirty(VulkanRenderer gd)
{ {
_dirty = DirtyFlags.Standard; _dirty = DirtyFlags.Standard;
@ -227,6 +237,11 @@ namespace Ryujinx.Graphics.Vulkan
{ {
_dirty &= ~DirtyFlags.LineWidth; _dirty &= ~DirtyFlags.LineWidth;
} }
if (!gd.ExtendedLogicOp)
{
_dirty &= ~DirtyFlags.LogicOp;
}
} }
public void ReplayIfDirty(VulkanRenderer gd, CommandBuffer commandBuffer) public void ReplayIfDirty(VulkanRenderer gd, CommandBuffer commandBuffer)
@ -291,6 +306,11 @@ namespace Ryujinx.Graphics.Vulkan
RecordRasterizationDiscard(gd, commandBuffer); RecordRasterizationDiscard(gd, commandBuffer);
} }
if (_dirty.HasFlag(DirtyFlags.RasterDiscard))
{
RecordLogicOp(gd, commandBuffer);
}
_dirty = DirtyFlags.None; _dirty = DirtyFlags.None;
} }
@ -370,33 +390,38 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
private void RecordCullMode(ExtExtendedDynamicState api, CommandBuffer commandBuffer) private readonly void RecordCullMode(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
{ {
api.CmdSetCullMode(commandBuffer, CullMode); api.CmdSetCullMode(commandBuffer, CullMode);
} }
private void RecordFrontFace(ExtExtendedDynamicState api, CommandBuffer commandBuffer) private readonly void RecordFrontFace(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
{ {
api.CmdSetFrontFace(commandBuffer, FrontFace); api.CmdSetFrontFace(commandBuffer, FrontFace);
} }
private 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 void RecordDepthTestCompareOp(ExtExtendedDynamicState api, CommandBuffer commandBuffer) private readonly void RecordDepthTestCompareOp(ExtExtendedDynamicState api, CommandBuffer commandBuffer)
{ {
api.CmdSetDepthCompareOp(commandBuffer, _depthCompareOp); api.CmdSetDepthCompareOp(commandBuffer, _depthCompareOp);
} }
private void RecordRasterizationDiscard(VulkanRenderer gd, CommandBuffer commandBuffer) private readonly void RecordRasterizationDiscard(VulkanRenderer gd, CommandBuffer commandBuffer)
{ {
gd.ExtendedDynamicState2Api.CmdSetRasterizerDiscardEnable(commandBuffer, _discard); gd.ExtendedDynamicState2Api.CmdSetRasterizerDiscardEnable(commandBuffer, _discard);
} }
private void RecordLineWidth(Vk api, CommandBuffer commandBuffer) private readonly void RecordLogicOp(VulkanRenderer gd, CommandBuffer commandBuffer)
{
gd.ExtendedDynamicState2Api.CmdSetLogicOp(commandBuffer, _logicOp);
}
private readonly void RecordLineWidth(Vk api, CommandBuffer commandBuffer)
{ {
if (!OperatingSystem.IsMacOS()) if (!OperatingSystem.IsMacOS())
{ {

View file

@ -588,11 +588,15 @@ namespace Ryujinx.Graphics.Vulkan
{ {
SType = StructureType.PipelineColorBlendStateCreateInfo, SType = StructureType.PipelineColorBlendStateCreateInfo,
LogicOpEnable = LogicOpEnable, LogicOpEnable = LogicOpEnable,
LogicOp = LogicOp,
AttachmentCount = ColorBlendAttachmentStateCount, AttachmentCount = ColorBlendAttachmentStateCount,
PAttachments = pColorBlendAttachmentState, PAttachments = pColorBlendAttachmentState,
}; };
if (!(supportsExtDynamicState2 && gd.ExtendedLogicOp))
{
colorBlendState.LogicOp = LogicOp;
}
PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState; PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
if (!AdvancedBlendSrcPreMultiplied || if (!AdvancedBlendSrcPreMultiplied ||
@ -610,8 +614,29 @@ namespace Ryujinx.Graphics.Vulkan
colorBlendState.PNext = &colorBlendAdvancedState; colorBlendState.PNext = &colorBlendAdvancedState;
} }
int dynamicStatesCount = supportsExtDynamicState ? (isMoltenVk ? 18 : 19) : (isMoltenVk ? 7 : 8); int baseDynamicStatesCount = 7;
int additionalDynamicStatesCount = 0;
if (!isMoltenVk)
{
baseDynamicStatesCount++;
}
if (supportsExtDynamicState)
{
additionalDynamicStatesCount += isMoltenVk ? 11 : 12;
}
if (supportsExtDynamicState2)
{
additionalDynamicStatesCount += 2;
if (gd.ExtendedLogicOp)
{
additionalDynamicStatesCount++;
}
}
int dynamicStatesCount = baseDynamicStatesCount + additionalDynamicStatesCount;
DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount]; DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount];
dynamicStates[0] = DynamicState.Viewport; dynamicStates[0] = DynamicState.Viewport;
@ -622,32 +647,39 @@ namespace Ryujinx.Graphics.Vulkan
dynamicStates[5] = DynamicState.StencilReference; dynamicStates[5] = DynamicState.StencilReference;
dynamicStates[6] = DynamicState.BlendConstants; dynamicStates[6] = DynamicState.BlendConstants;
if(!isMoltenVk) int currentIndex = 7;
if (!isMoltenVk)
{ {
dynamicStates[7] = DynamicState.LineWidth; dynamicStates[currentIndex++] = DynamicState.LineWidth;
} }
if (supportsExtDynamicState) if (supportsExtDynamicState)
{ {
int index = (isMoltenVk ? 7 : 8); if (!isMoltenVk)
if (!isMoltenVk) { {
dynamicStates[index++] = DynamicState.VertexInputBindingStrideExt; dynamicStates[currentIndex++] = DynamicState.VertexInputBindingStrideExt;
} }
dynamicStates[index++] = DynamicState.CullModeExt; dynamicStates[currentIndex++] = DynamicState.CullModeExt;
dynamicStates[index++] = DynamicState.FrontFaceExt; dynamicStates[currentIndex++] = DynamicState.FrontFaceExt;
dynamicStates[index++] = DynamicState.DepthTestEnableExt; dynamicStates[currentIndex++] = DynamicState.DepthTestEnableExt;
dynamicStates[index++] = DynamicState.DepthWriteEnableExt; dynamicStates[currentIndex++] = DynamicState.DepthWriteEnableExt;
dynamicStates[index++] = DynamicState.DepthCompareOpExt; dynamicStates[currentIndex++] = DynamicState.DepthCompareOpExt;
dynamicStates[index++] = DynamicState.StencilTestEnableExt; dynamicStates[currentIndex++] = DynamicState.StencilTestEnableExt;
dynamicStates[index++] = DynamicState.ViewportWithCountExt; dynamicStates[currentIndex++] = DynamicState.ViewportWithCountExt;
dynamicStates[index++] = DynamicState.ScissorWithCountExt; dynamicStates[currentIndex++] = DynamicState.ScissorWithCountExt;
dynamicStates[index] = DynamicState.StencilOpExt; dynamicStates[currentIndex++] = DynamicState.StencilOpExt;
} }
if (supportsExtDynamicState2) if (supportsExtDynamicState2)
{ {
dynamicStates[16] = DynamicState.DepthBiasEnableExt; dynamicStates[currentIndex++] = DynamicState.DepthBiasEnableExt;
dynamicStates[17] = DynamicState.RasterizerDiscardEnableExt; dynamicStates[currentIndex++] = DynamicState.RasterizerDiscardEnableExt;
if (gd.ExtendedLogicOp)
{
dynamicStates[currentIndex++] = DynamicState.LogicOpExt;
}
} }
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo

View file

@ -263,7 +263,7 @@ namespace Ryujinx.Graphics.Vulkan
return InvalidIndex; return InvalidIndex;
} }
internal static Device CreateDevice(Vk api, VulkanPhysicalDevice physicalDevice, uint queueFamilyIndex, uint queueCount) internal static Device CreateDevice(Vk api, VulkanPhysicalDevice physicalDevice, uint queueFamilyIndex, uint queueCount, out bool extendedLogicOp)
{ {
if (queueCount > QueuesCount) if (queueCount > QueuesCount)
{ {
@ -460,6 +460,8 @@ namespace Ryujinx.Graphics.Vulkan
ExtendedDynamicState2PatchControlPoints = supportedFeaturesExtExtendedDynamicState2.ExtendedDynamicState2PatchControlPoints, ExtendedDynamicState2PatchControlPoints = supportedFeaturesExtExtendedDynamicState2.ExtendedDynamicState2PatchControlPoints,
}; };
extendedLogicOp = supportedFeaturesExtExtendedDynamicState2.ExtendedDynamicState2LogicOp;
pExtendedFeatures = &featuresExtendedDynamicState2; pExtendedFeatures = &featuresExtendedDynamicState2;
var featuresVk11 = new PhysicalDeviceVulkan11Features var featuresVk11 = new PhysicalDeviceVulkan11Features

View file

@ -99,6 +99,8 @@ namespace Ryujinx.Graphics.Vulkan
public bool PreferThreading => true; public bool PreferThreading => true;
public bool ExtendedLogicOp;
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured; public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
public VulkanRenderer(Vk api, Func<Instance, Vk, SurfaceKHR> surfaceFunc, Func<string[]> requiredExtensionsFunc, string preferredGpuId) public VulkanRenderer(Vk api, Func<Instance, Vk, SurfaceKHR> surfaceFunc, Func<string[]> requiredExtensionsFunc, string preferredGpuId)
@ -454,7 +456,9 @@ 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); _device = VulkanInitialization.CreateDevice(Api, _physicalDevice, queueFamilyIndex, maxQueueCount, out bool extendedLogicOp);
ExtendedLogicOp = extendedLogicOp;
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out KhrSwapchain swapchainApi)) if (Api.TryGetDeviceExtension(_instance.Instance, _device, out KhrSwapchain swapchainApi))
{ {