aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Vulkan/BarrierBatch.cs
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2024-09-02 01:28:16 +0100
committerGitHub <noreply@github.com>2024-09-01 21:28:16 -0300
commitca59c3f4998e2d1beb3b0d0214611e3332238557 (patch)
tree38d1a2e2c0b4a906b258ee2e988256299e3e866d /src/Ryujinx.Graphics.Vulkan/BarrierBatch.cs
parentfdd7ee791cd37546390856f38eab16ea78451742 (diff)
Vulkan: Feedback loop detection and barriers (#7226)
* Vulkan: Feedback loop improvements This PR allows the Vulkan backend to detect attachment feedback loops. These are currently used in the following ways: - Partial use of VK_EXT_attachment_feedback_loop_layout - All renderable textures have AttachmentFeedbackLoopBitExt - Compile pipelines with Color/DepthStencil feedback loop flags when present - Support using FragmentBarrier for feedback loops (fixes regressions from https://github.com/Ryujinx/Ryujinx/pull/7012 ) TODO: - AMD GPUs may need layout transitions for it to properly allow textures to be used in feedback loops. - Use dynamic state for feedback loops. The background pipeline will always miss since feedback loop state isn't known on the GPU project. - How is the barrier dependency flag used? (DXVK just ignores it, there's no vulkan validation...) - Improve subpass dependencies to fix validation errors * Mark field readonly * Add feedback loop dynamic state * fix: add MoltenVK resolver workaround fix: add MoltenVK resolver workaround * Formatting * Fix more complaints * RADV dcc workaround * Use dynamic state properly, cleanup. * Use aspects flags in more places
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/BarrierBatch.cs')
-rw-r--r--src/Ryujinx.Graphics.Vulkan/BarrierBatch.cs39
1 files changed, 26 insertions, 13 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/BarrierBatch.cs b/src/Ryujinx.Graphics.Vulkan/BarrierBatch.cs
index a6a006bb..bcfb3dbf 100644
--- a/src/Ryujinx.Graphics.Vulkan/BarrierBatch.cs
+++ b/src/Ryujinx.Graphics.Vulkan/BarrierBatch.cs
@@ -32,10 +32,12 @@ namespace Ryujinx.Graphics.Vulkan
CommandBuffer
}
+ private bool _feedbackLoopActive;
private PipelineStageFlags _incoherentBufferWriteStages;
private PipelineStageFlags _incoherentTextureWriteStages;
private PipelineStageFlags _extraStages;
private IncoherentBarrierType _queuedIncoherentBarrier;
+ private bool _queuedFeedbackLoopBarrier;
public BarrierBatch(VulkanRenderer gd)
{
@@ -53,17 +55,6 @@ namespace Ryujinx.Graphics.Vulkan
stages |= PipelineStageFlags.TransformFeedbackBitExt;
}
- if (!gd.IsTBDR)
- {
- // Desktop GPUs can transform image barriers into memory barriers.
-
- access |= AccessFlags.DepthStencilAttachmentWriteBit | AccessFlags.ColorAttachmentWriteBit;
- access |= AccessFlags.DepthStencilAttachmentReadBit | AccessFlags.ColorAttachmentReadBit;
-
- stages |= PipelineStageFlags.EarlyFragmentTestsBit | PipelineStageFlags.LateFragmentTestsBit;
- stages |= PipelineStageFlags.ColorAttachmentOutputBit;
- }
-
return (access, stages);
}
@@ -178,16 +169,34 @@ namespace Ryujinx.Graphics.Vulkan
}
_queuedIncoherentBarrier = IncoherentBarrierType.None;
+ _queuedFeedbackLoopBarrier = false;
}
+ else if (_feedbackLoopActive && _queuedFeedbackLoopBarrier)
+ {
+ // Feedback loop barrier.
+
+ MemoryBarrier barrier = new MemoryBarrier()
+ {
+ SType = StructureType.MemoryBarrier,
+ SrcAccessMask = AccessFlags.ShaderWriteBit,
+ DstAccessMask = AccessFlags.ShaderReadBit
+ };
+
+ QueueBarrier(barrier, PipelineStageFlags.FragmentShaderBit, PipelineStageFlags.AllGraphicsBit);
+
+ _queuedFeedbackLoopBarrier = false;
+ }
+
+ _feedbackLoopActive = false;
}
}
public unsafe void Flush(CommandBufferScoped cbs, bool inRenderPass, RenderPassHolder rpHolder, Action endRenderPass)
{
- Flush(cbs, null, inRenderPass, rpHolder, endRenderPass);
+ Flush(cbs, null, false, inRenderPass, rpHolder, endRenderPass);
}
- public unsafe void Flush(CommandBufferScoped cbs, ShaderCollection program, bool inRenderPass, RenderPassHolder rpHolder, Action endRenderPass)
+ public unsafe void Flush(CommandBufferScoped cbs, ShaderCollection program, bool feedbackLoopActive, bool inRenderPass, RenderPassHolder rpHolder, Action endRenderPass)
{
if (program != null)
{
@@ -195,6 +204,8 @@ namespace Ryujinx.Graphics.Vulkan
_incoherentTextureWriteStages |= program.IncoherentTextureWriteStages;
}
+ _feedbackLoopActive |= feedbackLoopActive;
+
FlushMemoryBarrier(program, inRenderPass);
if (!inRenderPass && rpHolder != null)
@@ -406,6 +417,8 @@ namespace Ryujinx.Graphics.Vulkan
{
_queuedIncoherentBarrier = type;
}
+
+ _queuedFeedbackLoopBarrier = true;
}
public void QueueTextureBarrier()