diff options
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan')
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, |