Report base and extra sets from the backend
This commit is contained in:
parent
c98b7fc702
commit
f83a4739ce
9 changed files with 141 additions and 36 deletions
|
@ -51,6 +51,13 @@ namespace Ryujinx.Graphics.GAL
|
|||
public readonly bool SupportsIndirectParameters;
|
||||
public readonly bool SupportsDepthClipControl;
|
||||
|
||||
public readonly int UniformBufferSetIndex;
|
||||
public readonly int StorageBufferSetIndex;
|
||||
public readonly int TextureSetIndex;
|
||||
public readonly int ImageSetIndex;
|
||||
public readonly int ExtraSetBaseIndex;
|
||||
public readonly int MaximumExtraSets;
|
||||
|
||||
public readonly uint MaximumUniformBuffersPerStage;
|
||||
public readonly uint MaximumStorageBuffersPerStage;
|
||||
public readonly uint MaximumTexturesPerStage;
|
||||
|
@ -109,6 +116,12 @@ namespace Ryujinx.Graphics.GAL
|
|||
bool supportsViewportSwizzle,
|
||||
bool supportsIndirectParameters,
|
||||
bool supportsDepthClipControl,
|
||||
int uniformBufferSetIndex,
|
||||
int storageBufferSetIndex,
|
||||
int textureSetIndex,
|
||||
int imageSetIndex,
|
||||
int extraSetBaseIndex,
|
||||
int maximumExtraSets,
|
||||
uint maximumUniformBuffersPerStage,
|
||||
uint maximumStorageBuffersPerStage,
|
||||
uint maximumTexturesPerStage,
|
||||
|
@ -164,6 +177,12 @@ namespace Ryujinx.Graphics.GAL
|
|||
SupportsViewportSwizzle = supportsViewportSwizzle;
|
||||
SupportsIndirectParameters = supportsIndirectParameters;
|
||||
SupportsDepthClipControl = supportsDepthClipControl;
|
||||
UniformBufferSetIndex = uniformBufferSetIndex;
|
||||
StorageBufferSetIndex = storageBufferSetIndex;
|
||||
TextureSetIndex = textureSetIndex;
|
||||
ImageSetIndex = imageSetIndex;
|
||||
ExtraSetBaseIndex = extraSetBaseIndex;
|
||||
MaximumExtraSets = maximumExtraSets;
|
||||
MaximumUniformBuffersPerStage = maximumUniformBuffersPerStage;
|
||||
MaximumStorageBuffersPerStage = maximumStorageBuffersPerStage;
|
||||
MaximumTexturesPerStage = maximumTexturesPerStage;
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
_reservedImages = rrc.ReservedImages;
|
||||
}
|
||||
|
||||
public int CreateConstantBufferBinding(int index)
|
||||
public SetBindingPair CreateConstantBufferBinding(int index)
|
||||
{
|
||||
int binding;
|
||||
|
||||
|
@ -64,10 +64,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
binding = _resourceCounts.UniformBuffersCount++;
|
||||
}
|
||||
|
||||
return binding + _reservedConstantBuffers;
|
||||
return new SetBindingPair(_context.Capabilities.UniformBufferSetIndex, binding + _reservedConstantBuffers);
|
||||
}
|
||||
|
||||
public int CreateImageBinding(int count, bool isBuffer)
|
||||
public SetBindingPair CreateImageBinding(int count, bool isBuffer)
|
||||
{
|
||||
int binding;
|
||||
|
||||
|
@ -96,10 +96,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
_resourceCounts.ImagesCount += count;
|
||||
}
|
||||
|
||||
return binding + _reservedImages;
|
||||
return new SetBindingPair(_context.Capabilities.ImageSetIndex, binding + _reservedImages);
|
||||
}
|
||||
|
||||
public int CreateStorageBufferBinding(int index)
|
||||
public SetBindingPair CreateStorageBufferBinding(int index)
|
||||
{
|
||||
int binding;
|
||||
|
||||
|
@ -112,10 +112,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
binding = _resourceCounts.StorageBuffersCount++;
|
||||
}
|
||||
|
||||
return binding + _reservedStorageBuffers;
|
||||
return new SetBindingPair(_context.Capabilities.StorageBufferSetIndex, binding + _reservedStorageBuffers);
|
||||
}
|
||||
|
||||
public int CreateTextureBinding(int count, bool isBuffer)
|
||||
public SetBindingPair CreateTextureBinding(int count, bool isBuffer)
|
||||
{
|
||||
int binding;
|
||||
|
||||
|
@ -144,7 +144,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
_resourceCounts.TexturesCount += count;
|
||||
}
|
||||
|
||||
return binding + _reservedTextures;
|
||||
return new SetBindingPair(_context.Capabilities.TextureSetIndex, binding + _reservedTextures);
|
||||
}
|
||||
|
||||
private int GetBindingFromIndex(int index, uint maxPerStage, string resourceName)
|
||||
|
@ -183,6 +183,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
return maxPerStage * Constants.ShaderStages;
|
||||
}
|
||||
|
||||
public int CreateExtraSet()
|
||||
{
|
||||
if (_resourceCounts.SetsCount >= _context.Capabilities.MaximumExtraSets)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _context.Capabilities.ExtraSetBaseIndex + _resourceCounts.SetsCount++;
|
||||
}
|
||||
|
||||
public int QueryHostGatherBiasPrecision() => _context.Capabilities.GatherBiasPrecision;
|
||||
|
||||
public bool QueryHostReducedPrecision() => _context.Capabilities.ReduceShaderPrecision;
|
||||
|
|
|
@ -24,5 +24,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||
/// Total of images used by the shaders.
|
||||
/// </summary>
|
||||
public int ImagesCount;
|
||||
|
||||
/// <summary>
|
||||
/// Total of extra sets used by the shaders.
|
||||
/// </summary>
|
||||
public int SetsCount;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -187,6 +187,12 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
supportsViewportSwizzle: HwCapabilities.SupportsViewportSwizzle,
|
||||
supportsIndirectParameters: HwCapabilities.SupportsIndirectParameters,
|
||||
supportsDepthClipControl: true,
|
||||
uniformBufferSetIndex: 0,
|
||||
storageBufferSetIndex: 1,
|
||||
textureSetIndex: 2,
|
||||
imageSetIndex: 3,
|
||||
extraSetBaseIndex: 0,
|
||||
maximumExtraSets: 0,
|
||||
maximumUniformBuffersPerStage: 13, // TODO: Avoid hardcoding those limits here and get from driver?
|
||||
maximumStorageBuffersPerStage: 16,
|
||||
maximumTexturesPerStage: 32,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using Ryujinx.Graphics.Shader.CodeGen;
|
||||
using Ryujinx.Graphics.Shader.CodeGen;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader
|
||||
|
@ -27,34 +27,43 @@ namespace Ryujinx.Graphics.Shader
|
|||
ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize);
|
||||
|
||||
/// <summary>
|
||||
/// Queries the binding number of a constant buffer.
|
||||
/// Gets the binding number of a constant buffer.
|
||||
/// </summary>
|
||||
/// <param name="index">Constant buffer index</param>
|
||||
/// <returns>Binding number</returns>
|
||||
int CreateConstantBufferBinding(int index);
|
||||
SetBindingPair CreateConstantBufferBinding(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Queries the binding number of an image.
|
||||
/// Gets the binding number of an image.
|
||||
/// </summary>
|
||||
/// <param name="count">For array of images, the number of elements of the array, otherwise it should be 1</param>
|
||||
/// <param name="isBuffer">Indicates if the image is a buffer image</param>
|
||||
/// <returns>Binding number</returns>
|
||||
int CreateImageBinding(int count, bool isBuffer);
|
||||
SetBindingPair CreateImageBinding(int count, bool isBuffer);
|
||||
|
||||
/// <summary>
|
||||
/// Queries the binding number of a storage buffer.
|
||||
/// Gets the binding number of a storage buffer.
|
||||
/// </summary>
|
||||
/// <param name="index">Storage buffer index</param>
|
||||
/// <returns>Binding number</returns>
|
||||
int CreateStorageBufferBinding(int index);
|
||||
SetBindingPair CreateStorageBufferBinding(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Queries the binding number of a texture.
|
||||
/// Gets the binding number of a texture.
|
||||
/// </summary>
|
||||
/// <param name="count">For array of textures, the number of elements of the array, otherwise it should be 1</param>
|
||||
/// <param name="isBuffer">Indicates if the texture is a buffer texture</param>
|
||||
/// <returns>Binding number</returns>
|
||||
int CreateTextureBinding(int count, bool isBuffer);
|
||||
SetBindingPair CreateTextureBinding(int count, bool isBuffer);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the set index for an additional set, or -1 if there's no extra set available.
|
||||
/// </summary>
|
||||
/// <returns>Extra set index, or -1 if not available</returns>
|
||||
int CreateExtraSet()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Queries Local Size X for compute shaders.
|
||||
|
|
41
src/Ryujinx.Graphics.Shader/SetBindingPair.cs
Normal file
41
src/Ryujinx.Graphics.Shader/SetBindingPair.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Shader
|
||||
{
|
||||
public readonly struct SetBindingPair : IEquatable<SetBindingPair>
|
||||
{
|
||||
public readonly int SetIndex;
|
||||
public readonly int Binding;
|
||||
|
||||
public SetBindingPair(int setIndex, int binding)
|
||||
{
|
||||
SetIndex = setIndex;
|
||||
Binding = binding;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is SetBindingPair other && Equals(other);
|
||||
}
|
||||
|
||||
public bool Equals(SetBindingPair other)
|
||||
{
|
||||
return SetIndex == other.SetIndex && Binding == other.Binding;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (((ulong)(uint)SetIndex << 32) | (uint)Binding).GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator ==(SetBindingPair left, SetBindingPair right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(SetBindingPair left, SetBindingPair right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,6 +33,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
private struct TextureMeta
|
||||
{
|
||||
public int Set;
|
||||
public int Binding;
|
||||
public bool AccurateType;
|
||||
public SamplerType Type;
|
||||
|
@ -149,10 +150,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
int binding = _cbSlotToBindingMap[slot];
|
||||
if (binding < 0)
|
||||
{
|
||||
binding = _gpuAccessor.CreateConstantBufferBinding(slot);
|
||||
SetBindingPair setAndBinding = _gpuAccessor.CreateConstantBufferBinding(slot);
|
||||
binding = setAndBinding.Binding;
|
||||
_cbSlotToBindingMap[slot] = binding;
|
||||
string slotNumber = slot.ToString(CultureInfo.InvariantCulture);
|
||||
AddNewConstantBuffer(binding, $"{_stagePrefix}_c{slotNumber}");
|
||||
AddNewConstantBuffer(setAndBinding.SetIndex, binding, $"{_stagePrefix}_c{slotNumber}");
|
||||
}
|
||||
|
||||
return binding;
|
||||
|
@ -170,10 +172,11 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
if (binding < 0)
|
||||
{
|
||||
binding = _gpuAccessor.CreateStorageBufferBinding(slot);
|
||||
SetBindingPair setAndBinding = _gpuAccessor.CreateStorageBufferBinding(slot);
|
||||
binding = setAndBinding.Binding;
|
||||
_sbSlotToBindingMap[slot] = binding;
|
||||
string slotNumber = slot.ToString(CultureInfo.InvariantCulture);
|
||||
AddNewStorageBuffer(binding, $"{_stagePrefix}_s{slotNumber}");
|
||||
AddNewStorageBuffer(setAndBinding.SetIndex, binding, $"{_stagePrefix}_s{slotNumber}");
|
||||
}
|
||||
|
||||
if (write)
|
||||
|
@ -311,21 +314,26 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
UsageFlags = usageFlags,
|
||||
};
|
||||
|
||||
int setIndex;
|
||||
int binding;
|
||||
|
||||
if (dict.TryGetValue(info, out var existingMeta))
|
||||
{
|
||||
dict[info] = MergeTextureMeta(meta, existingMeta);
|
||||
setIndex = existingMeta.Set;
|
||||
binding = existingMeta.Binding;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isBuffer = (type & SamplerType.Mask) == SamplerType.TextureBuffer;
|
||||
|
||||
binding = isImage
|
||||
SetBindingPair setAndBinding = isImage
|
||||
? _gpuAccessor.CreateImageBinding(arrayLength, isBuffer)
|
||||
: _gpuAccessor.CreateTextureBinding(arrayLength, isBuffer);
|
||||
|
||||
setIndex = setAndBinding.SetIndex;
|
||||
binding = setAndBinding.Binding;
|
||||
meta.Set = setIndex;
|
||||
meta.Binding = binding;
|
||||
|
||||
dict.Add(info, meta);
|
||||
|
@ -355,7 +363,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
}
|
||||
|
||||
var definition = new TextureDefinition(
|
||||
isImage ? 3 : 2,
|
||||
setIndex,
|
||||
binding,
|
||||
arrayLength,
|
||||
separate,
|
||||
|
@ -378,6 +386,7 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
|
||||
private static TextureMeta MergeTextureMeta(TextureMeta meta, TextureMeta existingMeta)
|
||||
{
|
||||
meta.Set = existingMeta.Set;
|
||||
meta.Binding = existingMeta.Binding;
|
||||
meta.UsageFlags |= existingMeta.UsageFlags;
|
||||
|
||||
|
@ -587,24 +596,24 @@ namespace Ryujinx.Graphics.Shader.Translation
|
|||
return false;
|
||||
}
|
||||
|
||||
private void AddNewConstantBuffer(int binding, string name)
|
||||
private void AddNewConstantBuffer(int setIndex, int binding, string name)
|
||||
{
|
||||
StructureType type = new(new[]
|
||||
{
|
||||
new StructureField(AggregateType.Array | AggregateType.Vector4 | AggregateType.FP32, "data", Constants.ConstantBufferSize / 16),
|
||||
});
|
||||
|
||||
Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, 0, binding, name, type));
|
||||
Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, setIndex, binding, name, type));
|
||||
}
|
||||
|
||||
private void AddNewStorageBuffer(int binding, string name)
|
||||
private void AddNewStorageBuffer(int setIndex, int binding, string name)
|
||||
{
|
||||
StructureType type = new(new[]
|
||||
{
|
||||
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0),
|
||||
});
|
||||
|
||||
Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, 1, binding, name, type));
|
||||
Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, setIndex, binding, name, type));
|
||||
}
|
||||
|
||||
public static string GetShaderStagePrefix(ShaderStage stage)
|
||||
|
|
|
@ -728,6 +728,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||
supportsViewportSwizzle: false,
|
||||
supportsIndirectParameters: true,
|
||||
supportsDepthClipControl: Capabilities.SupportsDepthClipControl,
|
||||
uniformBufferSetIndex: PipelineBase.UniformSetIndex,
|
||||
storageBufferSetIndex: PipelineBase.StorageSetIndex,
|
||||
textureSetIndex: PipelineBase.TextureSetIndex,
|
||||
imageSetIndex: PipelineBase.ImageSetIndex,
|
||||
extraSetBaseIndex: PipelineBase.DescriptorSetLayouts,
|
||||
maximumExtraSets: Math.Max(0, (int)limits.MaxBoundDescriptorSets - PipelineBase.DescriptorSetLayouts),
|
||||
maximumUniformBuffersPerStage: Constants.MaxUniformBuffersPerStage,
|
||||
maximumStorageBuffersPerStage: Constants.MaxStorageBuffersPerStage,
|
||||
maximumTexturesPerStage: Constants.MaxTexturesPerStage,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using CommandLine;
|
||||
using CommandLine;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using System;
|
||||
|
@ -25,32 +25,32 @@ namespace Ryujinx.ShaderTools
|
|||
_imagesCount = 0;
|
||||
}
|
||||
|
||||
public int CreateConstantBufferBinding(int index)
|
||||
public SetBindingPair CreateConstantBufferBinding(int index)
|
||||
{
|
||||
return index + 1;
|
||||
return new SetBindingPair(0, index + 1);
|
||||
}
|
||||
|
||||
public int CreateImageBinding(int count, bool isBuffer)
|
||||
public SetBindingPair CreateImageBinding(int count, bool isBuffer)
|
||||
{
|
||||
int binding = _imagesCount;
|
||||
|
||||
_imagesCount += count;
|
||||
|
||||
return binding;
|
||||
return new SetBindingPair(3, binding);
|
||||
}
|
||||
|
||||
public int CreateStorageBufferBinding(int index)
|
||||
public SetBindingPair CreateStorageBufferBinding(int index)
|
||||
{
|
||||
return index;
|
||||
return new SetBindingPair(1, index);
|
||||
}
|
||||
|
||||
public int CreateTextureBinding(int count, bool isBuffer)
|
||||
public SetBindingPair CreateTextureBinding(int count, bool isBuffer)
|
||||
{
|
||||
int binding = _texturesCount;
|
||||
|
||||
_texturesCount += count;
|
||||
|
||||
return binding;
|
||||
return new SetBindingPair(2, binding);
|
||||
}
|
||||
|
||||
public ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize)
|
||||
|
|
Loading…
Add table
Reference in a new issue