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

View file

@ -1,3 +1,4 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Engine.Threed;
using Ryujinx.Graphics.Gpu.Image;
@ -31,7 +32,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
{
if (_context.Capabilities.Api == TargetApi.Vulkan)
{
return 1 + GetStageIndex() * 18 + index;
return 1 + GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer");
}
else
{
@ -44,7 +45,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
{
if (_context.Capabilities.Api == TargetApi.Vulkan)
{
return GetStageIndex() * 16 + index;
return GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer");
}
else
{
@ -57,7 +58,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
{
if (_context.Capabilities.Api == TargetApi.Vulkan)
{
return GetStageIndex() * 32 + index;
return GetBindingFromIndex(index, _context.Capabilities.MaximumTexturesPerStage, "Texture");
}
else
{
@ -70,7 +71,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
{
if (_context.Capabilities.Api == TargetApi.Vulkan)
{
return GetStageIndex() * 8 + index;
return GetBindingFromIndex(index, _context.Capabilities.MaximumImagesPerStage, "Image");
}
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()
{
// 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 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 TextureBase _unit0Texture;

View file

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

View file

@ -24,8 +24,8 @@ namespace Ryujinx.Graphics.Shader
public static int ComputeRenderScaleOffset;
public const int FragmentIsBgraCount = 8;
// One for the render target, 32 for the textures, and 8 for the images.
public const int RenderScaleMaxCount = 1 + 32 + 8;
// One for the render target, 64 for the textures, and 8 for the images.
public const int RenderScaleMaxCount = 1 + 64 + 8;
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<int> FragmentRenderScaleCount;
// Render scale max count: 1 + 32 + 8. First scale is fragment output scale, others are textures/image inputs.
public Array41<Vector4<float>> RenderScale;
// Render scale max count: 1 + 64 + 8. First scale is fragment output scale, others are textures/image inputs.
public Array73<Vector4<float>> RenderScale;
}
}

View file

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

View file

@ -31,7 +31,7 @@ void main()
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) out vec4 colour;
@ -43,7 +43,7 @@ void main()
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) out vec4 colour;
@ -83,7 +83,6 @@ void main()
colour = clear_colour;
}";
private readonly PipelineHelperShader _pipeline;
private readonly ISampler _samplerLinear;
private readonly ISampler _samplerNearest;
@ -127,7 +126,7 @@ void main()
var fragmentBindings = new ShaderBindings(
Array.Empty<int>(),
Array.Empty<int>(),
new[] { 32 },
new[] { Constants.MaxTexturesPerStage },
Array.Empty<int>(),
Array.Empty<int>(),
Array.Empty<int>());
@ -191,7 +190,7 @@ void main()
var sampler = linearFilter ? _samplerLinear : _samplerNearest;
_pipeline.SetTextureAndSampler(32, src, sampler);
_pipeline.SetTextureAndSampler(Constants.MaxTexturesPerStage, src, sampler);
Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)];
@ -328,7 +327,7 @@ void main()
{
const int RegionBufferSize = 16;
pipeline.SetTextureAndSampler(32, src, srcSampler);
pipeline.SetTextureAndSampler(Constants.MaxTexturesPerStage, src, srcSampler);
Span<float> region = stackalloc float[RegionBufferSize / sizeof(float)];

View file

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

View file

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