aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs')
-rw-r--r--src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
index b1547b79..c9aab401 100644
--- a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
+++ b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
@@ -27,6 +27,9 @@ namespace Ryujinx.Graphics.Vulkan
public uint Stages { get; }
+ public PipelineStageFlags IncoherentBufferWriteStages { get; }
+ public PipelineStageFlags IncoherentTextureWriteStages { get; }
+
public ResourceBindingSegment[][] ClearSegments { get; }
public ResourceBindingSegment[][] BindingSegments { get; }
public DescriptorSetTemplate[] Templates { get; }
@@ -131,6 +134,7 @@ namespace Ryujinx.Graphics.Vulkan
ClearSegments = BuildClearSegments(sets);
BindingSegments = BuildBindingSegments(resourceLayout.SetUsages, out bool usesBufferTextures);
Templates = BuildTemplates(usePushDescriptors);
+ (IncoherentBufferWriteStages, IncoherentTextureWriteStages) = BuildIncoherentStages(resourceLayout.SetUsages);
// Updating buffer texture bindings using template updates crashes the Adreno driver on Windows.
UpdateTexturesWithoutTemplate = gd.IsQualcommProprietary && usesBufferTextures;
@@ -377,6 +381,73 @@ namespace Ryujinx.Graphics.Vulkan
return templates;
}
+ private PipelineStageFlags GetPipelineStages(ResourceStages stages)
+ {
+ PipelineStageFlags result = 0;
+
+ if ((stages & ResourceStages.Compute) != 0)
+ {
+ result |= PipelineStageFlags.ComputeShaderBit;
+ }
+
+ if ((stages & ResourceStages.Vertex) != 0)
+ {
+ result |= PipelineStageFlags.VertexShaderBit;
+ }
+
+ if ((stages & ResourceStages.Fragment) != 0)
+ {
+ result |= PipelineStageFlags.FragmentShaderBit;
+ }
+
+ if ((stages & ResourceStages.Geometry) != 0)
+ {
+ result |= PipelineStageFlags.GeometryShaderBit;
+ }
+
+ if ((stages & ResourceStages.TessellationControl) != 0)
+ {
+ result |= PipelineStageFlags.TessellationControlShaderBit;
+ }
+
+ if ((stages & ResourceStages.TessellationEvaluation) != 0)
+ {
+ result |= PipelineStageFlags.TessellationEvaluationShaderBit;
+ }
+
+ return result;
+ }
+
+ private (PipelineStageFlags Buffer, PipelineStageFlags Texture) BuildIncoherentStages(ReadOnlyCollection<ResourceUsageCollection> setUsages)
+ {
+ PipelineStageFlags buffer = PipelineStageFlags.None;
+ PipelineStageFlags texture = PipelineStageFlags.None;
+
+ foreach (var set in setUsages)
+ {
+ foreach (var range in set.Usages)
+ {
+ if (range.Write)
+ {
+ PipelineStageFlags stages = GetPipelineStages(range.Stages);
+
+ switch (range.Type)
+ {
+ case ResourceType.Image:
+ texture |= stages;
+ break;
+ case ResourceType.StorageBuffer:
+ case ResourceType.BufferImage:
+ buffer |= stages;
+ break;
+ }
+ }
+ }
+ }
+
+ return (buffer, texture);
+ }
+
private async Task BackgroundCompilation()
{
await Task.WhenAll(_shaders.Select(shader => shader.CompileTask));