mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-12-26 21:06:00 +00:00
Use device features to enable to disable LogicOp Extended Dynamic State
Improve index counting
This commit is contained in:
parent
0049585a36
commit
66b6b46716
6 changed files with 121 additions and 82 deletions
|
@ -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;
|
||||||
|
|
||||||
|
@ -989,8 +989,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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())
|
||||||
{
|
{
|
||||||
|
|
|
@ -584,19 +584,19 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vendors other than NVIDIA have a bug where it enables logical operations even for float formats,
|
|
||||||
// so we need to force disable them here.
|
|
||||||
bool logicOpEnable = LogicOpEnable && (gd.Vendor == Vendor.Nvidia || Internal.LogicOpsAllowed);
|
|
||||||
|
|
||||||
var colorBlendState = new PipelineColorBlendStateCreateInfo
|
var colorBlendState = new PipelineColorBlendStateCreateInfo
|
||||||
{
|
{
|
||||||
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 ||
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue