aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2024-04-06 13:25:51 -0300
committerGitHub <noreply@github.com>2024-04-06 13:25:51 -0300
commit791bf22109b90eca79fe1bf934074809661a6c86 (patch)
tree1356f92bfbeecea55748b2cb18809665aaf2ce6b
parent66b1d59c666b425a8451e1a4fe981e3311be08fb (diff)
Vulkan: Skip draws when patches topology is used without a tessellation shader (#6508)
-rw-r--r--src/Ryujinx.Graphics.Vulkan/PipelineBase.cs1
-rw-r--r--src/Ryujinx.Graphics.Vulkan/PipelineState.cs11
-rw-r--r--src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs2
3 files changed, 14 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs
index 2bcab514..d5169a68 100644
--- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs
+++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs
@@ -981,6 +981,7 @@ namespace Ryujinx.Graphics.Vulkan
_bindingBarriersDirty = true;
_newState.PipelineLayout = internalProgram.PipelineLayout;
+ _newState.HasTessellationControlShader = internalProgram.HasTessellationControlShader;
_newState.StagesCount = (uint)stages.Length;
stages.CopyTo(_newState.Stages.AsSpan()[..stages.Length]);
diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs
index 25fd7168..49c12b37 100644
--- a/src/Ryujinx.Graphics.Vulkan/PipelineState.cs
+++ b/src/Ryujinx.Graphics.Vulkan/PipelineState.cs
@@ -311,6 +311,7 @@ namespace Ryujinx.Graphics.Vulkan
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFBF) | ((value ? 1UL : 0UL) << 6);
}
+ public bool HasTessellationControlShader;
public NativeArray<PipelineShaderStageCreateInfo> Stages;
public PipelineLayout PipelineLayout;
public SpecData SpecializationData;
@@ -319,6 +320,7 @@ namespace Ryujinx.Graphics.Vulkan
public void Initialize()
{
+ HasTessellationControlShader = false;
Stages = new NativeArray<PipelineShaderStageCreateInfo>(Constants.MaxShaderStages);
AdvancedBlendSrcPreMultiplied = true;
@@ -419,6 +421,15 @@ namespace Ryujinx.Graphics.Vulkan
PVertexBindingDescriptions = pVertexBindingDescriptions,
};
+ // Using patches topology without a tessellation shader is invalid.
+ // If we find such a case, return null pipeline to skip the draw.
+ if (Topology == PrimitiveTopology.PatchList && !HasTessellationControlShader)
+ {
+ program.AddGraphicsPipeline(ref Internal, null);
+
+ return null;
+ }
+
bool primitiveRestartEnable = PrimitiveRestartEnable;
bool topologySupportsRestart;
diff --git a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
index e4ea0e4e..b2be541b 100644
--- a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
+++ b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
@@ -21,6 +21,7 @@ namespace Ryujinx.Graphics.Vulkan
public bool HasMinimalLayout { get; }
public bool UsePushDescriptors { get; }
public bool IsCompute { get; }
+ public bool HasTessellationControlShader => (Stages & (1u << 3)) != 0;
public uint Stages { get; }
@@ -461,6 +462,7 @@ namespace Ryujinx.Graphics.Vulkan
stages[i] = _shaders[i].GetInfo();
}
+ pipeline.HasTessellationControlShader = HasTessellationControlShader;
pipeline.StagesCount = (uint)_shaders.Length;
pipeline.PipelineLayout = PipelineLayout;