Raise textures limit to 64 on Vulkan

This commit is contained in:
gdk 2022-04-12 17:28:04 -03:00 committed by riperiperi
parent efa2868825
commit fd2e53fdc6
10 changed files with 59 additions and 17 deletions

View file

@ -640,4 +640,15 @@ namespace Ryujinx.Common.Memory
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref ToSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 64); public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 64);
} }
public struct Array73<T> : IArray<T> where T : unmanaged
{
#pragma warning disable CS0169
T _e0;
Array64<T> _other;
Array8<T> _other2;
#pragma warning restore CS0169
public int Length => 73;
public ref T this[int index] => ref ToSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 73);
}
} }

View file

@ -24,6 +24,11 @@ namespace Ryujinx.Graphics.GAL
public readonly bool SupportsViewportSwizzle; public readonly bool SupportsViewportSwizzle;
public readonly bool SupportsIndirectParameters; public readonly bool SupportsIndirectParameters;
public readonly uint MaximumUniformBuffersPerStage;
public readonly uint MaximumStorageBuffersPerStage;
public readonly uint MaximumTexturesPerStage;
public readonly uint MaximumImagesPerStage;
public readonly int MaximumComputeSharedMemorySize; public readonly int MaximumComputeSharedMemorySize;
public readonly float MaximumSupportedAnisotropy; public readonly float MaximumSupportedAnisotropy;
public readonly int StorageBufferOffsetAlignment; public readonly int StorageBufferOffsetAlignment;
@ -46,6 +51,10 @@ namespace Ryujinx.Graphics.GAL
bool supportsTextureShadowLod, bool supportsTextureShadowLod,
bool supportsViewportSwizzle, bool supportsViewportSwizzle,
bool supportsIndirectParameters, bool supportsIndirectParameters,
uint maximumUniformBuffersPerStage,
uint maximumStorageBuffersPerStage,
uint maximumTexturesPerStage,
uint maximumImagesPerStage,
int maximumComputeSharedMemorySize, int maximumComputeSharedMemorySize,
float maximumSupportedAnisotropy, float maximumSupportedAnisotropy,
int storageBufferOffsetAlignment) int storageBufferOffsetAlignment)
@ -67,6 +76,10 @@ namespace Ryujinx.Graphics.GAL
SupportsTextureShadowLod = supportsTextureShadowLod; SupportsTextureShadowLod = supportsTextureShadowLod;
SupportsViewportSwizzle = supportsViewportSwizzle; SupportsViewportSwizzle = supportsViewportSwizzle;
SupportsIndirectParameters = supportsIndirectParameters; SupportsIndirectParameters = supportsIndirectParameters;
MaximumUniformBuffersPerStage = maximumUniformBuffersPerStage;
MaximumStorageBuffersPerStage = maximumStorageBuffersPerStage;
MaximumTexturesPerStage = maximumTexturesPerStage;
MaximumImagesPerStage = maximumImagesPerStage;
MaximumComputeSharedMemorySize = maximumComputeSharedMemorySize; MaximumComputeSharedMemorySize = maximumComputeSharedMemorySize;
MaximumSupportedAnisotropy = maximumSupportedAnisotropy; MaximumSupportedAnisotropy = maximumSupportedAnisotropy;
StorageBufferOffsetAlignment = storageBufferOffsetAlignment; StorageBufferOffsetAlignment = storageBufferOffsetAlignment;

View file

@ -1,3 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Engine.Threed; using Ryujinx.Graphics.Gpu.Engine.Threed;
using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.Image;
@ -31,7 +32,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
{ {
if (_context.Capabilities.Api == TargetApi.Vulkan) if (_context.Capabilities.Api == TargetApi.Vulkan)
{ {
return 1 + GetStageIndex() * 18 + index; return 1 + GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer");
} }
else else
{ {
@ -44,7 +45,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
{ {
if (_context.Capabilities.Api == TargetApi.Vulkan) if (_context.Capabilities.Api == TargetApi.Vulkan)
{ {
return GetStageIndex() * 16 + index; return GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer");
} }
else else
{ {
@ -57,7 +58,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
{ {
if (_context.Capabilities.Api == TargetApi.Vulkan) if (_context.Capabilities.Api == TargetApi.Vulkan)
{ {
return GetStageIndex() * 32 + index; return GetBindingFromIndex(index, _context.Capabilities.MaximumTexturesPerStage, "Texture");
} }
else else
{ {
@ -70,7 +71,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
{ {
if (_context.Capabilities.Api == TargetApi.Vulkan) if (_context.Capabilities.Api == TargetApi.Vulkan)
{ {
return GetStageIndex() * 8 + index; return GetBindingFromIndex(index, _context.Capabilities.MaximumImagesPerStage, "Image");
} }
else else
{ {
@ -78,6 +79,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
} }
} }
private int GetBindingFromIndex(int index, uint maxPerStage, string resourceName)
{
if ((uint)index >= maxPerStage)
{
Logger.Error?.Print(LogClass.Gpu, $"{resourceName} index {index} exceeds per stage limit of {maxPerStage}.");
}
return GetStageIndex() * (int)maxPerStage + index;
}
private int GetStageIndex() private int GetStageIndex()
{ {
// This is just a simple remapping to ensure that most frequently used shader stages // This is just a simple remapping to ensure that most frequently used shader stages

View file

@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.OpenGL
private CounterQueueEvent _activeConditionalRender; private CounterQueueEvent _activeConditionalRender;
private Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount]; private Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount];
private Vector4<float>[] _renderScale = new Vector4<float>[65]; private Vector4<float>[] _renderScale = new Vector4<float>[73];
private int _fragmentScaleCount; private int _fragmentScaleCount;
private TextureBase _unit0Texture; private TextureBase _unit0Texture;

View file

@ -117,6 +117,10 @@ namespace Ryujinx.Graphics.OpenGL
supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod, supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod,
supportsViewportSwizzle: HwCapabilities.SupportsViewportSwizzle, supportsViewportSwizzle: HwCapabilities.SupportsViewportSwizzle,
supportsIndirectParameters: HwCapabilities.SupportsIndirectParameters, supportsIndirectParameters: HwCapabilities.SupportsIndirectParameters,
maximumUniformBuffersPerStage: 13, // TODO: Avoid hardcoding those limits here and get from driver?
maximumStorageBuffersPerStage: 16,
maximumTexturesPerStage: 32,
maximumImagesPerStage: 8,
maximumComputeSharedMemorySize: HwCapabilities.MaximumComputeSharedMemorySize, maximumComputeSharedMemorySize: HwCapabilities.MaximumComputeSharedMemorySize,
maximumSupportedAnisotropy: HwCapabilities.MaximumSupportedAnisotropy, maximumSupportedAnisotropy: HwCapabilities.MaximumSupportedAnisotropy,
storageBufferOffsetAlignment: HwCapabilities.StorageBufferOffsetAlignment); storageBufferOffsetAlignment: HwCapabilities.StorageBufferOffsetAlignment);

View file

@ -24,8 +24,8 @@ namespace Ryujinx.Graphics.Shader
public static int ComputeRenderScaleOffset; public static int ComputeRenderScaleOffset;
public const int FragmentIsBgraCount = 8; public const int FragmentIsBgraCount = 8;
// One for the render target, 32 for the textures, and 8 for the images. // One for the render target, 64 for the textures, and 8 for the images.
public const int RenderScaleMaxCount = 1 + 32 + 8; public const int RenderScaleMaxCount = 1 + 64 + 8;
private static int OffsetOf<T>(ref SupportBuffer storage, ref T target) private static int OffsetOf<T>(ref SupportBuffer storage, ref T target)
{ {
@ -52,7 +52,7 @@ namespace Ryujinx.Graphics.Shader
public Vector4<float> ViewportInverse; public Vector4<float> ViewportInverse;
public Vector4<int> FragmentRenderScaleCount; public Vector4<int> FragmentRenderScaleCount;
// Render scale max count: 1 + 32 + 8. First scale is fragment output scale, others are textures/image inputs. // Render scale max count: 1 + 64 + 8. First scale is fragment output scale, others are textures/image inputs.
public Array41<Vector4<float>> RenderScale; public Array73<Vector4<float>> RenderScale;
} }
} }

View file

@ -10,7 +10,7 @@
public const int MaxShaderStages = 5; public const int MaxShaderStages = 5;
public const int MaxUniformBuffersPerStage = 18; public const int MaxUniformBuffersPerStage = 18;
public const int MaxStorageBuffersPerStage = 16; public const int MaxStorageBuffersPerStage = 16;
public const int MaxTexturesPerStage = 32; public const int MaxTexturesPerStage = 64;
public const int MaxImagesPerStage = 8; public const int MaxImagesPerStage = 8;
public const int MaxUniformBufferBindings = MaxUniformBuffersPerStage * MaxShaderStages; public const int MaxUniformBufferBindings = MaxUniformBuffersPerStage * MaxShaderStages;
public const int MaxStorageBufferBindings = MaxStorageBuffersPerStage * MaxShaderStages; public const int MaxStorageBufferBindings = MaxStorageBuffersPerStage * MaxShaderStages;

View file

@ -31,7 +31,7 @@ void main()
private const string ColorBlitFragmentShaderSource = @"#version 450 core private const string ColorBlitFragmentShaderSource = @"#version 450 core
layout (binding = 32, set = 2) uniform sampler2D tex; layout (binding = 64, set = 2) uniform sampler2D tex;
layout (location = 0) in vec2 tex_coord; layout (location = 0) in vec2 tex_coord;
layout (location = 0) out vec4 colour; layout (location = 0) out vec4 colour;
@ -43,7 +43,7 @@ void main()
private const string ColorBlitClearAlphaFragmentShaderSource = @"#version 450 core private const string ColorBlitClearAlphaFragmentShaderSource = @"#version 450 core
layout (binding = 32, set = 2) uniform sampler2D tex; layout (binding = 64, set = 2) uniform sampler2D tex;
layout (location = 0) in vec2 tex_coord; layout (location = 0) in vec2 tex_coord;
layout (location = 0) out vec4 colour; layout (location = 0) out vec4 colour;
@ -83,7 +83,6 @@ void main()
colour = clear_colour; colour = clear_colour;
}"; }";
private readonly PipelineHelperShader _pipeline; private readonly PipelineHelperShader _pipeline;
private readonly ISampler _samplerLinear; private readonly ISampler _samplerLinear;
private readonly ISampler _samplerNearest; private readonly ISampler _samplerNearest;
@ -127,7 +126,7 @@ void main()
var fragmentBindings = new ShaderBindings( var fragmentBindings = new ShaderBindings(
Array.Empty<int>(), Array.Empty<int>(),
Array.Empty<int>(), Array.Empty<int>(),
new[] { 32 }, new[] { Constants.MaxTexturesPerStage },
Array.Empty<int>(), Array.Empty<int>(),
Array.Empty<int>(), Array.Empty<int>(),
Array.Empty<int>()); Array.Empty<int>());
@ -191,7 +190,7 @@ void main()
var sampler = linearFilter ? _samplerLinear : _samplerNearest; var sampler = linearFilter ? _samplerLinear : _samplerNearest;
_pipeline.SetTextureAndSampler(32, src, sampler); _pipeline.SetTextureAndSampler(Constants.MaxTexturesPerStage, src, sampler);
Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)]; Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)];
@ -328,7 +327,7 @@ void main()
{ {
const int RegionBufferSize = 16; const int RegionBufferSize = 16;
pipeline.SetTextureAndSampler(32, src, srcSampler); pipeline.SetTextureAndSampler(Constants.MaxTexturesPerStage, src, srcSampler);
Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)]; Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)];

View file

@ -39,7 +39,7 @@ namespace Ryujinx.Graphics.Vulkan
private ShaderCollection _program; private ShaderCollection _program;
private Vector4<float>[] _renderScale = new Vector4<float>[65]; private Vector4<float>[] _renderScale = new Vector4<float>[73];
private int _fragmentScaleCount; private int _fragmentScaleCount;
protected FramebufferParams FramebufferParams; protected FramebufferParams FramebufferParams;

View file

@ -318,6 +318,10 @@ namespace Ryujinx.Graphics.Vulkan
supportsTextureShadowLod: false, supportsTextureShadowLod: false,
supportsViewportSwizzle: false, supportsViewportSwizzle: false,
supportsIndirectParameters: SupportsIndirectParameters, supportsIndirectParameters: SupportsIndirectParameters,
maximumUniformBuffersPerStage: Constants.MaxUniformBuffersPerStage,
maximumStorageBuffersPerStage: Constants.MaxStorageBuffersPerStage,
maximumTexturesPerStage: Constants.MaxTexturesPerStage,
maximumImagesPerStage: Constants.MaxImagesPerStage,
maximumComputeSharedMemorySize: (int)limits.MaxComputeSharedMemorySize, maximumComputeSharedMemorySize: (int)limits.MaxComputeSharedMemorySize,
maximumSupportedAnisotropy: (int)limits.MaxSamplerAnisotropy, maximumSupportedAnisotropy: (int)limits.MaxSamplerAnisotropy,
storageBufferOffsetAlignment: (int)limits.MinStorageBufferOffsetAlignment); storageBufferOffsetAlignment: (int)limits.MinStorageBufferOffsetAlignment);