diff options
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/PipelineBase.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Vulkan/PipelineBase.cs | 101 |
1 files changed, 16 insertions, 85 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 2b2caeaec..bda6167d7 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs | |||
@@ -55,6 +55,7 @@ namespace Ryujinx.Graphics.Vulkan | |||
55 | 55 | ||
56 | protected FramebufferParams FramebufferParams; | 56 | protected FramebufferParams FramebufferParams; |
57 | private Auto<DisposableFramebuffer> _framebuffer; | 57 | private Auto<DisposableFramebuffer> _framebuffer; |
58 | private RenderPassHolder _rpHolder; | ||
58 | private Auto<DisposableRenderPass> _renderPass; | 59 | private Auto<DisposableRenderPass> _renderPass; |
59 | private RenderPassHolder _nullRenderPass; | 60 | private RenderPassHolder _nullRenderPass; |
60 | private int _writtenAttachmentCount; | 61 | private int _writtenAttachmentCount; |
@@ -85,8 +86,6 @@ namespace Ryujinx.Graphics.Vulkan | |||
85 | private bool _tfActive; | 86 | private bool _tfActive; |
86 | 87 | ||
87 | private readonly PipelineColorBlendAttachmentState[] _storedBlend; | 88 | private readonly PipelineColorBlendAttachmentState[] _storedBlend; |
88 | |||
89 | private ulong _drawCountSinceBarrier; | ||
90 | public ulong DrawCount { get; private set; } | 89 | public ulong DrawCount { get; private set; } |
91 | public bool RenderPassActive { get; private set; } | 90 | public bool RenderPassActive { get; private set; } |
92 | 91 | ||
@@ -135,48 +134,7 @@ namespace Ryujinx.Graphics.Vulkan | |||
135 | 134 | ||
136 | public unsafe void Barrier() | 135 | public unsafe void Barrier() |
137 | { | 136 | { |
138 | if (_drawCountSinceBarrier != DrawCount) | 137 | Gd.Barriers.QueueMemoryBarrier(); |
139 | { | ||
140 | _drawCountSinceBarrier = DrawCount; | ||
141 | |||
142 | // Barriers are not supported inside a render pass on Apple GPUs. | ||
143 | // As a workaround, end the render pass. | ||
144 | if (Gd.Vendor == Vendor.Apple) | ||
145 | { | ||
146 | EndRenderPass(); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | MemoryBarrier memoryBarrier = new() | ||
151 | { | ||
152 | SType = StructureType.MemoryBarrier, | ||
153 | SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit, | ||
154 | DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit, | ||
155 | }; | ||
156 | |||
157 | PipelineStageFlags pipelineStageFlags = PipelineStageFlags.VertexShaderBit | PipelineStageFlags.FragmentShaderBit; | ||
158 | |||
159 | if (Gd.Capabilities.SupportsGeometryShader) | ||
160 | { | ||
161 | pipelineStageFlags |= PipelineStageFlags.GeometryShaderBit; | ||
162 | } | ||
163 | |||
164 | if (Gd.Capabilities.SupportsTessellationShader) | ||
165 | { | ||
166 | pipelineStageFlags |= PipelineStageFlags.TessellationControlShaderBit | PipelineStageFlags.TessellationEvaluationShaderBit; | ||
167 | } | ||
168 | |||
169 | Gd.Api.CmdPipelineBarrier( | ||
170 | CommandBuffer, | ||
171 | pipelineStageFlags, | ||
172 | pipelineStageFlags, | ||
173 | 0, | ||
174 | 1, | ||
175 | memoryBarrier, | ||
176 | 0, | ||
177 | null, | ||
178 | 0, | ||
179 | null); | ||
180 | } | 138 | } |
181 | 139 | ||
182 | public void ComputeBarrier() | 140 | public void ComputeBarrier() |
@@ -203,6 +161,7 @@ namespace Ryujinx.Graphics.Vulkan | |||
203 | 161 | ||
204 | public void BeginTransformFeedback(PrimitiveTopology topology) | 162 | public void BeginTransformFeedback(PrimitiveTopology topology) |
205 | { | 163 | { |
164 | Gd.Barriers.EnableTfbBarriers(true); | ||
206 | _tfEnabled = true; | 165 | _tfEnabled = true; |
207 | } | 166 | } |
208 | 167 | ||
@@ -249,7 +208,7 @@ namespace Ryujinx.Graphics.Vulkan | |||
249 | CreateRenderPass(); | 208 | CreateRenderPass(); |
250 | } | 209 | } |
251 | 210 | ||
252 | Gd.Barriers.Flush(Cbs.CommandBuffer, RenderPassActive, EndRenderPassDelegate); | 211 | Gd.Barriers.Flush(Cbs, RenderPassActive, _rpHolder, EndRenderPassDelegate); |
253 | 212 | ||
254 | BeginRenderPass(); | 213 | BeginRenderPass(); |
255 | 214 | ||
@@ -287,7 +246,7 @@ namespace Ryujinx.Graphics.Vulkan | |||
287 | CreateRenderPass(); | 246 | CreateRenderPass(); |
288 | } | 247 | } |
289 | 248 | ||
290 | Gd.Barriers.Flush(Cbs.CommandBuffer, RenderPassActive, EndRenderPassDelegate); | 249 | Gd.Barriers.Flush(Cbs, RenderPassActive, _rpHolder, EndRenderPassDelegate); |
291 | 250 | ||
292 | BeginRenderPass(); | 251 | BeginRenderPass(); |
293 | 252 | ||
@@ -299,24 +258,7 @@ namespace Ryujinx.Graphics.Vulkan | |||
299 | 258 | ||
300 | public unsafe void CommandBufferBarrier() | 259 | public unsafe void CommandBufferBarrier() |
301 | { | 260 | { |
302 | MemoryBarrier memoryBarrier = new() | 261 | Gd.Barriers.QueueCommandBufferBarrier(); |
303 | { | ||
304 | SType = StructureType.MemoryBarrier, | ||
305 | SrcAccessMask = BufferHolder.DefaultAccessFlags, | ||
306 | DstAccessMask = AccessFlags.IndirectCommandReadBit, | ||
307 | }; | ||
308 | |||
309 | Gd.Api.CmdPipelineBarrier( | ||
310 | CommandBuffer, | ||
311 | PipelineStageFlags.AllCommandsBit, | ||
312 | PipelineStageFlags.DrawIndirectBit, | ||
313 | 0, | ||
314 | 1, | ||
315 | memoryBarrier, | ||
316 | 0, | ||
317 | null, | ||
318 | 0, | ||
319 | null); | ||
320 | } | 262 | } |
321 | 263 | ||
322 | public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size) | 264 | public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size) |
@@ -722,6 +664,7 @@ namespace Ryujinx.Graphics.Vulkan | |||
722 | 664 | ||
723 | public void EndTransformFeedback() | 665 | public void EndTransformFeedback() |
724 | { | 666 | { |
667 | Gd.Barriers.EnableTfbBarriers(false); | ||
725 | PauseTransformFeedbackInternal(); | 668 | PauseTransformFeedbackInternal(); |
726 | _tfEnabled = false; | 669 | _tfEnabled = false; |
727 | } | 670 | } |
@@ -1408,24 +1351,7 @@ namespace Ryujinx.Graphics.Vulkan | |||
1408 | 1351 | ||
1409 | public unsafe void TextureBarrier() | 1352 | public unsafe void TextureBarrier() |
1410 | { | 1353 | { |
1411 | MemoryBarrier memoryBarrier = new() | 1354 | Gd.Barriers.QueueTextureBarrier(); |
1412 | { | ||
1413 | SType = StructureType.MemoryBarrier, | ||
1414 | SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit, | ||
1415 | DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit, | ||
1416 | }; | ||
1417 | |||
1418 | Gd.Api.CmdPipelineBarrier( | ||
1419 | CommandBuffer, | ||
1420 | PipelineStageFlags.FragmentShaderBit, | ||
1421 | PipelineStageFlags.FragmentShaderBit, | ||
1422 | 0, | ||
1423 | 1, | ||
1424 | memoryBarrier, | ||
1425 | 0, | ||
1426 | null, | ||
1427 | 0, | ||
1428 | null); | ||
1429 | } | 1355 | } |
1430 | 1356 | ||
1431 | public void TextureBarrierTiled() | 1357 | public void TextureBarrierTiled() |
@@ -1532,12 +1458,15 @@ namespace Ryujinx.Graphics.Vulkan | |||
1532 | // Use the null framebuffer. | 1458 | // Use the null framebuffer. |
1533 | _nullRenderPass ??= new RenderPassHolder(Gd, Device, new RenderPassCacheKey(), FramebufferParams); | 1459 | _nullRenderPass ??= new RenderPassHolder(Gd, Device, new RenderPassCacheKey(), FramebufferParams); |
1534 | 1460 | ||
1461 | _rpHolder = _nullRenderPass; | ||
1535 | _renderPass = _nullRenderPass.GetRenderPass(); | 1462 | _renderPass = _nullRenderPass.GetRenderPass(); |
1536 | _framebuffer = _nullRenderPass.GetFramebuffer(Gd, Cbs, FramebufferParams); | 1463 | _framebuffer = _nullRenderPass.GetFramebuffer(Gd, Cbs, FramebufferParams); |
1537 | } | 1464 | } |
1538 | else | 1465 | else |
1539 | { | 1466 | { |
1540 | (_renderPass, _framebuffer) = FramebufferParams.GetPassAndFramebuffer(Gd, Device, Cbs); | 1467 | (_rpHolder, _framebuffer) = FramebufferParams.GetPassAndFramebuffer(Gd, Device, Cbs); |
1468 | |||
1469 | _renderPass = _rpHolder.GetRenderPass(); | ||
1541 | } | 1470 | } |
1542 | } | 1471 | } |
1543 | 1472 | ||
@@ -1564,7 +1493,7 @@ namespace Ryujinx.Graphics.Vulkan | |||
1564 | } | 1493 | } |
1565 | } | 1494 | } |
1566 | 1495 | ||
1567 | Gd.Barriers.Flush(Cbs.CommandBuffer, RenderPassActive, EndRenderPassDelegate); | 1496 | Gd.Barriers.Flush(Cbs, _program, RenderPassActive, _rpHolder, EndRenderPassDelegate); |
1568 | 1497 | ||
1569 | _descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, PipelineBindPoint.Compute); | 1498 | _descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, PipelineBindPoint.Compute); |
1570 | } | 1499 | } |
@@ -1629,7 +1558,7 @@ namespace Ryujinx.Graphics.Vulkan | |||
1629 | } | 1558 | } |
1630 | } | 1559 | } |
1631 | 1560 | ||
1632 | Gd.Barriers.Flush(Cbs.CommandBuffer, RenderPassActive, EndRenderPassDelegate); | 1561 | Gd.Barriers.Flush(Cbs, _program, RenderPassActive, _rpHolder, EndRenderPassDelegate); |
1633 | 1562 | ||
1634 | _descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, PipelineBindPoint.Graphics); | 1563 | _descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, PipelineBindPoint.Graphics); |
1635 | 1564 | ||
@@ -1708,6 +1637,8 @@ namespace Ryujinx.Graphics.Vulkan | |||
1708 | { | 1637 | { |
1709 | if (RenderPassActive) | 1638 | if (RenderPassActive) |
1710 | { | 1639 | { |
1640 | FramebufferParams.AddStoreOpUsage(); | ||
1641 | |||
1711 | PauseTransformFeedbackInternal(); | 1642 | PauseTransformFeedbackInternal(); |
1712 | Gd.Api.CmdEndRenderPass(CommandBuffer); | 1643 | Gd.Api.CmdEndRenderPass(CommandBuffer); |
1713 | SignalRenderPassEnd(); | 1644 | SignalRenderPassEnd(); |