diff options
author | gdkchan <gab.dark.100@gmail.com> | 2024-01-26 13:58:57 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-26 13:58:57 -0300 |
commit | b8d992e5a770931382fd39108601b0abe75149cc (patch) | |
tree | 35035d4adebd93fba80ab4bd4ad85b3f275a1bed /src/Ryujinx.Graphics.Vulkan/PipelineBase.cs | |
parent | a620cbcc9050d7d3b0932d97db87628dd4e97b0a (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.cs | 122 |
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() |