Add support for large sampler arrays on Vulkan (#6489)

* Add support for large sampler arrays on Vulkan

* Shader cache version bump

* Format whitespace

* Move DescriptorSetManager to PipelineLayoutCacheEntry to allow different pool sizes per layout

* Handle array textures with different types on the same buffer

* Somewhat better caching system

* Avoid useless buffer data modification checks

* Move redundant bindings update checking to the backend

* Fix an issue where texture arrays would get the same bindings across stages on Vulkan

* Backport some fixes from part 2

* Fix typo

* PR feedback

* Format whitespace

* Add some missing XML docs
This commit is contained in:
gdkchan 2024-04-07 18:25:55 -03:00 committed by GitHub
parent 808803d97a
commit 3e6e0e4afa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
83 changed files with 3263 additions and 955 deletions

View file

@ -20,6 +20,9 @@ namespace Ryujinx.Graphics.Gpu.Shader
private int _reservedTextures;
private int _reservedImages;
private int _staticTexturesCount;
private int _staticImagesCount;
/// <summary>
/// Creates a new GPU accessor.
/// </summary>
@ -48,7 +51,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
_reservedImages = rrc.ReservedImages;
}
public int QueryBindingConstantBuffer(int index)
public int CreateConstantBufferBinding(int index)
{
int binding;
@ -64,7 +67,39 @@ namespace Ryujinx.Graphics.Gpu.Shader
return binding + _reservedConstantBuffers;
}
public int QueryBindingStorageBuffer(int index)
public int CreateImageBinding(int count, bool isBuffer)
{
int binding;
if (_context.Capabilities.Api == TargetApi.Vulkan)
{
if (count == 1)
{
int index = _staticImagesCount++;
if (isBuffer)
{
index += (int)_context.Capabilities.MaximumImagesPerStage;
}
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumImagesPerStage * 2, "Image");
}
else
{
binding = (int)GetDynamicBaseIndexDual(_context.Capabilities.MaximumImagesPerStage) + _resourceCounts.ImagesCount++;
}
}
else
{
binding = _resourceCounts.ImagesCount;
_resourceCounts.ImagesCount += count;
}
return binding + _reservedImages;
}
public int CreateStorageBufferBinding(int index)
{
int binding;
@ -80,48 +115,38 @@ namespace Ryujinx.Graphics.Gpu.Shader
return binding + _reservedStorageBuffers;
}
public int QueryBindingTexture(int index, bool isBuffer)
public int CreateTextureBinding(int count, bool isBuffer)
{
int binding;
if (_context.Capabilities.Api == TargetApi.Vulkan)
{
if (isBuffer)
if (count == 1)
{
index += (int)_context.Capabilities.MaximumTexturesPerStage;
}
int index = _staticTexturesCount++;
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumTexturesPerStage * 2, "Texture");
if (isBuffer)
{
index += (int)_context.Capabilities.MaximumTexturesPerStage;
}
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumTexturesPerStage * 2, "Texture");
}
else
{
binding = (int)GetDynamicBaseIndexDual(_context.Capabilities.MaximumTexturesPerStage) + _resourceCounts.TexturesCount++;
}
}
else
{
binding = _resourceCounts.TexturesCount++;
binding = _resourceCounts.TexturesCount;
_resourceCounts.TexturesCount += count;
}
return binding + _reservedTextures;
}
public int QueryBindingImage(int index, bool isBuffer)
{
int binding;
if (_context.Capabilities.Api == TargetApi.Vulkan)
{
if (isBuffer)
{
index += (int)_context.Capabilities.MaximumImagesPerStage;
}
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumImagesPerStage * 2, "Image");
}
else
{
binding = _resourceCounts.ImagesCount++;
}
return binding + _reservedImages;
}
private int GetBindingFromIndex(int index, uint maxPerStage, string resourceName)
{
if ((uint)index >= maxPerStage)
@ -148,6 +173,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
};
}
private static uint GetDynamicBaseIndexDual(uint maxPerStage)
{
return GetDynamicBaseIndex(maxPerStage) * 2;
}
private static uint GetDynamicBaseIndex(uint maxPerStage)
{
return maxPerStage * Constants.ShaderStages;
}
public int QueryHostGatherBiasPrecision() => _context.Capabilities.GatherBiasPrecision;
public bool QueryHostReducedPrecision() => _context.Capabilities.ReduceShaderPrecision;