aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2024-01-26 13:58:57 -0300
committerGitHub <noreply@github.com>2024-01-26 13:58:57 -0300
commitb8d992e5a770931382fd39108601b0abe75149cc (patch)
tree35035d4adebd93fba80ab4bd4ad85b3f275a1bed /src/Ryujinx.Graphics.Vulkan/PipelineBase.cs
parenta620cbcc9050d7d3b0932d97db87628dd4e97b0a (diff)
Allow skipping draws with broken pipeline variants on Vulkan (#5807)1.1.1139
* Allow skipping draws with broken pipeline variants on Vulkan * Move IsLinked check to CreatePipeline * Restore throw on error behaviour for background compile * Can't remove SetAlphaTest pragmas yet * Double new line
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/PipelineBase.cs')
-rw-r--r--src/Ryujinx.Graphics.Vulkan/PipelineBase.cs122
1 files changed, 83 insertions, 39 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs
index af3a27e5..61215b67 100644
--- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs
+++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs
@@ -34,7 +34,8 @@ namespace Ryujinx.Graphics.Vulkan
protected PipelineDynamicState DynamicState;
private PipelineState _newState;
- private bool _stateDirty;
+ private bool _graphicsStateDirty;
+ private bool _computeStateDirty;
private PrimitiveTopology _topology;
private ulong _currentPipelineHandle;
@@ -353,7 +354,7 @@ namespace Ryujinx.Graphics.Vulkan
}
EndRenderPass();
- RecreatePipelineIfNeeded(PipelineBindPoint.Compute);
+ RecreateComputePipelineIfNeeded();
Gd.Api.CmdDispatch(CommandBuffer, (uint)groupsX, (uint)groupsY, (uint)groupsZ);
}
@@ -366,19 +367,23 @@ namespace Ryujinx.Graphics.Vulkan
}
EndRenderPass();
- RecreatePipelineIfNeeded(PipelineBindPoint.Compute);
+ RecreateComputePipelineIfNeeded();
Gd.Api.CmdDispatchIndirect(CommandBuffer, indirectBuffer.Get(Cbs, indirectBufferOffset, 12).Value, (ulong)indirectBufferOffset);
}
public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance)
{
- if (!_program.IsLinked || vertexCount == 0)
+ if (vertexCount == 0)
+ {
+ return;
+ }
+
+ if (!RecreateGraphicsPipelineIfNeeded())
{
return;
}
- RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
BeginRenderPass();
DrawCount++;
@@ -437,13 +442,18 @@ namespace Ryujinx.Graphics.Vulkan
public void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int firstVertex, int firstInstance)
{
- if (!_program.IsLinked || indexCount == 0)
+ if (indexCount == 0)
{
return;
}
UpdateIndexBufferPattern();
- RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
+
+ if (!RecreateGraphicsPipelineIfNeeded())
+ {
+ return;
+ }
+
BeginRenderPass();
DrawCount++;
@@ -476,17 +486,17 @@ namespace Ryujinx.Graphics.Vulkan
public void DrawIndexedIndirect(BufferRange indirectBuffer)
{
- if (!_program.IsLinked)
- {
- return;
- }
-
var buffer = Gd.BufferManager
.GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
UpdateIndexBufferPattern();
- RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
+
+ if (!RecreateGraphicsPipelineIfNeeded())
+ {
+ return;
+ }
+
BeginRenderPass();
DrawCount++;
@@ -522,11 +532,6 @@ namespace Ryujinx.Graphics.Vulkan
public void DrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
{
- if (!_program.IsLinked)
- {
- return;
- }
-
var countBuffer = Gd.BufferManager
.GetBuffer(CommandBuffer, parameterBuffer.Handle, parameterBuffer.Offset, parameterBuffer.Size, false)
.Get(Cbs, parameterBuffer.Offset, parameterBuffer.Size).Value;
@@ -536,7 +541,12 @@ namespace Ryujinx.Graphics.Vulkan
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
UpdateIndexBufferPattern();
- RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
+
+ if (!RecreateGraphicsPipelineIfNeeded())
+ {
+ return;
+ }
+
BeginRenderPass();
DrawCount++;
@@ -614,18 +624,17 @@ namespace Ryujinx.Graphics.Vulkan
public void DrawIndirect(BufferRange indirectBuffer)
{
- if (!_program.IsLinked)
- {
- return;
- }
-
// TODO: Support quads and other unsupported topologies.
var buffer = Gd.BufferManager
.GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size, false).Value;
- RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
+ if (!RecreateGraphicsPipelineIfNeeded())
+ {
+ return;
+ }
+
BeginRenderPass();
ResumeTransformFeedbackInternal();
DrawCount++;
@@ -641,11 +650,6 @@ namespace Ryujinx.Graphics.Vulkan
throw new NotSupportedException();
}
- if (!_program.IsLinked)
- {
- return;
- }
-
var buffer = Gd.BufferManager
.GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size, false).Value;
@@ -656,7 +660,11 @@ namespace Ryujinx.Graphics.Vulkan
// TODO: Support quads and other unsupported topologies.
- RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
+ if (!RecreateGraphicsPipelineIfNeeded())
+ {
+ return;
+ }
+
BeginRenderPass();
ResumeTransformFeedbackInternal();
DrawCount++;
@@ -1576,10 +1584,23 @@ namespace Ryujinx.Graphics.Vulkan
protected void SignalStateChange()
{
- _stateDirty = true;
+ _graphicsStateDirty = true;
+ _computeStateDirty = true;
}
- private void RecreatePipelineIfNeeded(PipelineBindPoint pbp)
+ private void RecreateComputePipelineIfNeeded()
+ {
+ if (_computeStateDirty || Pbp != PipelineBindPoint.Compute)
+ {
+ CreatePipeline(PipelineBindPoint.Compute);
+ _computeStateDirty = false;
+ Pbp = PipelineBindPoint.Compute;
+ }
+
+ _descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, PipelineBindPoint.Compute);
+ }
+
+ private bool RecreateGraphicsPipelineIfNeeded()
{
if (AutoFlush.ShouldFlushDraw(DrawCount))
{
@@ -1620,17 +1641,23 @@ namespace Ryujinx.Graphics.Vulkan
_vertexBufferUpdater.Commit(Cbs);
}
- if (_stateDirty || Pbp != pbp)
+ if (_graphicsStateDirty || Pbp != PipelineBindPoint.Graphics)
{
- CreatePipeline(pbp);
- _stateDirty = false;
- Pbp = pbp;
+ if (!CreatePipeline(PipelineBindPoint.Graphics))
+ {
+ return false;
+ }
+
+ _graphicsStateDirty = false;
+ Pbp = PipelineBindPoint.Graphics;
}
- _descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, pbp);
+ _descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, PipelineBindPoint.Graphics);
+
+ return true;
}
- private void CreatePipeline(PipelineBindPoint pbp)
+ private bool CreatePipeline(PipelineBindPoint pbp)
{
// We can only create a pipeline if the have the shader stages set.
if (_newState.Stages != null)
@@ -1640,10 +1667,25 @@ namespace Ryujinx.Graphics.Vulkan
CreateRenderPass();
}
+ if (!_program.IsLinked)
+ {
+ // Background compile failed, we likely can't create the pipeline because the shader is broken
+ // or the driver failed to compile it.
+
+ return false;
+ }
+
var pipeline = pbp == PipelineBindPoint.Compute
? _newState.CreateComputePipeline(Gd, Device, _program, PipelineCache)
: _newState.CreateGraphicsPipeline(Gd, Device, _program, PipelineCache, _renderPass.Get(Cbs).Value);
+ if (pipeline == null)
+ {
+ // Host failed to create the pipeline, likely due to driver bugs.
+
+ return false;
+ }
+
ulong pipelineHandle = pipeline.GetUnsafe().Value.Handle;
if (_currentPipelineHandle != pipelineHandle)
@@ -1655,6 +1697,8 @@ namespace Ryujinx.Graphics.Vulkan
Gd.Api.CmdBindPipeline(CommandBuffer, pbp, Pipeline.Get(Cbs).Value);
}
}
+
+ return true;
}
private unsafe void BeginRenderPass()