aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/PipelineBase.cs')
-rw-r--r--src/Ryujinx.Graphics.Vulkan/PipelineBase.cs101
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();