Skip to content

Commit

Permalink
Update descriptor init logic to account for ResourceLayout
Browse files Browse the repository at this point in the history
  • Loading branch information
gdkchan committed May 25, 2023
1 parent 30ecb50 commit d709b12
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 27 deletions.
4 changes: 2 additions & 2 deletions src/Ryujinx.Graphics.Vulkan/DescriptorSetCollection.cs
Expand Up @@ -16,9 +16,9 @@ public DescriptorSetCollection(DescriptorSetManager.DescriptorPoolHolder holder,
_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()
{
Expand Down
33 changes: 8 additions & 25 deletions src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs
Expand Up @@ -596,36 +596,19 @@ private void UpdateAndBindUniformBufferPd(CommandBufferScoped cbs, PipelineBindP
}
}

[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);
}
}

Expand Down
56 changes: 56 additions & 0 deletions src/Ryujinx.Graphics.Vulkan/ShaderCollection.cs
Expand Up @@ -24,6 +24,7 @@ class ShaderCollection : IProgram

public uint Stages { get; }

public ResourceBindingSegment[][] ClearSegments { get; }
public ResourceBindingSegment[][] BindingSegments { get; }

public ProgramLinkStatus LinkStatus { get; private set; }
Expand Down Expand Up @@ -115,6 +116,7 @@ public bool IsLinked

Stages = stages;

ClearSegments = BuildClearSegments(resourceLayout.Sets);
BindingSegments = BuildBindingSegments(resourceLayout.SetUsages);

_compileTask = Task.CompletedTask;
Expand All @@ -135,6 +137,60 @@ public bool IsLinked
_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][];
Expand Down

0 comments on commit d709b12

Please sign in to comment.