aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Vulkan
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan')
-rw-r--r--src/Ryujinx.Graphics.Vulkan/DescriptorSetCollection.cs4
-rw-r--r--src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs33
-rw-r--r--src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs56
-rw-r--r--src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs1
4 files changed, 67 insertions, 27 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetCollection.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetCollection.cs
index 70b3ebfe..a185d787 100644
--- a/src/Ryujinx.Graphics.Vulkan/DescriptorSetCollection.cs
+++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetCollection.cs
@@ -16,9 +16,9 @@ namespace Ryujinx.Graphics.Vulkan
_descriptorSets = descriptorSets;
}
- public void InitializeBuffers(int setIndex, int baseBinding, int countPerUnit, DescriptorType type, VkBuffer dummyBuffer)
+ public void InitializeBuffers(int setIndex, int baseBinding, int count, DescriptorType type, VkBuffer dummyBuffer)
{
- Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[countPerUnit];
+ Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[count];
infos.Fill(new DescriptorBufferInfo()
{
diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs
index cbac1cd4..b09a0667 100644
--- a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs
+++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs
@@ -596,36 +596,19 @@ namespace Ryujinx.Graphics.Vulkan
}
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void Initialize(CommandBufferScoped cbs, int setIndex, DescriptorSetCollection dsc)
{
- var dummyBuffer = _dummyBuffer?.GetBuffer().Get(cbs).Value ?? default;
+ // We don't support clearing texture descriptors currently.
+ if (setIndex != PipelineBase.UniformSetIndex && setIndex != PipelineBase.StorageSetIndex)
+ {
+ return;
+ }
- uint stages = _program.Stages;
+ var dummyBuffer = _dummyBuffer?.GetBuffer().Get(cbs).Value ?? default;
- while (stages != 0)
+ foreach (ResourceBindingSegment segment in _program.ClearSegments[setIndex])
{
- int stage = BitOperations.TrailingZeroCount(stages);
- stages &= ~(1u << stage);
-
- if (setIndex == PipelineBase.UniformSetIndex)
- {
- dsc.InitializeBuffers(
- 0,
- 1 + stage * Constants.MaxUniformBuffersPerStage,
- Constants.MaxUniformBuffersPerStage,
- DescriptorType.UniformBuffer,
- dummyBuffer);
- }
- else if (setIndex == PipelineBase.StorageSetIndex)
- {
- dsc.InitializeBuffers(
- 0,
- stage * Constants.MaxStorageBuffersPerStage,
- Constants.MaxStorageBuffersPerStage,
- DescriptorType.StorageBuffer,
- dummyBuffer);
- }
+ dsc.InitializeBuffers(0, segment.Binding, segment.Count, segment.Type.Convert(), dummyBuffer);
}
}
diff --git a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
index 334dfc20..222cdf2a 100644
--- a/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
+++ b/src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
@@ -24,6 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
public uint Stages { get; }
+ public ResourceBindingSegment[][] ClearSegments { get; }
public ResourceBindingSegment[][] BindingSegments { get; }
public ProgramLinkStatus LinkStatus { get; private set; }
@@ -115,6 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
Stages = stages;
+ ClearSegments = BuildClearSegments(resourceLayout.Sets);
BindingSegments = BuildBindingSegments(resourceLayout.SetUsages);
_compileTask = Task.CompletedTask;
@@ -135,6 +137,60 @@ namespace Ryujinx.Graphics.Vulkan
_firstBackgroundUse = !fromCache;
}
+ private static ResourceBindingSegment[][] BuildClearSegments(ReadOnlyCollection<ResourceDescriptorCollection> sets)
+ {
+ ResourceBindingSegment[][] segments = new ResourceBindingSegment[sets.Count][];
+
+ for (int setIndex = 0; setIndex < sets.Count; setIndex++)
+ {
+ List<ResourceBindingSegment> currentSegments = new List<ResourceBindingSegment>();
+
+ ResourceDescriptor currentDescriptor = default;
+ int currentCount = 0;
+
+ for (int index = 0; index < sets[setIndex].Descriptors.Count; index++)
+ {
+ ResourceDescriptor descriptor = sets[setIndex].Descriptors[index];
+
+ if (currentDescriptor.Binding + currentCount != descriptor.Binding ||
+ currentDescriptor.Type != descriptor.Type ||
+ currentDescriptor.Stages != descriptor.Stages)
+ {
+ if (currentCount != 0)
+ {
+ currentSegments.Add(new ResourceBindingSegment(
+ currentDescriptor.Binding,
+ currentCount,
+ currentDescriptor.Type,
+ currentDescriptor.Stages,
+ ResourceAccess.ReadWrite));
+ }
+
+ currentDescriptor = descriptor;
+ currentCount = descriptor.Count;
+ }
+ else
+ {
+ currentCount += descriptor.Count;
+ }
+ }
+
+ if (currentCount != 0)
+ {
+ currentSegments.Add(new ResourceBindingSegment(
+ currentDescriptor.Binding,
+ currentCount,
+ currentDescriptor.Type,
+ currentDescriptor.Stages,
+ ResourceAccess.ReadWrite));
+ }
+
+ segments[setIndex] = currentSegments.ToArray();
+ }
+
+ return segments;
+ }
+
private static ResourceBindingSegment[][] BuildBindingSegments(ReadOnlyCollection<ResourceUsageCollection> setUsages)
{
ResourceBindingSegment[][] segments = new ResourceBindingSegment[setUsages.Count][];
diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index a059d683..8c1787d6 100644
--- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -589,6 +589,7 @@ namespace Ryujinx.Graphics.Vulkan
supportsFragmentShaderOrderingIntel: false,
supportsGeometryShader: Capabilities.SupportsGeometryShader,
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
+ supportsTransformFeedback: Capabilities.SupportsTransformFeedback,
supportsImageLoadFormatted: features2.Features.ShaderStorageImageReadWithoutFormat,
supportsLayerVertexTessellation: featuresVk12.ShaderOutputLayer,
supportsMismatchingViewFormat: true,