Allow texture arrays to use separate descriptor sets on Vulkan (#6870)
* Report base and extra sets from the backend * Pass texture set index everywhere * Key textures using set and binding (rather than just binding) * Start using extra sets for array textures * Shader cache version bump * Separate new commands, some PR feedback * Introduce new manual descriptor set reservation method that prevents it from being used by something else while owned by an array * Move bind extra sets logic to new method * Should only use separate array is MaximumExtraSets is not zero * Format whitespace
This commit is contained in:
parent
4cc00bb4b1
commit
53d096e392
47 changed files with 996 additions and 262 deletions
|
@ -3,6 +3,7 @@ using Silk.NET.Vulkan;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
|
@ -27,6 +28,24 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
private int _dsLastCbIndex;
|
||||
private int _dsLastSubmissionCount;
|
||||
|
||||
private struct ManualDescriptorSetEntry
|
||||
{
|
||||
public Auto<DescriptorSetCollection> DescriptorSet;
|
||||
public int CbIndex;
|
||||
public int CbSubmissionCount;
|
||||
public bool InUse;
|
||||
|
||||
public ManualDescriptorSetEntry(Auto<DescriptorSetCollection> descriptorSet, int cbIndex, int cbSubmissionCount, bool inUse)
|
||||
{
|
||||
DescriptorSet = descriptorSet;
|
||||
CbIndex = cbIndex;
|
||||
CbSubmissionCount = cbSubmissionCount;
|
||||
InUse = inUse;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<ManualDescriptorSetEntry>[] _manualDsCache;
|
||||
|
||||
private readonly Dictionary<long, DescriptorSetTemplate> _pdTemplates;
|
||||
private readonly ResourceDescriptorCollection _pdDescriptors;
|
||||
private long _lastPdUsage;
|
||||
|
@ -50,6 +69,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
}
|
||||
|
||||
_dsCacheCursor = new int[setsCount];
|
||||
_manualDsCache = new List<ManualDescriptorSetEntry>[setsCount];
|
||||
}
|
||||
|
||||
public PipelineLayoutCacheEntry(
|
||||
|
@ -124,6 +144,51 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
return list[index];
|
||||
}
|
||||
|
||||
public Auto<DescriptorSetCollection> GetNewManualDescriptorSetCollection(int commandBufferIndex, int setIndex, out int cacheIndex)
|
||||
{
|
||||
int submissionCount = _gd.CommandBufferPool.GetSubmissionCount(commandBufferIndex);
|
||||
|
||||
var list = _manualDsCache[setIndex] ??= new();
|
||||
var span = CollectionsMarshal.AsSpan(list);
|
||||
|
||||
for (int index = 0; index < span.Length; index++)
|
||||
{
|
||||
ref ManualDescriptorSetEntry entry = ref span[index];
|
||||
|
||||
if (!entry.InUse && (entry.CbIndex != commandBufferIndex || entry.CbSubmissionCount != submissionCount))
|
||||
{
|
||||
entry.InUse = true;
|
||||
entry.CbIndex = commandBufferIndex;
|
||||
entry.CbSubmissionCount = submissionCount;
|
||||
|
||||
cacheIndex = index;
|
||||
|
||||
return entry.DescriptorSet;
|
||||
}
|
||||
}
|
||||
|
||||
var dsc = _descriptorSetManager.AllocateDescriptorSet(
|
||||
_gd.Api,
|
||||
DescriptorSetLayouts[setIndex],
|
||||
_poolSizes[setIndex],
|
||||
setIndex,
|
||||
_consumedDescriptorsPerSet[setIndex],
|
||||
false);
|
||||
|
||||
cacheIndex = list.Count;
|
||||
list.Add(new ManualDescriptorSetEntry(dsc, commandBufferIndex, submissionCount, inUse: true));
|
||||
|
||||
return dsc;
|
||||
}
|
||||
|
||||
public void ReleaseManualDescriptorSetCollection(int setIndex, int cacheIndex)
|
||||
{
|
||||
var list = _manualDsCache[setIndex];
|
||||
var span = CollectionsMarshal.AsSpan(list);
|
||||
|
||||
span[cacheIndex].InUse = false;
|
||||
}
|
||||
|
||||
private static Span<DescriptorPoolSize> GetDescriptorPoolSizes(Span<DescriptorPoolSize> output, ResourceDescriptorCollection setDescriptor, uint multiplier)
|
||||
{
|
||||
int count = 0;
|
||||
|
@ -204,6 +269,21 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < _manualDsCache.Length; i++)
|
||||
{
|
||||
if (_manualDsCache[i] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < _manualDsCache[i].Count; j++)
|
||||
{
|
||||
_manualDsCache[i][j].DescriptorSet.Dispose();
|
||||
}
|
||||
|
||||
_manualDsCache[i].Clear();
|
||||
}
|
||||
|
||||
_gd.Api.DestroyPipelineLayout(_device, PipelineLayout, null);
|
||||
|
||||
for (int i = 0; i < DescriptorSetLayouts.Length; i++)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue