Vulkan separate descriptor set fixes (#6895)

* Ensure descriptor sets are only re-used when all command buffers using it have completed

* Fix some SPIR-V capabilities

* Set update after bind flag if we exceed limits

* Simpler fix for Intel

* Format whitespace

* Make struct readonly

* Add barriers for extra set arrays too
This commit is contained in:
gdkchan 2024-06-02 22:40:28 -03:00 committed by GitHub
parent d7c6474729
commit c0f2491eae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 365 additions and 113 deletions

View file

@ -2,11 +2,10 @@ using Ryujinx.Graphics.GAL;
using Silk.NET.Vulkan;
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace Ryujinx.Graphics.Vulkan
{
class ImageArray : IImageArray
class ImageArray : ResourceArray, IImageArray
{
private readonly VulkanRenderer _gd;
@ -25,19 +24,11 @@ namespace Ryujinx.Graphics.Vulkan
private HashSet<TextureStorage> _storages;
private DescriptorSet[] _cachedDescriptorSets;
private int _cachedCommandBufferIndex;
private int _cachedSubmissionCount;
private ShaderCollection _cachedDscProgram;
private int _cachedDscSetIndex;
private int _cachedDscIndex;
private readonly bool _isBuffer;
private int _bindCount;
public ImageArray(VulkanRenderer gd, int size, bool isBuffer)
{
_gd = gd;
@ -104,12 +95,7 @@ namespace Ryujinx.Graphics.Vulkan
{
_cachedCommandBufferIndex = -1;
_storages = null;
_cachedDescriptorSets = null;
if (_bindCount != 0)
{
_gd.PipelineInternal.ForceImageDirty();
}
SetDirty(_gd);
}
public void QueueWriteToReadBarriers(CommandBufferScoped cbs, PipelineStageFlags stageFlags)
@ -195,7 +181,7 @@ namespace Ryujinx.Graphics.Vulkan
int setIndex,
TextureView dummyTexture)
{
if (_cachedDescriptorSets != null)
if (TryGetCachedDescriptorSets(cbs, program, setIndex, out DescriptorSet[] sets))
{
// We still need to ensure the current command buffer holds a reference to all used textures.
@ -208,12 +194,9 @@ namespace Ryujinx.Graphics.Vulkan
GetBufferViews(cbs);
}
return _cachedDescriptorSets;
return sets;
}
_cachedDscProgram?.ReleaseManualDescriptorSetCollection(_cachedDscSetIndex, _cachedDscIndex);
var dsc = program.GetNewManualDescriptorSetCollection(cbs.CommandBufferIndex, setIndex, out _cachedDscIndex).Get(cbs);
DescriptorSetTemplate template = program.Templates[setIndex];
DescriptorSetTemplateWriter tu = templateUpdater.Begin(template);
@ -227,24 +210,9 @@ namespace Ryujinx.Graphics.Vulkan
tu.Push(GetBufferViews(cbs));
}
var sets = dsc.GetSets();
templateUpdater.Commit(_gd, device, sets[0]);
_cachedDescriptorSets = sets;
_cachedDscProgram = program;
_cachedDscSetIndex = setIndex;
return sets;
}
public void IncrementBindCount()
{
_bindCount++;
}
public void DecrementBindCount()
{
int newBindCount = --_bindCount;
Debug.Assert(newBindCount >= 0);
}
}
}